1 // license:BSD-3-Clause
2 // copyright-holders:Ryan Holtz
3 /**********************************************************************
4 
5     Motorola 68328 ("DragonBall") System-on-a-Chip implementation
6 
7     By Ryan Holtz
8 
9 **********************************************************************/
10 
11 #include "emu.h"
12 #include "machine/mc68328.h"
13 
14 
15 #define SCR_BETO                0x80
16 #define SCR_WPV                 0x40
17 #define SCR_PRV                 0x20
18 #define SCR_BETEN               0x10
19 #define SCR_SO                  0x08
20 #define SCR_DMAP                0x04
21 #define SCR_WDTH8               0x01
22 
23 #define ICR_POL6                0x0100
24 #define ICR_POL3                0x0200
25 #define ICR_POL2                0x0400
26 #define ICR_POL1                0x0800
27 #define ICR_ET6                 0x1000
28 #define ICR_ET3                 0x2000
29 #define ICR_ET2                 0x4000
30 #define ICR_ET1                 0x8000
31 
32 #define INT_SPIM                0x000001
33 #define INT_TIMER2              0x000002
34 #define INT_UART                0x000004
35 #define INT_WDT                 0x000008
36 #define INT_RTC                 0x000010
37 #define INT_RESERVED            0x000020
38 #define INT_KB                  0x000040
39 #define INT_PWM                 0x000080
40 #define INT_INT0                0x000100
41 #define INT_INT1                0x000200
42 #define INT_INT2                0x000400
43 #define INT_INT3                0x000800
44 #define INT_INT4                0x001000
45 #define INT_INT5                0x002000
46 #define INT_INT6                0x004000
47 #define INT_INT7                0x008000
48 #define INT_KBDINTS             0x00ff00
49 #define INT_IRQ1                0x010000
50 #define INT_IRQ2                0x020000
51 #define INT_IRQ3                0x040000
52 #define INT_IRQ6                0x080000
53 #define INT_PEN                 0x100000
54 #define INT_SPIS                0x200000
55 #define INT_TIMER1              0x400000
56 #define INT_IRQ7                0x800000
57 
58 #define INT_M68K_LINE1          (INT_IRQ1)
59 #define INT_M68K_LINE2          (INT_IRQ2)
60 #define INT_M68K_LINE3          (INT_IRQ3)
61 #define INT_M68K_LINE4          (INT_INT0 | INT_INT1 | INT_INT2 | INT_INT3 | INT_INT4 | INT_INT5 | INT_INT6 | INT_INT7 | \
62 									INT_PWM | INT_KB | INT_RTC | INT_WDT | INT_UART | INT_TIMER2 | INT_SPIM)
63 #define INT_M68K_LINE5          (INT_PEN)
64 #define INT_M68K_LINE6          (INT_IRQ6 | INT_TIMER1 | INT_SPIS)
65 #define INT_M68K_LINE7          (INT_IRQ7)
66 #define INT_M68K_LINE67         (INT_M68K_LINE6 | INT_M68K_LINE7)
67 #define INT_M68K_LINE567        (INT_M68K_LINE5 | INT_M68K_LINE6 | INT_M68K_LINE7)
68 #define INT_M68K_LINE4567       (INT_M68K_LINE4 | INT_M68K_LINE5 | INT_M68K_LINE6 | INT_M68K_LINE7)
69 #define INT_M68K_LINE34567      (INT_M68K_LINE3 | INT_M68K_LINE4 | INT_M68K_LINE5 | INT_M68K_LINE6 | INT_M68K_LINE7)
70 #define INT_M68K_LINE234567     (INT_M68K_LINE2 | INT_M68K_LINE3 | INT_M68K_LINE4 | INT_M68K_LINE5 | INT_M68K_LINE6 | INT_M68K_LINE7)
71 
72 #define INT_IRQ1_SHIFT          0x000001
73 #define INT_IRQ2_SHIFT          0x000002
74 #define INT_IRQ3_SHIFT          0x000004
75 #define INT_IRQ6_SHIFT          0x000008
76 #define INT_PEN_SHIFT           0x000010
77 #define INT_SPIS_SHIFT          0x000020
78 #define INT_TIMER1_SHIFT        0x000040
79 #define INT_IRQ7_SHIFT          0x000080
80 
81 #define INT_ACTIVE              1
82 #define INT_INACTIVE            0
83 
84 #define GRPBASE_BASE_ADDR       0xfff0
85 #define GRPBASE_VALID           0x0001
86 
87 #define GRPMASK_BASE_MASK       0xfff0
88 
89 #define CSAB_COMPARE            0xff000000
90 #define CSAB_BSW                0x00010000
91 #define CSAB_MASK               0x0000ff00
92 #define CSAB_RO                 0x00000008
93 #define CSAB_WAIT               0x00000007
94 
95 #define CSCD_COMPARE            0xfff00000
96 #define CSCD_BSW                0x00010000
97 #define CSCD_MASK               0x0000fff0
98 #define CSCD_RO                 0x00000008
99 #define CSCD_WAIT               0x00000007
100 
101 #define PLLCR_PIXCLK_SEL        0x3800
102 #define PLLCR_PIXCLK_SEL_DIV2       0x0000
103 #define PLLCR_PIXCLK_SEL_DIV4       0x0800
104 #define PLLCR_PIXCLK_SEL_DIV8       0x1000
105 #define PLLCR_PIXCLK_SEL_DIV16      0x1800
106 #define PLLCR_PIXCLK_SEL_DIV1_0     0x2000
107 #define PLLCR_PIXCLK_SEL_DIV1_1     0x2800
108 #define PLLCR_PIXCLK_SEL_DIV1_2     0x3000
109 #define PLLCR_PIXCLK_SEL_DIV1_3     0x3800
110 #define PLLCR_SYSCLK_SEL        0x0700
111 #define PLLCR_SYSCLK_SEL_DIV2       0x0000
112 #define PLLCR_SYSCLK_SEL_DIV4       0x0100
113 #define PLLCR_SYSCLK_SEL_DIV8       0x0200
114 #define PLLCR_SYSCLK_SEL_DIV16      0x0300
115 #define PLLCR_SYSCLK_SEL_DIV1_0     0x0400
116 #define PLLCR_SYSCLK_SEL_DIV1_1     0x0500
117 #define PLLCR_SYSCLK_SEL_DIV1_2     0x0600
118 #define PLLCR_SYSCLK_SEL_DIV1_3     0x0700
119 #define PLLCR_CLKEN             0x0010
120 #define PLLCR_DISPLL            0x0008
121 
122 #define PLLFSR_CLK32            0x8000
123 #define PLLFSR_PROT             0x4000
124 #define PLLFSR_QCNT             0x0f00
125 #define PLLFSR_PCNT             0x00ff
126 
127 #define PCTLR_PC_EN             0x80
128 #define PCTLR_STOP              0x40
129 #define PCTLR_WIDTH             0x1f
130 
131 #define CXP_CC                  0xc000
132 #define CXP_CC_XLU                  0x0000
133 #define CXP_CC_BLACK                0x4000
134 #define CXP_CC_INVERSE              0x8000
135 #define CXP_CC_INVALID              0xc000
136 #define CXP_MASK                0x03ff
137 
138 #define CYP_MASK                0x01ff
139 
140 #define CWCH_CW                 0x1f00
141 #define CWCH_CH                 0x001f
142 
143 #define BLKC_BKEN               0x80
144 #define BLKC_BD                 0x7f
145 
146 #define LPICF_PBSIZ             0x06
147 #define LPICF_PBSIZ_1               0x00
148 #define LPICF_PBSIZ_2               0x02
149 #define LPICF_PBSIZ_4               0x04
150 #define LPICF_PBSIZ_INVALID         0x06
151 
152 #define LPOLCF_LCKPOL           0x08
153 #define LPOLCF_FLMPOL           0x04
154 #define LPOLCF_LPPOL            0x02
155 #define LPOLCF_PIXPOL           0x01
156 
157 #define LACDRC_MASK             0x0f
158 
159 #define LPXCD_MASK              0x3f
160 
161 #define LCKCON_LCDC_EN          0x80
162 #define LCKCON_LCDON            0x80
163 #define LCKCON_DMA16            0x40
164 #define LCKCON_WS               0x30
165 #define LCKCON_WS_1                 0x00
166 #define LCKCON_WS_2                 0x10
167 #define LCKCON_WS_3                 0x20
168 #define LCKCON_WS_4                 0x30
169 #define LCKCON_DWIDTH           0x02
170 #define LCKCON_PCDS             0x01
171 
172 #define LBAR_MASK               0x7f
173 
174 #define LPOSR_BOS               0x08
175 #define LPOSR_POS               0x07
176 
177 #define LFRCM_XMOD              0xf0
178 #define LFRCM_YMOD              0x0f
179 
180 #define LGPMR_PAL1              0x7000
181 #define LGPMR_PAL0              0x0700
182 #define LGPMR_PAL3              0x0070
183 #define LGPMR_PAL2              0x0007
184 
185 #define RTCHMSR_HOURS           0x1f000000
186 #define RTCHMSR_MINUTES         0x003f0000
187 #define RTCHMSR_SECONDS         0x0000003f
188 
189 #define RTCCTL_38_4             0x0020
190 #define RTCCTL_ENABLE           0x0080
191 
192 #define RTCINT_STOPWATCH        0x0001
193 #define RTCINT_MINUTE           0x0002
194 #define RTCINT_ALARM            0x0004
195 #define RTCINT_DAY              0x0008
196 #define RTCINT_SECOND           0x0010
197 
198 #define RTCSTPWTCH_MASK         0x003f
199 
200 #define TCTL_TEN                0x0001
201 #define TCTL_TEN_ENABLE             0x0001
202 #define TCTL_CLKSOURCE          0x000e
203 #define TCTL_CLKSOURCE_STOP         0x0000
204 #define TCTL_CLKSOURCE_SYSCLK       0x0002
205 #define TCTL_CLKSOURCE_SYSCLK16     0x0004
206 #define TCTL_CLKSOURCE_TIN          0x0006
207 #define TCTL_CLKSOURCE_32KHZ4       0x0008
208 #define TCTL_CLKSOURCE_32KHZ5       0x000a
209 #define TCTL_CLKSOURCE_32KHZ6       0x000c
210 #define TCTL_CLKSOURCE_32KHZ7       0x000e
211 #define TCTL_IRQEN              0x0010
212 #define TCTL_IRQEN_ENABLE           0x0010
213 #define TCTL_OM                 0x0020
214 #define TCTL_OM_ACTIVELOW           0x0000
215 #define TCTL_OM_TOGGLE              0x0020
216 #define TCTL_CAPTURE            0x00c0
217 #define TCTL_CAPTURE_NOINT          0x0000
218 #define TCTL_CAPTURE_RISING         0x0040
219 #define TCTL_CAPTURE_FALLING        0x0080
220 #define TCTL_CAPTURE_BOTH           0x00c0
221 #define TCTL_FRR                0x0100
222 #define TCTL_FRR_RESTART            0x0000
223 #define TCTL_FRR_FREERUN            0x0100
224 
225 #define TSTAT_COMP              0x0001
226 #define TSTAT_CAPT              0x0002
227 
228 #define WCTLR_WDRST             0x0008
229 #define WCTLR_LOCK              0x0004
230 #define WCTLR_FI                0x0002
231 #define WCTLR_WDEN              0x0001
232 
233 #define USTCNT_UART_EN          0x8000
234 #define USTCNT_RX_EN            0x4000
235 #define USTCNT_TX_EN            0x2000
236 #define USTCNT_RX_CLK_CONT      0x1000
237 #define USTCNT_PARITY_EN        0x0800
238 #define USTCNT_ODD_EVEN         0x0400
239 #define USTCNT_STOP_BITS        0x0200
240 #define USTCNT_8_7              0x0100
241 #define USTCNT_GPIO_DELTA_EN    0x0080
242 #define USTCNT_CTS_DELTA_EN     0x0040
243 #define USTCNT_RX_FULL_EN       0x0020
244 #define USTCNT_RX_HALF_EN       0x0010
245 #define USTCNT_RX_RDY_EN        0x0008
246 #define USTCNT_TX_EMPTY_EN      0x0004
247 #define USTCNT_TX_HALF_EN       0x0002
248 #define USTCNT_TX_AVAIL_EN      0x0001
249 
250 #define UBAUD_GPIO_DELTA        0x8000
251 #define UBAUD_GPIO              0x4000
252 #define UBAUD_GPIO_DIR          0x2000
253 #define UBAUD_GPIO_SRC          0x1000
254 #define UBAUD_BAUD_SRC          0x0800
255 #define UBAUD_DIVIDE            0x0700
256 #define UBAUD_DIVIDE_1              0x0000
257 #define UBAUD_DIVIDE_2              0x0100
258 #define UBAUD_DIVIDE_4              0x0200
259 #define UBAUD_DIVIDE_8              0x0300
260 #define UBAUD_DIVIDE_16             0x0400
261 #define UBAUD_DIVIDE_32             0x0500
262 #define UBAUD_DIVIDE_64             0x0600
263 #define UBAUD_DIVIDE_128            0x0700
264 #define UBAUD_PRESCALER         0x00ff
265 
266 #define URX_FIFO_FULL           0x8000
267 #define URX_FIFO_HALF           0x4000
268 #define URX_DATA_READY          0x2000
269 #define URX_OVRUN               0x0800
270 #define URX_FRAME_ERROR         0x0400
271 #define URX_BREAK               0x0200
272 #define URX_PARITY_ERROR        0x0100
273 
274 #define UTX_FIFO_EMPTY          0x8000
275 #define UTX_FIFO_HALF           0x4000
276 #define UTX_TX_AVAIL            0x2000
277 #define UTX_SEND_BREAK          0x1000
278 #define UTX_IGNORE_CTS          0x0800
279 #define UTX_CTS_STATUS          0x0200
280 #define UTX_CTS_DELTA           0x0100
281 
282 #define UMISC_CLK_SRC           0x4000
283 #define UMISC_FORCE_PERR        0x2000
284 #define UMISC_LOOP              0x1000
285 #define UMISC_RTS_CONT          0x0080
286 #define UMISC_RTS               0x0040
287 #define UMISC_IRDA_ENABLE       0x0020
288 #define UMISC_IRDA_LOOP         0x0010
289 
290 #define SPIS_SPIS_IRQ           0x8000
291 #define SPIS_IRQEN              0x4000
292 #define SPIS_ENPOL              0x2000
293 #define SPIS_DATA_RDY           0x1000
294 #define SPIS_OVRWR              0x0800
295 #define SPIS_PHA                0x0400
296 #define SPIS_POL                0x0200
297 #define SPIS_SPISEN             0x0100
298 
299 #define SPIM_CLOCK_COUNT        0x000f
300 #define SPIM_POL                0x0010
301 #define SPIM_POL_HIGH               0x0000
302 #define SPIM_POL_LOW                0x0010
303 #define SPIM_PHA                0x0020
304 #define SPIM_PHA_NORMAL             0x0000
305 #define SPIM_PHA_OPPOSITE           0x0020
306 #define SPIM_IRQEN              0x0040
307 #define SPIM_SPIMIRQ            0x0080
308 #define SPIM_XCH                0x0100
309 #define SPIM_XCH_IDLE               0x0000
310 #define SPIM_XCH_INIT               0x0100
311 #define SPIM_SPMEN              0x0200
312 #define SPIM_SPMEN_DISABLE          0x0000
313 #define SPIM_SPMEN_ENABLE           0x0200
314 #define SPIM_RATE               0xe000
315 #define SPIM_RATE_4                 0x0000
316 #define SPIM_RATE_8                 0x2000
317 #define SPIM_RATE_16                0x4000
318 #define SPIM_RATE_32                0x6000
319 #define SPIM_RATE_64                0x8000
320 #define SPIM_RATE_128               0xa000
321 #define SPIM_RATE_256               0xc000
322 #define SPIM_RATE_512               0xe000
323 
324 #define PWMC_PWMIRQ             0x8000
325 #define PWMC_IRQEN              0x4000
326 #define PWMC_LOAD               0x0100
327 #define PWMC_PIN                0x0080
328 #define PWMC_POL                0x0040
329 #define PWMC_PWMEN              0x0010
330 #define PWMC_CLKSEL             0x0007
331 
332 
333 #define VERBOSE_LEVEL   (0)
334 
verboselog(device_t & device,int n_level,const char * s_fmt,...)335 static inline void ATTR_PRINTF(3,4) verboselog(device_t &device, int n_level, const char *s_fmt, ...)
336 {
337 	if (VERBOSE_LEVEL >= n_level)
338 	{
339 		va_list v;
340 		char buf[32768];
341 		va_start(v, s_fmt);
342 		vsprintf(buf, s_fmt, v);
343 		va_end(v);
344 		device.logerror("%s: %s", device.machine().describe_context(), buf);
345 	}
346 }
347 
348 DEFINE_DEVICE_TYPE(MC68328, mc68328_device, "mc68328", "MC68328 DragonBall Integrated Processor")
349 
350 
internal_map(address_map & map)351 void mc68328_device::internal_map(address_map &map)
352 {
353 	map(0xfff000, 0xffffff).rw(FUNC(mc68328_device::internal_read), FUNC(mc68328_device::internal_write));
354 }
355 
cpu_space_map(address_map & map)356 void mc68328_device::cpu_space_map(address_map &map)
357 {
358 	map(0xfffff0, 0xffffff).r(FUNC(mc68328_device::irq_callback)).umask16(0x00ff);
359 }
360 
361 
mc68328_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)362 mc68328_device::mc68328_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
363 	: m68000_device(mconfig, tag, owner, clock, MC68328, 16, 24, address_map_constructor(FUNC(mc68328_device::internal_map), this))
364 	, m_rtc(nullptr), m_pwm(nullptr)
365 	, m_out_port_a_cb(*this)
366 	, m_out_port_b_cb(*this)
367 	, m_out_port_c_cb(*this)
368 	, m_out_port_d_cb(*this)
369 	, m_out_port_e_cb(*this)
370 	, m_out_port_f_cb(*this)
371 	, m_out_port_g_cb(*this)
372 	, m_out_port_j_cb(*this)
373 	, m_out_port_k_cb(*this)
374 	, m_out_port_m_cb(*this)
375 	, m_in_port_a_cb(*this)
376 	, m_in_port_b_cb(*this)
377 	, m_in_port_c_cb(*this)
378 	, m_in_port_d_cb(*this)
379 	, m_in_port_e_cb(*this)
380 	, m_in_port_f_cb(*this)
381 	, m_in_port_g_cb(*this)
382 	, m_in_port_j_cb(*this)
383 	, m_in_port_k_cb(*this)
384 	, m_in_port_m_cb(*this)
385 	, m_out_pwm_cb(*this)
386 	, m_out_spim_cb(*this)
387 	, m_in_spim_cb(*this)
388 	, m_spim_xch_trigger_cb(*this)
389 {
390 	m_cpu_space_config.m_internal_map = address_map_constructor(FUNC(mc68328_device::cpu_space_map), this);
391 }
392 
393 //-------------------------------------------------
394 //  device_resolve_objects - resolve objects that
395 //  may be needed for other devices to set
396 //  initial conditions at start time
397 //-------------------------------------------------
398 
device_resolve_objects()399 void mc68328_device::device_resolve_objects()
400 {
401 	m68000_device::device_resolve_objects();
402 
403 	m_out_port_a_cb.resolve();
404 	m_out_port_b_cb.resolve();
405 	m_out_port_c_cb.resolve();
406 	m_out_port_d_cb.resolve();
407 	m_out_port_e_cb.resolve();
408 	m_out_port_f_cb.resolve();
409 	m_out_port_g_cb.resolve();
410 	m_out_port_j_cb.resolve();
411 	m_out_port_k_cb.resolve();
412 	m_out_port_m_cb.resolve();
413 
414 	m_in_port_a_cb.resolve();
415 	m_in_port_b_cb.resolve();
416 	m_in_port_c_cb.resolve();
417 	m_in_port_d_cb.resolve();
418 	m_in_port_e_cb.resolve();
419 	m_in_port_f_cb.resolve();
420 	m_in_port_g_cb.resolve();
421 	m_in_port_j_cb.resolve();
422 	m_in_port_k_cb.resolve();
423 	m_in_port_m_cb.resolve();
424 
425 	m_out_pwm_cb.resolve();
426 
427 	m_out_spim_cb.resolve();
428 	m_in_spim_cb.resolve();
429 
430 	m_spim_xch_trigger_cb.resolve();
431 }
432 
433 //-------------------------------------------------
434 //  device_start - device-specific startup
435 //-------------------------------------------------
436 
device_start()437 void mc68328_device::device_start()
438 {
439 	m68000_device::device_start();
440 
441 	m_gptimer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68328_device::timer1_hit),this));
442 	m_gptimer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68328_device::timer2_hit),this));
443 	m_rtc = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68328_device::rtc_tick),this));
444 	m_pwm = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68328_device::pwm_transition),this));
445 
446 	register_state_save();
447 }
448 
449 //-------------------------------------------------
450 //  device_reset - device-specific reset
451 //-------------------------------------------------
452 
device_reset()453 void mc68328_device::device_reset()
454 {
455 	m68000_device::device_reset();
456 
457 	m_regs.scr = 0x0c;
458 	m_regs.grpbasea = 0x0000;
459 	m_regs.grpbaseb = 0x0000;
460 	m_regs.grpbasec = 0x0000;
461 	m_regs.grpbased = 0x0000;
462 	m_regs.grpmaska = 0x0000;
463 	m_regs.grpmaskb = 0x0000;
464 	m_regs.grpmaskc = 0x0000;
465 	m_regs.grpmaskd = 0x0000;
466 	m_regs.csa0 = 0x00010006;
467 	m_regs.csa1 = 0x00010006;
468 	m_regs.csa2 = 0x00010006;
469 	m_regs.csa3 = 0x00010006;
470 	m_regs.csb0 = 0x00010006;
471 	m_regs.csb1 = 0x00010006;
472 	m_regs.csb2 = 0x00010006;
473 	m_regs.csb3 = 0x00010006;
474 	m_regs.csc0 = 0x00010006;
475 	m_regs.csc1 = 0x00010006;
476 	m_regs.csc2 = 0x00010006;
477 	m_regs.csc3 = 0x00010006;
478 	m_regs.csd0 = 0x00010006;
479 	m_regs.csd1 = 0x00010006;
480 	m_regs.csd2 = 0x00010006;
481 	m_regs.csd3 = 0x00010006;
482 
483 	m_regs.pllcr = 0x2400;
484 	m_regs.pllfsr = 0x0123;
485 	m_regs.pctlr = 0x1f;
486 
487 	m_regs.ivr = 0x00;
488 	m_regs.icr = 0x0000;
489 	m_regs.imr = 0x00ffffff;
490 	m_regs.iwr = 0x00ffffff;
491 	m_regs.isr = 0x00000000;
492 	m_regs.ipr = 0x00000000;
493 
494 	m_regs.padir = 0x00;
495 	m_regs.padata = 0x00;
496 	m_regs.pasel = 0x00;
497 	m_regs.pbdir = 0x00;
498 	m_regs.pbdata = 0x00;
499 	m_regs.pbsel = 0x00;
500 	m_regs.pcdir = 0x00;
501 	m_regs.pcdata = 0x00;
502 	m_regs.pcsel = 0x00;
503 	m_regs.pddir = 0x00;
504 	m_regs.pddata = 0x00;
505 	m_regs.pdpuen = 0xff;
506 	m_regs.pdpol = 0x00;
507 	m_regs.pdirqen = 0x00;
508 	m_regs.pddataedge = 0x00;
509 	m_regs.pdirqedge = 0x00;
510 	m_regs.pedir = 0x00;
511 	m_regs.pedata = 0x00;
512 	m_regs.pepuen = 0x80;
513 	m_regs.pesel = 0x80;
514 	m_regs.pfdir = 0x00;
515 	m_regs.pfdata = 0x00;
516 	m_regs.pfpuen = 0xff;
517 	m_regs.pfsel = 0xff;
518 	m_regs.pgdir = 0x00;
519 	m_regs.pgdata = 0x00;
520 	m_regs.pgpuen = 0xff;
521 	m_regs.pgsel = 0xff;
522 	m_regs.pjdir = 0x00;
523 	m_regs.pjdata = 0x00;
524 	m_regs.pjsel = 0x00;
525 	m_regs.pkdir = 0x00;
526 	m_regs.pkdata = 0x00;
527 	m_regs.pkpuen = 0xff;
528 	m_regs.pksel = 0xff;
529 	m_regs.pmdir = 0x00;
530 	m_regs.pmdata = 0x00;
531 	m_regs.pmpuen = 0xff;
532 	m_regs.pmsel = 0xff;
533 
534 	m_regs.pwmc = 0x0000;
535 	m_regs.pwmp = 0x0000;
536 	m_regs.pwmw = 0x0000;
537 	m_regs.pwmcnt = 0x0000;
538 
539 	m_regs.tctl[0] = m_regs.tctl[1] = 0x0000;
540 	m_regs.tprer[0] = m_regs.tprer[1] = 0x0000;
541 	m_regs.tcmp[0] = m_regs.tcmp[1] = 0xffff;
542 	m_regs.tcr[0] = m_regs.tcr[1] = 0x0000;
543 	m_regs.tcn[0] = m_regs.tcn[1] = 0x0000;
544 	m_regs.tstat[0] = m_regs.tstat[1] = 0x0000;
545 	m_regs.wctlr = 0x0000;
546 	m_regs.wcmpr = 0xffff;
547 	m_regs.wcn = 0x0000;
548 
549 	m_regs.spisr = 0x0000;
550 
551 	m_regs.spimdata = 0x0000;
552 	m_regs.spimcont = 0x0000;
553 
554 	m_regs.ustcnt = 0x0000;
555 	m_regs.ubaud = 0x003f;
556 	m_regs.urx = 0x0000;
557 	m_regs.utx = 0x0000;
558 	m_regs.umisc = 0x0000;
559 
560 	m_regs.lssa = 0x00000000;
561 	m_regs.lvpw = 0xff;
562 	m_regs.lxmax = 0x03ff;
563 	m_regs.lymax = 0x01ff;
564 	m_regs.lcxp = 0x0000;
565 	m_regs.lcyp = 0x0000;
566 	m_regs.lcwch = 0x0101;
567 	m_regs.lblkc = 0x7f;
568 	m_regs.lpicf = 0x00;
569 	m_regs.lpolcf = 0x00;
570 	m_regs.lacdrc = 0x00;
571 	m_regs.lpxcd = 0x00;
572 	m_regs.lckcon = 0x40;
573 	m_regs.llbar = 0x3e;
574 	m_regs.lotcr = 0x3f;
575 	m_regs.lposr = 0x00;
576 	m_regs.lfrcm = 0xb9;
577 	m_regs.lgpmr = 0x1073;
578 
579 	m_regs.hmsr = 0x00000000;
580 	m_regs.alarm = 0x00000000;
581 	m_regs.rtcctl = 0x00;
582 	m_regs.rtcisr = 0x00;
583 	m_regs.rtcienr = 0x00;
584 	m_regs.stpwtch = 0x00;
585 
586 	m_rtc->adjust(attotime::from_hz(1), 0, attotime::from_hz(1));
587 }
588 
589 
set_interrupt_line(uint32_t line,uint32_t active)590 void mc68328_device::set_interrupt_line(uint32_t line, uint32_t active)
591 {
592 	if (active)
593 	{
594 		m_regs.ipr |= line;
595 
596 		if (!(m_regs.imr & line) && !(m_regs.isr & line))
597 		{
598 			m_regs.isr |= line;
599 
600 			if (m_regs.isr & INT_M68K_LINE7)
601 			{
602 				set_input_line(M68K_IRQ_7, ASSERT_LINE);
603 			}
604 			else if (m_regs.isr & INT_M68K_LINE6)
605 			{
606 				set_input_line(M68K_IRQ_6, ASSERT_LINE);
607 			}
608 			else if (m_regs.isr & INT_M68K_LINE5)
609 			{
610 				set_input_line(M68K_IRQ_5, ASSERT_LINE);
611 			}
612 			else if (m_regs.isr & INT_M68K_LINE4)
613 			{
614 				set_input_line(M68K_IRQ_4, ASSERT_LINE);
615 			}
616 			else if (m_regs.isr & INT_M68K_LINE3)
617 			{
618 				set_input_line(M68K_IRQ_3, ASSERT_LINE);
619 			}
620 			else if (m_regs.isr & INT_M68K_LINE2)
621 			{
622 				set_input_line(M68K_IRQ_2, ASSERT_LINE);
623 			}
624 			else if (m_regs.isr & INT_M68K_LINE1)
625 			{
626 				set_input_line(M68K_IRQ_1, ASSERT_LINE);
627 			}
628 		}
629 	}
630 	else
631 	{
632 		m_regs.isr &= ~line;
633 
634 		if ((line & INT_M68K_LINE7) && !(m_regs.isr & INT_M68K_LINE7))
635 		{
636 			set_input_line(M68K_IRQ_7, CLEAR_LINE);
637 		}
638 		if ((line & INT_M68K_LINE6) && !(m_regs.isr & INT_M68K_LINE6))
639 		{
640 			set_input_line(M68K_IRQ_6, CLEAR_LINE);
641 		}
642 		if ((line & INT_M68K_LINE5) && !(m_regs.isr & INT_M68K_LINE5))
643 		{
644 			set_input_line(M68K_IRQ_5, CLEAR_LINE);
645 		}
646 		if ((line & INT_M68K_LINE4) && !(m_regs.isr & INT_M68K_LINE4))
647 		{
648 			set_input_line(M68K_IRQ_4, CLEAR_LINE);
649 		}
650 		if ((line & INT_M68K_LINE3) && !(m_regs.isr & INT_M68K_LINE3))
651 		{
652 			set_input_line(M68K_IRQ_3, CLEAR_LINE);
653 		}
654 		if ((line & INT_M68K_LINE2) && !(m_regs.isr & INT_M68K_LINE2))
655 		{
656 			set_input_line(M68K_IRQ_2, CLEAR_LINE);
657 		}
658 		if ((line & INT_M68K_LINE1) && !(m_regs.isr & INT_M68K_LINE1))
659 		{
660 			set_input_line(M68K_IRQ_1, CLEAR_LINE);
661 		}
662 	}
663 }
664 
poll_port_d_interrupts()665 void mc68328_device::poll_port_d_interrupts()
666 {
667 	uint8_t line_transitions = m_regs.pddataedge & m_regs.pdirqedge;
668 	uint8_t line_holds = m_regs.pddata &~ m_regs.pdirqedge;
669 	uint8_t line_interrupts = (line_transitions | line_holds) & m_regs.pdirqen;
670 
671 	if (line_interrupts)
672 	{
673 		set_interrupt_line(line_interrupts << 8, 1);
674 	}
675 	else
676 	{
677 		set_interrupt_line(INT_KBDINTS, 0);
678 	}
679 }
680 
WRITE_LINE_MEMBER(mc68328_device::set_penirq_line)681 WRITE_LINE_MEMBER( mc68328_device::set_penirq_line )
682 {
683 	if (state)
684 	{
685 		set_interrupt_line(INT_PEN, 1);
686 	}
687 	else
688 	{
689 		m_regs.ipr &= ~INT_PEN;
690 		set_interrupt_line(INT_PEN, 0);
691 	}
692 }
693 
set_port_d_lines(uint8_t state,int bit)694 void mc68328_device::set_port_d_lines(uint8_t state, int bit)
695 {
696 	uint8_t old_button_state = m_regs.pddata;
697 
698 	if (state & (1 << bit))
699 	{
700 		m_regs.pddata |= (1 << bit);
701 	}
702 	else
703 	{
704 		m_regs.pddata &= ~(1 << bit);
705 	}
706 
707 	m_regs.pddataedge |= ~old_button_state & m_regs.pddata;
708 
709 	poll_port_d_interrupts();
710 }
711 
irq_callback(offs_t offset)712 uint8_t mc68328_device::irq_callback(offs_t offset)
713 {
714 	return m_regs.ivr | offset;
715 }
716 
get_timer_frequency(uint32_t index)717 uint32_t mc68328_device::get_timer_frequency(uint32_t index)
718 {
719 	uint32_t frequency = 0;
720 
721 	switch (m_regs.tctl[index] & TCTL_CLKSOURCE)
722 	{
723 		case TCTL_CLKSOURCE_SYSCLK:
724 			frequency = 32768 * 506;
725 			break;
726 
727 		case TCTL_CLKSOURCE_SYSCLK16:
728 			frequency = (32768 * 506) / 16;
729 			break;
730 
731 		case TCTL_CLKSOURCE_32KHZ4:
732 		case TCTL_CLKSOURCE_32KHZ5:
733 		case TCTL_CLKSOURCE_32KHZ6:
734 		case TCTL_CLKSOURCE_32KHZ7:
735 			frequency = 32768;
736 			break;
737 	}
738 	frequency /= (m_regs.tprer[index] + 1);
739 
740 	return frequency;
741 }
742 
maybe_start_timer(uint32_t index,uint32_t new_enable)743 void mc68328_device::maybe_start_timer(uint32_t index, uint32_t new_enable)
744 {
745 	if ((m_regs.tctl[index] & TCTL_TEN) == TCTL_TEN_ENABLE && (m_regs.tctl[index] & TCTL_CLKSOURCE) > TCTL_CLKSOURCE_STOP)
746 	{
747 		if ((m_regs.tctl[index] & TCTL_CLKSOURCE) == TCTL_CLKSOURCE_TIN)
748 		{
749 			m_gptimer[index]->adjust(attotime::never);
750 		}
751 		else if (m_regs.tcmp[index] == 0)
752 		{
753 			m_gptimer[index]->adjust(attotime::never);
754 		}
755 		else
756 		{
757 			uint32_t frequency = get_timer_frequency(index);
758 			attotime period = (attotime::from_hz(frequency) *  m_regs.tcmp[index]);
759 
760 			if (new_enable)
761 			{
762 				m_regs.tcn[index] = 0x0000;
763 			}
764 
765 			m_gptimer[index]->adjust(period);
766 		}
767 	}
768 	else
769 	{
770 		m_gptimer[index]->adjust(attotime::never);
771 	}
772 }
773 
timer_compare_event(uint32_t index)774 void mc68328_device::timer_compare_event(uint32_t index)
775 {
776 	m_regs.tcn[index] = m_regs.tcmp[index];
777 	m_regs.tstat[index] |= TSTAT_COMP;
778 
779 	if ((m_regs.tctl[index] & TCTL_FRR) == TCTL_FRR_RESTART)
780 	{
781 		uint32_t frequency = get_timer_frequency(index);
782 
783 		if (frequency > 0)
784 		{
785 			attotime period = attotime::from_hz(frequency) * m_regs.tcmp[index];
786 
787 			m_regs.tcn[index] = 0x0000;
788 
789 			m_gptimer[index]->adjust(period);
790 		}
791 		else
792 		{
793 			m_gptimer[index]->adjust(attotime::never);
794 		}
795 	}
796 	else
797 	{
798 		uint32_t frequency = get_timer_frequency(index);
799 
800 		if (frequency > 0)
801 		{
802 			attotime period = attotime::from_hz(frequency) * 0x10000;
803 
804 			m_gptimer[index]->adjust(period);
805 		}
806 		else
807 		{
808 			m_gptimer[index]->adjust(attotime::never);
809 		}
810 	}
811 	if ((m_regs.tctl[index] & TCTL_IRQEN) == TCTL_IRQEN_ENABLE)
812 	{
813 		set_interrupt_line((index == 0) ? INT_TIMER1 : INT_TIMER2, 1);
814 	}
815 }
816 
TIMER_CALLBACK_MEMBER(mc68328_device::timer1_hit)817 TIMER_CALLBACK_MEMBER( mc68328_device::timer1_hit )
818 {
819 	timer_compare_event(0);
820 }
821 
TIMER_CALLBACK_MEMBER(mc68328_device::timer2_hit)822 TIMER_CALLBACK_MEMBER( mc68328_device::timer2_hit )
823 {
824 	timer_compare_event(1);
825 }
826 
TIMER_CALLBACK_MEMBER(mc68328_device::pwm_transition)827 TIMER_CALLBACK_MEMBER( mc68328_device::pwm_transition )
828 {
829 	if (m_regs.pwmw >= m_regs.pwmp || m_regs.pwmw == 0 || m_regs.pwmp == 0)
830 	{
831 		m_pwm->adjust(attotime::never);
832 		return;
833 	}
834 
835 	if (((m_regs.pwmc & PWMC_POL) == 0 && (m_regs.pwmc & PWMC_PIN) != 0) ||
836 		((m_regs.pwmc & PWMC_POL) != 0 && (m_regs.pwmc & PWMC_PIN) == 0))
837 	{
838 		uint32_t frequency = 32768 * 506;
839 		uint32_t divisor = 4 << (m_regs.pwmc & PWMC_CLKSEL); // ?? Datasheet says 2 <<, but then we're an octave higher than CoPilot.
840 		attotime period;
841 
842 		frequency /= divisor;
843 		period = attotime::from_hz(frequency) * (m_regs.pwmp - m_regs.pwmw);
844 
845 		m_pwm->adjust(period);
846 
847 		if (m_regs.pwmc & PWMC_IRQEN)
848 		{
849 			set_interrupt_line(INT_PWM, 1);
850 		}
851 	}
852 	else
853 	{
854 		uint32_t frequency = 32768 * 506;
855 		uint32_t divisor = 4 << (m_regs.pwmc & PWMC_CLKSEL); // ?? Datasheet says 2 <<, but then we're an octave higher than CoPilot.
856 		attotime period;
857 
858 		frequency /= divisor;
859 		period = attotime::from_hz(frequency) * m_regs.pwmw;
860 
861 		m_pwm->adjust(period);
862 	}
863 
864 	m_regs.pwmc ^= PWMC_PIN;
865 
866 	if (!m_out_pwm_cb.isnull())
867 	{
868 		m_out_pwm_cb((offs_t)0, (m_regs.pwmc & PWMC_PIN) ? 1 : 0);
869 	}
870 }
871 
TIMER_CALLBACK_MEMBER(mc68328_device::rtc_tick)872 TIMER_CALLBACK_MEMBER( mc68328_device::rtc_tick )
873 {
874 	if (m_regs.rtcctl & RTCCTL_ENABLE)
875 	{
876 		uint32_t set_int = 0;
877 
878 		m_regs.hmsr++;
879 
880 		if (m_regs.rtcienr & RTCINT_SECOND)
881 		{
882 			set_int = 1;
883 			m_regs.rtcisr |= RTCINT_SECOND;
884 		}
885 
886 		if ((m_regs.hmsr & 0x0000003f) == 0x0000003c)
887 		{
888 			m_regs.hmsr &= 0xffffffc0;
889 			m_regs.hmsr += 0x00010000;
890 
891 			if (m_regs.rtcienr & RTCINT_MINUTE)
892 			{
893 				set_int = 1;
894 				m_regs.rtcisr |= RTCINT_MINUTE;
895 			}
896 
897 			if ((m_regs.hmsr & 0x003f0000) == 0x003c0000)
898 			{
899 				m_regs.hmsr &= 0xffc0ffff;
900 				m_regs.hmsr += 0x0100000;
901 
902 				if ((m_regs.hmsr & 0x1f000000) == 0x18000000)
903 				{
904 					m_regs.hmsr &= 0xe0ffffff;
905 
906 					if (m_regs.rtcienr & RTCINT_DAY)
907 					{
908 						set_int = 1;
909 						m_regs.rtcisr |= RTCINT_DAY;
910 					}
911 				}
912 			}
913 
914 			if (m_regs.stpwtch != 0x003f)
915 			{
916 				m_regs.stpwtch--;
917 				m_regs.stpwtch &= 0x003f;
918 
919 				if (m_regs.stpwtch == 0x003f)
920 				{
921 					if (m_regs.rtcienr & RTCINT_STOPWATCH)
922 					{
923 						set_int = 1;
924 						m_regs.rtcisr |= RTCINT_STOPWATCH;
925 					}
926 				}
927 			}
928 		}
929 
930 		if (m_regs.hmsr == m_regs.alarm)
931 		{
932 			if (m_regs.rtcienr & RTCINT_ALARM)
933 			{
934 				set_int = 1;
935 				m_regs.rtcisr |= RTCINT_STOPWATCH;
936 			}
937 		}
938 
939 		if (set_int)
940 		{
941 			set_interrupt_line(INT_RTC, 1);
942 		}
943 		else
944 		{
945 			set_interrupt_line(INT_RTC, 0);
946 		}
947 	}
948 }
949 
internal_write(offs_t offset,uint16_t data,uint16_t mem_mask)950 void mc68328_device::internal_write(offs_t offset, uint16_t data, uint16_t mem_mask)
951 {
952 	uint32_t address = offset << 1;
953 	uint16_t temp16[4] = { 0 };
954 	uint32_t imr_old = m_regs.imr, imr_diff;
955 
956 	switch (address)
957 	{
958 		case 0x000:
959 			if (mem_mask & 0x00ff)
960 			{
961 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfff001) = %02x\n", data & 0x00ff);
962 			}
963 			else
964 			{
965 				verboselog( *this, 2, "mc68328_w: SCR = %02x\n", (data >> 8) & 0x00ff);
966 			}
967 			break;
968 
969 		case 0x100:
970 			verboselog( *this, 2, "mc68328_w: GRPBASEA = %04x\n", data);
971 			m_regs.grpbasea = data;
972 			break;
973 
974 		case 0x102:
975 			verboselog( *this, 2, "mc68328_w: GRPBASEB = %04x\n", data);
976 			m_regs.grpbaseb = data;
977 			break;
978 
979 		case 0x104:
980 			verboselog( *this, 2, "mc68328_w: GRPBASEC = %04x\n", data);
981 			m_regs.grpbasec = data;
982 			break;
983 
984 		case 0x106:
985 			verboselog( *this, 2, "mc68328_w: GRPBASED = %04x\n", data);
986 			m_regs.grpbased = data;
987 			break;
988 
989 		case 0x108:
990 			verboselog( *this, 2, "mc68328_w: GRPMASKA = %04x\n", data);
991 			m_regs.grpmaska = data;
992 			break;
993 
994 		case 0x10a:
995 			verboselog( *this, 2, "mc68328_w: GRPMASKB = %04x\n", data);
996 			m_regs.grpmaskb = data;
997 			break;
998 
999 		case 0x10c:
1000 			verboselog( *this, 2, "mc68328_w: GRPMASKC = %04x\n", data);
1001 			m_regs.grpmaskc = data;
1002 			break;
1003 
1004 		case 0x10e:
1005 			verboselog( *this, 2, "mc68328_w: GRPMASKD = %04x\n", data);
1006 			m_regs.grpmaskd = data;
1007 			break;
1008 
1009 		case 0x110:
1010 			verboselog( *this, 5, "mc68328_w: CSA0(0) = %04x\n", data);
1011 			m_regs.csa0 &= 0xffff0000 | (~mem_mask);
1012 			m_regs.csa0 |= data & mem_mask;
1013 			break;
1014 
1015 		case 0x112:
1016 			verboselog( *this, 5, "mc68328_w: CSA0(16) = %04x\n", data);
1017 			m_regs.csa0 &= ~(mem_mask << 16);
1018 			m_regs.csa0 |= (data & mem_mask) << 16;
1019 			break;
1020 
1021 		case 0x114:
1022 			verboselog( *this, 5, "mc68328_w: CSA1(0) = %04x\n", data);
1023 			m_regs.csa1 &= 0xffff0000 | (~mem_mask);
1024 			m_regs.csa1 |= data & mem_mask;
1025 			break;
1026 
1027 		case 0x116:
1028 			verboselog( *this, 5, "mc68328_w: CSA1(16) = %04x\n", data);
1029 			m_regs.csa1 &= ~(mem_mask << 16);
1030 			m_regs.csa1 |= (data & mem_mask) << 16;
1031 			break;
1032 
1033 		case 0x118:
1034 			verboselog( *this, 5, "mc68328_w: CSA2(0) = %04x\n", data);
1035 			m_regs.csa2 &= 0xffff0000 | (~mem_mask);
1036 			m_regs.csa2 |= data & mem_mask;
1037 			break;
1038 
1039 		case 0x11a:
1040 			verboselog( *this, 5, "mc68328_w: CSA2(16) = %04x\n", data);
1041 			m_regs.csa2 &= ~(mem_mask << 16);
1042 			m_regs.csa2 |= (data & mem_mask) << 16;
1043 			break;
1044 
1045 		case 0x11c:
1046 			verboselog( *this, 5, "mc68328_w: CSA3(0) = %04x\n", data);
1047 			m_regs.csa3 &= 0xffff0000 | (~mem_mask);
1048 			m_regs.csa3 |= data & mem_mask;
1049 			break;
1050 
1051 		case 0x11e:
1052 			verboselog( *this, 5, "mc68328_w: CSA3(16) = %04x\n", data);
1053 			m_regs.csa3 &= ~(mem_mask << 16);
1054 			m_regs.csa3 |= (data & mem_mask) << 16;
1055 			break;
1056 
1057 		case 0x120:
1058 			verboselog( *this, 5, "mc68328_w: CSB0(0) = %04x\n", data);
1059 			m_regs.csb0 &= 0xffff0000 | (~mem_mask);
1060 			m_regs.csb0 |= data & mem_mask;
1061 			break;
1062 
1063 		case 0x122:
1064 			verboselog( *this, 5, "mc68328_w: CSB0(16) = %04x\n", data);
1065 			m_regs.csb0 &= ~(mem_mask << 16);
1066 			m_regs.csb0 |= (data & mem_mask) << 16;
1067 			break;
1068 
1069 		case 0x124:
1070 			verboselog( *this, 5, "mc68328_w: CSB1(0) = %04x\n", data);
1071 			m_regs.csb1 &= 0xffff0000 | (~mem_mask);
1072 			m_regs.csb1 |= data & mem_mask;
1073 			break;
1074 
1075 		case 0x126:
1076 			verboselog( *this, 5, "mc68328_w: CSB1(16) = %04x\n", data);
1077 			m_regs.csb1 &= ~(mem_mask << 16);
1078 			m_regs.csb1 |= (data & mem_mask) << 16;
1079 			break;
1080 
1081 		case 0x128:
1082 			verboselog( *this, 5, "mc68328_w: CSB2(0) = %04x\n", data);
1083 			m_regs.csb2 &= 0xffff0000 | (~mem_mask);
1084 			m_regs.csb2 |= data & mem_mask;
1085 			break;
1086 
1087 		case 0x12a:
1088 			verboselog( *this, 5, "mc68328_w: CSB2(16) = %04x\n", data);
1089 			m_regs.csb2 &= ~(mem_mask << 16);
1090 			m_regs.csb2 |= (data & mem_mask) << 16;
1091 			break;
1092 
1093 		case 0x12c:
1094 			verboselog( *this, 5, "mc68328_w: CSB3(0) = %04x\n", data);
1095 			m_regs.csb3 &= 0xffff0000 | (~mem_mask);
1096 			m_regs.csb3 |= data & mem_mask;
1097 			break;
1098 
1099 		case 0x12e:
1100 			verboselog( *this, 5, "mc68328_w: CSB3(16) = %04x\n", data);
1101 			m_regs.csb3 &= ~(mem_mask << 16);
1102 			m_regs.csb3 |= (data & mem_mask) << 16;
1103 			break;
1104 
1105 		case 0x130:
1106 			verboselog( *this, 5, "mc68328_w: CSC0(0) = %04x\n", data);
1107 			m_regs.csc0 &= 0xffff0000 | (~mem_mask);
1108 			m_regs.csc0 |= data & mem_mask;
1109 			break;
1110 
1111 		case 0x132:
1112 			verboselog( *this, 5, "mc68328_w: CSC0(16) = %04x\n", data);
1113 			m_regs.csc0 &= ~(mem_mask << 16);
1114 			m_regs.csc0 |= (data & mem_mask) << 16;
1115 			break;
1116 
1117 		case 0x134:
1118 			verboselog( *this, 5, "mc68328_w: CSC1(0) = %04x\n", data);
1119 			m_regs.csc1 &= 0xffff0000 | (~mem_mask);
1120 			m_regs.csc1 |= data & mem_mask;
1121 			break;
1122 
1123 		case 0x136:
1124 			verboselog( *this, 5, "mc68328_w: CSC1(16) = %04x\n", data);
1125 			m_regs.csc1 &= ~(mem_mask << 16);
1126 			m_regs.csc1 |= (data & mem_mask) << 16;
1127 			break;
1128 
1129 		case 0x138:
1130 			verboselog( *this, 5, "mc68328_w: CSC2(0) = %04x\n", data);
1131 			m_regs.csc2 &= 0xffff0000 | (~mem_mask);
1132 			m_regs.csc2 |= data & mem_mask;
1133 			break;
1134 
1135 		case 0x13a:
1136 			verboselog( *this, 5, "mc68328_w: CSC2(16) = %04x\n", data);
1137 			m_regs.csc2 &= ~(mem_mask << 16);
1138 			m_regs.csc2 |= (data & mem_mask) << 16;
1139 			break;
1140 
1141 		case 0x13c:
1142 			verboselog( *this, 5, "mc68328_w: CSC3(0) = %04x\n", data);
1143 			m_regs.csc3 &= 0xffff0000 | (~mem_mask);
1144 			m_regs.csc3 |= data & mem_mask;
1145 			break;
1146 
1147 		case 0x13e:
1148 			verboselog( *this, 5, "mc68328_w: CSC3(16) = %04x\n", data);
1149 			m_regs.csc3 &= ~(mem_mask << 16);
1150 			m_regs.csc3 |= (data & mem_mask) << 16;
1151 			break;
1152 
1153 		case 0x140:
1154 			verboselog( *this, 5, "mc68328_w: CSD0(0) = %04x\n", data);
1155 			m_regs.csd0 &= 0xffff0000 | (~mem_mask);
1156 			m_regs.csd0 |= data & mem_mask;
1157 			break;
1158 
1159 		case 0x142:
1160 			verboselog( *this, 5, "mc68328_w: CSD0(16) = %04x\n", data);
1161 			m_regs.csd0 &= ~(mem_mask << 16);
1162 			m_regs.csd0 |= (data & mem_mask) << 16;
1163 			break;
1164 
1165 		case 0x144:
1166 			verboselog( *this, 5, "mc68328_w: CSD1(0) = %04x\n", data);
1167 			m_regs.csd1 &= 0xffff0000 | (~mem_mask);
1168 			m_regs.csd1 |= data & mem_mask;
1169 			break;
1170 
1171 		case 0x146:
1172 			verboselog( *this, 5, "mc68328_w: CSD1(16) = %04x\n", data);
1173 			m_regs.csd1 &= ~(mem_mask << 16);
1174 			m_regs.csd1 |= (data & mem_mask) << 16;
1175 			break;
1176 
1177 		case 0x148:
1178 			verboselog( *this, 5, "mc68328_w: CSD2(0) = %04x\n", data);
1179 			m_regs.csd2 &= 0xffff0000 | (~mem_mask);
1180 			m_regs.csd2 |= data & mem_mask;
1181 			break;
1182 
1183 		case 0x14a:
1184 			verboselog( *this, 5, "mc68328_w: CSD2(16) = %04x\n", data);
1185 			m_regs.csd2 &= ~(mem_mask << 16);
1186 			m_regs.csd2 |= (data & mem_mask) << 16;
1187 			break;
1188 
1189 		case 0x14c:
1190 			verboselog( *this, 5, "mc68328_w: CSD3(0) = %04x\n", data);
1191 			m_regs.csd3 &= 0xffff0000 | (~mem_mask);
1192 			m_regs.csd3 |= data & mem_mask;
1193 			break;
1194 
1195 		case 0x14e:
1196 			verboselog( *this, 5, "mc68328_w: CSD3(16) = %04x\n", data);
1197 			m_regs.csd3 &= ~(mem_mask << 16);
1198 			m_regs.csd3 |= (data & mem_mask) << 16;
1199 			break;
1200 
1201 		case 0x200:
1202 			verboselog( *this, 2, "mc68328_w: PLLCR = %04x\n", data);
1203 			m_regs.pllcr = data;
1204 			break;
1205 
1206 		case 0x202:
1207 			verboselog( *this, 2, "mc68328_w: PLLFSR = %04x\n", data);
1208 			m_regs.pllfsr = data;
1209 			break;
1210 
1211 		case 0x206:
1212 			if (mem_mask & 0x00ff)
1213 			{
1214 				verboselog( *this, 2, "mc68328_w: PCTLR = %02x\n", data & 0x00ff);
1215 				m_regs.pctlr = data & 0x00ff;
1216 			}
1217 			else
1218 			{
1219 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfff206) = %02x\n", (data >> 8) & 0x00ff);
1220 			}
1221 			break;
1222 
1223 		case 0x300:
1224 			if (mem_mask & 0x00ff)
1225 			{
1226 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfff301) = %02x\n", data & 0x00ff);
1227 			}
1228 			else
1229 			{
1230 				verboselog( *this, 2, "mc68328_w: IVR = %02x\n", (data >> 8) & 0x00f8);
1231 				m_regs.ivr = (data >> 8) & 0x00f8;
1232 			}
1233 			break;
1234 
1235 		case 0x302:
1236 			verboselog( *this, 2, "mc68328_w: ICR = %04x\n", data);
1237 			m_regs.icr = data;
1238 			break;
1239 
1240 		case 0x304:
1241 			verboselog( *this, 2, "mc68328_w: IMR(16) = %04x\n", data);
1242 			m_regs.imr &= ~(mem_mask << 16);
1243 			m_regs.imr |= (data & mem_mask) << 16;
1244 			m_regs.isr &= ~((data & mem_mask) << 16);
1245 
1246 			imr_diff = imr_old ^ m_regs.imr;
1247 			set_interrupt_line(imr_diff, 0);
1248 			break;
1249 
1250 		case 0x306:
1251 			verboselog( *this, 2, "mc68328_w: IMR(0) = %04x\n", data);
1252 			m_regs.imr &= 0xffff0000 | (~mem_mask);
1253 			m_regs.imr |= data & mem_mask;
1254 			m_regs.isr &= ~(data & mem_mask);
1255 
1256 			imr_diff = imr_old ^ m_regs.imr;
1257 			set_interrupt_line(imr_diff, 0);
1258 			break;
1259 
1260 		case 0x308:
1261 			verboselog( *this, 2, "mc68328_w: IWR(16) = %04x\n", data);
1262 			m_regs.iwr &= ~(mem_mask << 16);
1263 			m_regs.iwr |= (data & mem_mask) << 16;
1264 			break;
1265 
1266 		case 0x30a:
1267 			verboselog( *this, 2, "mc68328_w: IWR(0) = %04x\n", data);
1268 			m_regs.iwr &= 0xffff0000 | (~mem_mask);
1269 			m_regs.iwr |= data & mem_mask;
1270 			break;
1271 
1272 		case 0x30c:
1273 			verboselog( *this, 2, "mc68328_w: ISR(16) = %04x\n", data);
1274 			// Clear edge-triggered IRQ1
1275 			if ((m_regs.icr & ICR_ET1) == ICR_ET1 && (data & INT_IRQ1_SHIFT) == INT_IRQ1_SHIFT)
1276 			{
1277 				m_regs.isr &= ~INT_IRQ1;
1278 			}
1279 
1280 			// Clear edge-triggered IRQ2
1281 			if ((m_regs.icr & ICR_ET2) == ICR_ET2 && (data & INT_IRQ2_SHIFT) == INT_IRQ2_SHIFT)
1282 			{
1283 				m_regs.isr &= ~INT_IRQ2;
1284 			}
1285 
1286 			// Clear edge-triggered IRQ3
1287 			if ((m_regs.icr & ICR_ET3) == ICR_ET3 && (data & INT_IRQ3_SHIFT) == INT_IRQ3_SHIFT)
1288 			{
1289 				m_regs.isr &= ~INT_IRQ3;
1290 			}
1291 
1292 			// Clear edge-triggered IRQ6
1293 			if ((m_regs.icr & ICR_ET6) == ICR_ET6 && (data & INT_IRQ6_SHIFT) == INT_IRQ6_SHIFT)
1294 			{
1295 				m_regs.isr &= ~INT_IRQ6;
1296 			}
1297 
1298 			// Clear edge-triggered IRQ7
1299 			if ((data & INT_IRQ7_SHIFT) == INT_IRQ7_SHIFT)
1300 			{
1301 				m_regs.isr &= ~INT_IRQ7;
1302 			}
1303 			break;
1304 
1305 		case 0x30e:
1306 			verboselog( *this, 2, "mc68328_w: ISR(0) = %04x (Ignored)\n", data);
1307 			break;
1308 
1309 		case 0x310:
1310 			verboselog( *this, 2, "mc68328_w: IPR(16) = %04x (Ignored)\n", data);
1311 			break;
1312 
1313 		case 0x312:
1314 			verboselog( *this, 2, "mc68328_w: IPR(0) = %04x (Ignored)\n", data);
1315 			break;
1316 
1317 		case 0x400:
1318 			if (mem_mask & 0x00ff)
1319 			{
1320 				verboselog( *this, 2, "mc68328_w: PADATA = %02x\n", data & 0x00ff);
1321 				m_regs.padata = data & 0x00ff;
1322 				if (!m_out_port_a_cb.isnull())
1323 				{
1324 					m_out_port_a_cb((offs_t)0, data & 0x00ff);
1325 				}
1326 			}
1327 			else
1328 			{
1329 				verboselog( *this, 2, "mc68328_w: PADIR = %02x\n", (data >> 8) & 0x00ff);
1330 				m_regs.padir = (data >> 8) & 0x00ff;
1331 			}
1332 			break;
1333 
1334 		case 0x402:
1335 			if (mem_mask & 0x00ff)
1336 			{
1337 				verboselog( *this, 2, "mc68328_w: PASEL = %02x\n", data & 0x00ff);
1338 				m_regs.pasel = data & 0x00ff;
1339 			}
1340 			else
1341 			{
1342 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfff402) = %02x\n", (data >> 8) & 0x00ff);
1343 			}
1344 			break;
1345 
1346 		case 0x408:
1347 			if (mem_mask & 0x00ff)
1348 			{
1349 				verboselog( *this, 2, "mc68328_w: PBDATA = %02x\n", data & 0x00ff);
1350 				m_regs.pbdata = data & 0x00ff;
1351 				if (!m_out_port_b_cb.isnull())
1352 				{
1353 					m_out_port_b_cb((offs_t)0, data & 0x00ff);
1354 				}
1355 			}
1356 			else
1357 			{
1358 				verboselog( *this, 2, "mc68328_w: PBDIR = %02x\n", (data >> 8) & 0x00ff);
1359 				m_regs.pbdir = (data >> 8) & 0x00ff;
1360 			}
1361 			break;
1362 
1363 		case 0x40a:
1364 			if (mem_mask & 0x00ff)
1365 			{
1366 				verboselog( *this, 2, "mc68328_w: PBSEL = %02x\n", data & 0x00ff);
1367 				m_regs.pbsel = data & 0x00ff;
1368 			}
1369 			else
1370 			{
1371 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfff40a) = %02x\n", (data >> 8) & 0x00ff);
1372 			}
1373 			break;
1374 
1375 		case 0x410:
1376 			if (mem_mask & 0x00ff)
1377 			{
1378 				verboselog( *this, 2, "mc68328_w: PCDATA = %02x\n", data & 0x00ff);
1379 				m_regs.pcdata = data & 0x00ff;
1380 				if (!m_out_port_c_cb.isnull())
1381 				{
1382 					m_out_port_c_cb((offs_t)0, data & 0x00ff);
1383 				}
1384 			}
1385 			else
1386 			{
1387 				verboselog( *this, 2, "mc68328_w: PCDIR = %02x\n", (data >> 8) & 0x00ff);
1388 				m_regs.pcdir = (data >> 8) & 0x00ff;
1389 			}
1390 			break;
1391 
1392 		case 0x412:
1393 			if (mem_mask & 0x00ff)
1394 			{
1395 				verboselog( *this, 2, "mc68328_w: PCSEL = %02x\n", data & 0x00ff);
1396 				m_regs.pcsel = data & 0x00ff;
1397 			}
1398 			else
1399 			{
1400 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfff412) = %02x\n", (data >> 8) & 0x00ff);
1401 			}
1402 			break;
1403 
1404 		case 0x418:
1405 			if (mem_mask & 0x00ff)
1406 			{
1407 				verboselog( *this, 2, "mc68328_w: PDDATA = %02x\n", data & 0x00ff);
1408 
1409 				m_regs.pddataedge &= ~(data & 0x00ff);
1410 				poll_port_d_interrupts();
1411 			}
1412 			else
1413 			{
1414 				verboselog( *this, 2, "mc68328_w: PDDIR = %02x\n", (data >> 8) & 0x00ff);
1415 				m_regs.pddir = (data >> 8) & 0x00ff;
1416 			}
1417 			break;
1418 
1419 		case 0x41a:
1420 			if (mem_mask & 0x00ff)
1421 			{
1422 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfff41b) = %02x\n", data & 0x00ff);
1423 			}
1424 			else
1425 			{
1426 				verboselog( *this, 2, "mc68328_w: PDPUEN = %02x\n", (data >> 8) & 0x00ff);
1427 				m_regs.pdpuen = (data >> 8) & 0x00ff;
1428 			}
1429 			break;
1430 
1431 		case 0x41c:
1432 			if (mem_mask & 0x00ff)
1433 			{
1434 				verboselog( *this, 2, "mc68328_w: PDIRQEN = %02x\n", data & 0x00ff);
1435 				m_regs.pdirqen = data & 0x00ff;
1436 
1437 				poll_port_d_interrupts();
1438 			}
1439 			else
1440 			{
1441 				verboselog( *this, 2, "mc68328_w: PDPOL = %02x\n", (data >> 8) & 0x00ff);
1442 				m_regs.pdpol = (data >> 8) & 0x00ff;
1443 			}
1444 			break;
1445 
1446 		case 0x41e:
1447 			if (mem_mask & 0x00ff)
1448 			{
1449 				verboselog( *this, 2, "mc68328_w: PDIRQEDGE = %02x\n", data & 0x00ff);
1450 				m_regs.pdirqedge = data & 0x00ff;
1451 			}
1452 			else
1453 			{
1454 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfff41e) = %02x\n", (data >> 8) & 0x00ff);
1455 			}
1456 			break;
1457 
1458 		case 0x420:
1459 			if (mem_mask & 0x00ff)
1460 			{
1461 				verboselog( *this, 2, "mc68328_w: PEDATA = %02x\n", data & 0x00ff);
1462 				m_regs.pedata = data & 0x00ff;
1463 				if (!m_out_port_e_cb.isnull())
1464 				{
1465 					m_out_port_e_cb((offs_t)0, data & 0x00ff);
1466 				}
1467 			}
1468 			else
1469 			{
1470 				verboselog( *this, 2, "mc68328_w: PEDIR = %02x\n", (data >> 8) & 0x00ff);
1471 				m_regs.pedir = (data >> 8) & 0x00ff;
1472 			}
1473 			break;
1474 
1475 		case 0x422:
1476 			if (mem_mask & 0x00ff)
1477 			{
1478 				verboselog( *this, 2, "mc68328_w: PESEL = %02x\n", data & 0x00ff);
1479 				m_regs.pesel = data & 0x00ff;
1480 			}
1481 			else
1482 			{
1483 				verboselog( *this, 2, "mc68328_w: PEPUEN = %02x\n", (data >> 8) & 0x00ff);
1484 				m_regs.pepuen = (data >> 8) & 0x00ff;
1485 				m_regs.pedata |= m_regs.pepuen;
1486 			}
1487 			break;
1488 
1489 		case 0x428:
1490 			if (mem_mask & 0x00ff)
1491 			{
1492 				verboselog( *this, 2, "mc68328_w: PFDATA = %02x\n", data & 0x00ff);
1493 				m_regs.pfdata = data & 0x00ff;
1494 				if (!m_out_port_f_cb.isnull())
1495 				{
1496 					m_out_port_f_cb((offs_t)0, data & 0x00ff);
1497 				}
1498 			}
1499 			else
1500 			{
1501 				verboselog( *this, 2, "mc68328_w: PFDIR = %02x\n", (data >> 8) & 0x00ff);
1502 				m_regs.pfdir = (data >> 8) & 0x00ff;
1503 			}
1504 			break;
1505 
1506 		case 0x42a:
1507 			if (mem_mask & 0x00ff)
1508 			{
1509 				verboselog( *this, 2, "mc68328_w: PFSEL = %02x\n", data & 0x00ff);
1510 				m_regs.pfsel = data & 0x00ff;
1511 			}
1512 			else
1513 			{
1514 				verboselog( *this, 2, "mc68328_w: PFPUEN = %02x\n", (data >> 8) & 0x00ff);
1515 				m_regs.pfpuen = (data >> 8) & 0x00ff;
1516 			}
1517 			break;
1518 
1519 		case 0x430:
1520 			if (mem_mask & 0x00ff)
1521 			{
1522 				verboselog( *this, 2, "mc68328_w: PGDATA = %02x\n", data & 0x00ff);
1523 				m_regs.pgdata = data & 0x00ff;
1524 				if (!m_out_port_g_cb.isnull())
1525 				{
1526 					m_out_port_g_cb((offs_t)0, data & 0x00ff);
1527 				}
1528 			}
1529 			else
1530 			{
1531 				verboselog( *this, 2, "mc68328_w: PGDIR = %02x\n", (data >> 8) & 0x00ff);
1532 				m_regs.pgdir = (data >> 8) & 0x00ff;
1533 			}
1534 			break;
1535 
1536 		case 0x432:
1537 			if (mem_mask & 0x00ff)
1538 			{
1539 				verboselog( *this, 2, "mc68328_w: PGSEL = %02x\n", data & 0x00ff);
1540 				m_regs.pgsel = data & 0x00ff;
1541 			}
1542 			else
1543 			{
1544 				verboselog( *this, 2, "mc68328_w: PGPUEN = %02x\n", (data >> 8) & 0x00ff);
1545 				m_regs.pgpuen = (data >> 8) & 0x00ff;
1546 			}
1547 			break;
1548 
1549 		case 0x438:
1550 			if (mem_mask & 0x00ff)
1551 			{
1552 				verboselog( *this, 2, "mc68328_w: PJDATA = %02x\n", data & 0x00ff);
1553 				m_regs.pjdata = data & 0x00ff;
1554 				if (!m_out_port_j_cb.isnull())
1555 				{
1556 					m_out_port_j_cb((offs_t)0, data & 0x00ff);
1557 				}
1558 			}
1559 			else
1560 			{
1561 				verboselog( *this, 2, "mc68328_w: PJDIR = %02x\n", (data >> 8) & 0x00ff);
1562 				m_regs.pjdir = (data >> 8) & 0x00ff;
1563 			}
1564 			break;
1565 
1566 		case 0x43a:
1567 			if (mem_mask & 0x00ff)
1568 			{
1569 				verboselog( *this, 2, "mc68328_w: PJSEL = %02x\n", data & 0x00ff);
1570 				m_regs.pjsel = data & 0x00ff;
1571 			}
1572 			else
1573 			{
1574 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfff43a) = %02x\n", (data >> 8) & 0x00ff);
1575 			}
1576 			break;
1577 
1578 		case 0x440:
1579 			if (mem_mask & 0x00ff)
1580 			{
1581 				verboselog( *this, 2, "mc68328_w: PKDATA = %02x\n", data & 0x00ff);
1582 				m_regs.pkdata = data & 0x00ff;
1583 				if (!m_out_port_k_cb.isnull())
1584 				{
1585 					m_out_port_k_cb((offs_t)0, data & 0x00ff);
1586 				}
1587 			}
1588 			else
1589 			{
1590 				verboselog( *this, 2, "mc68328_w: PKDIR = %02x\n", (data >> 8) & 0x00ff);
1591 				m_regs.pkdir = (data >> 8) & 0x00ff;
1592 			}
1593 			break;
1594 
1595 		case 0x442:
1596 			if (mem_mask & 0x00ff)
1597 			{
1598 				verboselog( *this, 2, "mc68328_w: PKSEL = %02x\n", data & 0x00ff);
1599 				m_regs.pksel = data & 0x00ff;
1600 			}
1601 			else
1602 			{
1603 				verboselog( *this, 2, "mc68328_w: PKPUEN = %02x\n", (data >> 8) & 0x00ff);
1604 				m_regs.pgpuen = (data >> 8) & 0x00ff;
1605 			}
1606 			break;
1607 
1608 		case 0x448:
1609 			if (mem_mask & 0x00ff)
1610 			{
1611 				verboselog( *this, 2, "mc68328_w: PMDATA = %02x\n", data & 0x00ff);
1612 				m_regs.pmdata = data & 0x00ff;
1613 				if (!m_out_port_m_cb.isnull())
1614 				{
1615 					m_out_port_m_cb((offs_t)0, data & 0x00ff);
1616 				}
1617 			}
1618 			else
1619 			{
1620 				verboselog( *this, 2, "mc68328_w: PMDIR = %02x\n", (data >> 8) & 0x00ff);
1621 				m_regs.pmdir = (data >> 8) & 0x00ff;
1622 			}
1623 			break;
1624 
1625 		case 0x44a:
1626 			if (mem_mask & 0x00ff)
1627 			{
1628 				verboselog( *this, 2, "mc68328_w: PMSEL = %02x\n", data & 0x00ff);
1629 				m_regs.pmsel = data & 0x00ff;
1630 			}
1631 			else
1632 			{
1633 				verboselog( *this, 2, "mc68328_w: PMPUEN = %02x\n", (data >> 8) & 0x00ff);
1634 				m_regs.pmpuen = (data >> 8) & 0x00ff;
1635 			}
1636 			break;
1637 
1638 		case 0x500:
1639 			verboselog( *this, 2, "mc68328_w: PWMC = %04x\n", data);
1640 
1641 			m_regs.pwmc = data;
1642 
1643 			if (m_regs.pwmc & PWMC_PWMIRQ)
1644 			{
1645 				set_interrupt_line(INT_PWM, 1);
1646 			}
1647 
1648 			m_regs.pwmc &= ~PWMC_LOAD;
1649 
1650 			if ((m_regs.pwmc & PWMC_PWMEN) != 0 && m_regs.pwmw != 0 && m_regs.pwmp != 0)
1651 			{
1652 				uint32_t frequency = 32768 * 506;
1653 				uint32_t divisor = 4 << (m_regs.pwmc & PWMC_CLKSEL); // ?? Datasheet says 2 <<, but then we're an octave higher than CoPilot.
1654 				attotime period;
1655 				frequency /= divisor;
1656 				period = attotime::from_hz(frequency) * m_regs.pwmw;
1657 				m_pwm->adjust(period);
1658 				if (m_regs.pwmc & PWMC_IRQEN)
1659 				{
1660 					set_interrupt_line(INT_PWM, 1);
1661 				}
1662 				m_regs.pwmc ^= PWMC_PIN;
1663 			}
1664 			else
1665 			{
1666 				m_pwm->adjust(attotime::never);
1667 			}
1668 			break;
1669 
1670 		case 0x502:
1671 			verboselog( *this, 2, "mc68328_w: PWMP = %04x\n", data);
1672 			m_regs.pwmp = data;
1673 			break;
1674 
1675 		case 0x504:
1676 			verboselog( *this, 2, "mc68328_w: PWMW = %04x\n", data);
1677 			m_regs.pwmw = data;
1678 			break;
1679 
1680 		case 0x506:
1681 			verboselog( *this, 2, "mc68328_w: PWMCNT = %04x\n", data);
1682 			m_regs.pwmcnt = 0;
1683 			break;
1684 
1685 		case 0x600:
1686 			verboselog( *this, 2, "mc68328_w: TCTL1 = %04x\n", data);
1687 			temp16[0] = m_regs.tctl[0];
1688 			m_regs.tctl[0] = data;
1689 			if ((temp16[0] & TCTL_TEN) == (m_regs.tctl[0] & TCTL_TEN))
1690 			{
1691 				maybe_start_timer(0, 0);
1692 			}
1693 			else if ((temp16[0] & TCTL_TEN) != TCTL_TEN_ENABLE && (m_regs.tctl[0] & TCTL_TEN) == TCTL_TEN_ENABLE)
1694 			{
1695 				maybe_start_timer(0, 1);
1696 			}
1697 			break;
1698 
1699 		case 0x602:
1700 			verboselog( *this, 2, "mc68328_w: TPRER1 = %04x\n", data);
1701 			m_regs.tprer[0] = data;
1702 			maybe_start_timer(0, 0);
1703 			break;
1704 
1705 		case 0x604:
1706 			verboselog( *this, 2, "mc68328_w: TCMP1 = %04x\n", data);
1707 			m_regs.tcmp[0] = data;
1708 			maybe_start_timer(0, 0);
1709 			break;
1710 
1711 		case 0x606:
1712 			verboselog( *this, 2, "mc68328_w: TCR1 = %04x (Ignored)\n", data);
1713 			break;
1714 
1715 		case 0x608:
1716 			verboselog( *this, 2, "mc68328_w: TCN1 = %04x (Ignored)\n", data);
1717 			break;
1718 
1719 		case 0x60a:
1720 			verboselog( *this, 5, "mc68328_w: TSTAT1 = %04x\n", data);
1721 			m_regs.tstat[0] &= ~m_regs.tclear[0];
1722 			if (!(m_regs.tstat[0] & TSTAT_COMP))
1723 			{
1724 				set_interrupt_line(INT_TIMER1, 0);
1725 			}
1726 			break;
1727 
1728 		case 0x60c:
1729 			verboselog( *this, 2, "mc68328_w: TCTL2 = %04x\n", data);
1730 			temp16[0] = m_regs.tctl[1];
1731 			m_regs.tctl[1] = data;
1732 			if ((temp16[0] & TCTL_TEN) == (m_regs.tctl[1] & TCTL_TEN))
1733 			{
1734 				maybe_start_timer(1, 0);
1735 			}
1736 			else if ((temp16[0] & TCTL_TEN) != TCTL_TEN_ENABLE && (m_regs.tctl[1] & TCTL_TEN) == TCTL_TEN_ENABLE)
1737 			{
1738 				maybe_start_timer(1, 1);
1739 			}
1740 			break;
1741 
1742 		case 0x60e:
1743 			verboselog( *this, 2, "mc68328_w: TPRER2 = %04x\n", data);
1744 			m_regs.tprer[1] = data;
1745 			maybe_start_timer(1, 0);
1746 			break;
1747 
1748 		case 0x610:
1749 			verboselog( *this, 2, "mc68328_w: TCMP2 = %04x\n", data);
1750 			m_regs.tcmp[1] = data;
1751 			maybe_start_timer(1, 0);
1752 			break;
1753 
1754 		case 0x612:
1755 			verboselog( *this, 2, "mc68328_w: TCR2 = %04x (Ignored)\n", data);
1756 			break;
1757 
1758 		case 0x614:
1759 			verboselog( *this, 2, "mc68328_w: TCN2 = %04x (Ignored)\n", data);
1760 			break;
1761 
1762 		case 0x616:
1763 			verboselog( *this, 2, "mc68328_w: TSTAT2 = %04x\n", data);
1764 			m_regs.tstat[1] &= ~m_regs.tclear[1];
1765 			if (!(m_regs.tstat[1] & TSTAT_COMP))
1766 			{
1767 				set_interrupt_line(INT_TIMER2, 0);
1768 			}
1769 			break;
1770 
1771 		case 0x618:
1772 			verboselog( *this, 2, "mc68328_w: WCTLR = %04x\n", data);
1773 			m_regs.wctlr = data;
1774 			break;
1775 
1776 		case 0x61a:
1777 			verboselog( *this, 2, "mc68328_w: WCMPR = %04x\n", data);
1778 			m_regs.wcmpr = data;
1779 			break;
1780 
1781 		case 0x61c:
1782 			verboselog( *this, 2, "mc68328_w: WCN = %04x (Ignored)\n", data);
1783 			break;
1784 
1785 		case 0x700:
1786 			verboselog( *this, 2, "mc68328_w: SPISR = %04x\n", data);
1787 			m_regs.spisr = data;
1788 			break;
1789 
1790 		case 0x800:
1791 			verboselog( *this, 2, "mc68328_w: SPIMDATA = %04x\n", data);
1792 			if (!m_out_spim_cb.isnull())
1793 			{
1794 				m_out_spim_cb(0, data, 0xffff);
1795 			}
1796 			else
1797 			{
1798 				m_regs.spimdata = data;
1799 			}
1800 			break;
1801 
1802 		case 0x802:
1803 			verboselog( *this, 2, "mc68328_w: SPIMCONT = %04x\n", data);
1804 			verboselog( *this, 3, "           Count = %d\n", data & SPIM_CLOCK_COUNT);
1805 			verboselog( *this, 3, "           Polarity = %s\n", (data & SPIM_POL) ? "Inverted" : "Active-high");
1806 			verboselog( *this, 3, "           Phase = %s\n", (data & SPIM_PHA) ? "Opposite" : "Normal");
1807 			verboselog( *this, 3, "           IRQ Enable = %s\n", (data & SPIM_IRQEN) ? "Enable" : "Disable");
1808 			verboselog( *this, 3, "           IRQ Pending = %s\n", (data & SPIM_SPIMIRQ) ? "Yes" : "No");
1809 			verboselog( *this, 3, "           Exchange = %s\n", (data & SPIM_XCH) ? "Initiate" : "Idle");
1810 			verboselog( *this, 3, "           SPIM Enable = %s\n", (data & SPIM_SPMEN) ? "Enable" : "Disable");
1811 			verboselog( *this, 3, "           Data Rate = Divide By %d\n", 1 << ((((data & SPIM_RATE) >> 13) & 0x0007) + 2) );
1812 			m_regs.spimcont = data;
1813 			// $$HACK$$ We should probably emulate the ADS7843 A/D device properly.
1814 			if (data & SPIM_XCH)
1815 			{
1816 				m_regs.spimcont &= ~SPIM_XCH;
1817 				if (!m_spim_xch_trigger_cb.isnull())
1818 				{
1819 					m_spim_xch_trigger_cb(0);
1820 				}
1821 				if (data & SPIM_IRQEN)
1822 				{
1823 					m_regs.spimcont |= SPIM_SPIMIRQ;
1824 					verboselog( *this, 3, "Triggering SPIM Interrupt\n" );
1825 					set_interrupt_line(INT_SPIM, 1);
1826 				}
1827 			}
1828 			if (!(data & SPIM_IRQEN))
1829 			{
1830 				set_interrupt_line(INT_SPIM, 0);
1831 			}
1832 			break;
1833 
1834 		case 0x900:
1835 			verboselog( *this, 2, "mc68328_w: USTCNT = %04x\n", data);
1836 			m_regs.ustcnt = data;
1837 			break;
1838 
1839 		case 0x902:
1840 			verboselog( *this, 2, "mc68328_w: UBAUD = %04x\n", data);
1841 			m_regs.ubaud = data;
1842 			break;
1843 
1844 		case 0x904:
1845 			verboselog( *this, 2, "mc68328_w: URX = %04x\n", data);
1846 			break;
1847 
1848 		case 0x906:
1849 			verboselog( *this, 2, "mc68328_w: UTX = %04x\n", data);
1850 			break;
1851 
1852 		case 0x908:
1853 			verboselog( *this, 2, "mc68328_w: UMISC = %04x\n", data);
1854 			m_regs.umisc = data;
1855 			break;
1856 
1857 		case 0xa00:
1858 			verboselog( *this, 2, "mc68328_w: LSSA(16) = %04x\n", data);
1859 			m_regs.lssa &= ~(mem_mask << 16);
1860 			m_regs.lssa |= (data & mem_mask) << 16;
1861 			verboselog( *this, 3, "              Address: %08x\n", m_regs.lssa);
1862 			break;
1863 
1864 		case 0xa02:
1865 			verboselog( *this, 2, "mc68328_w: LSSA(0) = %04x\n", data);
1866 			m_regs.lssa &= 0xffff0000 | (~mem_mask);
1867 			m_regs.lssa |= data & mem_mask;
1868 			verboselog( *this, 3, "              Address: %08x\n", m_regs.lssa);
1869 			break;
1870 
1871 		case 0xa04:
1872 			if (mem_mask & 0x00ff)
1873 			{
1874 				verboselog( *this, 2, "mc68328_w: LVPW = %02x\n", data & 0x00ff);
1875 				m_regs.lvpw = data & 0x00ff;
1876 				verboselog( *this, 3, "              Page Width: %d\n", (m_regs.lvpw + 1) * ((m_regs.lpicf & 0x01) ? 8 : 16));
1877 			}
1878 			else
1879 			{
1880 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfffa04) = %02x\n", (data >> 8) & 0x00ff);
1881 			}
1882 			break;
1883 
1884 		case 0xa08:
1885 			verboselog( *this, 2, "mc68328_w: LXMAX = %04x\n", data);
1886 			m_regs.lxmax = data;
1887 			verboselog( *this, 3, "              Width: %d\n", (data & 0x03ff) + 1);
1888 			break;
1889 
1890 		case 0xa0a:
1891 			verboselog( *this, 2, "mc68328_w: LYMAX = %04x\n", data);
1892 			m_regs.lymax = data;
1893 			verboselog( *this, 3, "              Height: %d\n", (data & 0x03ff) + 1);
1894 			break;
1895 
1896 		case 0xa18:
1897 			verboselog( *this, 2, "mc68328_w: LCXP = %04x\n", data);
1898 			m_regs.lcxp = data;
1899 			verboselog( *this, 3, "              X Position: %d\n", data & 0x03ff);
1900 			switch (m_regs.lcxp >> 14)
1901 			{
1902 				case 0:
1903 					verboselog( *this, 3, "              Cursor Control: Transparent\n");
1904 					break;
1905 
1906 				case 1:
1907 					verboselog( *this, 3, "              Cursor Control: Black\n");
1908 					break;
1909 
1910 				case 2:
1911 					verboselog( *this, 3, "              Cursor Control: Reverse\n");
1912 					break;
1913 
1914 				case 3:
1915 					verboselog( *this, 3, "              Cursor Control: Invalid\n");
1916 					break;
1917 			}
1918 			break;
1919 
1920 		case 0xa1a:
1921 			verboselog( *this, 2, "mc68328_w: LCYP = %04x\n", data);
1922 			m_regs.lcyp = data;
1923 			verboselog( *this, 3, "              Y Position: %d\n", data & 0x01ff);
1924 			break;
1925 
1926 		case 0xa1c:
1927 			verboselog( *this, 2, "mc68328_w: LCWCH = %04x\n", data);
1928 			m_regs.lcwch = data;
1929 			verboselog( *this, 3, "              Width:  %d\n", (data >> 8) & 0x1f);
1930 			verboselog( *this, 3, "              Height: %d\n", data & 0x1f);
1931 			break;
1932 
1933 		case 0xa1e:
1934 			if (mem_mask & 0x00ff)
1935 			{
1936 				verboselog( *this, 2, "mc68328_w: LBLKC = %02x\n", data & 0x00ff);
1937 				m_regs.lblkc = data & 0x00ff;
1938 				verboselog( *this, 3, "              Blink Enable:  %d\n", m_regs.lblkc >> 7);
1939 				verboselog( *this, 3, "              Blink Divisor: %d\n", m_regs.lblkc & 0x7f);
1940 			}
1941 			else
1942 			{
1943 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfffa1e) = %02x\n", (data >> 8) & 0x00ff);
1944 			}
1945 			break;
1946 
1947 		case 0xa20:
1948 			if (mem_mask & 0x00ff)
1949 			{
1950 				verboselog( *this, 2, "mc68328_w: LPOLCF = %02x\n", data & 0x00ff);
1951 				m_regs.lpolcf = data & 0x00ff;
1952 				verboselog( *this, 3, "              LCD Shift Clock Polarity: %s\n", (m_regs.lpicf & 0x08) ? "Active positive edge of LCLK" : "Active negative edge of LCLK");
1953 				verboselog( *this, 3, "              First-line marker polarity: %s\n", (m_regs.lpicf & 0x04) ? "Active Low" : "Active High");
1954 				verboselog( *this, 3, "              Line-pulse polarity: %s\n", (m_regs.lpicf & 0x02) ? "Active Low" : "Active High");
1955 				verboselog( *this, 3, "              Pixel polarity: %s\n", (m_regs.lpicf & 0x01) ? "Active Low" : "Active High");
1956 			}
1957 			else
1958 			{
1959 				verboselog( *this, 2, "mc68328_w: LPICF = %02x\n", (data >> 8) & 0x00ff);
1960 				m_regs.lpicf = (data >> 8) & 0x00ff;
1961 				switch((m_regs.lpicf >> 1) & 0x03)
1962 				{
1963 					case 0:
1964 						verboselog( *this, 3, "              Bus Size: 1-bit\n");
1965 						break;
1966 
1967 					case 1:
1968 						verboselog( *this, 3, "              Bus Size: 2-bit\n");
1969 						break;
1970 
1971 					case 2:
1972 						verboselog( *this, 3, "              Bus Size: 4-bit\n");
1973 						break;
1974 
1975 					case 3:
1976 						verboselog( *this, 3, "              Bus Size: unused\n");
1977 						break;
1978 				}
1979 				verboselog( *this, 3, "              Gray scale enable: %d\n", m_regs.lpicf & 0x01);
1980 			}
1981 			break;
1982 
1983 		case 0xa22:
1984 			if (mem_mask & 0x00ff)
1985 			{
1986 				verboselog( *this, 2, "mc68328_w: LACDRC = %02x\n", data & 0x00ff);
1987 				m_regs.lacdrc = data & 0x00ff;
1988 			}
1989 			else
1990 			{
1991 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfffa22) = %02x\n", (data >> 8) & 0x00ff);
1992 			}
1993 			break;
1994 
1995 		case 0xa24:
1996 			if (mem_mask & 0x00ff)
1997 			{
1998 				verboselog( *this, 2, "mc68328_w: LPXCD = %02x\n", data & 0x00ff);
1999 				m_regs.lpxcd = data & 0x00ff;
2000 				verboselog( *this, 3, "              Clock Divisor: %d\n", m_regs.lpxcd + 1);
2001 			}
2002 			else
2003 			{
2004 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfffa24) = %02x\n", (data >> 8) & 0x00ff);
2005 			}
2006 			break;
2007 
2008 		case 0xa26:
2009 			if (mem_mask & 0x00ff)
2010 			{
2011 				verboselog( *this, 2, "mc68328_w: LCKCON = %02x\n", data & 0x00ff);
2012 				m_regs.lckcon = data & 0x00ff;
2013 				verboselog( *this, 3, "              LCDC Enable: %d\n", (m_regs.lckcon >> 7) & 0x01);
2014 				verboselog( *this, 3, "              DMA Burst Length: %d\n", ((m_regs.lckcon >> 6) & 0x01) ? 16 : 8);
2015 				verboselog( *this, 3, "              DMA Bursting Clock Control: %d\n", ((m_regs.lckcon >> 4) & 0x03) + 1);
2016 				verboselog( *this, 3, "              Bus Width: %d\n", ((m_regs.lckcon >> 1) & 0x01) ? 8 : 16);
2017 				verboselog( *this, 3, "              Pixel Clock Divider Source: %s\n", (m_regs.lckcon & 0x01) ? "PIX" : "SYS");
2018 			}
2019 			else
2020 			{
2021 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfffa26) = %02x\n", (data >> 8) & 0x00ff);
2022 			}
2023 			break;
2024 
2025 		case 0xa28:
2026 			if (mem_mask & 0x00ff)
2027 			{
2028 				verboselog( *this, 2, "mc68328_w: LLBAR = %02x\n", data & 0x00ff);
2029 				m_regs.llbar = data & 0x00ff;
2030 				verboselog( *this, 3, "              Address: %d\n", (m_regs.llbar & 0x7f) * ((m_regs.lpicf & 0x01) ? 8 : 16));
2031 			}
2032 			else
2033 			{
2034 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfffa28) = %02x\n", (data >> 8) & 0x00ff);
2035 			}
2036 			break;
2037 
2038 		case 0xa2a:
2039 			if (mem_mask & 0x00ff)
2040 			{
2041 				verboselog( *this, 2, "mc68328_w: LOTCR = %02x\n", data & 0x00ff);
2042 			}
2043 			else
2044 			{
2045 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfffa2a) = %02x\n", (data >> 8) & 0x00ff);
2046 			}
2047 			break;
2048 
2049 		case 0xa2c:
2050 			if (mem_mask & 0x00ff)
2051 			{
2052 				verboselog( *this, 2, "mc68328_w: LPOSR = %02x\n", data & 0x00ff);
2053 				m_regs.lposr = data & 0x00ff;
2054 				verboselog( *this, 3, "              Byte Offset: %d\n", (m_regs.lposr >> 3) & 0x01);
2055 				verboselog( *this, 3, "              Pixel Offset: %d\n", m_regs.lposr & 0x07);
2056 			}
2057 			else
2058 			{
2059 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfffa2c) = %02x\n", (data >> 8) & 0x00ff);
2060 			}
2061 			break;
2062 
2063 		case 0xa30:
2064 			if (mem_mask & 0x00ff)
2065 			{
2066 				verboselog( *this, 2, "mc68328_w: LFRCM = %02x\n", data & 0x00ff);
2067 				m_regs.lfrcm = data & 0x00ff;
2068 				verboselog( *this, 3, "              X Modulation: %d\n", (m_regs.lfrcm >> 4) & 0x0f);
2069 				verboselog( *this, 3, "              Y Modulation: %d\n", m_regs.lfrcm & 0x0f);
2070 			}
2071 			else
2072 			{
2073 				verboselog( *this, 2, "mc68328_w: Unknown address (0xfffa30) = %02x\n", (data >> 8) & 0x00ff);
2074 			}
2075 			break;
2076 
2077 		case 0xa32:
2078 			verboselog( *this, 2, "mc68328_w: LGPMR = %04x\n", data);
2079 			m_regs.lgpmr = data;
2080 			verboselog( *this, 3, "              Palette 0: %d\n", (m_regs.lgpmr >>  8) & 0x07);
2081 			verboselog( *this, 3, "              Palette 1: %d\n", (m_regs.lgpmr >> 12) & 0x07);
2082 			verboselog( *this, 3, "              Palette 2: %d\n", (m_regs.lgpmr >>  0) & 0x07);
2083 			verboselog( *this, 3, "              Palette 3: %d\n", (m_regs.lgpmr >>  4) & 0x07);
2084 			break;
2085 
2086 		case 0xb00:
2087 			verboselog( *this, 2, "mc68328_w: HMSR(0) = %04x\n", data);
2088 			m_regs.hmsr &= ~(mem_mask << 16);
2089 			m_regs.hmsr |= (data & mem_mask) << 16;
2090 			m_regs.hmsr &= 0x1f3f003f;
2091 			break;
2092 
2093 		case 0xb02:
2094 			verboselog( *this, 2, "mc68328_w: HMSR(16) = %04x\n", data);
2095 			m_regs.hmsr &= 0xffff0000 | (~mem_mask);
2096 			m_regs.hmsr |= data & mem_mask;
2097 			m_regs.hmsr &= 0x1f3f003f;
2098 			break;
2099 
2100 		case 0xb04:
2101 			verboselog( *this, 2, "mc68328_w: ALARM(0) = %04x\n", data);
2102 			m_regs.alarm &= ~(mem_mask << 16);
2103 			m_regs.alarm |= (data & mem_mask) << 16;
2104 			m_regs.alarm &= 0x1f3f003f;
2105 			break;
2106 
2107 		case 0xb06:
2108 			verboselog( *this, 2, "mc68328_w: ALARM(16) = %04x\n", data);
2109 			m_regs.alarm &= 0xffff0000 | (~mem_mask);
2110 			m_regs.alarm |= data & mem_mask;
2111 			m_regs.alarm &= 0x1f3f003f;
2112 			break;
2113 
2114 		case 0xb0c:
2115 			verboselog( *this, 2, "mc68328_w: RTCCTL = %04x\n", data);
2116 			m_regs.rtcctl = data & 0x00a0;
2117 			break;
2118 
2119 		case 0xb0e:
2120 			verboselog( *this, 2, "mc68328_w: RTCISR = %04x\n", data);
2121 			m_regs.rtcisr &= ~data;
2122 			if (m_regs.rtcisr == 0)
2123 			{
2124 				set_interrupt_line(INT_RTC, 0);
2125 			}
2126 			break;
2127 
2128 		case 0xb10:
2129 			verboselog( *this, 2, "mc68328_w: RTCIENR = %04x\n", data);
2130 			m_regs.rtcienr = data & 0x001f;
2131 			break;
2132 
2133 		case 0xb12:
2134 			verboselog( *this, 2, "mc68328_w: STPWTCH = %04x\n", data);
2135 			m_regs.stpwtch = data & 0x003f;
2136 			break;
2137 
2138 		default:
2139 			verboselog( *this, 0, "mc68328_w: Unknown address (0x%06x) = %04x (%04x)\n", 0xfff000 + address, data, mem_mask);
2140 			break;
2141 	}
2142 }
2143 
internal_read(offs_t offset,uint16_t mem_mask)2144 uint16_t mc68328_device::internal_read(offs_t offset, uint16_t mem_mask)
2145 {
2146 	uint16_t temp16;
2147 	uint32_t address = offset << 1;
2148 
2149 	switch (address)
2150 	{
2151 		case 0x000:
2152 			if (mem_mask & 0x00ff)
2153 			{
2154 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfff001)\n", mem_mask);
2155 			}
2156 			else
2157 			{
2158 				verboselog( *this, 2, "mc68328_r (%04x): SCR = %02x\n", mem_mask, m_regs.scr);
2159 				return m_regs.scr << 8;
2160 			}
2161 			break;
2162 
2163 		case 0x100:
2164 			verboselog( *this, 2, "mc68328_r (%04x): GRPBASEA = %04x\n", mem_mask, m_regs.grpbasea);
2165 			return m_regs.grpbasea;
2166 
2167 		case 0x102:
2168 			verboselog( *this, 2, "mc68328_r (%04x): GRPBASEB = %04x\n", mem_mask, m_regs.grpbaseb);
2169 			return m_regs.grpbaseb;
2170 
2171 		case 0x104:
2172 			verboselog( *this, 2, "mc68328_r (%04x): GRPBASEC = %04x\n", mem_mask, m_regs.grpbasec);
2173 			return m_regs.grpbasec;
2174 
2175 		case 0x106:
2176 			verboselog( *this, 2, "mc68328_r (%04x): GRPBASED = %04x\n", mem_mask, m_regs.grpbased);
2177 			return m_regs.grpbased;
2178 
2179 		case 0x108:
2180 			verboselog( *this, 2, "mc68328_r (%04x): GRPMASKA = %04x\n", mem_mask, m_regs.grpmaska);
2181 			return m_regs.grpmaska;
2182 
2183 		case 0x10a:
2184 			verboselog( *this, 2, "mc68328_r (%04x): GRPMASKB = %04x\n", mem_mask, m_regs.grpmaskb);
2185 			return m_regs.grpmaskb;
2186 
2187 		case 0x10c:
2188 			verboselog( *this, 2, "mc68328_r (%04x): GRPMASKC = %04x\n", mem_mask, m_regs.grpmaskc);
2189 			return m_regs.grpmaskc;
2190 
2191 		case 0x10e:
2192 			verboselog( *this, 2, "mc68328_r (%04x): GRPMASKD = %04x\n", mem_mask, m_regs.grpmaskd);
2193 			return m_regs.grpmaskd;
2194 
2195 		case 0x110:
2196 			verboselog( *this, 5, "mc68328_r (%04x): CSA0(0) = %04x\n", mem_mask, m_regs.csa0 & 0x0000ffff);
2197 			return m_regs.csa0 & 0x0000ffff;
2198 
2199 		case 0x112:
2200 			verboselog( *this, 5, "mc68328_r (%04x): CSA0(16) = %04x\n", mem_mask, m_regs.csa0 >> 16);
2201 			return m_regs.csa0 >> 16;
2202 
2203 		case 0x114:
2204 			verboselog( *this, 5, "mc68328_r (%04x): CSA1(0) = %04x\n", mem_mask, m_regs.csa1 & 0x0000ffff);
2205 			return m_regs.csa1 & 0x0000ffff;
2206 
2207 		case 0x116:
2208 			verboselog( *this, 5, "mc68328_r (%04x): CSA1(16) = %04x\n", mem_mask, m_regs.csa1 >> 16);
2209 			return m_regs.csa1 >> 16;
2210 
2211 		case 0x118:
2212 			verboselog( *this, 5, "mc68328_r (%04x): CSA2(0) = %04x\n", mem_mask, m_regs.csa2 & 0x0000ffff);
2213 			return m_regs.csa2 & 0x0000ffff;
2214 
2215 		case 0x11a:
2216 			verboselog( *this, 5, "mc68328_r (%04x): CSA2(16) = %04x\n", mem_mask, m_regs.csa2 >> 16);
2217 			return m_regs.csa2 >> 16;
2218 
2219 		case 0x11c:
2220 			verboselog( *this, 5, "mc68328_r (%04x): CSA3(0) = %04x\n", mem_mask, m_regs.csa3 & 0x0000ffff);
2221 			return m_regs.csa3 & 0x0000ffff;
2222 
2223 		case 0x11e:
2224 			verboselog( *this, 5, "mc68328_r (%04x): CSA3(16) = %04x\n", mem_mask, m_regs.csa3 >> 16);
2225 			return m_regs.csa3 >> 16;
2226 
2227 		case 0x120:
2228 			verboselog( *this, 5, "mc68328_r (%04x): CSB0(0) = %04x\n", mem_mask, m_regs.csb0 & 0x0000ffff);
2229 			return m_regs.csb0 & 0x0000ffff;
2230 
2231 		case 0x122:
2232 			verboselog( *this, 5, "mc68328_r (%04x): CSB0(16) = %04x\n", mem_mask, m_regs.csb0 >> 16);
2233 			return m_regs.csb0 >> 16;
2234 
2235 		case 0x124:
2236 			verboselog( *this, 5, "mc68328_r (%04x): CSB1(0) = %04x\n", mem_mask, m_regs.csb1 & 0x0000ffff);
2237 			return m_regs.csb1 & 0x0000ffff;
2238 
2239 		case 0x126:
2240 			verboselog( *this, 5, "mc68328_r (%04x): CSB1(16) = %04x\n", mem_mask, m_regs.csb1 >> 16);
2241 			return m_regs.csb1 >> 16;
2242 
2243 		case 0x128:
2244 			verboselog( *this, 5, "mc68328_r (%04x): CSB2(0) = %04x\n", mem_mask, m_regs.csb2 & 0x0000ffff);
2245 			return m_regs.csb2 & 0x0000ffff;
2246 
2247 		case 0x12a:
2248 			verboselog( *this, 5, "mc68328_r (%04x): CSB2(16) = %04x\n", mem_mask, m_regs.csb2 >> 16);
2249 			return m_regs.csb2 >> 16;
2250 
2251 		case 0x12c:
2252 			verboselog( *this, 5, "mc68328_r (%04x): CSB3(0) = %04x\n", mem_mask, m_regs.csb3 & 0x0000ffff);
2253 			return m_regs.csb3 & 0x0000ffff;
2254 
2255 		case 0x12e:
2256 			verboselog( *this, 5, "mc68328_r (%04x): CSB3(16) = %04x\n", mem_mask, m_regs.csb3 >> 16);
2257 			return m_regs.csb3 >> 16;
2258 
2259 		case 0x130:
2260 			verboselog( *this, 5, "mc68328_r (%04x): CSC0(0) = %04x\n", mem_mask, m_regs.csc0 & 0x0000ffff);
2261 			return m_regs.csc0 & 0x0000ffff;
2262 
2263 		case 0x132:
2264 			verboselog( *this, 5, "mc68328_r (%04x): CSC0(16) = %04x\n", mem_mask, m_regs.csc0 >> 16);
2265 			return m_regs.csc0 >> 16;
2266 
2267 		case 0x134:
2268 			verboselog( *this, 5, "mc68328_r (%04x): CSC1(0) = %04x\n", mem_mask, m_regs.csc1 & 0x0000ffff);
2269 			return m_regs.csc1 & 0x0000ffff;
2270 
2271 		case 0x136:
2272 			verboselog( *this, 5, "mc68328_r (%04x): CSC1(16) = %04x\n", mem_mask, m_regs.csc1 >> 16);
2273 			return m_regs.csc1 >> 16;
2274 
2275 		case 0x138:
2276 			verboselog( *this, 5, "mc68328_r (%04x): CSC2(0) = %04x\n", mem_mask, m_regs.csc2 & 0x0000ffff);
2277 			return m_regs.csc2 & 0x0000ffff;
2278 
2279 		case 0x13a:
2280 			verboselog( *this, 5, "mc68328_r (%04x): CSC2(16) = %04x\n", mem_mask, m_regs.csc2 >> 16);
2281 			return m_regs.csc2 >> 16;
2282 
2283 		case 0x13c:
2284 			verboselog( *this, 5, "mc68328_r (%04x): CSC3(0) = %04x\n", mem_mask, m_regs.csc3 & 0x0000ffff);
2285 			return m_regs.csc3 & 0x0000ffff;
2286 
2287 		case 0x13e:
2288 			verboselog( *this, 5, "mc68328_r (%04x): CSC3(16) = %04x\n", mem_mask, m_regs.csc3 >> 16);
2289 			return m_regs.csc3 >> 16;
2290 
2291 		case 0x140:
2292 			verboselog( *this, 5, "mc68328_r (%04x): CSD0(0) = %04x\n", mem_mask, m_regs.csd0 & 0x0000ffff);
2293 			return m_regs.csd0 & 0x0000ffff;
2294 
2295 		case 0x142:
2296 			verboselog( *this, 5, "mc68328_r (%04x): CSD0(16) = %04x\n", mem_mask, m_regs.csd0 >> 16);
2297 			return m_regs.csd0 >> 16;
2298 
2299 		case 0x144:
2300 			verboselog( *this, 5, "mc68328_r (%04x): CSD1(0) = %04x\n", mem_mask, m_regs.csd1 & 0x0000ffff);
2301 			return m_regs.csd1 & 0x0000ffff;
2302 
2303 		case 0x146:
2304 			verboselog( *this, 5, "mc68328_r (%04x): CSD1(16) = %04x\n", mem_mask, m_regs.csd1 >> 16);
2305 			return m_regs.csd1 >> 16;
2306 
2307 		case 0x148:
2308 			verboselog( *this, 5, "mc68328_r (%04x): CSD2(0) = %04x\n", mem_mask, m_regs.csd2 & 0x0000ffff);
2309 			return m_regs.csd2 & 0x0000ffff;
2310 
2311 		case 0x14a:
2312 			verboselog( *this, 5, "mc68328_r (%04x): CSD2(16) = %04x\n", mem_mask, m_regs.csd2 >> 16);
2313 			return m_regs.csd2 >> 16;
2314 
2315 		case 0x14c:
2316 			verboselog( *this, 5, "mc68328_r (%04x): CSD3(0) = %04x\n", mem_mask, m_regs.csd3 & 0x0000ffff);
2317 			return m_regs.csd3 & 0x0000ffff;
2318 
2319 		case 0x14e:
2320 			verboselog( *this, 5, "mc68328_r (%04x): CSD3(16) = %04x\n", mem_mask, m_regs.csd3 >> 16);
2321 			return m_regs.csd3 >> 16;
2322 
2323 		case 0x200:
2324 			verboselog( *this, 2, "mc68328_r (%04x): PLLCR = %04x\n", mem_mask, m_regs.pllcr);
2325 			return m_regs.pllcr;
2326 
2327 		case 0x202:
2328 			verboselog( *this, 2, "mc68328_r (%04x): PLLFSR = %04x\n", mem_mask, m_regs.pllfsr);
2329 			m_regs.pllfsr ^= 0x8000;
2330 			return m_regs.pllfsr;
2331 
2332 		case 0x206:
2333 			if (mem_mask & 0x00ff)
2334 			{
2335 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfff206)\n", mem_mask);
2336 			}
2337 			else
2338 			{
2339 				verboselog( *this, 2, "mc68328_r (%04x): PCTLR = %02x\n", mem_mask, m_regs.pctlr);
2340 				return m_regs.pctlr << 8;
2341 			}
2342 			break;
2343 
2344 		case 0x300:
2345 			if (mem_mask & 0x00ff)
2346 			{
2347 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfff301)\n", mem_mask);
2348 			}
2349 			else
2350 			{
2351 				verboselog( *this, 2, "mc68328_r (%04x): IVR = %02x\n", mem_mask, m_regs.ivr);
2352 				return m_regs.ivr << 8;
2353 			}
2354 			break;
2355 
2356 		case 0x302:
2357 			verboselog( *this, 2, "mc68328_r (%04x): ICR = %04x\n", mem_mask, m_regs.icr);
2358 			return m_regs.icr;
2359 
2360 		case 0x304:
2361 			verboselog( *this, 2, "mc68328_r (%04x): IMR(16) = %04x\n", mem_mask, m_regs.imr >> 16);
2362 			return m_regs.imr >> 16;
2363 
2364 		case 0x306:
2365 			verboselog( *this, 2, "mc68328_r (%04x): IMR(0) = %04x\n", mem_mask, m_regs.imr & 0x0000ffff);
2366 			return m_regs.imr & 0x0000ffff;
2367 
2368 		case 0x308:
2369 			verboselog( *this, 2, "mc68328_r (%04x): IWR(16) = %04x\n", mem_mask, m_regs.iwr >> 16);
2370 			return m_regs.iwr >> 16;
2371 
2372 		case 0x30a:
2373 			verboselog( *this, 2, "mc68328_r (%04x): IWR(0) = %04x\n", mem_mask, m_regs.iwr & 0x0000ffff);
2374 			return m_regs.iwr & 0x0000ffff;
2375 
2376 		case 0x30c:
2377 			verboselog( *this, 2, "mc68328_r (%04x): ISR(16) = %04x\n", mem_mask, m_regs.isr >> 16);
2378 			return m_regs.isr >> 16;
2379 
2380 		case 0x30e:
2381 			verboselog( *this, 2, "mc68328_r (%04x): ISR(0) = %04x\n", mem_mask, m_regs.isr & 0x0000ffff);
2382 			return m_regs.isr & 0x0000ffff;
2383 
2384 		case 0x310:
2385 			verboselog( *this, 2, "mc68328_r (%04x): IPR(16) = %04x\n", mem_mask, m_regs.ipr >> 16);
2386 			return m_regs.ipr >> 16;
2387 
2388 		case 0x312:
2389 			verboselog( *this, 2, "mc68328_r (%04x): IPR(0) = %04x\n", mem_mask, m_regs.ipr & 0x0000ffff);
2390 			return m_regs.ipr & 0x0000ffff;
2391 
2392 		case 0x400:
2393 			if (mem_mask & 0x00ff)
2394 			{
2395 				verboselog( *this, 2, "mc68328_r (%04x): PADATA = %02x\n", mem_mask, m_regs.padata);
2396 				if (!m_in_port_a_cb.isnull())
2397 				{
2398 					return m_in_port_a_cb(0);
2399 				}
2400 				else
2401 				{
2402 					return m_regs.padata;
2403 				}
2404 			}
2405 			else
2406 			{
2407 				verboselog( *this, 2, "mc68328_r (%04x): PADIR = %02x\n", mem_mask, m_regs.padir);
2408 				return m_regs.padir << 8;
2409 			}
2410 
2411 		case 0x402:
2412 			if (mem_mask & 0x00ff)
2413 			{
2414 				verboselog( *this, 2, "mc68328_r (%04x): PASEL = %02x\n", mem_mask, m_regs.pasel);
2415 				return m_regs.pasel;
2416 			}
2417 			else
2418 			{
2419 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfff402)\n", mem_mask);
2420 			}
2421 			break;
2422 
2423 		case 0x408:
2424 			if (mem_mask & 0x00ff)
2425 			{
2426 				verboselog( *this, 2, "mc68328_r (%04x): PBDATA = %02x\n", mem_mask, m_regs.pbdata);
2427 				if (!m_in_port_b_cb.isnull())
2428 				{
2429 					return m_in_port_b_cb(0);
2430 				}
2431 				else
2432 				{
2433 					return m_regs.pbdata;
2434 				}
2435 			}
2436 			else
2437 			{
2438 				verboselog( *this, 2, "mc68328_r (%04x): PBDIR = %02x\n", mem_mask, m_regs.pbdir);
2439 				return m_regs.pbdir << 8;
2440 			}
2441 
2442 		case 0x40a:
2443 			if (mem_mask & 0x00ff)
2444 			{
2445 				verboselog( *this, 2, "mc68328_r (%04x): PBSEL = %02x\n", mem_mask, m_regs.pbsel);
2446 				return m_regs.pbsel;
2447 			}
2448 			else
2449 			{
2450 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfff40a)\n", mem_mask);
2451 			}
2452 			break;
2453 
2454 		case 0x410:
2455 			if (mem_mask & 0x00ff)
2456 			{
2457 				verboselog( *this, 2, "mc68328_r (%04x): PCDATA = %02x\n", mem_mask, m_regs.pcdata);
2458 				if (!m_in_port_c_cb.isnull())
2459 				{
2460 					return m_in_port_c_cb(0);
2461 				}
2462 				else
2463 				{
2464 					return m_regs.pcdata;
2465 				}
2466 			}
2467 			else
2468 			{
2469 				verboselog( *this, 2, "mc68328_r (%04x): PCDIR = %02x\n", mem_mask, m_regs.pcdir);
2470 				return m_regs.pcdir << 8;
2471 			}
2472 
2473 		case 0x412:
2474 			if (mem_mask & 0x00ff)
2475 			{
2476 				verboselog( *this, 2, "mc68328_r (%04x): PCSEL = %02x\n", mem_mask, m_regs.pcsel);
2477 				return m_regs.pcsel;
2478 			}
2479 			else
2480 			{
2481 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfff412)\n", mem_mask);
2482 			}
2483 			break;
2484 
2485 		case 0x418:
2486 			if (mem_mask & 0x00ff)
2487 			{
2488 				verboselog( *this, 2, "mc68328_r (%04x): PDDATA = %02x\n", mem_mask, m_regs.pddata);
2489 				if (!m_in_port_d_cb.isnull())
2490 				{
2491 					return m_in_port_d_cb(0);
2492 				}
2493 				else
2494 				{
2495 					return m_regs.pddata;
2496 				}
2497 			}
2498 			else
2499 			{
2500 				verboselog( *this, 2, "mc68328_r (%04x): PDDIR = %02x\n", mem_mask, m_regs.pddir);
2501 				return m_regs.pddir << 8;
2502 			}
2503 
2504 		case 0x41a:
2505 			if (mem_mask & 0x00ff)
2506 			{
2507 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfff41b)\n", mem_mask);
2508 			}
2509 			else
2510 			{
2511 				verboselog( *this, 2, "mc68328_r (%04x): PDPUEN = %02x\n", mem_mask, m_regs.pdpuen);
2512 				return m_regs.pdpuen << 8;
2513 			}
2514 			break;
2515 
2516 		case 0x41c:
2517 			if (mem_mask & 0x00ff)
2518 			{
2519 				verboselog( *this, 2, "mc68328_r (%04x): PDIRQEN = %02x\n", mem_mask, m_regs.pdirqen);
2520 				return m_regs.pdirqen;
2521 			}
2522 			else
2523 			{
2524 				verboselog( *this, 2, "mc68328_r (%04x): PDPOL = %02x\n", mem_mask, m_regs.pdpol);
2525 				return m_regs.pdpol << 8;
2526 			}
2527 
2528 		case 0x41e:
2529 			if (mem_mask & 0x00ff)
2530 			{
2531 				verboselog( *this, 2, "mc68328_r (%04x): PDIRQEDGE = %02x\n", mem_mask, m_regs.pdirqedge);
2532 				return m_regs.pdirqedge;
2533 			}
2534 			else
2535 			{
2536 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfff41e)\n", mem_mask);
2537 			}
2538 			break;
2539 
2540 		case 0x420:
2541 			if (mem_mask & 0x00ff)
2542 			{
2543 				verboselog( *this, 2, "mc68328_r (%04x): PEDATA = %02x\n", mem_mask, m_regs.pedata);
2544 				if (!m_in_port_e_cb.isnull())
2545 				{
2546 					return m_in_port_e_cb(0);
2547 				}
2548 				else
2549 				{
2550 					return m_regs.pedata;
2551 				}
2552 			}
2553 			else
2554 			{
2555 				verboselog( *this, 2, "mc68328_r (%04x): PEDIR = %02x\n", mem_mask, m_regs.pedir);
2556 				return m_regs.pedir << 8;
2557 			}
2558 
2559 		case 0x422:
2560 			if (mem_mask & 0x00ff)
2561 			{
2562 				verboselog( *this, 2, "mc68328_r (%04x): PESEL = %02x\n", mem_mask, m_regs.pesel);
2563 				return m_regs.pesel;
2564 			}
2565 			else
2566 			{
2567 				verboselog( *this, 2, "mc68328_r (%04x): PEPUEN = %02x\n", mem_mask, m_regs.pepuen);
2568 				return m_regs.pepuen << 8;
2569 			}
2570 
2571 		case 0x428:
2572 			if (mem_mask & 0x00ff)
2573 			{
2574 				verboselog( *this, 2, "mc68328_r (%04x): PFDATA = %02x\n", mem_mask, m_regs.pfdata);
2575 				if (!m_in_port_f_cb.isnull())
2576 				{
2577 					return m_in_port_f_cb(0);
2578 				}
2579 				else
2580 				{
2581 					return m_regs.pfdata;
2582 				}
2583 			}
2584 			else
2585 			{
2586 				verboselog( *this, 2, "mc68328_r (%04x): PFDIR = %02x\n", mem_mask, m_regs.pfdir);
2587 				return m_regs.pfdir << 8;
2588 			}
2589 
2590 		case 0x42a:
2591 			if (mem_mask & 0x00ff)
2592 			{
2593 				verboselog( *this, 2, "mc68328_r (%04x): PFSEL = %02x\n", mem_mask, m_regs.pfsel);
2594 				return m_regs.pfsel;
2595 			}
2596 			else
2597 			{
2598 				verboselog( *this, 2, "mc68328_r (%04x): PFPUEN = %02x\n", mem_mask, m_regs.pfpuen);
2599 				return m_regs.pfpuen << 8;
2600 			}
2601 
2602 		case 0x430:
2603 			if (mem_mask & 0x00ff)
2604 			{
2605 				verboselog( *this, 2, "mc68328_r (%04x): PGDATA = %02x\n", mem_mask, m_regs.pgdata);
2606 				if (!m_in_port_g_cb.isnull())
2607 				{
2608 					return m_in_port_g_cb(0);
2609 				}
2610 				else
2611 				{
2612 					return m_regs.pgdata;
2613 				}
2614 			}
2615 			else
2616 			{
2617 				verboselog( *this, 2, "mc68328_r (%04x): PGDIR = %02x\n", mem_mask, m_regs.pgdir);
2618 				return m_regs.pgdir << 8;
2619 			}
2620 
2621 		case 0x432:
2622 			if (mem_mask & 0x00ff)
2623 			{
2624 				verboselog( *this, 2, "mc68328_r (%04x): PGSEL = %02x\n", mem_mask, m_regs.pgsel);
2625 				return m_regs.pgsel;
2626 			}
2627 			else
2628 			{
2629 				verboselog( *this, 2, "mc68328_r (%04x): PGPUEN = %02x\n", mem_mask, m_regs.pgpuen);
2630 				return m_regs.pgpuen << 8;
2631 			}
2632 
2633 		case 0x438:
2634 			if (mem_mask & 0x00ff)
2635 			{
2636 				verboselog( *this, 2, "mc68328_r (%04x): PJDATA = %02x\n", mem_mask, m_regs.pjdata);
2637 				if (!m_in_port_j_cb.isnull())
2638 				{
2639 					return m_in_port_j_cb(0);
2640 				}
2641 				else
2642 				{
2643 					return m_regs.pjdata;
2644 				}
2645 			}
2646 			else
2647 			{
2648 				verboselog( *this, 2, "mc68328_r (%04x): PJDIR = %02x\n", mem_mask, m_regs.pjdir);
2649 				return m_regs.pjdir << 8;
2650 			}
2651 
2652 		case 0x43a:
2653 			if (mem_mask & 0x00ff)
2654 			{
2655 				verboselog( *this, 2, "mc68328_r (%04x): PJSEL = %02x\n", mem_mask, m_regs.pjsel);
2656 				return m_regs.pjsel;
2657 			}
2658 			else
2659 			{
2660 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfff43a)\n", mem_mask);
2661 			}
2662 			break;
2663 
2664 		case 0x440:
2665 			if (mem_mask & 0x00ff)
2666 			{
2667 				verboselog( *this, 2, "mc68328_r (%04x): PKDATA = %02x\n", mem_mask, m_regs.pkdata);
2668 				if (!m_in_port_k_cb.isnull())
2669 				{
2670 					return m_in_port_k_cb(0);
2671 				}
2672 				else
2673 				{
2674 					return m_regs.pkdata;
2675 				}
2676 			}
2677 			else
2678 			{
2679 				verboselog( *this, 2, "mc68328_r (%04x): PKDIR = %02x\n", mem_mask, m_regs.pkdir);
2680 				return m_regs.pkdir << 8;
2681 			}
2682 
2683 		case 0x442:
2684 			if (mem_mask & 0x00ff)
2685 			{
2686 				verboselog( *this, 2, "mc68328_r (%04x): PKSEL = %02x\n", mem_mask, m_regs.pksel);
2687 				return m_regs.pksel;
2688 			}
2689 			else
2690 			{
2691 				verboselog( *this, 2, "mc68328_r (%04x): PKPUEN = %02x\n", mem_mask, m_regs.pkpuen);
2692 				return m_regs.pkpuen << 8;
2693 			}
2694 
2695 		case 0x448:
2696 			if (mem_mask & 0x00ff)
2697 			{
2698 				verboselog( *this, 2, "mc68328_r (%04x): PMDATA = %02x\n", mem_mask, m_regs.pmdata);
2699 				if (!m_in_port_m_cb.isnull())
2700 				{
2701 					return m_in_port_m_cb(0);
2702 				}
2703 				else
2704 				{
2705 					return m_regs.pmdata;
2706 				}
2707 			}
2708 			else
2709 			{
2710 				verboselog( *this, 2, "mc68328_r (%04x): PMDIR = %02x\n", mem_mask, m_regs.pmdir);
2711 				return m_regs.pmdir << 8;
2712 			}
2713 
2714 		case 0x44a:
2715 			if (mem_mask & 0x00ff)
2716 			{
2717 				verboselog( *this, 2, "mc68328_r (%04x): PMSEL = %02x\n", mem_mask, m_regs.pmsel);
2718 				return m_regs.pmsel;
2719 			}
2720 			else
2721 			{
2722 				verboselog( *this, 2, "mc68328_r (%04x): PMPUEN = %02x\n", mem_mask, m_regs.pmpuen);
2723 				return m_regs.pmpuen << 8;
2724 			}
2725 
2726 		case 0x500:
2727 			verboselog( *this, 2, "mc68328_r (%04x): PWMC = %04x\n", mem_mask, m_regs.pwmc);
2728 			temp16 = m_regs.pwmc;
2729 			if (m_regs.pwmc & PWMC_PWMIRQ)
2730 			{
2731 				m_regs.pwmc &= ~PWMC_PWMIRQ;
2732 				set_interrupt_line(INT_PWM, 0);
2733 			}
2734 			return temp16;
2735 
2736 		case 0x502:
2737 			verboselog( *this, 2, "mc68328_r (%04x): PWMP = %04x\n", mem_mask, m_regs.pwmp);
2738 			return m_regs.pwmp;
2739 
2740 		case 0x504:
2741 			verboselog( *this, 2, "mc68328_r (%04x): PWMW = %04x\n", mem_mask, m_regs.pwmw);
2742 			return m_regs.pwmw;
2743 
2744 		case 0x506:
2745 			verboselog( *this, 2, "mc68328_r (%04x): PWMCNT = %04x\n", mem_mask, m_regs.pwmcnt);
2746 			return m_regs.pwmcnt;
2747 
2748 		case 0x600:
2749 			verboselog( *this, 2, "mc68328_r (%04x): TCTL1 = %04x\n", mem_mask, m_regs.tctl[0]);
2750 			return m_regs.tctl[0];
2751 
2752 		case 0x602:
2753 			verboselog( *this, 2, "mc68328_r (%04x): TPRER1 = %04x\n", mem_mask, m_regs.tprer[0]);
2754 			return m_regs.tprer[0];
2755 
2756 		case 0x604:
2757 			verboselog( *this, 2, "mc68328_r (%04x): TCMP1 = %04x\n", mem_mask, m_regs.tcmp[0]);
2758 			return m_regs.tcmp[0];
2759 
2760 		case 0x606:
2761 			verboselog( *this, 2, "mc68328_r (%04x): TCR1 = %04x\n", mem_mask, m_regs.tcr[0]);
2762 			return m_regs.tcr[0];
2763 
2764 		case 0x608:
2765 			verboselog( *this, 2, "mc68328_r (%04x): TCN1 = %04x\n", mem_mask, m_regs.tcn[0]);
2766 			return m_regs.tcn[0];
2767 
2768 		case 0x60a:
2769 			verboselog( *this, 5, "mc68328_r (%04x): TSTAT1 = %04x\n", mem_mask, m_regs.tstat[0]);
2770 			m_regs.tclear[0] |= m_regs.tstat[0];
2771 			return m_regs.tstat[0];
2772 
2773 		case 0x60c:
2774 			verboselog( *this, 2, "mc68328_r (%04x): TCTL2 = %04x\n", mem_mask, m_regs.tctl[1]);
2775 			return m_regs.tctl[1];
2776 
2777 		case 0x60e:
2778 			verboselog( *this, 2, "mc68328_r (%04x): TPREP2 = %04x\n", mem_mask, m_regs.tprer[1]);
2779 			return m_regs.tprer[1];
2780 
2781 		case 0x610:
2782 			verboselog( *this, 2, "mc68328_r (%04x): TCMP2 = %04x\n", mem_mask, m_regs.tcmp[1]);
2783 			return m_regs.tcmp[1];
2784 
2785 		case 0x612:
2786 			verboselog( *this, 2, "mc68328_r (%04x): TCR2 = %04x\n", mem_mask, m_regs.tcr[1]);
2787 			return m_regs.tcr[1];
2788 
2789 		case 0x614:
2790 			verboselog( *this, 2, "mc68328_r (%04x): TCN2 = %04x\n", mem_mask, m_regs.tcn[1]);
2791 			return m_regs.tcn[1];
2792 
2793 		case 0x616:
2794 			verboselog( *this, 2, "mc68328_r (%04x): TSTAT2 = %04x\n", mem_mask, m_regs.tstat[1]);
2795 			m_regs.tclear[1] |= m_regs.tstat[1];
2796 			return m_regs.tstat[1];
2797 
2798 		case 0x618:
2799 			verboselog( *this, 2, "mc68328_r (%04x): WCTLR = %04x\n", mem_mask, m_regs.wctlr);
2800 			return m_regs.wctlr;
2801 
2802 		case 0x61a:
2803 			verboselog( *this, 2, "mc68328_r (%04x): WCMPR = %04x\n", mem_mask, m_regs.wcmpr);
2804 			return m_regs.wcmpr;
2805 
2806 		case 0x61c:
2807 			verboselog( *this, 2, "mc68328_r (%04x): WCN = %04x\n", mem_mask, m_regs.wcn);
2808 			return m_regs.wcn;
2809 
2810 		case 0x700:
2811 			verboselog( *this, 2, "mc68328_r (%04x): SPISR = %04x\n", mem_mask, m_regs.spisr);
2812 			return m_regs.spisr;
2813 
2814 		case 0x800:
2815 			verboselog( *this, 2, "mc68328_r (%04x): SPIMDATA = %04x\n", mem_mask, m_regs.spimdata);
2816 			if (!m_in_spim_cb.isnull())
2817 			{
2818 				return m_in_spim_cb(0, 0xffff);
2819 			}
2820 			return m_regs.spimdata;
2821 
2822 		case 0x802:
2823 			verboselog( *this, 2, "mc68328_r (%04x): SPIMCONT = %04x\n", mem_mask, m_regs.spimcont);
2824 			if (m_regs.spimcont & SPIM_XCH)
2825 			{
2826 				m_regs.spimcont &= ~SPIM_XCH;
2827 				m_regs.spimcont |= SPIM_SPIMIRQ;
2828 				return ((m_regs.spimcont | SPIM_XCH) &~ SPIM_SPIMIRQ);
2829 			}
2830 			return m_regs.spimcont;
2831 
2832 		case 0x900:
2833 			verboselog( *this, 2, "mc68328_r (%04x): USTCNT = %04x\n", mem_mask, m_regs.ustcnt);
2834 			return m_regs.ustcnt;
2835 
2836 		case 0x902:
2837 			verboselog( *this, 2, "mc68328_r (%04x): UBAUD = %04x\n", mem_mask, m_regs.ubaud);
2838 			return m_regs.ubaud;
2839 
2840 		case 0x904:
2841 			verboselog( *this, 5, "mc68328_r (%04x): URX = %04x\n", mem_mask, m_regs.urx);
2842 			return m_regs.urx;
2843 
2844 		case 0x906:
2845 			verboselog( *this, 5, "mc68328_r (%04x): UTX = %04x\n", mem_mask, m_regs.utx);
2846 			return m_regs.utx | UTX_FIFO_EMPTY | UTX_FIFO_HALF | UTX_TX_AVAIL;
2847 
2848 		case 0x908:
2849 			verboselog( *this, 2, "mc68328_r (%04x): UMISC = %04x\n", mem_mask, m_regs.umisc);
2850 			return m_regs.umisc;
2851 
2852 		case 0xa00:
2853 			verboselog( *this, 2, "mc68328_r (%04x): LSSA(16) = %04x\n", mem_mask, m_regs.lssa >> 16);
2854 			return m_regs.lssa >> 16;
2855 
2856 		case 0xa02:
2857 			verboselog( *this, 2, "mc68328_r (%04x): LSSA(0) = %04x\n", mem_mask, m_regs.lssa & 0x0000ffff);
2858 			return m_regs.lssa & 0x0000ffff;
2859 
2860 		case 0xa04:
2861 			if (mem_mask & 0x00ff)
2862 			{
2863 				verboselog( *this, 2, "mc68328_r (%04x): LVPW = %02x\n", mem_mask, m_regs.lvpw);
2864 				return m_regs.lvpw;
2865 			}
2866 			else
2867 			{
2868 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfffa04)\n", mem_mask);
2869 			}
2870 			break;
2871 
2872 		case 0xa08:
2873 			verboselog( *this, 2, "mc68328_r (%04x): LXMAX = %04x\n", mem_mask, m_regs.lxmax);
2874 			return m_regs.lxmax;
2875 
2876 		case 0xa0a:
2877 			verboselog( *this, 2, "mc68328_r (%04x): LYMAX = %04x\n", mem_mask, m_regs.lymax);
2878 			return m_regs.lymax;
2879 
2880 		case 0xa18:
2881 			verboselog( *this, 2, "mc68328_r (%04x): LCXP = %04x\n", mem_mask, m_regs.lcxp);
2882 			return m_regs.lcxp;
2883 
2884 		case 0xa1a:
2885 			verboselog( *this, 2, "mc68328_r (%04x): LCYP = %04x\n", mem_mask, m_regs.lcyp);
2886 			return m_regs.lcyp;
2887 
2888 		case 0xa1c:
2889 			verboselog( *this, 2, "mc68328_r (%04x): LCWCH = %04x\n", mem_mask, m_regs.lcwch);
2890 			return m_regs.lcwch;
2891 
2892 		case 0xa1e:
2893 			if (mem_mask & 0x00ff)
2894 			{
2895 				verboselog( *this, 2, "mc68328_r (%04x): LBLKC = %02x\n", mem_mask, m_regs.lblkc);
2896 				return m_regs.lblkc;
2897 			}
2898 			else
2899 			{
2900 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfffa1e)\n", mem_mask);
2901 			}
2902 			break;
2903 
2904 		case 0xa20:
2905 			if (mem_mask & 0x00ff)
2906 			{
2907 				verboselog( *this, 2, "mc68328_r (%04x): LPOLCF = %02x\n", mem_mask, m_regs.lpolcf);
2908 				return m_regs.lpolcf;
2909 			}
2910 			else
2911 			{
2912 				verboselog( *this, 2, "mc68328_r (%04x): LPICF = %02x\n", mem_mask, m_regs.lpicf);
2913 				return m_regs.lpicf << 8;
2914 			}
2915 
2916 		case 0xa22:
2917 			if (mem_mask & 0x00ff)
2918 			{
2919 				verboselog( *this, 2, "mc68328_r (%04x): LACDRC = %02x\n", mem_mask, m_regs.lacdrc);
2920 				return m_regs.lacdrc;
2921 			}
2922 			else
2923 			{
2924 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfffa22)\n", mem_mask);
2925 			}
2926 			break;
2927 
2928 		case 0xa24:
2929 			if (mem_mask & 0x00ff)
2930 			{
2931 				verboselog( *this, 2, "mc68328_r (%04x): LPXCD = %02x\n", mem_mask, m_regs.lpxcd);
2932 				return m_regs.lpxcd;
2933 			}
2934 			else
2935 			{
2936 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfffa24)\n", mem_mask);
2937 			}
2938 			break;
2939 
2940 		case 0xa26:
2941 			if (mem_mask & 0x00ff)
2942 			{
2943 				verboselog( *this, 2, "mc68328_r (%04x): LCKCON = %02x\n", mem_mask, m_regs.lckcon);
2944 				return m_regs.lckcon;
2945 			}
2946 			else
2947 			{
2948 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfffa26)\n", mem_mask);
2949 			}
2950 			break;
2951 
2952 		case 0xa28:
2953 			if (mem_mask & 0x00ff)
2954 			{
2955 				verboselog( *this, 2, "mc68328_r (%04x): LLBAR = %02x\n", mem_mask, m_regs.llbar);
2956 				return m_regs.llbar;
2957 			}
2958 			else
2959 			{
2960 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfffa28)\n", mem_mask);
2961 			}
2962 			break;
2963 
2964 		case 0xa2a:
2965 			if (mem_mask & 0x00ff)
2966 			{
2967 				verboselog( *this, 2, "mc68328_r (%04x): LOTCR = %02x\n", mem_mask, m_regs.lotcr);
2968 				return m_regs.lotcr;
2969 			}
2970 			else
2971 			{
2972 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfffa2a)\n", mem_mask);
2973 			}
2974 			break;
2975 
2976 		case 0xa2c:
2977 			if (mem_mask & 0x00ff)
2978 			{
2979 				verboselog( *this, 2, "mc68328_r (%04x): LPOSR = %02x\n", mem_mask, m_regs.lposr);
2980 				return m_regs.lposr;
2981 			}
2982 			else
2983 			{
2984 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfffa2c)\n", mem_mask);
2985 			}
2986 			break;
2987 
2988 		case 0xa30:
2989 			if (mem_mask & 0x00ff)
2990 			{
2991 				verboselog( *this, 2, "mc68328_r (%04x): LFRCM = %02x\n", mem_mask, m_regs.lfrcm);
2992 				return m_regs.lfrcm;
2993 			}
2994 			else
2995 			{
2996 				verboselog( *this, 2, "mc68328_r (%04x): Unknown address (0xfffa30)\n", mem_mask);
2997 			}
2998 			break;
2999 
3000 		case 0xa32:
3001 			verboselog( *this, 2, "mc68328_r (%04x): LGPMR = %04x\n", mem_mask, m_regs.lgpmr);
3002 			return m_regs.lgpmr;
3003 
3004 		case 0xb00:
3005 			verboselog( *this, 2, "mc68328_r (%04x): HMSR(0) = %04x\n", mem_mask, m_regs.hmsr & 0x0000ffff);
3006 			return m_regs.hmsr & 0x0000ffff;
3007 
3008 		case 0xb02:
3009 			verboselog( *this, 2, "mc68328_r (%04x): HMSR(16) = %04x\n", mem_mask, m_regs.hmsr >> 16);
3010 			return m_regs.hmsr >> 16;
3011 
3012 		case 0xb04:
3013 			verboselog( *this, 2, "mc68328_r (%04x): ALARM(0) = %04x\n", mem_mask, m_regs.alarm & 0x0000ffff);
3014 			return m_regs.alarm & 0x0000ffff;
3015 
3016 		case 0xb06:
3017 			verboselog( *this, 2, "mc68328_r (%04x): ALARM(16) = %04x\n", mem_mask, m_regs.alarm >> 16);
3018 			return m_regs.alarm >> 16;
3019 
3020 		case 0xb0c:
3021 			verboselog( *this, 2, "mc68328_r (%04x): RTCCTL = %04x\n", mem_mask, m_regs.rtcctl);
3022 			return m_regs.rtcctl;
3023 
3024 		case 0xb0e:
3025 			verboselog( *this, 2, "mc68328_r (%04x): RTCISR = %04x\n", mem_mask, m_regs.rtcisr);
3026 			return m_regs.rtcisr;
3027 
3028 		case 0xb10:
3029 			verboselog( *this, 2, "mc68328_r (%04x): RTCIENR = %04x\n", mem_mask, m_regs.rtcienr);
3030 			return m_regs.rtcienr;
3031 
3032 		case 0xb12:
3033 			verboselog( *this, 2, "mc68328_r (%04x): STPWTCH = %04x\n", mem_mask, m_regs.stpwtch);
3034 			return m_regs.stpwtch;
3035 
3036 		default:
3037 			verboselog( *this, 0, "mc68328_r (%04x): Unknown address (0x%06x)\n", mem_mask, 0xfff000 + address);
3038 			break;
3039 	}
3040 	return 0;
3041 }
3042 
3043 /* THIS IS PRETTY MUCH TOTALLY WRONG AND DOESN'T REFLECT THE MC68328'S INTERNAL FUNCTIONALITY AT ALL! */
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)3044 uint32_t mc68328_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
3045 {
3046 	uint32_t vram_addr = m_regs.lssa & 0x00fffffe;
3047 
3048 	if (m_regs.lckcon & LCKCON_LCDC_EN)
3049 	{
3050 		for (int y = 0; y < 160; y++)
3051 		{
3052 			uint16_t *const line = &bitmap.pix(y);
3053 
3054 			for (int x = 0; x < 160; x += 16, vram_addr += 2)
3055 			{
3056 				uint16_t const word = space(AS_PROGRAM).read_word(vram_addr);
3057 				for (int b = 0; b < 16; b++)
3058 				{
3059 					line[x + b] = (word >> (15 - b)) & 0x0001;
3060 				}
3061 			}
3062 		}
3063 	}
3064 	else
3065 	{
3066 		for (int y = 0; y < 160; y++)
3067 		{
3068 			uint16_t *const line = &bitmap.pix(y);
3069 
3070 			for (int x = 0; x < 160; x++)
3071 			{
3072 				line[x] = 0;
3073 			}
3074 		}
3075 	}
3076 	return 0;
3077 }
3078 
3079 
register_state_save()3080 void mc68328_device::register_state_save()
3081 {
3082 	save_item(NAME(m_regs.scr));
3083 	save_item(NAME(m_regs.grpbasea));
3084 	save_item(NAME(m_regs.grpbaseb));
3085 	save_item(NAME(m_regs.grpbasec));
3086 	save_item(NAME(m_regs.grpbased));
3087 	save_item(NAME(m_regs.grpmaska));
3088 	save_item(NAME(m_regs.grpmaskb));
3089 	save_item(NAME(m_regs.grpmaskc));
3090 	save_item(NAME(m_regs.grpmaskd));
3091 	save_item(NAME(m_regs.csa0));
3092 	save_item(NAME(m_regs.csa1));
3093 	save_item(NAME(m_regs.csa2));
3094 	save_item(NAME(m_regs.csa3));
3095 	save_item(NAME(m_regs.csb0));
3096 	save_item(NAME(m_regs.csb1));
3097 	save_item(NAME(m_regs.csb2));
3098 	save_item(NAME(m_regs.csb3));
3099 	save_item(NAME(m_regs.csc0));
3100 	save_item(NAME(m_regs.csc1));
3101 	save_item(NAME(m_regs.csc2));
3102 	save_item(NAME(m_regs.csc3));
3103 	save_item(NAME(m_regs.csd0));
3104 	save_item(NAME(m_regs.csd1));
3105 	save_item(NAME(m_regs.csd2));
3106 	save_item(NAME(m_regs.csd3));
3107 
3108 	save_item(NAME(m_regs.pllcr));
3109 	save_item(NAME(m_regs.pllfsr));
3110 	save_item(NAME(m_regs.pctlr));
3111 
3112 	save_item(NAME(m_regs.ivr));
3113 	save_item(NAME(m_regs.icr));
3114 	save_item(NAME(m_regs.imr));
3115 	save_item(NAME(m_regs.iwr));
3116 	save_item(NAME(m_regs.isr));
3117 	save_item(NAME(m_regs.ipr));
3118 
3119 	save_item(NAME(m_regs.padir));
3120 	save_item(NAME(m_regs.padata));
3121 	save_item(NAME(m_regs.pasel));
3122 	save_item(NAME(m_regs.pbdir));
3123 	save_item(NAME(m_regs.pbdata));
3124 	save_item(NAME(m_regs.pbsel));
3125 	save_item(NAME(m_regs.pcdir));
3126 	save_item(NAME(m_regs.pcdata));
3127 	save_item(NAME(m_regs.pcsel));
3128 	save_item(NAME(m_regs.pddir));
3129 	save_item(NAME(m_regs.pddata));
3130 	save_item(NAME(m_regs.pdpuen));
3131 	save_item(NAME(m_regs.pdpol));
3132 	save_item(NAME(m_regs.pdirqen));
3133 	save_item(NAME(m_regs.pddataedge));
3134 	save_item(NAME(m_regs.pdirqedge));
3135 	save_item(NAME(m_regs.pedir));
3136 	save_item(NAME(m_regs.pedata));
3137 	save_item(NAME(m_regs.pepuen));
3138 	save_item(NAME(m_regs.pesel));
3139 	save_item(NAME(m_regs.pfdir));
3140 	save_item(NAME(m_regs.pfdata));
3141 	save_item(NAME(m_regs.pfpuen));
3142 	save_item(NAME(m_regs.pfsel));
3143 	save_item(NAME(m_regs.pgdir));
3144 	save_item(NAME(m_regs.pgdata));
3145 	save_item(NAME(m_regs.pgpuen));
3146 	save_item(NAME(m_regs.pgsel));
3147 	save_item(NAME(m_regs.pjdir));
3148 	save_item(NAME(m_regs.pjdata));
3149 	save_item(NAME(m_regs.pjsel));
3150 	save_item(NAME(m_regs.pkdir));
3151 	save_item(NAME(m_regs.pkdata));
3152 	save_item(NAME(m_regs.pkpuen));
3153 	save_item(NAME(m_regs.pksel));
3154 	save_item(NAME(m_regs.pmdir));
3155 	save_item(NAME(m_regs.pmdata));
3156 	save_item(NAME(m_regs.pmpuen));
3157 	save_item(NAME(m_regs.pmsel));
3158 
3159 	save_item(NAME(m_regs.pwmc));
3160 	save_item(NAME(m_regs.pwmp));
3161 	save_item(NAME(m_regs.pwmw));
3162 	save_item(NAME(m_regs.pwmcnt));
3163 
3164 	save_item(NAME(m_regs.tctl[0]));
3165 	save_item(NAME(m_regs.tctl[1]));
3166 	save_item(NAME(m_regs.tprer[0]));
3167 	save_item(NAME(m_regs.tprer[1]));
3168 	save_item(NAME(m_regs.tcmp[0]));
3169 	save_item(NAME(m_regs.tcmp[1]));
3170 	save_item(NAME(m_regs.tcr[0]));
3171 	save_item(NAME(m_regs.tcr[1]));
3172 	save_item(NAME(m_regs.tcn[0]));
3173 	save_item(NAME(m_regs.tcn[1]));
3174 	save_item(NAME(m_regs.tstat[0]));
3175 	save_item(NAME(m_regs.tstat[1]));
3176 	save_item(NAME(m_regs.wctlr));
3177 	save_item(NAME(m_regs.wcmpr));
3178 	save_item(NAME(m_regs.wcn));
3179 
3180 	save_item(NAME(m_regs.spisr));
3181 
3182 	save_item(NAME(m_regs.spimdata));
3183 	save_item(NAME(m_regs.spimcont));
3184 
3185 	save_item(NAME(m_regs.ustcnt));
3186 	save_item(NAME(m_regs.ubaud));
3187 	save_item(NAME(m_regs.urx));
3188 	save_item(NAME(m_regs.utx));
3189 	save_item(NAME(m_regs.umisc));
3190 
3191 	save_item(NAME(m_regs.lssa));
3192 	save_item(NAME(m_regs.lvpw));
3193 	save_item(NAME(m_regs.lxmax));
3194 	save_item(NAME(m_regs.lymax));
3195 	save_item(NAME(m_regs.lcxp));
3196 	save_item(NAME(m_regs.lcyp));
3197 	save_item(NAME(m_regs.lcwch));
3198 	save_item(NAME(m_regs.lblkc));
3199 	save_item(NAME(m_regs.lpicf));
3200 	save_item(NAME(m_regs.lpolcf));
3201 	save_item(NAME(m_regs.lacdrc));
3202 	save_item(NAME(m_regs.lpxcd));
3203 	save_item(NAME(m_regs.lckcon));
3204 	save_item(NAME(m_regs.llbar));
3205 	save_item(NAME(m_regs.lotcr));
3206 	save_item(NAME(m_regs.lposr));
3207 	save_item(NAME(m_regs.lfrcm));
3208 	save_item(NAME(m_regs.lgpmr));
3209 
3210 	save_item(NAME(m_regs.hmsr));
3211 	save_item(NAME(m_regs.alarm));
3212 	save_item(NAME(m_regs.rtcctl));
3213 	save_item(NAME(m_regs.rtcisr));
3214 	save_item(NAME(m_regs.rtcienr));
3215 	save_item(NAME(m_regs.stpwtch));
3216 }
3217