1 // DGen/SDL v1.17+
2 // Megadrive C++ module
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <assert.h>
8 #include <ctype.h>
9 #ifdef HAVE_MEMCPY_H
10 #include "memcpy.h"
11 #endif
12 #include "md.h"
13 #include "system.h"
14 #include "romload.h"
15 #include "rc-vars.h"
16 #include "debug.h"
17 #include "decode.h"
18 
19 extern FILE *debug_log;
20 
21 #ifdef WITH_STAR
22 extern "C" unsigned star_readbyte(unsigned a, unsigned d);
23 extern "C" unsigned star_readword(unsigned a, unsigned d);
24 extern "C" unsigned star_writebyte(unsigned a, unsigned d);
25 extern "C" unsigned star_writeword(unsigned a, unsigned d);
26 
27 /**
28  * This sets up an array of memory locations.
29  * This method is StarScream specific.
30  * @return 0 on success
31  */
memory_map()32 int md::memory_map()
33 {
34   int i=0,j=0;
35   int rommax=romlen;
36 
37   if (rommax>0xa00000) rommax=0xa00000;
38   if (rommax<0) rommax=0;
39 
40 // FETCH: Set up 2 or 3 FETCH sections
41   i=0;
42   if (rommax>0)
43   { fetch[i].lowaddr=0x000000; fetch[i].highaddr=rommax-1; fetch[i].offset=(unsigned)rom-0x000000; i++; }
44   fetch[i].lowaddr=0xff0000; fetch[i].highaddr=0xffffff; fetch[i].offset=(unsigned)ram-  0xff0000; i++;
45 // Testing
46   fetch[i].lowaddr=0xffff0000; fetch[i].highaddr=0xffffffff; fetch[i].offset=(unsigned)ram-0xffff0000; i++;
47 // Testing 2
48   fetch[i].lowaddr=0xff000000; fetch[i].highaddr=0xff000000+rommax-1; fetch[i].offset=(unsigned)rom-0xff000000; i++;
49   fetch[i].lowaddr=fetch[i].highaddr=0xffffffff; fetch[i].offset=0; i++;
50 
51   if (debug_log!=NULL)
52     fprintf (debug_log,"StarScream memory_map has %d fetch sections\n",i);
53 
54   i=0; j=0;
55 
56 #if 0
57 // Simple version ***************
58   readbyte[i].lowaddr=   readword[i].lowaddr=
59   writebyte[j].lowaddr=  writeword[j].lowaddr=   0;
60   readbyte[i].highaddr=  readword[i].highaddr=
61   writebyte[j].highaddr= writeword[j].highaddr=  0xffffffff;
62 
63   readbyte[i].memorycall=(void *)star_readbyte;
64   readword[i].memorycall=(void *)star_readword;
65   writebyte[j].memorycall=(void *)star_writebyte;
66   writeword[j].memorycall=(void *)star_writeword;
67 
68   readbyte[i].userdata=  readword[i].userdata=
69   writebyte[j].userdata= writeword[j].userdata=  NULL;
70   i++; j++;
71 // Simple version end ***************
72 
73 #else
74 // Faster version ***************
75 // IO: Set up 3/4 read sections, and 2/3 write sections
76   if (rommax>0)
77   {
78 // Cartridge save RAM memory
79     if(save_len) {
80       readbyte[i].lowaddr=    readword[i].lowaddr=
81       writebyte[j].lowaddr=   writeword[j].lowaddr=   save_start;
82       readbyte[i].highaddr=   readword[i].highaddr=
83       writebyte[j].highaddr=  writeword[j].highaddr=  save_start+save_len-1;
84       readbyte[i].memorycall = star_readbyte;
85       readword[j].memorycall = star_readword;
86       writebyte[i].memorycall = star_writebyte;
87       writeword[j].memorycall = star_writeword;
88       readbyte[i].userdata=   readword[i].userdata=
89       writebyte[j].userdata=  writeword[j].userdata=  NULL;
90       i++; j++;
91     }
92 // Cartridge ROM memory (read only)
93     readbyte[i].lowaddr=   readword[i].lowaddr=   0x000000;
94     readbyte[i].highaddr=  readword[i].highaddr=  rommax-1;
95     readbyte[i].memorycall=readword[i].memorycall=NULL;
96     readbyte[i].userdata=  readword[i].userdata=  rom;
97     i++;
98 // misc memory (e.g. aoo and coo) through star_rw
99     readbyte[i].lowaddr=   readword[i].lowaddr=
100     writebyte[j].lowaddr=  writeword[j].lowaddr=   rommax;
101   }
102   else
103     readbyte[i].lowaddr=   readword[i].lowaddr=
104     writebyte[j].lowaddr=  writeword[j].lowaddr=   0;
105 
106   readbyte[i].highaddr=  readword[i].highaddr=
107   writebyte[j].highaddr= writeword[j].highaddr=  0xfeffff;
108 
109   readbyte[i].memorycall = star_readbyte;
110   readword[i].memorycall = star_readword;
111   writebyte[j].memorycall = star_writebyte;
112   writeword[j].memorycall = star_writeword;
113 
114   readbyte[i].userdata=  readword[i].userdata=
115   writebyte[j].userdata= writeword[j].userdata=  NULL;
116   i++; j++;
117 
118 // scratch RAM memory
119   readbyte[i].lowaddr =   readword[i].lowaddr =
120   writebyte[j].lowaddr =  writeword[j].lowaddr =   0xff0000;
121   readbyte[i].highaddr=   readword[i].highaddr=
122   writebyte[j].highaddr=  writeword[j].highaddr=   0xffffff;
123   readbyte[i].memorycall= readword[i].memorycall=
124   writebyte[j].memorycall=writeword[j].memorycall= NULL;
125   readbyte[i].userdata=  readword[i].userdata =
126   writebyte[j].userdata= writeword[j].userdata =   ram;
127   i++; j++;
128 // Faster version end ***************
129 #endif
130 
131 // The end
132    readbyte[i].lowaddr  =   readword[i].lowaddr  =
133   writebyte[j].lowaddr  =  writeword[j].lowaddr  =
134    readbyte[i].highaddr =   readword[i].highaddr =
135   writebyte[j].highaddr =  writeword[j].highaddr = 0xffffffff;
136 
137 	readbyte[i].memorycall = 0;
138 	readword[i].memorycall = 0;
139 	writebyte[j].memorycall = 0;
140 	writeword[j].memorycall = 0;
141 	readbyte[i].userdata = 0;
142 	readword[i].userdata = 0;
143 	writebyte[j].userdata = 0;
144 	writeword[j].userdata = 0;
145 
146   i++; j++;
147 
148   if (debug_log!=NULL)
149     fprintf (debug_log,"StarScream memory_map has %d read sections and %d write sections\n",i,j);
150 
151   return 0;
152 }
153 
star_irq_callback(void)154 void star_irq_callback(void)
155 {
156 	assert(md::md_star != NULL);
157 	md::md_star->m68k_vdp_irq_handler();
158 }
159 #endif
160 
161 #ifdef WITH_MUSA
162 /**
163  * This sets up an array of memory locations for Musashi.
164  */
musa_memory_map()165 void md::musa_memory_map()
166 {
167 	unsigned int rom0_len = romlen;
168 	unsigned int rom1_sta = 0;
169 	unsigned int rom1_len = 0;
170 
171 	m68k_register_memory(NULL, 0);
172 	if (save_len) {
173 		DEBUG(("[%06x-%06x] ???? (SAVE)",
174 		       save_start, (save_start + save_len - 1)));
175 		if (save_start < romlen) {
176 			/* Punch a hole through the ROM area. */
177 			rom0_len = save_start;
178 			/* Add entry for ROM leftovers, if any. */
179 			if ((save_start + save_len) < romlen) {
180 				rom1_sta = (save_start + save_len);
181 				rom1_len = (romlen - rom1_sta);
182 			}
183 		}
184 	}
185 
186 #ifdef ROM_BYTESWAP
187 #define S 1
188 #else
189 #define S 0
190 #endif
191 
192 	const m68k_mem_t mem[3] = {
193 		// r, w, x, swab, addr, size, mask, mem
194 		{ 1, 0, 1, S, 0x000000, rom0_len, 0x7fffff, rom }, // M68K ROM
195 		{ 1, 1, 1, 1, 0xe00000, 0x200000, 0x00ffff, ram }, // M68K RAM
196 		{ 1, 0, 1, S, rom1_sta, rom1_len, 0x7fffff, &rom[rom1_sta] }
197 	};
198 	unsigned int i;
199 	unsigned int j = 0;
200 
201 	for (i = 0; ((i < elemof(mem)) && (j < elemof(musa_memory))); ++i) {
202 		if (mem[i].size == 0)
203 			continue;
204 		DEBUG(("[%06x-%06x] %c%c%c%c (%s)",
205 		       mem[i].addr,
206 		       (mem[i].addr + mem[i].size - 1),
207 		       (mem[i].r ? 'r' : '-'),
208 		       (mem[i].w ? 'w' : '-'),
209 		       (mem[i].x ? 'x' : '-'),
210 		       (mem[i].swab ? 's' : '-'),
211 		       (mem[i].w ? "RAM" : "ROM")));
212 		musa_memory[j] = mem[i];
213 		++j;
214 	}
215 	if (j)
216 		m68k_register_memory(musa_memory, j);
217 	else
218 		DEBUG(("no memory region defined"));
219 }
220 
musa_irq_callback(int level)221 int musa_irq_callback(int level)
222 {
223 	(void)level;
224 	assert(md::md_musa != NULL);
225 	md::md_musa->m68k_vdp_irq_handler();
226 	return M68K_INT_ACK_AUTOVECTOR;
227 }
228 #endif
229 
230 #ifdef WITH_CYCLONE
231 extern "C" uint32_t cyclone_read_memory_8(uint32_t address);
232 extern "C" uint32_t cyclone_read_memory_16(uint32_t address);
233 extern "C" uint32_t cyclone_read_memory_32(uint32_t address);
234 extern "C" void cyclone_write_memory_8(uint32_t address, uint8_t value);
235 extern "C" void cyclone_write_memory_16(uint32_t address, uint16_t value);
236 extern "C" void cyclone_write_memory_32(uint32_t address, uint32_t value);
237 extern "C" uintptr_t cyclone_checkpc(uintptr_t pc);
238 
cyclone_irq_callback(int level)239 int cyclone_irq_callback(int level)
240 {
241 	(void)level;
242 	assert(md::md_cyclone != NULL);
243 	md::md_cyclone->m68k_vdp_irq_handler();
244 	return CYCLONE_INT_ACK_AUTOVECTOR;
245 }
246 #endif
247 
248 /**
249  * Resets everything (Z80, M68K, VDP, etc).
250  * @return 0 on success
251  */
reset()252 int md::reset()
253 {
254 	// Clear memory.
255 	memset(mem, 0, 0x20000);
256 	// Reset the VDP.
257 	vdp.reset();
258 	// Erase CPU states.
259 	memset(&m68k_state, 0, sizeof(m68k_state));
260 	memset(&z80_state, 0, sizeof(z80_state));
261 	m68k_state_restore();
262 	z80_state_restore();
263 #ifdef WITH_STAR
264 	md_set_star(1);
265 	s68000reset();
266 	md_set_star(0);
267 #endif
268 #ifdef WITH_MUSA
269 	md_set_musa(1);
270 	m68k_pulse_reset();
271 	md_set_musa(0);
272 #endif
273 #ifdef WITH_CYCLONE
274 	md_set_cyclone(1);
275 	CycloneReset(&cyclonecpu);
276 	md_set_cyclone(0);
277 #endif
278 #ifdef WITH_DEBUGGER
279 	debug_m68k_instr_count = 0;
280 	debug_z80_instr_count = 0;
281 #endif
282   if (debug_log) fprintf (debug_log,"reset()\n");
283 
284     aoo3_toggle=aoo5_toggle=aoo3_six=aoo5_six
285     =aoo3_six_timeout=aoo5_six_timeout
286     =coo4=coo5=0;
287   pad[0] = MD_PAD_UNTOUCHED;
288   pad[1] = MD_PAD_UNTOUCHED;
289   memset(pad_com, 0, sizeof(pad_com));
290 
291 #ifdef WITH_PICO
292   // Initialize Pico pen X, Y coordinates
293   pico_pen_coords[0] = 0x3c;
294   pico_pen_coords[1] = 0x1fc;
295 #endif
296 
297   // Reset FM registers
298   fm_reset();
299   dac_init();
300 
301   memset(&odo, 0, sizeof(odo));
302   ras = 0;
303 
304   z80_st_running = 0;
305   m68k_st_running = 0;
306   z80_reset();
307   z80_st_busreq = 1;
308   z80_st_reset = 1;
309   z80_st_irq = 0;
310   return 0;
311 }
312 
313 #ifdef WITH_MZ80
314 
315 extern "C" UINT8 mz80_read(UINT32 a, struct MemoryReadByte *unused);
316 extern "C" void mz80_write(UINT32 a, UINT8 d, struct MemoryWriteByte *unused);
317 extern "C" UINT16 mz80_ioread(UINT16 a, struct z80PortRead *unused);
318 extern "C" void mz80_iowrite(UINT16 a, UINT8 d, struct z80PortWrite *unused);
319 
320 static struct MemoryReadByte mem_read[] = {
321 	{ 0x0000, 0xffff, mz80_read, NULL },
322 	{ (UINT32)-1, (UINT32)-1, NULL, NULL }
323 };
324 
325 static struct MemoryWriteByte mem_write[] = {
326 	{ 0x0000, 0xffff, mz80_write, NULL },
327 	{ (UINT32)-1, (UINT32)-1, NULL, NULL }
328 };
329 
330 static struct z80PortRead io_read[] = {
331 	{ 0x00, 0xff, mz80_ioread, NULL },
332 	{ (UINT16)-1, (UINT16)-1, NULL, NULL }
333 };
334 
335 static struct z80PortWrite io_write[] = {
336 	{ 0x00, 0xff, mz80_iowrite, NULL },
337 	{ (UINT16)-1, (UINT16)-1, NULL, NULL }
338 };
339 
340 #endif // WITH_MZ80
341 
342 #ifdef WITH_CZ80
343 
344 extern "C" uint8_t cz80_memread(void *ctx, uint16_t a);
345 extern "C" void cz80_memwrite(void *ctx, uint16_t a, uint8_t d);
346 extern "C" uint16_t cz80_memread16(void *ctx, uint16_t a);
347 extern "C" void cz80_memwrite16(void *ctx, uint16_t a, uint16_t d);
348 extern "C" uint8_t cz80_ioread(void *ctx, uint16_t a);
349 extern "C" void cz80_iowrite(void *ctx, uint16_t a, uint8_t d);
350 
351 #endif // WITH_CZ80
352 
353 #ifdef WITH_DRZ80
354 
355 extern uintptr_t drz80_rebaseSP(uint16_t new_sp);
356 extern uintptr_t drz80_rebasePC(uint16_t new_pc);
357 extern uint8_t drz80_read8(uint16_t a);
358 extern uint16_t drz80_read16(uint16_t a);
359 extern void drz80_write8(uint8_t d, uint16_t a);
360 extern void drz80_write16(uint16_t d, uint16_t a);
361 extern uint8_t drz80_in(uint16_t p);
362 extern void drz80_out(uint16_t p, uint8_t d);
363 
drz80_irq_callback()364 void drz80_irq_callback()
365 {
366 	md::md_drz80->drz80_irq_cb();
367 }
368 
drz80_irq_cb()369 void md::drz80_irq_cb()
370 {
371 	drz80.Z80_IRQ = 0x00; // lower irq when in accepted
372 }
373 
374 #endif // WITH_DRZ80
375 
376 /**
377  * Initialise the Z80.
378  */
z80_init()379 void md::z80_init()
380 {
381 #ifdef WITH_MZ80
382 	md_set_mz80(1);
383 	mz80init();
384 	mz80reset();
385 	// Erase local context with global context.
386 	mz80GetContext(&z80);
387 	// Configure callbacks in local context.
388 	z80.z80Base = z80ram;
389 	z80.z80MemRead = mem_read;
390 	z80.z80MemWrite = mem_write;
391 	z80.z80IoRead = io_read;
392 	z80.z80IoWrite = io_write;
393 	// Erase global context with the above.
394 	mz80SetContext(&z80);
395 	md_set_mz80(0);
396 #endif
397 #ifdef WITH_CZ80
398 	Cz80_Set_Ctx(&cz80, this);
399 	Cz80_Set_Fetch(&cz80, 0x0000, 0xffff, (void *)z80ram);
400 	Cz80_Set_ReadB(&cz80, cz80_memread);
401 	Cz80_Set_WriteB(&cz80, cz80_memwrite);
402 	Cz80_Set_ReadW(&cz80, cz80_memread16);
403 	Cz80_Set_WriteW(&cz80, cz80_memwrite16);
404 	Cz80_Set_INPort(&cz80, cz80_ioread);
405 	Cz80_Set_OUTPort(&cz80, cz80_iowrite);
406 	Cz80_Reset(&cz80);
407 #endif
408 #ifdef WITH_DRZ80
409 	memset(&drz80, 0, sizeof(drz80));
410 	drz80.z80_write8 = drz80_write8;
411 	drz80.z80_write16 = drz80_write16;
412 	drz80.z80_in = drz80_in;
413 	drz80.z80_out = drz80_out;
414 	drz80.z80_read8 = drz80_read8;
415 	drz80.z80_read16 = drz80_read16;
416 	drz80.z80_rebasePC = drz80_rebasePC;
417 	drz80.z80_rebaseSP = drz80_rebaseSP;
418 	drz80.z80_irq_callback = drz80_irq_callback;
419 #endif
420 	z80_st_busreq = 1;
421 	z80_st_reset = 0;
422 	z80_bank68k = 0xff8000;
423 }
424 
425 /**
426  * Reset the Z80.
427  */
z80_reset()428 void md::z80_reset()
429 {
430 	z80_bank68k = 0xff8000;
431 #ifdef WITH_MZ80
432 	md_set_mz80(1);
433 	mz80reset();
434 	md_set_mz80(0);
435 #endif
436 #ifdef WITH_CZ80
437 	Cz80_Reset(&cz80);
438 #endif
439 #ifdef WITH_DRZ80
440 	md_set_drz80(1);
441 	drz80.Z80A = (1 << 2); // set ZFlag
442 	drz80.Z80F = (1 << 2); // set ZFlag
443 	drz80.Z80BC = 0;
444 	drz80.Z80DE = 0;
445 	drz80.Z80HL = 0;
446 	drz80.Z80A2 = 0;
447 	drz80.Z80F2 = 0;
448 	drz80.Z80BC2 = 0x0000 << 16;
449 	drz80.Z80DE2 = 0x0000 << 16;
450 	drz80.Z80HL2 = 0x0000 << 16;
451 	drz80.Z80IX = 0xFFFF << 16;
452 	drz80.Z80IY = 0xFFFF << 16;
453 
454 	drz80.Z80I = 0x00;
455 	drz80.Z80_IRQ = 0x00;
456 	drz80.Z80IF = 0x00;
457 	drz80.Z80IM = 0x00;
458 	drz80.Z80R = 0x00;
459 
460 	drz80.Z80PC = drz80_rebasePC(0);
461 	drz80.Z80SP = drz80_rebaseSP(0x2000);
462 	md_set_drz80(0);
463 #endif
464 }
465 
466 /**
467  * Initialise sound.
468  * @return True when successful.
469  */
init_sound()470 bool md::init_sound()
471 {
472 	if (lock == false)
473 		return false;
474 	if (ok_ym2612) {
475 		YM2612Shutdown();
476 		ok_ym2612 = false;
477 	}
478 	if (ok_sn76496) {
479 		(void)0;
480 		ok_sn76496 = false;
481 	}
482 	// Initialize two additional chips when MJazz is enabled.
483 	if (YM2612Init((dgen_mjazz ? 3 : 1),
484 		       (((pal) ? PAL_MCLK : NTSC_MCLK) / 7),
485 		       dgen_soundrate, dgen_mjazz, NULL, NULL))
486 		return false;
487 	ok_ym2612 = true;
488 	if (SN76496_init(0,
489 			 (((pal) ? PAL_MCLK : NTSC_MCLK) / 15),
490 			 dgen_soundrate, 16))
491 		return false;
492 	ok_sn76496 = true;
493 	return true;
494 }
495 
496 /**
497  * Switch to PAL or NTSC.
498  * This method's name is a bit misleading.  This switches to PAL or not
499  * depending on "md::pal".
500  */
init_pal()501 void md::init_pal()
502 {
503 	unsigned int hc;
504 
505 	if (pal) {
506 		mclk = PAL_MCLK;
507 		lines = PAL_LINES;
508 		vhz = PAL_HZ;
509 	}
510 	else {
511 		mclk = NTSC_MCLK;
512 		lines = NTSC_LINES;
513 		vhz = NTSC_HZ;
514 	}
515 	clk0 = (mclk / 15);
516 	clk1 = (mclk / 7);
517 	// Initialize horizontal counter table (Gens style)
518 	for (hc = 0; (hc < 512); ++hc) {
519 		// H32
520 		hc_table[hc][0] = (((hc * 170) / M68K_CYCLES_PER_LINE) - 0x18);
521 		// H40
522 		hc_table[hc][1] = (((hc * 205) / M68K_CYCLES_PER_LINE) - 0x1c);
523 	}
524 }
525 
526 bool md::lock = false;
527 
528 /**
529  * MD constructor.
530  * @param pal True if we are running the MD in PAL mode.
531  * @param region Region to emulate ('J', 'U', or 'E').
532  */
md(bool pal,char region)533 md::md(bool pal, char region):
534 #ifdef WITH_MUSA
535 	md_musa_ref(0), md_musa_prev(0),
536 #endif
537 #ifdef WITH_CYCLONE
538 	md_cyclone_ref(0), md_cyclone_prev(0),
539 #endif
540 #ifdef WITH_STAR
541 	md_star_ref(0), md_star_prev(0),
542 #endif
543 #ifdef WITH_CZ80
544 	md_cz80_ref(0),
545 #endif
546 #ifdef WITH_MZ80
547 	md_mz80_ref(0), md_mz80_prev(0),
548 #endif
549 	pal(pal), ok_ym2612(false), ok_sn76496(false),
550 	vdp(*this), region(region), plugged(false)
551 {
552 	// Only one MD object is allowed to exist at once.
553 	if (lock)
554 		return;
555 	lock = true;
556 
557 	// PAL or NTSC.
558 	init_pal();
559 
560 	// Start up the sound chips.
561 	if (init_sound() == false)
562 		goto cleanup;
563 
564 	romlen = no_rom_size;
565 	rom = (uint8_t*)no_rom;
566   mem=ram=z80ram=saveram=NULL;
567   save_start=save_len=save_prot=save_active=0;
568 
569   fm_reset();
570 
571 #ifdef WITH_VGMDUMP
572 	vgm_dump_file = NULL;
573 	vgm_dump_samples_total = 0;
574 	vgm_dump_dac_wait = 0;
575 	vgm_dump_dac_samples = 0;
576 	vgm_dump = false;
577 #endif
578 
579 #ifdef WITH_PICO
580 	pico_enabled = false;
581 #endif
582 
583   memset(&m68k_state, 0, sizeof(m68k_state));
584   memset(&z80_state, 0, sizeof(z80_state));
585 
586 #ifdef WITH_MUSA
587 	ctx_musa = calloc(1, m68k_context_size());
588 	if (ctx_musa == NULL)
589 		goto cleanup;
590 	md_set_musa(1);
591 	m68k_init();
592 	m68k_set_cpu_type(M68K_CPU_TYPE_68000);
593 	m68k_register_memory(NULL, 0);
594 	m68k_set_int_ack_callback(musa_irq_callback);
595 	md_set_musa(0);
596 #endif
597 
598 #ifdef WITH_STAR
599   fetch=NULL;
600   readbyte=readword=writebyte=writeword=NULL;
601   memset(&cpu,0,sizeof(cpu));
602 #endif
603 
604 #ifdef WITH_CYCLONE
605   memset(&cyclonecpu, 0, sizeof(cyclonecpu));
606   cyclonecpu.read8 = cyclone_read_memory_8;
607   cyclonecpu.read16 = cyclone_read_memory_16;
608   cyclonecpu.read32 = cyclone_read_memory_32;
609   cyclonecpu.write8 = cyclone_write_memory_8;
610   cyclonecpu.write16 = cyclone_write_memory_16;
611   cyclonecpu.write32 = cyclone_write_memory_32;
612   cyclonecpu.checkpc = cyclone_checkpc;
613   cyclonecpu.fetch8 = cyclone_read_memory_8;
614   cyclonecpu.fetch16 = cyclone_read_memory_16;
615   cyclonecpu.fetch32 = cyclone_read_memory_32;
616   cyclonecpu.IrqCallback = cyclone_irq_callback;
617   md_set_cyclone(1);
618   CycloneInit();
619   md_set_cyclone(0);
620 #endif
621 
622 #ifdef WITH_MZ80
623   memset(&z80,0,sizeof(z80));
624 #endif
625 #ifdef WITH_CZ80
626   Cz80_Init(&cz80);
627 #endif
628 #ifdef WITH_DRZ80
629   memset(&drz80, 0, sizeof(drz80));
630 #endif
631   memset(&cart_head, 0, sizeof(cart_head));
632 
633   memset(romname, 0, sizeof(romname));
634 
635   ok=0;
636 
637   //  Format of pad is: __SA____ UDLRBC__
638 
639   rom = (uint8_t*)no_rom;
640   romlen = no_rom_size;
641   mem=ram=z80ram=NULL;
642   mem=(unsigned char *)malloc(0x20008);
643 	if (mem == NULL)
644 		goto cleanup;
645   memset(mem,0,0x20000);
646   ram=   mem+0x00000;
647   z80ram=mem+0x10000;
648   // Hack for DrZ80 to avoid crashing when PC leaves z80ram.
649   z80ram[0x10000] = 0x00; // NOP
650   z80ram[0x10001] = 0x00; // NOP
651   z80ram[0x10002] = 0x00; // NOP
652   z80ram[0x10003] = 0x00; // NOP
653   z80ram[0x10004] = 0x00; // NOP
654   z80ram[0x10005] = 0xc3; // JP 0x0000
655   z80ram[0x10006] = 0x00;
656   z80ram[0x10007] = 0x00;
657 
658 #ifdef WITH_MUSA
659 	md_set_musa(1);
660 	musa_memory_map();
661 	md_set_musa(0);
662 #endif
663 #ifdef WITH_STAR
664 	md_set_star(1);
665 	if (s68000init() != 0) {
666 		md_set_star(0);
667 		printf ("s68000init failed!\n");
668 		goto cleanup;
669 	}
670 	md_set_star(0);
671 
672 // Dave: Rich said doing point star stuff is done after s68000init
673 // in Asgard68000, so just in case...
674 	if (((fetch = new STARSCREAM_PROGRAMREGION [6]) == NULL) ||
675 	    ((readbyte = new STARSCREAM_DATAREGION [5]) == NULL) ||
676 	    ((readword = new STARSCREAM_DATAREGION [5]) == NULL) ||
677 	    ((writebyte = new STARSCREAM_DATAREGION [5]) == NULL) ||
678 	    ((writeword = new STARSCREAM_DATAREGION [5]) == NULL))
679 		goto cleanup;
680 
681   memory_map();
682 
683   // point star stuff
684   cpu.s_fetch     = cpu.u_fetch     =     fetch;
685   cpu.s_readbyte  = cpu.u_readbyte  =  readbyte;
686   cpu.s_readword  = cpu.u_readword  =  readword;
687   cpu.s_writebyte = cpu.u_writebyte = writebyte;
688   cpu.s_writeword = cpu.u_writeword = writeword;
689 
690 	cpu.inthandler = star_irq_callback;
691 	md_set_star(1);
692 	s68000reset();
693 	md_set_star(0);
694 #endif
695 
696 	// M68K: 0 = none, 1 = StarScream, 2 = Musashi, 3 = Cyclone
697 	switch (dgen_emu_m68k) {
698 #ifdef WITH_STAR
699 	case 1:
700 		cpu_emu = CPU_EMU_STAR;
701 		break;
702 #endif
703 #ifdef WITH_MUSA
704 	case 2:
705 		cpu_emu = CPU_EMU_MUSA;
706 		break;
707 #endif
708 #ifdef WITH_CYCLONE
709 	case 3:
710 		cpu_emu = CPU_EMU_CYCLONE;
711 		break;
712 #endif
713 	default:
714 		cpu_emu = CPU_EMU_NONE;
715 		break;
716 	}
717 	// Z80: 0 = none, 1 = CZ80, 2 = MZ80, 3 = DrZ80
718 	switch (dgen_emu_z80) {
719 #ifdef WITH_MZ80
720 	case 1:
721 		z80_core = Z80_CORE_MZ80;
722 		break;
723 #endif
724 #ifdef WITH_CZ80
725 	case 2:
726 		z80_core = Z80_CORE_CZ80;
727 		break;
728 #endif
729 #ifdef WITH_DRZ80
730 	case 3:
731 		z80_core = Z80_CORE_DRZ80;
732 		break;
733 #endif
734 	default:
735 		z80_core = Z80_CORE_NONE;
736 		break;
737 	}
738 
739 #ifdef WITH_MUSA
740 	md_set_musa(1);
741 	m68k_pulse_reset();
742 	md_set_musa(0);
743 #endif
744 
745 #ifdef WITH_DEBUGGER
746 	debug_init();
747 #endif
748 
749   z80_init();
750 
751   reset(); // reset megadrive
752 
753 	patch_elem = NULL;
754 
755   ok=1;
756 
757 	return;
758 cleanup:
759 	if (ok_ym2612)
760 		YM2612Shutdown();
761 	if (ok_sn76496)
762 		(void)0;
763 #ifdef WITH_MUSA
764 	free(ctx_musa);
765 #endif
766 #ifdef WITH_STAR
767 	delete [] fetch;
768 	delete [] readbyte;
769 	delete [] readword;
770 	delete [] writebyte;
771 	delete [] writeword;
772 #endif
773 	free(mem);
774 	memset(this, 0, sizeof(*this));
775 	lock = false;
776 }
777 
~md()778 md::~md()
779 {
780 #ifdef WITH_VGMDUMP
781 	vgm_dump_stop();
782 #endif
783 
784 	assert(rom != NULL);
785 	if (rom != no_rom)
786 		unplug();
787 
788   free(mem);
789   rom=mem=ram=z80ram=NULL;
790 
791 #ifdef WITH_DEBUGGER
792 	debug_leave();
793 #endif
794 #ifdef WITH_MUSA
795 	free(ctx_musa);
796 #endif
797 #ifdef WITH_STAR
798 	delete [] fetch;
799 	delete [] readbyte;
800 	delete [] readword;
801 	delete [] writebyte;
802 	delete [] writeword;
803 #endif
804 
805 	if (ok_ym2612)
806 		YM2612Shutdown();
807 	if (ok_sn76496)
808 		(void)0;
809 	ok=0;
810 	memset(this, 0, sizeof(*this));
811 	lock = false;
812 }
813 
814 #ifdef ROM_BYTESWAP
815 /**
816  * Byteswaps memory.
817  * @param[in] start Byte array of cart memory.
818  * @param len How many bytes to byteswap.
819  * @return 0 on success (always 0).
820  */
821 // Byteswaps memory
byteswap_memory(unsigned char * start,int len)822 int byteswap_memory(unsigned char *start,int len)
823 { int i; unsigned char tmp;
824   for (i=0;i<len;i+=2)
825   { tmp=start[i+0]; start[i+0]=start[i+1]; start[i+1]=tmp; }
826   return 0;
827 }
828 #endif
829 
830 /**
831  * Plug a cart into the MD.
832  * @param[in] cart Cart's memory as a byte array.
833  * @param len Length of the cart.
834  * @return 0 on success.
835  */
plug_in(unsigned char * cart,int len)836 int md::plug_in(unsigned char *cart,int len)
837 {
838   // Plug in the cartridge specified by the uchar *
839   // NB - The megadrive will free() it if unplug() is called, or it exits
840   // So it must be a single piece of malloced data
841   if (cart==NULL) return 1; if (len<=0) return 1;
842 #ifdef ROM_BYTESWAP
843   byteswap_memory(cart,len); // for starscream
844 #endif
845   romlen=len;
846   rom=cart;
847   // Get saveram start, length (remember byteswapping)
848   // First check magic, if there is saveram
849   if(rom[ROM_ADDR(0x1b0)] == 'R' && rom[ROM_ADDR(0x1b1)] == 'A')
850     {
851       save_start = rom[ROM_ADDR(0x1b4)] << 24 | rom[ROM_ADDR(0x1b5)] << 16 |
852                    rom[ROM_ADDR(0x1b6)] << 8  | rom[ROM_ADDR(0x1b7)];
853       save_len = rom[ROM_ADDR(0x1b8)] << 24 | rom[ROM_ADDR(0x1b9)] << 16 |
854                  rom[ROM_ADDR(0x1ba)] << 8  | rom[ROM_ADDR(0x1bb)];
855       // Make sure start is even, end is odd, for alignment
856 // A ROM that I came across had the start and end bytes of
857 // the save ram the same and wouldn't work.  Fix this as seen
858 // fit, I know it could probably use some work. [PKH]
859       if(save_start != save_len) {
860         if(save_start & 1) --save_start;
861         if(!(save_len & 1)) ++save_len;
862         save_len -= (save_start - 1);
863         saveram = (unsigned char*)calloc(1, save_len);
864 	if (saveram == NULL) {
865 	  save_len = 0;
866 	  save_start = 0;
867 	}
868 	// If save RAM does not overlap main ROM, set it active by default since
869 	// a few games can't manage to properly switch it on/off.
870 	if(save_start >= (unsigned int)romlen)
871 	  save_active = 1;
872       }
873       else {
874         save_start = save_len = 0;
875         saveram = NULL;
876       }
877     }
878   else
879     {
880       save_start = save_len = 0;
881       saveram = NULL;
882     }
883 #ifdef WITH_MUSA
884 	md_set_musa(1);
885 	musa_memory_map();
886 	md_set_musa(0);
887 #endif
888 #ifdef WITH_STAR
889 	md_set_star(1);
890 	memory_map(); // Update memory map to include this cartridge
891 	md_set_star(0);
892 #endif
893   reset(); // Reset megadrive
894   return 0;
895 }
896 
897 /**
898  * Region to emulate according to dgen_region_order and ROM header.
899  * @return Region identifier ('J', 'U' or 'E').
900  */
region_guess()901 uint8_t md::region_guess()
902 {
903 	char const* order = dgen_region_order.val;
904 	char const* avail = this->cart_head.countries;
905 	size_t r;
906 	size_t i;
907 
908 	assert(order != NULL);
909 	assert(avail != NULL);
910 	for (r = 0; (order[r] != '\0'); ++r)
911 		for (i = 0; (i != sizeof(this->cart_head.countries)); ++i)
912 			if ((isprint(order[r])) &&
913 			    (toupper(order[r]) == toupper(avail[i])))
914 				return toupper(order[r]);
915 	// Use default region.
916 	return dgen_region;
917 }
918 
919 /**
920  * Unplug a cart from the system.
921  * @return 0 on success.
922  */
unplug()923 int md::unplug()
924 {
925   assert(rom != NULL);
926   assert(romlen != 0);
927   if (rom == no_rom) return 1;
928   unload_rom(rom);
929   rom = (uint8_t*)no_rom;
930   romlen = no_rom_size;
931   free(saveram);
932   saveram = NULL;
933   save_start = save_len = 0;
934 #ifdef WITH_MUSA
935 	md_set_musa(1);
936 	musa_memory_map();
937 	md_set_musa(0);
938 #endif
939 #ifdef WITH_STAR
940 	md_set_star(1);
941 	memory_map(); // Update memory map to include no rom
942 	md_set_star(0);
943 #endif
944   memset(romname, 0, sizeof(romname));
945   memset(&cart_head, 0, sizeof(cart_head));
946   reset();
947 
948 	while (patch_elem != NULL) {
949 		struct patch_elem *next = patch_elem->next;
950 
951 		free(patch_elem);
952 		patch_elem = next;
953 	}
954 	plugged = false;
955 
956   return 0;
957 }
958 
959 /**
960  * Load a ROM.
961  * @param[in] name File name of cart to load.
962  * @return 0 on success.
963  */
load(const char * name)964 int md::load(const char *name)
965 {
966 	uint8_t *temp;
967 	size_t size;
968 	const char *b_name;
969 
970 	if ((name == NULL) ||
971 	    ((b_name = dgen_basename(name)) == NULL))
972 		return 1;
973 	temp = load_rom(&size, name);
974 	if (temp == NULL)
975 		return 1;
976 
977 	// Register name
978 	romname[0] = '\0';
979 	if ((b_name[0] != '\0')) {
980 		unsigned int i;
981 
982 		snprintf(romname, sizeof(romname), "%s", b_name);
983 		for (i = 0; (romname[i] != '\0'); ++i)
984 			if (romname[i] == '.') {
985 				memset(&(romname[i]), 0,
986 				       (sizeof(romname) - i));
987 				break;
988 			}
989 	}
990 	if (romname[0] == '\0')
991 		snprintf(romname, sizeof(romname), "%s", "unknown");
992 
993   // Fill the header with ROM info (god this is ugly)
994   memcpy((void*)cart_head.system_name,  (void*)(temp + 0x100), 0x10);
995   memcpy((void*)cart_head.copyright,    (void*)(temp + 0x110), 0x10);
996   memcpy((void*)cart_head.domestic_name,(void*)(temp + 0x120), 0x30);
997   memcpy((void*)cart_head.overseas_name,(void*)(temp + 0x150), 0x30);
998   memcpy((void*)cart_head.product_no,   (void*)(temp + 0x180), 0x0e);
999   cart_head.checksum = temp[0x18e]<<8 | temp[0x18f]; // ugly, but endian-neutral
1000   memcpy((void*)cart_head.control_data, (void*)(temp + 0x190), 0x10);
1001   cart_head.rom_start  = temp[0x1a0]<<24 | temp[0x1a1]<<16 | temp[0x1a2]<<8 | temp[0x1a3];
1002   cart_head.rom_end    = temp[0x1a4]<<24 | temp[0x1a5]<<16 | temp[0x1a6]<<8 | temp[0x1a7];
1003   cart_head.ram_start  = temp[0x1a8]<<24 | temp[0x1a9]<<16 | temp[0x1aa]<<8 | temp[0x1ab];
1004   cart_head.ram_end    = temp[0x1ac]<<24 | temp[0x1ad]<<16 | temp[0x1ae]<<8 | temp[0x1af];
1005   cart_head.save_magic = temp[0x1b0]<<8 | temp[0x1b1];
1006   cart_head.save_flags = temp[0x1b2]<<8 | temp[0x1b3];
1007   cart_head.save_start = temp[0x1b4]<<24 | temp[0x1b5]<<16 | temp[0x1b6]<<8 | temp[0x1b7];
1008   cart_head.save_end   = temp[0x1b8]<<24 | temp[0x1b9]<<16 | temp[0x1ba]<<8 | temp[0x1bb];
1009   memcpy((void*)cart_head.memo,       (void*)(temp + 0x1c8), 0x28);
1010   memcpy((void*)cart_head.countries,  (void*)(temp + 0x1f0), 0x10);
1011 
1012 #ifdef WITH_PICO
1013 	// Check if cartridge inserted is intended for Sega Pico.
1014 	// If it is, the Sega Pico I/O area will be enabled, and the
1015 	// Megadrive I/O area will be disabled.
1016 	if ((!strncmp(cart_head.system_name, "SEGA PICO", 9)) ||
1017 	    (!strncmp(cart_head.system_name, "SEGATOYS PICO", 13)))
1018 		pico_enabled = true;
1019 	else
1020 		pico_enabled = false;
1021 #endif
1022 	// Plug it into the memory map
1023 	plug_in(temp, size); // md then deallocates it when it's done
1024 	plugged = true;
1025 	return 0;
1026 }
1027 
1028 /**
1029  * Cycle through Z80 CPU implementations.
1030  */
cycle_z80()1031 void md::cycle_z80()
1032 {
1033 	z80_state_dump();
1034 	z80_core = (enum z80_core)((z80_core + 1) % Z80_CORE_TOTAL);
1035 	z80_state_restore();
1036 }
1037 
1038 /**
1039  * Cycle between M68K CPU implementations.
1040  */
cycle_cpu()1041 void md::cycle_cpu()
1042 {
1043 	m68k_state_dump();
1044 	cpu_emu = (enum cpu_emu)((cpu_emu + 1) % CPU_EMU_TOTAL);
1045 	m68k_state_restore();
1046 }
1047 
1048 /**
1049  * Dump Z80 ram to a file named "dgz80ram".
1050  * @return Always returns 0.
1051  */
z80dump()1052 int md::z80dump()
1053 {
1054   FILE *hand;
1055   hand = dgen_fopen(NULL, "dgz80ram", DGEN_WRITE);
1056   if (hand!=NULL)
1057   { fwrite(z80ram,1,0x10000,hand); fclose(hand); }
1058   return 0;
1059 }
1060 
1061 /**
1062  * This takes a comma or whitespace-separated list of Game Genie and/or hex
1063  * codes to patch the ROM with.
1064  * @param[in] list List of codes separated by '\\t', '\\n', or ','.
1065  * @param[out] errors Number of codes that failed to apply.
1066  * @param[out] applied Number of codes that applied correctly.
1067  * @param[out] reverted Number of codes that were reverted.
1068  * @return 0 on success.
1069  */
patch(const char * list,unsigned int * errors,unsigned int * applied,unsigned int * reverted)1070 int md::patch(const char *list, unsigned int *errors,
1071 	      unsigned int *applied, unsigned int *reverted)
1072 {
1073   static const char delims[] = " \t\n,";
1074   char *worklist, *tok;
1075   struct patch p;
1076   int ret = 0;
1077   size_t wl_sz;
1078 
1079   if (errors != NULL)
1080     *errors = 0;
1081   if (applied != NULL)
1082     *applied = 0;
1083   if (reverted != NULL)
1084     *reverted = 0;
1085 
1086   // Copy the given list to a working list so we can strtok it
1087   wl_sz = strlen(list) + 1;
1088   worklist = (char *)malloc(wl_sz);
1089   if (worklist == NULL)
1090     return -1;
1091   strncpy(worklist, list, wl_sz);
1092 
1093   for(tok = strtok(worklist, delims); tok; tok = strtok(NULL, delims))
1094     {
1095       struct patch_elem *elem = patch_elem;
1096       struct patch_elem *prev = NULL;
1097       uint8_t *dest = rom;
1098       size_t mask = ~(size_t)0;
1099       int rev = 0;
1100       bool swap = true;
1101 
1102       // If it's empty, toss it
1103       if(*tok == '\0') continue;
1104       // Decode it
1105       decode(tok, &p);
1106       // Discard it if it was bad code
1107       if (((signed)p.addr == -1) || (p.addr >= (size_t)(romlen - 1))) {
1108 		if ((p.addr < 0xff0000) || (p.addr >= 0xffffff)) {
1109 			printf("Bad patch \"%s\"\n", tok);
1110 			if (errors != NULL)
1111 				++(*errors);
1112 			ret = -1;
1113 			continue;
1114 		}
1115 		// This is a RAM patch.
1116 		dest = ram;
1117 		mask = 0xffff;
1118       }
1119       if (dest == no_rom) {
1120 	      printf("Cannot patch this ROM\n");
1121 	      continue;
1122       }
1123 #ifndef ROM_BYTESWAP
1124       if (dest == rom)
1125 	      swap = false;
1126 #endif
1127       // Put it into dest (remember byteswapping)
1128       while (elem != NULL) {
1129 	if (elem->addr == p.addr) {
1130 	  // Revert a previous patch.
1131 	  p.data = elem->data;
1132 	  if (prev != NULL)
1133 	    prev->next = elem->next;
1134 	  else
1135 	    patch_elem = NULL;
1136 	  free(elem);
1137 	  rev = 1;
1138 	  break;
1139 	}
1140 	prev = elem;
1141 	elem = elem->next;
1142       }
1143       if (rev) {
1144         printf("Reverting patch \"%s\" -> %06X\n", tok, p.addr);
1145 	if (reverted != NULL)
1146 	  ++(*reverted);
1147       }
1148       else {
1149 	printf("Patch \"%s\" -> %06X:%04X\n", tok, p.addr, p.data);
1150 	if (applied != NULL)
1151 	  ++(*applied);
1152 	if ((elem = (struct patch_elem *)malloc(sizeof(*elem))) != NULL) {
1153 	  elem->next = patch_elem;
1154 	  elem->addr = p.addr;
1155 	  elem->data = ((dest[((p.addr + 0) ^ swap) & mask] << 8) |
1156 			(dest[((p.addr + 1) ^ swap) & mask]));
1157 	  patch_elem = elem;
1158 	}
1159       }
1160       dest[((p.addr + 0) ^ swap) & mask] = (uint8_t)(p.data >> 8);
1161       dest[((p.addr + 1) ^ swap) & mask] = (uint8_t)(p.data & 0xff);
1162     }
1163   // Done!
1164   free(worklist);
1165   return ret;
1166 }
1167 
1168 /**
1169  * Get saveram from FILE*.
1170  * @param from File to read from.
1171  * @return 0 on success.
1172  */
get_save_ram(FILE * from)1173 int md::get_save_ram(FILE *from)
1174 {
1175 	return !fread((void*)saveram, save_len, 1, from);
1176 }
1177 
1178 /**
1179  * Write a saveram to FILE*.
1180  * @param into File to write to.
1181  * @return 0 on success.
1182  */
put_save_ram(FILE * into)1183 int md::put_save_ram(FILE *into)
1184 {
1185 	return !fwrite((void*)saveram, save_len, 1, into);
1186 }
1187 
1188 /**
1189  * Calculates a ROM's checksum.
1190  * @param rom ROM memory area.
1191  * @param len ROM size.
1192  * @return Checksum.
1193  */
calculate_checksum(unsigned char * rom,int len)1194 static unsigned short calculate_checksum(unsigned char *rom,int len)
1195 {
1196   unsigned short checksum=0;
1197   int i;
1198   for (i=512;i<=(len-2);i+=2)
1199   {
1200     checksum+=(rom[ROM_ADDR(i+0)]<<8);
1201     checksum+=rom[ROM_ADDR(i+1)];
1202   }
1203   return checksum;
1204 }
1205 
1206 /**
1207  * Replace the in-memory ROM checksum with a calculated checksum.
1208  */
fix_rom_checksum()1209 void md::fix_rom_checksum()
1210 {
1211   unsigned short cs; cs=calculate_checksum(rom,romlen);
1212   if (romlen>=0x190) { rom[ROM_ADDR(0x18e)]=cs>>8; rom[ROM_ADDR(0x18f)]=cs&255; }
1213 }
1214 
1215 /**
1216  * This is the default ROM, used when nothing is loaded.
1217  */
1218 #ifdef ROM_BYTESWAP
1219 
1220 const uint8_t md::no_rom[] = {
1221 	// Note: everything is byte swapped.
1222 	"\x72\x4e" "\xff\xff" // stop #0xffff
1223 	"\x71\x4e"            // nop
1224 	"\x71\x4e"            // nop
1225 	"\xf6\x60"            // bra.b 0
1226 };
1227 
1228 #else
1229 
1230 const uint8_t md::no_rom[] = {
1231 	"\x4e\x72" "\xff\xff" // stop #0xffff
1232 	"\x4e\x71"            // nop
1233 	"\x4e\x71"            // nop
1234 	"\x60\xf6"            // bra.b 0
1235 };
1236 
1237 #endif
1238 
1239 const size_t md::no_rom_size = sizeof(no_rom);
1240