Advertisement
xiahanlu

设备ticks/MMU设备

Oct 13th, 2018
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.31 KB | None | 0 0
  1. /* nintendo gameboy
  2.  * https://en.wikipedia.org/wiki/Game_Boy
  3.  *
  4.  * Copyright (C) 2018 moecmks
  5.  * This file is part of KS3578.
  6.  *
  7.  * do What The Fuck you want to Public License
  8.  *
  9.  * Version 1.0, March 2000
  10.  * Copyright (C) 2000 Banlu Kemiyatorn (]d).
  11.  * 136 Nives 7 Jangwattana 14 Laksi Bangkok
  12.  * Everyone is permitted to copy and distribute verbatim copies
  13.  * of this license document, but changing it is not allowed.
  14.  *
  15.  * Ok, the purpose of this license is simple
  16.  * and you just
  17.  *
  18.  * DO WHAT THE FUCK YOU WANT TO.
  19.  */
  20.  
  21. #include "gameboy.h"
  22. #include "internal.h"
  23.  
  24. void controller_setupdate_ (struct controller *ctl, void (*update)
  25.             (struct controller *,
  26.             void *,
  27.               struct controller_pad *, /* self */
  28.             struct controller_pad * /* host edge */), void *obj);
  29. void ppu_setupdate_ (struct ppu *ppu, void (*update)
  30.             (struct ppu *,
  31.             void *,
  32.               struct ppu_framebuffer *), void *obj);
  33.  
  34. static
  35. void controller_hostdrv_s (struct gameboy *gb, void *controller_drvobj,
  36.                          struct controller_pad *gb_pad, /* gb-self for recv joypadbuffer */
  37.                          struct controller_pad *hostedge /* host-edge 1?pulse gen:nodone */)
  38. {
  39.   printf ("%s:%s please set controller_hostdrv\n", __FILE__, __LINE__);
  40.   assert (0);
  41. }
  42.  
  43. static
  44. void display_hostdrv_s (struct gameboy *gb,
  45.                       void *display_drvobj,
  46.                       struct ppu_framebuffer *fmebuf)
  47. {
  48.   printf ("%s:%s please set display_hostdrv\n", __FILE__, __LINE__);
  49.   assert (0);
  50. }
  51.  
  52. static
  53. void controller_hostdrv_route (struct controller *ctl, void *obj, struct controller_pad *gb_infos, struct controller_pad *host_infos) {
  54.   ctl->gb->controller_hostdrv (ctl->gb, obj, gb_infos, host_infos);
  55. }
  56. static
  57. void lcdvideo_hostdrv_route (struct ppu *ppu, void *obj, struct ppu_framebuffer *fbuf) {
  58.   ppu->gb->display_hostdrv (ppu->gb, obj, fbuf);
  59. }
  60.  
  61. void gameboy_controller_setupdate (struct gameboy *gb, void (*controller_hostdrv)
  62.              (struct gameboy *,
  63.              void *,
  64.                 struct controller_pad *, /* gb-self for recv joypadbuffer */
  65.              struct controller_pad * /* host-edge */), void *obj)
  66. {
  67.   gb->controller_hostdrv = controller_hostdrv;
  68.   gb->controller_drvobj = obj;
  69.  
  70.   controller_setupdate_ (gb->joypad, controller_hostdrv_route, obj);
  71. }
  72.  
  73. void gameboy_lcdvideo_setupdate (struct gameboy *gb, void (*lcdvideo_hostdrv)
  74.              (struct gameboy *,
  75.               void *,
  76.               struct ppu_framebuffer *), void *obj)
  77. {
  78.   gb->display_hostdrv = lcdvideo_hostdrv;
  79.   gb->display_drvobj = obj;
  80.  
  81.   ppu_setupdate_ (gb->lh5028, lcdvideo_hostdrv_route, obj);
  82. }
  83.  
  84. extern
  85. ks_int ks_callc
  86. cpu_optick (struct cpu *cpu_);
  87.  
  88. ks_finline
  89. ks_void
  90. internaldev_clks (struct gameboy *gb, ks_double clks) {
  91.   /* update internal device divider */
  92.   gb->cpu_clks_total += clks;
  93.   gb->cpu_clks_divider += clks;
  94.   gb->cpu_clks_ppu += clks;
  95.   gb->cpu_clks_timer += clks;
  96.   gb->cpu_clks_joypad += clks;
  97.   gb->cpu_clks_apu += clks;
  98.   gb->cpu_clks_cart += clks;
  99.   gb->cpu_clks_serial += clks;
  100.   /* update device */
  101.   gb->divider->clks (gb->divider);
  102.   gb->lh5028->clks (gb->lh5028);
  103.   gb->timer->clks (gb->timer);
  104.   gb->joypad->clks (gb->joypad);
  105.   gb->apu->clks (gb->apu);
  106.   gb->cart->clks (gb->cart);
  107.   gb->serial->clks (gb->serial);
  108. }
  109.  
  110. void /* gameboy's main function */
  111. gameboy_run_ms (struct gameboy *gb, ks_double exec_ms /*neg disable */) {
  112.  
  113.   ks_int opclks_;
  114.   ks_double opclks;
  115.   ks_double clks_b;
  116.   ks_bool fadjust;
  117.   ks_uint8 imask;
  118.   ks_double cpu_clks;
  119.   ks_double op_ms;
  120.   ks_double oc_ms;
  121.   static ks_uint16 PC_cac;
  122.   oc_ms = gb->deflect_ms;
  123.   gb->deflect_ms += exec_ms;
  124.   if (ks_cmp0_double (& gb->deflect_ms) == KS_CMP_ABOVE) {
  125.     op_ms = exec_ms -  oc_ms;
  126.     gb->deflect_ms = 0.0;
  127.     clks_b = op_ms * gb->mach_tools->clk_ms;
  128.     cpu_clks = clks_b;
  129.     /* device done loop */
  130.     while (ks_true)  {
  131.       /* check remain clks */
  132.       if (ks_cmp0_double (& cpu_clks) != KS_CMP_ABOVE)  {
  133.         /* cycles burning out **/
  134.         gb->deflect_ms = cpu_clks / gb->mach_tools->clk_ms;
  135.         break ;
  136.       } else {
  137.         /* remain clks to run, first check dma run. */
  138.         if (ks_cmp0_double (& gb->cpu_clks_dma) == KS_CMP_ABOVE) {
  139.           /* DMA active, exec nop instruction, clks:4 */
  140.           gb->cpu_clks_dma -= 4.0;
  141.           cpu_clks -= 4.0; /* XXX:stride clks for next DMA. */
  142.           internaldev_clks (gb, 4.0);
  143.           continue ;
  144.         } else if (gb->lh5028->hdma_gen != ks_false && !gb->lh5028->hdma_r16) {
  145.           gb->lh5028->hdma_gen = ks_false;
  146.           gb->lh5028->reg55_HDMA5 |= 0x80; /* Set unactive */
  147.         }
  148.         /* check stop, about stop opcode
  149.            see http://gbdev.gg8.se/wiki/articles/Joypad_Input
  150.                http://www.devrs.com/gb/files/faqs.html#STOP */
  151.         if (gb->lr35902->stop != ks_false) {
  152.           /* XXX: in fact not close APU. */
  153.           cpu_clks -= 4.0;
  154.           gb->cpu_clks_joypad += 4.0;
  155.           gb->joypad->clks (gb->joypad);
  156.           continue;
  157.         }
  158.         /* check halt, about halt opcode
  159.            see. http://www.devrs.com/gb/files/faqs.html#HALT */
  160.         if (gb->lr35902->halt != ks_false/* && gb->lr35902->IME != 0*/) {  
  161.           cpu_clks -= 4.0;
  162.           internaldev_clks (gb, 4.0);
  163.           fadjust = ks_false;
  164.           if ((gb->reg0F_IF & gb->regFF_IE & 0x1F) != 0) {
  165.             gb->lr35902->halt = ks_false;  /* close halt*/
  166.             if (gb->lr35902->IME == 0) {
  167.               /* halt bug gen, read next byte twice */
  168.               gb->lr35902->_backup = 0;
  169.             }
  170.           }
  171.           goto check_interrupt;
  172.         }
  173.         /* run cpu opcode */
  174.                 //        if (gb->lr35902->PC == 0x1E48)
  175.         // _DEBUG_BREAK ();
  176.              //   if (gb->lr35902->PC == 0x1E66)
  177.         // _DEBUG_BREAK ();
  178.         PC_cac = gb->lr35902->PC;
  179.         opclks_ = cpu_optick (gb->lr35902);
  180.         // assert (opclks_ < 5);
  181.        
  182.         printf ("pc:%04x prombank:%d\n", gb->lr35902->PC, gb->cart->mbc1->prombank);
  183.         if (gb->lr35902->PC == 0x1E65)
  184.          _DEBUG_BREAK ();
  185.         /* check KEY1 */
  186.         fadjust = ks_true;
  187.         if (opclks_ & 0x80000000)
  188.           opclks_ &= 0x7FFFFFFF;
  189.         else fadjust = ks_false;
  190.         opclks = (ks_double) opclks_;
  191.         cpu_clks -= opclks_;
  192.         internaldev_clks (gb, opclks_);
  193.   check_interrupt:
  194.         if (gb->lr35902->IME != 0) {
  195.           if ((imask = (gb->reg0F_IF & gb->regFF_IE & 0x1F)) != 0) {    
  196.            /* Interrupt Service Routine According to Z80 datasheets,
  197.               the following occurs when control is being transferred to an interrupt handler: */        
  198.             ks_uint16 iaddr;
  199.             gb->lr35902->halt = ks_false;  /* close halt*/
  200.             gb->lr35902->_backup = 0;
  201.             if (imask & IRQ_1) {
  202.               iaddr = IRQ_1_ADDRESS; imask= IRQ_1; }
  203.             else if (imask & IRQ_2) {
  204.               iaddr = IRQ_2_ADDRESS; imask= IRQ_2; }
  205.             else if (imask & IRQ_3) {
  206.               iaddr = IRQ_3_ADDRESS; imask= IRQ_3; }
  207.             else if (imask & IRQ_4) {
  208.               iaddr = IRQ_4_ADDRESS; imask= IRQ_4; }
  209.             else if (imask & IRQ_5) {
  210.               iaddr = IRQ_5_ADDRESS; imask= IRQ_5; }
  211.             /* 1. Two wait states are executed
  212.               (2 machine cycles pass while nothing occurs, presumably the CPU is executing NOPs during this time). */
  213.             cpu_clks -= 8.0;
  214.             internaldev_clks (gb, 8.0);
  215.             gb->reg0F_IF &=~imask; /*close interrupr request mask */
  216.             gb->lr35902->IME = 0; /* reset IME. */
  217.             gameboy_mmu_write (gb, gb->lr35902->SP - 1, gb->lr35902->PH);
  218.             gameboy_mmu_write (gb, gb->lr35902->SP - 2, gb->lr35902->PL);
  219.             gb->lr35902->SP -= 2;
  220.             /* 2. The current PC is pushed onto the stack, this process consumes 2 more machine cycles. */
  221.             cpu_clks -= 8.0;
  222.             internaldev_clks (gb, 8.0);
  223.             /* 3. The high byte of the PC is set to 0,
  224.                   the low byte is set to the address of the handler ($40,$48,$50,$58,$60).
  225.                   This consumes one last machine cycle. */
  226.             gb->lr35902->PC = iaddr;
  227.             cpu_clks -= 4.0;
  228.             internaldev_clks (gb, 4.0);
  229.           }
  230.         }
  231.         if (fadjust != ks_false) {
  232.           /* freq adjust in all device  */
  233.           if (gb->lr35902->reg4D_key1 & 0x80) {
  234.             /* normal to double freq */
  235.             cpu_clks *= std_machine.cgb_gbp_p;
  236.             gb->cpu_clks_ppu *= std_machine.cgb_gbp_p;
  237.             gb->lh5028->hbl_clks_st *= std_machine.cgb_gbp_p;
  238.             gb->lh5028->oambg_clks_divider21 *= std_machine.cgb_gbp_p;
  239.             gb->mach_tools = (struct machine_setup *)& adv_machine;
  240.           } else {
  241.             /* double freq to normal */
  242.             cpu_clks *= adv_machine.gbp_cgb_p;
  243.             gb->cpu_clks_ppu *= adv_machine.gbp_cgb_p;
  244.             gb->lh5028->hbl_clks_st *= adv_machine.gbp_cgb_p;
  245.             gb->lh5028->oambg_clks_divider21 *= adv_machine.gbp_cgb_p;
  246.             gb->mach_tools = (struct machine_setup *)& std_machine;
  247.           }
  248.         }
  249.       }
  250.     }
  251.   }
  252. }
  253.  
  254. int apu_init (struct apu **apu);
  255. int ppu_init (struct ppu **ppu);
  256. int cpu_init (struct cpu **cpu);
  257. int controller_init (struct controller **controller);
  258. int timer_init (struct timer **timer);
  259. int divider_init (struct divider **divider_);
  260. int cartridge_init (struct cartridge ** cartridge);
  261. int serial_init (struct serial ** serial);
  262.  
  263. int gameboy_init (struct gameboy **gb) {
  264.  
  265.   struct gameboy *gb_ =ks_null;
  266.   assert (gb != ks_null);
  267.  
  268.   gb_ = (struct gameboy *)
  269.      calloc (sizeof (struct gameboy), 1);
  270.   apu_init (& gb_->apu);
  271.   ppu_init (& gb_->lh5028);
  272.   cpu_init (& gb_->lr35902);
  273.   controller_init (& gb_->joypad);
  274.   timer_init (& gb_->timer);
  275.   divider_init (& gb_->divider);
  276.   cartridge_init (& gb_->cart);
  277.   serial_init (& gb_->serial);
  278.  
  279.   /* lnk child objects */
  280.   gb_->apu->gb = gb_;
  281.   gb_->lh5028->gb = gb_;
  282.   gb_->lr35902->gb = gb_;
  283.   gb_->joypad->gb = gb_;
  284.   gb_->timer->gb = gb_;
  285.   gb_->divider->gb = gb_;
  286.   gb_->cart->gb = gb_;
  287.   gb_->serial->gb = gb_;
  288.  
  289.   gb_->controller_hostdrv = controller_hostdrv_s;
  290.   gb_->display_hostdrv = display_hostdrv_s;
  291.  
  292.   ppu_setupdate_ (gb_->lh5028, lcdvideo_hostdrv_route, ks_null);
  293.   controller_setupdate_ (gb_->joypad, controller_hostdrv_route, ks_null);
  294.  
  295.   gb_->reg70_SVBK = 1;
  296.   gb_->regFF_IE = 0;
  297.  
  298.  
  299.   * gb = gb_;
  300.   return 0;
  301. }
  302.  
  303. void divider_write (struct divider *divider, ks_uint8 value);
  304. void timer_write (struct timer *timer, ks_uint16 addr, ks_uint8 value);
  305. void ppu_write (struct ppu *ppu, ks_uint16 addr, ks_uint8 value);
  306. void apu_write (struct apu *apu, ks_uint16 addr, ks_uint8 value);
  307. void serial_write (struct serial *apu, ks_uint16 addr, ks_uint8 value);
  308. void cartridge_write (struct cartridge *cart, ks_uint16 addr, ks_uint8 value);
  309. void controller_write (struct controller *cart, ks_uint8 value);
  310.  
  311. void
  312. ks_callstd gameboy_mmu_write (struct gameboy *gb, ks_uint16 address, ks_uint8 value) {
  313.  
  314.   switch (address >> 13) {
  315.   case 0x00: /* Memmap- 0x0000-0x1FFF*/
  316.   case 0x01: /* Memmap- 0x2000-0x3FFF*/
  317.   case 0x02: /* Memmap- 0x4000-0x5FFF*/
  318.   case 0x03: /* Memmap- 0x6000-0x7FFF*/
  319.   case 0x05: /* Memmap- 0xA000-0xBFFF*/
  320.     gb->cart->write (gb->cart, address, value); /* Program ROM BANK0 or BANK1-NN */
  321.     break;
  322.   case 0x04: /* Memmap- 0x8000-0x9FFF*/
  323.     gb->lh5028->ram[address-0x8000+(gb->lh5028->reg4F_VBK&1)*0x2000] = value;
  324.     break;
  325.   case 0x07: /* Memmap- 0xE000-0xFFFF*/
  326.     if (address <= 0xFDFF) /* echo ram. same as nes's mirror ram. */
  327.   case 0x06: /* Memmap- 0xC000-0xDFFF*/
  328.       if (address & 0x1000)
  329.         gb->wram[(address & 0x0FFF)+(gb->reg70_SVBK & 7)*0x1000] = value;
  330.       else
  331.         gb->wram[address & 0x0FFF] = value;
  332.     else if (address <= 0xFE9F)
  333.       ((ks_int8 *)&gb->lh5028->sp[0])[address-0xFE00] = value;
  334.     else if (address <= 0xFEFF)  /* Not Usable */
  335.   default:
  336.       gb->unknow_ram[address] = value;
  337.     else
  338.       switch (address) {
  339.       case 0xFF00: /* P1 */
  340.         controller_write (gb->joypad, value);
  341.         break;
  342.       case 0xFF01: /* SB */
  343.       case 0xFF02: /* SC */
  344.         serial_write (gb->serial, address, value);
  345.         break;
  346.       case 0xFF04: /* DIV */
  347.         divider_write (gb->divider, value);
  348.         break;
  349.       case 0xFF05: /* TIMA*/
  350.       case 0xFF06: /* TMA */
  351.       case 0xFF07: /* TAC */
  352.         timer_write (gb->timer, address, value);
  353.         break;
  354.       case 0xFF10: /* NR10 */
  355.       case 0xFF11: /* NR11 */
  356.       case 0xFF12: /* NR12 */
  357.       case 0xFF13: /* NR13 */
  358.       case 0xFF14: /* NR14 */
  359.       case 0xFF16: /* NR21 */
  360.       case 0xFF17: /* NR22 */
  361.       case 0xFF18: /* NR23 */
  362.       case 0xFF19: /* NR24 */
  363.       case 0xFF1A: /* NR30 */
  364.       case 0xFF1B: /* NR31 */
  365.       case 0xFF1C: /* NR32 */
  366.       case 0xFF1D: /* NR33 */
  367.       case 0xFF1E: /* NR34 */
  368.       case 0xFF20: /* NR41 */
  369.       case 0xFF21: /* NR42 */
  370.       case 0xFF22: /* NR43 */
  371.       case 0xFF23: /* NR44 */
  372.       case 0xFF24: /* NR50 */
  373.       case 0xFF25: /* NR51 */
  374.       case 0xFF26: /* NR52 */
  375.       case 0xFF30: /* AUD3WAVERAM */
  376.       case 0xFF31: /* AUD3WAVERAM */
  377.       case 0xFF32: /* AUD3WAVERAM */
  378.       case 0xFF33: /* AUD3WAVERAM */
  379.       case 0xFF34: /* AUD3WAVERAM */
  380.       case 0xFF35: /* AUD3WAVERAM */
  381.       case 0xFF36: /* AUD3WAVERAM */
  382.       case 0xFF37: /* AUD3WAVERAM */
  383.       case 0xFF38: /* AUD3WAVERAM */
  384.       case 0xFF39: /* AUD3WAVERAM */
  385.       case 0xFF3A: /* AUD3WAVERAM */
  386.       case 0xFF3B: /* AUD3WAVERAM */
  387.       case 0xFF3C: /* AUD3WAVERAM */
  388.       case 0xFF3D: /* AUD3WAVERAM */
  389.       case 0xFF3E: /* AUD3WAVERAM */
  390.       case 0xFF3F: /* AUD3WAVERAM */
  391.         apu_write (gb->apu, address, value);
  392.         break;
  393.       case 0xFF40: /* LCDC */
  394.       case 0xFF41: /* LCDS */
  395.       case 0xFF42: /* SCY */
  396.       case 0xFF43: /* SCX */
  397.       case 0xFF44: /* LY */
  398.       case 0xFF45: /* LYC */
  399.       case 0xFF46: /* OAMDMA */
  400.       case 0xFF47: /* BGP -DMG Only */
  401.       case 0xFF48: /* OBP0 -DMG Only */
  402.       case 0xFF49: /* OBP1 -DMG Only */
  403.       case 0xFF4A: /* WY */
  404.       case 0xFF4B: /* WX */
  405.       case 0xFF4F: /* VBK -CBG Only*/
  406.       case 0xFF51: /* HDMA1 -CBG Only*/
  407.       case 0xFF52: /* HDMA2 -CBG Only*/
  408.       case 0xFF53: /* HDMA3 -CBG Only*/
  409.       case 0xFF54: /* HDMA4 -CBG Only*/
  410.       case 0xFF55: /* HDMA5 -CBG Only*/
  411.       case 0xFF68: /* BCPS -CBG Only*/
  412.       case 0xFF69: /* BCPD -CBG Only*/
  413.       case 0xFF6A: /* OCPS -CBG Only*/
  414.       case 0xFF6B: /* OCPD -CBG Only*/
  415.         ppu_write (gb->lh5028, address, value);
  416.         break;
  417.       case 0xFF56: /* RP -CBG Only*/
  418.         break;
  419.       case 0xFF70: /* SVBK -CBG Only*/
  420.         if ((gb->reg70_SVBK = (value & 7)) == 0)
  421.           gb->reg70_SVBK = 1;
  422.         break;
  423.       case 0xFF4D: /* KEY1 -CBG Only*/
  424.         gb->lr35902->reg4D_key1 = value;
  425.         break;
  426.       case 0xFFFF: /* Interrupt Enable */
  427.         gb->regFF_IE = value;
  428.         break;
  429.       case 0xFF0F: /* IF */
  430.         gb->reg0F_IF = value;  
  431.         break;
  432.       default:
  433.         if (address >= 0xFF80)
  434.           gb->hram[address-0xFF80] = value;
  435.         break;
  436.       }
  437.     break;
  438.   }
  439. }
  440.  
  441. ks_void
  442. ks_callstd gameboy_mmu_write_w (struct gameboy *gb, ks_uint16 address, ks_uint16 value) {
  443.   gameboy_mmu_write (gb, address, value & 0xFF);
  444.   gameboy_mmu_write (gb, address+1, value>> 8);
  445. }
  446.  
  447. ks_uint8 divider_read (struct divider *divider);
  448. ks_uint8 timer_read (struct timer *timer, ks_uint16 addr);
  449. ks_uint8 ppu_read (struct ppu *ppu, ks_uint16 addr);
  450. ks_uint8 apu_read (struct apu *apu, ks_uint16 addr);
  451. ks_uint8 serial_read (struct serial *apu, ks_uint16 addr);
  452. ks_uint8 cartridge_read (struct cartridge *cart, ks_uint16 addr);
  453. ks_uint8 controller_read (struct controller *controller);
  454.  
  455. ks_uint8
  456. ks_callstd gameboy_mmu_read (struct gameboy *gb, ks_uint16 address) {
  457.  
  458.   switch (address >> 13) {
  459.   case 0x00: /* Memmap- 0x0000-0x1FFF - BANK-0 */
  460.   case 0x01: /* Memmap- 0x2000-0x3FFF - BANK-0 */
  461.   case 0x02: /* Memmap- 0x4000-0x5FFF - BANK-N */
  462.   case 0x03: /* Memmap- 0x6000-0x7FFF - BANK-N */
  463.   case 0x05: /* Memmap- 0xA000-0xBFFF - SRAM/RAM/EXT */
  464.     return gb->cart->read (gb->cart, address);
  465.   case 0x04: /* Memmap- 0x8000-0x9FFF*/
  466.     return gb->lh5028->ram[(address & 0x1FFF) +(gb->lh5028->reg4F_VBK&1)*0x2000];
  467.   case 0x07: /* Memmap- 0xE000-0xFFFF*/
  468.     if (address <= 0xFDFF) /* echo ram. same as nes's mirror ram. */
  469.   case 0x06: /* Memmap- 0xC000-0xDFFF*/
  470.       if (address & 0x1000)
  471.         return gb->wram[(address & 0x0FFF) +(gb->reg70_SVBK & 7)*0x1000];
  472.       else
  473.         return gb->wram[address & 0x0FFF];      
  474.     else if (address <= 0xFE9F)
  475.       return ((ks_int8 *)&gb->lh5028->sp[0])[address-0xFE00];
  476.     else if (address <= 0xFEFF)  /* Not Usable */
  477.   default:
  478.       return gb->unknow_ram[address];
  479.     else
  480.       switch (address) {
  481.       case 0xFF00: /* P1 */
  482.         return controller_read (gb->joypad);
  483.       case 0xFF01: /* SB */
  484.       case 0xFF02: /* SC */
  485.         return serial_read (gb->serial, address);
  486.       case 0xFF04: /* DIV */
  487.         return divider_read (gb->divider);
  488.       case 0xFF05: /* TIMA*/
  489.       case 0xFF06: /* TMA */
  490.       case 0xFF07: /* TAC */
  491.         return timer_read (gb->timer, address);  
  492.       case 0xFF10: /* NR10 */
  493.       case 0xFF11: /* NR11 */
  494.       case 0xFF12: /* NR12 */
  495.       case 0xFF13: /* NR13 */
  496.       case 0xFF14: /* NR14 */
  497.       case 0xFF16: /* NR21 */
  498.       case 0xFF17: /* NR22 */
  499.       case 0xFF18: /* NR23 */
  500.       case 0xFF19: /* NR24 */
  501.       case 0xFF1A: /* NR30 */
  502.       case 0xFF1B: /* NR31 */
  503.       case 0xFF1C: /* NR32 */
  504.       case 0xFF1D: /* NR33 */
  505.       case 0xFF1E: /* NR34 */
  506.       case 0xFF20: /* NR41 */
  507.       case 0xFF21: /* NR42 */
  508.       case 0xFF22: /* NR43 */
  509.       case 0xFF23: /* NR44 */
  510.       case 0xFF24: /* NR50 */
  511.       case 0xFF25: /* NR51 */
  512.       case 0xFF26: /* NR52 */
  513.       case 0xFF30: /* AUD3WAVERAM */
  514.       case 0xFF31: /* AUD3WAVERAM */
  515.       case 0xFF32: /* AUD3WAVERAM */
  516.       case 0xFF33: /* AUD3WAVERAM */
  517.       case 0xFF34: /* AUD3WAVERAM */
  518.       case 0xFF35: /* AUD3WAVERAM */
  519.       case 0xFF36: /* AUD3WAVERAM */
  520.       case 0xFF37: /* AUD3WAVERAM */
  521.       case 0xFF38: /* AUD3WAVERAM */
  522.       case 0xFF39: /* AUD3WAVERAM */
  523.       case 0xFF3A: /* AUD3WAVERAM */
  524.       case 0xFF3B: /* AUD3WAVERAM */
  525.       case 0xFF3C: /* AUD3WAVERAM */
  526.       case 0xFF3D: /* AUD3WAVERAM */
  527.       case 0xFF3E: /* AUD3WAVERAM */
  528.       case 0xFF3F: /* AUD3WAVERAM */
  529.         return apu_read (gb->apu, address);
  530.       case 0xFF40: /* LCDC */
  531.       case 0xFF41: /* LCDS */
  532.       case 0xFF42: /* SCY */
  533.       case 0xFF43: /* SCX */
  534.       case 0xFF44: /* LY */
  535.       case 0xFF45: /* LYC */
  536.       case 0xFF46: /* OAMDMA */
  537.       case 0xFF47: /* BGP -DMG Only */
  538.       case 0xFF48: /* OBP0 -DMG Only */
  539.       case 0xFF49: /* OBP1 -DMG Only */
  540.       case 0xFF4A: /* WY */
  541.       case 0xFF4B: /* WX */
  542.       case 0xFF4F: /* VBK -CBG Only*/
  543.       case 0xFF51: /* HDMA1 -CBG Only*/
  544.       case 0xFF52: /* HDMA2 -CBG Only*/
  545.       case 0xFF53: /* HDMA3 -CBG Only*/
  546.       case 0xFF54: /* HDMA4 -CBG Only*/
  547.       case 0xFF55: /* HDMA5 -CBG Only*/
  548.       case 0xFF68: /* BCPS -CBG Only*/
  549.       case 0xFF69: /* BCPD -CBG Only*/
  550.       case 0xFF6A: /* OCPS -CBG Only*/
  551.       case 0xFF6B: /* OCPD -CBG Only*/
  552.         return ppu_read (gb->lh5028, address);
  553.       case 0xFF56: /* RP -CBG Only*/
  554.         return 0xFF;
  555.       case 0xFF70: /* SVBK -CBG Only*/
  556.         return (gb->reg70_SVBK & 7);
  557.       case 0xFF4D: /* KEY1 -CBG Only*/
  558.         return gb->lr35902->reg4D_key1;
  559.       case 0xFFFF: /* Interrupt Enable */
  560.         return gb->regFF_IE;
  561.       case 0xFF0F: /* IF */
  562.         return gb->reg0F_IF;
  563.       default:
  564.         if (address >= 0xFF80) /* High RAM */
  565.           return gb->hram[address-0xFF80];
  566.         else
  567.           return 0;
  568.       }
  569.   }
  570.   return 0xFF;
  571. }
  572.  
  573. ks_uint16
  574. ks_callstd gameboy_mmu_read_w (struct gameboy *gb, ks_uint16 address) {
  575.   ks_uint16 u = gameboy_mmu_read (gb, address);
  576.   ks_uint16 v = gameboy_mmu_read (gb, address+1) << 8;
  577.   return (u |v);
  578. }
  579.  
  580. int gameboy_loadrom (struct gameboy *gb, FILE *fp) {
  581.   int cartridge_load (struct cartridge *cart, FILE *cartmem);
  582.   return cartridge_load (gb->cart, fp);
  583. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement