public void RLC() { cpu = new CPU(mmu, regs); regs.PC = 0xc000; regs.SetAllRegs(0x85); //put the test data into memory. for (int i = 0; i < 8; i++) { mmu.wb((ushort)(0xc000 + i), (byte)i); // push the RLC instructions into memory. } cpu.Tick(0xcb); Assert.That(regs.B, Is.EqualTo(0xb)); cpu.Tick(0xcb); Assert.That(regs.C, Is.EqualTo(0xb)); cpu.Tick(0xcb); Assert.That(regs.D, Is.EqualTo(0xb)); cpu.Tick(0xcb); Assert.That(regs.E, Is.EqualTo(0xb)); cpu.Tick(0xcb); Assert.That(regs.H, Is.EqualTo(0xb)); cpu.Tick(0xcb); Assert.That(regs.L, Is.EqualTo(0xb)); //the HL register mmu.wb(0xc150, 0x85); regs.HL = 0xc150; cpu.Tick(0xcb); Assert.That(mmu.rb(0xc150), Is.EqualTo(0xb)); //Finally a register. cpu.Tick(0xcb); Assert.That(regs.A, Is.EqualTo(0xb)); }
public void wb(int addr, int val) { gaddr = addr - 0xFF40; _reg[gaddr] = val; switch (gaddr) { case 0: _lcdon = ((val & 0x80) > 0)?true:false; _winbase = ((val & 0x40) > 0)?0x1C00:0x1800; _winon = ((val & 0x20) > 0)?true:false; _bgtilebase = ((val & 0x10) > 0)?0x0000:0x0800; _bgmapbase = ((val & 0x08) > 0)?0x1C00:0x1800; _objsize = ((val & 0x04) > 0)?16:8; _winTransparent = ((val & 0x02) > 0)?false:true; _bgon = ((val & 0x01) > 0)?true:false; break; case 2: _yscrl = val; break; case 3: _xscrl = val; break; case 5: _raster = val; break; // OAM DMA case 6: for (i = 0; i < 160; i++) { v = mMU.rb((val << 8) + i); _oam[i] = v; updateoam(0xFE00 + i, v); } break; // BG palette mapping case 7: for (i = 0; i < 4; i++) { switch ((val >> (i * 2)) & 3) { case 3: bgPalette[i] = '\uE00F'; break; case 2: bgPalette[i] = '\uE00E'; break; case 1: bgPalette[i] = '\uE00D'; break; case 0: bgPalette[i] = '\uE006'; break; } } break; // OBJ0 palette mapping case 8: for (i = 0; i < 4; i++) { switch ((val >> (i * 2)) & 3) { case 3: obj0Palette[i] = '\uE00F'; break; case 2: obj0Palette[i] = '\uE00E'; break; case 1: obj0Palette[i] = '\uE00D'; break; case 0: obj0Palette[i] = '\uE006'; break; } } break; // OBJ1 palette mapping case 9: for (i = 0; i < 4; i++) { switch ((val >> (i * 2)) & 3) { case 3: obj1Palette[i] = '\uE00F'; break; case 2: obj1Palette[i] = '\uE00E'; break; case 1: obj1Palette[i] = '\uE00D'; break; case 0: obj1Palette[i] = '\uE006'; break; } } break; case 10: // WNDPOSY winy = val; break; case 11: if (val > 166) { _winon = false; } winx = val; break; } }
public void frame(int throttle, int frameSkip, int stage) { fclock = z80._clock.m + 17556; //Echo every 100 frames // if(stage % 100 == 0) Echo("Stepping Gameboy (PC = " + z80.r.pc + ")"); //var brk = document.getElementById('breakpoint').value; if ((stage % frameSkip) == 0) { gPU.drawNow(); } currentTime = System.DateTime.Now.Ticks; mMU._timer [0] = (int)((currentTime - startTime) / 610.3515625); switch (mMU._timer[3] & 0x3) { case 0: mMU._timer [1] += (int)(((currentTime - lastTime) / 610.3515625) / 1024); break; case 1: mMU._timer [1] += (int)(((currentTime - lastTime) / 610.3515625) / 16); break; case 2: mMU._timer [1] += (int)(((currentTime - lastTime) / 610.3515625) / 64); break; case 3: mMU._timer [1] += (int)(((currentTime - lastTime) / 610.3515625) / 256); break; } if (mMU._timer [1] > 255) { mMU._if |= 0x04; lastTime = currentTime; } if (currentTime - hblankTime > 283813) //handle hblank { mMU._if |= 0x01; hblankTime = currentTime; vblanks++; // Echo("vblank " + vblanks); } lastTime = currentTime; for (; z80._clock.m < fclock && throttle > 0; throttle--) { //if(z80._halt!=0) z80.r.m=1; //else //{ // z80.r.r = (z80.r.r+1) & 127; z80._map[mMU.rb(z80.r.pc++)](); z80.r.pc &= 65535; //} if (z80.r.ime != 0 && mMU._ie != 0 && mMU._if != 0) { z80._halt = 0; z80.r.ime = 0; ifired = mMU._ie & mMU._if; if ((ifired & 1) != 0) { mMU._if &= 0xFE; z80.RST40(); } else if ((ifired & 2) != 0) { mMU._if &= 0xFD; z80.RST48(); } else if ((ifired & 4) != 0) { mMU._if &= 0xFB; z80.RST50(); } else if ((ifired & 8) != 0) { mMU._if &= 0xF7; z80.RST58(); } else if ((ifired & 16) != 0) { mMU._if &= 0xEF; z80.RST60(); } else { z80.r.ime = 1; } } z80._clock.m += z80.r.m; gPU.checkline(); // tIMER.inc(); } }