1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 /*****************************************************************************
4
5 SunPlus "GCM394" (based on die pictures)
6
7 Note, these are all the same chip but in different configurations so
8 should be tidied up and made to use callbacks
9
10 **********************************************************************/
11
12 #include "emu.h"
13 #include "generalplus_gpl16250soc.h"
14
15
16 #define LOG_GCM394_SPI (1U << 5)
17 #define LOG_GCM394_IO (1U << 4)
18 #define LOG_GCM394_SYSDMA (1U << 3)
19 #define LOG_GCM394 (1U << 2)
20 #define LOG_GCM394_UNMAPPED (1U << 1)
21
22 #define VERBOSE (LOG_GCM394 | LOG_GCM394_IO | LOG_GCM394_UNMAPPED | LOG_GCM394_SYSDMA)
23 #include "logmacro.h"
24
25
26 DEFINE_DEVICE_TYPE(GCM394, sunplus_gcm394_device, "gcm394", "GeneralPlus GPL16250 System-on-a-Chip")
27
sunplus_gcm394_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)28 sunplus_gcm394_device::sunplus_gcm394_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
29 sunplus_gcm394_base_device(mconfig, GCM394, tag, owner, clock)
30 {
31 }
32
33 DEFINE_DEVICE_TYPE(GPAC800, generalplus_gpac800_device, "gpac800", "GeneralPlus GPL16250 System-on-a-Chip (with NAND handling)")
34
generalplus_gpac800_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)35 generalplus_gpac800_device::generalplus_gpac800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
36 sunplus_gcm394_base_device(mconfig, GPAC800, tag, owner, clock, address_map_constructor(FUNC(generalplus_gpac800_device::gpac800_internal_map), this))
37 {
38 }
39
40
41 DEFINE_DEVICE_TYPE(GP_SPISPI, generalplus_gpspispi_device, "gpac800spi", "GeneralPlus GPL16250 (with SPI handling)")
42
generalplus_gpspispi_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)43 generalplus_gpspispi_device::generalplus_gpspispi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
44 sunplus_gcm394_base_device(mconfig, GP_SPISPI, tag, owner, clock, address_map_constructor(FUNC(generalplus_gpspispi_device::gpspispi_internal_map), this))
45 {
46 }
47
48
default_cs_callback(uint16_t cs0,uint16_t cs1,uint16_t cs2,uint16_t cs3,uint16_t cs4)49 void sunplus_gcm394_base_device::default_cs_callback(uint16_t cs0, uint16_t cs1, uint16_t cs2, uint16_t cs3, uint16_t cs4)
50 {
51 logerror("callback not hooked\n");
52 }
53
54
55 // **************************************** SYSTEM DMA device *************************************************
56
read_dma_params(int channel,int offset)57 uint16_t sunplus_gcm394_base_device::read_dma_params(int channel, int offset)
58 {
59 uint16_t retdata = m_dma_params[offset][channel];
60 LOGMASKED(LOG_GCM394_SYSDMA, "%s:sunplus_gcm394_base_device::read_dma_params (channel %01x) %01x returning %04x\n", machine().describe_context(), channel, offset, retdata);
61 return retdata;
62 }
63
write_dma_params(int channel,int offset,uint16_t data)64 void sunplus_gcm394_base_device::write_dma_params(int channel, int offset, uint16_t data)
65 {
66 LOGMASKED(LOG_GCM394_SYSDMA, "%s:sunplus_gcm394_base_device::write_dma_params (channel %01x) %01x %04x\n", machine().describe_context(), channel, offset, data);
67
68 m_dma_params[offset][channel] = data;
69
70 // TODO: very likely DMA happens whenever the length is not 0, as long as it's been enabled previously
71 // jak_prft doesn't rewrite the offset 0 register between requests, and instead writes the length
72 // as the final thing for each new request. other games do not write the length last, but turn off
73 // register 0 before writing params, and enable it again afterwards
74 // if that's the case, this code can be refactored to work on 'length' instead of the m_dma_latched
75
76 if (offset == 3)
77 {
78 m_dma_latched[channel] = true;
79
80 if (m_dma_params[0][channel] & 1)
81 trigger_systemm_dma(channel);
82 }
83
84 if (offset == 0 && (data & 1))
85 {
86 if (m_dma_latched[channel])
87 trigger_systemm_dma(channel);
88 }
89
90 }
91
92
system_dma_params_channel0_r(offs_t offset)93 uint16_t sunplus_gcm394_base_device::system_dma_params_channel0_r(offs_t offset)
94 {
95 return read_dma_params(0, offset);
96 }
97
98
system_dma_params_channel0_w(offs_t offset,uint16_t data)99 void sunplus_gcm394_base_device::system_dma_params_channel0_w(offs_t offset, uint16_t data)
100 {
101 write_dma_params(0, offset, data);
102 }
103
system_dma_params_channel1_r(offs_t offset)104 uint16_t sunplus_gcm394_base_device::system_dma_params_channel1_r(offs_t offset)
105 {
106 return read_dma_params(1, offset);
107 }
108
system_dma_params_channel1_w(offs_t offset,uint16_t data)109 void sunplus_gcm394_base_device::system_dma_params_channel1_w(offs_t offset, uint16_t data)
110 {
111 write_dma_params(1, offset, data);
112 }
113
system_dma_params_channel2_r(offs_t offset)114 uint16_t sunplus_gcm394_base_device::system_dma_params_channel2_r(offs_t offset)
115 {
116 return read_dma_params(2, offset);
117 }
118
system_dma_params_channel2_w(offs_t offset,uint16_t data)119 void sunplus_gcm394_base_device::system_dma_params_channel2_w(offs_t offset, uint16_t data)
120 {
121 write_dma_params(2, offset, data);
122 }
123
system_dma_params_channel3_r(offs_t offset)124 uint16_t sunplus_gcm394_base_device::system_dma_params_channel3_r(offs_t offset)
125 {
126 return read_dma_params(3, offset);
127 }
128
system_dma_params_channel3_w(offs_t offset,uint16_t data)129 void sunplus_gcm394_base_device::system_dma_params_channel3_w(offs_t offset, uint16_t data)
130 {
131 write_dma_params(3, offset, data);
132 }
133
134
135
136
system_dma_status_r()137 uint16_t sunplus_gcm394_base_device::system_dma_status_r()
138 {
139 LOGMASKED(LOG_GCM394_SYSDMA, "%s:sunplus_gcm394_base_device::system_dma_status_r (7abf)\n", machine().describe_context());
140
141 // bit 0 = channel 0 ready
142 // bit 1 = channel 1 ready
143
144 return 0x00ff;
145 }
146
trigger_systemm_dma(int channel)147 void sunplus_gcm394_base_device::trigger_systemm_dma(int channel)
148 {
149 uint16_t mode = m_dma_params[0][channel];
150 uint32_t source = m_dma_params[1][channel] | (m_dma_params[4][channel] << 16);
151 uint32_t dest = m_dma_params[2][channel] | (m_dma_params[5][channel] << 16) ;
152 uint32_t length = m_dma_params[3][channel] | (m_dma_params[6][channel] << 16);
153 int sourcedelta = 0;
154 int destdelta = 0;
155
156 if ((mode & 0xa0) == 0x00)
157 sourcedelta = 1;
158 else if ((mode & 0xa0) == 0x20)
159 sourcedelta = -1;
160
161 if ((mode & 0x50) == 0x00)
162 destdelta = 1;
163 else if ((mode & 0x50) == 0x10)
164 destdelta = -1;
165
166 LOGMASKED(LOG_GCM394_SYSDMA, "%s:possible DMA operation with params mode:%04x source:%08x (word offset) dest:%08x (word offset) length:%08x (words) while csbank is %02x\n", machine().describe_context().c_str(), mode, source, dest, length, m_membankswitch_7810 );
167
168 // wrlshunt transfers ROM to RAM, all RAM write addresses have 0x800000 in the destination set
169
170 source &= 0x0fffffff;
171 length &= 0x0fffffff; // gormiti
172
173 for (int i = 0; i < length; i++)
174 {
175 uint16_t val;
176 if (mode & 0x1000)
177 {
178 val = (read_space(source) & 0xFF) | (read_space(source) << 8);
179 i++;
180 }
181 else
182 {
183 val = read_space(source);
184 }
185
186 source += sourcedelta;
187
188 if (mode & 0x2000)
189 {
190 write_space(dest, val & 0xFF);
191 dest += destdelta;
192 write_space(dest, val >> 8);
193 }
194 else
195 {
196 write_space(dest, val);
197 }
198
199 dest += destdelta;
200 }
201
202 // HACKS to get into service mode for debugging
203
204 // note, these patch the code copied to SRAM so the 'PROGRAM ROM' check fails (it passes otherwise)
205
206 address_space& mem = this->space(AS_PROGRAM);
207
208 //if (mem.read_word(0x4368c) == 0x4846)
209 // mem.write_word(0x4368c, 0x4840); // cars 2 force service mode
210
211 //if (mem.read_word(0x34410) == 0x4846)
212 // mem.write_word(0x34410, 0x4840); // golden tee force service mode
213
214 // what is it waiting for when we need these? (needed on some service mode screens)
215 //if (mem.read_word(0x3f368) == 0x4840)
216 // mem.write_word(0x3f368, 0x4841); // cars 2 IRQ? wait hack
217
218 //if (mem.read_word(0x4d8d4) == 0x4840)
219 // mem.write_word(0x4d8d4, 0x4841); // golden tee IRQ? wait hack
220
221 //if (mem.read_word(0x3510f) == 0x4845)
222 // mem.write_word(0x3510f, 0x4840); // camp rock force service mode
223
224 if (mem.read_word(0x4abe7) == 0x4840)
225 mem.write_word(0x4abe7, 0x4841); // camp rock IRQ? wait hack
226
227
228
229 // clear params after operation
230 m_dma_params[0][channel] = m_dma_params[0][channel] & 0x00f7;
231
232 m_dma_params[1][channel] = m_dma_params[2][channel] = m_dma_params[3][channel] = m_dma_params[4][channel] = m_dma_params[5][channel] = m_dma_params[6][channel] = 0x0000;
233 m_dma_latched[channel] = false;
234
235 //machine().debug_break();
236
237 }
238
system_dma_7abf_unk_w(uint16_t data)239 void sunplus_gcm394_base_device::system_dma_7abf_unk_w(uint16_t data)
240 {
241 // if this isn't trigger, is it enable? (which could maybe used as similar if DMA only starts to happen if unmasked?)
242
243 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::system_dma_7abf_unk_w %04x\n", machine().describe_context(), data);
244 }
245
system_dma_memtype_r()246 uint16_t sunplus_gcm394_base_device::system_dma_memtype_r()
247 {
248 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::system_dma_memtype_r\n", machine().describe_context());
249 return m_system_dma_memtype;
250 }
251
system_dma_memtype_w(uint16_t data)252 void sunplus_gcm394_base_device::system_dma_memtype_w(uint16_t data)
253 {
254 static char const* const types[16] =
255 {
256 "Unused / USB",
257 "DAC CHA",
258 "UART TX",
259 "UART RX",
260 "SD/MMC",
261 "NAND Flash",
262 "Serial Interface",
263 "DAC CHB",
264 "ADC Audo Sample Full",
265 "SPI TX",
266 "SPI RX",
267 "RESERVED (c)",
268 "RESERVED (d)",
269 "RESERVED (e)",
270 "RESERVED (f)"
271 };
272
273 m_system_dma_memtype = data;
274
275 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::system_dma_memtype_w %04x (CH3: %s | CH2: %s | CH1: %s | CH0: %s )\n", machine().describe_context(), data,
276 types[((m_system_dma_memtype>>12)&0xf)],
277 types[((m_system_dma_memtype>>8)&0xf)],
278 types[((m_system_dma_memtype>>4)&0xf)],
279 types[((m_system_dma_memtype)&0xf)]);
280
281 }
282
system_7a35_r()283 uint16_t sunplus_gcm394_base_device::system_7a35_r()
284 {
285 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::system_7a35_r\n", machine().describe_context());
286 return machine().rand();
287 }
288
system_7a37_r()289 uint16_t sunplus_gcm394_base_device::system_7a37_r()
290 {
291 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::system_7a37_r\n", machine().describe_context());
292 return machine().rand();
293 }
294
system_7a39_r()295 uint16_t sunplus_gcm394_base_device::system_7a39_r()
296 {
297 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::system_7a39_r\n", machine().describe_context());
298 return machine().rand();
299 }
300
301
system_7a3a_r()302 uint16_t sunplus_gcm394_base_device::system_7a3a_r()
303 {
304 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::system_7a3a_r\n", machine().describe_context());
305 return machine().rand();
306 }
307
system_7a46_r()308 uint16_t sunplus_gcm394_base_device::system_7a46_r()
309 {
310 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::system_7a46_r\n", machine().describe_context());
311 return machine().rand();
312 }
313
system_7a54_r()314 uint16_t sunplus_gcm394_base_device::system_7a54_r()
315 {
316 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::system_7a54_r\n", machine().describe_context());
317 return machine().rand();
318 }
319
320 // **************************************** 78xx region with some handling *************************************************
321
unkarea_780f_status_r()322 uint16_t sunplus_gcm394_base_device::unkarea_780f_status_r()
323 {
324 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_780f_status_r\n", machine().describe_context());
325 return 0x0002;
326 }
327
unkarea_78fb_status_r()328 uint16_t sunplus_gcm394_base_device::unkarea_78fb_status_r()
329 {
330 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78fb_status_r\n", machine().describe_context());
331 m_78fb ^= 0x0100; // status flag for something?
332 return m_78fb;
333 }
334
335 // sets bit 0x0002 then expects it to have cleared
unkarea_7819_r()336 uint16_t sunplus_gcm394_base_device::unkarea_7819_r() { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7819_r\n", machine().describe_context()); return m_7819 & ~ 0x0002; }
unkarea_7819_w(uint16_t data)337 void sunplus_gcm394_base_device::unkarea_7819_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7819_w %04x\n", machine().describe_context(), data); m_7819 = data; }
338
339 // **************************************** 78xx region stubs *************************************************
340
unkarea_782d_r()341 uint16_t sunplus_gcm394_base_device::unkarea_782d_r() { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_782d_r\n", machine().describe_context()); return m_782d; }
unkarea_782d_w(uint16_t data)342 void sunplus_gcm394_base_device::unkarea_782d_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_782d_w %04x\n", machine().describe_context(), data); m_782d = data; }
343
unkarea_7803_r()344 uint16_t sunplus_gcm394_base_device::unkarea_7803_r() { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7803_r\n", machine().describe_context()); return m_7803; }
unkarea_7803_w(uint16_t data)345 void sunplus_gcm394_base_device::unkarea_7803_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7803_w %04x\n", machine().describe_context(), data); m_7803 = data; }
346
unkarea_7807_w(uint16_t data)347 void sunplus_gcm394_base_device::unkarea_7807_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7807_w %04x\n", machine().describe_context(), data); m_7807 = data; }
348
waitmode_enter_780c_w(uint16_t data)349 void sunplus_gcm394_base_device::waitmode_enter_780c_w(uint16_t data)
350 {
351 // LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::waitmode_enter_780c_w %04x\n", machine().describe_context(), data);
352 // must be followed by 6 nops to ensure wait mode is entered
353 }
354
355 // this gets stored / modified / restored before certain memory accesses (
356 // used extensively during SDRAM checks in jak_gtg and jak_car2
357
membankswitch_7810_r()358 uint16_t sunplus_gcm394_base_device::membankswitch_7810_r()
359 {
360 // LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::membankswitch_7810_r\n", machine().describe_context());
361 return m_membankswitch_7810;
362 }
363
membankswitch_7810_w(uint16_t data)364 void sunplus_gcm394_base_device::membankswitch_7810_w(uint16_t data)
365 {
366 // if (m_membankswitch_7810 != data)
367 // LOGMASKED(LOG_GCM394,"%s:sunplus_gcm394_base_device::membankswitch_7810_w %04x\n", machine().describe_context(), data);
368
369 // if (m_membankswitch_7810 != data)
370 // popmessage("bankswitch %04x -> %04x", m_membankswitch_7810, data);
371
372 m_membankswitch_7810 = data;
373 }
374
375
unkarea_7816_w(uint16_t data)376 void sunplus_gcm394_base_device::unkarea_7816_w(uint16_t data)
377 {
378 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7816_w %04x\n", machine().describe_context(), data);
379 m_7816 = data;
380 }
381
unkarea_7817_w(uint16_t data)382 void sunplus_gcm394_base_device::unkarea_7817_w(uint16_t data)
383 {
384 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7817_w %04x\n", machine().describe_context(), data);
385 m_7817 = data;
386 }
387
chipselect_csx_memory_device_control_w(offs_t offset,uint16_t data)388 void sunplus_gcm394_base_device::chipselect_csx_memory_device_control_w(offs_t offset, uint16_t data)
389 {
390 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::chipselect_csx_memory_device_control_w %04x (782x registers offset %d)\n", machine().describe_context(), data, offset);
391 m_782x[offset] = data;
392
393
394 static const char* const md[] =
395 {
396 "(00) ROM / SRAM",
397 "(01) ROM / SRAM",
398 "(10) NOR FLASH",
399 "(11) NAND FLASH",
400 };
401
402 uint8_t cs_wait = data & 0x000f;
403 uint8_t cs_warat = (data & 0x0030)>>4;
404 uint8_t cs_md = (data & 0x00c0)>>6;
405 int cs_size = (data & 0xff00)>>8;
406
407 logerror("CS%d set to size: %02x (%08x words) md: %01x %s warat: %01x wait: %01x\n", offset, cs_size, (cs_size+1)*0x10000, cs_md, md[cs_md], cs_warat, cs_wait);
408
409
410 m_cs_callback(m_782x[0], m_782x[1], m_782x[2], m_782x[3], m_782x[4]);
411
412 }
413
device_post_load()414 void sunplus_gcm394_base_device::device_post_load()
415 {
416 m_cs_callback(m_782x[0], m_782x[1], m_782x[2], m_782x[3], m_782x[4]);
417 }
418
unkarea_7835_w(uint16_t data)419 void sunplus_gcm394_base_device::unkarea_7835_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7835_w %04x\n", machine().describe_context(), data); m_7835 = data; }
420
421 // IO here?
422
423 // Port A
424
ioarea_7860_porta_r()425 uint16_t sunplus_gcm394_base_device::ioarea_7860_porta_r()
426 {
427 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7860_porta_r\n", machine().describe_context());
428 return m_porta_in();
429 }
430
ioarea_7860_porta_w(uint16_t data)431 void sunplus_gcm394_base_device::ioarea_7860_porta_w(uint16_t data)
432 {
433 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7860_porta_w %04x\n", machine().describe_context(), data);
434 if (m_porta_out)
435 m_porta_out(data);
436 }
437
ioarea_7861_porta_buffer_r()438 uint16_t sunplus_gcm394_base_device::ioarea_7861_porta_buffer_r()
439 {
440 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7861_porta_buffer_r\n", machine().describe_context());
441 return 0x0000;// 0xffff;// m_7861;
442 }
443
ioarea_7861_porta_buffer_w(uint16_t data)444 void sunplus_gcm394_base_device::ioarea_7861_porta_buffer_w(uint16_t data)
445 {
446 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7861_porta_buffer_w %04x\n", machine().describe_context(), data);
447 }
448
ioarea_7862_porta_direction_r()449 uint16_t sunplus_gcm394_base_device::ioarea_7862_porta_direction_r()
450 {
451 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7862_porta_direction_r\n", machine().describe_context());
452 return m_7862_porta_direction;
453 }
454
ioarea_7862_porta_direction_w(uint16_t data)455 void sunplus_gcm394_base_device::ioarea_7862_porta_direction_w(uint16_t data)
456 {
457 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7862_porta_direction_w %04x\n", machine().describe_context(), data);
458 m_7862_porta_direction = data;
459 }
460
ioarea_7863_porta_attribute_r()461 uint16_t sunplus_gcm394_base_device::ioarea_7863_porta_attribute_r()
462 {
463 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7863_porta_attribute_r\n", machine().describe_context());
464 return m_7863_porta_attribute;
465 }
466
ioarea_7863_porta_attribute_w(uint16_t data)467 void sunplus_gcm394_base_device::ioarea_7863_porta_attribute_w(uint16_t data)
468 {
469 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7863_porta_attribute_w %04x\n", machine().describe_context(), data);
470 m_7863_porta_attribute = data;
471 }
472
473 // Port B
474
ioarea_7868_portb_r()475 uint16_t sunplus_gcm394_base_device::ioarea_7868_portb_r()
476 {
477 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7868_portb_r\n", machine().describe_context());
478 return m_portb_in();
479 }
480
ioarea_7869_portb_buffer_r()481 uint16_t sunplus_gcm394_base_device::ioarea_7869_portb_buffer_r()
482 {
483 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7869_portb_buffer_r\n", machine().describe_context());
484 return machine().rand();
485 }
486
ioarea_7869_portb_buffer_w(uint16_t data)487 void sunplus_gcm394_base_device::ioarea_7869_portb_buffer_w(uint16_t data)
488 {
489 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7869_portb_buffer_w %04x\n", machine().describe_context(), data);
490 }
491
ioarea_7868_portb_w(uint16_t data)492 void sunplus_gcm394_base_device::ioarea_7868_portb_w(uint16_t data)
493 {
494 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7868_portb_w %04x\n", machine().describe_context(), data);
495 if (m_portb_out)
496 m_portb_out(data);
497 }
498
ioarea_786a_portb_direction_r()499 uint16_t sunplus_gcm394_base_device::ioarea_786a_portb_direction_r()
500 {
501 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_786a_portb_direction_r\n", machine().describe_context());
502 return m_786a_portb_direction;
503 }
504
ioarea_786a_portb_direction_w(uint16_t data)505 void sunplus_gcm394_base_device::ioarea_786a_portb_direction_w(uint16_t data)
506 {
507 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_786a_portb_direction_w %04x\n", machine().describe_context(), data);
508 m_786a_portb_direction = data;
509 }
510
ioarea_786b_portb_attribute_r()511 uint16_t sunplus_gcm394_base_device::ioarea_786b_portb_attribute_r()
512 {
513 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_786b_portb_attribute_r\n", machine().describe_context());
514 return m_786b_portb_attribute;
515 }
516
ioarea_786b_portb_attribute_w(uint16_t data)517 void sunplus_gcm394_base_device::ioarea_786b_portb_attribute_w(uint16_t data)
518 {
519 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_786b_portb_attribute_w %04x\n", machine().describe_context(), data);
520 m_786b_portb_attribute = data;
521 }
522
523 // Port C
524
ioarea_7870_portc_r()525 uint16_t sunplus_gcm394_base_device::ioarea_7870_portc_r()
526 {
527 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7870_portc_r\n", machine().describe_context());
528 return m_portc_in();
529 }
530
ioarea_7870_portc_w(uint16_t data)531 void sunplus_gcm394_base_device::ioarea_7870_portc_w(uint16_t data)
532 {
533 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7870_portc_w %04x\n", machine().describe_context(), data);
534 m_7870 = data;
535 if (m_portc_out)
536 m_portc_out(data);
537 }
538
ioarea_7871_portc_buffer_r()539 uint16_t sunplus_gcm394_base_device::ioarea_7871_portc_buffer_r()
540 {
541 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7871_portc_buffer_r\n", machine().describe_context());
542 return 0xffff;// m_7871;
543 }
544
ioarea_7871_portc_buffer_w(uint16_t data)545 void sunplus_gcm394_base_device::ioarea_7871_portc_buffer_w(uint16_t data)
546 {
547 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7871_portc_buffer_w %04x\n", machine().describe_context(), data);
548 }
549
550
ioarea_7872_portc_direction_r()551 uint16_t sunplus_gcm394_base_device::ioarea_7872_portc_direction_r()
552 {
553 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7872_portc_direction_r\n", machine().describe_context());
554 return m_7872_portc_direction;
555 }
556
ioarea_7872_portc_direction_w(uint16_t data)557 void sunplus_gcm394_base_device::ioarea_7872_portc_direction_w(uint16_t data)
558 {
559 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7872_portc_direction_w %04x\n", machine().describe_context(), data);
560 m_7872_portc_direction = data;
561 }
562
ioarea_7873_portc_attribute_r()563 uint16_t sunplus_gcm394_base_device::ioarea_7873_portc_attribute_r()
564 {
565 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7873_portc_attribute_r\n", machine().describe_context());
566 return m_7873_portc_attribute;
567 }
568
ioarea_7873_portc_attribute_w(uint16_t data)569 void sunplus_gcm394_base_device::ioarea_7873_portc_attribute_w(uint16_t data)
570 {
571 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7873_portc_attribute_w %04x\n", machine().describe_context(), data);
572 m_7873_portc_attribute = data;
573 }
574
575 // Port D
576
ioarea_7878_portd_r()577 uint16_t sunplus_gcm394_base_device::ioarea_7878_portd_r()
578 {
579 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7878_portd_r\n", machine().describe_context());
580 return m_portd_in();
581 }
582
ioarea_7878_portd_w(uint16_t data)583 void sunplus_gcm394_base_device::ioarea_7878_portd_w(uint16_t data)
584 {
585 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7878_portd_w %04x\n", machine().describe_context(), data);
586 //m_7878 = data;
587
588 if (m_portd_out)
589 m_portd_out(data);
590 }
591
ioarea_7879_portd_buffer_r()592 uint16_t sunplus_gcm394_base_device::ioarea_7879_portd_buffer_r()
593 {
594 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7879_portd_buffer_r\n", machine().describe_context());
595 return 0xffff;// m_7871;
596 }
597
ioarea_7879_portd_buffer_w(uint16_t data)598 void sunplus_gcm394_base_device::ioarea_7879_portd_buffer_w(uint16_t data)
599 {
600 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_7879_portd_buffer_w %04x\n", machine().describe_context(), data);
601 }
602
603
ioarea_787a_portd_direction_r()604 uint16_t sunplus_gcm394_base_device::ioarea_787a_portd_direction_r()
605 {
606 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_787a_portd_direction_r\n", machine().describe_context());
607 return m_787a_portd_direction;
608 }
609
ioarea_787a_portd_direction_w(uint16_t data)610 void sunplus_gcm394_base_device::ioarea_787a_portd_direction_w(uint16_t data)
611 {
612 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_787a_portd_direction_w %04x\n", machine().describe_context(), data);
613 m_787a_portd_direction = data;
614 }
615
ioarea_787b_portd_attribute_r()616 uint16_t sunplus_gcm394_base_device::ioarea_787b_portd_attribute_r()
617 {
618 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_787b_portd_attribute_r\n", machine().describe_context());
619 return m_787b_portd_attribute;
620 }
621
ioarea_787b_portd_attribute_w(uint16_t data)622 void sunplus_gcm394_base_device::ioarea_787b_portd_attribute_w(uint16_t data)
623 {
624 LOGMASKED(LOG_GCM394_IO, "%s:sunplus_gcm394_base_device::ioarea_787b_portd_attribute_w %04x\n", machine().describe_context(), data);
625 m_787b_portd_attribute = data;
626 }
627
unkarea_7882_r()628 uint16_t sunplus_gcm394_base_device::unkarea_7882_r() { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7882_r\n", machine().describe_context()); return 0xffff;// m_7882;
629 }
unkarea_7882_w(uint16_t data)630 void sunplus_gcm394_base_device::unkarea_7882_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7882_w %04x\n", machine().describe_context(), data); m_7882 = data; }
unkarea_7883_r()631 uint16_t sunplus_gcm394_base_device::unkarea_7883_r() { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7883_r\n", machine().describe_context()); return 0xffff;// m_7883;
632 }
unkarea_7883_w(uint16_t data)633 void sunplus_gcm394_base_device::unkarea_7883_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7883_w %04x\n", machine().describe_context(), data); m_7883 = data; }
634
unkarea_78a0_w(uint16_t data)635 void sunplus_gcm394_base_device::unkarea_78a0_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a0_w %04x\n", machine().describe_context(), data); m_78a0 = data; }
636
unkarea_78a0_r()637 uint16_t sunplus_gcm394_base_device::unkarea_78a0_r()
638 {
639 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a0_r\n", machine().describe_context());
640 return 0x0000;// machine().rand();
641 }
642
unkarea_78a1_r()643 uint16_t sunplus_gcm394_base_device::unkarea_78a1_r()
644 {
645 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a1_r\n", machine().describe_context());
646 return 0xffff;// machine().rand();
647 }
648
unkarea_78a4_w(uint16_t data)649 void sunplus_gcm394_base_device::unkarea_78a4_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a4_w %04x\n", machine().describe_context(), data); m_78a4 = data; }
unkarea_78a5_w(uint16_t data)650 void sunplus_gcm394_base_device::unkarea_78a5_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a5_w %04x\n", machine().describe_context(), data); m_78a5 = data; }
unkarea_78a6_w(uint16_t data)651 void sunplus_gcm394_base_device::unkarea_78a6_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a6_w %04x\n", machine().describe_context(), data); m_78a6 = data; }
652
unkarea_78a8_w(uint16_t data)653 void sunplus_gcm394_base_device::unkarea_78a8_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a8_w %04x\n", machine().describe_context(), data); m_78a8 = data; }
654
655
unkarea_78b0_w(uint16_t data)656 void sunplus_gcm394_base_device::unkarea_78b0_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78b0_w %04x\n", machine().describe_context(), data); m_78b0 = data; }
unkarea_78b1_w(uint16_t data)657 void sunplus_gcm394_base_device::unkarea_78b1_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78b1_w %04x\n", machine().describe_context(), data); m_78b1 = data; }
658
unkarea_78b2_r()659 uint16_t sunplus_gcm394_base_device::unkarea_78b2_r()
660 {
661 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78b2_r\n", machine().describe_context());
662 return 0xffff;// m_78b2;
663 }
664
unkarea_78b2_w(uint16_t data)665 void sunplus_gcm394_base_device::unkarea_78b2_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78b2_w %04x\n", machine().describe_context(), data); m_78b2 = data; }
666
unkarea_78b8_w(uint16_t data)667 void sunplus_gcm394_base_device::unkarea_78b8_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78b8_w %04x\n", machine().describe_context(), data); m_78b8 = data; }
unkarea_78f0_w(uint16_t data)668 void sunplus_gcm394_base_device::unkarea_78f0_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78f0_w %04x\n", machine().describe_context(), data); m_78f0 = data; }
669
unkarea_78c0_r()670 uint16_t sunplus_gcm394_base_device::unkarea_78c0_r()
671 {
672 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78c0_r\n", machine().describe_context());
673 return machine().rand();
674 }
675
unkarea_78d0_r()676 uint16_t sunplus_gcm394_base_device::unkarea_78d0_r()
677 {
678 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78d0_r\n", machine().describe_context());
679 return machine().rand();
680 }
681
unkarea_78d8_r()682 uint16_t sunplus_gcm394_base_device::unkarea_78d8_r()
683 {
684 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78d8_r\n", machine().describe_context());
685 return machine().rand();
686 }
687
688 // **************************************** 793x uknown region stubs *************************************************
689
unkarea_7904_r()690 uint16_t sunplus_gcm394_base_device::unkarea_7904_r()
691 {
692 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7904_r\n", machine().describe_context());
693 return machine().rand(); // lazertag waits on a bit, status flag for something?
694
695 }
696
unkarea_7934_r()697 uint16_t sunplus_gcm394_base_device::unkarea_7934_r()
698 {
699 // does this return data written, or is it a status flag?
700 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7934_r\n", machine().describe_context());
701 return m_7934;
702 }
703
unkarea_7934_w(uint16_t data)704 void sunplus_gcm394_base_device::unkarea_7934_w(uint16_t data)
705 {
706 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7934_w %04x\n", machine().describe_context(), data);
707 m_7934 = data;
708 }
709
710 // value of 7935 is read then written in irq6, nothing happens unless bit 0x0100 was set, which could be some kind of irq source being acked?
unkarea_7935_r()711 uint16_t sunplus_gcm394_base_device::unkarea_7935_r()
712 {
713 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7935_r\n", machine().describe_context());
714 return m_7935;
715 }
716
unkarea_7935_w(uint16_t data)717 void sunplus_gcm394_base_device::unkarea_7935_w(uint16_t data)
718 {
719 LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7935_w %04x\n", machine().describe_context(), data);
720 m_7935 &= ~data;
721 //checkirq6();
722 }
723
unkarea_7936_r()724 uint16_t sunplus_gcm394_base_device::unkarea_7936_r() { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7936_r\n", machine().describe_context()); return 0x0000; }
unkarea_7936_w(uint16_t data)725 void sunplus_gcm394_base_device::unkarea_7936_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7936_w %04x\n", machine().describe_context(), data); m_7936 = data; }
726
727 // **************************************** 794x SPI *************************************************
728
729 // these are related to the accelerometer values on jak_g500 (8-bit signed) and also the SPI reads for bkrankp
spi_7944_rxdata_r()730 uint16_t sunplus_gcm394_base_device::spi_7944_rxdata_r()
731 {
732 LOGMASKED(LOG_GCM394_SPI, "%s:sunplus_gcm394_base_device::spi_7944_rxdata_r\n", machine().describe_context());
733 return machine().rand();
734 }
735
spi_7945_misc_control_reg_r()736 uint16_t sunplus_gcm394_base_device::spi_7945_misc_control_reg_r()
737 {
738 LOGMASKED(LOG_GCM394_SPI, "%s:sunplus_gcm394_base_device::spi_7945_misc_control_reg_r\n", machine().describe_context());
739 return machine().rand();// &0x0007;
740 }
741
spi_7942_txdata_w(uint16_t data)742 void sunplus_gcm394_base_device::spi_7942_txdata_w(uint16_t data)
743 {
744 LOGMASKED(LOG_GCM394_SPI, "%s:sunplus_gcm394_base_device::spi_7942_txdata_w %04x\n", machine().describe_context(), data);
745 }
746
747 // **************************************** 796x unknown *************************************************
748
unkarea_7960_w(uint16_t data)749 void sunplus_gcm394_base_device::unkarea_7960_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7960_w %04x\n", machine().describe_context(), data); m_7960 = data; }
750
unkarea_7961_r()751 uint16_t sunplus_gcm394_base_device::unkarea_7961_r() { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7961_r\n", machine().describe_context()); return m_7961; }
unkarea_7961_w(uint16_t data)752 void sunplus_gcm394_base_device::unkarea_7961_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7961_w %04x\n", machine().describe_context(), data); m_7961 = data; }
753
754
755 // **************************************** fallthrough logger etc. *************************************************
756
unk_r(offs_t offset)757 uint16_t sunplus_gcm394_base_device::unk_r(offs_t offset)
758 {
759 switch (offset)
760 {
761 default:
762 LOGMASKED(LOG_GCM394_UNMAPPED, "%s:sunplus_gcm394_base_device::unk_r @ 0x%04x\n", machine().describe_context(), offset + 0x7000);
763 return 0x0000;
764 }
765
766 return 0x0000;
767 }
768
unk_w(offs_t offset,uint16_t data)769 void sunplus_gcm394_base_device::unk_w(offs_t offset, uint16_t data)
770 {
771
772 switch (offset)
773 {
774 default:
775 LOGMASKED(LOG_GCM394_UNMAPPED, "%s:sunplus_gcm394_base_device::unk_w @ 0x%04x (data 0x%04x)\n", machine().describe_context(), offset + 0x7000, data);
776 break;
777 }
778 }
779
base_internal_map(address_map & map)780 void sunplus_gcm394_base_device::base_internal_map(address_map &map)
781 {
782 map(0x000000, 0x006fff).ram().share("mainram");
783 map(0x007000, 0x007fff).rw(FUNC(sunplus_gcm394_base_device::unk_r), FUNC(sunplus_gcm394_base_device::unk_w)); // catch unhandled
784
785 // ######################################################################################################################################################################################
786 // 70xx region = video hardware
787 // ######################################################################################################################################################################################
788
789 // note, tilemaps are at the same address offsets in video device as spg2xx (but unknown devices are extra)
790
791 map(0x007000, 0x007007).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap2_regs_r), FUNC(gcm394_base_video_device::tmap2_regs_w)); // written with other unknown_video_device1 LSB/MSB regs below (roz layer or line layer?)
792 map(0x007008, 0x00700f).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap3_regs_r), FUNC(gcm394_base_video_device::tmap3_regs_w)); // written with other unknown_video_device2 LSB/MSB regs below (roz layer or line layer?)
793
794 map(0x007010, 0x007015).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap0_regs_r), FUNC(gcm394_base_video_device::tmap0_regs_w));
795 map(0x007016, 0x00701b).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap1_regs_r), FUNC(gcm394_base_video_device::tmap1_regs_w));
796
797 map(0x00701c, 0x00701c).w(m_spg_video, FUNC(gcm394_base_video_device::video_701c_w)); // these 3 are written together in paccon
798 map(0x00701d, 0x00701d).w(m_spg_video, FUNC(gcm394_base_video_device::video_701d_w));
799 map(0x00701e, 0x00701e).w(m_spg_video, FUNC(gcm394_base_video_device::video_701e_w));
800
801 // tilebase LSBs
802 map(0x007020, 0x007020).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap0_tilebase_lsb_r), FUNC(gcm394_base_video_device::tmap0_tilebase_lsb_w)); // tilebase, written with other tmap0 regs
803 map(0x007021, 0x007021).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap1_tilebase_lsb_r), FUNC(gcm394_base_video_device::tmap1_tilebase_lsb_w)); // tilebase, written with other tmap1 regs
804 map(0x007022, 0x007022).rw(m_spg_video, FUNC(gcm394_base_video_device::sprite_7022_gfxbase_lsb_r), FUNC(gcm394_base_video_device::sprite_7022_gfxbase_lsb_w)); // sprite tilebase written as 7022, 702d and 7042 group
805 map(0x007023, 0x007023).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap2_tilebase_lsb_r), FUNC(gcm394_base_video_device::tmap2_tilebase_lsb_w)); // written with other tmap2 regs (roz layer or line layer?)
806 map(0x007024, 0x007024).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap3_tilebase_lsb_r), FUNC(gcm394_base_video_device::tmap3_tilebase_lsb_w)); // written with other tmap3 regs (roz layer or line layer?)
807
808 map(0x00702a, 0x00702a).w(m_spg_video, FUNC(gcm394_base_video_device::video_702a_w)); // blend level control
809
810 // tilebase MSBs
811 map(0x00702b, 0x00702b).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap0_tilebase_msb_r), FUNC(gcm394_base_video_device::tmap0_tilebase_msb_w)); // written with other tmap0 regs
812 map(0x00702c, 0x00702c).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap1_tilebase_msb_r), FUNC(gcm394_base_video_device::tmap1_tilebase_msb_w)); // written with other tmap1 regs
813 map(0x00702d, 0x00702d).rw(m_spg_video, FUNC(gcm394_base_video_device::sprite_702d_gfxbase_msb_r), FUNC(gcm394_base_video_device::sprite_702d_gfxbase_msb_w)); // sprites, written as 7022, 702d and 7042 group
814 map(0x00702e, 0x00702e).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap2_tilebase_msb_r), FUNC(gcm394_base_video_device::tmap2_tilebase_msb_w)); // written with other tmap2 regs (roz layer or line layer?)
815 map(0x00702f, 0x00702f).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap3_tilebase_msb_r), FUNC(gcm394_base_video_device::tmap3_tilebase_msb_w)); // written with other tmap3 regs (roz layer or line layer?)
816
817 map(0x007036, 0x007036).w(m_spg_video, FUNC(gcm394_base_video_device::split_irq_xpos_w));
818 map(0x007037, 0x007037).w(m_spg_video, FUNC(gcm394_base_video_device::split_irq_ypos_w));
819
820
821 map(0x007030, 0x007030).rw(m_spg_video, FUNC(gcm394_base_video_device::video_7030_brightness_r), FUNC(gcm394_base_video_device::video_7030_brightness_w));
822 map(0x007038, 0x007038).r(m_spg_video, FUNC(gcm394_base_video_device::video_curline_r));
823 map(0x00703a, 0x00703a).rw(m_spg_video, FUNC(gcm394_base_video_device::video_703a_palettebank_r), FUNC(gcm394_base_video_device::video_703a_palettebank_w));
824 map(0x00703c, 0x00703c).rw(m_spg_video, FUNC(gcm394_base_video_device::video_703c_tvcontrol1_r), FUNC(gcm394_base_video_device::video_703c_tvcontrol1_w)); // TV Control 1
825
826 map(0x007042, 0x007042).rw(m_spg_video, FUNC(gcm394_base_video_device::sprite_7042_extra_r), FUNC(gcm394_base_video_device::sprite_7042_extra_w)); // maybe sprites, written as 7022, 702d and 7042 group
827
828 map(0x007051, 0x007051).r(m_spg_video, FUNC(gcm394_base_video_device::video_7051_r)); // wrlshunt checks this (doesn't exist on older SPG?)
829
830 map(0x007062, 0x007062).rw(m_spg_video, FUNC(gcm394_base_video_device::videoirq_source_enable_r), FUNC(gcm394_base_video_device::videoirq_source_enable_w));
831 map(0x007063, 0x007063).rw(m_spg_video, FUNC(gcm394_base_video_device::video_7063_videoirq_source_r), FUNC(gcm394_base_video_device::video_7063_videoirq_source_ack_w));
832
833 // note, 70 / 71 / 72 are the same offsets used for DMA as in spg2xx video device
834 map(0x007070, 0x007070).w(m_spg_video, FUNC(gcm394_base_video_device::video_dma_source_w)); // video dma, not system dma? (sets pointers to ram buffers)
835 map(0x007071, 0x007071).w(m_spg_video, FUNC(gcm394_base_video_device::video_dma_dest_w)); // sets pointers to 7300, 7400 ram areas below
836 map(0x007072, 0x007072).rw(m_spg_video, FUNC(gcm394_base_video_device::video_dma_size_busy_r), FUNC(gcm394_base_video_device::video_dma_size_trigger_w)); //
837
838 // these don't exist on older SPG
839 map(0x00707c, 0x00707c).r(m_spg_video, FUNC(gcm394_base_video_device::video_707c_r)); // wrlshunt polls this waiting for 0x8000, is this some kind of manual port-based data upload?
840
841 map(0x00707e, 0x00707e).w(m_spg_video, FUNC(gcm394_base_video_device::video_707e_spritebank_w)); // written around same time as DMA, seems to select alt sprite bank
842 map(0x00707f, 0x00707f).rw(m_spg_video, FUNC(gcm394_base_video_device::video_707f_r), FUNC(gcm394_base_video_device::video_707f_w));
843
844 // another set of registers for something?
845 map(0x007080, 0x007080).w(m_spg_video, FUNC(gcm394_base_video_device::video_7080_w));
846 map(0x007081, 0x007081).w(m_spg_video, FUNC(gcm394_base_video_device::video_7081_w));
847 map(0x007082, 0x007082).w(m_spg_video, FUNC(gcm394_base_video_device::video_7082_w));
848 map(0x007083, 0x007083).rw(m_spg_video, FUNC(gcm394_base_video_device::video_7083_r), FUNC(gcm394_base_video_device::video_7083_w));
849 map(0x007084, 0x007084).w(m_spg_video, FUNC(gcm394_base_video_device::video_7084_w));
850 map(0x007085, 0x007085).w(m_spg_video, FUNC(gcm394_base_video_device::video_7085_w));
851 map(0x007086, 0x007086).w(m_spg_video, FUNC(gcm394_base_video_device::video_7086_w));
852 map(0x007087, 0x007087).w(m_spg_video, FUNC(gcm394_base_video_device::video_7087_w));
853 map(0x007088, 0x007088).w(m_spg_video, FUNC(gcm394_base_video_device::video_7088_w));
854
855 map(0x0070e0, 0x0070e0).r(m_spg_video, FUNC(gcm394_base_video_device::video_70e0_r)); // gormiti checks this
856
857 // ######################################################################################################################################################################################
858 // 73xx-77xx = video ram
859 // ######################################################################################################################################################################################
860
861 map(0x007100, 0x0071ff).ram().share("rowscroll"); // based on jak_s500
862 map(0x007200, 0x0072ff).ram().share("rowzoom"); // ^^
863
864 map(0x007300, 0x0073ff).rw(m_spg_video, FUNC(gcm394_base_video_device::palette_r), FUNC(gcm394_base_video_device::palette_w));
865
866 map(0x007400, 0x0077ff).rw(m_spg_video, FUNC(gcm394_base_video_device::spriteram_r), FUNC(gcm394_base_video_device::spriteram_w));
867
868 // ######################################################################################################################################################################################
869 // 78xx region = system regs?
870 // ######################################################################################################################################################################################
871
872 map(0x007803, 0x007803).rw(FUNC(sunplus_gcm394_base_device::unkarea_7803_r), FUNC(sunplus_gcm394_base_device::unkarea_7803_w));
873
874 map(0x007807, 0x007807).w(FUNC(sunplus_gcm394_base_device::unkarea_7807_w));
875 // 7808
876
877 // 780a
878
879 map(0x00780c, 0x00780c).w(FUNC(sunplus_gcm394_base_device::waitmode_enter_780c_w));
880
881 map(0x00780f, 0x00780f).r(FUNC(sunplus_gcm394_base_device::unkarea_780f_status_r));
882
883 map(0x007810, 0x007810).rw(FUNC(sunplus_gcm394_base_device::membankswitch_7810_r), FUNC(sunplus_gcm394_base_device::membankswitch_7810_w)); // 7810 Bank Switch Control Register (P_BankSwitch_Ctrl) (maybe)
884
885 map(0x007819, 0x007819).rw(FUNC(sunplus_gcm394_base_device::unkarea_7819_r), FUNC(sunplus_gcm394_base_device::unkarea_7819_w));
886
887 map(0x007816, 0x007816).w(FUNC(sunplus_gcm394_base_device::unkarea_7816_w));
888 map(0x007817, 0x007817).w(FUNC(sunplus_gcm394_base_device::unkarea_7817_w));
889
890 // ######################################################################################################################################################################################
891 // 782x region = memory config / control
892 // ######################################################################################################################################################################################
893 // wrlshunt | smartfp
894 map(0x007820, 0x007824).w(FUNC(sunplus_gcm394_base_device::chipselect_csx_memory_device_control_w)); // 7f8a (7f8a before DMA from ROM to RAM, 008a after DMA from ROM to RAM) | 3f04 7820 Chip Select (CS0) Memory Device Control (P_MC50_Ctrl)
895 // 7f47 | 0044 7821 Chip Select (CS1) Memory Device Control (P_MC51_Ctrl)
896 // 0047 | 1f44 7822 Chip Select (CS2) Memory Device Control (P_MC52_Ctrl)
897 // 0047 | 0044 7823 Chip Select (CS3) Memory Device Control (P_MC53_Ctrl)
898 // 0047 | 0044 7824 Chip Select (CS4) Memory Device Control (P_MC54_Ctrl)
899
900 map(0x00782d, 0x00782d).rw(FUNC(sunplus_gcm394_base_device::unkarea_782d_r), FUNC(sunplus_gcm394_base_device::unkarea_782d_w)); // on startup
901 // 782f
902
903 map(0x007835, 0x007835).w(FUNC(sunplus_gcm394_base_device::unkarea_7835_w));
904
905 // 783a
906 // 783b
907 // 783c
908 // 783d
909 // 783e
910
911 // 7840 - accessed by code in RAM when changing bank in tkmag220
912 // 7841 - ^^
913
914 // ######################################################################################################################################################################################
915 // 786x - 787x - IO related?
916 // ######################################################################################################################################################################################
917
918 map(0x007860, 0x007860).rw(FUNC(sunplus_gcm394_base_device::ioarea_7860_porta_r), FUNC(sunplus_gcm394_base_device::ioarea_7860_porta_w)); // 7860 I/O PortA Data Register
919 map(0x007861, 0x007861).rw(FUNC(sunplus_gcm394_base_device::ioarea_7861_porta_buffer_r), FUNC(sunplus_gcm394_base_device::ioarea_7861_porta_buffer_w)); // 7861 I/O PortA Buffer Register
920 map(0x007862, 0x007862).rw(FUNC(sunplus_gcm394_base_device::ioarea_7862_porta_direction_r), FUNC(sunplus_gcm394_base_device::ioarea_7862_porta_direction_w)); // 7862 I/O PortA Direction Register
921 map(0x007863, 0x007863).rw(FUNC(sunplus_gcm394_base_device::ioarea_7863_porta_attribute_r), FUNC(sunplus_gcm394_base_device::ioarea_7863_porta_attribute_w)); // 7863 I/O PortA Attribute Register
922
923 map(0x007868, 0x007868).rw(FUNC(sunplus_gcm394_base_device::ioarea_7868_portb_r), FUNC(sunplus_gcm394_base_device::ioarea_7868_portb_w)); // on startup // 7868 I/O PortB Data Register
924 map(0x007869, 0x007869).rw(FUNC(sunplus_gcm394_base_device::ioarea_7869_portb_buffer_r), FUNC(sunplus_gcm394_base_device::ioarea_7869_portb_buffer_w)); // 7869 I/O PortB Buffer Register // jak_s500
925 map(0x00786a, 0x00786a).rw(FUNC(sunplus_gcm394_base_device::ioarea_786a_portb_direction_r), FUNC(sunplus_gcm394_base_device::ioarea_786a_portb_direction_w)); // 786a I/O PortB Direction Register
926 map(0x00786b, 0x00786b).rw(FUNC(sunplus_gcm394_base_device::ioarea_786b_portb_attribute_r), FUNC(sunplus_gcm394_base_device::ioarea_786b_portb_attribute_w)); // 786b I/O PortB Attribute Register
927 // 786c I/O PortB Latch / Wakeup
928
929 map(0x007870, 0x007870).rw(FUNC(sunplus_gcm394_base_device::ioarea_7870_portc_r) ,FUNC(sunplus_gcm394_base_device::ioarea_7870_portc_w)); // 7870 I/O PortC Data Register
930 map(0x007871, 0x007871).rw(FUNC(sunplus_gcm394_base_device::ioarea_7871_portc_buffer_r), FUNC(sunplus_gcm394_base_device::ioarea_7871_portc_buffer_w)); // 7871 I/O PortC Buffer Register
931 map(0x007872, 0x007872).rw(FUNC(sunplus_gcm394_base_device::ioarea_7872_portc_direction_r), FUNC(sunplus_gcm394_base_device::ioarea_7872_portc_direction_w)); // 7872 I/O PortC Direction Register
932 map(0x007873, 0x007873).rw(FUNC(sunplus_gcm394_base_device::ioarea_7873_portc_attribute_r), FUNC(sunplus_gcm394_base_device::ioarea_7873_portc_attribute_w)); // 7873 I/O PortC Attribute Register
933
934 // 7874 (data 0x1249) (bkrankp data 0x36db)
935
936 map(0x007878, 0x007878).rw(FUNC(sunplus_gcm394_base_device::ioarea_7878_portd_r) ,FUNC(sunplus_gcm394_base_device::ioarea_7878_portd_w)); // 7878 I/O PortD Data Register
937 map(0x007879, 0x007879).rw(FUNC(sunplus_gcm394_base_device::ioarea_7879_portd_buffer_r), FUNC(sunplus_gcm394_base_device::ioarea_7879_portd_buffer_w)); // 7879 I/O PortD Buffer Register
938 map(0x00787a, 0x00787a).rw(FUNC(sunplus_gcm394_base_device::ioarea_787a_portd_direction_r), FUNC(sunplus_gcm394_base_device::ioarea_787a_portd_direction_w)); // 787a I/O PortD Direction Register
939 map(0x00787b, 0x00787b).rw(FUNC(sunplus_gcm394_base_device::ioarea_787b_portd_attribute_r), FUNC(sunplus_gcm394_base_device::ioarea_787b_portd_attribute_w)); // 787b I/O PortD Attribute Register
940
941 // 787c (data 0x1249) (bkrankp data 0x36db)
942 // 787e (data 0x1249) (bkrankp data 0x36db)
943
944 // 7880
945
946 map(0x007882, 0x007882).rw(FUNC(sunplus_gcm394_base_device::unkarea_7882_r), FUNC(sunplus_gcm394_base_device::unkarea_7882_w));
947 map(0x007883, 0x007883).rw(FUNC(sunplus_gcm394_base_device::unkarea_7883_r), FUNC(sunplus_gcm394_base_device::unkarea_7883_w));
948
949 // 0x7888 (data 0x1249) (bkrankp data 0x36db), written with 7874 / 787c / 787e above
950
951 // ######################################################################################################################################################################################
952 // 78ax - interrupt controller?
953 // ######################################################################################################################################################################################
954
955 map(0x0078a0, 0x0078a0).rw(FUNC(sunplus_gcm394_base_device::unkarea_78a0_r), FUNC(sunplus_gcm394_base_device::unkarea_78a0_w));
956 map(0x0078a1, 0x0078a1).r(FUNC(sunplus_gcm394_base_device::unkarea_78a1_r));
957
958 map(0x0078a4, 0x0078a4).w(FUNC(sunplus_gcm394_base_device::unkarea_78a4_w));
959 map(0x0078a5, 0x0078a5).w(FUNC(sunplus_gcm394_base_device::unkarea_78a5_w));
960 map(0x0078a6, 0x0078a6).w(FUNC(sunplus_gcm394_base_device::unkarea_78a6_w));
961
962 map(0x0078a8, 0x0078a8).w(FUNC(sunplus_gcm394_base_device::unkarea_78a8_w));
963
964 // ######################################################################################################################################################################################
965 // 78bx - timer control?
966 // ######################################################################################################################################################################################
967
968 map(0x0078b0, 0x0078b0).w(FUNC(sunplus_gcm394_base_device::unkarea_78b0_w)); // 78b0 TimeBase A Control Register (P_TimeBaseA_Ctrl)
969 map(0x0078b1, 0x0078b1).w(FUNC(sunplus_gcm394_base_device::unkarea_78b1_w)); // 78b1 TimeBase B Control Register (P_TimeBaseB_Ctrl)
970 map(0x0078b2, 0x0078b2).rw(FUNC(sunplus_gcm394_base_device::unkarea_78b2_r), FUNC(sunplus_gcm394_base_device::unkarea_78b2_w)); // 78b2 TimeBase C Control Register (P_TimeBaseC_Ctrl)
971
972 map(0x0078b8, 0x0078b8).w(FUNC(sunplus_gcm394_base_device::unkarea_78b8_w)); // 78b8 TimeBase Counter Reset Register (P_TimeBase_Reset)
973
974 map(0x0078c0, 0x0078c0).r(FUNC(sunplus_gcm394_base_device::unkarea_78c0_r)); // beijuehh
975
976 map(0x0078d0, 0x0078d0).r(FUNC(sunplus_gcm394_base_device::unkarea_78d0_r)); // jak_s500
977 map(0x0078d8, 0x0078d8).r(FUNC(sunplus_gcm394_base_device::unkarea_78d8_r)); // jak_tsh
978
979
980 // ######################################################################################################################################################################################
981 // 78fx - unknown
982 // ######################################################################################################################################################################################
983
984 map(0x0078f0, 0x0078f0).w(FUNC(sunplus_gcm394_base_device::unkarea_78f0_w));
985
986 map(0x0078fb, 0x0078fb).r(FUNC(sunplus_gcm394_base_device::unkarea_78fb_status_r));
987
988 // ######################################################################################################################################################################################
989 // 793x - misc?
990 // ######################################################################################################################################################################################
991
992 map(0x007904, 0x007904).r(FUNC(sunplus_gcm394_base_device::unkarea_7904_r)); // lazertag after a while
993
994 // possible rtc?
995 map(0x007934, 0x007934).rw(FUNC(sunplus_gcm394_base_device::unkarea_7934_r), FUNC(sunplus_gcm394_base_device::unkarea_7934_w));
996 map(0x007935, 0x007935).rw(FUNC(sunplus_gcm394_base_device::unkarea_7935_r), FUNC(sunplus_gcm394_base_device::unkarea_7935_w));
997 map(0x007936, 0x007936).rw(FUNC(sunplus_gcm394_base_device::unkarea_7936_r), FUNC(sunplus_gcm394_base_device::unkarea_7936_w));
998
999 // ######################################################################################################################################################################################
1000 // 794x - SPI
1001 // ######################################################################################################################################################################################
1002
1003 //7940 P_SPI_Ctrl - SPI Control Register
1004 //7941 P_SPI_TXStatus - SPI Transmit Status Register
1005 map(0x007942, 0x007942).w(FUNC(sunplus_gcm394_base_device::spi_7942_txdata_w)); //7942 P_SPI_TXData - SPI Transmit FIFO Register
1006 //7943 P_SPI_RXStatus - SPI Receive Status Register
1007 map(0x007944, 0x007944).r(FUNC(sunplus_gcm394_base_device::spi_7944_rxdata_r)); // 7944 P_SPI_RXData - SPI Receive FIFO Register (jak_s500 accelerometer) (also the SPI ROM DMA input port for bkrankp?)
1008 map(0x007945, 0x007945).r(FUNC(sunplus_gcm394_base_device::spi_7945_misc_control_reg_r)); // 7945 P_SPI_Misc - SPI Misc Control Register (jak_s500 accelerometer)
1009
1010 // ######################################################################################################################################################################################
1011 // 796x - unknown
1012 // ######################################################################################################################################################################################
1013
1014 // possible adc?
1015 map(0x007960, 0x007960).w(FUNC(sunplus_gcm394_base_device::unkarea_7960_w));
1016 map(0x007961, 0x007961).rw(FUNC(sunplus_gcm394_base_device::unkarea_7961_r), FUNC(sunplus_gcm394_base_device::unkarea_7961_w));
1017
1018 // ######################################################################################################################################################################################
1019 // 7axx region = system (including dma)
1020 // ######################################################################################################################################################################################
1021
1022 map(0x007a35, 0x007a35).r(FUNC(sunplus_gcm394_base_device::system_7a35_r)); // wlsair60
1023 map(0x007a37, 0x007a37).r(FUNC(sunplus_gcm394_base_device::system_7a37_r)); // wlsair60
1024 map(0x007a39, 0x007a39).r(FUNC(sunplus_gcm394_base_device::system_7a39_r)); // wlsair60
1025 map(0x007a3a, 0x007a3a).r(FUNC(sunplus_gcm394_base_device::system_7a3a_r)); // ?
1026 map(0x007a46, 0x007a46).r(FUNC(sunplus_gcm394_base_device::system_7a46_r)); // wlsair60
1027 map(0x007a54, 0x007a54).r(FUNC(sunplus_gcm394_base_device::system_7a54_r)); // wlsair60
1028
1029 map(0x007a80, 0x007a87).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel0_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel0_w));
1030 map(0x007a88, 0x007a8f).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel1_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel1_w)); // jak_tsm writes here
1031 map(0x007a90, 0x007a97).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel2_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel2_w)); // bkrankp writes here (is this on all types or just SPI?)
1032 map(0x007a98, 0x007a9f).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel3_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel3_w)); // not seen, but probably
1033
1034 map(0x007abe, 0x007abe).rw(FUNC(sunplus_gcm394_base_device::system_dma_memtype_r), FUNC(sunplus_gcm394_base_device::system_dma_memtype_w)); // 7abe - written with DMA stuff (source type for each channel so that device handles timings properly?)
1035 map(0x007abf, 0x007abf).rw(FUNC(sunplus_gcm394_base_device::system_dma_status_r), FUNC(sunplus_gcm394_base_device::system_dma_7abf_unk_w));
1036
1037 // ######################################################################################################################################################################################
1038 // 7bxx-7fxx = audio
1039 // ######################################################################################################################################################################################
1040
1041 map(0x007b80, 0x007bbf).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::control_r), FUNC(sunplus_gcm394_audio_device::control_w));
1042 map(0x007c00, 0x007dff).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::audio_r), FUNC(sunplus_gcm394_audio_device::audio_w));
1043 map(0x007e00, 0x007fff).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::audio_phase_r), FUNC(sunplus_gcm394_audio_device::audio_phase_w));
1044
1045 }
1046
gcm394_internal_map(address_map & map)1047 void sunplus_gcm394_base_device::gcm394_internal_map(address_map& map)
1048 {
1049 sunplus_gcm394_base_device::base_internal_map(map);
1050
1051 // no internal ROM on this model?
1052
1053 map(0x08000, 0x0ffff).r(FUNC(sunplus_gcm394_base_device::internalrom_lower32_r)).nopw();
1054
1055 map(0x10000, 0x01ffff).nopr();
1056
1057 map(0x020000, 0x1fffff).rw(FUNC(sunplus_gcm394_base_device::cs_space_r), FUNC(sunplus_gcm394_base_device::cs_space_w));
1058 map(0x200000, 0x3fffff).rw(FUNC(sunplus_gcm394_base_device::cs_bank_space_r), FUNC(sunplus_gcm394_base_device::cs_bank_space_w));
1059 }
1060
cs_space_r(offs_t offset)1061 uint16_t sunplus_gcm394_base_device::cs_space_r(offs_t offset)
1062 {
1063 return m_cs_space->read_word(offset);
1064 }
1065
cs_space_w(offs_t offset,uint16_t data)1066 void sunplus_gcm394_base_device::cs_space_w(offs_t offset, uint16_t data)
1067 {
1068 m_cs_space->write_word(offset, data);
1069 }
cs_bank_space_r(offs_t offset)1070 uint16_t sunplus_gcm394_base_device::cs_bank_space_r(offs_t offset)
1071 {
1072 int bank = m_membankswitch_7810 & 0x3f;
1073 int realoffset = offset + (bank * 0x200000) - m_csbase;
1074
1075 if (realoffset < 0)
1076 {
1077 logerror("read real offset < 0\n");
1078 return 0;
1079 }
1080
1081 return m_cs_space->read_word(realoffset);
1082 }
1083
cs_bank_space_w(offs_t offset,uint16_t data)1084 void sunplus_gcm394_base_device::cs_bank_space_w(offs_t offset, uint16_t data)
1085 {
1086 int bank = m_membankswitch_7810 & 0x3f;
1087 int realoffset = offset + (bank * 0x200000) - m_csbase;
1088
1089 if (realoffset < 0)
1090 {
1091 logerror("write real offset < 0\n");
1092 return;
1093 }
1094
1095 m_cs_space->write_word(realoffset, data);
1096 }
1097
1098
1099
internalrom_lower32_r(offs_t offset)1100 uint16_t sunplus_gcm394_base_device::internalrom_lower32_r(offs_t offset)
1101 {
1102 if (m_boot_mode == 0)
1103 {
1104 uint16_t* introm = (uint16_t*)m_internalrom->base();
1105 return introm[offset];
1106 }
1107 else
1108 {
1109 if (!m_cs_space)
1110 return 0x0000;
1111
1112 uint16_t val = m_cs_space->read_word(offset+0x8000);
1113 return val;
1114 }
1115 }
1116
1117
1118 // GPR27P512A = C2 76
1119 // HY27UF081G2A = AD F1 80 1D
1120 // H27U518S2C = AD 76
1121
nand_7854_r()1122 uint16_t generalplus_gpac800_device::nand_7854_r()
1123 {
1124 // TODO: use actual NAND / Smart Media devices once this is better understood.
1125 // The games have extensive checks on startup to determine the flash types, but then it appears that
1126 // certain games (eg jak_tsm) will only function correctly with specific ones, even if the code
1127 // continues regardless. Others will bail early if they don't get what they want.
1128
1129 // I think some unSP core maths bugs are causing severe issues after the initial load for jak_tsm
1130 // at the moment, possibly the same ones that are causing rendering issues in the jak_gtg bitmap
1131 // test and seemingly incorrect road data for jak_car2, either that or the hookup here is very
1132 // non-standard outside of the ident codes
1133
1134 // real TSM code starts at 4c000
1135
1136
1137 //logerror("%s:sunplus_gcm394_base_device::nand_7854_r\n", machine().describe_context());
1138
1139 if (m_nandcommand == 0x90) // read ident
1140 {
1141 logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ IDENT byte %d\n", machine().describe_context(), m_curblockaddr);
1142
1143 uint8_t data = 0x00;
1144
1145 if (m_romtype == 0)
1146 {
1147 if (m_curblockaddr == 0)
1148 data = 0xc2;
1149 else
1150 data = 0x76;
1151 }
1152 else if (m_romtype == 1)
1153 {
1154 if (m_curblockaddr == 0)
1155 data = 0xad;
1156 else if (m_curblockaddr == 1)
1157 data = 0x76;
1158 }
1159 else
1160 {
1161 if (m_curblockaddr == 0)
1162 data = 0xad;
1163 else if (m_curblockaddr == 1)
1164 data = 0xf1;
1165 else if (m_curblockaddr == 2)
1166 data = 0x80;
1167 else if (m_curblockaddr == 3)
1168 data = 0x1d;
1169 }
1170
1171 m_curblockaddr++;
1172
1173 return data;
1174 }
1175 else if (m_nandcommand == 0x00 || m_nandcommand == 0x01 || m_nandcommand == 0x50)
1176 {
1177 //logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ DATA byte %d\n", machine().describe_context(), m_curblockaddr);
1178
1179 uint8_t data = m_nand_read_cb(m_effectiveaddress + m_curblockaddr);
1180
1181 m_curblockaddr++;
1182
1183 return data;
1184 }
1185 else if (m_nandcommand == 0x70) // read status
1186 {
1187 logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ STATUS byte %d\n", machine().describe_context(), m_curblockaddr);
1188
1189 return 0xffff;
1190 }
1191 else
1192 {
1193 logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ UNKNOWN byte %d\n", machine().describe_context(), m_curblockaddr);
1194 return 0xffff;
1195 }
1196
1197 return 0x0000;
1198 }
1199
1200 // 7998
1201
nand_command_w(uint16_t data)1202 void generalplus_gpac800_device::nand_command_w(uint16_t data)
1203 {
1204 logerror("%s:sunplus_gcm394_base_device::nand_command_w %04x\n", machine().describe_context(), data);
1205 m_nandcommand = data;
1206 }
1207
nand_addr_low_w(uint16_t data)1208 void generalplus_gpac800_device::nand_addr_low_w(uint16_t data)
1209 {
1210 logerror("%s:sunplus_gcm394_base_device::nand_addr_low_w %04x\n", machine().describe_context(), data);
1211 m_nand_addr_low = data;
1212 m_curblockaddr = 0;
1213 }
1214
recalculate_calculate_effective_nand_address()1215 void generalplus_gpac800_device::recalculate_calculate_effective_nand_address()
1216 {
1217 uint8_t type = m_nand_7856 & 0xf;
1218 uint8_t shift = 0;
1219 uint32_t page_offset = 0;
1220
1221 if (type == 7)
1222 shift = 4;
1223 else if (type == 11)
1224 shift = 5;
1225
1226 if (m_nandcommand == 0x01)
1227 page_offset = 256;
1228 else if (m_nandcommand == 0x50)
1229 page_offset = 512;
1230
1231 uint32_t nandaddress = (m_nand_addr_high << 16) | m_nand_addr_low;
1232
1233 if (m_nand_7850 & 0x4000)
1234 nandaddress *= 2;
1235
1236 uint32_t page = type ? nandaddress : /*(m_nand_7850 & 0x4000) ?*/ nandaddress >> 8 /*: nandaddress >> 9*/;
1237 m_effectiveaddress = (page * 528 + page_offset) << shift;
1238
1239 logerror("%s: Requested address is %08x, translating to %08x\n", machine().describe_context(), nandaddress, m_effectiveaddress);
1240 }
1241
nand_addr_high_w(uint16_t data)1242 void generalplus_gpac800_device::nand_addr_high_w(uint16_t data)
1243 {
1244 logerror("%s:sunplus_gcm394_base_device::nand_addr_high_w %04x\n", machine().describe_context(), data);
1245 m_nand_addr_high = data;
1246
1247 recalculate_calculate_effective_nand_address();
1248
1249 m_curblockaddr = 0;
1250 }
1251
nand_dma_ctrl_w(uint16_t data)1252 void generalplus_gpac800_device::nand_dma_ctrl_w(uint16_t data)
1253 {
1254 logerror("%s:sunplus_gcm394_base_device::nand_dma_ctrl_w(?) %04x\n", machine().describe_context(), data);
1255 m_nand_dma_ctrl = data;
1256 }
1257
nand_7850_status_r()1258 uint16_t generalplus_gpac800_device::nand_7850_status_r()
1259 {
1260 // 0x8000 = ready
1261 return m_nand_7850 | 0x8000;
1262 }
1263
nand_7850_w(uint16_t data)1264 void generalplus_gpac800_device::nand_7850_w(uint16_t data)
1265 {
1266 logerror("%s:sunplus_gcm394_base_device::nand_7850_w %04x\n", machine().describe_context(), data);
1267 m_nand_7850 = data;
1268 }
1269
nand_7856_type_w(uint16_t data)1270 void generalplus_gpac800_device::nand_7856_type_w(uint16_t data)
1271 {
1272 logerror("%s:sunplus_gcm394_base_device::nand_7856_type_w %04x\n", machine().describe_context(), data);
1273 m_nand_7856 = data;
1274
1275 recalculate_calculate_effective_nand_address();
1276
1277 m_curblockaddr = 0;
1278 }
1279
nand_7857_w(uint16_t data)1280 void generalplus_gpac800_device::nand_7857_w(uint16_t data)
1281 {
1282 logerror("%s:sunplus_gcm394_base_device::nand_7857_w %04x\n", machine().describe_context(), data);
1283 m_nand_7857 = data;
1284 }
1285
nand_785b_w(uint16_t data)1286 void generalplus_gpac800_device::nand_785b_w(uint16_t data)
1287 {
1288 logerror("%s:sunplus_gcm394_base_device::nand_785b_w %04x\n", machine().describe_context(), data);
1289 m_nand_785b = data;
1290 }
1291
nand_785c_w(uint16_t data)1292 void generalplus_gpac800_device::nand_785c_w(uint16_t data)
1293 {
1294 logerror("%s:sunplus_gcm394_base_device::nand_785c_w %04x\n", machine().describe_context(), data);
1295 m_nand_785c = data;
1296 }
1297
nand_785d_w(uint16_t data)1298 void generalplus_gpac800_device::nand_785d_w(uint16_t data)
1299 {
1300 logerror("%s:sunplus_gcm394_base_device::nand_785d_w %04x\n", machine().describe_context(), data);
1301 m_nand_785d = data;
1302 }
1303
1304 // [:maincpu] ':maincpu' (00146D) jak_tsm
nand_785e_r()1305 uint16_t generalplus_gpac800_device::nand_785e_r()
1306 {
1307 return 0x0000;
1308 }
1309
1310 //[:maincpu] ':maincpu' (001490) jak_tsm
nand_ecc_low_byte_error_flag_1_r()1311 uint16_t generalplus_gpac800_device::nand_ecc_low_byte_error_flag_1_r()
1312 {
1313 return 0x0000;
1314 }
1315
1316 /*
1317 UNMAPPED reads writes
1318
1319 jak_tsm uses these (all iniitalized near start)
1320 unclear if these are specific to the GPAC800 type, or present in the older types
1321
1322 [:maincpu] ':maincpu' (00043F):sunplus_gcm394_base_device::unk_w @ 0x780a (data 0x0000)
1323 [:maincpu] ':maincpu' (000442):sunplus_gcm394_base_device::unk_w @ 0x7808 (data 0x0000)
1324 [:maincpu] ':maincpu' (000445):sunplus_gcm394_base_device::unk_w @ 0x782f (data 0x0002)
1325 [:maincpu] ':maincpu' (000449):sunplus_gcm394_base_device::unk_w @ 0x783d (data 0x05d9)
1326 [:maincpu] ':maincpu' (00044D):sunplus_gcm394_base_device::unk_w @ 0x783c (data 0x0a57)
1327 [:maincpu] ':maincpu' (000451):sunplus_gcm394_base_device::unk_w @ 0x783b (data 0x2400)
1328 [:maincpu] ':maincpu' (000454):sunplus_gcm394_base_device::unk_w @ 0x783e (data 0x0002)
1329 [:maincpu] ':maincpu' (000458):sunplus_gcm394_base_device::unk_w @ 0x783a (data 0x3011)
1330 [:maincpu] ':maincpu' (00045B):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x0000)
1331 [:maincpu] ':maincpu' (00045D):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x0000)
1332 [:maincpu] ':maincpu' (00045F):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x0000)
1333 [:maincpu] ':maincpu' (000461):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x0000)
1334
1335 jak_car2 uses these
1336
1337 [:maincpu] ':maincpu' (004056):sunplus_gcm394_base_device::unk_w @ 0x782f (data 0x0002)
1338 [:maincpu] ':maincpu' (004059):sunplus_gcm394_base_device::unk_w @ 0x783d (data 0x05d9)
1339 [:maincpu] ':maincpu' (00405C):sunplus_gcm394_base_device::unk_w @ 0x783c (data 0x0a57)
1340 [:maincpu] ':maincpu' (00405F):sunplus_gcm394_base_device::unk_w @ 0x783b (data 0x2400)
1341 [:maincpu] ':maincpu' (004062):sunplus_gcm394_base_device::unk_w @ 0x783e (data 0x0002)
1342 [:maincpu] ':maincpu' (004065):sunplus_gcm394_base_device::unk_w @ 0x783a (data 0x3011)
1343 [:maincpu] ':maincpu' (004069):sunplus_gcm394_base_device::unk_r @ 0x7880
1344 [:maincpu] ':maincpu' (00406F):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x1249)
1345 [:maincpu] ':maincpu' (004071):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x1249)
1346 [:maincpu] ':maincpu' (004073):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x1249)
1347 [:maincpu] ':maincpu' (004075):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x1249)
1348 [:maincpu] ':maincpu' (004088):sunplus_gcm394_base_device::unk_w @ 0x7841 (data 0x000f)
1349 [:maincpu] ':maincpu' (00408F):sunplus_gcm394_base_device::unk_w @ 0x780a (data 0x0000)
1350 [:maincpu] ':maincpu' (004092):sunplus_gcm394_base_device::unk_w @ 0x7808 (data 0x0002)
1351
1352 [:maincpu] ':maincpu' (03000A):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x36db)
1353 [:maincpu] ':maincpu' (03000C):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x36db)
1354 [:maincpu] ':maincpu' (03000E):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x36db)
1355 [:maincpu] ':maincpu' (030010):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x36db)
1356 [:maincpu] ':maincpu' (030013):sunplus_gcm394_base_device::unk_w @ 0x787f (data 0x0010)
1357 [:maincpu] ':maincpu' (03001D):sunplus_gcm394_base_device::unk_w @ 0x7804 (data 0x1c7f)
1358 [:maincpu] ':maincpu' (030023):sunplus_gcm394_base_device::unk_w @ 0x7805 (data 0xcdf0)
1359 [:maincpu] ':maincpu' (03E645):sunplus_gcm394_base_device::unk_w @ 0x7861 (data 0x1f66)
1360 [:maincpu] ':maincpu' (03E64C):sunplus_gcm394_base_device::unk_w @ 0x786b (data 0x0000)
1361 [:maincpu] ':maincpu' (03E64F):sunplus_gcm394_base_device::unk_w @ 0x7869 (data 0x0000)
1362 [:maincpu] ':maincpu' (03E652):sunplus_gcm394_base_device::unk_w @ 0x786a (data 0x0000)
1363 [:maincpu] ':maincpu' (03E65B):sunplus_gcm394_base_device::unk_w @ 0x7966 (data 0x0001)
1364 [:maincpu] ':maincpu' (03CBD0):sunplus_gcm394_base_device::unk_w @ 0x7871 (data 0x0000)
1365
1366 -- this one seems like a common alt type of DMA, used in both hw types as it polls 707c status before doing it
1367 [:maincpu] ':maincpu' (03B4C7):sunplus_gcm394_base_device::unk_w @ 0x707c (data 0x0001)
1368 -- also video / alt dma?
1369 [:maincpu] ':maincpu' (068C15):sunplus_gcm394_base_device::unk_r @ 0x707e
1370
1371 beambox sets things up with different values (ultimately stalls on some check, maybe seeprom?)
1372
1373 [:maincpu] ':maincpu' (00043F):sunplus_gcm394_base_device::unk_w @ 0x780a (data 0x0000)
1374 [:maincpu] ':maincpu' (000442):sunplus_gcm394_base_device::unk_w @ 0x7808 (data 0x0000)
1375 [:maincpu] ':maincpu' (000445):sunplus_gcm394_base_device::unk_w @ 0x782f (data 0x0002)
1376 [:maincpu] ':maincpu' (000449):sunplus_gcm394_base_device::unk_w @ 0x783d (data 0x05d9)
1377 [:maincpu] ':maincpu' (00044D):sunplus_gcm394_base_device::unk_w @ 0x783c (data 0x0f58)
1378 [:maincpu] ':maincpu' (000451):sunplus_gcm394_base_device::unk_w @ 0x783b (data 0x2400)
1379 [:maincpu] ':maincpu' (000454):sunplus_gcm394_base_device::unk_w @ 0x783e (data 0x0002)
1380 [:maincpu] ':maincpu' (000458):sunplus_gcm394_base_device::unk_w @ 0x783a (data 0x4011)
1381 [:maincpu] ':maincpu' (00045C):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x2492) -- note pair of 4, but different values to above games
1382 [:maincpu] ':maincpu' (00045E):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x2492)
1383 [:maincpu] ':maincpu' (000460):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x2492)
1384 [:maincpu] ':maincpu' (000462):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x2492)
1385
1386 vbaby code is very differet, attempts to load NAND block manually, not with DMA
1387
1388 */
1389
1390
1391 // all tilemap registers etc. appear to be in the same place as the above system, including the 'extra' ones not on the earlier models
1392 // so it's likely this is built on top of that just with NAND support
gpac800_internal_map(address_map & map)1393 void generalplus_gpac800_device::gpac800_internal_map(address_map& map)
1394 {
1395 sunplus_gcm394_base_device::base_internal_map(map);
1396
1397 // 785x = NAND device
1398 map(0x007850, 0x007850).rw(FUNC(generalplus_gpac800_device::nand_7850_status_r), FUNC(generalplus_gpac800_device::nand_7850_w)); // NAND Control Reg
1399 map(0x007851, 0x007851).w(FUNC(generalplus_gpac800_device::nand_command_w)); // NAND Command Reg
1400 map(0x007852, 0x007852).w(FUNC(generalplus_gpac800_device::nand_addr_low_w)); // NAND Low Address Reg
1401 map(0x007853, 0x007853).w(FUNC(generalplus_gpac800_device::nand_addr_high_w)); // NAND High Address Reg
1402 map(0x007854, 0x007854).r(FUNC(generalplus_gpac800_device::nand_7854_r)); // NAND Data Reg
1403 map(0x007855, 0x007855).w(FUNC(generalplus_gpac800_device::nand_dma_ctrl_w)); // NAND DMA / INT Control
1404 map(0x007856, 0x007856).w(FUNC(generalplus_gpac800_device::nand_7856_type_w)); // usually 0x0021?
1405 map(0x007857, 0x007857).w(FUNC(generalplus_gpac800_device::nand_7857_w));
1406
1407 // most of these are likely ECC stuff for testing the ROM?
1408 map(0x00785b, 0x00785b).w(FUNC(generalplus_gpac800_device::nand_785b_w));
1409 map(0x00785c, 0x00785c).w(FUNC(generalplus_gpac800_device::nand_785c_w));
1410 map(0x00785d, 0x00785d).w(FUNC(generalplus_gpac800_device::nand_785d_w));
1411 map(0x00785e, 0x00785e).r(FUNC(generalplus_gpac800_device::nand_785e_r)); // also ECC status related?
1412 map(0x00785f, 0x00785f).r(FUNC(generalplus_gpac800_device::nand_ecc_low_byte_error_flag_1_r)); // ECC Low Byte Error Flag 1 (maybe)
1413
1414 // 128kwords internal ROM
1415 //map(0x08000, 0x0ffff).rom().region("internal", 0); // lower 32kwords of internal ROM is visible / shadowed depending on boot pins and register
1416 map(0x08000, 0x0ffff).r(FUNC(generalplus_gpac800_device::internalrom_lower32_r)).nopw();
1417 map(0x10000, 0x27fff).rom().region("internal", 0x10000); // upper 96kwords of internal ROM is always visible
1418 map(0x28000, 0x2ffff).noprw(); // reserved
1419 // 0x30000+ is CS access
1420
1421 map(0x030000, 0x1fffff).rw(FUNC(generalplus_gpac800_device::cs_space_r), FUNC(generalplus_gpac800_device::cs_space_w));
1422 map(0x200000, 0x3fffff).rw(FUNC(generalplus_gpac800_device::cs_bank_space_r), FUNC(generalplus_gpac800_device::cs_bank_space_w));
1423 }
1424
1425
spi_unk_7943_r()1426 uint16_t generalplus_gpspispi_device::spi_unk_7943_r()
1427 {
1428 return 0x0007;
1429 }
1430
gpspispi_internal_map(address_map & map)1431 void generalplus_gpspispi_device::gpspispi_internal_map(address_map& map)
1432 {
1433 sunplus_gcm394_base_device::base_internal_map(map);
1434
1435 map(0x007943, 0x007943).r(FUNC(generalplus_gpspispi_device::spi_unk_7943_r));
1436
1437 map(0x008000, 0x00ffff).rom().region("internal", 0);
1438 }
1439
1440
device_start()1441 void sunplus_gcm394_base_device::device_start()
1442 {
1443 unsp_20_device::device_start();
1444
1445 m_cs_callback.resolve();
1446
1447 m_porta_in.resolve_safe(0);
1448 m_portb_in.resolve_safe(0);
1449 m_portc_in.resolve_safe(0);
1450 m_portd_in.resolve_safe(0);
1451
1452 m_porta_out.resolve();
1453 m_portb_out.resolve();
1454 m_portc_out.resolve();
1455 m_portd_out.resolve();
1456
1457
1458 m_space_read_cb.resolve_safe(0);
1459 m_space_write_cb.resolve();
1460
1461 m_nand_read_cb.resolve_safe(0);
1462
1463 m_unk_timer = timer_alloc(0);
1464 m_unk_timer->adjust(attotime::never);
1465
1466 save_item(NAME(m_dma_params));
1467 save_item(NAME(m_7803));
1468 save_item(NAME(m_7807));
1469 save_item(NAME(m_membankswitch_7810));
1470 save_item(NAME(m_7816));
1471 save_item(NAME(m_7817));
1472 save_item(NAME(m_7819));
1473 save_item(NAME(m_782x));
1474 save_item(NAME(m_782d));
1475 save_item(NAME(m_7835));
1476 save_item(NAME(m_7860));
1477 save_item(NAME(m_7861));
1478 save_item(NAME(m_7862_porta_direction));
1479 save_item(NAME(m_7863_porta_attribute));
1480
1481 save_item(NAME(m_786a_portb_direction));
1482 save_item(NAME(m_786b_portb_attribute));
1483
1484 save_item(NAME(m_7870));
1485 //save_item(NAME(m_7871));
1486 save_item(NAME(m_7872_portc_direction));
1487 save_item(NAME(m_7873_portc_attribute));
1488 save_item(NAME(m_7882));
1489 save_item(NAME(m_7883));
1490 save_item(NAME(m_78a0));
1491 save_item(NAME(m_78a4));
1492 save_item(NAME(m_78a5));
1493 save_item(NAME(m_78a6));
1494 save_item(NAME(m_78a8));
1495 save_item(NAME(m_78b0));
1496 save_item(NAME(m_78b1));
1497 save_item(NAME(m_78b2));
1498 save_item(NAME(m_78b8));
1499 save_item(NAME(m_78f0));
1500 save_item(NAME(m_78fb));
1501 save_item(NAME(m_7934));
1502 save_item(NAME(m_7935));
1503 save_item(NAME(m_7936));
1504 save_item(NAME(m_7960));
1505 save_item(NAME(m_7961));
1506 save_item(NAME(m_system_dma_memtype));
1507 save_item(NAME(m_csbase));
1508 save_item(NAME(m_romtype));
1509 }
1510
device_reset()1511 void sunplus_gcm394_base_device::device_reset()
1512 {
1513 unsp_20_device::device_reset();
1514
1515 for (int j = 0; j < 3; j++)
1516 {
1517 for (int i = 0; i < 7; i++)
1518 {
1519 m_dma_params[i][j] = 0x0000;
1520 }
1521 m_dma_latched[j] = false;
1522 }
1523
1524 // 78xx unknown
1525
1526 m_78fb = 0x0000;
1527 m_782d = 0x0000;
1528
1529 m_7807 = 0x0000;
1530
1531 m_membankswitch_7810 = 0x0001;
1532
1533 m_7816 = 0x0000;
1534 m_7817 = 0x0000;
1535
1536 m_7819 = 0x0000;
1537
1538 m_782x[0] = 0x0000;
1539 m_782x[1] = 0x0000;
1540 m_782x[2] = 0x0000;
1541 m_782x[3] = 0x0000;
1542 m_782x[4] = 0x0000;
1543
1544 m_7835 = 0x0000;
1545
1546 m_7860 = 0x0000;
1547
1548 m_7861 = 0x0000;
1549
1550 m_7862_porta_direction = 0x0000;
1551 m_7863_porta_attribute = 0x0000;
1552
1553 m_786a_portb_direction = 0x0000;
1554 m_786b_portb_attribute = 0x0000;
1555
1556 m_7870 = 0x0000;
1557
1558 //m_7871 = 0x0000;
1559
1560 m_7872_portc_direction = 0x0000;
1561 m_7873_portc_attribute = 0x0000;
1562
1563 m_7882 = 0x0000;
1564 m_7883 = 0x0000;
1565
1566 m_78a0 = 0x0000;
1567
1568 m_78a4 = 0x0000;
1569 m_78a5 = 0x0000;
1570 m_78a6 = 0x0000;
1571
1572 m_78a8 = 0x0000;
1573
1574 m_78b0 = 0x0000;
1575 m_78b1 = 0x0000;
1576 m_78b2 = 0x0000;
1577
1578 m_78b8 = 0x0000;
1579 m_78f0 = 0x0000;
1580
1581 // 79xx unknown
1582
1583 m_7934 = 0x0000;
1584 m_7935 = 0x0000;
1585 m_7936 = 0x0000;
1586
1587 m_7960 = 0x0000;
1588 m_7961 = 0x0000;
1589
1590 m_system_dma_memtype = 0x0000;
1591
1592 m_unk_timer->adjust(attotime::from_hz(60), 0, attotime::from_hz(60));
1593
1594 m_spg_video->set_video_spaces(this->space(AS_PROGRAM), *m_cs_space, m_csbase);
1595 m_spg_video->reset();
1596 }
1597
device_reset()1598 void generalplus_gpac800_device::device_reset()
1599 {
1600 sunplus_gcm394_base_device::device_reset();
1601
1602 m_nand_addr_low = 0x0000;
1603 m_nand_addr_high = 0x0000;
1604 m_nand_dma_ctrl = 0x0000;
1605 m_nand_7850 = 0x0000;
1606 m_nand_785d = 0x0000;
1607 m_nand_785c = 0x0000;
1608 m_nand_785b = 0x0000;
1609 m_nand_7856 = 0x0000;
1610 m_nand_7857 = 0x0000;
1611 }
1612
IRQ_CALLBACK_MEMBER(sunplus_gcm394_base_device::irq_vector_cb)1613 IRQ_CALLBACK_MEMBER(sunplus_gcm394_base_device::irq_vector_cb)
1614 {
1615 //logerror("irq_vector_cb %d\n", irqline);
1616
1617 if (irqline == UNSP_IRQ6_LINE)
1618 set_state_unsynced(UNSP_IRQ6_LINE, CLEAR_LINE);
1619
1620 if (irqline == UNSP_IRQ4_LINE)
1621 set_state_unsynced(UNSP_IRQ4_LINE, CLEAR_LINE);
1622
1623 return 0;
1624 }
1625
1626
checkirq6()1627 void sunplus_gcm394_base_device::checkirq6()
1628 {
1629 /*
1630 if (m_7935 & 0x0100)
1631 set_state_unsynced(UNSP_IRQ6_LINE, ASSERT_LINE);
1632 else
1633 set_state_unsynced(UNSP_IRQ6_LINE, CLEAR_LINE);
1634 */
1635 }
1636
1637 /* the IRQ6 interrupt on Wrlshunt
1638 reads 78a1, checks bit 0400
1639 if it IS set, just increases value in RAM at 1a2e (no ack)
1640 if it ISN'T set, then read/write 78b2 (ack something?) then increase value in RAM at 1a2e
1641 (smartfp doesn't touch these addresses? but instead reads/writes 7935, alt ack?)
1642
1643 wrlshunt also has an IRQ4
1644 it always reads/writes 78c0 before executing payload (ack?)
1645 payload is a lot of manipulation of values in RAM, no registers touched
1646
1647 wrlshunt also has FIQ
1648 no ack mechanism, for sound timer maybe (as it appears to be on spg110)
1649
1650
1651 ----
1652
1653 IRQ5 is video IRQ
1654 in both games writing 0x0001 to 7063 seems to be an ack mechanism
1655 wrlshunt also checks bit 0x0040 of 7863 and will ack that too with alt code paths
1656
1657 7863 is therefore some kind of 'video irq source' ?
1658
1659 */
1660
1661
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)1662 void sunplus_gcm394_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
1663 {
1664 switch (id)
1665 {
1666 case 0:
1667 {
1668 m_7935 |= 0x0100;
1669 set_state_unsynced(UNSP_IRQ6_LINE, ASSERT_LINE);
1670 //set_state_unsynced(UNSP_IRQ4_LINE, ASSERT_LINE);
1671
1672 // checkirq6();
1673 break;
1674 }
1675 }
1676 }
1677
1678
WRITE_LINE_MEMBER(sunplus_gcm394_base_device::audioirq_w)1679 WRITE_LINE_MEMBER(sunplus_gcm394_base_device::audioirq_w)
1680 {
1681 //set_state_unsynced(UNSP_IRQ5_LINE, state);
1682 }
1683
WRITE_LINE_MEMBER(sunplus_gcm394_base_device::videoirq_w)1684 WRITE_LINE_MEMBER(sunplus_gcm394_base_device::videoirq_w)
1685 {
1686 set_state_unsynced(UNSP_IRQ5_LINE, state);
1687 }
1688
read_space(uint32_t offset)1689 uint16_t sunplus_gcm394_base_device::read_space(uint32_t offset)
1690 {
1691 address_space& space = this->space(AS_PROGRAM);
1692 uint16_t val;
1693 if (offset < m_csbase)
1694 {
1695 val = space.read_word(offset);
1696 }
1697 else
1698 {
1699 val = m_cs_space->read_word(offset-m_csbase);
1700 }
1701
1702 return val;
1703 }
1704
1705
1706
write_space(uint32_t offset,uint16_t data)1707 void sunplus_gcm394_base_device::write_space(uint32_t offset, uint16_t data)
1708 {
1709 address_space& space = this->space(AS_PROGRAM);
1710 if (offset < m_csbase)
1711 {
1712 space.write_word(offset, data);
1713 }
1714 else
1715 {
1716 m_cs_space->write_word(offset-m_csbase, data);
1717 }
1718 }
1719
1720
1721
device_add_mconfig(machine_config & config)1722 void sunplus_gcm394_base_device::device_add_mconfig(machine_config &config)
1723 {
1724 SUNPLUS_GCM394_AUDIO(config, m_spg_audio, DERIVED_CLOCK(1, 1));
1725 m_spg_audio->write_irq_callback().set(FUNC(sunplus_gcm394_base_device::audioirq_w));
1726 m_spg_audio->space_read_callback().set(FUNC(sunplus_gcm394_base_device::read_space));
1727
1728 m_spg_audio->add_route(0, *this, 1.0, AUTO_ALLOC_INPUT, 0);
1729 m_spg_audio->add_route(1, *this, 1.0, AUTO_ALLOC_INPUT, 1);
1730
1731 GCM394_VIDEO(config, m_spg_video, DERIVED_CLOCK(1, 1), DEVICE_SELF, m_screen);
1732 m_spg_video->write_video_irq_callback().set(FUNC(sunplus_gcm394_base_device::videoirq_w));
1733 m_spg_video->space_read_callback().set(FUNC(sunplus_gcm394_base_device::read_space));
1734 }
1735
1736
1737