1 // license:BSD-3-Clause
2 // copyright-holders:Joakim Larsson Edstrom
3 /**********************************************************************
4 *
5 *   Motorola MC68230 PI/T Parallel Interface and Timer
6 *
7 *                           _____   _____
8 *                   D5   1 |*    \_/     | 48  D4
9 *                   D6   2 |             | 47  D3
10 *                   D7   3 |             | 46  D2
11 *                  PA0   4 |             | 45  D1
12 *                  PA1   5 |             | 44  D0
13 *                  PA2   6 |             | 43  R/W*
14 *                  PA3   7 |             | 42  DTACK*
15 *                  PA4   8 |             | 41  CS*
16 *                  PA5   9 |             | 40  CLK
17 *                  PA6  10 |             | 39  RESET*
18 *                  PA7  11 |             | 38  VSS
19 *                  Vcc  12 |   TS68230   | 37  PC7/TIACK*
20 *                   H1  13 |   SC87845   | 36  PC6/PIACK*
21 *                   H2  14 |             | 35  PC5/PIRQ*
22 *                   H3  15 |             | 34  PC4/DMAREQ*
23 *                   H4  16 |             | 33  PC3/TOUT
24 *                  PB0  17 |             | 32  PC2/TIN
25 *                  PB1  18 |             | 31  PC1
26 *                  PB2  19 |             | 30  PC0
27 *                  PB3  20 |             | 29  RS1
28 *                  PB4  21 |             | 28  RS2
29 *                  PB5  22 |             | 27  RS3
30 *                  PB6  23 |             | 26  RS4
31 *                  PB7  24 |_____________| 25  RS5
32 *
33 **********************************************************************/
34 
35 #ifndef MAME_MACHINE_68230PIT_H
36 #define MAME_MACHINE_68230PIT_H
37 
38 #pragma once
39 
40 
41 /*-----------------------------------------------------------------------
42  * Registers                RS1-RS5   R/W Description
43  * -------------------------------------------------------------------------*/
44 #define PIT_68230_PGCR        0x00 /* RW Port General Control register   */
45 #define PIT_68230_PSRR        0x01 /* RW Port Service Request register   */
46 #define PIT_68230_PADDR       0x02 /* RW Port A Data Direction register  */
47 #define PIT_68230_PBDDR       0x03 /* RW Port B Data Direction register  */
48 #define PIT_68230_PCDDR       0x04 /* RW Port C Data Direction register  */
49 #define PIT_68230_PIVR        0x05 /* RW Port Interrupt vector register  */
50 #define PIT_68230_PACR        0x06 /* RW Port A Control register         */
51 #define PIT_68230_PBCR        0x07 /* RW Port B Control register         */
52 #define PIT_68230_PADR        0x08 /* RW Port A Data register            */
53 #define PIT_68230_PBDR        0x09 /* RW Port B Data register            */
54 #define PIT_68230_PAAR        0x0a /* RO Port A Alternate register       */
55 #define PIT_68230_PBAR        0x0b /* RO Port B Alternate register       */
56 #define PIT_68230_PCDR        0x0c /* RW Port C Data register            */
57 #define PIT_68230_PSR         0x0d /* RW Port Status register            */
58 #define PIT_68230_TCR         0x10 /* RW Timer Control Register          */
59 #define PIT_68230_TIVR        0x11 /* RW Timer Interrupt Vector Register */
60 #define PIT_68230_CPRH        0x13 /* RW Counter Preload Register High   */
61 #define PIT_68230_CPRM        0x14 /* RW Counter Preload Register Middle */
62 #define PIT_68230_CPRL        0x15 /* RW Counter Preload Register Low    */
63 #define PIT_68230_CNTRH       0x17 /* RO Counter Register High           */
64 #define PIT_68230_CNTRM       0x18 /* RO Counter Register Middle         */
65 #define PIT_68230_CNTRL       0x19 /* RO Counter Register Low            */
66 #define PIT_68230_TSR         0x1A /* RW Timer Status Register           */
67 
68 //**************************************************************************
69 //  TYPE DEFINITIONS
70 //**************************************************************************
71 class pit68230_device :  public device_t//, public device_execute_interface
72 {
73 public:
74 	// construction/destruction
75 	pit68230_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
76 
pa_in_callback()77 	auto pa_in_callback() { return m_pa_in_cb.bind(); }
pa_out_callback()78 	auto pa_out_callback() { return m_pa_out_cb.bind(); }
pb_in_callback()79 	auto pb_in_callback() { return m_pb_in_cb.bind(); }
pb_out_callback()80 	auto pb_out_callback() { return m_pb_out_cb.bind(); }
pc_in_callback()81 	auto pc_in_callback() { return m_pc_in_cb.bind(); }
pc_out_callback()82 	auto pc_out_callback() { return m_pc_out_cb.bind(); }
h1_out_callback()83 	auto h1_out_callback() { return m_h1_out_cb.bind(); }
h2_out_callback()84 	auto h2_out_callback() { return m_h2_out_cb.bind(); }
h3_out_callback()85 	auto h3_out_callback() { return m_h3_out_cb.bind(); }
h4_out_callback()86 	auto h4_out_callback() { return m_h4_out_cb.bind(); }
timer_irq_callback()87 	auto timer_irq_callback() { return m_tirq_out_cb.bind(); }
port_irq_callback()88 	auto port_irq_callback() { return m_pirq_out_cb.bind(); }
89 
90 	void write(offs_t offset, uint8_t data);
91 	uint8_t read(offs_t offset);
92 
93 	// TODO: remove these methods and replace it with a call to methods below in force68k.cpp
h1_set(uint8_t state)94 	void h1_set(uint8_t state) { if (state) m_psr |= 1; else m_psr &= ~1; }
95 	void portb_setbit(uint8_t bit, uint8_t state);
96 
97 	// Bit updaters
98 	void pa_update_bit(uint8_t bit, uint8_t state);
99 	void pb_update_bit(uint8_t bit, uint8_t state);
100 	void pc_update_bit(uint8_t bit, uint8_t state);
101 	void update_tin(uint8_t);
102 
103 	DECLARE_WRITE_LINE_MEMBER( h1_w );
104 	DECLARE_WRITE_LINE_MEMBER( h2_w );
105 	DECLARE_WRITE_LINE_MEMBER( h3_w );
106 	DECLARE_WRITE_LINE_MEMBER( h4_w );
107 
DECLARE_WRITE_LINE_MEMBER(pa0_w)108 	DECLARE_WRITE_LINE_MEMBER( pa0_w ) { pa_update_bit(0, state); }
DECLARE_WRITE_LINE_MEMBER(pa1_w)109 	DECLARE_WRITE_LINE_MEMBER( pa1_w ) { pa_update_bit(1, state); }
DECLARE_WRITE_LINE_MEMBER(pa2_w)110 	DECLARE_WRITE_LINE_MEMBER( pa2_w ) { pa_update_bit(2, state); }
DECLARE_WRITE_LINE_MEMBER(pa3_w)111 	DECLARE_WRITE_LINE_MEMBER( pa3_w ) { pa_update_bit(3, state); }
DECLARE_WRITE_LINE_MEMBER(pa4_w)112 	DECLARE_WRITE_LINE_MEMBER( pa4_w ) { pa_update_bit(4, state); }
DECLARE_WRITE_LINE_MEMBER(pa5_w)113 	DECLARE_WRITE_LINE_MEMBER( pa5_w ) { pa_update_bit(5, state); }
DECLARE_WRITE_LINE_MEMBER(pa6_w)114 	DECLARE_WRITE_LINE_MEMBER( pa6_w ) { pa_update_bit(6, state); }
DECLARE_WRITE_LINE_MEMBER(pa7_w)115 	DECLARE_WRITE_LINE_MEMBER( pa7_w ) { pa_update_bit(7, state); }
116 
DECLARE_WRITE_LINE_MEMBER(pb0_w)117 	DECLARE_WRITE_LINE_MEMBER( pb0_w ) { pb_update_bit(0, state); }
DECLARE_WRITE_LINE_MEMBER(pb1_w)118 	DECLARE_WRITE_LINE_MEMBER( pb1_w ) { pb_update_bit(1, state); }
DECLARE_WRITE_LINE_MEMBER(pb2_w)119 	DECLARE_WRITE_LINE_MEMBER( pb2_w ) { pb_update_bit(2, state); }
DECLARE_WRITE_LINE_MEMBER(pb3_w)120 	DECLARE_WRITE_LINE_MEMBER( pb3_w ) { pb_update_bit(3, state); }
DECLARE_WRITE_LINE_MEMBER(pb4_w)121 	DECLARE_WRITE_LINE_MEMBER( pb4_w ) { pb_update_bit(4, state); }
DECLARE_WRITE_LINE_MEMBER(pb5_w)122 	DECLARE_WRITE_LINE_MEMBER( pb5_w ) { pb_update_bit(5, state); }
DECLARE_WRITE_LINE_MEMBER(pb6_w)123 	DECLARE_WRITE_LINE_MEMBER( pb6_w ) { pb_update_bit(6, state); }
DECLARE_WRITE_LINE_MEMBER(pb7_w)124 	DECLARE_WRITE_LINE_MEMBER( pb7_w ) { pb_update_bit(7, state); }
125 
DECLARE_WRITE_LINE_MEMBER(pc0_w)126 	DECLARE_WRITE_LINE_MEMBER( pc0_w ) { pc_update_bit(0, state); }
DECLARE_WRITE_LINE_MEMBER(pc1_w)127 	DECLARE_WRITE_LINE_MEMBER( pc1_w ) { pc_update_bit(1, state); }
DECLARE_WRITE_LINE_MEMBER(pc2_w)128 	DECLARE_WRITE_LINE_MEMBER( pc2_w ) { pc_update_bit(2, state); }
DECLARE_WRITE_LINE_MEMBER(pc3_w)129 	DECLARE_WRITE_LINE_MEMBER( pc3_w ) { pc_update_bit(3, state); }
DECLARE_WRITE_LINE_MEMBER(pc4_w)130 	DECLARE_WRITE_LINE_MEMBER( pc4_w ) { pc_update_bit(4, state); }
DECLARE_WRITE_LINE_MEMBER(pc5_w)131 	DECLARE_WRITE_LINE_MEMBER( pc5_w ) { pc_update_bit(5, state); }
DECLARE_WRITE_LINE_MEMBER(pc6_w)132 	DECLARE_WRITE_LINE_MEMBER( pc6_w ) { pc_update_bit(6, state); }
DECLARE_WRITE_LINE_MEMBER(pc7_w)133 	DECLARE_WRITE_LINE_MEMBER( pc7_w ) { pc_update_bit(7, state); }
134 
135 	uint8_t irq_tiack();
136 	uint8_t irq_piack();
137 
138 private:
139 	void wr_pitreg_pgcr(uint8_t data);
140 	void wr_pitreg_psrr(uint8_t data);
141 	void wr_pitreg_paddr(uint8_t data);
142 	void wr_pitreg_pbddr(uint8_t data);
143 	void wr_pitreg_pcddr(uint8_t data);
144 	void wr_pitreg_pivr(uint8_t data);
145 	void wr_pitreg_pacr(uint8_t data);
146 	void wr_pitreg_pbcr(uint8_t data);
147 	void wr_pitreg_padr(uint8_t data);
148 	void wr_pitreg_pbdr(uint8_t data);
149 	void wr_pitreg_paar(uint8_t data);
150 	void wr_pitreg_pbar(uint8_t data);
151 	void wr_pitreg_pcdr(uint8_t data);
152 	void wr_pitreg_psr(uint8_t data);
153 	void wr_pitreg_tcr(uint8_t data);
154 	void wr_pitreg_tivr(uint8_t data);
155 	void wr_pitreg_cprh(uint8_t data);
156 	void wr_pitreg_cprm(uint8_t data);
157 	void wr_pitreg_cprl(uint8_t data);
158 	void wr_pitreg_tsr(uint8_t data);
159 
160 	uint8_t rr_pitreg_pgcr();
161 	uint8_t rr_pitreg_psrr();
162 	uint8_t rr_pitreg_paddr();
163 	uint8_t rr_pitreg_pbddr();
164 	uint8_t rr_pitreg_pcddr();
165 	uint8_t rr_pitreg_pivr();
166 	uint8_t rr_pitreg_pacr();
167 	uint8_t rr_pitreg_pbcr();
168 	uint8_t rr_pitreg_padr();
169 	uint8_t rr_pitreg_pbdr();
170 	uint8_t rr_pitreg_paar();
171 	uint8_t rr_pitreg_pbar();
172 	uint8_t rr_pitreg_pcdr();
173 	uint8_t rr_pitreg_psr();
174 	uint8_t rr_pitreg_tcr();
175 	uint8_t rr_pitreg_tivr();
176 	uint8_t rr_pitreg_cprh();
177 	uint8_t rr_pitreg_cprm();
178 	uint8_t rr_pitreg_cprl();
179 	uint8_t rr_pitreg_cntrh();
180 	uint8_t rr_pitreg_cntrm();
181 	uint8_t rr_pitreg_cntrl();
182 	uint8_t rr_pitreg_tsr();
183 
184 protected:
185 
186 	enum { // PGCR - Port Global Control register
187 		REG_PGCR_MODE_MASK      = 0xc0,
188 		REG_PGCR_MODE_0         = 0x00, // 0 0 Unidirectional  8 bit mode
189 		REG_PGCR_MODE_1         = 0x40, // 0 1 Unidirectional 16 bit mode
190 		REG_PGCR_MODE_2         = 0x80, // 1 0 Bidirectional   8 bit mode
191 		REG_PGCR_MODE_3         = 0xc0, // 1 1 Bidirectional  16 bit mode
192 		REG_PGCR_H34_ENABLE     = 0x20,
193 		REG_PGCR_H12_ENABLE     = 0x10,
194 		REG_PGCR_H4_SENSE       = 0x80,
195 		REG_PGCR_H3_SENSE       = 0x40,
196 		REG_PGCR_H2_SENSE       = 0x20,
197 		REG_PGCR_H1_SENSE       = 0x10,
198 	};
199 
200 	enum {
201 		REG_PACR_SUBMODE_MASK   = 0xc0,
202 		REG_PACR_SUBMODE_0      = 0x00, // 0 0
203 		REG_PACR_SUBMODE_1      = 0x40, // 0 1
204 		REG_PACR_SUBMODE_2      = 0x80, // 1 0
205 		REG_PACR_SUBMODE_3      = 0xc0, // 1 1
206 		REG_PACR_H2_CTRL_MASK   = 0x38,
207 		REG_PACR_H2_CTRL_IN_OUT = 0x20, // H2 sense always cleared if set
208 		REG_PACR_H2_CTRL_OUT_00 = 0x20, // H2 output negated
209 		REG_PACR_H2_CTRL_OUT_01 = 0x28, // H2 output asserted
210 		REG_PACR_H2_CTRL_OUT_10 = 0x30, // H2 output in interlocked input handshake protocol
211 		REG_PACR_H2_CTRL_OUT_11 = 0x38, // H2 output in pulsed input handshake protocol
212 		REG_PACR_H2_INT_ENABLE  = 0x04,
213 		REG_PACR_H1_SVCR_ENABLE = 0x02,
214 		REG_PACR_H1_STATUS_CTRL = 0x01,
215 	};
216 
217 	enum {
218 		REG_PBCR_SUBMODE_MASK   = 0xc0,
219 		REG_PBCR_SUBMODE_00     = 0x00, // 0 0
220 		REG_PBCR_SUBMODE_01     = 0x40, // 0 1
221 		REG_PBCR_SUBMODE_10     = 0x80, // 1 0
222 		REG_PBCR_SUBMODE_11     = 0xc0, // 1 1
223 		REG_PBCR_SUBMODE_1X     = 0x80, // submode 2 or 3
224 		REG_PBCR_H4_CTRL_MASK   = 0x38,
225 		REG_PBCR_H4_CTRL_IN_OUT = 0x20, // H4 sense always cleared if set
226 		REG_PBCR_H4_CTRL_OUT_00 = 0x20, // H4 output negated
227 		REG_PBCR_H4_CTRL_OUT_01 = 0x28, // H4 output asserted
228 		REG_PBCR_H4_CTRL_OUT_10 = 0x30, // H4 output in interlocked input handshake protocol
229 		REG_PBCR_H4_CTRL_OUT_11 = 0x38, // H4 output in pulsed input handshake protocol
230 		REG_PBCR_H4_INT_ENABLE  = 0x04,
231 		REG_PBCR_H3_SVCRQ_ENABLE= 0x02,
232 		REG_PBCR_H3_STATUS_CTRL = 0x01,
233 	};
234 
235 	enum {
236 		REG_PCDR_TIN_BIT        = 2,   // BIT number
237 		REG_PCDR_TIN            = 0x04 // bit position
238 	};
239 
240 	enum {
241 		REG_PSR_H1S    = 0x01,
242 		REG_PSR_H2S    = 0x02,
243 		REG_PSR_H3S    = 0x04,
244 		REG_PSR_H4S    = 0x08,
245 		REG_PSR_H1L    = 0x10,
246 		REG_PSR_H2L    = 0x20,
247 		REG_PSR_H3L    = 0x40,
248 		REG_PSR_H4L    = 0x80,
249 	};
250 
251 	enum {
252 		REG_TCR_TIMER_ENABLE    = 0x01
253 	};
254 
255 	enum { // TCR - Timer Control register
256 		REG_TCR_ENABLE          = 0x01,
257 		REG_TCR_CC_MASK         = 0x06,
258 		REG_TCR_CC_PC2_CLK_PSC  = 0x00,
259 		REG_TCR_CC_TEN_CLK_PSC  = 0x02,
260 		REG_TCR_CC_TIN_PSC      = 0x04,
261 		REG_TCR_CC_TIN_RAW      = 0x06,
262 		REG_TCR_ZR              = 0x08,
263 		REG_TCR_ZD              = 0x10,
264 		REG_TCR_TOUT_TIACK_MASK = 0xe0, // 1 1 1
265 		REG_TCR_PC3_PC7         = 0x00, // 0 0 0
266 		REG_TCR_PC3_PC7_DC      = 0x20, // 0 0 1
267 		REG_TCR_TOUT_PC7_SQ     = 0x40, // 0 1 0
268 		REG_TCR_TOUT_PC7_SQ_DC  = 0x60, // 0 1 1
269 		REG_TCR_TOUT_TIACK      = 0x80, // 1 0 0
270 		REG_TCR_TOUT_TIACK_INT  = 0xa0, // 1 0 1
271 		REG_TCR_TOUT_PC7        = 0xc0, // 1 1 0
272 		REG_TCR_TOUT_PC7_INT    = 0xe0, // 1 1 1
273 	};
274 
275 	void tick_clock();
276 
277 	pit68230_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant);
278 
279 	// device-level overrides
280 	virtual void device_start() override;
281 	virtual void device_reset() override;
282 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
283 
284 	// Interrupt methods
285 	void trigger_interrupt(int source);
286 
287 	int m_icount;
288 
289 	devcb_write8        m_pa_out_cb;
290 	devcb_read8         m_pa_in_cb;
291 	devcb_write8        m_pb_out_cb;
292 	devcb_read8         m_pb_in_cb;
293 	devcb_write8        m_pc_out_cb;
294 	devcb_read8         m_pc_in_cb;
295 	devcb_write_line    m_h1_out_cb;
296 	devcb_write_line    m_h2_out_cb;
297 	devcb_write_line    m_h3_out_cb;
298 	devcb_write_line    m_h4_out_cb;
299 	devcb_write_line    m_tirq_out_cb;
300 	devcb_write_line    m_pirq_out_cb;
301 
302 	// registers
303 	uint8_t m_pgcr;           // Port General Control register
304 	uint8_t m_psrr;           // Port Service Request register
305 	uint8_t m_paddr;          // Port A Data Direction register
306 	uint8_t m_pbddr;          // Port B Data Direction register
307 	uint8_t m_pcddr;          // Port C Data Direction register
308 	uint8_t m_pivr;           // Ports Interrupt vector
309 	uint8_t m_pacr;           // Port A Control register
310 	uint8_t m_pbcr;           // Port B Control register
311 	uint8_t m_padr;           // Port A Data register
312 	uint8_t m_pbdr;           // Port B Data register
313 	uint8_t m_pcdr;           // Port C Data register
314 	uint8_t m_pail;           // Port A input lines
315 	uint8_t m_pbil;           // Port B input lines
316 	uint8_t m_pcil;           // Port C input lines
317 	uint8_t m_psr;            // Port Status Register
318 	uint8_t m_tcr;            // Timer Control Register
319 	uint8_t m_tivr;           // Timer Interrupt Vector register
320 	int     m_cpr;            // Counter Preload Registers (3 x 8 = 24 bits)
321 	int     m_cntr;           // - The 24 bit Counter
322 	uint8_t m_tsr;            // Timer Status Register
323 
324 
325 	// Interrupt sources
326 	enum
327 	{
328 		INT_TIMER
329 	};
330 
331 	// Timers
332 	emu_timer *pit_timer;
333 
334 	enum
335 	{
336 		TIMER_ID_PIT
337 	};
338 };
339 
340 // device type definition
341 DECLARE_DEVICE_TYPE(PIT68230, pit68230_device)
342 
343 #endif // MAME_MACHINE_68230PIT_H
344