Merge branch 'master' of https://github.com/TASVideos/BizHawk.git
This commit is contained in:
commit
de00fbaf19
|
@ -9,8 +9,14 @@
|
|||
means that we lower the priority of a state that goes at that index. Priority changes
|
||||
depending on current frame and amount of states. States with biggest priority get erased
|
||||
first. With a 4-bit battern and no initial gap between states, total frame coverage is
|
||||
about 5 times state count. Initial state gap can screw up our patterns, so do all
|
||||
calculations like gap isn't there, and take it back into account afterwards.
|
||||
about 5 times state count.
|
||||
|
||||
Initial state gap can screw up our patterns, so do all the calculations like the gap
|
||||
isn't there, and take it back into account afterwards. The algo only works with integral
|
||||
greenzone, so we make it think it is integral by reducing the frame numbers. Before any
|
||||
decay logic starts for each state, we check if it has a marker on it (in which case we
|
||||
don't drop it) or appears inside the state gap (in which case we forcibly drop it). This
|
||||
step doesn't involve numbers reduction.
|
||||
|
||||
_zeros values are essentialy the values of rshiftby here:
|
||||
bitwise view frame rshiftby priority
|
||||
|
@ -59,7 +65,7 @@ namespace BizHawk.Client.Common
|
|||
for (; decayStates > 0 && _tsm.StateCount > 1;)
|
||||
{
|
||||
int baseStateIndex = _tsm.GetStateIndexByFrame(Global.Emulator.Frame);
|
||||
int baseStateFrame = _tsm.GetStateFrameByIndex(baseStateIndex) / _step;
|
||||
int baseStateFrame = _tsm.GetStateFrameByIndex(baseStateIndex) / _step; // reduce right away
|
||||
int forwardPriority = -1000000;
|
||||
int backwardPriority = -1000000;
|
||||
int forwardFrame = -1;
|
||||
|
@ -76,14 +82,18 @@ namespace BizHawk.Client.Common
|
|||
else if (currentFrame % _step > 0)
|
||||
{
|
||||
// ignore the pattern if the state doesn't belong already, drop it blindly and skip everything
|
||||
_tsm.RemoveState(currentFrame);
|
||||
decayStates--;
|
||||
if (_tsm.RemoveState(currentFrame))
|
||||
{
|
||||
// decrementing this if no state was removed is BAD
|
||||
decayStates--;
|
||||
|
||||
// this is the kind of highly complex loops that might justify goto
|
||||
goto next_state;
|
||||
// this is the kind of highly complex loops that might justify goto
|
||||
goto next_state;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// reduce to imaginary integral greenzone for all the decay logic
|
||||
currentFrame /= _step;
|
||||
}
|
||||
|
||||
|
@ -104,7 +114,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
for (int currentStateIndex = _tsm.StateCount - 1; currentStateIndex > baseStateIndex; currentStateIndex--)
|
||||
{
|
||||
int currentFrame = _tsm.GetStateFrameByIndex(currentStateIndex) / _step;
|
||||
int currentFrame = _tsm.GetStateFrameByIndex(currentStateIndex);
|
||||
|
||||
if (_tsm.StateIsMarker(currentFrame))
|
||||
{
|
||||
|
@ -113,14 +123,18 @@ namespace BizHawk.Client.Common
|
|||
else if (currentFrame % _step > 0)
|
||||
{
|
||||
// ignore the pattern if the state doesn't belong already, drop it blindly and skip everything
|
||||
_tsm.RemoveState(currentFrame);
|
||||
decayStates--;
|
||||
if (_tsm.RemoveState(currentFrame))
|
||||
{
|
||||
// decrementing this if no state was removed is BAD
|
||||
decayStates--;
|
||||
|
||||
// this is the kind of highly complex loops that might justify goto
|
||||
goto next_state;
|
||||
// this is the kind of highly complex loops that might justify goto
|
||||
goto next_state;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// reduce to imaginary integral greenzone for all the decay logic
|
||||
currentFrame /= _step;
|
||||
}
|
||||
|
||||
|
@ -143,30 +157,46 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
if (baseStateFrame - forwardFrame > backwardFrame - baseStateFrame)
|
||||
{
|
||||
_tsm.RemoveState(forwardFrame * _step);
|
||||
if (_tsm.RemoveState(forwardFrame * _step))
|
||||
{
|
||||
// decrementing this if no state was removed is BAD
|
||||
decayStates--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_tsm.RemoveState(backwardFrame * _step);
|
||||
if (_tsm.RemoveState(backwardFrame * _step))
|
||||
{
|
||||
// decrementing this if no state was removed is BAD
|
||||
decayStates--;
|
||||
}
|
||||
}
|
||||
|
||||
decayStates--;
|
||||
}
|
||||
else if (forwardFrame > -1)
|
||||
{
|
||||
_tsm.RemoveState(forwardFrame * _step);
|
||||
decayStates--;
|
||||
if (_tsm.RemoveState(forwardFrame * _step))
|
||||
{
|
||||
// decrementing this if no state was removed is BAD
|
||||
decayStates--;
|
||||
}
|
||||
}
|
||||
else if (backwardFrame > -1)
|
||||
{
|
||||
_tsm.RemoveState(backwardFrame * _step);
|
||||
decayStates--;
|
||||
if (_tsm.RemoveState(backwardFrame * _step))
|
||||
{
|
||||
// decrementing this if no state was removed is BAD
|
||||
decayStates--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we're very sorry about failing to find states to remove, but we can't go beyond capacity, so remove at least something
|
||||
// this shouldn't happen, but if we don't do it here, nothing good will happen either
|
||||
_tsm.RemoveState(_tsm.GetStateFrameByIndex(1));
|
||||
if (_tsm.RemoveState(_tsm.GetStateFrameByIndex(1)))
|
||||
{
|
||||
// decrementing this if no state was removed is BAD
|
||||
decayStates--;
|
||||
}
|
||||
}
|
||||
|
||||
// this is the kind of highly complex loops that might justify goto
|
||||
|
|
|
@ -262,13 +262,13 @@ namespace BizHawk.Client.Common
|
|||
return _movie.Markers.IsMarker(frame + 1);
|
||||
}
|
||||
|
||||
public void RemoveState(int frame)
|
||||
public bool RemoveState(int frame)
|
||||
{
|
||||
int index = _states.IndexOfKey(frame);
|
||||
|
||||
if (frame < 1 || index < 1)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
StateManagerState state = _states.Values[index];
|
||||
|
@ -283,6 +283,8 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
_states.RemoveAt(index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -4,8 +4,8 @@ namespace BizHawk.Emulation.Common.Components.LR35902
|
|||
{
|
||||
public partial class LR35902
|
||||
{
|
||||
private int totalExecutedCycles;
|
||||
public int TotalExecutedCycles { get { return totalExecutedCycles; } set { totalExecutedCycles = value; } }
|
||||
private ulong totalExecutedCycles;
|
||||
public ulong TotalExecutedCycles { get { return totalExecutedCycles; } set { totalExecutedCycles = value; } }
|
||||
|
||||
private int EI_pending;
|
||||
private bool interrupts_enabled;
|
||||
|
|
|
@ -295,7 +295,8 @@ namespace BizHawk.Emulation.Common.Components.LR35902
|
|||
// call the interrupt processor after 4 extra cycles
|
||||
if (!Halt_bug_3)
|
||||
{
|
||||
INTERRUPT_GBC_NOP();
|
||||
INTERRUPT_GBC_NOP();
|
||||
//INTERRUPT_();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -58,9 +58,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
public override byte ReadReg(int addr)
|
||||
{
|
||||
byte ret = 0;
|
||||
|
||||
//Console.WriteLine(Core.cpu.TotalExecutedCycles);
|
||||
switch (addr)
|
||||
{
|
||||
{
|
||||
case 0xFF40: ret = LCDC; break; // LCDC
|
||||
case 0xFF41: ret = STAT; break; // STAT
|
||||
case 0xFF42: ret = scroll_y; break; // SCY
|
||||
|
@ -350,7 +350,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
cycle = 0;
|
||||
LY_actual = LY;
|
||||
LY += LY_inc;
|
||||
Core.cpu.LY = LY;
|
||||
// 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;
|
||||
STAT &= 0xFB;
|
||||
}
|
||||
|
||||
no_scan = false;
|
||||
|
||||
|
@ -359,6 +366,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
LY_inc = 1;
|
||||
Core.in_vblank = false;
|
||||
|
||||
/*
|
||||
VBL_INT = false;
|
||||
if (STAT.Bit(3)) { HBL_INT = true; }
|
||||
|
||||
STAT &= 0xFC;
|
||||
*/
|
||||
// special note here, the y coordiate of the window is kept if the window is deactivated
|
||||
// meaning it will pick up where it left off if re-enabled later
|
||||
// so we don't reset it in the scanline loop
|
||||
|
@ -368,8 +381,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
window_is_reset = true;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -381,34 +392,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
}
|
||||
|
||||
if (cycle == 452)
|
||||
{
|
||||
LY += LY_inc;
|
||||
|
||||
// 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;
|
||||
STAT &= 0xFB;
|
||||
}
|
||||
else
|
||||
{
|
||||
VBL_INT = false;
|
||||
if (STAT.Bit(3)) { HBL_INT = true; }
|
||||
|
||||
STAT &= 0xFC;
|
||||
}
|
||||
|
||||
Core.cpu.LY = LY;
|
||||
}
|
||||
|
||||
if ((LY == 153) && (cycle == 0))
|
||||
{
|
||||
LY = 0;
|
||||
LY_inc = 0;
|
||||
|
||||
}
|
||||
|
||||
// exit vblank if LCD went from off to on
|
||||
if (LCD_was_off)
|
||||
{
|
||||
|
@ -424,25 +407,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
// also, the LCD does not enter mode 2 on scanline 0 when first turned on
|
||||
no_scan = true;
|
||||
cycle = 4;
|
||||
cycle = 8;
|
||||
}
|
||||
|
||||
// the VBL stat is continuously asserted
|
||||
if ((LY_actual >= 144))
|
||||
if ((LY >= 144))
|
||||
{
|
||||
if (STAT.Bit(4))
|
||||
{
|
||||
if ((cycle >= 0) && (LY_actual == 144))
|
||||
if ((cycle >= 4) && (LY == 144))
|
||||
{
|
||||
VBL_INT = true;
|
||||
}
|
||||
else if (LY_actual > 144)
|
||||
else if (LY > 144)
|
||||
{
|
||||
VBL_INT = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((cycle == 0) && (LY_actual == 144)) {
|
||||
if ((cycle == 4) && (LY == 144)) {
|
||||
|
||||
HBL_INT = false;
|
||||
|
||||
|
@ -454,15 +437,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
Core.REG_FF0F |= 0x01;
|
||||
}
|
||||
|
||||
if ((LY_actual >= 144) && (cycle == 0))
|
||||
if ((LY >= 144) && (cycle == 4))
|
||||
{
|
||||
// a special case of OAM mode 2 IRQ assertion, even though PPU Mode still is 1
|
||||
if (STAT.Bit(5)) { OAM_INT = true; }
|
||||
//if (STAT.Bit(5)) { OAM_INT = true; }
|
||||
}
|
||||
|
||||
if ((LY_actual == 153) && (cycle == 4))
|
||||
if ((LY == 153) && (cycle == 8))
|
||||
{
|
||||
LY_actual = 0;
|
||||
LY = 0;
|
||||
LY_inc = 0;
|
||||
Core.cpu.LY = LY;
|
||||
}
|
||||
}
|
||||
|
@ -475,7 +459,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
// there is no mode 2 (presumably it missed the trigger)
|
||||
// mode 3 is very short, probably in some self test mode before turning on?
|
||||
|
||||
if (cycle == 4)
|
||||
if (cycle == 8)
|
||||
{
|
||||
if (LY != LYC)
|
||||
{
|
||||
|
@ -491,9 +475,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
}
|
||||
|
||||
if (cycle == 80)
|
||||
if (cycle == 84)
|
||||
{
|
||||
|
||||
STAT &= 0xFC;
|
||||
STAT |= 0x03;
|
||||
OAM_INT = false;
|
||||
|
@ -504,7 +487,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
VRAM_access_write = false;
|
||||
}
|
||||
|
||||
if (cycle == 252)
|
||||
if (cycle == 256)
|
||||
{
|
||||
STAT &= 0xFC;
|
||||
OAM_INT = false;
|
||||
|
@ -519,9 +502,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
if (cycle < 76)
|
||||
if (cycle < 80)
|
||||
{
|
||||
if (cycle == 0)
|
||||
if (cycle == 4)
|
||||
{
|
||||
// apparently, writes can make it to OAM one cycle longer then reads
|
||||
OAM_access_write = false;
|
||||
|
@ -529,24 +512,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
// here mode 2 will be set to true and interrupts fired if enabled
|
||||
STAT &= 0xFC;
|
||||
STAT |= 0x2;
|
||||
|
||||
if (STAT.Bit(5)) { OAM_INT = true; }
|
||||
|
||||
HBL_INT = false;
|
||||
// DMG exits VBlank into mode 0, but not GBC, so this line is needed
|
||||
// (This is important for Wacky Racers and Altered Space)
|
||||
VBL_INT = false;
|
||||
}
|
||||
|
||||
// here OAM scanning is performed
|
||||
OAM_scan(cycle + 4);
|
||||
OAM_scan(cycle);
|
||||
}
|
||||
else if (cycle >= 76 && LY_actual < 144)
|
||||
else if ((cycle >= 80) && (LY < 144))
|
||||
{
|
||||
if (cycle == 76)
|
||||
{
|
||||
OAM_access_read = false;
|
||||
OAM_access_write = true;
|
||||
VRAM_access_read = false;
|
||||
}
|
||||
|
||||
if (cycle == 80)
|
||||
if (cycle == 84)
|
||||
{
|
||||
STAT &= 0xFC;
|
||||
STAT |= 0x03;
|
||||
|
@ -556,20 +537,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
// render the screen and handle hblank
|
||||
render(cycle - 76);
|
||||
render(cycle - 80);
|
||||
}
|
||||
}
|
||||
|
||||
if (cycle >= 452)
|
||||
{
|
||||
OAM_access_read = false;
|
||||
OAM_scan(cycle - 452);
|
||||
}
|
||||
}
|
||||
|
||||
if ((LY_inc == 0))
|
||||
{
|
||||
if (cycle == 8)
|
||||
if (cycle == 12)
|
||||
{
|
||||
LYC_INT = false;
|
||||
STAT &= 0xFB;
|
||||
|
@ -583,14 +558,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
// also a special case of OAM mode 2 IRQ assertion, even though PPU Mode still is 1
|
||||
if (STAT.Bit(5)) { OAM_INT = true; }
|
||||
//if (STAT.Bit(5)) { OAM_INT = true; }
|
||||
}
|
||||
|
||||
if (cycle == 88) { OAM_INT = false; }
|
||||
//if (cycle == 92) { OAM_INT = false; }
|
||||
}
|
||||
|
||||
// here LY=LYC will be asserted
|
||||
if ((cycle == 0) && (LY_actual != 0))
|
||||
if ((cycle == 4) && (LY != 0))
|
||||
{
|
||||
if ((LY == LYC) && !STAT.Bit(2))
|
||||
{
|
||||
|
@ -613,7 +588,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
LCD_was_off = true;
|
||||
|
||||
LY = 0;
|
||||
LY_actual = 0;
|
||||
Core.cpu.LY = LY;
|
||||
|
||||
cycle = 0;
|
||||
|
@ -647,6 +621,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
// i.e. just keeping track of the lowest x-value sprite
|
||||
if (render_cycle == 0)
|
||||
{
|
||||
OAM_access_read = false;
|
||||
OAM_access_write = true;
|
||||
VRAM_access_read = false;
|
||||
|
||||
// window X is latched for the scanline, mid-line changes have no effect
|
||||
window_x_latch = window_x;
|
||||
|
||||
|
@ -847,6 +825,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
{
|
||||
read_case = 8;
|
||||
hbl_countdown = 5;
|
||||
if (window_started)
|
||||
{
|
||||
hbl_countdown -= 2;
|
||||
}
|
||||
}
|
||||
if (pixel_counter == 158 && window_started)
|
||||
{
|
||||
STAT &= 0xFC;
|
||||
STAT |= 0x00;
|
||||
|
||||
if (STAT.Bit(3)) { HBL_INT = true; }
|
||||
}
|
||||
}
|
||||
else if ((render_counter >= render_offset) && (pixel_counter < 0))
|
||||
|
@ -1411,6 +1400,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
// TODO: maybe stat mode 2 flags are set at cycle 0 on visible scanlines?
|
||||
if (OAM_cycle == 0)
|
||||
{
|
||||
OAM_access_read = false;
|
||||
|
||||
OAM_scan_index = 0;
|
||||
SL_sprites_index = 0;
|
||||
write_sprite = 0;
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
public int TotalExecutedCycles
|
||||
{
|
||||
get { return cpu.TotalExecutedCycles; }
|
||||
get { return (int)cpu.TotalExecutedCycles; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
x_tile = (int)Math.Floor((float)(scroll_x) / 8);
|
||||
break;
|
||||
case 0xFF44: // LY
|
||||
LY = LY_actual = 0; /*reset*/
|
||||
LY = 0; /*reset*/
|
||||
break;
|
||||
case 0xFF45: // LYC
|
||||
LYC = value;
|
||||
|
@ -125,7 +125,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
cycle = 0;
|
||||
LY_actual = LY;
|
||||
|
||||
LY += LY_inc;
|
||||
Core.cpu.LY = LY;
|
||||
// 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;
|
||||
STAT &= 0xFB;
|
||||
}
|
||||
|
||||
no_scan = false;
|
||||
|
||||
|
@ -134,6 +142,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
LY_inc = 1;
|
||||
Core.in_vblank = false;
|
||||
|
||||
VBL_INT = false;
|
||||
if (STAT.Bit(3)) { HBL_INT = true; }
|
||||
|
||||
STAT &= 0xFC;
|
||||
|
||||
// special note here, the y coordiate of the window is kept if the window is deactivated
|
||||
// meaning it will pick up where it left off if re-enabled later
|
||||
// so we don't reset it in the scanline loop
|
||||
|
@ -154,34 +167,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
}
|
||||
|
||||
if (cycle == 452)
|
||||
{
|
||||
LY += LY_inc;
|
||||
|
||||
// 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;
|
||||
STAT &= 0xFB;
|
||||
}
|
||||
else
|
||||
{
|
||||
VBL_INT = false;
|
||||
if (STAT.Bit(3)) { HBL_INT = true; }
|
||||
|
||||
STAT &= 0xFC;
|
||||
}
|
||||
|
||||
Core.cpu.LY = LY;
|
||||
}
|
||||
|
||||
if ((LY == 153) && (cycle == 0))
|
||||
{
|
||||
LY = 0;
|
||||
LY_inc = 0;
|
||||
|
||||
}
|
||||
|
||||
// exit vblank if LCD went from off to on
|
||||
if (LCD_was_off)
|
||||
{
|
||||
|
@ -197,25 +182,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
// also, the LCD does not enter mode 2 on scanline 0 when first turned on
|
||||
no_scan = true;
|
||||
cycle = 4;
|
||||
cycle = 8;
|
||||
}
|
||||
|
||||
// the VBL stat is continuously asserted
|
||||
if ((LY_actual >= 144))
|
||||
if ((LY >= 144))
|
||||
{
|
||||
if (STAT.Bit(4))
|
||||
{
|
||||
if ((cycle >= 0) && (LY_actual == 144))
|
||||
if ((cycle >= 4) && (LY == 144))
|
||||
{
|
||||
VBL_INT = true;
|
||||
}
|
||||
else if (LY_actual > 144)
|
||||
else if (LY > 144)
|
||||
{
|
||||
VBL_INT = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((cycle == 0) && (LY_actual == 144)) {
|
||||
if ((cycle == 4) && (LY == 144)) {
|
||||
|
||||
HBL_INT = false;
|
||||
|
||||
|
@ -227,15 +212,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
Core.REG_FF0F |= 0x01;
|
||||
}
|
||||
|
||||
if ((LY_actual >= 144) && (cycle == 0))
|
||||
if ((LY >= 144) && (cycle == 4))
|
||||
{
|
||||
// a special case of OAM mode 2 IRQ assertion, even though PPU Mode still is 1
|
||||
if (STAT.Bit(5)) { OAM_INT = true; }
|
||||
}
|
||||
|
||||
if ((LY_actual == 153) && (cycle == 4))
|
||||
if ((LY == 153) && (cycle == 8))
|
||||
{
|
||||
LY_actual = 0;
|
||||
LY = 0;
|
||||
LY_inc = 0;
|
||||
Core.cpu.LY = LY;
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +234,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
// there is no mode 2 (presumably it missed the trigger)
|
||||
// mode 3 is very short, probably in some self test mode before turning on?
|
||||
|
||||
if (cycle == 4)
|
||||
if (cycle == 8)
|
||||
{
|
||||
if (LY != LYC)
|
||||
{
|
||||
|
@ -264,7 +250,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
}
|
||||
|
||||
if (cycle == 80)
|
||||
if (cycle == 84)
|
||||
{
|
||||
|
||||
STAT &= 0xFC;
|
||||
|
@ -277,7 +263,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
VRAM_access_write = false;
|
||||
}
|
||||
|
||||
if (cycle == 252)
|
||||
if (cycle == 256)
|
||||
{
|
||||
STAT &= 0xFC;
|
||||
OAM_INT = false;
|
||||
|
@ -292,9 +278,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
if (cycle < 76)
|
||||
if (cycle < 80)
|
||||
{
|
||||
if (cycle == 0)
|
||||
if (cycle == 4)
|
||||
{
|
||||
// apparently, writes can make it to OAM one cycle longer then reads
|
||||
OAM_access_write = false;
|
||||
|
@ -308,18 +294,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
// here OAM scanning is performed
|
||||
OAM_scan(cycle + 4);
|
||||
OAM_scan(cycle);
|
||||
}
|
||||
else if ((cycle >= 76) && (LY_actual < 144))
|
||||
else if ((cycle >= 80) && (LY < 144))
|
||||
{
|
||||
if (cycle == 76)
|
||||
{
|
||||
OAM_access_read = false;
|
||||
OAM_access_write = true;
|
||||
VRAM_access_read = false;
|
||||
}
|
||||
|
||||
if (cycle == 80)
|
||||
if (cycle == 84)
|
||||
{
|
||||
STAT &= 0xFC;
|
||||
STAT |= 0x03;
|
||||
|
@ -329,20 +308,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
// render the screen and handle hblank
|
||||
render(cycle - 76);
|
||||
render(cycle - 80);
|
||||
}
|
||||
}
|
||||
|
||||
if (cycle >= 452)
|
||||
{
|
||||
if (LY != 144) { OAM_access_read = false; }
|
||||
OAM_scan(cycle - 452);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((LY_inc == 0))
|
||||
{
|
||||
if (cycle == 8)
|
||||
if (cycle == 12)
|
||||
{
|
||||
LYC_INT = false;
|
||||
STAT &= 0xFB;
|
||||
|
@ -359,11 +332,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
if (STAT.Bit(5)) { OAM_INT = true; }
|
||||
}
|
||||
|
||||
if (cycle == 88) { OAM_INT = false; }
|
||||
if (cycle == 92) { OAM_INT = false; }
|
||||
}
|
||||
|
||||
// here LY=LYC will be asserted
|
||||
if ((cycle == 0) && (LY_actual != 0))
|
||||
if ((cycle == 4) && (LY != 0))
|
||||
{
|
||||
if ((LY == LYC) && !STAT.Bit(2))
|
||||
{
|
||||
|
@ -386,7 +359,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
LCD_was_off = true;
|
||||
|
||||
LY = 0;
|
||||
LY_actual = 0;
|
||||
Core.cpu.LY = LY;
|
||||
|
||||
cycle = 0;
|
||||
|
@ -420,6 +392,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
// i.e. just keeping track of the lowest x-value sprite
|
||||
if (render_cycle == 0)
|
||||
{
|
||||
OAM_access_read = false;
|
||||
OAM_access_write = true;
|
||||
VRAM_access_read = false;
|
||||
|
||||
// window X is latched for the scanline, mid-line changes have no effect
|
||||
window_x_latch = window_x;
|
||||
|
||||
|
@ -924,14 +900,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
{
|
||||
if (LCDC.Bit(2))
|
||||
{
|
||||
y = LY_actual - (SL_sprites[sl_use_index * 4] - 16);
|
||||
y = LY - (SL_sprites[sl_use_index * 4] - 16);
|
||||
y = 15 - y;
|
||||
sprite_sel[0] = Core.VRAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2];
|
||||
sprite_sel[1] = Core.VRAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2 + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
y = LY_actual - (SL_sprites[sl_use_index * 4] - 16);
|
||||
y = LY - (SL_sprites[sl_use_index * 4] - 16);
|
||||
y = 7 - y;
|
||||
sprite_sel[0] = Core.VRAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2];
|
||||
sprite_sel[1] = Core.VRAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2 + 1];
|
||||
|
@ -941,13 +917,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
{
|
||||
if (LCDC.Bit(2))
|
||||
{
|
||||
y = LY_actual - (SL_sprites[sl_use_index * 4] - 16);
|
||||
y = LY - (SL_sprites[sl_use_index * 4] - 16);
|
||||
sprite_sel[0] = Core.VRAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2];
|
||||
sprite_sel[1] = Core.VRAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2 + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
y = LY_actual - (SL_sprites[sl_use_index * 4] - 16);
|
||||
y = LY - (SL_sprites[sl_use_index * 4] - 16);
|
||||
sprite_sel[0] = Core.VRAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2];
|
||||
sprite_sel[1] = Core.VRAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2 + 1];
|
||||
}
|
||||
|
@ -1085,6 +1061,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
// TODO: maybe stat mode 2 flags are set at cycle 0 on visible scanlines?
|
||||
if (OAM_cycle == 0)
|
||||
{
|
||||
OAM_access_read = false;
|
||||
|
||||
OAM_scan_index = 0;
|
||||
SL_sprites_index = 0;
|
||||
write_sprite = 0;
|
||||
|
|
Loading…
Reference in New Issue