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