Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.  */
  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.  
  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.  */
  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.  
  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.  
  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.  */
  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.  
  364. void drz80_irq_callback()
  365. {
  366.         md::md_drz80->drz80_irq_cb();
  367. }
  368.  
  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.  */
  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.  */
  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.  */
  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.  */
  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.  */
  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.  
  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
  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.  */
  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.  */
  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.  */
  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.  */
  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.  */
  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.  */
  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.  */
  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.  */
  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.  */
  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.  */
  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.  */
  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.  */
  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.