GBHawk: Bug Fixes
This commit is contained in:
parent
f494b58f3b
commit
0e028a2284
|
@ -12,11 +12,9 @@ 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;
|
||||
bool contr_check_once;
|
||||
|
||||
public void FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
|
@ -57,7 +55,43 @@ 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;
|
||||
contr_check_once = true;
|
||||
|
||||
// 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();
|
||||
|
@ -69,43 +103,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
timer.tick_2();
|
||||
|
||||
// check for controller interrupts somewhere around the middle of the frame
|
||||
if ((cpu.LY == 50) && contr_check_once)
|
||||
{
|
||||
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 & 2) > 0) && ((input_register & 1) == 0))
|
||||
{
|
||||
if (REG_FFFF.Bit(4)) { cpu.FlagI = true; }
|
||||
REG_FF0F |= 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (in_vblank && !in_vblank_old)
|
||||
{
|
||||
vblank_rise = true;
|
||||
|
@ -126,15 +123,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 int Frame => _frame;
|
||||
|
|
|
@ -62,7 +62,6 @@ 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);
|
||||
|
|
|
@ -16,26 +16,6 @@ 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) == 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;
|
||||
}
|
||||
ret = input_register;
|
||||
break;
|
||||
|
||||
|
@ -143,7 +123,42 @@ 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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -428,8 +428,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;
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
public byte ReadReg(int addr)
|
||||
{
|
||||
byte ret = 0;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0xFF01:
|
||||
|
@ -29,7 +27,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
return serial_control;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0xFF;
|
||||
|
||||
}
|
||||
|
||||
public void WriteReg(int addr, byte value)
|
||||
|
@ -58,6 +57,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
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;
|
||||
|
@ -69,7 +83,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
{
|
||||
if (serial_start)
|
||||
{
|
||||
serial_clock--;
|
||||
if (serial_clock > 0) { serial_clock--; }
|
||||
if (serial_clock == 0)
|
||||
{
|
||||
if (serial_bits > 0)
|
||||
|
@ -98,10 +112,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
// call this function to get the clock rate of a connected device
|
||||
// internal rate is 512
|
||||
// if no external device, the clocking doesn't occur
|
||||
public int get_external_clock()
|
||||
{
|
||||
return 512;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// call this function to get the next bit from the connected device
|
||||
|
@ -120,7 +134,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
{
|
||||
serial_control = 0x7E;
|
||||
serial_start = false;
|
||||
serial_data = 0xFF;
|
||||
serial_data = 0x00;
|
||||
}
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
|
|
Loading…
Reference in New Issue