1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     Sinclair ZX8302 emulation
6 
7 **********************************************************************
8                             _____   _____
9                  ERASE   1 |*    \_/     | 40  Vdd
10                EXTINTL   2 |             | 39  DB4
11                 MDRDWL   3 |             | 38  DB5
12                 NETOUT   4 |             | 37  DB0
13                 BAUDX4   5 |             | 36  DB1
14                  DTR1L   6 |             | 35  COMDATA
15                  CTS2L   7 |             | 34  MDSELDH
16                  DCSML   8 |             | 33  MDSELCKN
17                   ROWL   9 |             | 32  VSYNCH
18                  PCENL  10 |    ZX8302   | 31  XTAL2
19                    Vdd  11 |     ULA     | 30  XTAL1
20                    DB2  12 |             | 29
21                   TXD1  13 |             | 28  RESETOUTL
22                   TXD2  14 |             | 27  DB7
23                     A5  15 |             | 26  IPL1L
24                  NETIN  16 |             | 25  CLKCPU
25                     A1  17 |             | 24  DB3
26                     A0  18 |             | 23  DB6
27                   RAW2  19 |             | 22  COMCTL
28                    GND  20 |_____________| 21  RAW1
29 
30 **********************************************************************/
31 
32 #ifndef MAME_MACHINE_ZX8302_H
33 #define MAME_MACHINE_ZX8302_H
34 
35 #pragma once
36 
37 #include "diserial.h"
38 
39 
40 ///*************************************************************************
41 //  TYPE DEFINITIONS
42 ///*************************************************************************
43 
44 // ======================> zx8302_device
45 
46 class zx8302_device :  public device_t,
47 						public device_serial_interface
48 {
49 public:
50 	// construction/destruction
51 	zx8302_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
52 
set_rtc_clock(int rtc_clock)53 	void set_rtc_clock(int rtc_clock) { m_rtc_clock = rtc_clock; }
set_rtc_clock(const XTAL & rtc_clock)54 	void set_rtc_clock(const XTAL &rtc_clock) { set_rtc_clock(rtc_clock.value()); }
out_ipl1l_callback()55 	auto out_ipl1l_callback() { return m_out_ipl1l_cb.bind(); }
out_baudx4_callback()56 	auto out_baudx4_callback() { return m_out_baudx4_cb.bind(); }
out_comdata_callback()57 	auto out_comdata_callback() { return m_out_comdata_cb.bind(); }
out_txd1_callback()58 	auto out_txd1_callback() { return m_out_txd1_cb.bind(); }
out_txd2_callback()59 	auto out_txd2_callback() { return m_out_txd2_cb.bind(); }
out_netout_callback()60 	auto out_netout_callback() { return m_out_netout_cb.bind(); }
out_mdselck_callback()61 	auto out_mdselck_callback() { return m_out_mdselck_cb.bind(); }
out_mdseld_callback()62 	auto out_mdseld_callback() { return m_out_mdseld_cb.bind(); }
out_mdrdw_callback()63 	auto out_mdrdw_callback() { return m_out_mdrdw_cb.bind(); }
out_erase_callback()64 	auto out_erase_callback() { return m_out_erase_cb.bind(); }
out_raw1_callback()65 	auto out_raw1_callback() { return m_out_raw1_cb.bind(); }
in_raw1_callback()66 	auto in_raw1_callback() { return m_in_raw1_cb.bind(); }
out_raw2_callback()67 	auto out_raw2_callback() { return m_out_raw2_cb.bind(); }
in_raw2_callback()68 	auto in_raw2_callback() { return m_in_raw2_cb.bind(); }
69 
70 	uint8_t rtc_r(offs_t offset);
71 	void rtc_w(uint8_t data);
72 	void control_w(uint8_t data);
73 	uint8_t mdv_track_r();
74 	uint8_t status_r();
75 	void ipc_command_w(uint8_t data);
76 	void mdv_control_w(uint8_t data);
77 	uint8_t irq_status_r();
78 	void irq_acknowledge_w(uint8_t data);
79 	void data_w(uint8_t data);
80 	DECLARE_WRITE_LINE_MEMBER( vsync_w );
81 	DECLARE_WRITE_LINE_MEMBER( comctl_w );
82 	DECLARE_WRITE_LINE_MEMBER( comdata_w );
83 	DECLARE_WRITE_LINE_MEMBER( extint_w );
84 
85 	DECLARE_WRITE_LINE_MEMBER( write_netin );
86 	DECLARE_WRITE_LINE_MEMBER( write_dtr1 );
87 	DECLARE_WRITE_LINE_MEMBER( write_cts2 );
88 
89 protected:
90 	// device-level overrides
91 	virtual void device_start() override;
92 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
93 
94 	// device_serial_interface overrides
95 	virtual void tra_callback() override;
96 	virtual void tra_complete() override;
97 	virtual void rcv_callback() override;
98 	virtual void rcv_complete() override;
99 
100 	inline void trigger_interrupt(uint8_t line);
101 	inline void transmit_ipc_data();
102 
103 private:
104 	enum
105 	{
106 		TIMER_BAUDX4 = 0,
107 		TIMER_RTC,
108 		TIMER_GAP
109 	};
110 
111 	enum
112 	{
113 		IPC_START,
114 		IPC_DATA,
115 		IPC_STOP
116 	};
117 
118 	enum
119 	{
120 		BAUD_19200 = 0,
121 		BAUD_9600,
122 		BAUD_4800,
123 		BAUD_2400,
124 		BAUD_1200,
125 		BAUD_600,
126 		BAUD_300,
127 		BAUD_75,
128 		BAUD_MASK = 0x07
129 	};
130 
131 	enum
132 	{
133 		MODE_SER1               = 0x00,
134 		MODE_SER2               = 0x08,
135 		MODE_MDV                = 0x10,
136 		MODE_NET                = 0x18,
137 		MODE_MASK               = 0x18
138 	};
139 
140 	enum
141 	{
142 		INT_GAP                 = 0x01,
143 		INT_INTERFACE           = 0x02,
144 		INT_TRANSMIT            = 0x04,
145 		INT_FRAME               = 0x08,
146 		INT_EXTERNAL            = 0x10
147 	};
148 
149 	enum
150 	{
151 		STATUS_NETWORK_PORT     = 0x01,
152 		STATUS_TX_BUFFER_FULL   = 0x02,
153 		STATUS_RX_BUFFER_FULL   = 0x04,
154 		STATUS_MICRODRIVE_GAP   = 0x08
155 	};
156 
157 	int m_rtc_clock;              // the RTC clock (pin 30) of the chip
158 
159 	// serial
160 	devcb_write_line    m_out_ipl1l_cb;
161 	devcb_write_line    m_out_baudx4_cb;
162 	devcb_write_line    m_out_comdata_cb;
163 	devcb_write_line    m_out_txd1_cb;
164 	devcb_write_line    m_out_txd2_cb;
165 	devcb_write_line    m_out_netout_cb;
166 
167 	// microdrive
168 	devcb_write_line    m_out_mdselck_cb;
169 	devcb_write_line    m_out_mdseld_cb;
170 	devcb_write_line    m_out_mdrdw_cb;
171 	devcb_write_line    m_out_erase_cb;
172 	devcb_write_line    m_out_raw1_cb;
173 	devcb_read_line     m_in_raw1_cb;
174 	devcb_write_line    m_out_raw2_cb;
175 	devcb_read_line     m_in_raw2_cb;
176 
177 	int m_rs232_rx;
178 	int m_dtr1;
179 	int m_cts2;
180 
181 	// registers
182 	uint8_t m_idr;                    // IPC data register
183 	uint8_t m_tcr;                    // transfer control register
184 	uint8_t m_tdr;                    // transfer data register
185 	uint8_t m_irq;                    // interrupt register
186 	uint32_t m_ctr;                   // counter register
187 	uint8_t m_status;                 // status register
188 
189 	// IPC communication state
190 	int m_comdata_from_ipc;         // pending data from IPC->68000
191 	int m_comdata_to_cpu;           // communication data IPC->68000
192 	int m_comdata_to_ipc;           // communication data 68000->IPC
193 	int m_comctl;                   // communication control
194 	int m_ipc_state;                // communication state
195 	int m_ipc_busy;                 // IPC busy
196 	int m_baudx4;                   // IPC baud x4
197 
198 	// microdrive state
199 	uint8_t m_mdv_data[2];            // track data register
200 	int m_track;                    // current track
201 
202 	// timers
203 	emu_timer *m_baudx4_timer;      // baud x4 timer
204 	emu_timer *m_rtc_timer;         // real time clock timer
205 	emu_timer *m_gap_timer;         // microdrive gap timer
206 };
207 
208 
209 // device type definition
210 DECLARE_DEVICE_TYPE(ZX8302, zx8302_device)
211 
212 
213 
214 #endif // MAME_MACHINE_ZX8302_H
215