diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj
index bffa4d9258..dddf4adbe9 100644
--- a/BizHawk.Emulation/BizHawk.Emulation.csproj
+++ b/BizHawk.Emulation/BizHawk.Emulation.csproj
@@ -82,6 +82,7 @@
+
diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.core.cs b/BizHawk.Emulation/Computers/Commodore64/C64.core.cs
index 7b0147d6da..24d8423fb9 100644
--- a/BizHawk.Emulation/Computers/Commodore64/C64.core.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/C64.core.cs
@@ -62,9 +62,16 @@ namespace BizHawk.Emulation.Computers.Commodore64
mediaAttached.Add(new PRGFile(inputFile, mem, cpu));
break;
case @".CRT":
- Cartridge cart = new Cartridge(inputFile);
- if (cart.valid)
+ Cartridge newCart = new Cartridge(inputFile, mem);
+ if (newCart.valid)
+ {
+ cart = newCart;
mediaAttached.Add(cart);
+ }
+ else
+ {
+ cart = null;
+ }
break;
}
diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.cs b/BizHawk.Emulation/Computers/Commodore64/C64.cs
index 6be347e354..85182764a7 100644
--- a/BizHawk.Emulation/Computers/Commodore64/C64.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/C64.cs
@@ -93,7 +93,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
{
if (!media.Loaded() && media.Ready())
{
- media.Apply(mem);
+ media.Apply();
}
}
diff --git a/BizHawk.Emulation/Computers/Commodore64/Cartridge.cs b/BizHawk.Emulation/Computers/Commodore64/Cartridge.cs
index 092b078b11..f165856464 100644
--- a/BizHawk.Emulation/Computers/Commodore64/Cartridge.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/Cartridge.cs
@@ -15,19 +15,26 @@ namespace BizHawk.Emulation.Computers.Commodore64
public int type;
}
- public class Cartridge : IMedia
+ public partial class Cartridge : IMedia
{
+ public Func Read;
+ public Func ReadPort;
+ public Action WritePort;
+
public List chips;
public bool exRomPin;
public bool gamePin;
+ public CartridgeChip selectedChip;
public int type;
public bool valid;
public int version;
private bool loaded;
+ private Memory mem;
- public Cartridge(byte[] rom)
+ public Cartridge(byte[] rom, Memory memory)
{
+ mem = memory;
chips = new List();
if (rom.Length >= 0x50)
@@ -131,18 +138,19 @@ namespace BizHawk.Emulation.Computers.Commodore64
}
valid = (chips.Count > 0);
+
+ if (valid)
+ UpdateMapper();
}
reader.Close();
source.Dispose();
}
}
- public void Apply(Memory mem)
+ public void Apply()
{
mem.cart = this;
- mem.exRomPin = exRomPin;
- mem.gamePin = gamePin;
- mem.UpdateLayout();
+ UpdateRomPins();
loaded = true;
}
@@ -151,10 +159,9 @@ namespace BizHawk.Emulation.Computers.Commodore64
return loaded;
}
- public byte Read(ushort addr)
+ private byte ReadDummy(ushort addr)
{
- CartridgeChip currentChip = chips[0];
- return currentChip.data[addr & currentChip.romMask];
+ return 0;
}
public bool Ready()
@@ -162,9 +169,31 @@ namespace BizHawk.Emulation.Computers.Commodore64
return true;
}
- public void Write(ushort addr, byte val)
+ private void UpdateMapper()
+ {
+ Read = ReadDummy;
+ ReadPort = ReadDummy;
+ WritePort = WriteDummy;
+
+ switch (type)
+ {
+ case 0x0000:
+ Read = Read0000;
+ ReadPort = ReadPort0000;
+ WritePort = WritePort0000;
+ break;
+ }
+ }
+
+ private void UpdateRomPins()
+ {
+ mem.exRomPin = exRomPin;
+ mem.gamePin = gamePin;
+ mem.UpdateLayout();
+ }
+
+ private void WriteDummy(ushort addr, byte val)
{
- // can't write to rom but we can process DE00/DF00 here
}
}
}
diff --git a/BizHawk.Emulation/Computers/Commodore64/CartridgeMappers.cs b/BizHawk.Emulation/Computers/Commodore64/CartridgeMappers.cs
new file mode 100644
index 0000000000..25c22f7ede
--- /dev/null
+++ b/BizHawk.Emulation/Computers/Commodore64/CartridgeMappers.cs
@@ -0,0 +1,419 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Emulation.Computers.Commodore64
+{
+ public partial class Cartridge : IMedia
+ {
+ public int bank;
+
+ private byte Read0000(ushort addr)
+ {
+ // standard cart, no banking
+ CartridgeChip currentChip = chips[0];
+ return currentChip.data[addr & currentChip.romMask];
+ }
+
+ private byte Read0001(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0002(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0003(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0004(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0005(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0006(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0007(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0008(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0009(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read000A(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read000B(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read000C(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read000D(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read000E(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read000F(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0010(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0011(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0012(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0013(ushort addr)
+ {
+
+ return 0;
+ }
+
+ private byte Read0014(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0015(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0016(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0017(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0018(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read0019(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read001A(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte Read001B(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0000(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0001(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0002(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0003(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0004(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0005(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0006(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0007(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0008(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0009(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort000A(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort000B(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort000C(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort000D(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort000E(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort000F(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0010(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0011(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0012(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0013(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0014(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0015(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0016(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0017(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0018(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort0019(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort001A(ushort addr)
+ {
+ return 0;
+ }
+
+ private byte ReadPort001B(ushort addr)
+ {
+ return 0;
+ }
+
+ private void WritePort0000(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0001(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0002(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0003(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0004(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0005(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0006(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0007(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0008(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0009(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort000A(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort000B(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort000C(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort000D(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort000E(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort000F(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0010(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0011(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0012(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0013(ushort addr, byte val)
+ {
+ bank = (val & 0x7F) % chips.Count;
+ if ((bank & 0x80) != 0x00)
+ {
+ exRomPin = false;
+ gamePin = false;
+ }
+ else
+ {
+ exRomPin = true;
+ gamePin = false;
+ }
+ UpdateRomPins();
+ }
+
+ private void WritePort0014(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0015(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0016(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0017(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0018(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort0019(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort001A(ushort addr, byte val)
+ {
+ }
+
+ private void WritePort001B(ushort addr, byte val)
+ {
+ }
+ }
+}
diff --git a/BizHawk.Emulation/Computers/Commodore64/IMedia.cs b/BizHawk.Emulation/Computers/Commodore64/IMedia.cs
index 4e9420e929..2e1e89f70e 100644
--- a/BizHawk.Emulation/Computers/Commodore64/IMedia.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/IMedia.cs
@@ -7,7 +7,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
{
public interface IMedia
{
- void Apply(Memory mem);
+ void Apply();
bool Loaded();
bool Ready();
}
diff --git a/BizHawk.Emulation/Computers/Commodore64/MemBus.cs b/BizHawk.Emulation/Computers/Commodore64/MemBus.cs
index e900f5ed11..f84882b17e 100644
--- a/BizHawk.Emulation/Computers/Commodore64/MemBus.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/MemBus.cs
@@ -228,7 +228,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
result = sid.regs[addr & 0x1F];
break;
case MemoryDesignation.ColorRam:
- result = colorRam[addr & 0x03FF];
+ result = (byte)(colorRam[addr & 0x03FF] | (busData & 0xF0));
break;
case MemoryDesignation.Cia0:
result = cia0.regs[addr & 0x0F];
@@ -249,10 +249,10 @@ namespace BizHawk.Emulation.Computers.Commodore64
result = ram[addr];
break;
case MemoryDesignation.ROMHi:
- result = cart.chips[0].data[addr & cart.chips[0].romMask];
+ result = cart.chips[cart.bank].data[addr & cart.chips[cart.bank].romMask];
break;
case MemoryDesignation.ROMLo:
- result = cart.chips[0].data[addr & cart.chips[0].romMask];
+ result = cart.chips[cart.bank].data[addr & cart.chips[cart.bank].romMask];
break;
default:
return 0;
@@ -303,7 +303,10 @@ namespace BizHawk.Emulation.Computers.Commodore64
result = cia1.Read(addr);
break;
case MemoryDesignation.Expansion0:
- result = 0;
+ if (cart != null)
+ result = cart.ReadPort(addr);
+ else
+ result = 0;
break;
case MemoryDesignation.Expansion1:
result = 0;
@@ -455,6 +458,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
public void WipeMemory()
{
+ // memory is striped in sections 00/FF
for (int i = 0; i < 0x10000; i += 0x80)
{
for (int j = 0; j < 0x40; j++)
@@ -501,6 +505,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
cia1.Write(addr, val);
break;
case MemoryDesignation.Expansion0:
+ if (cart != null)
+ cart.WritePort(addr, val);
break;
case MemoryDesignation.Expansion1:
break;
diff --git a/BizHawk.Emulation/Computers/Commodore64/PRGFile.cs b/BizHawk.Emulation/Computers/Commodore64/PRGFile.cs
index fbe3fd6de2..245a40df46 100644
--- a/BizHawk.Emulation/Computers/Commodore64/PRGFile.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/PRGFile.cs
@@ -20,7 +20,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
data = file;
}
- public void Apply(Memory mem)
+ public void Apply()
{
int address = data[1];
address <<= 8;
@@ -34,24 +34,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
address++;
}
- //// "RUN"
- //mem[0x04F0] = 0x12;
- //mem[0x04F1] = 0x15;
- //mem[0x04F2] = 0x0E;
-
- //// set cursor to be right after run (3, 6)
- //mem[0x00C9] = 0x06;
- //mem[0x00CA] = 0x03;
- //mem[0x00D3] = 0x03;
- //mem[0x00D6] = 0x06;
-
- //// set keyboard buffer
- //mem[0x00C5] = 0x0D;
- //mem[0x00C6] = 0x02;
- //mem[0x00CB] = 0x0D;
- //mem[0x0277] = 0x0D;
- //mem[0x0278] = 0x0D;
-
if (data[0x06] == 0x9E)
{
// sys command