- Reorganize Sachen Mappers
- Add Sachen MMC1 support (Captain Knick Knack)
This commit is contained in:
alyosha-tas 2018-04-10 09:19:29 -04:00
parent f2529fa0e0
commit 0e4887b2f7
8 changed files with 131 additions and 105 deletions

View File

@ -117,7 +117,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// These things do not change speed in GBC double spped mode // These things do not change speed in GBC double spped mode
audio.tick(); audio.tick();
ppu.tick(); ppu.tick();
if (Use_RTC) { mapper.RTC_Tick(); } if (Use_MT) { mapper.Mapper_Tick(); }
if (!HDMA_transfer) if (!HDMA_transfer)
{ {

View File

@ -94,7 +94,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("speed_switch", ref speed_switch); ser.Sync("speed_switch", ref speed_switch);
ser.Sync("HDMA_transfer", ref HDMA_transfer); ser.Sync("HDMA_transfer", ref HDMA_transfer);
ser.Sync("Use_RTC", ref Use_RTC); ser.Sync("Use_MT", ref Use_MT);
ser.Sync("addr_access", ref addr_access);
// probably a better way to do this // probably a better way to do this
if (cart_RAM != null) if (cart_RAM != null)

View File

@ -68,7 +68,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
private int _frame = 0; private int _frame = 0;
public bool Use_RTC; public bool Use_MT;
public ushort addr_access;
public MapperBase mapper; public MapperBase mapper;
@ -373,6 +374,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
Console.WriteLine("Using RockMan 8 (Unlicensed) Mapper"); Console.WriteLine("Using RockMan 8 (Unlicensed) Mapper");
mapper = new MapperRM8(); mapper = new MapperRM8();
} }
if ((_rom.HashMD5(0, _rom.Length) == "D3C1924D847BC5D125BF54C2076BE27A"))
{
Console.WriteLine("Using Sachen 1 (Unlicensed) Mapper");
mapper = new MapperSachen1();
mppr = "Schn1";
}
Console.Write("Mapper: "); Console.Write("Mapper: ");
Console.WriteLine(mppr); Console.WriteLine(mppr);
@ -407,6 +414,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if ((mppr == "Schn1") || (mppr == "Schn2")) if ((mppr == "Schn1") || (mppr == "Schn2"))
{ {
cart_RAM = null; cart_RAM = null;
Use_MT = true;
} }
// mbc2 carts have built in RAM // mbc2 carts have built in RAM
@ -438,7 +446,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// Extra RTC initialization for mbc3 // Extra RTC initialization for mbc3
if (mppr == "MBC3") if (mppr == "MBC3")
{ {
Use_RTC = true; Use_MT = true;
int days = (int)Math.Floor(_syncSettings.RTCInitialTime / 86400.0); int days = (int)Math.Floor(_syncSettings.RTCInitialTime / 86400.0);
int days_upper = ((days & 0x100) >> 8) | ((days & 0x200) >> 2); int days_upper = ((days & 0x100) >> 8) | ((days & 0x200) >> 2);

View File

@ -37,7 +37,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{ {
} }
public virtual void RTC_Tick() public virtual void Mapper_Tick()
{ {
} }

View File

@ -158,7 +158,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
RTC_regs[index] = value; RTC_regs[index] = value;
} }
public override void RTC_Tick() public override void Mapper_Tick()
{ {
if (!halt) if (!halt)
{ {

View File

@ -17,6 +17,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public int ROM_bank_mask; public int ROM_bank_mask;
public int BASE_ROM_Bank; public int BASE_ROM_Bank;
public bool reg_access; public bool reg_access;
public ushort addr_last;
public int counter;
public override void Initialize() public override void Initialize()
{ {
@ -26,37 +28,33 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ROM_bank_mask = 0xFF; ROM_bank_mask = 0xFF;
locked = true; locked = true;
reg_access = false; reg_access = false;
addr_last = 0;
counter = 0;
} }
public override byte ReadMemory(ushort addr) public override byte ReadMemory(ushort addr)
{ {
if (addr < 0x4000) if (addr < 0x4000)
{ {
ushort t_addr = addr; if (locked)
// header is scrambled
if ((addr >= 0x100) && (addr < 0x200))
{ {
int temp0 = (addr & 1); // header is scrambled
int temp1 = (addr & 2); if ((addr >= 0x100) && (addr < 0x200))
int temp4 = (addr & 0x10); {
int temp6 = (addr & 0x40); int temp0 = (addr & 1);
int temp1 = (addr & 2);
int temp4 = (addr & 0x10);
int temp6 = (addr & 0x40);
temp0 = temp0 << 6; temp0 = temp0 << 6;
temp1 = temp1 << 3; temp1 = temp1 << 3;
temp4 = temp4 >> 3; temp4 = temp4 >> 3;
temp6 = temp6 >> 6; temp6 = temp6 >> 6;
addr &= 0x1AC; addr &= 0x1AC;
addr |= (ushort)(temp0 | temp1 | temp4 | temp6); addr |= (ushort)(temp0 | temp1 | temp4 | temp6);
} }
addr |= 0x80;
if (locked) { addr |= 0x80; }
if (t_addr == 0x133)
{
locked = false;
Console.WriteLine("cleared");
} }
return Core._rom[addr + BASE_ROM_Bank * 0x4000]; return Core._rom[addr + BASE_ROM_Bank * 0x4000];
@ -73,39 +71,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public override byte PeekMemory(ushort addr) public override byte PeekMemory(ushort addr)
{ {
if (addr < 0x4000) return ReadMemory(addr);
{
ushort t_addr = addr;
// header is scrambled
if ((addr >= 0x100) && (addr < 0x200))
{
int temp0 = (addr & 1);
int temp1 = (addr & 2);
int temp4 = (addr & 0x10);
int temp6 = (addr & 0x40);
temp0 = temp0 << 6;
temp1 = temp1 << 3;
temp4 = temp4 >> 3;
temp6 = temp6 >> 6;
addr &= 0x1AC;
addr |= (ushort)(temp0 | temp1 | temp4 | temp6);
}
if (locked) { addr |= 0x80; }
return Core._rom[addr + BASE_ROM_Bank * 0x4000];
}
else if (addr < 0x8000)
{
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
}
else
{
return 0xFF;
}
} }
public override void WriteMemory(ushort addr, byte value) public override void WriteMemory(ushort addr, byte value)
@ -144,6 +110,29 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
WriteMemory(addr, value); WriteMemory(addr, value);
} }
public override void Mapper_Tick()
{
if (locked)
{
if (((Core.addr_access & 0x8000) == 0) && ((addr_last & 0x8000) > 0) && (Core.addr_access >= 0x100))
{
counter++;
Console.WriteLine(Core.cpu.TotalExecutedCycles);
}
if (Core.addr_access >= 0x100)
{
addr_last = Core.addr_access;
}
if (counter == 0x30)
{
locked = false;
Console.WriteLine("Unlocked");
}
}
}
public override void SyncState(Serializer ser) public override void SyncState(Serializer ser)
{ {
ser.Sync("ROM_Bank", ref ROM_bank); ser.Sync("ROM_Bank", ref ROM_bank);
@ -152,6 +141,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("ROM_bank_mask", ref ROM_bank_mask); ser.Sync("ROM_bank_mask", ref ROM_bank_mask);
ser.Sync("BASE_ROM_Bank", ref BASE_ROM_Bank); ser.Sync("BASE_ROM_Bank", ref BASE_ROM_Bank);
ser.Sync("reg_access", ref reg_access); ser.Sync("reg_access", ref reg_access);
ser.Sync("addr_last", ref addr_last);
ser.Sync("counter", ref counter);
} }
} }
} }

View File

@ -12,11 +12,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
class MapperSachen2 : MapperBase class MapperSachen2 : MapperBase
{ {
public int ROM_bank; public int ROM_bank;
public bool locked; public bool locked, locked_GBC, finished;
public int ROM_mask; public int ROM_mask;
public int ROM_bank_mask; public int ROM_bank_mask;
public int BASE_ROM_Bank; public int BASE_ROM_Bank;
public bool reg_access; public bool reg_access;
public ushort addr_last;
public int counter;
public override void Initialize() public override void Initialize()
{ {
@ -24,16 +26,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ROM_mask = Core._rom.Length / 0x4000 - 1; ROM_mask = Core._rom.Length / 0x4000 - 1;
BASE_ROM_Bank = 0; BASE_ROM_Bank = 0;
ROM_bank_mask = 0; ROM_bank_mask = 0;
locked = false; locked = true;
locked_GBC = false;
finished = false;
reg_access = false; reg_access = false;
addr_last = 0;
counter = 0;
} }
public override byte ReadMemory(ushort addr) public override byte ReadMemory(ushort addr)
{ {
if (addr < 0x4000) if (addr < 0x4000)
{ {
ushort t_addr = addr;
// header is scrambled // header is scrambled
if ((addr >= 0x100) && (addr < 0x200)) if ((addr >= 0x100) && (addr < 0x200))
{ {
@ -51,12 +55,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
addr |= (ushort)(temp0 | temp1 | temp4 | temp6); addr |= (ushort)(temp0 | temp1 | temp4 | temp6);
} }
if (locked) { addr |= 0x80; } if (locked_GBC) { addr |= 0x80; }
if (t_addr == 0x133)
{
if ((Core.GB_bios_register & 0x1) == 0) { locked ^= true; }
}
return Core._rom[addr + BASE_ROM_Bank * 0x4000]; return Core._rom[addr + BASE_ROM_Bank * 0x4000];
} }
@ -75,39 +74,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public override byte PeekMemory(ushort addr) public override byte PeekMemory(ushort addr)
{ {
if (addr < 0x4000) return ReadMemory(addr);
{
ushort t_addr = addr;
// header is scrambled
if ((addr >= 0x100) && (addr < 0x200))
{
int temp0 = (addr & 1);
int temp1 = (addr & 2);
int temp4 = (addr & 0x10);
int temp6 = (addr & 0x40);
temp0 = temp0 << 6;
temp1 = temp1 << 3;
temp4 = temp4 >> 3;
temp6 = temp6 >> 6;
addr &= 0x1AC;
addr |= (ushort)(temp0 | temp1 | temp4 | temp6);
}
if (locked) { addr |= 0x80; }
return Core._rom[addr + BASE_ROM_Bank * 0x4000];
}
else if (addr < 0x8000)
{
return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000];
}
else
{
return 0xFF;
}
} }
public override void WriteMemory(ushort addr, byte value) public override void WriteMemory(ushort addr, byte value)
@ -146,14 +113,71 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
WriteMemory(addr, value); WriteMemory(addr, value);
} }
public override void Mapper_Tick()
{
if (locked)
{
if (((Core.addr_access & 0x8000) == 0) && ((addr_last & 0x8000) > 0) && (Core.addr_access >= 0x100))
{
counter++;
}
if (Core.addr_access >= 0x100)
{
addr_last = Core.addr_access;
}
if (counter == 0x30)
{
locked = false;
locked_GBC = true;
counter = 0;
}
}
else if (locked_GBC)
{
if (((Core.addr_access & 0x8000) == 0) && ((addr_last & 0x8000) > 0) && (Core.addr_access >= 0x100))
{
counter++;
}
if (Core.addr_access >= 0x100)
{
addr_last = Core.addr_access;
}
if (counter == 0x30)
{
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
// so for now add this one
if ((Core.addr_access == 0x133) && (counter == 1))
{
locked_GBC = false;
finished = true;
Console.WriteLine("Unlocked");
}
}
}
public override void SyncState(Serializer ser) public override void SyncState(Serializer ser)
{ {
ser.Sync("ROM_Bank", ref ROM_bank); ser.Sync("ROM_Bank", ref ROM_bank);
ser.Sync("ROM_Mask", ref ROM_mask); ser.Sync("ROM_Mask", ref ROM_mask);
ser.Sync("locked", ref locked); ser.Sync("locked", ref locked);
ser.Sync("locked_GBC", ref locked_GBC);
ser.Sync("finished", ref finished);
ser.Sync("ROM_bank_mask", ref ROM_bank_mask); ser.Sync("ROM_bank_mask", ref ROM_bank_mask);
ser.Sync("BASE_ROM_Bank", ref BASE_ROM_Bank); ser.Sync("BASE_ROM_Bank", ref BASE_ROM_Bank);
ser.Sync("reg_access", ref reg_access); ser.Sync("reg_access", ref reg_access);
ser.Sync("addr_last", ref addr_last);
ser.Sync("counter", ref counter);
} }
} }
} }

View File

@ -30,6 +30,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public byte ReadMemory(ushort addr) public byte ReadMemory(ushort addr)
{ {
MemoryCallbacks.CallReads(addr, "System Bus"); MemoryCallbacks.CallReads(addr, "System Bus");
addr_access = addr;
if (ppu.DMA_start) if (ppu.DMA_start)
{ {
@ -150,7 +151,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public void WriteMemory(ushort addr, byte value) public void WriteMemory(ushort addr, byte value)
{ {
MemoryCallbacks.CallWrites(addr, "System Bus"); MemoryCallbacks.CallWrites(addr, "System Bus");
addr_access = addr;
if (ppu.DMA_start) if (ppu.DMA_start)
{ {
// some of gekkio's tests require this to be accessible during DMA // some of gekkio's tests require this to be accessible during DMA