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