1 /***************************************************************************************
2 * Genesis Plus
3 * Internal Hardware & Bus controllers
4 *
5 * Support for SG-1000, Mark-III, Master System, Game Gear, Mega Drive & Mega CD hardware
6 *
7 * Copyright (C) 1998-2003 Charles Mac Donald (original code)
8 * Copyright (C) 2007-2018 Eke-Eke (Genesis Plus GX)
9 *
10 * Redistribution and use of this code or any derivative works are permitted
11 * provided that the following conditions are met:
12 *
13 * - Redistributions may not be sold, nor may they be used in a commercial
14 * product or activity.
15 *
16 * - Redistributions that are modified from the original source must include the
17 * complete source code, including the source code for all components used by a
18 * binary built from the modified sources. However, as a special exception, the
19 * source code distributed need not include anything that is normally distributed
20 * (in either source or binary form) with the major components (compiler, kernel,
21 * and so on) of the operating system on which the executable runs, unless that
22 * component itself accompanies the executable.
23 *
24 * - Redistributions must reproduce the above copyright notice, this list of
25 * conditions and the following disclaimer in the documentation and/or other
26 * materials provided with the distribution.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 *
40 ****************************************************************************************/
41
42 #include "shared.h"
43
44 #ifdef USE_DYNAMIC_ALLOC
45 external_t *ext;
46 #else /* External Hardware (Cartridge, CD unit, ...) */
47 external_t ext;
48 #endif
49 uint8 boot_rom[0x800]; /* Genesis BOOT ROM */
50 uint8 work_ram[0x10000]; /* 68K RAM */
51 uint8 zram[0x2000]; /* Z80 RAM */
52 uint32 zbank; /* Z80 bank window address */
53 uint8 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */
54 uint8 pico_current; /* PICO current page */
55
56 static uint8 tmss[4]; /* TMSS security register */
57
58 extern uint8 reset_do_not_clear_buffers;
59
60 /*--------------------------------------------------------------------------*/
61 /* Init, reset, shutdown functions */
62 /*--------------------------------------------------------------------------*/
63
gen_init(void)64 void gen_init(void)
65 {
66 int i;
67
68 /* initialize Z80 */
69 z80_init(0,z80_irq_callback);
70
71 /* 8-bit / 16-bit modes */
72 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
73 {
74 /* initialize main 68k */
75 m68k_init();
76 m68k.aerr_enabled = config.addr_error;
77
78 /* initialize main 68k memory map */
79
80 /* $800000-$DFFFFF : illegal access by default */
81 for (i=0x80; i<0xe0; i++)
82 {
83 m68k.memory_map[i].base = work_ram; /* for VDP DMA */
84 m68k.memory_map[i].read8 = m68k_lockup_r_8;
85 m68k.memory_map[i].read16 = m68k_lockup_r_16;
86 m68k.memory_map[i].write8 = m68k_lockup_w_8;
87 m68k.memory_map[i].write16 = m68k_lockup_w_16;
88 zbank_memory_map[i].read = zbank_lockup_r;
89 zbank_memory_map[i].write = zbank_lockup_w;
90 }
91
92 /* $C0xxxx, $C8xxxx, $D0xxxx, $D8xxxx : VDP ports */
93 for (i=0xc0; i<0xe0; i+=8)
94 {
95 m68k.memory_map[i].read8 = vdp_read_byte;
96 m68k.memory_map[i].read16 = vdp_read_word;
97 m68k.memory_map[i].write8 = vdp_write_byte;
98 m68k.memory_map[i].write16 = vdp_write_word;
99 zbank_memory_map[i].read = zbank_read_vdp;
100 zbank_memory_map[i].write = zbank_write_vdp;
101 }
102
103 /* $E00000-$FFFFFF : Work RAM (64k) */
104 for (i=0xe0; i<0x100; i++)
105 {
106 m68k.memory_map[i].base = work_ram;
107 m68k.memory_map[i].read8 = NULL;
108 m68k.memory_map[i].read16 = NULL;
109 m68k.memory_map[i].write8 = NULL;
110 m68k.memory_map[i].write16 = NULL;
111
112 /* Z80 can ONLY write to 68k RAM, not read it */
113 zbank_memory_map[i].read = zbank_unused_r;
114 zbank_memory_map[i].write = NULL;
115 }
116
117 if (system_hw == SYSTEM_PICO)
118 {
119 /* additional registers mapped to $800000-$80FFFF */
120 m68k.memory_map[0x80].read8 = pico_read_byte;
121 m68k.memory_map[0x80].read16 = pico_read_word;
122 m68k.memory_map[0x80].write8 = m68k_unused_8_w;
123 m68k.memory_map[0x80].write16 = m68k_unused_16_w;
124
125 /* there is no I/O area (Notaz) */
126 m68k.memory_map[0xa1].read8 = m68k_read_bus_8;
127 m68k.memory_map[0xa1].read16 = m68k_read_bus_16;
128 m68k.memory_map[0xa1].write8 = m68k_unused_8_w;
129 m68k.memory_map[0xa1].write16 = m68k_unused_16_w;
130
131 /* initialize page index (closed) */
132 pico_current = 0;
133 }
134 else
135 {
136 /* $A10000-$A1FFFF : I/O & Control registers */
137 m68k.memory_map[0xa1].read8 = ctrl_io_read_byte;
138 m68k.memory_map[0xa1].read16 = ctrl_io_read_word;
139 m68k.memory_map[0xa1].write8 = ctrl_io_write_byte;
140 m68k.memory_map[0xa1].write16 = ctrl_io_write_word;
141 zbank_memory_map[0xa1].read = zbank_read_ctrl_io;
142 zbank_memory_map[0xa1].write = zbank_write_ctrl_io;
143
144 /* initialize Z80 memory map */
145 /* $0000-$3FFF is mapped to Z80 RAM (8K mirrored) */
146 /* $4000-$FFFF is mapped to hardware but Z80 PC should never point there */
147 for (i=0; i<64; i++)
148 {
149 z80_readmap[i] = &zram[(i & 7) << 10];
150 }
151
152 /* initialize Z80 memory handlers */
153 z80_writemem = z80_memory_w;
154 z80_readmem = z80_memory_r;
155
156 /* initialize Z80 port handlers */
157 z80_writeport = z80_unused_port_w;
158 z80_readport = z80_unused_port_r;
159 }
160
161 /* $000000-$7FFFFF : external hardware area */
162 if (system_hw == SYSTEM_MCD)
163 {
164 /* initialize SUB-CPU */
165 s68k_init();
166
167 /* initialize CD hardware */
168 scd_init();
169 }
170 else
171 {
172 /* Cartridge hardware */
173 md_cart_init();
174 }
175 }
176 else
177 {
178 /* initialize cartridge hardware & Z80 memory handlers */
179 sms_cart_init();
180
181 /* initialize Z80 ports handlers */
182 switch (system_hw)
183 {
184 /* Master System compatibility mode */
185 case SYSTEM_PBC:
186 {
187 z80_writeport = z80_md_port_w;
188 z80_readport = z80_md_port_r;
189 break;
190 }
191
192 /* Game Gear hardware */
193 case SYSTEM_GG:
194 case SYSTEM_GGMS:
195 {
196 /* initialize cartridge hardware & Z80 memory handlers */
197 sms_cart_init();
198
199 /* initialize Z80 ports handlers */
200 z80_writeport = z80_gg_port_w;
201 z80_readport = z80_gg_port_r;
202 break;
203 }
204
205 /* Master System hardware */
206 case SYSTEM_SMS:
207 case SYSTEM_SMS2:
208 {
209 z80_writeport = z80_ms_port_w;
210 z80_readport = z80_ms_port_r;
211 break;
212 }
213
214 /* Mark-III hardware */
215 case SYSTEM_MARKIII:
216 {
217 z80_writeport = z80_m3_port_w;
218 z80_readport = z80_m3_port_r;
219 break;
220 }
221
222 /* SG-1000 hardware */
223 case SYSTEM_SG:
224 case SYSTEM_SGII:
225 {
226 z80_writeport = z80_sg_port_w;
227 z80_readport = z80_sg_port_r;
228 break;
229 }
230 }
231 }
232 }
233
gen_reset(int hard_reset)234 void gen_reset(int hard_reset)
235 {
236 /* System Reset */
237 if (hard_reset)
238 {
239 /* On hard reset, 68k CPU always starts at the same point in VDP frame */
240 /* Tests performed on VA4 PAL MD1 showed that the first HVC value read */
241 /* with 'move.w #0x8104,0xC00004' , 'move.w 0xC00008,%d0' sequence was */
242 /* 0x9F21 in 60HZ mode (0x9F00 if Mode 5 is not enabled by first MOVE) */
243 /* 0x8421 in 50HZ mode (0x8400 if Mode 5 is not enabled by first MOVE) */
244 /* Same value is returned on every power ON, indicating VDP is always */
245 /* starting at the same fixed point in frame (probably at the start of */
246 /* VSYNC and HSYNC) while 68k /VRES line remains asserted a fixed time */
247 /* after /SRES line has been released (13 msec approx). The difference */
248 /* between PAL & NTSC is caused by the top border area being 27 lines */
249 /* larger in PAL mode than in NTSC mode. CPU cycle counter is adjusted */
250 /* to match these results (taking in account emulated frame is started */
251 /* on line 192 */
252 m68k.cycles = ((lines_per_frame - 192 + 159 - (27 * vdp_pal)) * MCYCLES_PER_LINE) + 1004;
253
254 /* clear RAM (on real hardware, RAM values are random / undetermined on Power ON) */
255 if (!reset_do_not_clear_buffers)
256 {
257 memset(work_ram, 0x00, sizeof(work_ram));
258 memset(zram, 0x00, sizeof(zram));
259 }
260 }
261 else
262 {
263 /* when RESET button is pressed, 68k could be anywhere in VDP frame (Bonkers, Eternal Champions, X-Men 2) */
264 m68k.cycles = (uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX));
265
266 /* reset YM2612 (on hard reset, this is done by sound_reset) */
267 fm_reset(0);
268 }
269
270 /* 68k M-cycles should be a multiple of 7 */
271 m68k.cycles = (m68k.cycles / 7) * 7;
272
273 /* Z80 M-cycles should be a multiple of 15 */
274 Z80.cycles = (m68k.cycles / 15) * 15;
275
276 /* 8-bit / 16-bit modes */
277 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
278 {
279 if (system_hw == SYSTEM_MCD)
280 {
281 /* FRES is only asserted on Power ON */
282 if (hard_reset)
283 {
284 /* reset CD hardware */
285 scd_reset(1);
286 }
287 }
288
289 /* reset MD cartridge hardware */
290 md_cart_reset(hard_reset);
291
292 /* Z80 bus is released & Z80 is reseted */
293 m68k.memory_map[0xa0].read8 = m68k_read_bus_8;
294 m68k.memory_map[0xa0].read16 = m68k_read_bus_16;
295 m68k.memory_map[0xa0].write8 = m68k_unused_8_w;
296 m68k.memory_map[0xa0].write16 = m68k_unused_16_w;
297 zstate = 0;
298
299 /* assume default bank is $000000-$007FFF */
300 zbank = 0;
301
302 /* TMSS support */
303 if ((config.bios & 1) && (system_hw == SYSTEM_MD) && hard_reset)
304 {
305 int i;
306
307 /* clear TMSS register */
308 memset(tmss, 0x00, sizeof(tmss));
309
310 /* VDP access is locked by default */
311 for (i=0xc0; i<0xe0; i+=8)
312 {
313 m68k.memory_map[i].read8 = m68k_lockup_r_8;
314 m68k.memory_map[i].read16 = m68k_lockup_r_16;
315 m68k.memory_map[i].write8 = m68k_lockup_w_8;
316 m68k.memory_map[i].write16 = m68k_lockup_w_16;
317 zbank_memory_map[i].read = zbank_lockup_r;
318 zbank_memory_map[i].write = zbank_lockup_w;
319 }
320
321 /* check if BOOT ROM is loaded */
322 if (system_bios & SYSTEM_MD)
323 {
324 /* save default cartridge slot mapping */
325 cart.base = m68k.memory_map[0].base;
326 if (cart.base == boot_rom) cart.base = &cart.rom[0];
327
328 /* BOOT ROM is mapped at $000000-$0007FF */
329 m68k.memory_map[0].base = boot_rom;
330 }
331 }
332
333 /* reset MAIN-CPU */
334 m68k_pulse_reset();
335 }
336 else
337 {
338 /* RAM state at power-on is undefined on some systems */
339 if ((system_hw == SYSTEM_MARKIII) || ((system_hw & SYSTEM_SMS) && (region_code == REGION_JAPAN_NTSC)))
340 {
341 /* some korean games rely on RAM to be initialized with values different from $00 or $ff */
342 if (!reset_do_not_clear_buffers)
343 {
344 memset(work_ram, 0xf0, sizeof(work_ram));
345 }
346 }
347
348 /* reset cartridge hardware */
349 sms_cart_reset();
350
351 /* halt 68k (/VRES is forced low) */
352 m68k_pulse_halt();
353 }
354
355 /* reset Z80 */
356 z80_reset();
357
358 /* some Z80 registers need to be initialized on Power ON */
359 if (hard_reset)
360 {
361 /* Power Base Converter specific */
362 if (system_hw == SYSTEM_PBC)
363 {
364 /* startup code logic (verified on real hardware): */
365 /* 21 01 E1 : LD HL, $E101
366 25 -- -- : DEC H
367 F9 -- -- : LD SP,HL
368 C7 -- -- : RST $00
369 01 01 -- : LD BC, $xx01
370 */
371 Z80.hl.w.l = 0xE001;
372 Z80.sp.w.l = 0xDFFF;
373 Z80.r = 4;
374 }
375
376 /* Master System & Game Gear specific */
377 else if (system_hw & (SYSTEM_SMS | SYSTEM_GG))
378 {
379 /* check if BIOS is not being used */
380 if ((!(config.bios & 1) || !(system_bios & (SYSTEM_SMS | SYSTEM_GG))))
381 {
382 /* a few Master System (Ace of Aces, Shadow Dancer) & Game Gear (Ecco the Dolphin, Evander Holyfield Real Deal Boxing) games crash if SP is not properly initialized */
383 Z80.sp.w.l = 0xDFF0;
384 }
385 }
386 }
387 }
388
389 /*-----------------------------------------------------------------------*/
390 /* OS ROM / TMSS register control functions (Genesis mode) */
391 /*-----------------------------------------------------------------------*/
392
gen_tmss_w(unsigned int offset,unsigned int data)393 void gen_tmss_w(unsigned int offset, unsigned int data)
394 {
395 int i;
396
397 /* write TMSS register */
398 WRITE_WORD(tmss, offset, data);
399
400 /* VDP requires "SEGA" value to be written in TMSS register */
401 if (memcmp((char *)tmss, "SEGA", 4) == 0)
402 {
403 for (i=0xc0; i<0xe0; i+=8)
404 {
405 m68k.memory_map[i].read8 = vdp_read_byte;
406 m68k.memory_map[i].read16 = vdp_read_word;
407 m68k.memory_map[i].write8 = vdp_write_byte;
408 m68k.memory_map[i].write16 = vdp_write_word;
409 zbank_memory_map[i].read = zbank_read_vdp;
410 zbank_memory_map[i].write = zbank_write_vdp;
411 }
412 }
413 else
414 {
415 for (i=0xc0; i<0xe0; i+=8)
416 {
417 m68k.memory_map[i].read8 = m68k_lockup_r_8;
418 m68k.memory_map[i].read16 = m68k_lockup_r_16;
419 m68k.memory_map[i].write8 = m68k_lockup_w_8;
420 m68k.memory_map[i].write16 = m68k_lockup_w_16;
421 zbank_memory_map[i].read = zbank_lockup_r;
422 zbank_memory_map[i].write = zbank_lockup_w;
423 }
424 }
425 }
426
gen_bankswitch_w(unsigned int data)427 void gen_bankswitch_w(unsigned int data)
428 {
429 /* check if BOOT ROM is loaded */
430 if (system_bios & SYSTEM_MD)
431 {
432 if (data & 1)
433 {
434 /* enable cartridge ROM */
435 m68k.memory_map[0].base = cart.base;
436 }
437 else
438 {
439 /* enable internal BOOT ROM */
440 m68k.memory_map[0].base = boot_rom;
441 }
442 }
443 }
444
gen_bankswitch_r(void)445 unsigned int gen_bankswitch_r(void)
446 {
447 /* check if BOOT ROM is loaded */
448 if (system_bios & SYSTEM_MD)
449 {
450 return (m68k.memory_map[0].base == cart.base);
451 }
452
453 return 0xff;
454 }
455
456
457 /*-----------------------------------------------------------------------*/
458 /* Z80 Bus controller chip functions (Genesis mode) */
459 /* ----------------------------------------------------------------------*/
460
gen_zbusreq_w(unsigned int data,unsigned int cycles)461 void gen_zbusreq_w(unsigned int data, unsigned int cycles)
462 {
463 if (data) /* !ZBUSREQ asserted */
464 {
465 /* check if Z80 is going to be stopped */
466 if (zstate == 1)
467 {
468 /* resynchronize with 68k */
469 z80_run(cycles);
470
471 /* enable 68k access to Z80 bus */
472 m68k.memory_map[0xa0].read8 = z80_read_byte;
473 m68k.memory_map[0xa0].read16 = z80_read_word;
474 m68k.memory_map[0xa0].write8 = z80_write_byte;
475 m68k.memory_map[0xa0].write16 = z80_write_word;
476 }
477
478 /* update Z80 bus status */
479 zstate |= 2;
480 }
481 else /* !ZBUSREQ released */
482 {
483 /* check if Z80 is going to be restarted */
484 if (zstate == 3)
485 {
486 /* resynchronize with 68k (Z80 cycles should remain a multiple of 15 MClocks) */
487 Z80.cycles = ((cycles + 14) / 15) * 15;
488
489 /* disable 68k access to Z80 bus */
490 m68k.memory_map[0xa0].read8 = m68k_read_bus_8;
491 m68k.memory_map[0xa0].read16 = m68k_read_bus_16;
492 m68k.memory_map[0xa0].write8 = m68k_unused_8_w;
493 m68k.memory_map[0xa0].write16 = m68k_unused_16_w;
494 }
495
496 /* update Z80 bus status */
497 zstate &= 1;
498 }
499 }
500
gen_zreset_w(unsigned int data,unsigned int cycles)501 void gen_zreset_w(unsigned int data, unsigned int cycles)
502 {
503 if (data) /* !ZRESET released */
504 {
505 /* check if Z80 is going to be restarted */
506 if (zstate == 0)
507 {
508 /* resynchronize with 68k (Z80 cycles should remain a multiple of 15 MClocks) */
509 Z80.cycles = ((cycles + 14) / 15) * 15;
510
511 /* reset Z80 & YM2612 */
512 z80_reset();
513 fm_reset(cycles);
514 }
515
516 /* check if 68k access to Z80 bus is granted */
517 else if (zstate == 2)
518 {
519 /* enable 68k access to Z80 bus */
520 m68k.memory_map[0xa0].read8 = z80_read_byte;
521 m68k.memory_map[0xa0].read16 = z80_read_word;
522 m68k.memory_map[0xa0].write8 = z80_write_byte;
523 m68k.memory_map[0xa0].write16 = z80_write_word;
524
525 /* reset Z80 & YM2612 */
526 z80_reset();
527 fm_reset(cycles);
528 }
529
530 /* update Z80 bus status */
531 zstate |= 1;
532 }
533 else /* !ZRESET asserted */
534 {
535 /* check if Z80 is going to be stopped */
536 if (zstate == 1)
537 {
538 /* resynchronize with 68k */
539 z80_run(cycles);
540 }
541
542 /* check if 68k had access to Z80 bus */
543 else if (zstate == 3)
544 {
545 /* disable 68k access to Z80 bus */
546 m68k.memory_map[0xa0].read8 = m68k_read_bus_8;
547 m68k.memory_map[0xa0].read16 = m68k_read_bus_16;
548 m68k.memory_map[0xa0].write8 = m68k_unused_8_w;
549 m68k.memory_map[0xa0].write16 = m68k_unused_16_w;
550 }
551
552 /* stop YM2612 */
553 fm_reset(cycles);
554
555 /* update Z80 bus status */
556 zstate &= 2;
557 }
558 }
559
gen_zbank_w(unsigned int data)560 void gen_zbank_w (unsigned int data)
561 {
562 zbank = ((zbank >> 1) | ((data & 1) << 23)) & 0xFF8000;
563 }
564
565
566 /*-----------------------------------------------------------------------*/
567 /* Z80 interrupt callback */
568 /* ----------------------------------------------------------------------*/
569
z80_irq_callback(int param)570 int z80_irq_callback (int param)
571 {
572 return -1;
573 }
574