diff --git a/Assets/defctrl.json b/Assets/defctrl.json
index e213cfae5f..42f8b4cee1 100644
--- a/Assets/defctrl.json
+++ b/Assets/defctrl.json
@@ -755,7 +755,7 @@
"Reset": "J1 B9, X1 Back",
"Pause": "J1 B10, X1 Start"
},
- "SMS Sports Pad Controller": {
+ "SMS Sports Pad Controller": {
"P1 Up": "UpArrow, J1 POV1U",
"P1 Down": "DownArrow, J1 POV1D",
"P1 Left": "LeftArrow, J1 POV1L",
@@ -771,6 +771,89 @@
"P2 B1": "",
"P2 B2": ""
},
+ "SMS Keyboard Controller": {
+ "Key 1": "D1",
+ "Key 2": "D2",
+ "Key 3": "D3",
+ "Key 4": "D4",
+ "Key 5": "D5",
+ "Key 6": "D6",
+ "Key 7": "D7",
+ "Key 8": "D8",
+ "Key 9": "D9",
+ "Key 0": "D0",
+ "Key Minus": "Minus",
+ "Key Caret": "Equals",
+ "Key Yen": "Backspace",
+ "Key Break": "Delete",
+
+ "Key Function": "Tab",
+ "Key Q": "Q",
+ "Key W": "W",
+ "Key E": "E",
+ "Key R": "R",
+ "Key T": "T",
+ "Key Y": "Y",
+ "Key U": "U",
+ "Key I": "I",
+ "Key O": "O",
+ "Key P": "P",
+ "Key At": "LeftBracket",
+ "Key Left Bracket": "RightBracket",
+ "Key Return": "Return",
+ "Key Up Arrow": "UpArrow",
+
+ "Key Control": "CapsLock",
+ "Key A": "A",
+ "Key S": "S",
+ "Key D": "D",
+ "Key F": "F",
+ "Key G": "G",
+ "Key H": "H",
+ "Key J": "J",
+ "Key K": "K",
+ "Key L": "L",
+ "Key Semicolon": "Semicolon",
+ "Key Colon": "Apostrophe",
+ "Key Right Bracket": "Backslash",
+ "Key Left Arrow": "LeftArrow",
+ "Key Right Arrow": "RightArrow",
+
+ "Key Shift": "LeftShift",
+ "Key Z": "Z",
+ "Key X": "X",
+ "Key C": "C",
+ "Key V": "V",
+ "Key B": "B",
+ "Key N": "N",
+ "Key M": "M",
+ "Key Comma": "Comma",
+ "Key Period": "Period",
+ "Key Slash": "Slash",
+ "Key PI": "RightShift",
+ "Key Down Arrow": "DownArrow",
+
+ "Key Graph": "PageUp",
+ "Key Kana": "PageDown",
+ "Key Space": "Space",
+ "Key Home/Clear": "Home",
+ "Key Insert/Delete": "Insert",
+
+ "P1 Up": "J1 POV1U, X1 DpadUp, X1 LStickUp",
+ "P1 Down": "J1 POV1D, X1 DpadDown, X1 LStickDown",
+ "P1 Left": "J1 POV1L, X1 DpadLeft, X1 LStickLeft",
+ "P1 Right": "J1 POV1R, X1 DpadRight, X1 LStickRight",
+ "P1 B1": "J1 B1, X1 X",
+ "P1 B2": "J1 B2, X1 A",
+ "Reset": "J1 B9, X1 Back",
+ "Pause": "J1 B10, X1 Start",
+ "P2 Up": "",
+ "P2 Down": "",
+ "P2 Left": "",
+ "P2 Right": "",
+ "P2 B1": "",
+ "P2 B2": ""
+ },
"GG Controller": {
"P1 Up": "UpArrow, J1 POV1U, X1 DpadUp, X1 LStickUp",
"P1 Down": "DownArrow, J1 POV1D, X1 DpadDown, X1 LStickDown",
@@ -1615,23 +1698,23 @@
"Deadzone": 0.0
}
},
- "SMS Sports Pad Controller": {
+ "SMS Sports Pad Controller": {
"P1 X": {
"Value": "X1 LeftThumbX",
"Mult": 1.0,
"Deadzone": 0.1
},
- "P1 Y": {
+ "P1 Y": {
"Value": "X1 LeftThumbY",
"Mult": -1.0,
"Deadzone": 0.1
},
- "P2 X": {
+ "P2 X": {
"Value": "X2 LeftThumbX",
"Mult": 1.0,
"Deadzone": 0.1
},
- "P2 Y": {
+ "P2 Y": {
"Value": "X2 LeftThumbY",
"Mult": -1.0,
"Deadzone": 0.1
diff --git a/BizHawk.Client.Common/tools/Cheat.cs b/BizHawk.Client.Common/tools/Cheat.cs
index 4680168276..28ab738080 100644
--- a/BizHawk.Client.Common/tools/Cheat.cs
+++ b/BizHawk.Client.Common/tools/Cheat.cs
@@ -288,17 +288,17 @@ namespace BizHawk.Client.Common
{
if (addr == _watch.Address)
{
- return (byte)(_val & 0xFF);
+ return (byte)(_val >> 8);
}
- return (byte)(_val >> 8);
+ return (byte)(_val & 0xFF);
}
else
{
if (addr == _watch.Address)
{
- return (byte)(_val >> 8);
+ return (byte)(_val & 0xFF);
}
- return (byte)(_val & 0xFF);
+ return (byte)(_val >> 8);
}
case WatchSize.DWord:
if (_watch.BigEndian)
diff --git a/BizHawk.Client.EmuHawk/MainForm.Designer.cs b/BizHawk.Client.EmuHawk/MainForm.Designer.cs
index 0e250d1e01..d2c636448a 100644
--- a/BizHawk.Client.EmuHawk/MainForm.Designer.cs
+++ b/BizHawk.Client.EmuHawk/MainForm.Designer.cs
@@ -450,6 +450,7 @@
this.SMSControllerPaddleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SMSControllerLightPhaserToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SMSControllerSportsPadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.SMSControllerKeyboardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.MainformMenu.SuspendLayout();
this.MainStatusBar.SuspendLayout();
this.MainFormContextMenu.SuspendLayout();
@@ -2584,7 +2585,8 @@
this.SMSControllerStandardToolStripMenuItem,
this.SMSControllerPaddleToolStripMenuItem,
this.SMSControllerLightPhaserToolStripMenuItem,
- this.SMSControllerSportsPadToolStripMenuItem});
+ this.SMSControllerSportsPadToolStripMenuItem,
+ this.SMSControllerKeyboardToolStripMenuItem});
//
// SMSControllerStandardToolStripMenuItem
//
@@ -2609,6 +2611,12 @@
this.SMSControllerSportsPadToolStripMenuItem.Name = "SMSControllerSportsPadToolStripMenuItem";
this.SMSControllerSportsPadToolStripMenuItem.Text = "Sports Pad";
this.SMSControllerSportsPadToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerSportsPadToolStripMenuItem_Click);
+ //
+ // SMSControllerKeyboardToolStripMenuItem
+ //
+ this.SMSControllerKeyboardToolStripMenuItem.Name = "SMSControllerKeyboardToolStripMenuItem";
+ this.SMSControllerKeyboardToolStripMenuItem.Text = "Keyboard";
+ this.SMSControllerKeyboardToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerKeyboardToolStripMenuItem_Click);
//
// SMSdisplayPalToolStripMenuItem
@@ -4445,5 +4453,6 @@
private System.Windows.Forms.ToolStripMenuItem SMSControllerPaddleToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem SMSControllerLightPhaserToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem SMSControllerSportsPadToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem SMSControllerKeyboardToolStripMenuItem;
}
}
diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs
index 026adb32be..3eb36838f1 100644
--- a/BizHawk.Client.EmuHawk/MainForm.Events.cs
+++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs
@@ -1765,6 +1765,7 @@ namespace BizHawk.Client.EmuHawk
SMSControllerPaddleToolStripMenuItem.Checked = ss.ControllerType == "Paddle";
SMSControllerLightPhaserToolStripMenuItem.Checked = ss.ControllerType == "Light Phaser";
SMSControllerSportsPadToolStripMenuItem.Checked = ss.ControllerType == "Sports Pad";
+ SMSControllerKeyboardToolStripMenuItem.Checked = ss.ControllerType == "Keyboard";
SMSenableBIOSToolStripMenuItem.Checked = ss.UseBIOS;
SMSEnableFMChipMenuItem.Checked = ss.EnableFM;
SMSOverclockMenuItem.Checked = ss.AllowOverlock;
@@ -1946,6 +1947,13 @@ namespace BizHawk.Client.EmuHawk
s.ControllerType = "Sports Pad";
PutCoreSyncSettings(s);
}
+
+ private void SMSControllerKeyboardToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ var s = ((SMS)Emulator).GetSyncSettings();
+ s.ControllerType = "Keyboard";
+ PutCoreSyncSettings(s);
+ }
#endregion
diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs
index 170dbb2322..fa6977cd9f 100644
--- a/BizHawk.Client.EmuHawk/MainForm.cs
+++ b/BizHawk.Client.EmuHawk/MainForm.cs
@@ -3854,6 +3854,7 @@ namespace BizHawk.Client.EmuHawk
UpdateStatusSlots();
CurrentlyOpenRom = null;
CurrentlyOpenRomArgs = null;
+ _currentlyOpenRomPoopForAdvancedLoaderPleaseRefactorMe = "";
}
}
diff --git a/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs b/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs
index 8dc50567ef..42a6507166 100644
--- a/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs
+++ b/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs
@@ -87,7 +87,6 @@ namespace BizHawk.Client.EmuHawk
{
_cgb = Gb.IsCGBMode();
_lcdc = 0;
-
_memory = Gb.GetGPU();
tilespal = _memory.Bgpal;
@@ -129,7 +128,7 @@ namespace BizHawk.Client.EmuHawk
for (int x = 0; x < 8; x++) // right to left
{
int color = loplane & 1 | hiplane & 2;
- *dest-- = pal[color];
+ *dest-- = (int)(pal[color] | 0xFF000000);
loplane >>= 1;
hiplane >>= 1;
}
@@ -161,7 +160,7 @@ namespace BizHawk.Client.EmuHawk
for (int x = 0; x < 8; x++) // right to left
{
int color = loplane & 1 | hiplane & 2;
- *dest = pal[color];
+ *dest = (int)(pal[color] | 0xFF000000);
if (!hflip)
dest--;
else
@@ -316,9 +315,11 @@ namespace BizHawk.Client.EmuHawk
int* thispal = pal + 4 * (cgb ? flags & 7 : flags >> 4 & 1);
if (cgb && flags.Bit(3))
tile += 8192;
+
DrawTileHv(tile, dest, pitch, thispal, hflip, vflip);
+
if (tall)
- DrawTileHv((byte*)((int)tile ^ 16), dest + pitch * 8, pitch, thispal, hflip, vflip);
+ DrawTileHv(tile + 16, dest + pitch * 8, pitch, thispal, hflip, vflip);
dest += 8;
}
b.UnlockBits(lockdata);
@@ -341,7 +342,7 @@ namespace BizHawk.Client.EmuHawk
{
for (int py = 0; py < 4; py++)
{
- *dest = *pal++;
+ *dest = (int)(*pal++ | 0xFF000000);
dest += pitch;
}
dest -= pitch * 4;
@@ -465,7 +466,7 @@ namespace BizHawk.Client.EmuHawk
}
DrawOam(bmpViewOAM.BMP, _oam, _vram, _sppal, lcdc.Bit(2), _cgb);
bmpViewOAM.Refresh();
- }
+ }
// try to run the current mouseover, to refresh if the mouse is being held over a pane while the emulator runs
// this doesn't really work well; the update rate seems to be throttled
MouseEventArgs e = new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0);
diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index 05baf2d9d0..4a00050be4 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -582,6 +582,9 @@
+
+
+
diff --git a/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs b/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs
index 921ee5f19f..f68b2689c8 100644
--- a/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs
+++ b/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs
@@ -68,7 +68,7 @@ namespace BizHawk.Emulation.Common.Components.LR35902
case 0x27: INT_OP(DA, A); break; // DAA
case 0x28: JR_COND(FlagZ); break; // JR Z, r8
case 0x29: ADD_16(L, H, L, H); break; // ADD HL, HL
- case 0x2A: LD_IND_8_INC(A, L, H); break; // LD A, (HL+)
+ case 0x2A: LD_IND_8_INC_HL(A, L, H); break; // LD A, (HL+)
case 0x2B: DEC_16(L, H); break; // DEC HL
case 0x2C: INT_OP(INC8, L); break; // INC L
case 0x2D: INT_OP(DEC8, L); break; // DEC L
@@ -84,7 +84,7 @@ namespace BizHawk.Emulation.Common.Components.LR35902
case 0x37: INT_OP(SCF, A); break; // SCF
case 0x38: JR_COND(FlagC); break; // JR C, r8
case 0x39: ADD_16(L, H, SPl, SPh); break; // ADD HL, SP
- case 0x3A: LD_IND_8_DEC(A, L, H); break; // LD A, (HL-)
+ case 0x3A: LD_IND_8_DEC_HL(A, L, H); break; // LD A, (HL-)
case 0x3B: DEC_16(SPl, SPh); break; // DEC SP
case 0x3C: INT_OP(INC8, A); break; // INC A
case 0x3D: INT_OP(DEC8, A); break; // DEC A
diff --git a/BizHawk.Emulation.Cores/CPUs/LR35902/Tables_Direct.cs b/BizHawk.Emulation.Cores/CPUs/LR35902/Tables_Direct.cs
index 5979671599..a611b780b9 100644
--- a/BizHawk.Emulation.Cores/CPUs/LR35902/Tables_Direct.cs
+++ b/BizHawk.Emulation.Cores/CPUs/LR35902/Tables_Direct.cs
@@ -19,10 +19,10 @@ namespace BizHawk.Emulation.Common.Components.LR35902
private void INC_16(ushort src_l, ushort src_h)
{
cur_instr = new ushort[]
- {INC16, src_l, src_h,
- IDLE,
+ {IDLE,
IDLE,
IDLE,
+ INC16, src_l, src_h,
IDLE,
IDLE,
IDLE,
@@ -33,10 +33,10 @@ namespace BizHawk.Emulation.Common.Components.LR35902
private void DEC_16(ushort src_l, ushort src_h)
{
cur_instr = new ushort[]
- {DEC16, src_l, src_h,
- IDLE,
+ {IDLE,
IDLE,
IDLE,
+ DEC16, src_l, src_h,
IDLE,
IDLE,
IDLE,
@@ -46,10 +46,10 @@ namespace BizHawk.Emulation.Common.Components.LR35902
private void ADD_16(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
{
cur_instr = new ushort[]
- {ADD16, dest_l, dest_h, src_l, src_h,
- IDLE,
+ {IDLE,
IDLE,
IDLE,
+ ADD16, dest_l, dest_h, src_l, src_h,
IDLE,
IDLE,
IDLE,
@@ -76,15 +76,7 @@ namespace BizHawk.Emulation.Common.Components.LR35902
private void HALT_()
{
- if (!FlagI)
- {
- cur_instr = new ushort[]
- {IDLE,
- IDLE,
- IDLE,
- HALT };
- }
- else
+ if (FlagI && (EI_pending == 0))
{
// if interrupts are disabled,
// a glitchy decrement to the program counter happens
@@ -94,6 +86,14 @@ namespace BizHawk.Emulation.Common.Components.LR35902
IDLE,
OP_G};
}
+ else
+ {
+ cur_instr = new ushort[]
+ {IDLE,
+ IDLE,
+ IDLE,
+ HALT };
+ }
}
diff --git a/BizHawk.Emulation.Cores/CPUs/LR35902/Tables_Indirect.cs b/BizHawk.Emulation.Cores/CPUs/LR35902/Tables_Indirect.cs
index 59b3ed63bc..79d2e67341 100644
--- a/BizHawk.Emulation.Cores/CPUs/LR35902/Tables_Indirect.cs
+++ b/BizHawk.Emulation.Cores/CPUs/LR35902/Tables_Indirect.cs
@@ -169,7 +169,20 @@
OP };
}
- private void LD_IND_8_DEC(ushort dest, ushort src_l, ushort src_h)
+ private void LD_IND_8_INC_HL(ushort dest, ushort src_l, ushort src_h)
+ {
+ cur_instr = new ushort[]
+ {IDLE,
+ IDLE,
+ IDLE,
+ RD, dest, src_l, src_h,
+ IDLE,
+ INC16, src_l, src_h,
+ IDLE,
+ OP };
+ }
+
+ private void LD_IND_8_DEC_HL(ushort dest, ushort src_l, ushort src_h)
{
cur_instr = new ushort[]
{IDLE,
diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/NewDisassembler.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/NewDisassembler.cs
index 6ac1a76444..a312975d78 100644
--- a/BizHawk.Emulation.Cores/CPUs/Z80A/NewDisassembler.cs
+++ b/BizHawk.Emulation.Cores/CPUs/Z80A/NewDisassembler.cs
@@ -393,7 +393,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0x100
};
- public string Disassemble(ushort addr, Func read, out ushort size)
+ public string Disassemble(ushort addr, Func read, out int size)
{
ushort start_addr = addr;
ushort extra_inc = 0;
@@ -434,7 +434,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
addr += extra_inc;
- size = (ushort)(addr - start_addr);
+ size = addr - start_addr;
return temp;
}
@@ -458,10 +458,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
public string Disassemble(MemoryDomain m, uint addr, out int length)
{
- int loc = (int)addr;
- ushort unused = 0;
- string ret = Disassemble((ushort) addr, a => m.PeekByte(a), out unused);
- length = loc - (int)addr;
+ string ret = Disassemble((ushort)addr, a => m.PeekByte(a), out length);
return ret;
}
diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs
index 6cb1a36617..46abee9809 100644
--- a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs
+++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs
@@ -609,7 +609,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
public TraceInfo State(bool disassemble = true)
{
- ushort bytes_read = 0;
+ int bytes_read = 0;
string disasm = disassemble ? Disassemble(RegPC, ReadMemory, out bytes_read) : "---";
string byte_code = null;
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs
index 5d3cbe082c..28b9c2edf2 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs
@@ -85,7 +85,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public int SQ1_vol_per, SQ2_vol_per, NOISE_vol_per;
public int SQ1_intl_swp_cnt;
public int NOISE_LFSR;
- public ushort SQ1_len_cntr, SQ2_len_cntr, WAVE_len_cntr, NOISE_len_cntr;
+ public ushort SQ1_len_cntr, SQ2_len_cntr, WAVE_len_cntr, NOISE_len_cntr;
// computed
public int SQ1_output, SQ2_output, WAVE_output, NOISE_output;
@@ -179,7 +179,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
SQ1_negate = (value & 8) > 0;
SQ1_shift = (byte)(value & 7);
- if (!SQ1_negate && SQ1_calc_done) { SQ1_enable = false; }
+ if (!SQ1_negate && SQ1_calc_done) { SQ1_enable = false; SQ1_output = 0; }
break;
case 0xFF11: // NR11 (sound length / wave pattern duty %)
Audio_Regs[NR11] = value;
@@ -192,8 +192,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
SQ1_st_vol = (byte)((value & 0xF0) >> 4);
SQ1_env_add = (value & 8) > 0;
SQ1_per = (byte)(value & 7);
- if (SQ1_per == 0) { SQ1_per = 8; }
- if ((value & 0xF8) == 0) { SQ1_enable = SQ1_swp_enable = false; }
+ if ((value & 0xF8) == 0) { SQ1_enable = SQ1_swp_enable = false; SQ1_output = 0; }
break;
case 0xFF13: // NR13 (freq low)
Audio_Regs[NR13] = value;
@@ -211,7 +210,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (!SQ1_len_en && ((value & 0x40) > 0) && (SQ1_len_cntr > 0))
{
SQ1_len_cntr--;
- if ((SQ1_len_cntr == 0) && !SQ1_trigger) { SQ1_enable = SQ1_swp_enable = false; }
+ if ((SQ1_len_cntr == 0) && !SQ1_trigger) { SQ1_enable = SQ1_swp_enable = false; SQ1_output = 0; }
}
}
@@ -251,14 +250,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// disable channel if overflow
if ((uint)shadow_frq > 2047)
{
- SQ1_enable = SQ1_swp_enable = false;
+ SQ1_enable = SQ1_swp_enable = false; SQ1_output = 0;
}
// set negate mode flag that disables channel is negate clerar
if (SQ1_negate) { SQ1_calc_done = true; }
}
- if ((SQ1_vol_state == 0) && !SQ1_env_add) { SQ1_enable = SQ1_swp_enable = false; }
+ if ((SQ1_vol_state == 0) && !SQ1_env_add) { SQ1_enable = SQ1_swp_enable = false; SQ1_output = 0; }
}
SQ1_len_en = (value & 0x40) > 0;
@@ -274,8 +273,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
SQ2_st_vol = (byte)((value & 0xF0) >> 4);
SQ2_env_add = (value & 8) > 0;
SQ2_per = (byte)(value & 7);
- //if (SQ2_per == 0) { SQ2_per = 8; }
- if ((value & 0xF8) == 0) { SQ2_enable = false; }
+ if ((value & 0xF8) == 0) { SQ2_enable = false; SQ2_output = 0; }
break;
case 0xFF18: // NR23 (freq low)
Audio_Regs[NR23] = value;
@@ -293,7 +291,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (!SQ2_len_en && ((value & 0x40) > 0) && (SQ2_len_cntr > 0))
{
SQ2_len_cntr--;
- if ((SQ2_len_cntr == 0) && !SQ2_trigger) { SQ2_enable = false; }
+ if ((SQ2_len_cntr == 0) && !SQ2_trigger) { SQ2_enable = false; SQ2_output = 0; }
}
}
@@ -310,16 +308,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
SQ2_intl_cntr = (2048 - SQ2_frq) * 4;
SQ2_vol_state = SQ2_st_vol;
SQ2_vol_per = (SQ2_per > 0) ? SQ2_per : 8;
- if ((SQ2_vol_state == 0) && !SQ2_env_add) { SQ2_enable = false; }
+ if ((SQ2_vol_state == 0) && !SQ2_env_add) { SQ2_enable = false; SQ2_output = 0; }
}
SQ2_len_en = (value & 0x40) > 0;
-
break;
case 0xFF1A: // NR30 (on/off)
Audio_Regs[NR30] = value;
WAVE_DAC_pow = (value & 0x80) > 0;
- if (!WAVE_DAC_pow) { WAVE_enable = false; }
+ if (!WAVE_DAC_pow) { WAVE_enable = false; WAVE_output = 0; }
break;
case 0xFF1B: // NR31 (length)
Audio_Regs[NR31] = value;
@@ -346,7 +343,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (!WAVE_len_en && ((value & 0x40) > 0) && (WAVE_len_cntr > 0))
{
WAVE_len_cntr--;
- if ((WAVE_len_cntr == 0) && !WAVE_trigger) { WAVE_enable = false; }
+ if ((WAVE_len_cntr == 0) && !WAVE_trigger) { WAVE_enable = false; WAVE_output = 0; }
}
}
@@ -379,7 +376,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
WAVE_intl_cntr = (2048 - WAVE_frq) * 2 + 6; // trigger delay for wave channel
WAVE_wave_cntr = 0;
- if (!WAVE_DAC_pow) { WAVE_enable = false; }
+ if (!WAVE_DAC_pow) { WAVE_enable = false; WAVE_output = 0; }
}
WAVE_len_en = (value & 0x40) > 0;
@@ -395,8 +392,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
NOISE_st_vol = (byte)((value & 0xF0) >> 4);
NOISE_env_add = (value & 8) > 0;
NOISE_per = (byte)(value & 7);
- //if (NOISE_per == 0) { NOISE_per = 8; }
- if ((value & 0xF8) == 0) { NOISE_enable = false; }
+ if ((value & 0xF8) == 0) { NOISE_enable = false; NOISE_output = 0; }
break;
case 0xFF22: // NR43 (shift)
Audio_Regs[NR43] = value;
@@ -413,7 +409,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (!NOISE_len_en && ((value & 0x40) > 0) && (NOISE_len_cntr > 0))
{
NOISE_len_cntr--;
- if ((NOISE_len_cntr == 0) && !NOISE_trigger) { NOISE_enable = false; }
+ if ((NOISE_len_cntr == 0) && !NOISE_trigger) { NOISE_enable = false; NOISE_output = 0; }
}
}
@@ -431,7 +427,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
NOISE_vol_state = NOISE_st_vol;
NOISE_vol_per = (NOISE_per > 0) ? NOISE_per : 8;
NOISE_LFSR = 0x7FFF;
- if ((NOISE_vol_state == 0) && !NOISE_env_add) { NOISE_enable = false; }
+ if ((NOISE_vol_state == 0) && !NOISE_env_add) { NOISE_enable = false; NOISE_output = 0; }
}
NOISE_len_en = (value & 0x40) > 0;
@@ -454,10 +450,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
AUD_CTRL_sq2_R_en = (value & 2) > 0;
AUD_CTRL_sq1_R_en = (value & 1) > 0;
break;
- case 0xFF26: // NR52 (ctrl)
+ case 0xFF26: // NR52 (ctrl)
+ // NOTE: Make sure to do the power off first since it will call the write_reg function again
+ if ((value & 0x80) == 0) { power_off(); }
AUD_CTRL_power = (value & 0x80) > 0;
-
- if (!AUD_CTRL_power) { power_off(); }
break;
// wave ram table
@@ -548,12 +544,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
SQ1_intl_cntr--;
if (SQ1_intl_cntr == 0)
{
- SQ1_intl_cntr = (2048 - SQ1_frq_shadow) * 4;
+ SQ1_intl_cntr = (2048 - SQ1_frq) * 4;
SQ1_duty_cntr++;
SQ1_duty_cntr &= 7;
SQ1_output = DUTY_CYCLES[SQ1_duty * 8 + SQ1_duty_cntr];
SQ1_output *= SQ1_vol_state;
+
+ // avoid aliasing at high frequenices
+ if (SQ1_frq > 0x7F0) { SQ1_output = 0; }
}
}
@@ -569,6 +568,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
SQ2_output = DUTY_CYCLES[SQ2_duty * 8 + SQ2_duty_cntr];
SQ2_output *= SQ2_vol_state;
+
+ // avoid aliasing at high frequenices
+ if (SQ2_frq > 0x7F0) { SQ2_output = 0; }
}
}
@@ -613,6 +615,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
WAVE_output = sample;
if (!WAVE_DAC_pow) { WAVE_output = 0; }
+
+ // avoid aliasing at high frequenices
+ if (WAVE_frq > 0x7F0) { WAVE_output = 0; }
}
}
@@ -664,9 +669,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
master_audio_clock = 0;
if (AudioClocks < 1500)
{
- AudioSamples[AudioClocks] = (short)(L_final * 4);
+ AudioSamples[AudioClocks] = (short)(L_final * 20);
AudioClocks++;
- AudioSamples[AudioClocks] = (short)(R_final * 4);
+ AudioSamples[AudioClocks] = (short)(R_final * 20);
AudioClocks++;
}
}
@@ -688,22 +693,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (SQ1_len_en && SQ1_len_cntr > 0)
{
SQ1_len_cntr--;
- if (SQ1_len_cntr == 0) { SQ1_enable = SQ1_swp_enable = false; }
+ if (SQ1_len_cntr == 0) { SQ1_enable = SQ1_swp_enable = false; SQ1_output = 0; }
}
if (SQ2_len_en && SQ2_len_cntr > 0)
{
SQ2_len_cntr--;
- if (SQ2_len_cntr == 0) { SQ2_enable = false; }
+ if (SQ2_len_cntr == 0) { SQ2_enable = false; SQ2_output = 0; }
}
if (WAVE_len_en && WAVE_len_cntr > 0)
{
WAVE_len_cntr--;
- if (WAVE_len_cntr == 0) { WAVE_enable = false; }
+ if (WAVE_len_cntr == 0) { WAVE_enable = false; WAVE_output = 0; }
}
if (NOISE_len_en && NOISE_len_cntr > 0)
{
NOISE_len_cntr--;
- if (NOISE_len_cntr == 0) { NOISE_enable = false; }
+ if (NOISE_len_cntr == 0) { NOISE_enable = false; NOISE_output = 0; }
}
}
@@ -728,7 +733,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// disable channel if overflow
if ((uint)shadow_frq > 2047)
{
- SQ1_enable = SQ1_swp_enable = false;
+ SQ1_enable = SQ1_swp_enable = false; SQ1_output = 0;
}
else
{
@@ -751,7 +756,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if ((uint)shadow_frq > 2047)
{
- SQ1_enable = SQ1_swp_enable = false;
+ SQ1_enable = SQ1_swp_enable = false; SQ1_output = 0;
}
}
}
@@ -783,6 +788,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
}
}
+
if (SQ2_per > 0)
{
SQ2_vol_per--;
@@ -804,6 +810,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
}
}
+
if (NOISE_per > 0)
{
NOISE_vol_per--;
@@ -831,30 +838,24 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public void power_off()
{
- for (int i = 0; i < 21; i++)
+ for (int i = 0; i < 0x16; i++)
{
- Audio_Regs[i] = 0;
+ WriteReg(0xFF10 + i, 0);
}
- // reset derived values
- sync_channels();
+ // duty and length are reset
+ SQ1_duty_cntr = SQ2_duty_cntr = 0;
// reset state variables
- SQ1_enable = SQ1_swp_enable = false;
- SQ2_enable = false;
- WAVE_enable = false;
- NOISE_enable = false;
+ SQ1_enable = SQ1_swp_enable = SQ2_enable = WAVE_enable = NOISE_enable = false;
- SQ1_len_en = false;
- SQ2_len_en = false;
- WAVE_len_en = false;
- NOISE_len_en = false;
+ SQ1_len_en = SQ2_len_en = WAVE_len_en = NOISE_len_en = false;
+
+ SQ1_output = SQ2_output = WAVE_output = NOISE_output = 0;
sequencer_len = 0;
sequencer_vol = 0;
sequencer_swp = 0;
-
- master_audio_clock = 0;
}
public void Reset()
@@ -877,43 +878,82 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
ser.Sync("Audio_Regs", ref Audio_Regs, false);
ser.Sync("Wave_Ram", ref Wave_RAM, false);
-
- // save state variables
- ser.Sync("WAVE_can_get", ref WAVE_can_get);
+
ser.Sync("SQ1_vol_done", ref SQ1_vol_done);
- ser.Sync("SQ2_vol_done", ref SQ2_vol_done);
- ser.Sync("NOISE_vol_done", ref NOISE_vol_done);
ser.Sync("SQ1_calc_done", ref SQ1_calc_done);
ser.Sync("SQ1_swp_enable", ref SQ1_swp_enable);
ser.Sync("SQ1_length_counter", ref SQ1_len_cntr);
- ser.Sync("SQ2_length_counter", ref SQ2_len_cntr);
- ser.Sync("WAVE_length_counter", ref WAVE_len_cntr);
- ser.Sync("NOISE_length_counter", ref NOISE_len_cntr);
ser.Sync("SQ1_enable", ref SQ1_enable);
- ser.Sync("SQ2_enable", ref SQ2_enable);
- ser.Sync("WAVE_enable", ref WAVE_enable);
- ser.Sync("NOISE_enable", ref NOISE_enable);
ser.Sync("SQ1_vol_state", ref SQ1_vol_state);
- ser.Sync("SQ2_vol_state", ref SQ2_vol_state);
- ser.Sync("NOISE_vol_state", ref NOISE_vol_state);
ser.Sync("SQ1_duty_cntr", ref SQ1_duty_cntr);
- ser.Sync("SQ2_duty_cntr", ref SQ2_duty_cntr);
- ser.Sync("WAVE_wave_cntr", ref WAVE_wave_cntr);
ser.Sync("SQ1_frq_shadow", ref SQ1_frq_shadow);
ser.Sync("SQ1_intl_cntr", ref SQ1_intl_cntr);
- ser.Sync("SQ2_intl_cntr", ref SQ2_intl_cntr);
- ser.Sync("WAVE_intl_cntr", ref WAVE_intl_cntr);
- ser.Sync("NOISE_intl_cntr", ref NOISE_intl_cntr);
ser.Sync("SQ1_vol_per", ref SQ1_vol_per);
- ser.Sync("SQ2_vol_per", ref SQ2_vol_per);
- ser.Sync("NOISE_vol_per", ref NOISE_vol_per);
ser.Sync("SQ1_intl_swp_cnt", ref SQ1_intl_swp_cnt);
- ser.Sync("NOISE_LFSR", ref NOISE_LFSR);
ser.Sync("SQ1_len_cntr", ref SQ1_len_cntr);
- ser.Sync("SQ2_len_cntr", ref SQ2_len_cntr);
- ser.Sync("WAVE_len_cntr", ref WAVE_len_cntr);
- ser.Sync("NOISE_len_cntr", ref NOISE_len_cntr);
+ ser.Sync("SQ1_negate", ref SQ1_negate);
+ ser.Sync("SQ1_trigger", ref SQ1_trigger);
+ ser.Sync("SQ1_len_en", ref SQ1_len_en);
+ ser.Sync("SQ1_env_add", ref SQ1_env_add);
+ ser.Sync("SQ1_shift", ref SQ1_shift);
+ ser.Sync("SQ1_duty", ref SQ1_duty);
+ ser.Sync("SQ1_st_vol", ref SQ1_st_vol);
+ ser.Sync("SQ1_per", ref SQ1_per);
+ ser.Sync("SQ1_swp_prd", ref SQ1_swp_prd);
+ ser.Sync("SQ1_frq", ref SQ1_frq);
+ ser.Sync("SQ1_length", ref SQ1_length);
+ ser.Sync("SQ1_output", ref SQ1_output);
+ ser.Sync("SQ2_vol_done", ref SQ2_vol_done);
+ ser.Sync("SQ2_length_counter", ref SQ2_len_cntr);
+ ser.Sync("SQ2_enable", ref SQ2_enable);
+ ser.Sync("SQ2_vol_state", ref SQ2_vol_state);
+ ser.Sync("SQ2_duty_cntr", ref SQ2_duty_cntr);
+ ser.Sync("SQ2_intl_cntr", ref SQ2_intl_cntr);
+ ser.Sync("SQ2_vol_per", ref SQ2_vol_per);
+ ser.Sync("SQ2_len_cntr", ref SQ2_len_cntr);
+ ser.Sync("SQ2_trigger", ref SQ2_trigger);
+ ser.Sync("SQ2_len_en", ref SQ2_len_en);
+ ser.Sync("SQ2_env_add", ref SQ2_env_add);
+ ser.Sync("SQ2_duty", ref SQ2_duty);
+ ser.Sync("SQ2_st_vol", ref SQ2_st_vol);
+ ser.Sync("SQ2_per", ref SQ2_per);
+ ser.Sync("SQ2_frq", ref SQ2_frq);
+ ser.Sync("SQ2_length", ref SQ2_length);
+ ser.Sync("SQ2_output", ref SQ2_output);
+
+ ser.Sync("WAVE_can_get", ref WAVE_can_get);
+ ser.Sync("WAVE_length_counter", ref WAVE_len_cntr);
+ ser.Sync("WAVE_enable", ref WAVE_enable);
+ ser.Sync("WAVE_wave_cntr", ref WAVE_wave_cntr);
+ ser.Sync("WAVE_intl_cntr", ref WAVE_intl_cntr);
+ ser.Sync("WAVE_len_cntr", ref WAVE_len_cntr);
+ ser.Sync("WAVE_DAC_pow", ref WAVE_DAC_pow);
+ ser.Sync("WAVE_trigger", ref WAVE_trigger);
+ ser.Sync("WAVE_len_en", ref WAVE_len_en);
+ ser.Sync("WAVE_vol_code", ref WAVE_vol_code);
+ ser.Sync("WAVE_frq", ref WAVE_frq);
+ ser.Sync("WAVE_length", ref WAVE_length);
+ ser.Sync("WAVE_output", ref WAVE_output);
+
+ ser.Sync("NOISE_vol_done", ref NOISE_vol_done);
+ ser.Sync("NOISE_length_counter", ref NOISE_len_cntr);
+ ser.Sync("NOISE_enable", ref NOISE_enable);
+ ser.Sync("NOISE_vol_state", ref NOISE_vol_state);
+ ser.Sync("NOISE_intl_cntr", ref NOISE_intl_cntr);
+ ser.Sync("NOISE_vol_per", ref NOISE_vol_per);
+ ser.Sync("NOISE_LFSR", ref NOISE_LFSR);
+ ser.Sync("NOISE_len_cntr", ref NOISE_len_cntr);
+ ser.Sync("NOISE_wdth_md", ref NOISE_wdth_md);
+ ser.Sync("NOISE_trigger", ref NOISE_trigger);
+ ser.Sync("NOISE_len_en", ref NOISE_len_en);
+ ser.Sync("NOISE_env_add", ref NOISE_env_add);
+ ser.Sync("NOISE_clk_shft", ref NOISE_clk_shft);
+ ser.Sync("NOISE_div_code", ref NOISE_div_code);
+ ser.Sync("NOISE_st_vol", ref NOISE_st_vol);
+ ser.Sync("NOISE_per", ref NOISE_per);
+ ser.Sync("NOISE_length", ref NOISE_length);
+ ser.Sync("NOISE_output", ref NOISE_output);
ser.Sync("sequencer_len", ref sequencer_len);
ser.Sync("sequencer_vol", ref sequencer_vol);
@@ -921,93 +961,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("sequencer_tick", ref sequencer_tick);
ser.Sync("master_audio_clock", ref master_audio_clock);
-
- // get derived state
- if (ser.IsReader)
- {
- sync_channels();
- }
- }
-
- public void sync_channels()
- {
-
- SQ1_swp_prd = (byte)((Audio_Regs[NR10] & 0x70) >> 4);
- SQ1_negate = (Audio_Regs[NR10] & 8) > 0;
- SQ1_shift = (byte)(Audio_Regs[NR10] & 7);
-
- SQ1_duty = (byte)((Audio_Regs[NR11] & 0xC0) >> 6);
- SQ1_length = (ushort)(64 - Audio_Regs[NR11] & 0x3F);
-
- SQ1_st_vol = (byte)((Audio_Regs[NR12] & 0xF0) >> 4);
- SQ1_env_add = (Audio_Regs[NR12] & 8) > 0;
- SQ1_per = (byte)(Audio_Regs[NR12] & 7);
-
- SQ1_frq &= 0x700;
- SQ1_frq |= Audio_Regs[NR13];
-
- SQ1_trigger = (Audio_Regs[NR14] & 0x80) > 0;
- SQ1_len_en = (Audio_Regs[NR14] & 0x40) > 0;
- SQ1_frq &= 0xFF;
- SQ1_frq |= (ushort)((Audio_Regs[NR14] & 7) << 8);
-
- SQ2_duty = (byte)((Audio_Regs[NR21] & 0xC0) >> 6);
- SQ2_length = (ushort)(64 - Audio_Regs[NR21] & 0x3F);
-
- SQ2_st_vol = (byte)((Audio_Regs[NR22] & 0xF0) >> 4);
- SQ2_env_add = (Audio_Regs[NR22] & 8) > 0;
- SQ2_per = (byte)(Audio_Regs[NR22] & 7);
-
- SQ2_frq &= 0x700;
- SQ2_frq |= Audio_Regs[NR23];
-
- SQ2_trigger = (Audio_Regs[NR24] & 0x80) > 0;
- SQ2_len_en = (Audio_Regs[NR24] & 0x40) > 0;
- SQ2_frq &= 0xFF;
- SQ2_frq |= (ushort)((Audio_Regs[NR24] & 7) << 8);
-
- WAVE_DAC_pow = (Audio_Regs[NR30] & 0x80) > 0;
-
- WAVE_length = (ushort)(256 - Audio_Regs[NR31]);
-
- WAVE_vol_code = (byte)((Audio_Regs[NR32] & 0x60) >> 5);
-
- WAVE_frq &= 0x700;
- WAVE_frq |= Audio_Regs[NR33];
-
- WAVE_trigger = (Audio_Regs[NR34] & 0x80) > 0;
- WAVE_len_en = (Audio_Regs[NR34] & 0x40) > 0;
- WAVE_frq &= 0xFF;
- WAVE_frq |= (ushort)((Audio_Regs[NR34] & 7) << 8);
-
- NOISE_length = (ushort)(64 - Audio_Regs[NR41] & 0x3F);
-
- NOISE_st_vol = (byte)((Audio_Regs[NR42] & 0xF0) >> 4);
- NOISE_env_add = (Audio_Regs[NR42] & 8) > 0;
- NOISE_per = (byte)(Audio_Regs[NR42] & 7);
-
- NOISE_clk_shft = (byte)((Audio_Regs[NR43] & 0xF0) >> 4);
- NOISE_wdth_md = (Audio_Regs[NR43] & 8) > 0;
- NOISE_div_code = (byte)(Audio_Regs[NR43] & 7);
-
- WAVE_trigger = (Audio_Regs[NR44] & 0x80) > 0;
- WAVE_len_en = (Audio_Regs[NR44] & 0x40) > 0;
-
- AUD_CTRL_vin_L_en = (Audio_Regs[NR50] & 0x80) > 0;
- AUD_CTRL_vol_L = (byte)((Audio_Regs[NR50] & 0x70) >> 4);
- AUD_CTRL_vin_R_en = (Audio_Regs[NR50] & 8) > 0;
- AUD_CTRL_vol_R = (byte)(Audio_Regs[NR50] & 7);
-
- AUD_CTRL_noise_L_en = (Audio_Regs[NR51] & 0x80) > 0;
- AUD_CTRL_wave_L_en = (Audio_Regs[NR51] & 0x40) > 0;
- AUD_CTRL_sq2_L_en = (Audio_Regs[NR51] & 0x20) > 0;
- AUD_CTRL_sq1_L_en = (Audio_Regs[NR51] & 0x10) > 0;
- AUD_CTRL_noise_R_en = (Audio_Regs[NR51] & 8) > 0;
- AUD_CTRL_wave_R_en = (Audio_Regs[NR51] & 4) > 0;
- AUD_CTRL_sq2_R_en = (Audio_Regs[NR51] & 2) > 0;
- AUD_CTRL_sq1_R_en = (Audio_Regs[NR51] & 1) > 0;
-
- AUD_CTRL_power = (Audio_Regs[NR51] & 0x80) > 0;
}
public byte Read_NR52()
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs
index 77fe21cc28..af6cc525d9 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs
@@ -2,6 +2,7 @@
using BizHawk.Emulation.Common;
using System;
using System.Collections.Generic;
+using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
@@ -12,7 +13,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public ControllerDefinition ControllerDefinition => _controllerDeck.Definition;
public byte controller_state;
- public byte controller_state_old;
public bool in_vblank_old;
public bool in_vblank;
public bool vblank_rise;
@@ -21,6 +21,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
//Console.WriteLine("-----------------------FRAME-----------------------");
+ //Update the color palette if a setting changed
+ if(_settings.Palette == GBSettings.PaletteType.BW)
+ {
+ color_palette[0] = color_palette_BW[0];
+ color_palette[1] = color_palette_BW[1];
+ color_palette[2] = color_palette_BW[2];
+ color_palette[3] = color_palette_BW[3];
+ }
+ else
+ {
+ color_palette[0] = color_palette_Gr[0];
+ color_palette[1] = color_palette_Gr[1];
+ color_palette[2] = color_palette_Gr[2];
+ color_palette[3] = color_palette_Gr[3];
+ }
+
+
if (_tracer.Enabled)
{
cpu.TraceCallback = s => _tracer.Put(s);
@@ -45,6 +62,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
do_frame();
+ if (_scanlineCallback != null)
+ {
+ GetGPU();
+ _scanlineCallback(ppu.LCDC);
+ }
+
if (_islag)
{
_lagcount++;
@@ -56,17 +79,56 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// gameboy frames can be variable lengths
// we want to end a frame when VBlank turns from false to true
int ticker = 0;
+
+ // check if new input changed the input register and triggered IRQ
+ byte contr_prev = input_register;
+
+ input_register &= 0xF0;
+ if ((input_register & 0x30) == 0x20)
+ {
+ input_register |= (byte)(controller_state & 0xF);
+ }
+ else if ((input_register & 0x30) == 0x10)
+ {
+ input_register |= (byte)((controller_state & 0xF0) >> 4);
+ }
+ else if ((input_register & 0x30) == 0x00)
+ {
+ // if both polls are set, then a bit is zero if either or both pins are zero
+ byte temp = (byte)((controller_state & 0xF) & ((controller_state & 0xF0) >> 4));
+ input_register |= temp;
+ }
+ else
+ {
+ input_register |= 0xF;
+ }
+
+ // check for interrupts
+
+
+ if (((contr_prev & 8) > 0) && ((input_register & 8) == 0) ||
+ ((contr_prev & 4) > 0) && ((input_register & 4) == 0) ||
+ ((contr_prev & 2) > 0) && ((input_register & 2) == 0) ||
+ ((contr_prev & 1) > 0) && ((input_register & 1) == 0))
+ {
+ if (REG_FFFF.Bit(4)) { cpu.FlagI = true; }
+ REG_FF0F |= 0x10;
+ }
+
+
while (!vblank_rise && (ticker < 100000))
{
audio.tick();
timer.tick_1();
ppu.tick();
+ serialport.serial_transfer_tick();
+
+ if (Use_RTC) { mapper.RTC_Tick(); }
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
timer.tick_2();
-
if (in_vblank && !in_vblank_old)
{
vblank_rise = true;
@@ -87,26 +149,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
InputCallbacks.Call();
controller_state = _controllerDeck.ReadPort1(controller);
-
- // set interrupt flag if a pin went from high to low
- if (controller_state < controller_state_old)
- {
- if (REG_FFFF.Bit(4)) { cpu.FlagI = true; }
- REG_FF0F |= 0x10;
- }
-
- controller_state_old = controller_state;
- }
-
- public void serial_transfer()
- {
- if (serial_control.Bit(7) && !serial_start_old)
- {
- serial_start_old = true;
-
- // transfer out on byte of data
- // needs to be modelled
- }
}
public int Frame => _frame;
@@ -126,7 +168,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public void Dispose()
{
-
+ Marshal.FreeHGlobal(iptr0);
+ Marshal.FreeHGlobal(iptr1);
+ Marshal.FreeHGlobal(iptr2);
+ Marshal.FreeHGlobal(iptr3);
}
@@ -149,7 +194,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public int VsyncNumerator => _frameHz;
public int VsyncDenominator => 1;
- public static readonly uint[] color_palette = { 0xFFFFFFFF , 0xFFAAAAAA, 0xFF555555, 0xFF000000 };
+ public static readonly uint[] color_palette_BW = { 0xFFFFFFFF , 0xFFAAAAAA, 0xFF555555, 0xFF000000 };
+ public static readonly uint[] color_palette_Gr = { 0xFFA4C505, 0xFF88A905, 0xFF1D551D, 0xFF052505 };
+
+ public uint[] color_palette = new uint[4];
#endregion
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IMemoryDomains.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IMemoryDomains.cs
index 971b3c3c2d..375abbd592 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IMemoryDomains.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IMemoryDomains.cs
@@ -34,6 +34,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
MemoryDomain.Endian.Little,
addr => PeekSystemBus(addr),
(addr, value) => PokeSystemBus(addr, value),
+ 1),
+ new MemoryDomainDelegate(
+ "ROM",
+ _rom.Length,
+ MemoryDomain.Endian.Little,
+ addr => _rom[addr],
+ (addr, value) => ZP_RAM[addr] = value,
1)
};
@@ -44,7 +51,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
private byte PeekSystemBus(long addr)
{
ushort addr2 = (ushort)(addr & 0xFFFF);
- return ReadMemory(addr2);
+ return PeekMemory(addr2);
}
private void PokeSystemBus(long addr, byte value)
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.ISettable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.ISettable.cs
index 55d2cc130e..79217600e4 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.ISettable.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.ISettable.cs
@@ -38,6 +38,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public class GBSettings
{
+ public enum PaletteType
+ {
+ BW,
+ Gr
+ }
+
+ [DisplayName("Console Mode")]
+ [Description("Pick which console to run, 'Auto' chooses from ROM header, 'GB' and 'GBC' chooses the respective system")]
+ [DefaultValue(PaletteType.BW)]
+ public PaletteType Palette { get; set; }
+
+
public GBSettings Clone()
{
return (GBSettings)MemberwiseClone();
@@ -63,6 +75,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
}
+ [DisplayName("RTC Initial Time")]
+ [Description("Set the initial RTC time in terms of elapsed seconds.")]
+ [DefaultValue(0)]
+ public int RTCInitialTime
+ {
+ get { return _RTCInitialTime; }
+ set { _RTCInitialTime = Math.Max(0, Math.Min(1024 * 24 * 60 * 60, value)); }
+ }
+
+ [DisplayName("Use Existing SaveRAM")]
+ [Description("When true, existing SaveRAM will be loaded at boot up")]
+ [DefaultValue(false)]
+ public bool Use_SRAM { get; set; }
+
+
+ [JsonIgnore]
+ private int _RTCInitialTime;
+
+
public GBSyncSettings Clone()
{
return (GBSyncSettings)MemberwiseClone();
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs
index c228de6e1e..dbccea7f07 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs
@@ -51,6 +51,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
mapper.SyncState(ser);
timer.SyncState(ser);
ppu.SyncState(ser);
+ serialport.SyncState(ser);
audio.SyncState(ser);
ser.BeginSection("Gameboy");
@@ -61,18 +62,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
_controllerDeck.SyncState(ser);
ser.Sync("controller_state", ref controller_state);
- ser.Sync("controller_state_old", ref controller_state_old);
ser.Sync("in_vblank", ref in_vblank);
ser.Sync("in_vblank_old", ref in_vblank_old);
ser.Sync("vblank_rise", ref vblank_rise);
ser.Sync("GB_bios_register", ref GB_bios_register);
ser.Sync("input_register", ref input_register);
- ser.Sync("serial_control", ref serial_control);
- ser.Sync("serial_data_out", ref serial_data_out);
- ser.Sync("serial_data_in", ref serial_data_in);
- ser.Sync("serial_start_old", ref serial_start_old);
-
ser.Sync("REG_FFFF", ref REG_FFFF);
ser.Sync("REG_FF0F", ref REG_FF0F);
ser.Sync("enable_VBL", ref enable_VBL);
@@ -88,6 +83,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("BG_map_1", ref BG_map_1, false);
ser.Sync("BG_map_2", ref BG_map_2, false);
ser.Sync("OAM", ref OAM, false);
+
+ ser.Sync("Use_RTC", ref Use_RTC);
+
// probably a better way to do this
if (cart_RAM != null)
{
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs
index 5a8c0eb3cc..983d547fae 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs
@@ -5,6 +5,9 @@ using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.Components.LR35902;
using BizHawk.Common.NumberExtensions;
+using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy;
+using System.Runtime.InteropServices;
+
namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
[Core(
@@ -13,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
isPorted: false,
isReleased: false)]
[ServiceNotApplicable(typeof(IDriveLight))]
- public partial class GBHawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable,
+ public partial class GBHawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable, IGameboyCommon,
ISettable
{
// this register controls whether or not the GB BIOS is mapped into memory
@@ -21,11 +24,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public byte input_register;
- public byte serial_control;
- public byte serial_data_out;
- public byte serial_data_in;
- public bool serial_start_old;
-
// The unused bits in this register are still read/writable
public byte REG_FFFF;
// The unused bits in this register (interrupt flags) are always set
@@ -54,6 +52,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
private int _frame = 0;
+ public bool Use_RTC;
+
public MapperBase mapper;
private readonly ITraceable _tracer;
@@ -62,6 +62,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public PPU ppu;
public Timer timer;
public Audio audio;
+ public SerialPort serialport;
[CoreConstructor("GB")]
public GBHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings)
@@ -72,13 +73,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
ReadMemory = ReadMemory,
WriteMemory = WriteMemory,
- PeekMemory = ReadMemory,
+ PeekMemory = PeekMemory,
DummyReadMemory = ReadMemory,
OnExecFetch = ExecFetch
};
ppu = new PPU();
timer = new Timer();
audio = new Audio();
+ serialport = new SerialPort();
CoreComm = comm;
@@ -109,6 +111,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
timer.Core = this;
audio.Core = this;
ppu.Core = this;
+ serialport.Core = this;
ser.Register(this);
ser.Register(audio);
@@ -121,9 +124,93 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Register(_tracer);
SetupMemoryDomains();
- HardReset();
+ HardReset();
+
+ iptr0 = Marshal.AllocHGlobal(CHR_RAM.Length + BG_map_1.Length + BG_map_2.Length + 1);
+ iptr1 = Marshal.AllocHGlobal(OAM.Length + 1);
+ iptr2 = Marshal.AllocHGlobal(color_palette.Length * 2 + 1);
+ iptr3 = Marshal.AllocHGlobal(color_palette.Length + 1);
+
+ _scanlineCallback = null;
}
+ #region GPUViewer
+
+ public bool IsCGBMode() => false;
+
+ public IntPtr iptr0 = IntPtr.Zero;
+ public IntPtr iptr1 = IntPtr.Zero;
+ public IntPtr iptr2 = IntPtr.Zero;
+ public IntPtr iptr3 = IntPtr.Zero;
+
+ private GPUMemoryAreas _gpuMemory
+ {
+ get
+ {
+ byte[] temp = new byte[CHR_RAM.Length + BG_map_1.Length + BG_map_2.Length];
+
+ for (int i = 0; i < CHR_RAM.Length; i++)
+ {
+ temp[i] = CHR_RAM[i];
+ }
+ for (int i = 0; i < BG_map_1.Length; i++)
+ {
+ temp[CHR_RAM.Length + i] = BG_map_1[i];
+ }
+ for (int i = 0; i < BG_map_2.Length; i++)
+ {
+ temp[CHR_RAM.Length + BG_map_1.Length + i] = BG_map_2[i];
+ }
+
+ Marshal.Copy(temp, 0, iptr0, temp.Length);
+ Marshal.Copy(OAM, 0, iptr1, OAM.Length);
+
+ int[] cp2 = new int[8];
+ for (int i = 0; i < 4; i++)
+ {
+ cp2[i] = (int)color_palette[(ppu.obj_pal_0 >> (i * 2)) & 3];
+ cp2[i + 4] = (int)color_palette[(ppu.obj_pal_1 >> (i * 2)) & 3];
+ }
+ Marshal.Copy(cp2, 0, iptr2, cp2.Length);
+
+ int[] cp = new int[4];
+ for (int i = 0; i < 4; i++)
+ {
+ cp[i] = (int)color_palette[(ppu.BGP >> (i * 2)) & 3];
+ }
+ Marshal.Copy(cp, 0, iptr3, cp.Length);
+
+
+ return new GPUMemoryAreas(iptr0, iptr1, iptr2, iptr3);
+ }
+ }
+
+ public GPUMemoryAreas GetGPU() => _gpuMemory;
+
+ public ScanlineCallback _scanlineCallback;
+ public int _scanlineCallbackLine = 0;
+
+ public void SetScanlineCallback(ScanlineCallback callback, int line)
+ {
+ _scanlineCallback = callback;
+ _scanlineCallbackLine = line;
+
+ if (line == -2)
+ {
+ GetGPU();
+ _scanlineCallback(ppu.LCDC);
+ }
+ }
+
+ private PrinterCallback _printerCallback = null;
+
+ public void SetPrinterCallback(PrinterCallback callback)
+ {
+ _printerCallback = null;
+ }
+
+ #endregion
+
public DisplayType Region => DisplayType.NTSC;
private readonly GBHawkControllerDeck _controllerDeck;
@@ -134,12 +221,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
in_vblank = true; // we start off in vblank since the LCD is off
in_vblank_old = true;
+ // Start off with RAM all 0xFF (the game 'X' (proto) expects this)
+ for (int i = 0; i < RAM.Length; i++)
+ {
+ RAM[i] = 0xFF;
+ }
+
Register_Reset();
timer.Reset();
ppu.Reset();
audio.Reset();
+ serialport.Reset();
- cpu.SetCallbacks(ReadMemory, ReadMemory, ReadMemory, WriteMemory);
+ cpu.SetCallbacks(ReadMemory, PeekMemory, PeekMemory, WriteMemory);
_vidbuffer = new int[VirtualWidth * VirtualHeight];
}
@@ -185,6 +279,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 0xFE: mapper = new MapperHuC3(); mppr = "HuC3"; break;
case 0xFF: mapper = new MapperHuC1(); mppr = "HuC1"; break;
+ // Bootleg mappers
+ // NOTE: Sachen mapper selection does not account for scrambling, so if another bootleg mapper
+ // identifies itself as 0x31, this will need to be modified
+ case 0x31: mapper = new MapperSachen2(); mppr = "Schn2"; break;
+
case 0x4:
case 0x7:
case 0xA:
@@ -198,6 +297,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 0x21:
default:
// mapper not implemented
+ Console.WriteLine(header[0x47]);
throw new Exception("Mapper not implemented");
break;
@@ -237,6 +337,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
break;
}
+ // Sachen maper not known to have RAM
+ if ((mppr == "Schn1") || (mppr == "Schn2"))
+ {
+ cart_RAM = null;
+ }
+
// mbc2 carts have built in RAM
if (mppr == "MBC2")
{
@@ -245,6 +351,53 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
mapper.Core = this;
mapper.Initialize();
+
+ if (cart_RAM != null)
+ {
+
+ Console.Write("RAM: "); Console.WriteLine(cart_RAM.Length);
+
+ if (_syncSettings.Use_SRAM)
+ {
+ // load cartRAM here
+ }
+ else
+ {
+ for (int i = 0; i < cart_RAM.Length; i++)
+ {
+ cart_RAM[i] = 0xFF;
+ }
+ }
+ }
+
+
+ // Extra RTC initialization for mbc3
+ if (mppr == "MBC3")
+ {
+ Use_RTC = true;
+ int days = (int)Math.Floor(_syncSettings.RTCInitialTime / 86400.0);
+
+ int days_upper = ((days & 0x100) >> 8) | ((days & 0x200) >> 2);
+
+ mapper.RTC_Get((byte)days_upper, 4);
+ mapper.RTC_Get((byte)(days & 0xFF), 3);
+
+ int remaining = _syncSettings.RTCInitialTime - (days * 86400);
+
+ int hours = (int)Math.Floor(remaining / 3600.0);
+
+ mapper.RTC_Get((byte)(hours & 0xFF), 2);
+
+ remaining = remaining - (hours * 3600);
+
+ int minutes = (int)Math.Floor(remaining / 60.0);
+
+ mapper.RTC_Get((byte)(minutes & 0xFF), 1);
+
+ remaining = remaining - (minutes * 60);
+
+ mapper.RTC_Get((byte)(remaining & 0xFF), 0);
+ }
}
}
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawkControllers.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawkControllers.cs
index d33a82ac7c..1900a4879b 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawkControllers.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawkControllers.cs
@@ -57,7 +57,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
private static readonly string[] BaseDefinition =
{
- "Up", "Down", "Left", "Right", "Start", "Select", "B", "A", "Power"
+ "Right", "Left", "Up", "Down", "A", "B", "Select", "Start", "Power"
};
public void SyncState(Serializer ser)
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs
index a55e91798e..daf9161210 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs
@@ -16,37 +16,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// Read Input
case 0xFF00:
_islag = false;
-
- input_register &= 0xF0;
- if ((input_register & 0x30) == 0x20)
- {
- input_register |= (byte)(controller_state & 0xF);
- }
- else if ((input_register & 0x30) == 0x10)
- {
- input_register |= (byte)((controller_state & 0xF0) >> 4);
- }
- else if ((input_register & 0x30) == 0x30)
- {
- // if both polls are set, then a bit is zero if either or both pins are zero
- byte temp = (byte)((controller_state & 0xF) & ((controller_state & 0xF0) >> 4));
- input_register |= temp;
- }
- else
- {
- input_register |= 0xF;
- }
ret = input_register;
break;
// Serial data port
case 0xFF01:
- ret = serial_data_in;
+ ret = serialport.ReadReg(addr);
break;
// Serial port control
case 0xFF02:
- ret = serial_control;
+ ret = serialport.ReadReg(addr);
break;
// Timer Registers
@@ -143,18 +123,52 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
// select input
case 0xFF00:
- input_register = (byte)(0xC0 | (value & 0x3F)); // top 2 bits always 1
+ input_register &= 0xCF;
+ input_register |= (byte)(value & 0x30); // top 2 bits always 1
+
+ // check for high to low transitions that trigger IRQs
+ byte contr_prev = input_register;
+
+ input_register &= 0xF0;
+ if ((input_register & 0x30) == 0x20)
+ {
+ input_register |= (byte)(controller_state & 0xF);
+ }
+ else if ((input_register & 0x30) == 0x10)
+ {
+ input_register |= (byte)((controller_state & 0xF0) >> 4);
+ }
+ else if ((input_register & 0x30) == 0x00)
+ {
+ // if both polls are set, then a bit is zero if either or both pins are zero
+ byte temp = (byte)((controller_state & 0xF) & ((controller_state & 0xF0) >> 4));
+ input_register |= temp;
+ }
+ else
+ {
+ input_register |= 0xF;
+ }
+
+ // check for interrupts
+ if (((contr_prev & 8) > 0) && ((input_register & 8) == 0) ||
+ ((contr_prev & 4) > 0) && ((input_register & 4) == 0) ||
+ ((contr_prev & 2) > 0) && ((input_register & 2) == 0) ||
+ ((contr_prev & 1) > 0) && ((input_register & 1) == 0))
+ {
+ if (REG_FFFF.Bit(4)) { cpu.FlagI = true; }
+ REG_FF0F |= 0x10;
+ }
+
break;
// Serial data port
case 0xFF01:
- serial_data_out = value;
- serial_data_in = serial_data_out;
+ serialport.WriteReg(addr, value);
break;
// Serial port control
case 0xFF02:
- serial_control = (byte)(0x7E | (value & 0x81)); // middle six bits always 1
+ serialport.WriteReg(addr, value);
break;
// Timer Registers
@@ -277,7 +291,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public void Register_Reset()
{
input_register = 0xCF; // not reading any input
- serial_control = 0x7E;
}
}
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/MapperBase.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/MapperBase.cs
index 0cd2cc11ea..ce4ed125bb 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/MapperBase.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/MapperBase.cs
@@ -36,5 +36,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public virtual void Initialize()
{
}
+
+ public virtual void RTC_Tick()
+ {
+ }
+
+ public virtual void RTC_Get(byte value, int index)
+ {
+ }
}
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1.cs
index c61133bdcd..c0c46c1890 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1.cs
@@ -21,6 +21,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
RAM_enable = false;
sel_mode = false;
ROM_mask = Core._rom.Length / 0x4000 - 1;
+
+ // some games have sizes that result in a degenerate ROM, account for it here
+ if (ROM_mask > 4) { ROM_mask |= 3; }
+
RAM_mask = 0;
if (Core.cart_RAM != null)
{
@@ -63,7 +67,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
else
{
- return 0;
+ return 0xFF;
}
}
}
@@ -79,7 +83,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
if (addr < 0x2000)
{
- RAM_enable = ((value & 0xA) == 0xA) ? true : false;
+ RAM_enable = (value & 0xA) == 0xA;
}
else if (addr < 0x4000)
{
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC2.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC2.cs
index 6327d00491..dfda342323 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC2.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC2.cs
@@ -32,7 +32,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
else if ((addr >= 0xA000) && (addr < 0xA200))
{
- return Core.cart_RAM[addr - 0xA000];
+ if (RAM_enable)
+ {
+ return Core.cart_RAM[addr - 0xA000];
+ }
+ return 0xFF;
}
else
{
@@ -49,13 +53,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
if (addr < 0x2000)
{
- RAM_enable = (addr & 0x100) > 0;
+ if ((addr & 0x100) == 0)
+ {
+ RAM_enable = ((value & 0xA) == 0xA) ? true : false;
+ }
}
else if (addr < 0x4000)
{
if ((addr & 0x100) > 0)
{
ROM_bank = value & 0xF;
+ if (ROM_bank==0) { ROM_bank = 1; }
}
}
else if ((addr >= 0xA000) && (addr < 0xA200))
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC3.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC3.cs
index 18a7f013c7..f1ed2a807d 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC3.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC3.cs
@@ -4,29 +4,85 @@ using System;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
- // Default mapper with no bank switching
+ // MBC3 mapper with Real Time Clock
public class MapperMBC3 : MapperBase
{
+ public int ROM_bank;
+ public int RAM_bank;
+ public bool RAM_enable;
+ public int ROM_mask;
+ public int RAM_mask;
+ public byte[] RTC_regs = new byte[5];
+ public byte[] RTC_regs_latch = new byte[5];
+ public bool RTC_regs_latch_wr;
+ public int RTC_timer;
+ public int RTC_low_clock;
+ public bool halt;
+
public override void Initialize()
{
- // nothing to initialize
+ ROM_bank = 1;
+ RAM_bank = 0;
+ RAM_enable = false;
+ ROM_mask = Core._rom.Length / 0x4000 - 1;
+
+ // some games have sizes that result in a degenerate ROM, account for it here
+ if (ROM_mask > 4) { ROM_mask |= 3; }
+
+ RAM_mask = 0;
+ if (Core.cart_RAM != null)
+ {
+ RAM_mask = Core.cart_RAM.Length / 0x2000 - 1;
+ if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; }
+ }
+
+ RTC_regs[0] = 0;
+ RTC_regs[1] = 0;
+ RTC_regs[2] = 0;
+ RTC_regs[3] = 0;
+ RTC_regs[4] = 0;
+
+ RTC_regs_latch_wr = true;
}
public override byte ReadMemory(ushort addr)
{
- if (addr < 0x8000)
+ if (addr < 0x4000)
{
return Core._rom[addr];
}
+ else if (addr < 0x8000)
+ {
+ return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
+ }
else
{
- if (Core.cart_RAM != null)
+ if (RAM_enable)
{
- return Core.cart_RAM[addr - 0xA000];
- }
+ if ((Core.cart_RAM != null) && (RAM_bank < 3))
+ {
+ if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)
+ {
+ return Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000];
+ }
+ else
+ {
+ return 0xFF;
+ }
+ }
+
+ if ((RAM_bank >= 8) && (RAM_bank < 0xC))
+ {
+ return RTC_regs_latch[RAM_bank - 8];
+ }
+ else
+ {
+ return 0xFF;
+ }
+ }
else
{
- return 0;
+ return 0xFF;
}
}
}
@@ -40,13 +96,54 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
if (addr < 0x8000)
{
- // no mapping hardware available
+ if (addr < 0x2000)
+ {
+ RAM_enable = ((value & 0xA) == 0xA) ? true : false;
+ }
+ else if (addr < 0x4000)
+ {
+ value &= 0x7F;
+
+ // writing zero gets translated to 1
+ if (value == 0) { value = 1; }
+
+ ROM_bank = value;
+ ROM_bank &= ROM_mask;
+ }
+ else if (addr < 0x6000)
+ {
+ RAM_bank = value & 3;
+ }
+ else
+ {
+ if (!RTC_regs_latch_wr && ((value & 1) == 1))
+ {
+ for (int i = 0; i < 5; i++)
+ {
+ RTC_regs_latch[i] = RTC_regs[i];
+ }
+ }
+
+ RTC_regs_latch_wr = (value & 1) > 0;
+ }
}
else
{
- if (Core.cart_RAM != null)
+ if (RAM_enable)
{
- Core.cart_RAM[addr - 0xA000] = value;
+ if ((Core.cart_RAM != null) && (RAM_bank <= 3))
+ {
+ if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)
+ {
+ Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value;
+ }
+ }
+ else if ((RAM_bank >= 8) && (RAM_bank < 0xC))
+ {
+ RTC_regs[RAM_bank - 8] = value;
+
+ halt = (RTC_regs[4] & 0x40) > 0;
+ }
}
}
}
@@ -55,5 +152,79 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
WriteMemory(addr, value);
}
+
+ public override void RTC_Get(byte value, int index)
+ {
+ RTC_regs[index] = value;
+ }
+
+ public override void RTC_Tick()
+ {
+ if (!halt)
+ {
+ RTC_timer++;
+
+ if (RTC_timer == 128)
+ {
+ RTC_timer = 0;
+
+ RTC_low_clock++;
+
+ if (RTC_low_clock == 32768)
+ {
+ RTC_low_clock = 0;
+
+ RTC_regs[0]++;
+ if (RTC_regs[0] > 59)
+ {
+ RTC_regs[0] = 0;
+ RTC_regs[1]++;
+ if (RTC_regs[1] > 59)
+ {
+ RTC_regs[2]++;
+ if (RTC_regs[2] > 23)
+ {
+ RTC_regs[2] = 0;
+ if (RTC_regs[3] < 0xFF)
+ {
+ RTC_regs[3]++;
+ }
+ else
+ {
+ RTC_regs[3] = 0;
+
+ if ((RTC_regs[4] & 1) == 0)
+ {
+ RTC_regs[4] |= 1;
+ }
+ else
+ {
+ RTC_regs[4] &= 0xFE;
+ RTC_regs[4] |= 0x80;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ public override void SyncState(Serializer ser)
+ {
+ ser.Sync("ROM_Bank", ref ROM_bank);
+ ser.Sync("ROM_Mask", ref ROM_mask);
+ ser.Sync("RAM_Bank", ref RAM_bank);
+ ser.Sync("RAM_Mask", ref RAM_mask);
+ ser.Sync("RAM_enable", ref RAM_enable);
+ ser.Sync("halt", ref halt);
+ ser.Sync("RTC_regs", ref RTC_regs, false);
+ ser.Sync("RTC_regs_latch", ref RTC_regs_latch, false);
+ ser.Sync("RTC_regs_latch_wr", ref RTC_regs_latch_wr);
+ ser.Sync("RTC_timer", ref RTC_timer);
+ ser.Sync("RTC_low_clock", ref RTC_low_clock);
+ }
}
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_Sachen_MMC1.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_Sachen_MMC1.cs
new file mode 100644
index 0000000000..b178fe1037
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_Sachen_MMC1.cs
@@ -0,0 +1,157 @@
+using BizHawk.Common;
+using BizHawk.Common.NumberExtensions;
+using System;
+
+namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
+{
+ // Sachen Bootleg Mapper
+ // NOTE: Normally, locked mode is disabled after 31 rises of A15
+ // this occurs when the Boot Rom is loading the nintendo logo into VRAM
+ // instead of tracking that in the main memory map where it will just slow things down for no reason
+ // we'll clear the 'locked' flag when the last byte of the logo is read
+ class MapperSachen1 : MapperBase
+ {
+ public int ROM_bank;
+ public bool locked;
+ public int ROM_mask;
+ public int ROM_bank_mask;
+ public int BASE_ROM_Bank;
+ public bool reg_access;
+
+ public override void Initialize()
+ {
+ ROM_bank = 1;
+ ROM_mask = Core._rom.Length / 0x4000 - 1;
+ BASE_ROM_Bank = 0;
+ ROM_bank_mask = 0xFF;
+ locked = true;
+ reg_access = false;
+ }
+
+ public override byte ReadMemory(ushort addr)
+ {
+ if (addr < 0x4000)
+ {
+ ushort t_addr = addr;
+
+ // header is scrambled
+ if ((addr >= 0x100) && (addr < 0x200))
+ {
+ int temp0 = (addr & 1);
+ int temp1 = (addr & 2);
+ int temp4 = (addr & 0x10);
+ int temp6 = (addr & 0x40);
+
+ temp0 = temp0 << 6;
+ temp1 = temp1 << 3;
+ temp4 = temp4 >> 3;
+ temp6 = temp6 >> 6;
+
+ addr &= 0x1AC;
+ addr |= (ushort)(temp0 | temp1 | temp4 | temp6);
+ }
+
+ if (locked) { addr |= 0x80; }
+
+ if (t_addr == 0x133)
+ {
+ locked = false;
+ Console.WriteLine("cleared");
+ }
+
+ return Core._rom[addr + BASE_ROM_Bank * 0x4000];
+ }
+ else if (addr < 0x8000)
+ {
+ return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
+ }
+ else
+ {
+ return 0xFF;
+ }
+ }
+
+ public override byte PeekMemory(ushort addr)
+ {
+ if (addr < 0x4000)
+ {
+ ushort t_addr = addr;
+
+ // header is scrambled
+ if ((addr >= 0x100) && (addr < 0x200))
+ {
+ int temp0 = (addr & 1);
+ int temp1 = (addr & 2);
+ int temp4 = (addr & 0x10);
+ int temp6 = (addr & 0x40);
+
+ temp0 = temp0 << 6;
+ temp1 = temp1 << 3;
+ temp4 = temp4 >> 3;
+ temp6 = temp6 >> 6;
+
+ addr &= 0x1AC;
+ addr |= (ushort)(temp0 | temp1 | temp4 | temp6);
+ }
+
+ if (locked) { addr |= 0x80; }
+
+ return Core._rom[addr + BASE_ROM_Bank * 0x4000];
+ }
+ else if (addr < 0x8000)
+ {
+ return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
+ }
+ else
+ {
+ return 0xFF;
+ }
+ }
+
+ public override void WriteMemory(ushort addr, byte value)
+ {
+ if (addr < 0x2000)
+ {
+ if (reg_access)
+ {
+ BASE_ROM_Bank = value;
+ }
+ }
+ else if (addr < 0x4000)
+ {
+ ROM_bank = (value > 0) ? value : 1;
+
+ if ((value & 0x30) == 0x30)
+ {
+ reg_access = true;
+ }
+ else
+ {
+ reg_access = false;
+ }
+ }
+ else if (addr < 0x6000)
+ {
+ if (reg_access)
+ {
+ ROM_bank_mask = value;
+ }
+ }
+ }
+
+ public override void PokeMemory(ushort addr, byte value)
+ {
+ WriteMemory(addr, value);
+ }
+
+ public override void SyncState(Serializer ser)
+ {
+ ser.Sync("ROM_Bank", ref ROM_bank);
+ ser.Sync("ROM_Mask", ref ROM_mask);
+ ser.Sync("locked", ref locked);
+ ser.Sync("ROM_bank_mask", ref ROM_bank_mask);
+ ser.Sync("BASE_ROM_Bank", ref BASE_ROM_Bank);
+ ser.Sync("reg_access", ref reg_access);
+ }
+ }
+}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_Sachen_MMC2.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_Sachen_MMC2.cs
new file mode 100644
index 0000000000..d43e912cf8
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_Sachen_MMC2.cs
@@ -0,0 +1,159 @@
+using BizHawk.Common;
+using BizHawk.Common.NumberExtensions;
+using System;
+
+namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
+{
+ // Sachen Bootleg Mapper
+ // NOTE: Normally, locked mode is disabled after 31 rises of A15
+ // this occurs when the Boot Rom is loading the nintendo logo into VRAM
+ // instead of tracking that in the main memory map where it will just slow things down for no reason
+ // we'll clear the 'locked' flag when the last byte of the logo is read
+ class MapperSachen2 : MapperBase
+ {
+ public int ROM_bank;
+ public bool locked;
+ public int ROM_mask;
+ public int ROM_bank_mask;
+ public int BASE_ROM_Bank;
+ public bool reg_access;
+
+ public override void Initialize()
+ {
+ ROM_bank = 1;
+ ROM_mask = Core._rom.Length / 0x4000 - 1;
+ BASE_ROM_Bank = 0;
+ ROM_bank_mask = 0;
+ locked = false;
+ reg_access = false;
+ }
+
+ public override byte ReadMemory(ushort addr)
+ {
+ if (addr < 0x4000)
+ {
+ ushort t_addr = addr;
+
+ // header is scrambled
+ if ((addr >= 0x100) && (addr < 0x200))
+ {
+ int temp0 = (addr & 1);
+ int temp1 = (addr & 2);
+ int temp4 = (addr & 0x10);
+ int temp6 = (addr & 0x40);
+
+ temp0 = temp0 << 6;
+ temp1 = temp1 << 3;
+ temp4 = temp4 >> 3;
+ temp6 = temp6 >> 6;
+
+ addr &= 0x1AC;
+ addr |= (ushort)(temp0 | temp1 | temp4 | temp6);
+ }
+
+ if (locked) { addr |= 0x80; }
+
+ if (t_addr == 0x133)
+ {
+ if ((Core.GB_bios_register & 0x1) == 0) { locked ^= true; }
+ }
+
+ return Core._rom[addr + BASE_ROM_Bank * 0x4000];
+ }
+ else if (addr < 0x8000)
+ {
+ int temp_bank = (ROM_bank & ~ROM_bank_mask) | (ROM_bank_mask & BASE_ROM_Bank);
+ temp_bank &= ROM_mask;
+
+ return Core._rom[(addr - 0x4000) + temp_bank * 0x4000];
+ }
+ else
+ {
+ return 0xFF;
+ }
+ }
+
+ public override byte PeekMemory(ushort addr)
+ {
+ if (addr < 0x4000)
+ {
+ ushort t_addr = addr;
+
+ // header is scrambled
+ if ((addr >= 0x100) && (addr < 0x200))
+ {
+ int temp0 = (addr & 1);
+ int temp1 = (addr & 2);
+ int temp4 = (addr & 0x10);
+ int temp6 = (addr & 0x40);
+
+ temp0 = temp0 << 6;
+ temp1 = temp1 << 3;
+ temp4 = temp4 >> 3;
+ temp6 = temp6 >> 6;
+
+ addr &= 0x1AC;
+ addr |= (ushort)(temp0 | temp1 | temp4 | temp6);
+ }
+
+ if (locked) { addr |= 0x80; }
+
+ return Core._rom[addr + BASE_ROM_Bank * 0x4000];
+ }
+ else if (addr < 0x8000)
+ {
+ return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
+ }
+ else
+ {
+ return 0xFF;
+ }
+ }
+
+ public override void WriteMemory(ushort addr, byte value)
+ {
+ if (addr < 0x2000)
+ {
+ if (reg_access)
+ {
+ BASE_ROM_Bank = value;
+ }
+ }
+ else if (addr < 0x4000)
+ {
+ ROM_bank = (value > 0) ? (value) : 1;
+
+ if ((value & 0x30) == 0x30)
+ {
+ reg_access = true;
+ }
+ else
+ {
+ reg_access = false;
+ }
+ }
+ else if (addr < 0x6000)
+ {
+ if (reg_access)
+ {
+ ROM_bank_mask = value;
+ }
+ }
+ }
+
+ public override void PokeMemory(ushort addr, byte value)
+ {
+ WriteMemory(addr, value);
+ }
+
+ public override void SyncState(Serializer ser)
+ {
+ ser.Sync("ROM_Bank", ref ROM_bank);
+ ser.Sync("ROM_Mask", ref ROM_mask);
+ ser.Sync("locked", ref locked);
+ ser.Sync("ROM_bank_mask", ref ROM_bank_mask);
+ ser.Sync("BASE_ROM_Bank", ref BASE_ROM_Bank);
+ ser.Sync("reg_access", ref reg_access);
+ }
+ }
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs
index fe6bb017ce..b1b241d39b 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs
@@ -30,7 +30,33 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public byte ReadMemory(ushort addr)
{
MemoryCallbacks.CallReads(addr, "System Bus");
-
+
+ if (ppu.DMA_start)
+ {
+ if (addr < 0x4000)
+ {
+ return mapper.ReadMemory(addr); // some of gekkio's tests require this to be accessible during DMA
+ }
+ else if ((addr >= 0xE000) && (addr < 0xFE00))
+ {
+ return RAM[addr - 0xE000]; // some of gekkio's tests require this to be accessible during DMA
+ }
+ else if ((addr >= 0xFE00) && (addr < 0xFEA0) && ppu.DMA_OAM_access)
+ {
+ return OAM[addr - 0xFE00];
+ }
+ else if ((addr >= 0xFF00) && (addr < 0xFF80)) // The game GOAL! Requires Hardware Regs to be accessible
+ {
+ return Read_Registers(addr);
+ }
+ else if ((addr >= 0xFF80))
+ {
+ return ZP_RAM[addr - 0xFF80];
+ }
+
+ return 0xFF;
+ }
+
if (addr < 0x100)
{
// return Either BIOS ROM or Game ROM
@@ -102,6 +128,27 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public void WriteMemory(ushort addr, byte value)
{
MemoryCallbacks.CallWrites(addr, "System Bus");
+
+ if (ppu.DMA_start)
+ {
+ if ((addr >= 0xE000) && (addr < 0xFE00))
+ {
+ RAM[addr - 0xE000] = value; // some of gekkio's tests require this to be accessible during DMA
+ }
+ else if ((addr >= 0xFE00) && (addr < 0xFEA0) && ppu.DMA_OAM_access)
+ {
+ OAM[addr - 0xFE00] = value;
+ }
+ else if ((addr >= 0xFF00) && (addr < 0xFF80)) // The game GOAL! Requires Hardware Regs to be accessible
+ {
+ Write_Registers(addr, value);
+ }
+ else if ((addr >= 0xFF80))
+ {
+ ZP_RAM[addr - 0xFF80] = value;
+ }
+ return;
+ }
if (addr < 0x100)
{
@@ -164,5 +211,101 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
Write_Registers(addr, value);
}
}
+
+ public byte PeekMemory(ushort addr)
+ {
+ if (ppu.DMA_start)
+ {
+ if (addr < 0x4000)
+ {
+ return mapper.ReadMemory(addr); // some of gekkio's tests require this to be accessible during DMA
+ }
+ else if ((addr >= 0xE000) && (addr < 0xFE00))
+ {
+ return RAM[addr - 0xE000]; // some of gekkio's tests require this to be accessible during DMA
+ }
+ else if ((addr >= 0xFE00) && (addr < 0xFEA0) && ppu.DMA_OAM_access)
+ {
+ return OAM[addr - 0xFE00];
+ }
+ else if ((addr >= 0xFF00) && (addr < 0xFF80)) // The game GOAL! Requires Hardware Regs to be accessible
+ {
+ return Read_Registers(addr);
+ }
+ else if ((addr >= 0xFF80))
+ {
+ return ZP_RAM[addr - 0xFF80];
+ }
+
+ return 0xFF;
+ }
+
+ if (addr < 0x100)
+ {
+ // return Either BIOS ROM or Game ROM
+ if ((GB_bios_register & 0x1) == 0)
+ {
+ return _bios[addr]; // Return BIOS
+ }
+ else
+ {
+ return mapper.PeekMemory(addr);
+ }
+ }
+ else if (addr < 0x8000)
+ {
+ return mapper.PeekMemory(addr);
+ }
+ else if (addr < 0x9800)
+ {
+ if (ppu.VRAM_access_read) { return CHR_RAM[addr - 0x8000]; }
+ else { return 0xFF; }
+ }
+ else if (addr < 0x9C00)
+ {
+ if (ppu.VRAM_access_read) { return BG_map_1[addr - 0x9800]; }
+ else { return 0xFF; }
+ }
+ else if (addr < 0xA000)
+ {
+ if (ppu.VRAM_access_read) { return BG_map_2[addr - 0x9C00]; }
+ else { return 0xFF; }
+ }
+ else if (addr < 0xC000)
+ {
+ return mapper.PeekMemory(addr);
+ }
+ else if (addr < 0xE000)
+ {
+ return RAM[addr - 0xC000];
+ }
+ else if (addr < 0xFE00)
+ {
+ return RAM[addr - 0xE000];
+ }
+ else if (addr < 0xFEA0)
+ {
+ if (ppu.OAM_access_read) { return OAM[addr - 0xFE00]; }
+ else { return 0xFF; }
+ }
+ else if (addr < 0xFF00)
+ {
+ // unmapped memory, returns 0xFF
+ return 0xFF;
+ }
+ else if (addr < 0xFF80)
+ {
+ return Read_Registers(addr);
+ }
+ else if (addr < 0xFFFF)
+ {
+ return ZP_RAM[addr - 0xFF80];
+ }
+ else
+ {
+ return Read_Registers(addr);
+ }
+
+ }
}
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs
index edf4110745..4c61d66dd2 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs
@@ -9,8 +9,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
public GBHawk Core { get; set; }
- //public byte BGP_l;
-
// register variables
public byte LCDC;
public byte STAT;
@@ -41,6 +39,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public bool stat_line_old;
public int hbl_countdown;
// OAM scan
+ public bool DMA_OAM_access;
public bool OAM_access_read;
public bool OAM_access_write;
public int OAM_scan_index;
@@ -118,9 +117,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
switch (addr)
{
case 0xFF40: // LCDC
+ if (LCDC.Bit(7) && !value.Bit(7))
+ {
+ VRAM_access_read = true;
+ VRAM_access_write = true;
+ OAM_access_read = true;
+ OAM_access_write = true;
+ }
+
LCDC = value;
break;
case 0xFF41: // STAT
+ // writing to STAT during mode 0 or 2 causes a STAT IRQ
+ if (LCDC.Bit(7))
+ {
+ if (((STAT & 3) == 0) || ((STAT & 3) == 1))
+ {
+ LYC_INT = true;
+ }
+ }
STAT = (byte)((value & 0xF8) | (STAT & 7) | 0x80);
break;
case 0xFF42: // SCY
@@ -141,6 +156,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 0xFF46: // DMA
DMA_addr = value;
DMA_start = true;
+ DMA_OAM_access = true;
DMA_clock = 0;
DMA_inc = 0;
break;
@@ -169,14 +185,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
if (DMA_clock >= 4)
{
- OAM_access_read = false;
- OAM_access_write = false;
+ DMA_OAM_access = false;
if ((DMA_clock % 4) == 1)
{
// the cpu can't access memory during this time, but we still need the ppu to be able to.
DMA_start = false;
DMA_byte = Core.ReadMemory((ushort)((DMA_addr << 8) + DMA_inc));
- DMA_start = true;
+ DMA_start = true;
}
else if ((DMA_clock % 4) == 3)
{
@@ -197,8 +212,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (DMA_clock == 648)
{
- OAM_access_read = true;
- OAM_access_write = true;
DMA_start = false;
}
}
@@ -209,6 +222,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// start the next scanline
if (cycle == 456)
{
+ // scanline callback
+ if ((LY + LY_inc) == Core._scanlineCallbackLine)
+ {
+ if (Core._scanlineCallback != null)
+ {
+ Core.GetGPU();
+ Core._scanlineCallback(LCDC);
+ }
+ }
+
+
cycle = 0;
LY += LY_inc;
//Console.WriteLine(Core.cpu.TotalExecutedCycles);
@@ -217,7 +241,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// here is where LY = LYC gets cleared (but only if LY isnt 0 as that's a special case
if (LY_inc == 1)
{
- //LYC_INT = false;
+ LYC_INT = false;
STAT &= 0xFB;
}
@@ -237,10 +261,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
Core.cpu.LY = LY;
+ // Automatically restore access to VRAM at this time (force end drawing)
+ // Who Framed Roger Rabbit seems to run into this.
+ VRAM_access_write = true;
+ VRAM_access_read = true;
+
if (LY == 144)
{
Core.in_vblank = true;
-
}
}
@@ -415,9 +443,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// here LY=LYC will be asserted
if ((cycle == 4) && (LY != 0))
{
- LYC_INT = false;
- STAT &= 0xFB;
-
if (LY == LYC)
{
// set STAT coincidence FLAG and interrupt flag if it is enabled
@@ -431,8 +456,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
else
{
// screen disable sets STAT as though it were vblank, but there is no Stat IRQ asserted
- STAT &= 0xFC;
- STAT |= 0x01;
+ //STAT &= 0xFC;
+ //STAT |= 0x01;
+
+ STAT &= 0xF8;
VBL_INT = LYC_INT = HBL_INT = OAM_INT = false;
@@ -582,7 +609,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
// before anything else, we have to check if windowing is in effect
- if (LCDC.Bit(5) && !window_started && LY >= window_y && pixel_counter >= window_x - 7)
+ if (LCDC.Bit(5) && !window_started && (LY >= window_y) && (pixel_counter >= (window_x - 7)))
{
/*
Console.Write(LY);
@@ -637,7 +664,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
pixel = tile_data_latch[0].Bit(7 - (render_counter % 8)) ? 1 : 0;
pixel |= tile_data_latch[1].Bit(7 - (render_counter % 8)) ? 2 : 0;
- pixel = (BGP >> (pixel * 2)) & 3;
+
+ int ref_pixel = pixel;
+ if (LCDC.Bit(0))
+ {
+ pixel = (BGP >> (pixel * 2)) & 3;
+ }
+ else
+ {
+ pixel = 0;
+ }
+
+
// now we have the BG pixel, we next need the sprite pixel
if (!no_sprites)
{
@@ -682,9 +720,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
if (!sprite_attr.Bit(7))
{
- if (s_pixel != 0) { use_sprite = true; }
+ use_sprite = true;
}
- else if (pixel == 0)
+ else if (ref_pixel == 0)
{
use_sprite = true;
}
@@ -704,13 +742,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
else
{
pixel = (obj_pal_0 >> (s_pixel * 2)) & 3;
- }
+ }
}
}
}
// based on sprite priority and pixel values, pick a final pixel color
- Core._vidbuffer[LY * 160 + pixel_counter] = (int)GBHawk.color_palette[pixel];
+ Core._vidbuffer[LY * 160 + pixel_counter] = (int)Core.color_palette[pixel];
pixel_counter++;
if (pixel_counter == 160)
@@ -1029,11 +1067,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
LY = 0;
LYC = 0;
DMA_addr = 0;
- BGP = 0;
+ BGP = 0xFF;
obj_pal_0 = 0xFF;
obj_pal_1 = 0xFF;
- window_y = 0;
- window_x = 0;
+ window_y = 0x0;
+ window_x = 0x0;
LY_inc = 1;
no_scan = false;
OAM_access_read = true;
@@ -1150,6 +1188,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("write_sprite", ref write_sprite);
ser.Sync("no_scan", ref no_scan);
+ ser.Sync("DMA_OAM_access", ref DMA_OAM_access);
ser.Sync("OAM_access_read", ref OAM_access_read);
ser.Sync("OAM_access_write", ref OAM_access_write);
ser.Sync("VRAM_access_read", ref VRAM_access_read);
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/SerialPort.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/SerialPort.cs
new file mode 100644
index 0000000000..64de7f5457
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/SerialPort.cs
@@ -0,0 +1,151 @@
+using System;
+using BizHawk.Emulation.Common;
+using BizHawk.Common.NumberExtensions;
+using BizHawk.Common;
+
+namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
+{
+ public class SerialPort
+ {
+ public GBHawk Core { get; set; }
+
+ public byte serial_control;
+ public byte serial_data;
+ public bool serial_start;
+ public int serial_clock;
+ public int serial_bits;
+ public bool clk_internal;
+ public int clk_rate;
+
+ public byte ReadReg(int addr)
+ {
+ switch (addr)
+ {
+ case 0xFF01:
+ return serial_data;
+ case 0xFF02:
+ return serial_control;
+ }
+
+ return 0xFF;
+
+ }
+
+ public void WriteReg(int addr, byte value)
+ {
+ switch (addr)
+ {
+ case 0xFF01:
+ serial_data = value;
+ break;
+
+ case 0xFF02:
+ if (((value & 0x80) > 0) && !serial_start)
+ {
+ serial_start = true;
+ serial_bits = 8;
+ if ((value & 1) > 0)
+ {
+ clk_internal = true;
+ clk_rate = 512;
+ serial_clock = clk_rate;
+ }
+ else
+ {
+ clk_internal = false;
+ clk_rate = get_external_clock();
+ serial_clock = clk_rate;
+ }
+ }
+ else if (serial_start)
+ {
+ if ((value & 1) > 0)
+ {
+ clk_internal = true;
+ clk_rate = 512;
+ serial_clock = clk_rate;
+ }
+ else
+ {
+ clk_internal = false;
+ clk_rate = get_external_clock();
+ serial_clock = clk_rate;
+ }
+ }
+
+ serial_control = (byte)(0x7E | (value & 0x81)); // middle six bits always 1
+ break;
+ }
+ }
+
+
+ public void serial_transfer_tick()
+ {
+ if (serial_start)
+ {
+ if (serial_clock > 0) { serial_clock--; }
+ if (serial_clock == 0)
+ {
+ if (serial_bits > 0)
+ {
+ send_external_bit((byte)(serial_data & 0x80));
+
+ byte temp = get_external_bit();
+ serial_data = (byte)((serial_data << 1) | temp);
+
+ serial_bits--;
+ if (serial_bits == 0)
+ {
+ serial_control &= 0x7F;
+ serial_start = false;
+
+ if (Core.REG_FFFF.Bit(3)) { Core.cpu.FlagI = true; }
+ Core.REG_FF0F |= 0x08;
+ }
+ else
+ {
+ serial_clock = clk_rate;
+ }
+ }
+ }
+ }
+ }
+
+ // call this function to get the clock rate of a connected device
+ // if no external device, the clocking doesn't occur
+ public int get_external_clock()
+ {
+ return -1;
+ }
+
+ // call this function to get the next bit from the connected device
+ // no device connected returns 0xFF
+ public byte get_external_bit()
+ {
+ return 1;
+ }
+
+ public void send_external_bit(byte bit_send)
+ {
+
+ }
+
+ public void Reset()
+ {
+ serial_control = 0x7E;
+ serial_start = false;
+ serial_data = 0x00;
+ }
+
+ public void SyncState(Serializer ser)
+ {
+ ser.Sync("serial_control", ref serial_control);
+ ser.Sync("serial_data", ref serial_data);
+ ser.Sync("serial_start", ref serial_start);
+ ser.Sync("serial_clock", ref serial_clock);
+ ser.Sync("serial_bits", ref serial_bits);
+ ser.Sync("clk_internal", ref clk_internal);
+ ser.Sync("clk_rate", ref clk_rate);
+ }
+ }
+}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IEmulator.cs
index b13d7e4dc8..2b55424647 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IEmulator.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IEmulator.cs
@@ -2,6 +2,7 @@
using System.Diagnostics;
using BizHawk.Emulation.Common;
+using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
@@ -99,6 +100,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
GambatteState = IntPtr.Zero;
}
+ _vram = IntPtr.Zero;
+ _oam = IntPtr.Zero;
+ _sppal = IntPtr.Zero;
+ _bgpal = IntPtr.Zero;
+
DisposeSound();
}
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs
index f4e67dae32..74412c7ff4 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs
@@ -54,19 +54,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
Console.WriteLine(game.System);
- byte[] BiosRom;
-
- if (game.System == "GB")
- {
- BiosRom = comm.CoreFileProvider.GetFirmware("GB", "World", false);
- }
- else
- {
- BiosRom = comm.CoreFileProvider.GetFirmware("GBC", "World", false);
- }
-
- int bios_length = BiosRom == null ? 0 : BiosRom.Length;
-
try
{
_syncSettings = (GambatteSyncSettings)syncSettings ?? new GambatteSyncSettings();
@@ -82,16 +69,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
case GambatteSyncSettings.ConsoleModeType.GB:
flags |= LibGambatte.LoadFlags.FORCE_DMG;
- // we need to change the BIOS to GB bios
- if (game.System == "GBC")
- {
- BiosRom = comm.CoreFileProvider.GetFirmware("GB", "World", false);
- bios_length = BiosRom.Length;
- }
break;
case GambatteSyncSettings.ConsoleModeType.GBC:
- BiosRom = comm.CoreFileProvider.GetFirmware("GBC", "World", false);
- bios_length = BiosRom.Length;
break;
default:
if (game.System == "GB")
@@ -99,9 +78,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
break;
}
- // to disable BIOS loading into gambatte, just set bios_length to 0
- bios_length = 0;
-
if (_syncSettings.GBACGB)
{
flags |= LibGambatte.LoadFlags.GBA_CGB;
@@ -112,7 +88,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
flags |= LibGambatte.LoadFlags.MULTICART_COMPAT;
}
- if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, BiosRom, (uint)bios_length, GetCurrentTime(), flags) != 0)
+ if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, GetCurrentTime(), flags) != 0)
{
throw new InvalidOperationException("gambatte_load() returned non-zero (is this not a gb or gbc rom?)");
}
@@ -432,12 +408,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
#region ppudebug
+ public IntPtr _vram = IntPtr.Zero;
+ public IntPtr _bgpal = IntPtr.Zero;
+ public IntPtr _sppal = IntPtr.Zero;
+ public IntPtr _oam = IntPtr.Zero;
+
public GPUMemoryAreas GetGPU()
- {
- IntPtr _vram = IntPtr.Zero;
- IntPtr _bgpal = IntPtr.Zero;
- IntPtr _sppal = IntPtr.Zero;
- IntPtr _oam = IntPtr.Zero;
+ {
int unused = 0;
if (!LibGambatte.gambatte_getmemoryarea(GambatteState, LibGambatte.MemoryAreas.vram, ref _vram, ref unused)
|| !LibGambatte.gambatte_getmemoryarea(GambatteState, LibGambatte.MemoryAreas.bgpal, ref _bgpal, ref unused)
@@ -447,7 +424,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
throw new InvalidOperationException("Unexpected error in gambatte_getmemoryarea");
}
return new GPUMemoryAreas(_vram, _oam, _sppal, _bgpal);
-
}
///
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
index 88c68bd3ed..3624bc9512 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
@@ -57,7 +57,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
/// ORed combination of LoadFlags.
/// 0 on success, negative value on failure.
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern int gambatte_load(IntPtr core, byte[] romdata, uint length, byte[] biosdata, uint bioslength, long now, LoadFlags flags);
+ public static extern int gambatte_load(IntPtr core, byte[] romdata, uint length, long now, LoadFlags flags);
///
/// Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer,
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.CodeMasters.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.CodeMasters.cs
index 020b424643..6bbc979612 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.CodeMasters.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.CodeMasters.cs
@@ -40,8 +40,8 @@
void InitCodeMastersMapper()
{
- ReadMemory = ReadMemoryCM;
- WriteMemory = WriteMemoryCM;
+ ReadMemoryMapper = ReadMemoryCM;
+ WriteMemoryMapper = WriteMemoryCM;
MapMemory = MapMemoryCM;
WriteMemoryCM(0x0000, 0);
WriteMemoryCM(0x4000, 1);
@@ -113,8 +113,8 @@
void InitCodeMastersMapperRam()
{
- ReadMemory = ReadMemoryCMRam;
- WriteMemory = WriteMemoryCMRam;
+ ReadMemoryMapper = ReadMemoryCMRam;
+ WriteMemoryMapper = WriteMemoryCMRam;
MapMemory = MapMemoryCMRam;
WriteMemoryCM(0x0000, 0);
WriteMemoryCM(0x4000, 1);
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.EEPROM.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.EEPROM.cs
index 2e5c544c11..2c7008da75 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.EEPROM.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.EEPROM.cs
@@ -122,8 +122,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
void InitEEPROMMapper()
{
- ReadMemory = ReadMemoryEEPROM;
- WriteMemory = WriteMemoryEEPROM;
+ ReadMemoryMapper = ReadMemoryEEPROM;
+ WriteMemoryMapper = WriteMemoryEEPROM;
MapMemory = MapMemoryEEPROM;
WriteMemoryEEPROM(0xFFFC, 0);
WriteMemoryEEPROM(0xFFFD, 0);
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.ExtRam.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.ExtRam.cs
index 0f369a2c61..73254208af 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.ExtRam.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.ExtRam.cs
@@ -38,8 +38,8 @@
{
ExtRam = new byte[size];
ExtRamMask = size - 1;
- ReadMemory = ReadMemoryExt;
- WriteMemory = WriteMemoryExt;
+ ReadMemoryMapper = ReadMemoryExt;
+ WriteMemoryMapper = WriteMemoryExt;
MapMemory = MapMemoryExt;
}
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Korea.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Korea.cs
index a5603e753a..d737844976 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Korea.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Korea.cs
@@ -30,8 +30,8 @@
void InitKoreaMapper()
{
- ReadMemory = ReadMemoryKR;
- WriteMemory = WriteMemoryKR;
+ ReadMemoryMapper = ReadMemoryKR;
+ WriteMemoryMapper = WriteMemoryKR;
MapMemory = MapMemoryKR;
RomBank0 = 0;
RomBank1 = 1;
@@ -101,9 +101,9 @@
void InitMSXMapper()
{
- ReadMemory = ReadMemoryMSX;
- WriteMemory = WriteMemoryMSX;
- ReadMemory = ReadMemoryMSX;
+ ReadMemoryMapper = ReadMemoryMSX;
+ WriteMemoryMapper = WriteMemoryMSX;
+ ReadMemoryMapper = ReadMemoryMSX;
RomBank0 = 0;
RomBank1 = 0;
RomBank2 = 0;
@@ -113,7 +113,7 @@
void InitNemesisMapper()
{
InitMSXMapper();
- ReadMemory = ReadMemoryNemesis;
+ ReadMemoryMapper = ReadMemoryNemesis;
MapMemory = MapMemoryNemesis;
}
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Sega.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Sega.cs
index 91075b9b8a..6e13147651 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Sega.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Sega.cs
@@ -132,8 +132,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
void InitSegaMapper()
{
- ReadMemory = ReadMemorySega;
- WriteMemory = WriteMemorySega;
+ ReadMemoryMapper = ReadMemorySega;
+ WriteMemoryMapper = WriteMemorySega;
MapMemory = MapMemorySega;
WriteMemorySega(0xFFFC, 0);
WriteMemorySega(0xFFFD, 0);
@@ -176,8 +176,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
void InitBiosMapper()
{
- ReadMemory = ReadMemoryBIOS;
- WriteMemory = WriteMemoryBIOS;
+ ReadMemoryMapper = ReadMemoryBIOS;
+ WriteMemoryMapper = WriteMemoryBIOS;
WriteMemorySega(0xFFFC, 0);
WriteMemorySega(0xFFFD, 0);
WriteMemorySega(0xFFFE, 1);
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ICodeDataLogger.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ICodeDataLogger.cs
index 888b0a3a2a..199cfef58c 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ICodeDataLogger.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ICodeDataLogger.cs
@@ -13,7 +13,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
{
Cpu.ReadMemory = ReadMemory;
Cpu.WriteMemory = WriteMemory;
- Cpu.FetchMemory = FetchMemory_StubThunk;
+ Cpu.FetchMemory = FetchMemory;
}
else
{
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.IDebuggable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.IDebuggable.cs
index 009cd5fd4c..d8b0d15402 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.IDebuggable.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.IDebuggable.cs
@@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
["Shadow BC"] = Cpu.Regs[Cpu.C_s] + (Cpu.Regs[Cpu.B_s] << 8),
["Shadow DE"] = Cpu.Regs[Cpu.E_s] + (Cpu.Regs[Cpu.D_s] << 8),
["Shadow HL"] = Cpu.Regs[Cpu.L_s] + (Cpu.Regs[Cpu.H_s] << 8),
- ["SP"] = Cpu.Regs[Cpu.Iyl] + (Cpu.Regs[Cpu.Iyh] << 8),
+ ["SP"] = Cpu.Regs[Cpu.SPl] + (Cpu.Regs[Cpu.SPh] << 8),
["Flag C"] = Cpu.FlagC,
["Flag N"] = Cpu.FlagN,
["Flag P/V"] = Cpu.FlagP,
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.IEmulator.cs
index e49a75ddad..59ab099595 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.IEmulator.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.IEmulator.cs
@@ -15,6 +15,9 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
return GGController;
}
+ // Sorta a hack but why not
+ PortDEEnabled = SyncSettings.ControllerType == "Keyboard";
+
switch(SyncSettings.ControllerType)
{
case "Paddle":
@@ -26,6 +29,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
return SMSLightPhaserController;
case "Sports Pad":
return SMSSportsPadController;
+ case "Keyboard":
+ return SMSKeyboardController;
default:
return SmsController;
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.Input.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.Input.cs
index c76dab5789..ffbe65cd1b 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.Input.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.Input.cs
@@ -90,6 +90,35 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
}
};
+ public static readonly ControllerDefinition SMSKeyboardController = new ControllerDefinition
+ {
+ Name = "SMS Keyboard Controller",
+ BoolButtons =
+ {
+ "Key 1", "Key 2", "Key 3", "Key 4", "Key 5", "Key 6", "Key 7", "Key 8", "Key 9", "Key 0", "Key Minus", "Key Caret", "Key Yen", "Key Break",
+ "Key Function", "Key Q", "Key W", "Key E", "Key R", "Key T", "Key Y", "Key U", "Key I", "Key O", "Key P", "Key At", "Key Left Bracket", "Key Return", "Key Up Arrow",
+ "Key Control", "Key A", "Key S", "Key D", "Key F", "Key G", "Key H", "Key J", "Key K", "Key L", "Key Semicolon", "Key Colon", "Key Right Bracket", "Key Left Arrow", "Key Right Arrow",
+ "Key Shift", "Key Z", "Key X", "Key C", "Key V", "Key B", "Key N", "Key M", "Key Comma", "Key Period", "Key Slash", "Key PI", "Key Down Arrow",
+ "Key Graph", "Key Kana", "Key Space", "Key Home/Clear", "Key Insert/Delete",
+
+ "Reset", "Pause",
+ "P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 B1", "P1 B2",
+ "P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 B1", "P2 B2"
+ }
+ };
+
+ private static readonly string[] KeyboardMap =
+ {
+ "Key 1", "Key Q", "Key A", "Key Z", "Key Kana", "Key Comma", "Key K", "Key I", "Key 8", null, null, null,
+ "Key 2", "Key W", "Key S", "Key X", "Key Space", "Key Period", "Key L", "Key O", "Key 9", null, null, null,
+ "Key 3", "Key E", "Key D", "Key C", "Key Home/Clear", "Key Slash", "Key Semicolon", "Key P", "Key 0", null, null, null,
+ "Key 4", "Key R", "Key F", "Key V", "Key Insert/Delete", "Key PI", "Key Colon", "Key At", "Key Minus", null, null, null,
+ "Key 5", "Key T", "Key G", "Key B", null, "Key Down Arrow", "Key Right Bracket", "Key Left Bracket", "Key Caret", null, null, null,
+ "Key 6", "Key Y", "Key H", "Key N", null, "Key Left Arrow", "Key Return", null, "Key Yen", null, null, "Key Function",
+ "Key 7", "Key U", "Key J", "Key M", null, "Key Right Arrow", "Key Up Arrow", null, "Key Break", "Key Graph", "Key Control", "Key Shift",
+ "P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 B1", "P1 B2", "P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 B1", "P2 B2"
+ };
+
const int PaddleMin = 0;
const int PaddleMax = 255;
const int SportsPadMin = -64;
@@ -209,13 +238,14 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
else
p2Y = (int)_controller.GetFloat("P2 Y");
- if(_region == "Japan")
+ if (_region == "Japan")
{
p1X += 128;
p1Y += 128;
p2X += 128;
p2Y += 128;
- } else
+ }
+ else
{
p1X *= -1;
p1Y *= -1;
@@ -323,6 +353,22 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
}
break;
+ case "Keyboard":
+ {
+ // use keyboard map to get each bit
+
+ for (int bit = 0; bit < 8; ++bit)
+ {
+ string key = KeyboardMap[(PortDE & 0x07) * 12 + bit];
+
+ if (key != null && _controller.IsPressed(key))
+ {
+ value &= (byte)~(1 << bit);
+ }
+ }
+ }
+ break;
+
default:
// Normal controller
@@ -464,6 +510,24 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
}
break;
+ case "Keyboard":
+ {
+ value &= 0x7F;
+
+ // use keyboard map to get each bit
+
+ for (int bit = 0; bit < 4; ++bit)
+ {
+ string key = KeyboardMap[(PortDE & 0x07) * 12 + bit + 8];
+
+ if (key != null && _controller.IsPressed(key))
+ {
+ value &= (byte)~(1 << bit);
+ }
+ }
+ }
+ break;
+
default:
// Normal controller
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs
index b2ee955288..41cf46626f 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs
@@ -78,10 +78,11 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
{
ReadHardware = ReadPort,
WriteHardware = WritePort,
- FetchMemory = ReadMemory,
+ FetchMemory = FetchMemory,
ReadMemory = ReadMemory,
WriteMemory = WriteMemory,
- MemoryCallbacks = MemoryCallbacks
+ MemoryCallbacks = MemoryCallbacks,
+ OnExecFetch = OnExecMemory
};
Vdp = new VDP(this, Cpu, IsGameGear ? VdpMode.GameGear : VdpMode.SMS, Region);
@@ -207,6 +208,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
public bool IsSG1000 { get; set; }
private bool HasYM2413 = false;
+ private bool PortDEEnabled = false;
private IController _controller;
private int _frame = 0;
@@ -215,6 +217,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
private byte Port02 = 0xFF;
private byte Port3E = 0xAF;
private byte Port3F = 0xFF;
+ private byte PortDE = 0x00;
private byte ForceStereoByte = 0xAD;
private bool IsGame3D = false;
@@ -249,15 +252,39 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
return DisplayType.NTSC;
}
+ private byte ReadMemory(ushort addr)
+ {
+ MemoryCallbacks.CallReads(addr, "System Bus");
+
+ return ReadMemoryMapper(addr);
+ }
+
+ private void WriteMemory(ushort addr, byte value)
+ {
+ WriteMemoryMapper(addr, value);
+
+ MemoryCallbacks.CallWrites(addr, "System Bus");
+ }
+
+ private byte FetchMemory(ushort addr)
+ {
+ return ReadMemoryMapper(addr);
+ }
+
+ private void OnExecMemory(ushort addr)
+ {
+ MemoryCallbacks.CallExecutes(addr, "System Bus");
+ }
+
///
/// The ReadMemory callback for the mapper
///
- private Func ReadMemory;
+ private Func ReadMemoryMapper;
///
/// The WriteMemory callback for the wrapper
///
- private Action WriteMemory;
+ private Action WriteMemoryMapper;
///
/// A dummy FetchMemory that simply reads the memory
@@ -305,6 +332,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
case 0xDC: return ReadControls1();
case 0xC1:
case 0xDD: return ReadControls2();
+ case 0xDE: return PortDEEnabled ? PortDE : (byte)0xFF;
case 0xF2: return HasYM2413 ? YM2413.DetectionValue : (byte)0xFF;
default: return 0xFF;
}
@@ -333,6 +361,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
else
Vdp.WriteVdpControl(value);
}
+ else if (port == 0xDE && PortDEEnabled) PortDE = value;
else if (port == 0xF0 && HasYM2413) YM2413.RegisterLatch = value;
else if (port == 0xF1 && HasYM2413) YM2413.Write(value);
else if (port == 0xF2 && HasYM2413) YM2413.DetectionValue = value;
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/TerebiOekaki.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/TerebiOekaki.cs
index a42a1b2704..30869f9042 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/TerebiOekaki.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/TerebiOekaki.cs
@@ -46,8 +46,8 @@
void InitTerebiOekaki()
{
- ReadMemory = ReadMemoryTO;
- WriteMemory = WriteMemoryTO;
+ ReadMemoryMapper = ReadMemoryTO;
+ WriteMemoryMapper = WriteMemoryTO;
}
}
}
diff --git a/libgambatte/include/gambatte.h b/libgambatte/include/gambatte.h
index 08b3575a6a..5f04191fe6 100644
--- a/libgambatte/include/gambatte.h
+++ b/libgambatte/include/gambatte.h
@@ -60,8 +60,7 @@ public:
* @param flags ORed combination of LoadFlags.
* @return 0 on success, negative value on failure.
*/
- bool use_bios;
- int load(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, std::uint32_t now, unsigned flags = 0);
+ int load(const char *romfiledata, unsigned romfilelength, std::uint32_t now, unsigned flags = 0);
/** Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer,
* or until a video frame has been drawn.
diff --git a/libgambatte/libgambatte.sln b/libgambatte/libgambatte.sln
index fe5fec1e4a..4849245619 100644
--- a/libgambatte/libgambatte.sln
+++ b/libgambatte/libgambatte.sln
@@ -1,6 +1,8 @@
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgambatte", "libgambatte.vcxproj", "{5D630682-7BDA-474D-B387-0EB420DDC199}"
EndProject
Global
@@ -11,10 +13,10 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {5D630682-7BDA-474D-B387-0EB420DDC199}.Debug|Win32.ActiveCfg = Debug|Win32
- {5D630682-7BDA-474D-B387-0EB420DDC199}.Debug|Win32.Build.0 = Debug|Win32
- {5D630682-7BDA-474D-B387-0EB420DDC199}.Debug|x64.ActiveCfg = Debug|x64
- {5D630682-7BDA-474D-B387-0EB420DDC199}.Debug|x64.Build.0 = Debug|x64
+ {5D630682-7BDA-474D-B387-0EB420DDC199}.Debug|Win32.ActiveCfg = Release|x64
+ {5D630682-7BDA-474D-B387-0EB420DDC199}.Debug|Win32.Build.0 = Release|x64
+ {5D630682-7BDA-474D-B387-0EB420DDC199}.Debug|x64.ActiveCfg = Release|x64
+ {5D630682-7BDA-474D-B387-0EB420DDC199}.Debug|x64.Build.0 = Release|x64
{5D630682-7BDA-474D-B387-0EB420DDC199}.Release|Win32.ActiveCfg = Release|Win32
{5D630682-7BDA-474D-B387-0EB420DDC199}.Release|Win32.Build.0 = Release|Win32
{5D630682-7BDA-474D-B387-0EB420DDC199}.Release|x64.ActiveCfg = Release|x64
diff --git a/libgambatte/src/cinterface.cpp b/libgambatte/src/cinterface.cpp
index 376b8c68f5..abb750b12b 100644
--- a/libgambatte/src/cinterface.cpp
+++ b/libgambatte/src/cinterface.cpp
@@ -29,9 +29,9 @@ GBEXPORT void gambatte_destroy(GB *g)
delete g;
}
-GBEXPORT int gambatte_load(GB *g, const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, long long now, unsigned flags)
+GBEXPORT int gambatte_load(GB *g, const char *romfiledata, unsigned romfilelength, long long now, unsigned flags)
{
- int ret = g->load(romfiledata, romfilelength, biosfiledata, biosfilelength, now, flags);
+ int ret = g->load(romfiledata, romfilelength, now, flags);
return ret;
}
diff --git a/libgambatte/src/cpu.h b/libgambatte/src/cpu.h
index 2c9e4547a4..b36112f7ea 100644
--- a/libgambatte/src/cpu.h
+++ b/libgambatte/src/cpu.h
@@ -99,13 +99,9 @@ public:
void setLinkCallback(void (*callback)()) {
memory.setLinkCallback(callback);
}
-
- void reset_bios(int setting) {
- memory.bios_reset(setting);
- }
- int load(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, bool forceDmg, bool multicartCompat) {
- return memory.loadROM(romfiledata, romfilelength, biosfiledata, biosfilelength, forceDmg, multicartCompat);
+ int load(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat) {
+ return memory.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat);
}
bool loaded() const { return memory.loaded(); }
diff --git a/libgambatte/src/gambatte.cpp b/libgambatte/src/gambatte.cpp
index ee064c0743..5e9c59e63f 100644
--- a/libgambatte/src/gambatte.cpp
+++ b/libgambatte/src/gambatte.cpp
@@ -94,12 +94,8 @@ void GB::reset(const std::uint32_t now) {
SaveState state;
p_->cpu.setStatePtrs(state);
- if (use_bios)
- {
- p_->cpu.reset_bios(0);
- }
- setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode, now, use_bios);
+ setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode, now);
p_->cpu.loadState(state);
if (length > 0)
{
@@ -145,17 +141,16 @@ void GB::setLinkCallback(void(*callback)()) {
p_->cpu.setLinkCallback(callback);
}
-int GB::load(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, const std::uint32_t now, const unsigned flags) {
+int GB::load(const char *romfiledata, unsigned romfilelength, const std::uint32_t now, const unsigned flags) {
//if (p_->cpu.loaded())
// p_->cpu.saveSavedata();
- const int failed = p_->cpu.load(romfiledata, romfilelength, biosfiledata, biosfilelength, flags & FORCE_DMG, flags & MULTICART_COMPAT);
- use_bios = biosfilelength > 0 ? true : false;
-
+ const int failed = p_->cpu.load(romfiledata, romfilelength, flags & FORCE_DMG, flags & MULTICART_COMPAT);
+
if (!failed) {
SaveState state;
p_->cpu.setStatePtrs(state);
- setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode = flags & GBA_CGB, now, use_bios);
+ setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode = flags & GBA_CGB, now);
p_->cpu.loadState(state);
//p_->cpu.loadSavedata();
}
@@ -238,7 +233,6 @@ SYNCFUNC(GB)
SSS(p_->cpu);
NSS(p_->gbaCgbMode);
NSS(p_->vbuff);
- NSS(use_bios);
}
}
diff --git a/libgambatte/src/initstate.cpp b/libgambatte/src/initstate.cpp
index add9c8b160..5f11104d08 100644
--- a/libgambatte/src/initstate.cpp
+++ b/libgambatte/src/initstate.cpp
@@ -1146,7 +1146,7 @@ static void setInitialDmgIoamhram(unsigned char *const ioamhram) {
} // anon namespace
-void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbMode, const std::uint32_t now, bool boot_bios) {
+void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbMode, const std::uint32_t now) {
static const unsigned char cgbObjpDump[0x40] = {
0x00, 0x00, 0xF2, 0xAB,
0x61, 0xC2, 0xD9, 0xBA,
@@ -1166,317 +1166,158 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM
0x83, 0x40, 0x0B, 0x77
};
- if (boot_bios)
- {
- state.cpu.PC = 0x00;
- state.cpu.SP = 0xFFFE;
- state.cpu.A = 0;
- state.cpu.B = 0;
- state.cpu.C = 0x0;
- state.cpu.D = 0x0;
- state.cpu.E = 0x0;
- state.cpu.F = 0x0;
- state.cpu.H = 0x0;
- state.cpu.L = 0x0;
- state.cpu.skip = false;
- state.cpu.cycleCounter = 0;
- state.mem.ioamhram.ptr[0x140] = 0x00;
- state.mem.ioamhram.ptr[0x104] = 0x00;
- state.mem.using_bios = true;
-
- std::memset(state.mem.sram.ptr, 0xFF, state.mem.sram.getSz());
-
- if (cgb) {
- setInitialCgbWram(state.mem.wram.ptr);
- }
- else {
- setInitialDmgWram(state.mem.wram.ptr);
- }
-
- if (cgb) {
- setInitialCgbIoamhram(state.mem.ioamhram.ptr);
- }
- else {
- setInitialDmgIoamhram(state.mem.ioamhram.ptr);
- }
-
- state.mem.ioamhram.ptr[0x144] = 0x00;
-
- state.mem.divLastUpdate = 0;
- state.mem.timaLastUpdate = 0;
- state.mem.tmatime = DISABLED_TIME;
- state.mem.nextSerialtime = DISABLED_TIME;
- state.mem.lastOamDmaUpdate = DISABLED_TIME;
- state.mem.unhaltTime = DISABLED_TIME;
- state.mem.minIntTime = 0;
- state.mem.rombank = 1;
- state.mem.dmaSource = 0;
- state.mem.dmaDestination = 0;
- state.mem.rambank = 0;
- state.mem.oamDmaPos = 0x0;
- state.mem.IME = false;
- state.mem.halted = false;
- state.mem.enableRam = false;
- state.mem.rambankMode = false;
- state.mem.hdmaTransfer = false;
-
-
- for (unsigned i = 0x00; i < 0x40; i += 0x02) {
- state.ppu.bgpData.ptr[i] = 0xFF;
- state.ppu.bgpData.ptr[i + 1] = 0x7F;
- }
-
- std::memcpy(state.ppu.objpData.ptr, cgbObjpDump, sizeof(cgbObjpDump));
-
- if (!cgb) {
- state.ppu.bgpData.ptr[0] = state.mem.ioamhram.get()[0x147];
- state.ppu.objpData.ptr[0] = state.mem.ioamhram.get()[0x148];
- state.ppu.objpData.ptr[1] = state.mem.ioamhram.get()[0x149];
- }
-
- for (unsigned pos = 0; pos < 80; ++pos)
- state.ppu.oamReaderBuf.ptr[pos] = state.mem.ioamhram.ptr[(pos * 2 & ~3) | (pos & 1)];
-
- std::fill_n(state.ppu.oamReaderSzbuf.ptr, 40, false);
- std::memset(state.ppu.spAttribList, 0, sizeof(state.ppu.spAttribList));
- std::memset(state.ppu.spByte0List, 0, sizeof(state.ppu.spByte0List));
- std::memset(state.ppu.spByte1List, 0, sizeof(state.ppu.spByte1List));
- state.ppu.videoCycles = cgb ? 144 * 456ul + 164 : 153 * 456ul + 396;
- state.ppu.enableDisplayM0Time = 0;
- state.ppu.winYPos = 0;
- state.ppu.xpos = 0;
- state.ppu.endx = 0;
- state.ppu.reg0 = 0;
- state.ppu.reg1 = 0;
- state.ppu.tileword = 0;
- state.ppu.ntileword = 0;
- state.ppu.attrib = 0;
- state.ppu.nattrib = 0;
- state.ppu.state = 0;
- state.ppu.nextSprite = 0;
- state.ppu.currentSprite = 0;
- state.ppu.lyc = 0;
- state.ppu.m0lyc = 0;
- state.ppu.weMaster = false;
- state.ppu.winDrawState = 0;
- state.ppu.wscx = 0;
- state.ppu.lastM0Time = 0;
- state.ppu.nextM0Irq = 0;
- state.ppu.oldWy = 0;
- state.ppu.pendingLcdstatIrq = false;
-
- state.spu.cycleCounter = 0;
-
- state.spu.ch1.sweep.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch1.sweep.shadow = 0;
- state.spu.ch1.sweep.nr0 = 0;
- state.spu.ch1.sweep.negging = false;
- state.spu.ch1.duty.nextPosUpdate = 0;
- state.spu.ch1.duty.nr3 = 0;
- state.spu.ch1.duty.pos = 0;
- state.spu.ch1.env.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch1.env.volume = 0;
- state.spu.ch1.lcounter.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch1.lcounter.lengthCounter = 0x0;
- state.spu.ch1.nr4 = 0;
- state.spu.ch1.master = false;
-
- state.spu.ch2.duty.nextPosUpdate = 0;
- state.spu.ch2.duty.nr3 = 0;
- state.spu.ch2.duty.pos = 0;
- state.spu.ch2.env.counter = 0;
- state.spu.ch2.env.volume = 0;
- state.spu.ch2.lcounter.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch2.lcounter.lengthCounter = 0x0;
- state.spu.ch2.nr4 = 0;
- state.spu.ch2.master = false;
-
- for (unsigned i = 0; i < 0x10; ++i)
- state.spu.ch3.waveRam.ptr[i] = 0;
-
- state.spu.ch3.lcounter.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch3.lcounter.lengthCounter = 0x0;
- state.spu.ch3.waveCounter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch3.lastReadTime = SoundUnit::COUNTER_DISABLED;
- state.spu.ch3.nr3 = 0;
- state.spu.ch3.nr4 = 0;
- state.spu.ch3.wavePos = 0;
- state.spu.ch3.sampleBuf = 0;
- state.spu.ch3.master = false;
-
- state.spu.ch4.lfsr.counter = 0;
- state.spu.ch4.lfsr.reg = 0;
- state.spu.ch4.env.counter = 0;
- state.spu.ch4.env.volume = 0;
- state.spu.ch4.lcounter.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch4.lcounter.lengthCounter = 0x0;
- state.spu.ch4.nr4 = 0;
- state.spu.ch4.master = false;
-
- state.rtc.baseTime = now;
- state.rtc.haltTime = state.rtc.baseTime;
- state.rtc.dataDh = 0;
- state.rtc.dataDl = 0;
- state.rtc.dataH = 0;
- state.rtc.dataM = 0;
- state.rtc.dataS = 0;
- state.rtc.lastLatchData = false;
- }
- else
- {
- state.cpu.PC = 0x100;
- state.cpu.SP = 0xFFFE;
- state.cpu.A = cgb * 0x10 | 0x01;
- state.cpu.B = cgb & gbaCgbMode;
- state.cpu.C = 0x13;
- state.cpu.D = 0x00;
- state.cpu.E = 0xD8;
- state.cpu.F = 0xB0;
- state.cpu.H = 0x01;
- state.cpu.L = 0x4D;
- state.cpu.skip = false;
- setInitialVram(state.mem.vram.ptr, cgb);
- state.cpu.cycleCounter = cgb ? 0x102A0 : 0x102A0 + 0x8D2C;
+ state.cpu.PC = 0x100;
+ state.cpu.SP = 0xFFFE;
+ state.cpu.A = cgb * 0x10 | 0x01;
+ state.cpu.B = cgb & gbaCgbMode;
+ state.cpu.C = 0x13;
+ state.cpu.D = 0x00;
+ state.cpu.E = 0xD8;
+ state.cpu.F = 0xB0;
+ state.cpu.H = 0x01;
+ state.cpu.L = 0x4D;
+ state.cpu.skip = false;
+ setInitialVram(state.mem.vram.ptr, cgb);
+ state.cpu.cycleCounter = cgb ? 0x102A0 : 0x102A0 + 0x8D2C;
- std::memset(state.mem.sram.ptr, 0xFF, state.mem.sram.getSz());
+ std::memset(state.mem.sram.ptr, 0xFF, state.mem.sram.getSz());
- if (cgb) {
- setInitialCgbWram(state.mem.wram.ptr);
- }
- else {
- setInitialDmgWram(state.mem.wram.ptr);
- }
-
- if (cgb) {
- setInitialCgbIoamhram(state.mem.ioamhram.ptr);
- }
- else {
- setInitialDmgIoamhram(state.mem.ioamhram.ptr);
- }
-
- state.mem.ioamhram.ptr[0x140] = 0x91;
- state.mem.ioamhram.ptr[0x104] = 0x1C;
- state.mem.ioamhram.ptr[0x144] = 0x00;
-
- state.mem.divLastUpdate = 0;
- state.mem.timaLastUpdate = 0;
- state.mem.tmatime = DISABLED_TIME;
- state.mem.nextSerialtime = DISABLED_TIME;
- state.mem.lastOamDmaUpdate = DISABLED_TIME;
- state.mem.unhaltTime = DISABLED_TIME;
- state.mem.minIntTime = 0;
- state.mem.rombank = 1;
- state.mem.dmaSource = 0;
- state.mem.dmaDestination = 0;
- state.mem.rambank = 0;
- state.mem.oamDmaPos = 0xFE;
- state.mem.IME = false;
- state.mem.halted = false;
- state.mem.enableRam = false;
- state.mem.rambankMode = false;
- state.mem.hdmaTransfer = false;
-
-
- for (unsigned i = 0x00; i < 0x40; i += 0x02) {
- state.ppu.bgpData.ptr[i] = 0xFF;
- state.ppu.bgpData.ptr[i + 1] = 0x7F;
- }
-
- std::memcpy(state.ppu.objpData.ptr, cgbObjpDump, sizeof(cgbObjpDump));
-
- if (!cgb) {
- state.ppu.bgpData.ptr[0] = state.mem.ioamhram.get()[0x147];
- state.ppu.objpData.ptr[0] = state.mem.ioamhram.get()[0x148];
- state.ppu.objpData.ptr[1] = state.mem.ioamhram.get()[0x149];
- }
-
- for (unsigned pos = 0; pos < 80; ++pos)
- state.ppu.oamReaderBuf.ptr[pos] = state.mem.ioamhram.ptr[(pos * 2 & ~3) | (pos & 1)];
-
- std::fill_n(state.ppu.oamReaderSzbuf.ptr, 40, false);
- std::memset(state.ppu.spAttribList, 0, sizeof(state.ppu.spAttribList));
- std::memset(state.ppu.spByte0List, 0, sizeof(state.ppu.spByte0List));
- std::memset(state.ppu.spByte1List, 0, sizeof(state.ppu.spByte1List));
- state.ppu.videoCycles = cgb ? 144 * 456ul + 164 : 153 * 456ul + 396;
- state.ppu.enableDisplayM0Time = state.cpu.cycleCounter;
- state.ppu.winYPos = 0xFF;
- state.ppu.xpos = 0;
- state.ppu.endx = 0;
- state.ppu.reg0 = 0;
- state.ppu.reg1 = 0;
- state.ppu.tileword = 0;
- state.ppu.ntileword = 0;
- state.ppu.attrib = 0;
- state.ppu.nattrib = 0;
- state.ppu.state = 0;
- state.ppu.nextSprite = 0;
- state.ppu.currentSprite = 0;
- state.ppu.lyc = state.mem.ioamhram.get()[0x145];
- state.ppu.m0lyc = state.mem.ioamhram.get()[0x145];
- state.ppu.weMaster = false;
- state.ppu.winDrawState = 0;
- state.ppu.wscx = 0;
- state.ppu.lastM0Time = 1234;
- state.ppu.nextM0Irq = 0;
- state.ppu.oldWy = state.mem.ioamhram.get()[0x14A];
- state.ppu.pendingLcdstatIrq = false;
-
- state.spu.cycleCounter = 0x1000 | (state.cpu.cycleCounter >> 1 & 0xFFF); // spu.cycleCounter >> 12 & 7 represents the frame sequencer position.
-
- state.spu.ch1.sweep.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch1.sweep.shadow = 0;
- state.spu.ch1.sweep.nr0 = 0;
- state.spu.ch1.sweep.negging = false;
- state.spu.ch1.duty.nextPosUpdate = (state.spu.cycleCounter & ~1) + 2048 * 2;
- state.spu.ch1.duty.nr3 = 0;
- state.spu.ch1.duty.pos = 0;
- state.spu.ch1.env.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch1.env.volume = 0;
- state.spu.ch1.lcounter.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch1.lcounter.lengthCounter = 0x40;
- state.spu.ch1.nr4 = 0;
- state.spu.ch1.master = true;
-
- state.spu.ch2.duty.nextPosUpdate = (state.spu.cycleCounter & ~1) + 2048 * 2;
- state.spu.ch2.duty.nr3 = 0;
- state.spu.ch2.duty.pos = 0;
- state.spu.ch2.env.counter = state.spu.cycleCounter - ((state.spu.cycleCounter - 0x1000) & 0x7FFF) + 8ul * 0x8000;
- state.spu.ch2.env.volume = 0;
- state.spu.ch2.lcounter.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch2.lcounter.lengthCounter = 0x40;
- state.spu.ch2.nr4 = 0;
- state.spu.ch2.master = false;
-
- for (unsigned i = 0; i < 0x10; ++i)
- state.spu.ch3.waveRam.ptr[i] = state.mem.ioamhram.get()[0x130 + i];
-
- state.spu.ch3.lcounter.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch3.lcounter.lengthCounter = 0x100;
- state.spu.ch3.waveCounter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch3.lastReadTime = SoundUnit::COUNTER_DISABLED;
- state.spu.ch3.nr3 = 0;
- state.spu.ch3.nr4 = 0;
- state.spu.ch3.wavePos = 0;
- state.spu.ch3.sampleBuf = 0;
- state.spu.ch3.master = false;
-
- state.spu.ch4.lfsr.counter = state.spu.cycleCounter + 4;
- state.spu.ch4.lfsr.reg = 0xFF;
- state.spu.ch4.env.counter = state.spu.cycleCounter - ((state.spu.cycleCounter - 0x1000) & 0x7FFF) + 8ul * 0x8000;
- state.spu.ch4.env.volume = 0;
- state.spu.ch4.lcounter.counter = SoundUnit::COUNTER_DISABLED;
- state.spu.ch4.lcounter.lengthCounter = 0x40;
- state.spu.ch4.nr4 = 0;
- state.spu.ch4.master = false;
-
- state.rtc.baseTime = now;
- state.rtc.haltTime = state.rtc.baseTime;
- state.rtc.dataDh = 0;
- state.rtc.dataDl = 0;
- state.rtc.dataH = 0;
- state.rtc.dataM = 0;
- state.rtc.dataS = 0;
- state.rtc.lastLatchData = false;
+ if (cgb) {
+ setInitialCgbWram(state.mem.wram.ptr);
}
+ else {
+ setInitialDmgWram(state.mem.wram.ptr);
+ }
+
+ if (cgb) {
+ setInitialCgbIoamhram(state.mem.ioamhram.ptr);
+ }
+ else {
+ setInitialDmgIoamhram(state.mem.ioamhram.ptr);
+ }
+
+ state.mem.ioamhram.ptr[0x140] = 0x91;
+ state.mem.ioamhram.ptr[0x104] = 0x1C;
+ state.mem.ioamhram.ptr[0x144] = 0x00;
+
+ state.mem.divLastUpdate = 0;
+ state.mem.timaLastUpdate = 0;
+ state.mem.tmatime = DISABLED_TIME;
+ state.mem.nextSerialtime = DISABLED_TIME;
+ state.mem.lastOamDmaUpdate = DISABLED_TIME;
+ state.mem.unhaltTime = DISABLED_TIME;
+ state.mem.minIntTime = 0;
+ state.mem.rombank = 1;
+ state.mem.dmaSource = 0;
+ state.mem.dmaDestination = 0;
+ state.mem.rambank = 0;
+ state.mem.oamDmaPos = 0xFE;
+ state.mem.IME = false;
+ state.mem.halted = false;
+ state.mem.enableRam = false;
+ state.mem.rambankMode = false;
+ state.mem.hdmaTransfer = false;
+
+
+ for (unsigned i = 0x00; i < 0x40; i += 0x02) {
+ state.ppu.bgpData.ptr[i] = 0xFF;
+ state.ppu.bgpData.ptr[i + 1] = 0x7F;
+ }
+
+ std::memcpy(state.ppu.objpData.ptr, cgbObjpDump, sizeof(cgbObjpDump));
+
+ if (!cgb) {
+ state.ppu.bgpData.ptr[0] = state.mem.ioamhram.get()[0x147];
+ state.ppu.objpData.ptr[0] = state.mem.ioamhram.get()[0x148];
+ state.ppu.objpData.ptr[1] = state.mem.ioamhram.get()[0x149];
+ }
+
+ for (unsigned pos = 0; pos < 80; ++pos)
+ state.ppu.oamReaderBuf.ptr[pos] = state.mem.ioamhram.ptr[(pos * 2 & ~3) | (pos & 1)];
+
+ std::fill_n(state.ppu.oamReaderSzbuf.ptr, 40, false);
+ std::memset(state.ppu.spAttribList, 0, sizeof(state.ppu.spAttribList));
+ std::memset(state.ppu.spByte0List, 0, sizeof(state.ppu.spByte0List));
+ std::memset(state.ppu.spByte1List, 0, sizeof(state.ppu.spByte1List));
+ state.ppu.videoCycles = cgb ? 144 * 456ul + 164 : 153 * 456ul + 396;
+ state.ppu.enableDisplayM0Time = state.cpu.cycleCounter;
+ state.ppu.winYPos = 0xFF;
+ state.ppu.xpos = 0;
+ state.ppu.endx = 0;
+ state.ppu.reg0 = 0;
+ state.ppu.reg1 = 0;
+ state.ppu.tileword = 0;
+ state.ppu.ntileword = 0;
+ state.ppu.attrib = 0;
+ state.ppu.nattrib = 0;
+ state.ppu.state = 0;
+ state.ppu.nextSprite = 0;
+ state.ppu.currentSprite = 0;
+ state.ppu.lyc = state.mem.ioamhram.get()[0x145];
+ state.ppu.m0lyc = state.mem.ioamhram.get()[0x145];
+ state.ppu.weMaster = false;
+ state.ppu.winDrawState = 0;
+ state.ppu.wscx = 0;
+ state.ppu.lastM0Time = 1234;
+ state.ppu.nextM0Irq = 0;
+ state.ppu.oldWy = state.mem.ioamhram.get()[0x14A];
+ state.ppu.pendingLcdstatIrq = false;
+
+ state.spu.cycleCounter = 0x1000 | (state.cpu.cycleCounter >> 1 & 0xFFF); // spu.cycleCounter >> 12 & 7 represents the frame sequencer position.
+
+ state.spu.ch1.sweep.counter = SoundUnit::COUNTER_DISABLED;
+ state.spu.ch1.sweep.shadow = 0;
+ state.spu.ch1.sweep.nr0 = 0;
+ state.spu.ch1.sweep.negging = false;
+ state.spu.ch1.duty.nextPosUpdate = (state.spu.cycleCounter & ~1) + 2048 * 2;
+ state.spu.ch1.duty.nr3 = 0;
+ state.spu.ch1.duty.pos = 0;
+ state.spu.ch1.env.counter = SoundUnit::COUNTER_DISABLED;
+ state.spu.ch1.env.volume = 0;
+ state.spu.ch1.lcounter.counter = SoundUnit::COUNTER_DISABLED;
+ state.spu.ch1.lcounter.lengthCounter = 0x40;
+ state.spu.ch1.nr4 = 0;
+ state.spu.ch1.master = true;
+
+ state.spu.ch2.duty.nextPosUpdate = (state.spu.cycleCounter & ~1) + 2048 * 2;
+ state.spu.ch2.duty.nr3 = 0;
+ state.spu.ch2.duty.pos = 0;
+ state.spu.ch2.env.counter = state.spu.cycleCounter - ((state.spu.cycleCounter - 0x1000) & 0x7FFF) + 8ul * 0x8000;
+ state.spu.ch2.env.volume = 0;
+ state.spu.ch2.lcounter.counter = SoundUnit::COUNTER_DISABLED;
+ state.spu.ch2.lcounter.lengthCounter = 0x40;
+ state.spu.ch2.nr4 = 0;
+ state.spu.ch2.master = false;
+
+ for (unsigned i = 0; i < 0x10; ++i)
+ state.spu.ch3.waveRam.ptr[i] = state.mem.ioamhram.get()[0x130 + i];
+
+ state.spu.ch3.lcounter.counter = SoundUnit::COUNTER_DISABLED;
+ state.spu.ch3.lcounter.lengthCounter = 0x100;
+ state.spu.ch3.waveCounter = SoundUnit::COUNTER_DISABLED;
+ state.spu.ch3.lastReadTime = SoundUnit::COUNTER_DISABLED;
+ state.spu.ch3.nr3 = 0;
+ state.spu.ch3.nr4 = 0;
+ state.spu.ch3.wavePos = 0;
+ state.spu.ch3.sampleBuf = 0;
+ state.spu.ch3.master = false;
+
+ state.spu.ch4.lfsr.counter = state.spu.cycleCounter + 4;
+ state.spu.ch4.lfsr.reg = 0xFF;
+ state.spu.ch4.env.counter = state.spu.cycleCounter - ((state.spu.cycleCounter - 0x1000) & 0x7FFF) + 8ul * 0x8000;
+ state.spu.ch4.env.volume = 0;
+ state.spu.ch4.lcounter.counter = SoundUnit::COUNTER_DISABLED;
+ state.spu.ch4.lcounter.lengthCounter = 0x40;
+ state.spu.ch4.nr4 = 0;
+ state.spu.ch4.master = false;
+
+ state.rtc.baseTime = now;
+ state.rtc.haltTime = state.rtc.baseTime;
+ state.rtc.dataDh = 0;
+ state.rtc.dataDl = 0;
+ state.rtc.dataH = 0;
+ state.rtc.dataM = 0;
+ state.rtc.dataS = 0;
+ state.rtc.lastLatchData = false;
}
diff --git a/libgambatte/src/initstate.h b/libgambatte/src/initstate.h
index ec56fae045..8d8ed5aaf6 100644
--- a/libgambatte/src/initstate.h
+++ b/libgambatte/src/initstate.h
@@ -22,7 +22,7 @@
#include
namespace gambatte {
-void setInitState(struct SaveState &state, bool cgb, bool gbaCgbMode, std::uint32_t now, bool boot_bios);
+void setInitState(struct SaveState &state, bool cgb, bool gbaCgbMode, std::uint32_t now);
}
#endif
diff --git a/libgambatte/src/mem/cartridge.cpp b/libgambatte/src/mem/cartridge.cpp
index 34e6ea7408..abee7c2042 100644
--- a/libgambatte/src/mem/cartridge.cpp
+++ b/libgambatte/src/mem/cartridge.cpp
@@ -525,21 +525,7 @@ static unsigned pow2ceil(unsigned n) {
return n;
}
-void Cartridge::bios_remap(int setting) {
- // disable the BIOS if writing 1 or 0x22 (GBC)
- if (setting == 1 || setting == 0x11) {
- std::memcpy(memptrs.romdata(), memptrs.notbiosdata_, loc_bios_length);
- using_bios = false;
- }
-
- // we'll also use it to reset to BIOS on reset
- if (setting == 0) {
- std::memcpy(memptrs.romdata(), memptrs.biosdata_, loc_bios_length);
- using_bios = true;
- }
-}
-
-int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, const bool forceDmg, const bool multicartCompat) {
+int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) {
//const std::auto_ptr rom(newFileInstance(romfile));
//if (rom->fail())
@@ -642,9 +628,6 @@ int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const ch
mbc.reset();
- use_bios = biosfilelength > 0 ? true : false;
- loc_bios_length = biosfilelength;
-
memptrs.reset(rombanks, rambanks, cgb ? 8 : 2);
rtc.set(false, 0);
@@ -655,26 +638,6 @@ int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const ch
std::memset(memptrs.romdata() + (filesize / 0x4000) * 0x4000ul, 0xFF, (rombanks - filesize / 0x4000) * 0x4000ul);
enforce8bit(memptrs.romdata(), rombanks * 0x4000ul);
- //we want to copy in the bios data only if it exists
- if (use_bios) {
- using_bios = true;
- memptrs.use_bios = true;
-
- memptrs.biosdata_ = new unsigned char[biosfilelength];
- memptrs.notbiosdata_ = new unsigned char[biosfilelength];
-
- std::memcpy(memptrs.biosdata_, biosfiledata, biosfilelength);
- std::memcpy(memptrs.notbiosdata_, romfiledata, biosfilelength);
-
- //if using GBC, the header is not overwritten by the BIOS
- if (biosfilelength > 256) {
- std::memcpy(memptrs.biosdata_ + 256, memptrs.notbiosdata_ + 256, 256);
- }
-
-
- std::memcpy(memptrs.romdata(), memptrs.biosdata_, biosfilelength);
- }
-
//if (rom->fail())
// return -1;
@@ -785,14 +748,6 @@ SYNCFUNC(Cartridge)
SSS(memptrs);
SSS(rtc);
TSS(mbc);
- NSS(using_bios);
-
- if (using_bios) {
- bios_remap(0);
- }
- else {
- bios_remap(1);
- }
}
}
diff --git a/libgambatte/src/mem/cartridge.h b/libgambatte/src/mem/cartridge.h
index c3a3d7ce27..0015924966 100644
--- a/libgambatte/src/mem/cartridge.h
+++ b/libgambatte/src/mem/cartridge.h
@@ -67,10 +67,6 @@ public:
void setStatePtrs(SaveState &);
void loadState(const SaveState &);
- bool use_bios;
- bool using_bios;
- unsigned loc_bios_length;
-
bool loaded() const { return mbc.get(); }
const unsigned char * rmem(unsigned area) const { return memptrs.rmem(area); }
@@ -101,15 +97,13 @@ public:
bool getMemoryArea(int which, unsigned char **data, int *length) const;
- int loadROM(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, bool forceDmg, bool multicartCompat);
+ int loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
const char * romTitle() const { return reinterpret_cast(memptrs.romdata() + 0x134); }
void setRTCCallback(std::uint32_t (*callback)()) {
rtc.setRTCCallback(callback);
}
- void bios_remap(int setting);
-
templatevoid SyncState(NewState *ns);
};
diff --git a/libgambatte/src/mem/memptrs.cpp b/libgambatte/src/mem/memptrs.cpp
index 4ddf5e0149..1b0399770a 100644
--- a/libgambatte/src/mem/memptrs.cpp
+++ b/libgambatte/src/mem/memptrs.cpp
@@ -31,11 +31,6 @@ MemPtrs::MemPtrs()
MemPtrs::~MemPtrs() {
delete []memchunk_;
- if (use_bios)
- {
- delete[]biosdata_;
- delete[]notbiosdata_;
- }
}
void MemPtrs::reset(const unsigned rombanks, const unsigned rambanks, const unsigned wrambanks) {
@@ -226,10 +221,6 @@ SYNCFUNC(MemPtrs)
MSS(rambankdata_);
MSS(wramdataend_);
NSS(oamDmaSrc_);
-
- NSS(biosdata_);
- NSS(notbiosdata_);
- NSS(use_bios);
}
}
diff --git a/libgambatte/src/mem/memptrs.h b/libgambatte/src/mem/memptrs.h
index 3c63670907..5e4f772a26 100644
--- a/libgambatte/src/mem/memptrs.h
+++ b/libgambatte/src/mem/memptrs.h
@@ -51,10 +51,6 @@ class MemPtrs {
unsigned char * rdisabledRamw() const { return wramdataend_ ; }
unsigned char * wdisabledRam() const { return wramdataend_ + 0x2000; }
public:
- unsigned char *biosdata_;
- unsigned char *notbiosdata_;
- bool use_bios;
-
enum RamFlag { READ_EN = 1, WRITE_EN = 2, RTC_EN = 4 };
MemPtrs();
diff --git a/libgambatte/src/memory.cpp b/libgambatte/src/memory.cpp
index 548e6705d2..0a52eb6686 100644
--- a/libgambatte/src/memory.cpp
+++ b/libgambatte/src/memory.cpp
@@ -875,7 +875,6 @@ void Memory::nontrivial_ff_write(const unsigned P, unsigned data, const unsigned
case 0x50:
// this is the register that turns off the bootrom
// it can only ever be written to once (with 1) once boot rom finishes
- cart.bios_remap(data);
return;
case 0x51:
dmaSource = data << 8 | (dmaSource & 0xFF);
@@ -1016,8 +1015,8 @@ void Memory::nontrivial_write(const unsigned P, const unsigned data, const unsig
ioamhram[P - 0xFE00] = data;
}
-int Memory::loadROM(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, const bool forceDmg, const bool multicartCompat) {
- if (const int fail = cart.loadROM(romfiledata, romfilelength, biosfiledata, biosfilelength, forceDmg, multicartCompat))
+int Memory::loadROM(const char *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) {
+ if (const int fail = cart.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat))
return fail;
sound.init(cart.isCgb());
diff --git a/libgambatte/src/memory.h b/libgambatte/src/memory.h
index 3bfe8675c0..9ea65bf4a1 100644
--- a/libgambatte/src/memory.h
+++ b/libgambatte/src/memory.h
@@ -88,10 +88,6 @@ public:
bool loaded() const { return cart.loaded(); }
const char * romTitle() const { return cart.romTitle(); }
- void bios_reset(int setting) {
- nontrivial_ff_write(0x50, setting, 0);
- }
-
int debugGetLY() const { return display.debugGetLY(); }
void setStatePtrs(SaveState &state);
@@ -249,7 +245,7 @@ public:
unsigned long event(unsigned long cycleCounter);
unsigned long resetCounters(unsigned long cycleCounter);
- int loadROM(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, bool forceDmg, bool multicartCompat);
+ int loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
void setInputGetter(unsigned (*getInput)()) {
this->getInput = getInput;
diff --git a/libgambatte/src/savestate.h b/libgambatte/src/savestate.h
index be3f21322a..4110161ca0 100644
--- a/libgambatte/src/savestate.h
+++ b/libgambatte/src/savestate.h
@@ -38,7 +38,7 @@ struct SaveState {
void set(T *ptr, const unsigned long sz) { this->ptr = ptr; this->sz = sz; }
friend class SaverList;
- friend void setInitState(SaveState &, bool, bool, std::uint32_t, bool);
+ friend void setInitState(SaveState &, bool, bool, std::uint32_t);
};
struct CPU {
@@ -78,7 +78,6 @@ struct SaveState {
bool enableRam;
bool rambankMode;
bool hdmaTransfer;
- bool using_bios;
} mem;
struct PPU {
diff --git a/output/dll/libgambatte.dll b/output/dll/libgambatte.dll
index 4bf168c395..17abbf85e0 100644
Binary files a/output/dll/libgambatte.dll and b/output/dll/libgambatte.dll differ