public static void wb(int addr, int val) { byte bval = (byte)val; switch (addr & 0xF000) { // ROM bank 0 // MBC1: Turn external RAM on case 0x0000: case 0x1000: switch (MMU._carttype) { case 1: MMU._mbc[1].ramon = ((bval & 0xF) == 0xA) ? 1 : 0; break; } break; // MBC1: ROM bank switch case 0x2000: case 0x3000: switch (MMU._carttype) { case 1: MMU._mbc[1].rombank &= 0x60; bval &= 0x1F; if (bval == 0) { bval = 1; } MMU._mbc[1].rombank |= bval; MMU._romoffs = MMU._mbc[1].rombank * 0x4000; break; } break; // ROM bank 1 // MBC1: RAM bank switch case 0x4000: case 0x5000: switch (MMU._carttype) { case 1: if (MMU._mbc[1].mode != 0) { MMU._mbc[1].rambank = (bval & 3); MMU._ramoffs = MMU._mbc[1].rambank * 0x2000; } else { MMU._mbc[1].rombank &= 0x1F; MMU._mbc[1].rombank |= ((bval & 3) << 5); MMU._romoffs = MMU._mbc[1].rombank * 0x4000; } break; } break; case 0x6000: case 0x7000: switch (MMU._carttype) { case 1: MMU._mbc[1].mode = bval & 1; break; } break; // VRAM case 0x8000: case 0x9000: GPU._vram[addr & 0x1FFF] = bval; GPU.updatetile(addr & 0x1FFF, bval); break; // External RAM case 0xA000: case 0xB000: MMU._eram[MMU._ramoffs + (addr & 0x1FFF)] = bval; break; // Work RAM and echo case 0xC000: case 0xD000: case 0xE000: MMU._wram[addr & 0x1FFF] = bval; break; // Everything else case 0xF000: switch (addr & 0x0F00) { // Echo RAM case 0x000: case 0x100: case 0x200: case 0x300: case 0x400: case 0x500: case 0x600: case 0x700: case 0x800: case 0x900: case 0xA00: case 0xB00: case 0xC00: case 0xD00: MMU._wram[addr & 0x1FFF] = bval; break; // OAM case 0xE00: if ((addr & 0xFF) < 0xA0) { GPU._oam[addr & 0xFF] = bval; } GPU.updateoam(addr, bval); break; // Zeropage RAM, I/O, interrupts case 0xF00: if (addr == 0xFFFF) { MMU._ie = bval; } else if (addr > 0xFF7F) { MMU._zram[addr & 0x7F] = bval; } else { switch (addr & 0xF0) { case 0x00: switch (addr & 0xF) { case 0: KEY.wb(bval); break; case 4: case 5: case 6: case 7: TIMER.wb(addr, bval); break; case 15: MMU._if = bval; break; } break; case 0x10: case 0x20: case 0x30: break; case 0x40: case 0x50: case 0x60: case 0x70: GPU.wb(addr, bval); break; } } break; } break; } }
public static void wb(int addr, int val) { var gaddr = addr - 0xFF40; GPU._reg[gaddr] = val; switch (gaddr) { case 0: GPU._lcdon = (val & 0x80) != 0 ? 1 : 0; GPU._bgtilebase = (val & 0x10) != 0 ? 0x0000 : 0x0800; GPU._bgmapbase = (val & 0x08) != 0 ? 0x1C00 : 0x1800; GPU._objsize = (val & 0x04) != 0 ? 1 : 0; GPU._objon = (val & 0x02) != 0 ? 1 : 0; GPU._bgon = (val & 0x01) != 0 ? 1 : 0; break; case 2: GPU._yscrl = val; break; case 3: GPU._xscrl = val; break; case 5: GPU._raster = val; goto case 6; // OAM DMA case 6: int v; for (var i = 0; i < 160; i++) { v = MMU.rb((val << 8) + i); GPU._oam[i] = v; GPU.updateoam(0xFE00 + i, v); } break; // BG palette mapping case 7: for (var i = 0; i < 4; i++) { switch ((val >> (i * 2)) & 3) { case 0: GPU._palette.bg[i] = 255; break; case 1: GPU._palette.bg[i] = 192; break; case 2: GPU._palette.bg[i] = 96; break; case 3: GPU._palette.bg[i] = 0; break; } } break; // OBJ0 palette mapping case 8: for (var i = 0; i < 4; i++) { switch ((val >> (i * 2)) & 0b11) { case 0: GPU._palette.obj0[i] = 255; break; case 1: GPU._palette.obj0[i] = 192; break; case 2: GPU._palette.obj0[i] = 96; break; case 3: GPU._palette.obj0[i] = 0; break; } } break; // OBJ1 palette mapping case 9: for (var i = 0; i < 4; i++) { switch ((val >> (i * 2)) & 0b11) { case 0: GPU._palette.obj1[i] = 255; break; case 1: GPU._palette.obj1[i] = 192; break; case 2: GPU._palette.obj1[i] = 96; break; case 3: GPU._palette.obj1[i] = 0; break; } } break; } }