GBHawk: FiX serial port emulation (somewhat) and cleanup some minor bugs
This commit is contained in:
parent
60da770532
commit
7ebc3a3058
|
@ -21,8 +21,8 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
|||
DEC16, SPl, SPh,
|
||||
INT_GET, 1, W,
|
||||
WR, SPl, SPh, PCl,
|
||||
IRQ_CLEAR,
|
||||
IDLE,
|
||||
IRQ_CLEAR,
|
||||
TR, PCl, W,
|
||||
OP };
|
||||
}
|
||||
|
@ -50,8 +50,8 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
|||
DEC16, SPl, SPh,
|
||||
INT_GET, 1, W,
|
||||
WR, SPl, SPh, PCl,
|
||||
IRQ_CLEAR,
|
||||
IDLE,
|
||||
IRQ_CLEAR,
|
||||
TR, PCl, W,
|
||||
OP };
|
||||
}
|
||||
|
|
|
@ -600,7 +600,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
|||
// interrupt src = 5 sets the PC to zero as observed
|
||||
// also the triggering interrupt seems like it is held low (i.e. cannot trigger I flag) until the interrupt is serviced
|
||||
ushort bit_check = instr_table[instr_pntr++];
|
||||
//Console.WriteLine(interrupt_src + " " + interrupt_enable + " " + TotalExecutedCycles);
|
||||
//Console.WriteLine("int " + TotalExecutedCycles);
|
||||
|
||||
interrupt_src_reg = GetIntRegs(0);
|
||||
interrupt_enable_reg = GetIntRegs(1);
|
||||
|
|
|
@ -20,5 +20,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
public void Step(StepType type) => throw new NotImplementedException();
|
||||
|
||||
public long TotalExecutedCycles => (long)cpu.TotalExecutedCycles;
|
||||
//public long TotalExecutedCycles => CycleCount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
public bool controller_was_checked;
|
||||
public bool delays_to_process;
|
||||
public int controller_delay_cd;
|
||||
//public long CycleCount;
|
||||
|
||||
public bool FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
|
@ -112,8 +113,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
cpu.ExecuteOne();
|
||||
timer.divider_reg++;
|
||||
if (delays_to_process) { process_delays(); }
|
||||
|
||||
REG_FF0F_OLD = REG_FF0F;
|
||||
}
|
||||
|
||||
|
||||
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
||||
serialport.serial_transfer_tick();
|
||||
timer.tick();
|
||||
|
@ -130,6 +133,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
cpu.TotalExecutedCycles++;
|
||||
timer.divider_reg++;
|
||||
if (delays_to_process) { process_delays(); }
|
||||
|
||||
REG_FF0F_OLD = REG_FF0F;
|
||||
}
|
||||
|
||||
timer.tick();
|
||||
|
@ -139,6 +144,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
if (delays_to_process) { process_delays(); }
|
||||
}
|
||||
|
||||
//CycleCount++;
|
||||
|
||||
if (in_vblank && !in_vblank_old)
|
||||
{
|
||||
_islag = false;
|
||||
|
@ -194,14 +201,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
if (!HDMA_transfer)
|
||||
{
|
||||
// These things all tick twice as fast in GBC double speed mode
|
||||
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
||||
serialport.serial_transfer_tick();
|
||||
timer.tick();
|
||||
cpu.ExecuteOne();
|
||||
timer.divider_reg++;
|
||||
|
||||
if (delays_to_process) { process_delays(); }
|
||||
|
||||
// Note that DMA is halted when the CPU is halted
|
||||
if (double_speed)
|
||||
{
|
||||
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
||||
|
@ -209,26 +209,36 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
timer.tick();
|
||||
cpu.ExecuteOne();
|
||||
timer.divider_reg++;
|
||||
|
||||
if (delays_to_process) { process_delays(); }
|
||||
|
||||
REG_FF0F_OLD = REG_FF0F;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
||||
serialport.serial_transfer_tick();
|
||||
timer.tick();
|
||||
cpu.TotalExecutedCycles++;
|
||||
cpu.ExecuteOne();
|
||||
timer.divider_reg++;
|
||||
|
||||
if (delays_to_process) { process_delays(); }
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (double_speed)
|
||||
{
|
||||
timer.tick();
|
||||
cpu.TotalExecutedCycles++;
|
||||
timer.divider_reg++;
|
||||
|
||||
if (delays_to_process) { process_delays(); }
|
||||
|
||||
REG_FF0F_OLD = REG_FF0F;
|
||||
}
|
||||
|
||||
timer.tick();
|
||||
cpu.TotalExecutedCycles++;
|
||||
timer.divider_reg++;
|
||||
|
||||
if (delays_to_process) { process_delays(); }
|
||||
}
|
||||
|
||||
if (in_vblank && !in_vblank_old)
|
||||
|
@ -314,7 +324,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
else
|
||||
{
|
||||
// reset the divider (only way for speed_change_timing_fine.gbc and speed_change_cancel.gbc to both work)
|
||||
timer.divider_reg = 1;
|
||||
//Console.WriteLine("at stop " + timer.divider_reg);
|
||||
timer.divider_reg = 0x1;
|
||||
|
||||
// TODO: resetting the divider causes an increment, but exact timing unclear
|
||||
//timer.tick();
|
||||
|
||||
double_speed = !double_speed;
|
||||
return 0;
|
||||
}
|
||||
|
@ -343,7 +358,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
public void SetIntRegs(byte r)
|
||||
{
|
||||
// For timer interrupts or serial interrupts that occur on the same cycle as the IRQ clear
|
||||
// the clear wins on GB but the set wins on GBC
|
||||
if (((REG_FF0F & 4) == 4) && ((r & 4) == 0) && timer.IRQ_block && !is_GBC) { r |= 4; }
|
||||
if (((REG_FF0F & 8) == 8) && ((r & 8) == 0) && serialport.IRQ_block && !is_GBC) { r |= 8; }
|
||||
REG_FF0F = r;
|
||||
}
|
||||
|
||||
|
|
|
@ -220,6 +220,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
iptr3 = Marshal.AllocHGlobal(ppu.color_palette.Length * 8 * 8 + 1);
|
||||
|
||||
_scanlineCallback = null;
|
||||
|
||||
/*
|
||||
for (int i = 0; i < ZP_RAM.Length; i++)
|
||||
{
|
||||
ZP_RAM[i] = 0xFF;
|
||||
}
|
||||
|
||||
for (int i = 0; i < RAM.Length; i++)
|
||||
{
|
||||
RAM[i] = 0xFF;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public bool IsCGBMode() => is_GBC;
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
blank_frame = true;
|
||||
}
|
||||
LCDC = value;
|
||||
//Console.WriteLine(LY + " " + cycle);
|
||||
break;
|
||||
case 0xFF41: // STAT
|
||||
// writing to STAT during mode 0 or 1 causes a STAT IRQ
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
// Interrupt flags
|
||||
case 0xFF0F:
|
||||
// TODO: Maybe some PPU bits are immediately visible, see 10spritesPrLine_10xposA7_m0irq_2_dmg08_cgb04c_out2.gbc
|
||||
//Console.WriteLine("FF0F " + cpu.TotalExecutedCycles);
|
||||
ret = REG_FF0F_OLD;
|
||||
break;
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
{
|
||||
public partial class GBHawk
|
||||
{
|
||||
//public byte[] RAM_read = new byte[0x8000];
|
||||
//public byte[] ZP_RAM_read = new byte[0x80];
|
||||
|
||||
public byte ReadMemory(ushort addr)
|
||||
{
|
||||
if (MemoryCallbacks.HasReads)
|
||||
|
@ -61,6 +64,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
if (addr >= 0xF000 && addr < 0xFE00)
|
||||
{
|
||||
//if (RAM_read[(RAM_Bank * 0x1000) + (addr - 0xF000)] == 0) { Console.WriteLine("RAM: " + addr + " " + cpu.TotalExecutedCycles); }
|
||||
return RAM[(RAM_Bank * 0x1000) + (addr - 0xF000)];
|
||||
}
|
||||
|
||||
|
@ -85,6 +89,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
{
|
||||
if (addr != 0xFFFF)
|
||||
{
|
||||
//if (ZP_RAM_read[addr - 0xFF80] == 0) { Console.WriteLine("ZP: " + (addr - 0xFF80) + " " + cpu.TotalExecutedCycles); }
|
||||
return ZP_RAM[addr - 0xFF80];
|
||||
}
|
||||
else
|
||||
|
@ -158,6 +163,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
if (addr < 0xFE00)
|
||||
{
|
||||
addr = (ushort)(RAM_Bank * (addr & 0x1000) + (addr & 0xFFF));
|
||||
//if (RAM_read[addr] == 0) { Console.WriteLine("RAM: " + addr + " " + cpu.TotalExecutedCycles); }
|
||||
return RAM[addr];
|
||||
}
|
||||
|
||||
|
@ -215,6 +221,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
if (addr < 0xFFFF)
|
||||
{
|
||||
//if (ZP_RAM_read[addr - 0xFF80] == 0) { Console.WriteLine("ZP: " + (addr - 0xFF80) + " " + cpu.TotalExecutedCycles); }
|
||||
return ZP_RAM[addr - 0xFF80];
|
||||
}
|
||||
|
||||
|
@ -234,7 +241,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
if (ppu.DMA_start)
|
||||
{
|
||||
// some of gekkio's tests require this to be accessible during DMA
|
||||
|
||||
if (addr >= 0xA000 && addr < 0xC000 && is_GBC)
|
||||
{
|
||||
// on GBC only, cart is accessible during DMA
|
||||
|
@ -243,10 +249,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
if (addr >= 0xE000 && addr < 0xF000)
|
||||
{
|
||||
//RAM_read[addr - 0xE000] = 1;
|
||||
RAM[addr - 0xE000] = value;
|
||||
}
|
||||
else if (addr >= 0xF000 && addr < 0xFE00)
|
||||
{
|
||||
//RAM_read[RAM_Bank * 0x1000 + (addr - 0xF000)] = 1;
|
||||
RAM[RAM_Bank * 0x1000 + (addr - 0xF000)] = value;
|
||||
}
|
||||
else if (addr >= 0xFE00 && addr < 0xFEA0 && ppu.DMA_OAM_access)
|
||||
|
@ -261,6 +269,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
{
|
||||
if (addr != 0xFFFF)
|
||||
{
|
||||
//ZP_RAM_read[addr - 0xFF80] = 1;
|
||||
ZP_RAM[addr - 0xFF80] = value;
|
||||
}
|
||||
else
|
||||
|
@ -281,6 +290,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else if (addr < 0xFFFF)
|
||||
{
|
||||
//ZP_RAM_read[addr - 0xFF80] = 1;
|
||||
ZP_RAM[addr - 0xFF80] = value;
|
||||
}
|
||||
else
|
||||
|
@ -294,7 +304,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
{
|
||||
if (ppu.OAM_access_write) { OAM[addr - 0xFE00] = value; }
|
||||
}
|
||||
// unmapped memory writes depend on console
|
||||
// unmapped memory writes depend on console
|
||||
else
|
||||
{
|
||||
if (is_GBC)
|
||||
|
@ -318,6 +328,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
else if (addr >= 0xC000)
|
||||
{
|
||||
addr = (ushort)(RAM_Bank * (addr & 0x1000) + (addr & 0xFFF));
|
||||
//RAM_read[addr] = 1;
|
||||
RAM[addr] = value;
|
||||
}
|
||||
else if (addr >= 0xA000)
|
||||
|
@ -326,7 +337,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else if (addr >= 0x8000)
|
||||
{
|
||||
if (ppu.VRAM_access_write) { VRAM[(VRAM_Bank * 0x2000) + (addr - 0x8000)] = value; }
|
||||
if (ppu.VRAM_access_write)
|
||||
{
|
||||
VRAM[(VRAM_Bank * 0x2000) + (addr - 0x8000)] = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using BizHawk.Common.NumberExtensions;
|
||||
using BizHawk.Common;
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||
{
|
||||
|
@ -15,6 +16,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
public int clk_rate;
|
||||
public byte going_out;
|
||||
public byte coming_in;
|
||||
public int serial_bits_old;
|
||||
public bool IRQ_block;
|
||||
|
||||
public byte ReadReg(int addr)
|
||||
{
|
||||
|
@ -40,20 +43,24 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
case 0xFF02:
|
||||
if ((value & 0x1) == 1)
|
||||
{
|
||||
|
||||
serial_bits = 8;
|
||||
|
||||
if (((value & 2) > 0) && Core.GBC_compat)
|
||||
{
|
||||
clk_rate = 16;
|
||||
serial_clock = (16 - (int)(Core.cpu.TotalExecutedCycles % 8)) + 1;
|
||||
serial_clock = 16 - (int)(Core.timer.divider_reg % 8) - 1;
|
||||
|
||||
// if the clock rate is changing and it's on a GBA/C, the parity of (cpu.totalexecutedcycles & 512) effects the first bit
|
||||
// Not sure exactly how yet
|
||||
}
|
||||
else
|
||||
{
|
||||
clk_rate = 512;
|
||||
serial_clock = 512 - (int)(Core.cpu.TotalExecutedCycles % 256) + 1;
|
||||
serial_clock = 512 - (int)(Core.timer.divider_reg % 256) - 1;
|
||||
|
||||
// there seems to be some clock inverting happening on some transfers
|
||||
// not sure of the exact nature of it, here is one methor that gives correct result on one test rom but not others
|
||||
// not sure of the exact nature of it, here is one method that gives correct result on one test rom but not others
|
||||
/*
|
||||
if (Core._syncSettings.GBACGB && Core.is_GBC)
|
||||
{
|
||||
|
@ -68,10 +75,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
serial_bits_old = serial_bits;
|
||||
serial_bits = 8;
|
||||
clk_rate = -1;
|
||||
serial_clock = clk_rate;
|
||||
can_pulse = false;
|
||||
|
||||
}
|
||||
|
||||
if (Core.GBC_compat)
|
||||
|
@ -90,6 +99,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
public void serial_transfer_tick()
|
||||
{
|
||||
IRQ_block = false;
|
||||
|
||||
if (serial_clock > 0)
|
||||
{
|
||||
serial_clock--;
|
||||
|
@ -108,6 +119,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
if (Core.REG_FFFF.Bit(3)) { Core.cpu.FlagI = true; }
|
||||
Core.REG_FF0F |= 0x08;
|
||||
//Console.WriteLine("SIRQ " + Core.cpu.TotalExecutedCycles);
|
||||
IRQ_block = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -141,6 +154,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
ser.Sync(nameof(going_out), ref going_out);
|
||||
ser.Sync(nameof(coming_in), ref coming_in);
|
||||
ser.Sync(nameof(can_pulse), ref can_pulse);
|
||||
ser.Sync(nameof(IRQ_block), ref IRQ_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,6 +204,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
// set interrupts
|
||||
if (Core.REG_FFFF.Bit(2)) { Core.cpu.FlagI = true; }
|
||||
//Console.WriteLine("timer " + Core.cpu.TotalExecutedCycles);
|
||||
Core.REG_FF0F |= 0x04;
|
||||
IRQ_block = true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue