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)
{
@ -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()
{
}
@ -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:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
uint32_t ROM_mask;
uint32_t RAM_mask;
bool regs_enable;
uint8_t regs[0x80] = {};
@ -27,9 +23,9 @@ namespace GBHawk
ROM_bank = 1;
RAM_bank = 0;
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;
}
@ -38,11 +34,11 @@ namespace GBHawk
{
if (addr < 0x4000)
{
return Core._rom[addr];
return ROM[addr];
}
else if (addr < 0x8000)
{
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
}
else
{
@ -59,9 +55,9 @@ namespace GBHawk
}
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
{
@ -87,7 +83,7 @@ namespace GBHawk
{
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);
}
@ -140,9 +136,9 @@ namespace GBHawk
}
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);
}
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)
{
return Core._rom[addr];
return ROM[addr];
}
else
{
if (Core.cart_RAM != null)
if (Cart_RAM_Length > 0)
{
return Core.cart_RAM[addr - 0xA000];
return Cart_RAM[addr - 0xA000];
}
else
{
@ -47,7 +47,7 @@ namespace GBHawk
}
else
{
if (Core.cart_RAM != null)
if (Cart_RAM != null)
{
SetCDLRAM(flags, addr - 0xA000);
}
@ -72,9 +72,9 @@ namespace GBHawk
}
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:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
uint32_t ROM_mask;
uint32_t RAM_mask;
bool IR_signal;
void Reset()
{
ROM_bank = 0;
RAM_bank = 0;
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
if (ROM_mask > 4) { ROM_mask |= 3; }
RAM_mask = 0;
if (Core.cart_RAM != null)
if (Cart_RAM_Length[0] > 0)
{
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; }
RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
}
}
@ -43,21 +36,21 @@ namespace GBHawk
{
if (addr < 0x4000)
{
return Core._rom[addr];
return ROM[addr];
}
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))
{
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
{
@ -97,9 +90,9 @@ namespace GBHawk
{
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);
}
@ -156,11 +149,11 @@ namespace GBHawk
{
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);
}
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:
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()
{
ROM_bank = 0;
RAM_bank = 0;
RAM_enable = false;
ROM_mask = Core._rom.Length / 0x4000 - 1;
ROM_mask = ROM_Length[0] / 0x4000 - 1;
control = 0;
chip_read = 1;
timer_read = false;
@ -44,10 +29,10 @@ namespace GBHawk
if (ROM_mask > 4) { ROM_mask |= 3; }
RAM_mask = 0;
if (Core.cart_RAM != null)
if (Cart_RAM_Length[0] > 0)
{
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; }
RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
}
}
@ -55,11 +40,11 @@ namespace GBHawk
{
if (addr < 0x4000)
{
return Core._rom[addr];
return ROM[addr];
}
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))
{
@ -74,11 +59,11 @@ namespace GBHawk
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
{
@ -117,9 +102,9 @@ namespace GBHawk
{
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);
}
@ -177,11 +162,11 @@ namespace GBHawk
{
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 < 28)
{
time |= (uint)((value & 0x0F) << time_val_shift);
time |= (uint32_t)((value & 0x0F) << time_val_shift);
time_val_shift += 4;
if (time_val_shift == 28) { timer_read = true; }
}
@ -253,7 +238,7 @@ namespace GBHawk
void RTC_Get(uint32_t value, uint32_t index)
{
time |= (uint)((value & 0xFF) << index);
time |= (uint32_t)((value & 0xFF) << index);
}
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:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
bool sel_mode;
uint32_t ROM_mask;
uint32_t RAM_mask;
void Reset()
{
ROM_bank = 1;
RAM_bank = 0;
RAM_enable = 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
if (ROM_mask > 4) { ROM_mask |= 3; }
RAM_mask = 0;
if (Core.cart_RAM != null)
if (Cart_RAM_Length[0] > 0)
{
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; }
RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
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
if (sel_mode)
{
return Core._rom[(ROM_bank & 0x60) * 0x4000 + addr];
return ROM[(ROM_bank & 0x60) * 0x4000 + addr];
}
else
{
return Core._rom[addr];
return ROM[addr];
}
}
else if (addr < 0x8000)
{
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
}
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
{
@ -100,9 +93,9 @@ namespace GBHawk
}
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);
}
@ -146,7 +139,7 @@ namespace GBHawk
}
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 &= RAM_mask;
@ -162,7 +155,7 @@ namespace GBHawk
{
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 &= ROM_mask;
@ -175,11 +168,11 @@ namespace GBHawk
}
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);
}
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:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
bool sel_mode;
uint32_t ROM_mask;
uint32_t RAM_mask;
void Reset()
{
ROM_bank = 1;
RAM_bank = 0;
RAM_enable = 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;
if (Core.cart_RAM != null)
if (Cart_RAM_Length[0] > 0)
{
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; }
RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
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
if (sel_mode)
{
return Core._rom[((ROM_bank & 0x60) >> 1) * 0x4000 + addr];
return ROM[((ROM_bank & 0x60) >> 1) * 0x4000 + addr];
}
else
{
return Core._rom[addr];
return ROM[addr];
}
}
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
{
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
{
@ -96,9 +89,9 @@ namespace GBHawk
}
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);
}
@ -142,7 +135,7 @@ namespace GBHawk
}
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 &= RAM_mask;
@ -158,7 +151,7 @@ namespace GBHawk
{
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 &= ROM_mask;
@ -171,11 +164,11 @@ namespace GBHawk
}
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);
}
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:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
uint32_t ROM_mask;
void Reset()
{
ROM_bank = 1;
RAM_bank = 0;
RAM_enable = false;
ROM_mask = Core._rom.Length / 0x4000 - 1;
ROM_mask = ROM_Length[0] / 0x4000 - 1;
}
uint8_t ReadMemory(uint32_t addr)
{
if (addr < 0x4000)
{
return Core._rom[addr];
return ROM[addr];
}
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))
{
if (RAM_enable)
{
return Core.cart_RAM[addr - 0xA000];
return Cart_RAM[addr - 0xA000];
}
return 0xFF;
}
@ -103,7 +98,7 @@ namespace GBHawk
{
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);
}
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:
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()
{
ROM_bank = 1;
RAM_bank = 0;
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
if (ROM_mask > 4) { ROM_mask |= 3; }
RAM_mask = 0;
if (Core.cart_RAM != null)
if (Cart_RAM_Length[0] > 0)
{
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; }
RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
}
RTC_regs_latch[0] = 0;
@ -57,21 +44,21 @@ namespace GBHawk
{
if (addr < 0x4000)
{
return Core._rom[addr];
return ROM[addr];
}
else if (addr < 0x8000)
{
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
}
else
{
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
{
@ -111,9 +98,9 @@ namespace GBHawk
{
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);
}
@ -184,11 +171,11 @@ namespace GBHawk
{
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))
@ -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:
uint32_t ROM_bank;
uint32_t RAM_bank;
bool RAM_enable;
uint32_t ROM_mask;
uint32_t RAM_mask;
void Reset()
{
ROM_bank = 1;
RAM_bank = 0;
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
if (ROM_mask > 4) { ROM_mask |= 3; }
if (ROM_mask > 0x100) { ROM_mask |= 0xFF; }
RAM_mask = 0;
if (Core.cart_RAM != null)
if (Cart_RAM_Length[0] > 0)
{
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; }
RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
}
}
@ -43,19 +37,19 @@ namespace GBHawk
{
if (addr < 0x4000)
{
return Core._rom[addr];
return ROM[addr];
}
else if (addr < 0x8000)
{
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
}
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
{
@ -83,9 +77,9 @@ namespace GBHawk
}
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);
}
@ -140,11 +134,11 @@ namespace GBHawk
}
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);
}
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)
{
return Core._rom[addr];
return ROM[addr];
}
else
{
if (Core.cart_RAM != null)
if (Cart_RAM_Length[0] > 0)
{
return Core.cart_RAM[addr - 0xA000];
return Cart_RAM[addr - 0xA000];
}
else
{
@ -47,7 +47,7 @@ namespace GBHawk
}
else
{
if (Core.cart_RAM != null)
if (Cart_RAM != null)
{
SetCDLRAM(flags, addr - 0xA000);
}
@ -72,9 +72,9 @@ namespace GBHawk
}
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:
uint32_t ROM_bank;
bool RAM_enable_1, RAM_enable_2;
uint32_t ROM_mask;
uint8_t acc_x_low;
uint8_t acc_x_high;
uint8_t acc_y_low;
@ -45,7 +43,7 @@ namespace GBHawk
{
ROM_bank = 1;
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
if (ROM_mask > 4) { ROM_mask |= 3; }
@ -67,11 +65,11 @@ namespace GBHawk
{
if (addr < 0x4000)
{
return Core._rom[addr];
return ROM[addr];
}
else if (addr < 0x8000)
{
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
}
else if (addr < 0xA000)
{
@ -170,35 +168,6 @@ namespace GBHawk
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)
{
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 CLK = value.Bit(6);
@ -349,7 +318,7 @@ namespace GBHawk
{
for (uint32_t i = 0; i < 256; i++)
{
Core.cart_RAM[i] = 0xFF;
Cart_RAM[i] = 0xFF;
}
}
DO = true;
@ -373,8 +342,8 @@ namespace GBHawk
instr_case = 6;
if (WR_EN)
{
Core.cart_RAM[EE_addr * 2] = 0xFF;
Core.cart_RAM[EE_addr * 2 + 1] = 0xFF;
Cart_RAM[EE_addr * 2] = 0xFF;
Cart_RAM[EE_addr * 2 + 1] = 0xFF;
}
DO = true;
break;
@ -405,8 +374,8 @@ namespace GBHawk
{
for (uint32_t i = 0; i < 128; i++)
{
Core.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] = (uint8_t)(EE_value & 0xFF);
Cart_RAM[i * 2 + 1] = (uint8_t)((EE_value & 0xFF00) >> 8);
}
}
instr_case = 7;
@ -421,8 +390,8 @@ namespace GBHawk
{
if (WR_EN)
{
Core.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] = (uint8_t)(EE_value & 0xFF);
Cart_RAM[EE_addr * 2 + 1] = (uint8_t)((EE_value & 0xFF00) >> 8);
}
instr_case = 7;
countdown = 8;
@ -432,11 +401,11 @@ namespace GBHawk
case 5:
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))
{
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)

View File

@ -23,13 +23,13 @@ namespace GBHawk
{
if (addr < 0x8000)
{
return Core._rom[addr];
return ROM[addr];
}
else
{
if (Core.cart_RAM != null)
if (Cart_RAM_Length[0] > 0)
{
return Core.cart_RAM[addr - 0xA000];
return Cart_RAM[addr - 0xA000];
}
else
{
@ -47,7 +47,7 @@ namespace GBHawk
}
else
{
if (Core.cart_RAM != null)
if (Cart_RAM != null)
{
SetCDLRAM(flags, addr - 0xA000);
}
@ -72,9 +72,9 @@ namespace GBHawk
}
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:
uint32_t ROM_bank;
uint32_t ROM_mask;
void Reset()
{
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
if (ROM_mask > 4) { ROM_mask |= 3; }
@ -31,12 +28,12 @@ namespace GBHawk
if (addr < 0x4000)
{
// lowest bank is fixed
return Core._rom[addr];
return ROM[addr];
}
else if (addr < 0x8000)
{
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
}
else
{
@ -86,11 +83,5 @@ namespace GBHawk
{
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:
uint32_t ROM_bank;
bool locked;
uint32_t ROM_mask;
uint32_t ROM_bank_mask;
uint32_t BASE_ROM_Bank;
bool reg_access;
@ -26,7 +24,7 @@ namespace GBHawk
void Reset()
{
ROM_bank = 1;
ROM_mask = Core._rom.Length / 0x4000 - 1;
ROM_mask = ROM_Length[0] / 0x4000 - 1;
BASE_ROM_Bank = 0;
ROM_bank_mask = 0xFF;
locked = true;
@ -60,11 +58,11 @@ namespace GBHawk
addr |= 0x80;
}
return Core._rom[addr + BASE_ROM_Bank * 0x4000];
return ROM[addr + BASE_ROM_Bank * 0x4000];
}
else if (addr < 0x8000)
{
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
}
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:
uint32_t ROM_bank;
bool locked, locked_GBC, finished;
uint32_t ROM_mask;
uint32_t ROM_bank_mask;
uint32_t BASE_ROM_Bank;
bool reg_access;
@ -26,7 +24,7 @@ namespace GBHawk
void Reset()
{
ROM_bank = 1;
ROM_mask = Core._rom.Length / 0x4000 - 1;
ROM_mask = ROM_Length[0] / 0x4000 - 1;
BASE_ROM_Bank = 0;
ROM_bank_mask = 0;
locked = true;
@ -60,14 +58,14 @@ namespace GBHawk
if (locked_GBC) { addr |= 0x80; }
return Core._rom[addr + BASE_ROM_Bank * 0x4000];
return ROM[addr + BASE_ROM_Bank * 0x4000];
}
else if (addr < 0x8000)
{
uint32_t temp_bank = (ROM_bank & ~ROM_bank_mask) | (ROM_bank_mask & BASE_ROM_Bank);
temp_bank &= ROM_mask;
return Core._rom[(addr - 0x4000) + temp_bank * 0x4000];
return ROM[(addr - 0x4000) + temp_bank * 0x4000];
}
else
{
@ -193,8 +191,6 @@ namespace GBHawk
{
locked_GBC = false;
finished = true;
Console.WriteLine("Finished");
Console.WriteLine(Core.cpu.TotalExecutedCycles);
}
// The above condition seems to never be reached as described in the mapper notes
@ -204,23 +200,8 @@ namespace GBHawk
{
locked_GBC = false;
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:
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()
{
ROM_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
if (ROM_mask > 4) { ROM_mask |= 3; }
RAM_mask = 0;
if (Core.cart_RAM != null)
if (Cart_RAM_Length[0] > 0)
{
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; }
RAM_mask = Cart_RAM_Length[0] / 0x2000 - 1;
if (Cart_RAM_Length[0] == 0x800) { RAM_mask = 0; }
}
RAM_addr_low = RAM_addr_high = RAM_val_low = RAM_val_high = 0;
@ -58,11 +41,11 @@ namespace GBHawk
{
if (addr < 0x4000)
{
return Core._rom[addr];
return ROM[addr];
}
else if (addr < 0x8000)
{
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
return ROM[(addr - 0x4000) + ROM_bank * 0x4000];
}
else
{
@ -127,7 +110,7 @@ namespace GBHawk
break;
case 5:
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;
case 6:
RAM_addr_high = (value & 1);
@ -136,24 +119,24 @@ namespace GBHawk
{
case 0:
// 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;
case 1:
// read from RAM
Chip_return_high = (uint8_t)(Core.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_high = (uint8_t)(Cart_RAM[(RAM_addr_high << 4) | RAM_addr_low] >> 4);
Chip_return_low = (uint8_t)(Cart_RAM[(RAM_addr_high << 4) | RAM_addr_low] & 0xF);
break;
case 2:
// read from RTC registers
if (RAM_addr_low == 3)
{
Chip_return_high = RTC_regs[2];
Chip_return_low = RTC_regs[1];
Chip_return_high = RTC_regs_TAMA[2];
Chip_return_low = RTC_regs_TAMA[1];
}
else if (RAM_addr_low == 6)
{
Chip_return_high = RTC_regs[4];
Chip_return_low = RTC_regs[3];
Chip_return_high = RTC_regs_TAMA[4];
Chip_return_low = RTC_regs_TAMA[3];
}
else
{
@ -165,13 +148,13 @@ namespace GBHawk
// write to RTC registers (probably wrong, not well tested)
if (RAM_addr_low == 3)
{
RTC_regs[2] = (uint8_t)(RAM_val_high & 0xF);
RTC_regs[1] = (uint8_t)(RAM_val_low & 0xF);
RTC_regs_TAMA[2] = (uint8_t)(RAM_val_high & 0xF);
RTC_regs_TAMA[1] = (uint8_t)(RAM_val_low & 0xF);
}
else if (RAM_addr_low == 6)
{
RTC_regs[4] = (uint8_t)(RAM_val_high & 0xF);
RTC_regs[3] = (uint8_t)(RAM_val_low & 0xF);
RTC_regs_TAMA[4] = (uint8_t)(RAM_val_high & 0xF);
RTC_regs_TAMA[3] = (uint8_t)(RAM_val_low & 0xF);
}
else
{
@ -180,7 +163,7 @@ namespace GBHawk
break;
case 4:
// 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;
}
@ -208,7 +191,7 @@ namespace GBHawk
{
if (index < 10)
{
RTC_regs[index] = (uint8_t)value;
RTC_regs_TAMA[index] = (uint8_t)value;
}
else
{
@ -233,32 +216,32 @@ namespace GBHawk
RTC_low_clock = 0;
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[1]++;
RTC_regs_TAMA[0] = 0;
RTC_regs_TAMA[1]++;
// 1's digit of minutes
if (RTC_regs[1] > 9)
if (RTC_regs_TAMA[1] > 9)
{
RTC_regs[1] = 0;
RTC_regs[2]++;
RTC_regs_TAMA[1] = 0;
RTC_regs_TAMA[2]++;
// 10's digit of minutes
if (RTC_regs[2] > 5)
if (RTC_regs_TAMA[2] > 5)
{
RTC_regs[2] = 0;
RTC_regs[3]++;
RTC_regs_TAMA[2] = 0;
RTC_regs_TAMA[3]++;
// 1's digit of hours
if (RTC_regs[3] > 9)
if (RTC_regs_TAMA[3] > 9)
{
RTC_regs[3] = 0;
RTC_regs[4]++;
RTC_regs_TAMA[3] = 0;
RTC_regs_TAMA[4]++;
// 10's digit of hours
if (RTC_regs[4] > 2)
if (RTC_regs_TAMA[4] > 2)
{
RTC_regs[4] = 0;
RTC_regs[5]++;
RTC_regs_TAMA[4] = 0;
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:
uint32_t ROM_bank;
uint32_t ROM_mask;
void Reset()
{
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
if (ROM_mask > 4) { ROM_mask |= 3; }
@ -31,7 +28,7 @@ namespace GBHawk
{
if (addr < 0x8000)
{
return Core._rom[ROM_bank * 0x8000 + addr];
return ROM[ROM_bank * 0x8000 + addr];
}
else
{
@ -71,11 +68,5 @@ namespace GBHawk
{
WriteMemory(addr, value);
}
void SyncState(Serializer ser)
{
ser.Sync(nameof(ROM_bank), ref ROM_bank);
ser.Sync(nameof(ROM_mask), ref ROM_mask);
}
};
}