GBHawk: Mapper cleanup

This commit is contained in:
alyosha-tas 2020-03-26 10:22:14 -04:00
parent 649f96b617
commit 03b83a1043
18 changed files with 323 additions and 471 deletions

View File

@ -18,7 +18,51 @@ namespace GBHawk
} }
uint32_t* uint32_t* ROM_Length = nullptr;
uint32_t* Cart_RAM_Length = nullptr;
uint32_t* ROM = nullptr;
uint32_t* Cart_RAM = nullptr;
// Generic Mapper Variables
bool RAM_enable;
bool sel_mode;
bool IR_signal;
uint32_t ROM_bank;
uint32_t RAM_bank;
uint32_t ROM_mask;
uint32_t RAM_mask;
// Common
bool halt;
uint32_t RTC_timer;
uint32_t RTC_low_clock;
// HuC3
bool timer_read;
uint8_t control;
uint8_t chip_read;
uint32_t time_val_shift;
uint32_t time;
uint32_t RTC_seconds;
// MBC3
uint8_t RTC_regs[5] = {};
uint8_t RTC_regs_latch[5] = {};
bool RTC_regs_latch_wr;
uint32_t RTC_offset;
// TAMA5
uint8_t RTC_regs_TAMA[10] = {};
uint32_t ctrl;
uint32_t RAM_addr_low;
uint32_t RAM_addr_high;
uint32_t RAM_val_low;
uint32_t RAM_val_high;
uint8_t Chip_return_low;
uint8_t Chip_return_high;
virtual uint8_t ReadMemory(uint32_t addr) virtual uint8_t ReadMemory(uint32_t addr)
{ {
@ -38,16 +82,7 @@ namespace GBHawk
{ {
} }
virtual uint8_t* SaveState(uint8_t* saver)
{
return nullptr;
}
virtual uint8_t* LoadState(uint8_t* loader)
{
return nullptr;
}
virtual void Dispose() virtual void Dispose()
{ {
} }
@ -79,5 +114,97 @@ namespace GBHawk
} }
*/ */
#pragma region State Save / Load
uint8_t* SaveState(uint8_t* saver)
{
saver = bool_saver(RAM_enable, saver);
saver = bool_saver(sel_mode, saver);
saver = bool_saver(IR_signal, saver);
saver = int_saver(ROM_bank, saver);
saver = int_saver(RAM_bank, saver);
saver = int_saver(ROM_mask, saver);
saver = int_saver(RAM_mask, saver);
saver = bool_saver(halt, saver);
saver = int_saver(RTC_timer, saver);
saver = int_saver(RTC_low_clock, saver);
saver = bool_saver(timer_read, saver);
saver = byte_saver(control, saver);
saver = byte_saver(chip_read, saver);
saver = int_saver(time_val_shift, saver);
saver = int_saver(time, saver);
saver = int_saver(RTC_seconds, saver);
for (int i = 0; i < 5; i++) { saver = byte_saver(RTC_regs[i], saver); }
for (int i = 0; i < 5; i++) { saver = byte_saver(RTC_regs_latch[i], saver); }
saver = bool_saver(RTC_regs_latch_wr, saver);
saver = int_saver(RTC_offset, saver);
for (int i = 0; i < 10; i++) { saver = byte_saver(RTC_regs_TAMA[i], saver); }
saver = byte_saver(Chip_return_low, saver);
saver = byte_saver(Chip_return_high, saver);
saver = int_saver(ctrl, saver);
saver = int_saver(RAM_addr_low, saver);
saver = int_saver(RAM_addr_high, saver);
saver = int_saver(RAM_val_low, saver);
saver = int_saver(RAM_val_high, saver);
return saver;
}
uint8_t* LoadState(uint8_t* loader)
{
return loader;
}
uint8_t* bool_saver(bool to_save, uint8_t* saver)
{
*saver = (uint8_t)(to_save ? 1 : 0); saver++;
return saver;
}
uint8_t* byte_saver(uint8_t to_save, uint8_t* saver)
{
*saver = to_save; saver++;
return saver;
}
uint8_t* int_saver(uint32_t to_save, uint8_t* saver)
{
*saver = (uint8_t)(to_save & 0xFF); saver++; *saver = (uint8_t)((to_save >> 8) & 0xFF); saver++;
*saver = (uint8_t)((to_save >> 16) & 0xFF); saver++; *saver = (uint8_t)((to_save >> 24) & 0xFF); saver++;
return saver;
}
uint8_t* bool_loader(bool* to_load, uint8_t* loader)
{
to_load[0] = *to_load == 1; loader++;
return loader;
}
uint8_t* byte_loader(uint8_t* to_load, uint8_t* loader)
{
to_load[0] = *loader; loader++;
return loader;
}
uint8_t* int_loader(uint32_t* to_load, uint8_t* loader)
{
to_load[0] = *loader; loader++; to_load[0] |= (*loader << 8); loader++;
to_load[0] |= (*loader << 16); loader++; to_load[0] |= (*loader << 24); loader++;
return loader;
}
#pragma endregion
}; };
} }

View File

@ -14,11 +14,7 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
uint32_t ROM_mask;
uint32_t RAM_mask;
bool regs_enable; bool regs_enable;
uint8_t regs[0x80] = {}; uint8_t regs[0x80] = {};
@ -27,9 +23,9 @@ namespace GBHawk
ROM_bank = 1; ROM_bank = 1;
RAM_bank = 0; RAM_bank = 0;
RAM_enable = false; RAM_enable = false;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1; RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
regs_enable = false; regs_enable = false;
} }
@ -38,11 +34,11 @@ namespace GBHawk
{ {
if (addr < 0x4000) if (addr < 0x4000)
{ {
return Core._rom[addr]; return ROM[addr];
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
} }
else else
{ {
@ -59,9 +55,9 @@ namespace GBHawk
} }
else else
{ {
if (/*RAM_enable && */(((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if (/*RAM_enable && */(((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
return Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000]; return Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000];
} }
else else
{ {
@ -87,7 +83,7 @@ namespace GBHawk
{ {
if (!regs_enable) if (!regs_enable)
{ {
if ((((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if ((((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000); SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000);
} }
@ -140,9 +136,9 @@ namespace GBHawk
} }
else else
{ {
if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value; Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value;
} }
} }
} }
@ -152,16 +148,5 @@ namespace GBHawk
{ {
WriteMemory(addr, value); WriteMemory(addr, value);
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(RAM_bank), ref RAM_bank);
ser.Sync(nameof(RAM_mask), ref RAM_mask);
ser.Sync(nameof(RAM_enable), ref RAM_enable);
ser.Sync(nameof(regs_enable), ref regs_enable);
ser.Sync(nameof(regs), ref regs, false);
}
}; };
} }

View File

@ -23,13 +23,13 @@ namespace GBHawk
{ {
if (addr < 0x8000) if (addr < 0x8000)
{ {
return Core._rom[addr]; return ROM[addr];
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length > 0)
{ {
return Core.cart_RAM[addr - 0xA000]; return Cart_RAM[addr - 0xA000];
} }
else else
{ {
@ -47,7 +47,7 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM != null)
{ {
SetCDLRAM(flags, addr - 0xA000); SetCDLRAM(flags, addr - 0xA000);
} }
@ -72,9 +72,9 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length > 0)
{ {
Core.cart_RAM[addr - 0xA000] = value; Cart_RAM[addr - 0xA000] = value;
} }
} }
} }

View File

@ -14,28 +14,21 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
uint32_t ROM_mask;
uint32_t RAM_mask;
bool IR_signal;
void Reset() void Reset()
{ {
ROM_bank = 0; ROM_bank = 0;
RAM_bank = 0; RAM_bank = 0;
RAM_enable = false; RAM_enable = false;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
// some games have sizes that result in a degenerate ROM, account for it here // some games have sizes that result in a degenerate ROM, account for it here
if (ROM_mask > 4) { ROM_mask |= 3; } if (ROM_mask > 4) { ROM_mask |= 3; }
RAM_mask = 0; RAM_mask = 0;
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1; RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; } if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
} }
} }
@ -43,21 +36,21 @@ namespace GBHawk
{ {
if (addr < 0x4000) if (addr < 0x4000)
{ {
return Core._rom[addr]; return ROM[addr];
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
} }
else if ((addr >= 0xA000) && (addr < 0xC000)) else if ((addr >= 0xA000) && (addr < 0xC000))
{ {
if (RAM_enable) if (RAM_enable)
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) if (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0])
{ {
return Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000]; return Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000];
} }
else else
{ {
@ -97,9 +90,9 @@ namespace GBHawk
{ {
if (RAM_enable) if (RAM_enable)
{ {
if (Core.cart_RAM != null) if (Cart_RAM != null)
{ {
if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) if (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0])
{ {
SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000); SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000);
} }
@ -156,11 +149,11 @@ namespace GBHawk
{ {
if (RAM_enable) if (RAM_enable)
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) if (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0])
{ {
Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value; Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value;
} }
} }
} }
@ -183,15 +176,5 @@ namespace GBHawk
{ {
WriteMemory(addr, value); WriteMemory(addr, value);
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(RAM_bank), ref RAM_bank);
ser.Sync(nameof(RAM_mask), ref RAM_mask);
ser.Sync(nameof(RAM_enable), ref RAM_enable);
ser.Sync(nameof(IR_signal), ref IR_signal);
}
}; };
} }

View File

@ -14,27 +14,12 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
uint32_t ROM_mask;
uint32_t RAM_mask;
bool IR_signal;
uint8_t control;
uint8_t chip_read;
bool timer_read;
uint32_t time_val_shift;
uint32_t time;
uint32_t RTC_timer;
uint32_t RTC_low_clock;
uint32_t RTC_seconds;
void Reset() void Reset()
{ {
ROM_bank = 0; ROM_bank = 0;
RAM_bank = 0; RAM_bank = 0;
RAM_enable = false; RAM_enable = false;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
control = 0; control = 0;
chip_read = 1; chip_read = 1;
timer_read = false; timer_read = false;
@ -44,10 +29,10 @@ namespace GBHawk
if (ROM_mask > 4) { ROM_mask |= 3; } if (ROM_mask > 4) { ROM_mask |= 3; }
RAM_mask = 0; RAM_mask = 0;
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1; RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; } if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
} }
} }
@ -55,11 +40,11 @@ namespace GBHawk
{ {
if (addr < 0x4000) if (addr < 0x4000)
{ {
return Core._rom[addr]; return ROM[addr];
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
} }
else if ((addr >= 0xA000) && (addr < 0xC000)) else if ((addr >= 0xA000) && (addr < 0xC000))
{ {
@ -74,11 +59,11 @@ namespace GBHawk
if (RAM_enable) if (RAM_enable)
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) if (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0])
{ {
return Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000]; return Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000];
} }
else else
{ {
@ -117,9 +102,9 @@ namespace GBHawk
{ {
if (RAM_enable) if (RAM_enable)
{ {
if (Core.cart_RAM != null) if (Cart_RAM != null)
{ {
if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) if (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0])
{ {
SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000); SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000);
} }
@ -177,11 +162,11 @@ namespace GBHawk
{ {
if (RAM_enable && ((control < 0xB) || (control > 0xE))) if (RAM_enable && ((control < 0xB) || (control > 0xE)))
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) if (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0])
{ {
Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value; Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value;
} }
} }
} }
@ -208,7 +193,7 @@ namespace GBHawk
if (time_val_shift == 0) { time = 0; } if (time_val_shift == 0) { time = 0; }
if (time_val_shift < 28) if (time_val_shift < 28)
{ {
time |= (uint)((value & 0x0F) << time_val_shift); time |= (uint32_t)((value & 0x0F) << time_val_shift);
time_val_shift += 4; time_val_shift += 4;
if (time_val_shift == 28) { timer_read = true; } if (time_val_shift == 28) { timer_read = true; }
} }
@ -253,7 +238,7 @@ namespace GBHawk
void RTC_Get(uint32_t value, uint32_t index) void RTC_Get(uint32_t value, uint32_t index)
{ {
time |= (uint)((value & 0xFF) << index); time |= (uint32_t)((value & 0xFF) << index);
} }
void Mapper_Tick() void Mapper_Tick()
@ -289,23 +274,5 @@ namespace GBHawk
} }
} }
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(RAM_bank), ref RAM_bank);
ser.Sync(nameof(RAM_mask), ref RAM_mask);
ser.Sync(nameof(RAM_enable), ref RAM_enable);
ser.Sync(nameof(IR_signal), ref IR_signal);
ser.Sync(nameof(control), ref control);
ser.Sync(nameof(chip_read), ref chip_read);
ser.Sync(nameof(timer_read), ref timer_read);
ser.Sync(nameof(time_val_shift), ref time_val_shift);
ser.Sync(nameof(time), ref time);
ser.Sync(nameof(RTC_timer), ref RTC_timer);
ser.Sync(nameof(RTC_low_clock), ref RTC_low_clock);
ser.Sync(nameof(RTC_seconds), ref RTC_seconds);
}
}; };
} }

View File

@ -14,29 +14,22 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
bool sel_mode;
uint32_t ROM_mask;
uint32_t RAM_mask;
void Reset() void Reset()
{ {
ROM_bank = 1; ROM_bank = 1;
RAM_bank = 0; RAM_bank = 0;
RAM_enable = false; RAM_enable = false;
sel_mode = false; sel_mode = false;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
// some games have sizes that result in a degenerate ROM, account for it here // some games have sizes that result in a degenerate ROM, account for it here
if (ROM_mask > 4) { ROM_mask |= 3; } if (ROM_mask > 4) { ROM_mask |= 3; }
RAM_mask = 0; RAM_mask = 0;
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1; RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; } if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
} }
} }
@ -47,24 +40,24 @@ namespace GBHawk
// lowest bank is fixed, but is still effected by mode // lowest bank is fixed, but is still effected by mode
if (sel_mode) if (sel_mode)
{ {
return Core._rom[(ROM_bank & 0x60) * 0x4000 + addr]; return ROM[(ROM_bank & 0x60) * 0x4000 + addr];
} }
else else
{ {
return Core._rom[addr]; return ROM[addr];
} }
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
return Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000]; return Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000];
} }
else else
{ {
@ -100,9 +93,9 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM != null)
{ {
if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000); SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000);
} }
@ -146,7 +139,7 @@ namespace GBHawk
} }
else if (addr < 0x6000) else if (addr < 0x6000)
{ {
if (sel_mode && Core.cart_RAM != null) if (sel_mode && (Cart_RAM_Length[0] > 0))
{ {
RAM_bank = value & 3; RAM_bank = value & 3;
RAM_bank &= RAM_mask; RAM_bank &= RAM_mask;
@ -162,7 +155,7 @@ namespace GBHawk
{ {
sel_mode = (value & 1) > 0; sel_mode = (value & 1) > 0;
if (sel_mode && Core.cart_RAM != null) if (sel_mode && (Cart_RAM_Length[0] > 0))
{ {
ROM_bank &= 0x1F; ROM_bank &= 0x1F;
ROM_bank &= ROM_mask; ROM_bank &= ROM_mask;
@ -175,11 +168,11 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value; Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value;
} }
} }
} }
@ -189,15 +182,5 @@ namespace GBHawk
{ {
WriteMemory(addr, value); WriteMemory(addr, value);
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(RAM_bank), ref RAM_bank);
ser.Sync(nameof(RAM_mask), ref RAM_mask);
ser.Sync(nameof(RAM_enable), ref RAM_enable);
ser.Sync(nameof(sel_mode), ref sel_mode);
}
}; };
} }

View File

@ -14,25 +14,18 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
bool sel_mode;
uint32_t ROM_mask;
uint32_t RAM_mask;
void Reset() void Reset()
{ {
ROM_bank = 1; ROM_bank = 1;
RAM_bank = 0; RAM_bank = 0;
RAM_enable = false; RAM_enable = false;
sel_mode = false; sel_mode = false;
ROM_mask = (Core._rom.Length / 0x4000 * 2) - 1; // due to how mapping works, we want a 1 bit higher mask ROM_mask = (ROM_Length[0] / 0x4000 * 2) - 1; // due to how mapping works, we want a 1 bit higher mask
RAM_mask = 0; RAM_mask = 0;
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1; RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; } if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
} }
} }
@ -43,24 +36,24 @@ namespace GBHawk
// lowest bank is fixed, but is still effected by mode // lowest bank is fixed, but is still effected by mode
if (sel_mode) if (sel_mode)
{ {
return Core._rom[((ROM_bank & 0x60) >> 1) * 0x4000 + addr]; return ROM[((ROM_bank & 0x60) >> 1) * 0x4000 + addr];
} }
else else
{ {
return Core._rom[addr]; return ROM[addr];
} }
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + (((ROM_bank & 0x60) >> 1) | (ROM_bank & 0xF)) * 0x4000]; return ROM[(addr - 0x4000) + (((ROM_bank & 0x60) >> 1) | (ROM_bank & 0xF)) * 0x4000];
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
return Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000]; return Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000];
} }
else else
{ {
@ -96,9 +89,9 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM != null)
{ {
if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000); SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000);
} }
@ -142,7 +135,7 @@ namespace GBHawk
} }
else if (addr < 0x6000) else if (addr < 0x6000)
{ {
if (sel_mode && Core.cart_RAM != null) if (sel_mode && (Cart_RAM_Length[0] > 0))
{ {
RAM_bank = value & 3; RAM_bank = value & 3;
RAM_bank &= RAM_mask; RAM_bank &= RAM_mask;
@ -158,7 +151,7 @@ namespace GBHawk
{ {
sel_mode = (value & 1) > 0; sel_mode = (value & 1) > 0;
if (sel_mode && Core.cart_RAM != null) if (sel_mode && (Cart_RAM_Length[0] > 0))
{ {
ROM_bank &= 0x1F; ROM_bank &= 0x1F;
ROM_bank &= ROM_mask; ROM_bank &= ROM_mask;
@ -171,11 +164,11 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value; Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value;
} }
} }
} }
@ -185,15 +178,5 @@ namespace GBHawk
{ {
WriteMemory(addr, value); WriteMemory(addr, value);
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(RAM_bank), ref RAM_bank);
ser.Sync(nameof(RAM_mask), ref RAM_mask);
ser.Sync(nameof(RAM_enable), ref RAM_enable);
ser.Sync(nameof(sel_mode), ref sel_mode);
}
}; };
} }

View File

@ -14,34 +14,29 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
uint32_t ROM_mask;
void Reset() void Reset()
{ {
ROM_bank = 1; ROM_bank = 1;
RAM_bank = 0; RAM_bank = 0;
RAM_enable = false; RAM_enable = false;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
} }
uint8_t ReadMemory(uint32_t addr) uint8_t ReadMemory(uint32_t addr)
{ {
if (addr < 0x4000) if (addr < 0x4000)
{ {
return Core._rom[addr]; return ROM[addr];
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
} }
else if ((addr >= 0xA000) && (addr < 0xA200)) else if ((addr >= 0xA000) && (addr < 0xA200))
{ {
if (RAM_enable) if (RAM_enable)
{ {
return Core.cart_RAM[addr - 0xA000]; return Cart_RAM[addr - 0xA000];
} }
return 0xFF; return 0xFF;
} }
@ -103,7 +98,7 @@ namespace GBHawk
{ {
if (RAM_enable) if (RAM_enable)
{ {
Core.cart_RAM[addr - 0xA000] = (uint8_t)(value & 0xF); Cart_RAM[addr - 0xA000] = (uint8_t)(value & 0xF);
} }
} }
} }
@ -112,13 +107,5 @@ namespace GBHawk
{ {
WriteMemory(addr, value); WriteMemory(addr, value);
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(RAM_bank), ref RAM_bank);
ser.Sync(nameof(RAM_enable), ref RAM_enable);
}
}; };
} }

View File

@ -14,34 +14,21 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
uint32_t ROM_mask;
uint32_t RAM_mask;
uint8_t[] RTC_regs = new uint8_t[5];
uint8_t[] RTC_regs_latch = new uint8_t[5];
bool RTC_regs_latch_wr;
uint32_t RTC_timer;
uint32_t RTC_low_clock;
bool halt;
uint32_t RTC_offset;
void Reset() void Reset()
{ {
ROM_bank = 1; ROM_bank = 1;
RAM_bank = 0; RAM_bank = 0;
RAM_enable = false; RAM_enable = false;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
// some games have sizes that result in a degenerate ROM, account for it here // some games have sizes that result in a degenerate ROM, account for it here
if (ROM_mask > 4) { ROM_mask |= 3; } if (ROM_mask > 4) { ROM_mask |= 3; }
RAM_mask = 0; RAM_mask = 0;
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1; RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; } if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
} }
RTC_regs_latch[0] = 0; RTC_regs_latch[0] = 0;
@ -57,21 +44,21 @@ namespace GBHawk
{ {
if (addr < 0x4000) if (addr < 0x4000)
{ {
return Core._rom[addr]; return ROM[addr];
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
} }
else else
{ {
if (RAM_enable) if (RAM_enable)
{ {
if ((Core.cart_RAM != null) && (RAM_bank <= RAM_mask)) if ((Cart_RAM_Length[0] > 0) && (RAM_bank <= RAM_mask))
{ {
if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) if (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0])
{ {
return Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000]; return Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000];
} }
else else
{ {
@ -111,9 +98,9 @@ namespace GBHawk
{ {
if (RAM_enable) if (RAM_enable)
{ {
if ((Core.cart_RAM != null) && (RAM_bank <= RAM_mask)) if ((Cart_RAM != null) && (RAM_bank <= RAM_mask))
{ {
if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) if (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0])
{ {
SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000); SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000);
} }
@ -184,11 +171,11 @@ namespace GBHawk
{ {
if (RAM_enable) if (RAM_enable)
{ {
if ((Core.cart_RAM != null) && (RAM_bank <= RAM_mask)) if ((Cart_RAM_Length[0] > 0) && (RAM_bank <= RAM_mask))
{ {
if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) if (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0])
{ {
Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value; Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value;
} }
} }
else if ((RAM_bank >= 8) && (RAM_bank <= 0xC)) else if ((RAM_bank >= 8) && (RAM_bank <= 0xC))
@ -275,21 +262,5 @@ namespace GBHawk
} }
} }
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(RAM_bank), ref RAM_bank);
ser.Sync(nameof(RAM_mask), ref RAM_mask);
ser.Sync(nameof(RAM_enable), ref RAM_enable);
ser.Sync(nameof(halt), ref halt);
ser.Sync(nameof(RTC_regs), ref RTC_regs, false);
ser.Sync(nameof(RTC_regs_latch), ref RTC_regs_latch, false);
ser.Sync(nameof(RTC_regs_latch_wr), ref RTC_regs_latch_wr);
ser.Sync(nameof(RTC_timer), ref RTC_timer);
ser.Sync(nameof(RTC_low_clock), ref RTC_low_clock);
ser.Sync(nameof(RTC_offset), ref RTC_offset);
}
}; };
} }

View File

@ -14,28 +14,22 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
uint32_t ROM_mask;
uint32_t RAM_mask;
void Reset() void Reset()
{ {
ROM_bank = 1; ROM_bank = 1;
RAM_bank = 0; RAM_bank = 0;
RAM_enable = false; RAM_enable = false;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
// some games have sizes that result in a degenerate ROM, account for it here // some games have sizes that result in a degenerate ROM, account for it here
if (ROM_mask > 4) { ROM_mask |= 3; } if (ROM_mask > 4) { ROM_mask |= 3; }
if (ROM_mask > 0x100) { ROM_mask |= 0xFF; } if (ROM_mask > 0x100) { ROM_mask |= 0xFF; }
RAM_mask = 0; RAM_mask = 0;
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1; RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; } if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
} }
} }
@ -43,19 +37,19 @@ namespace GBHawk
{ {
if (addr < 0x4000) if (addr < 0x4000)
{ {
return Core._rom[addr]; return ROM[addr];
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
return Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000]; return Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000];
} }
else else
{ {
@ -83,9 +77,9 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM != null)
{ {
if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000); SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000);
} }
@ -140,11 +134,11 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length)) if (RAM_enable && (((addr - 0xA000) + RAM_bank * 0x2000) < Cart_RAM_Length[0]))
{ {
Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value; Cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value;
} }
} }
} }
@ -154,14 +148,5 @@ namespace GBHawk
{ {
WriteMemory(addr, value); WriteMemory(addr, value);
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(RAM_bank), ref RAM_bank);
ser.Sync(nameof(RAM_mask), ref RAM_mask);
ser.Sync(nameof(RAM_enable), ref RAM_enable);
}
}; };
} }

View File

@ -23,13 +23,13 @@ namespace GBHawk
{ {
if (addr < 0x8000) if (addr < 0x8000)
{ {
return Core._rom[addr]; return ROM[addr];
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
return Core.cart_RAM[addr - 0xA000]; return Cart_RAM[addr - 0xA000];
} }
else else
{ {
@ -47,7 +47,7 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM != null)
{ {
SetCDLRAM(flags, addr - 0xA000); SetCDLRAM(flags, addr - 0xA000);
} }
@ -72,9 +72,9 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
Core.cart_RAM[addr - 0xA000] = value; Cart_RAM[addr - 0xA000] = value;
} }
} }
} }

View File

@ -14,9 +14,7 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
bool RAM_enable_1, RAM_enable_2; bool RAM_enable_1, RAM_enable_2;
uint32_t ROM_mask;
uint8_t acc_x_low; uint8_t acc_x_low;
uint8_t acc_x_high; uint8_t acc_x_high;
uint8_t acc_y_low; uint8_t acc_y_low;
@ -45,7 +43,7 @@ namespace GBHawk
{ {
ROM_bank = 1; ROM_bank = 1;
RAM_enable_1 = RAM_enable_2 = false; RAM_enable_1 = RAM_enable_2 = false;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
// some games have sizes that result in a degenerate ROM, account for it here // some games have sizes that result in a degenerate ROM, account for it here
if (ROM_mask > 4) { ROM_mask |= 3; } if (ROM_mask > 4) { ROM_mask |= 3; }
@ -67,11 +65,11 @@ namespace GBHawk
{ {
if (addr < 0x4000) if (addr < 0x4000)
{ {
return Core._rom[addr]; return ROM[addr];
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
} }
else if (addr < 0xA000) else if (addr < 0xA000)
{ {
@ -170,35 +168,6 @@ namespace GBHawk
WriteMemory(addr, value); WriteMemory(addr, value);
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(RAM_enable_1), ref RAM_enable_1);
ser.Sync(nameof(RAM_enable_2), ref RAM_enable_2);
ser.Sync(nameof(acc_x_low), ref acc_x_low);
ser.Sync(nameof(acc_x_high), ref acc_x_high);
ser.Sync(nameof(acc_y_low), ref acc_y_low);
ser.Sync(nameof(acc_y_high), ref acc_y_high);
ser.Sync(nameof(is_erased), ref is_erased);
ser.Sync(nameof(CS_prev), ref CS_prev);
ser.Sync(nameof(CLK_prev), ref CLK_prev);
ser.Sync(nameof(DI_prev), ref DI_prev);
ser.Sync(nameof(DO), ref DO);
ser.Sync(nameof(instr_read), ref instr_read);
ser.Sync(nameof(perf_instr), ref perf_instr);
ser.Sync(nameof(instr_bit_counter), ref instr_bit_counter);
ser.Sync(nameof(instr), ref instr);
ser.Sync(nameof(WR_EN), ref WR_EN);
ser.Sync(nameof(EE_addr), ref EE_addr);
ser.Sync(nameof(instr_case), ref instr_case);
ser.Sync(nameof(instr_clocks), ref instr_clocks);
ser.Sync(nameof(EE_value), ref EE_value);
ser.Sync(nameof(countdown), ref countdown);
ser.Sync(nameof(countdown_start), ref countdown_start);
}
uint8_t Register_Access_Read(uint32_t addr) uint8_t Register_Access_Read(uint32_t addr)
{ {
if ((addr & 0xA0F0) == 0xA000) if ((addr & 0xA0F0) == 0xA000)
@ -280,7 +249,7 @@ namespace GBHawk
} }
} }
private void EEPROM_write(uint8_t value) void EEPROM_write(uint8_t value)
{ {
bool CS = value.Bit(7); bool CS = value.Bit(7);
bool CLK = value.Bit(6); bool CLK = value.Bit(6);
@ -349,7 +318,7 @@ namespace GBHawk
{ {
for (uint32_t i = 0; i < 256; i++) for (uint32_t i = 0; i < 256; i++)
{ {
Core.cart_RAM[i] = 0xFF; Cart_RAM[i] = 0xFF;
} }
} }
DO = true; DO = true;
@ -373,8 +342,8 @@ namespace GBHawk
instr_case = 6; instr_case = 6;
if (WR_EN) if (WR_EN)
{ {
Core.cart_RAM[EE_addr * 2] = 0xFF; Cart_RAM[EE_addr * 2] = 0xFF;
Core.cart_RAM[EE_addr * 2 + 1] = 0xFF; Cart_RAM[EE_addr * 2 + 1] = 0xFF;
} }
DO = true; DO = true;
break; break;
@ -405,8 +374,8 @@ namespace GBHawk
{ {
for (uint32_t i = 0; i < 128; i++) for (uint32_t i = 0; i < 128; i++)
{ {
Core.cart_RAM[i * 2] = (uint8_t)(EE_value & 0xFF); Cart_RAM[i * 2] = (uint8_t)(EE_value & 0xFF);
Core.cart_RAM[i * 2 + 1] = (uint8_t)((EE_value & 0xFF00) >> 8); Cart_RAM[i * 2 + 1] = (uint8_t)((EE_value & 0xFF00) >> 8);
} }
} }
instr_case = 7; instr_case = 7;
@ -421,8 +390,8 @@ namespace GBHawk
{ {
if (WR_EN) if (WR_EN)
{ {
Core.cart_RAM[EE_addr * 2] = (uint8_t)(EE_value & 0xFF); Cart_RAM[EE_addr * 2] = (uint8_t)(EE_value & 0xFF);
Core.cart_RAM[EE_addr * 2 + 1] = (uint8_t)((EE_value & 0xFF00) >> 8); Cart_RAM[EE_addr * 2 + 1] = (uint8_t)((EE_value & 0xFF00) >> 8);
} }
instr_case = 7; instr_case = 7;
countdown = 8; countdown = 8;
@ -432,11 +401,11 @@ namespace GBHawk
case 5: case 5:
if ((instr_clocks >= 0) && (instr_clocks <= 7)) if ((instr_clocks >= 0) && (instr_clocks <= 7))
{ {
DO = ((Core.cart_RAM[EE_addr * 2 + 1] >> (7 - instr_clocks)) & 1) == 1; DO = ((Cart_RAM[EE_addr * 2 + 1] >> (7 - instr_clocks)) & 1) == 1;
} }
else if ((instr_clocks >= 8) && (instr_clocks <= 15)) else if ((instr_clocks >= 8) && (instr_clocks <= 15))
{ {
DO = ((Core.cart_RAM[EE_addr * 2] >> (15 - instr_clocks)) & 1) == 1; DO = ((Cart_RAM[EE_addr * 2] >> (15 - instr_clocks)) & 1) == 1;
} }
if (instr_clocks == 15) if (instr_clocks == 15)

View File

@ -23,13 +23,13 @@ namespace GBHawk
{ {
if (addr < 0x8000) if (addr < 0x8000)
{ {
return Core._rom[addr]; return ROM[addr];
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
return Core.cart_RAM[addr - 0xA000]; return Cart_RAM[addr - 0xA000];
} }
else else
{ {
@ -47,7 +47,7 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM != null)
{ {
SetCDLRAM(flags, addr - 0xA000); SetCDLRAM(flags, addr - 0xA000);
} }
@ -72,9 +72,9 @@ namespace GBHawk
} }
else else
{ {
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
Core.cart_RAM[addr - 0xA000] = value; Cart_RAM[addr - 0xA000] = value;
} }
} }
} }

View File

@ -14,13 +14,10 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
uint32_t ROM_mask;
void Reset() void Reset()
{ {
ROM_bank = 1; ROM_bank = 1;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
// some games have sizes that result in a degenerate ROM, account for it here // some games have sizes that result in a degenerate ROM, account for it here
if (ROM_mask > 4) { ROM_mask |= 3; } if (ROM_mask > 4) { ROM_mask |= 3; }
@ -31,12 +28,12 @@ namespace GBHawk
if (addr < 0x4000) if (addr < 0x4000)
{ {
// lowest bank is fixed // lowest bank is fixed
return Core._rom[addr]; return ROM[addr];
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
} }
else else
{ {
@ -86,11 +83,5 @@ namespace GBHawk
{ {
WriteMemory(addr, value); WriteMemory(addr, value);
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
}
}; };
} }

View File

@ -14,9 +14,7 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
bool locked; bool locked;
uint32_t ROM_mask;
uint32_t ROM_bank_mask; uint32_t ROM_bank_mask;
uint32_t BASE_ROM_Bank; uint32_t BASE_ROM_Bank;
bool reg_access; bool reg_access;
@ -26,7 +24,7 @@ namespace GBHawk
void Reset() void Reset()
{ {
ROM_bank = 1; ROM_bank = 1;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
BASE_ROM_Bank = 0; BASE_ROM_Bank = 0;
ROM_bank_mask = 0xFF; ROM_bank_mask = 0xFF;
locked = true; locked = true;
@ -60,11 +58,11 @@ namespace GBHawk
addr |= 0x80; addr |= 0x80;
} }
return Core._rom[addr + BASE_ROM_Bank * 0x4000]; return ROM[addr + BASE_ROM_Bank * 0x4000];
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
} }
else else
{ {
@ -174,17 +172,5 @@ namespace GBHawk
} }
} }
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(locked), ref locked);
ser.Sync(nameof(ROM_bank_mask), ref ROM_bank_mask);
ser.Sync(nameof(BASE_ROM_Bank), ref BASE_ROM_Bank);
ser.Sync(nameof(reg_access), ref reg_access);
ser.Sync(nameof(addr_last), ref addr_last);
ser.Sync(nameof(counter), ref counter);
}
}; };
} }

View File

@ -14,9 +14,7 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
bool locked, locked_GBC, finished; bool locked, locked_GBC, finished;
uint32_t ROM_mask;
uint32_t ROM_bank_mask; uint32_t ROM_bank_mask;
uint32_t BASE_ROM_Bank; uint32_t BASE_ROM_Bank;
bool reg_access; bool reg_access;
@ -26,7 +24,7 @@ namespace GBHawk
void Reset() void Reset()
{ {
ROM_bank = 1; ROM_bank = 1;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
BASE_ROM_Bank = 0; BASE_ROM_Bank = 0;
ROM_bank_mask = 0; ROM_bank_mask = 0;
locked = true; locked = true;
@ -60,14 +58,14 @@ namespace GBHawk
if (locked_GBC) { addr |= 0x80; } if (locked_GBC) { addr |= 0x80; }
return Core._rom[addr + BASE_ROM_Bank * 0x4000]; return ROM[addr + BASE_ROM_Bank * 0x4000];
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
uint32_t temp_bank = (ROM_bank & ~ROM_bank_mask) | (ROM_bank_mask & BASE_ROM_Bank); uint32_t temp_bank = (ROM_bank & ~ROM_bank_mask) | (ROM_bank_mask & BASE_ROM_Bank);
temp_bank &= ROM_mask; temp_bank &= ROM_mask;
return Core._rom[(addr - 0x4000) + temp_bank * 0x4000]; return ROM[(addr - 0x4000) + temp_bank * 0x4000];
} }
else else
{ {
@ -193,8 +191,6 @@ namespace GBHawk
{ {
locked_GBC = false; locked_GBC = false;
finished = true; finished = true;
Console.WriteLine("Finished");
Console.WriteLine(Core.cpu.TotalExecutedCycles);
} }
// The above condition seems to never be reached as described in the mapper notes // The above condition seems to never be reached as described in the mapper notes
@ -204,23 +200,8 @@ namespace GBHawk
{ {
locked_GBC = false; locked_GBC = false;
finished = true; finished = true;
Console.WriteLine("Unlocked");
} }
} }
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(locked), ref locked);
ser.Sync(nameof(locked_GBC), ref locked_GBC);
ser.Sync(nameof(finished), ref finished);
ser.Sync(nameof(ROM_bank_mask), ref ROM_bank_mask);
ser.Sync(nameof(BASE_ROM_Bank), ref BASE_ROM_Bank);
ser.Sync(nameof(reg_access), ref reg_access);
ser.Sync(nameof(addr_last), ref addr_last);
ser.Sync(nameof(counter), ref counter);
}
}; };
} }

View File

@ -14,37 +14,20 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
uint32_t RAM_bank;
uint32_t ROM_mask;
uint32_t RAM_mask;
uint8_t[] RTC_regs = new uint8_t[10];
uint32_t RTC_timer;
uint32_t RTC_low_clock;
bool halt;
uint32_t RTC_offset;
uint32_t ctrl;
uint32_t RAM_addr_low;
uint32_t RAM_addr_high;
uint32_t RAM_val_low;
uint32_t RAM_val_high;
uint8_t Chip_return_low;
uint8_t Chip_return_high;
void Reset() void Reset()
{ {
ROM_bank = 0; ROM_bank = 0;
RAM_bank = 0; RAM_bank = 0;
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = ROM_Length[0] / 0x4000 - 1;
// some games have sizes that result in a degenerate ROM, account for it here // some games have sizes that result in a degenerate ROM, account for it here
if (ROM_mask > 4) { ROM_mask |= 3; } if (ROM_mask > 4) { ROM_mask |= 3; }
RAM_mask = 0; RAM_mask = 0;
if (Core.cart_RAM != null) if (Cart_RAM_Length[0] > 0)
{ {
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1; RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; } if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
} }
RAM_addr_low = RAM_addr_high = RAM_val_low = RAM_val_high = 0; RAM_addr_low = RAM_addr_high = RAM_val_low = RAM_val_high = 0;
@ -58,11 +41,11 @@ namespace GBHawk
{ {
if (addr < 0x4000) if (addr < 0x4000)
{ {
return Core._rom[addr]; return ROM[addr];
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
} }
else else
{ {
@ -127,7 +110,7 @@ namespace GBHawk
break; break;
case 5: case 5:
RAM_val_high = (value & 0xF); RAM_val_high = (value & 0xF);
//Core.cart_RAM[(RAM_addr_high << 4) | RAM_addr_low] = (uint8_t)((RAM_val_high << 4) | RAM_val_low); //Cart_RAM[(RAM_addr_high << 4) | RAM_addr_low] = (uint8_t)((RAM_val_high << 4) | RAM_val_low);
break; break;
case 6: case 6:
RAM_addr_high = (value & 1); RAM_addr_high = (value & 1);
@ -136,24 +119,24 @@ namespace GBHawk
{ {
case 0: case 0:
// write to RAM // write to RAM
Core.cart_RAM[(RAM_addr_high << 4) | RAM_addr_low] = (uint8_t)((RAM_val_high << 4) | RAM_val_low); Cart_RAM[(RAM_addr_high << 4) | RAM_addr_low] = (uint8_t)((RAM_val_high << 4) | RAM_val_low);
break; break;
case 1: case 1:
// read from RAM // read from RAM
Chip_return_high = (uint8_t)(Core.cart_RAM[(RAM_addr_high << 4) | RAM_addr_low] >> 4); Chip_return_high = (uint8_t)(Cart_RAM[(RAM_addr_high << 4) | RAM_addr_low] >> 4);
Chip_return_low = (uint8_t)(Core.cart_RAM[(RAM_addr_high << 4) | RAM_addr_low] & 0xF); Chip_return_low = (uint8_t)(Cart_RAM[(RAM_addr_high << 4) | RAM_addr_low] & 0xF);
break; break;
case 2: case 2:
// read from RTC registers // read from RTC registers
if (RAM_addr_low == 3) if (RAM_addr_low == 3)
{ {
Chip_return_high = RTC_regs[2]; Chip_return_high = RTC_regs_TAMA[2];
Chip_return_low = RTC_regs[1]; Chip_return_low = RTC_regs_TAMA[1];
} }
else if (RAM_addr_low == 6) else if (RAM_addr_low == 6)
{ {
Chip_return_high = RTC_regs[4]; Chip_return_high = RTC_regs_TAMA[4];
Chip_return_low = RTC_regs[3]; Chip_return_low = RTC_regs_TAMA[3];
} }
else else
{ {
@ -165,13 +148,13 @@ namespace GBHawk
// write to RTC registers (probably wrong, not well tested) // write to RTC registers (probably wrong, not well tested)
if (RAM_addr_low == 3) if (RAM_addr_low == 3)
{ {
RTC_regs[2] = (uint8_t)(RAM_val_high & 0xF); RTC_regs_TAMA[2] = (uint8_t)(RAM_val_high & 0xF);
RTC_regs[1] = (uint8_t)(RAM_val_low & 0xF); RTC_regs_TAMA[1] = (uint8_t)(RAM_val_low & 0xF);
} }
else if (RAM_addr_low == 6) else if (RAM_addr_low == 6)
{ {
RTC_regs[4] = (uint8_t)(RAM_val_high & 0xF); RTC_regs_TAMA[4] = (uint8_t)(RAM_val_high & 0xF);
RTC_regs[3] = (uint8_t)(RAM_val_low & 0xF); RTC_regs_TAMA[3] = (uint8_t)(RAM_val_low & 0xF);
} }
else else
{ {
@ -180,7 +163,7 @@ namespace GBHawk
break; break;
case 4: case 4:
// read from seconds register (time changes are checked when it rolls over) // read from seconds register (time changes are checked when it rolls over)
Chip_return_low = (uint8_t)(RTC_regs[0] & 0xF); Chip_return_low = (uint8_t)(RTC_regs_TAMA[0] & 0xF);
break; break;
} }
@ -208,7 +191,7 @@ namespace GBHawk
{ {
if (index < 10) if (index < 10)
{ {
RTC_regs[index] = (uint8_t)value; RTC_regs_TAMA[index] = (uint8_t)value;
} }
else else
{ {
@ -233,32 +216,32 @@ namespace GBHawk
RTC_low_clock = 0; RTC_low_clock = 0;
RTC_timer = RTC_offset; RTC_timer = RTC_offset;
RTC_regs[0]++; RTC_regs_TAMA[0]++;
if (RTC_regs[0] > 59) if (RTC_regs_TAMA[0] > 59)
{ {
RTC_regs[0] = 0; RTC_regs_TAMA[0] = 0;
RTC_regs[1]++; RTC_regs_TAMA[1]++;
// 1's digit of minutes // 1's digit of minutes
if (RTC_regs[1] > 9) if (RTC_regs_TAMA[1] > 9)
{ {
RTC_regs[1] = 0; RTC_regs_TAMA[1] = 0;
RTC_regs[2]++; RTC_regs_TAMA[2]++;
// 10's digit of minutes // 10's digit of minutes
if (RTC_regs[2] > 5) if (RTC_regs_TAMA[2] > 5)
{ {
RTC_regs[2] = 0; RTC_regs_TAMA[2] = 0;
RTC_regs[3]++; RTC_regs_TAMA[3]++;
// 1's digit of hours // 1's digit of hours
if (RTC_regs[3] > 9) if (RTC_regs_TAMA[3] > 9)
{ {
RTC_regs[3] = 0; RTC_regs_TAMA[3] = 0;
RTC_regs[4]++; RTC_regs_TAMA[4]++;
// 10's digit of hours // 10's digit of hours
if (RTC_regs[4] > 2) if (RTC_regs_TAMA[4] > 2)
{ {
RTC_regs[4] = 0; RTC_regs_TAMA[4] = 0;
RTC_regs[5]++; RTC_regs_TAMA[5]++;
} }
} }
} }
@ -268,25 +251,5 @@ namespace GBHawk
} }
} }
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
ser.Sync(nameof(RAM_bank), ref RAM_bank);
ser.Sync(nameof(RAM_mask), ref RAM_mask);
ser.Sync(nameof(halt), ref halt);
ser.Sync(nameof(RTC_regs), ref RTC_regs, false);
ser.Sync(nameof(RTC_timer), ref RTC_timer);
ser.Sync(nameof(RTC_low_clock), ref RTC_low_clock);
ser.Sync(nameof(RTC_offset), ref RTC_offset);
ser.Sync(nameof(ctrl), ref ctrl);
ser.Sync(nameof(RAM_addr_low), ref RAM_addr_low);
ser.Sync(nameof(RAM_addr_high), ref RAM_addr_high);
ser.Sync(nameof(RAM_val_low), ref RAM_val_low);
ser.Sync(nameof(RAM_val_high), ref RAM_val_high);
ser.Sync(nameof(Chip_return_low), ref Chip_return_low);
ser.Sync(nameof(Chip_return_high), ref Chip_return_high);
}
}; };
} }

View File

@ -14,13 +14,10 @@ namespace GBHawk
{ {
public: public:
uint32_t ROM_bank;
uint32_t ROM_mask;
void Reset() void Reset()
{ {
ROM_bank = 0; ROM_bank = 0;
ROM_mask = Core._rom.Length / 0x8000 - 1; ROM_mask = ROM_Length[0] / 0x8000 - 1;
// some games have sizes that result in a degenerate ROM, account for it here // some games have sizes that result in a degenerate ROM, account for it here
if (ROM_mask > 4) { ROM_mask |= 3; } if (ROM_mask > 4) { ROM_mask |= 3; }
@ -31,7 +28,7 @@ namespace GBHawk
{ {
if (addr < 0x8000) if (addr < 0x8000)
{ {
return Core._rom[ROM_bank * 0x8000 + addr]; return ROM[ROM_bank * 0x8000 + addr];
} }
else else
{ {
@ -71,11 +68,5 @@ namespace GBHawk
{ {
WriteMemory(addr, value); WriteMemory(addr, value);
} }
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
}
}; };
} }