1 // license:BSD-3-Clause
2 // copyright-holders:Nathan Woods
3 /***************************************************************************
4 
5     coco.h
6 
7     TRS-80 Radio Shack Color Computer Family
8 
9 ***************************************************************************/
10 
11 #pragma once
12 
13 #ifndef MAME_INCLUDES_COCO_H
14 #define MAME_INCLUDES_COCO_H
15 
16 
17 #include "imagedev/cassette.h"
18 #include "bus/rs232/rs232.h"
19 #include "machine/6821pia.h"
20 #include "bus/coco/cococart.h"
21 #include "machine/coco_vhd.h"
22 #include "bus/coco/coco_dwsock.h"
23 #include "machine/ram.h"
24 #include "machine/bankdev.h"
25 #include "sound/dac.h"
26 #include "screen.h"
27 
28 
29 //**************************************************************************
30 //  MACROS / CONSTANTS
31 //**************************************************************************
32 
33 INPUT_PORTS_EXTERN( coco_analog_control );
34 INPUT_PORTS_EXTERN( coco_joystick );
35 INPUT_PORTS_EXTERN( coco_rtc );
36 INPUT_PORTS_EXTERN( coco_beckerport );
37 INPUT_PORTS_EXTERN( coco_beckerport_dw );
38 
39 void coco_cart(device_slot_interface &device);
40 
41 // constants
42 #define JOYSTICK_DELTA          10
43 #define JOYSTICK_SENSITIVITY    100
44 
45 // devices
46 #define MAINCPU_TAG                 "maincpu"
47 #define PIA0_TAG                    "pia0"
48 #define PIA1_TAG                    "pia1"
49 #define SAM_TAG                     "sam"
50 #define VDG_TAG                     "vdg"
51 #define SCREEN_TAG                  "screen"
52 #define CARTRIDGE_TAG               "ext"
53 #define RS232_TAG                   "rs232"
54 #define DWSOCK_TAG                  "dwsock"
55 #define VHD0_TAG                    "vhd0"
56 #define VHD1_TAG                    "vhd1"
57 #define FLOATING_TAG                "floating"
58 
59 // inputs
60 #define CTRL_SEL_TAG                "ctrl_sel"
61 #define HIRES_INTF_TAG              "hires_intf"
62 #define BECKERPORT_TAG              "beckerport"
63 #define JOYSTICK_RX_TAG             "joystick_rx"
64 #define JOYSTICK_RY_TAG             "joystick_ry"
65 #define JOYSTICK_LX_TAG             "joystick_lx"
66 #define JOYSTICK_LY_TAG             "joystick_ly"
67 #define JOYSTICK_BUTTONS_TAG        "joystick_buttons"
68 #define RAT_MOUSE_RX_TAG            "rat_mouse_rx"
69 #define RAT_MOUSE_RY_TAG            "rat_mouse_ry"
70 #define RAT_MOUSE_LX_TAG            "rat_mouse_lx"
71 #define RAT_MOUSE_LY_TAG            "rat_mouse_ly"
72 #define RAT_MOUSE_BUTTONS_TAG       "rat_mouse_buttons"
73 #define DIECOM_LIGHTGUN_RX_TAG      "dclg_rx"
74 #define DIECOM_LIGHTGUN_RY_TAG      "dclg_ry"
75 #define DIECOM_LIGHTGUN_LX_TAG      "dclg_lx"
76 #define DIECOM_LIGHTGUN_LY_TAG      "dclg_ly"
77 #define DIECOM_LIGHTGUN_BUTTONS_TAG "dclg_triggers"
78 
79 
80 //**************************************************************************
81 //  TYPE DEFINITIONS
82 //**************************************************************************
83 
84 class coco_state : public driver_device, public device_cococart_host_interface
85 {
86 public:
87 	coco_state(const machine_config &mconfig, device_type type, const char *tag);
88 
89 	// driver update handlers
90 	DECLARE_INPUT_CHANGED_MEMBER(keyboard_changed);
91 	DECLARE_INPUT_CHANGED_MEMBER(joystick_mode_changed);
92 
93 	// IO
94 	virtual void ff20_write(offs_t offset, uint8_t data);
95 	virtual uint8_t ff40_read(offs_t offset);
96 	virtual void ff40_write(offs_t offset, uint8_t data);
97 	uint8_t ff60_read(offs_t offset);
98 	void ff60_write(offs_t offset, uint8_t data);
99 
100 	// PIA0
101 	void pia0_pa_w(uint8_t data);
102 	void pia0_pb_w(uint8_t data);
103 	DECLARE_WRITE_LINE_MEMBER( pia0_ca2_w );
104 	DECLARE_WRITE_LINE_MEMBER( pia0_cb2_w );
105 	DECLARE_WRITE_LINE_MEMBER( pia0_irq_a );
106 	DECLARE_WRITE_LINE_MEMBER( pia0_irq_b );
107 
108 	// PIA1
109 	uint8_t pia1_pa_r();
110 	uint8_t pia1_pb_r();
111 	void pia1_pa_w(uint8_t data);
112 	void pia1_pb_w(uint8_t data);
113 	DECLARE_WRITE_LINE_MEMBER( pia1_ca2_w );
114 	DECLARE_WRITE_LINE_MEMBER( pia1_cb2_w );
115 	DECLARE_WRITE_LINE_MEMBER( pia1_firq_a );
116 	DECLARE_WRITE_LINE_MEMBER( pia1_firq_b );
117 
118 	// floating bus & "space"
floating_bus_r()119 	uint8_t floating_bus_r()   { return floating_bus_read(); }
120 	uint8_t floating_space_read(offs_t offset);
121 	void floating_space_write(offs_t offset, uint8_t data);
122 
123 	// cartridge stuff
DECLARE_WRITE_LINE_MEMBER(cart_w)124 	DECLARE_WRITE_LINE_MEMBER( cart_w ) { cart_w((bool) state); }
125 	virtual address_space &cartridge_space() override;
126 
127 	// disassembly override
128 	static offs_t os9_dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer &params);
129 	offs_t dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer &params);
130 
131 	void coco_sound(machine_config &config);
132 	void coco_floating(machine_config &config);
133 
134 	void coco_floating_map(address_map &map);
135 
136 protected:
137 	// device-level overrides
138 	virtual void device_start() override;
139 	virtual void device_reset() override;
140 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
141 
142 	// interrupts
143 	virtual bool firq_get_line(void);
144 	virtual bool irq_get_line(void);
145 	void recalculate_irq(void);
146 	void recalculate_firq(void);
147 
148 	// changed handlers
149 	virtual void pia1_pa_changed(uint8_t data);
150 	virtual void pia1_pb_changed(uint8_t data);
151 
152 	// accessors
pia_0()153 	pia6821_device &pia_0() { return *m_pia_0; }
pia_1()154 	pia6821_device &pia_1() { return *m_pia_1; }
cococart()155 	cococart_slot_device &cococart() { return *m_cococart; }
ram()156 	ram_device &ram() { return *m_ram; }
157 
158 	// miscellaneous
159 	virtual void update_keyboard_input(uint8_t value);
160 	virtual void cart_w(bool state);
update_cart_base(uint8_t * cart_base)161 	virtual void update_cart_base(uint8_t *cart_base) { };
162 
163 protected:
164 	// timer constants
165 	static const device_timer_id TIMER_HIRES_JOYSTICK_X = 0;
166 	static const device_timer_id TIMER_HIRES_JOYSTICK_Y = 1;
167 	static const device_timer_id TIMER_DIECOM_LIGHTGUN = 2;
168 
169 	enum soundmux_status_t
170 	{
171 		SOUNDMUX_SEL1 = 1,
172 		SOUNDMUX_SEL2 = 2,
173 		SOUNDMUX_ENABLE = 4
174 	};
175 
176 	enum joystick_type_t
177 	{
178 		JOYSTICK_NONE = 0x00,
179 		JOYSTICK_NORMAL = 0x01,
180 		JOYSTICK_RAT_MOUSE = 0x02,
181 		JOYSTICK_DIECOM_LIGHT_GUN = 0x03
182 	};
183 
184 	enum hires_type_t
185 	{
186 		HIRES_NONE = 0x00,
187 		HIRES_RIGHT = 0x01,
188 		HIRES_RIGHT_COCOMAX3 = 0x02,
189 		HIRES_LEFT = 0x03,
190 		HIRES_LEFT_COCOMAX3 = 0x04
191 	};
192 
193 	struct analog_input_t
194 	{
195 		ioport_port *m_input[2][2];
196 		ioport_port *m_buttons;
197 
inputanalog_input_t198 		uint8_t input(int joystick, int axis) const { return m_input[joystick][axis] ? m_input[joystick][axis]->read() : 0x00; }
buttonsanalog_input_t199 		uint8_t buttons(void) const { return m_buttons ? m_buttons->read() : 0x00; }
200 	};
201 
202 	void analog_port_start(analog_input_t *analog, const char *rx_tag, const char *ry_tag, const char *lx_tag, const char *ly_tag, const char *buttons_tag);
203 
204 	// wrappers for configuration
205 	joystick_type_t joystick_type(int index);
206 	hires_type_t hires_interface_type(void);
207 	bool is_joystick_hires(int joystick_index);
208 
209 	soundmux_status_t soundmux_status(void);
210 	void update_sound(void);
211 	void poll_joystick(bool *joyin, uint8_t *buttons);
212 	void poll_keyboard(void);
213 	void poll_hires_joystick(void);
214 	void update_cassout(int cassout);
215 	void update_prinout(bool prinout);
216 	void diecom_lightgun_clock(void);
217 
218 	// thin wrappers for PIA output
dac_output(void)219 	uint8_t dac_output(void)  { return m_dac_output; }    // PA drives the DAC
sel1(void)220 	bool sel1(void)         { return m_pia_0->ca2_output() ? true : false; }
sel2(void)221 	bool sel2(void)         { return m_pia_0->cb2_output() ? true : false; }
snden(void)222 	bool snden(void)        { return m_pia_1->cb2_output() ? true : false; }
223 
224 	// VHD selection
225 	coco_vhd_image_device *current_vhd();
226 
227 	// floating bus
228 	uint8_t floating_bus_read();
229 
230 	// devices
231 	required_device<cpu_device> m_maincpu;
232 	required_device<pia6821_device> m_pia_0;
233 	required_device<pia6821_device> m_pia_1;
234 	required_device<dac_byte_interface> m_dac;
235 	required_device<dac_1bit_device> m_sbs;
236 	optional_device<screen_device> m_screen;
237 	required_device<cococart_slot_device> m_cococart;
238 	required_device<ram_device> m_ram;
239 	required_device<cassette_image_device> m_cassette;
240 	required_device<address_map_bank_device> m_floating;
241 	optional_device<rs232_port_device> m_rs232;
242 	optional_device<coco_vhd_image_device> m_vhd_0;
243 	optional_device<coco_vhd_image_device> m_vhd_1;
244 	optional_device<beckerport_device> m_beckerport;
245 	optional_ioport                    m_beckerportconfig;
246 
247 	// input ports
248 	required_ioport_array<7> m_keyboard;
249 	optional_ioport m_joystick_type_control;
250 	optional_ioport m_joystick_hires_control;
251 	analog_input_t m_joystick;
252 	analog_input_t m_rat_mouse;
253 	analog_input_t m_diecom_lightgun;
254 
255 	// DAC output
256 	uint8_t m_dac_output;
257 
258 	// remember the last audio sample level from the analog sources (DAC, cart, cassette) so that we don't
259 	// introduce step changes when the audio output is enabled/disabled via PIA1 CB2
260 	uint8_t m_analog_audio_level;
261 
262 	// hires interface
263 	emu_timer *m_hiresjoy_transition_timer[2];
264 	bool m_hiresjoy_ca;
265 
266 	// diecom lightgun
267 	emu_timer *m_diecom_lightgun_timer;
268 	bool m_dclg_previous_bit;
269 	uint8_t m_dclg_output_h;
270 	uint8_t m_dclg_output_v;
271 	uint8_t m_dclg_state;
272 	uint16_t m_dclg_timer;
273 
274 	// VHD selection
275 	uint8_t m_vhd_select;
276 
277 	// address space for "floating access"
278 	//address_space m_floating_space;
279 
280 	// safety to prevent stack overflow when reading floating bus
281 	bool m_in_floating_bus_read;
282 };
283 
284 #endif // MAME_INCLUDES_COCO_H
285