c64- clean tabs, document some regs, VIC screen memory fetch added

This commit is contained in:
saxxonpike 2012-11-03 17:57:14 +00:00
parent 747c3db7cb
commit 97bdd9be9c
7 changed files with 1411 additions and 1380 deletions

View File

@ -9,19 +9,19 @@ namespace BizHawk.Emulation.Computers.Commodore64
{ {
public partial class C64 : IEmulator public partial class C64 : IEmulator
{ {
// source // source
public Cartridge cart; public Cartridge cart;
public bool cartInserted; public bool cartInserted;
public byte[] inputFile; public byte[] inputFile;
// chipset // chipset
public Cia cia1; public Cia cia1;
public Cia cia2; public Cia cia2;
public MOS6502X cpu; public MOS6502X cpu;
public Memory mem; public Memory mem;
public Sid sid; public Sid sid;
public VicII vic; public VicII vic;
public VicSignals vicSignal; public VicSignals vicSignal;
private void HardReset() private void HardReset()
{ {
@ -30,50 +30,53 @@ namespace BizHawk.Emulation.Computers.Commodore64
cpu.WriteMemory = WriteMemory; cpu.WriteMemory = WriteMemory;
cpu.DummyReadMemory = PeekMemory; cpu.DummyReadMemory = PeekMemory;
// initialize cia timers // initialize cia timers
cia1 = new Cia(Cia.DummyReadPort, Cia.DummyReadPort, Cia.DummyWritePort, Cia.DummyWritePort); cia1 = new Cia(Cia.DummyReadPort, Cia.DummyReadPort, Cia.DummyWritePort, Cia.DummyWritePort);
cia2 = new Cia(Cia.DummyReadPort, Cia.DummyReadPort, Cia.DummyWritePort, Cia.DummyWritePort); cia2 = new Cia(Cia.DummyReadPort, Cia.DummyReadPort, Cia.DummyWritePort, Cia.DummyWritePort);
// initialize vic // initialize vic
vicSignal = new VicSignals(); vicSignal = new VicSignals();
vic = new VicII(vicSignal, VicIIMode.NTSC); vic = new VicII(vicSignal, VicIIMode.NTSC);
// initialize sid // initialize sid
sid = new Sid(); sid = new Sid();
// initialize memory (this must be done AFTER all other chips are initialized) // initialize memory (this must be done AFTER all other chips are initialized)
string romPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "C64Kernal"); string romPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "C64Kernal");
mem = new Memory(romPath, vic, sid, cia1, cia2); mem = new Memory(romPath, vic, sid, cia1, cia2);
cia2.ReadPortA = mem.CIA2ReadPortA; vic.mem = mem;
cia2.ReadPortB = mem.CIA2ReadPortB;
cia2.WritePortA = mem.CIA2WritePortA;
cia2.WritePortB = mem.CIA2WritePortB;
// initialize media // initialize ports
Cartridge cart = new Cartridge(inputFile); cia2.ReadPortA = mem.CIA2ReadPortA;
if (cart.valid) cia2.ReadPortB = mem.CIA2ReadPortB;
{ cia2.WritePortA = mem.CIA2WritePortA;
mem.ApplyCartridge(cart); cia2.WritePortB = mem.CIA2WritePortB;
}
// initialize cpu (hard reset vector) // initialize media
cpu.PC = (ushort)(ReadMemory(0xFFFC) + (ReadMemory(0xFFFD) << 8)); Cartridge cart = new Cartridge(inputFile);
if (cart.valid)
{
mem.ApplyCartridge(cart);
}
// initialize cpu (hard reset vector)
cpu.PC = (ushort)(ReadMemory(0xFFFC) + (ReadMemory(0xFFFD) << 8));
} }
public byte PeekMemory(ushort addr) public byte PeekMemory(ushort addr)
{ {
return mem.Peek(addr); return mem.Peek(addr);
} }
public byte PeekMemoryInt(int addr) public byte PeekMemoryInt(int addr)
{ {
return mem.Peek((ushort)(addr & 0xFFFF)); return mem.Peek((ushort)(addr & 0xFFFF));
} }
public void PokeMemoryInt(int addr, byte val) public void PokeMemoryInt(int addr, byte val)
{ {
// todo // todo
} }
public byte ReadMemory(ushort addr) public byte ReadMemory(ushort addr)
{ {
@ -82,7 +85,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
public void WriteMemory(ushort addr, byte value) public void WriteMemory(ushort addr, byte value)
{ {
mem.Write(addr, value); mem.Write(addr, value);
} }
} }
} }

View File

@ -11,12 +11,12 @@ namespace BizHawk.Emulation.Computers.Commodore64
{ {
public C64(GameInfo game, byte[] rom, string romextension) public C64(GameInfo game, byte[] rom, string romextension)
{ {
inputFile = rom; inputFile = rom;
SetupMemoryDomains(); SetupMemoryDomains();
CoreOutputComm = new CoreOutputComm(); CoreOutputComm = new CoreOutputComm();
CoreInputComm = new CoreInputComm(); CoreInputComm = new CoreInputComm();
HardReset(); HardReset();
videoProvider = new MyVideoProvider(vic); videoProvider = new MyVideoProvider(vic);
} }
public string SystemId { get { return "C64"; } } public string SystemId { get { return "C64"; } }
@ -88,23 +88,23 @@ namespace BizHawk.Emulation.Computers.Commodore64
_frame++; _frame++;
_islag = true; _islag = true;
int cyclesPerSecond = (14318181 / 14 / 60); int cyclesPerSecond = (14318181 / 14 / 60);
for (int i = 0; i < cyclesPerSecond; i++) for (int i = 0; i < cyclesPerSecond; i++)
{ {
if (vicSignal.Interrupt || cia1.interrupt || cia2.interrupt) if (vicSignal.Interrupt || cia1.interrupt || cia2.interrupt)
{ {
cpu.IRQ = true; cpu.IRQ = true;
} }
if (vicSignal.AllowCpu) if (vicSignal.AllowCpu)
{ {
cpu.ExecuteOne(); cpu.ExecuteOne();
} }
vic.PerformCycle(); vic.PerformCycle();
sid.PerformCycle(); sid.PerformCycle();
cia1.PerformCycle(); cia1.PerformCycle();
cia2.PerformCycle(); cia2.PerformCycle();
} }
if (_islag) if (_islag)
{ {
@ -129,20 +129,20 @@ namespace BizHawk.Emulation.Computers.Commodore64
VicII vic; VicII vic;
public MyVideoProvider(VicII vic) public MyVideoProvider(VicII vic)
{ {
this.vic = vic; this.vic = vic;
buffer = new int[vic.visibleWidth * vic.visibleHeight]; buffer = new int[vic.visibleWidth * vic.visibleHeight];
top = 0; top = 0;
bottom = vic.visibleHeight - 1; bottom = vic.visibleHeight - 1;
left = 0; left = 0;
right = vic.visibleWidth - 1; right = vic.visibleWidth - 1;
} }
int[] buffer; int[] buffer;
public void FillFrameBuffer() public void FillFrameBuffer()
{ {
Array.Copy(vic.buffer, buffer, buffer.Length); Array.Copy(vic.buffer, buffer, buffer.Length);
} }
public int[] GetVideoBuffer() public int[] GetVideoBuffer()
@ -159,7 +159,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
private void SetupMemoryDomains() private void SetupMemoryDomains()
{ {
var domains = new List<MemoryDomain>(1); var domains = new List<MemoryDomain>(1);
domains.Add(new MemoryDomain("RAM", 0x10000, Endian.Little, new Func<int, byte>(PeekMemoryInt), new Action<int,byte>(PokeMemoryInt))); //TODO domains.Add(new MemoryDomain("RAM", 0x10000, Endian.Little, new Func<int, byte>(PeekMemoryInt), new Action<int,byte>(PokeMemoryInt))); //TODO
memoryDomains = domains.AsReadOnly(); memoryDomains = domains.AsReadOnly();
} }

View File

@ -6,135 +6,135 @@ using System.Text;
namespace BizHawk.Emulation.Computers.Commodore64 namespace BizHawk.Emulation.Computers.Commodore64
{ {
public class CartridgeChip public class CartridgeChip
{ {
public int address; public int address;
public int bank; public int bank;
public byte[] data; public byte[] data;
public ushort romMask; public ushort romMask;
public int type; public int type;
} }
public class Cartridge public class Cartridge
{ {
public List<CartridgeChip> chips; public List<CartridgeChip> chips;
public bool exRomPin; public bool exRomPin;
public bool gamePin; public bool gamePin;
public int type; public int type;
public bool valid; public bool valid;
public int version; public int version;
public Cartridge(byte[] rom) public Cartridge(byte[] rom)
{ {
chips = new List<CartridgeChip>(); chips = new List<CartridgeChip>();
if (rom.Length >= 0x50) if (rom.Length >= 0x50)
{ {
MemoryStream source = new MemoryStream(rom); MemoryStream source = new MemoryStream(rom);
BinaryReader reader = new BinaryReader(source); BinaryReader reader = new BinaryReader(source);
string idString; string idString;
// note: cartridge files store values big-endian. // note: cartridge files store values big-endian.
idString = new string(reader.ReadChars(16)); idString = new string(reader.ReadChars(16));
if (idString == "C64 CARTRIDGE ") if (idString == "C64 CARTRIDGE ")
{ {
int headerLength = 0; int headerLength = 0;
headerLength = reader.ReadByte(); headerLength = reader.ReadByte();
headerLength <<= 8; headerLength <<= 8;
headerLength |= reader.ReadByte(); headerLength |= reader.ReadByte();
headerLength <<= 8; headerLength <<= 8;
headerLength |= reader.ReadByte(); headerLength |= reader.ReadByte();
headerLength <<= 8; headerLength <<= 8;
headerLength |= reader.ReadByte(); headerLength |= reader.ReadByte();
version = reader.ReadByte(); version = reader.ReadByte();
version <<= 8; version <<= 8;
version |= reader.ReadByte(); version |= reader.ReadByte();
type = reader.ReadByte(); type = reader.ReadByte();
type <<= 8; type <<= 8;
type |= reader.ReadByte(); type |= reader.ReadByte();
exRomPin = (reader.ReadByte() == 1); exRomPin = (reader.ReadByte() == 1);
gamePin = (reader.ReadByte() == 1); gamePin = (reader.ReadByte() == 1);
reader.ReadBytes(6); // reserved reader.ReadBytes(6); // reserved
reader.ReadBytes(32); // name reader.ReadBytes(32); // name
// skip the rest, don't need this info // skip the rest, don't need this info
if (headerLength > 0x40) if (headerLength > 0x40)
{ {
reader.ReadBytes(headerLength - 0x40); reader.ReadBytes(headerLength - 0x40);
} }
while (source.Position < rom.Length) while (source.Position < rom.Length)
{ {
string chipID = new string(reader.ReadChars(4)); string chipID = new string(reader.ReadChars(4));
if (chipID == "CHIP") if (chipID == "CHIP")
{ {
CartridgeChip chip = new CartridgeChip(); CartridgeChip chip = new CartridgeChip();
int packetLength; int packetLength;
packetLength = reader.ReadByte(); packetLength = reader.ReadByte();
packetLength <<= 8; packetLength <<= 8;
packetLength |= reader.ReadByte(); packetLength |= reader.ReadByte();
packetLength <<= 8; packetLength <<= 8;
packetLength |= reader.ReadByte(); packetLength |= reader.ReadByte();
packetLength <<= 8; packetLength <<= 8;
packetLength |= reader.ReadByte(); packetLength |= reader.ReadByte();
packetLength -= 16; packetLength -= 16;
chip.type = reader.ReadByte(); chip.type = reader.ReadByte();
chip.type <<= 8; chip.type <<= 8;
chip.type |= reader.ReadByte(); chip.type |= reader.ReadByte();
chip.bank = reader.ReadByte(); chip.bank = reader.ReadByte();
chip.bank <<= 8; chip.bank <<= 8;
chip.bank |= reader.ReadByte(); chip.bank |= reader.ReadByte();
chip.address = reader.ReadByte(); chip.address = reader.ReadByte();
chip.address <<= 8; chip.address <<= 8;
chip.address |= reader.ReadByte(); chip.address |= reader.ReadByte();
int size; int size;
size = reader.ReadByte(); size = reader.ReadByte();
size <<= 8; size <<= 8;
size |= reader.ReadByte(); size |= reader.ReadByte();
chip.data = reader.ReadBytes(size); chip.data = reader.ReadBytes(size);
chip.romMask = (ushort)(size - 1); chip.romMask = (ushort)(size - 1);
packetLength -= size; packetLength -= size;
if (packetLength > 0) if (packetLength > 0)
{ {
// discard extra bytes // discard extra bytes
reader.ReadBytes(packetLength); reader.ReadBytes(packetLength);
} }
chips.Add(chip); chips.Add(chip);
} }
else else
{ {
break; break;
} }
} }
valid = (chips.Count > 0); valid = (chips.Count > 0);
} }
} }
} }
public byte Read(ushort addr) public byte Read(ushort addr)
{ {
CartridgeChip currentChip = chips[0]; CartridgeChip currentChip = chips[0];
return currentChip.data[addr & currentChip.romMask]; return currentChip.data[addr & currentChip.romMask];
} }
public void Write(ushort addr, byte val) public void Write(ushort addr, byte val)
{ {
// can't write to rom but we can process DE00/DF00 here // can't write to rom but we can process DE00/DF00 here
} }
} }
} }

View File

@ -5,259 +5,259 @@ using System.Text;
namespace BizHawk.Emulation.Computers.Commodore64 namespace BizHawk.Emulation.Computers.Commodore64
{ {
public class Cia public class Cia
{ {
public int alarmTime; public int alarmTime;
public bool alarmWriteEnabled; public bool alarmWriteEnabled;
public int cycles; public int cycles;
public bool flagPin; public bool flagPin;
public bool flagPinInterrupt; public bool flagPinInterrupt;
public bool flagPinInterruptEnabled; public bool flagPinInterruptEnabled;
public bool[] generatePositiveEdgeOnUnderflow = new bool[2]; public bool[] generatePositiveEdgeOnUnderflow = new bool[2];
public bool interrupt; public bool interrupt;
public bool[] loadStartValue = new bool[2]; public bool[] loadStartValue = new bool[2];
public bool palMode; public bool palMode;
public byte[] regs; public byte[] regs;
public int shiftRegisterCycles; public int shiftRegisterCycles;
public bool shiftRegisterInterrupt; public bool shiftRegisterInterrupt;
public bool shiftRegisterInterruptEnabled; public bool shiftRegisterInterruptEnabled;
public bool shiftRegisterIsOutput; public bool shiftRegisterIsOutput;
public bool[] stopOnUnderflow = new bool[2]; public bool[] stopOnUnderflow = new bool[2];
public int timeOfDay; public int timeOfDay;
public bool timeOfDayAlarmInterrupt; public bool timeOfDayAlarmInterrupt;
public bool timeOfDayAlarmInterruptEnabled; public bool timeOfDayAlarmInterruptEnabled;
public int[] timerConfig = new int[2]; public int[] timerConfig = new int[2];
public bool[] timerEnabled = new bool[2]; public bool[] timerEnabled = new bool[2];
public bool[] timerInterruptEnabled = new bool[2]; public bool[] timerInterruptEnabled = new bool[2];
public ushort[] timerLatch = new ushort[2]; public ushort[] timerLatch = new ushort[2];
public bool[] timerUnderflowMonitor = new bool[2]; public bool[] timerUnderflowMonitor = new bool[2];
public ushort[] timerValue = new ushort[2]; public ushort[] timerValue = new ushort[2];
public bool[] underflowTimerInterrupt = new bool[2]; public bool[] underflowTimerInterrupt = new bool[2];
public bool[] underflowTimerInterruptEnabled = new bool[2]; public bool[] underflowTimerInterruptEnabled = new bool[2];
public Func<byte> ReadPortA; public Func<byte> ReadPortA;
public Func<byte> ReadPortB; public Func<byte> ReadPortB;
public Action<byte, byte> WritePortA; public Action<byte, byte> WritePortA;
public Action<byte, byte> WritePortB; public Action<byte, byte> WritePortB;
public Cia(Func<byte> funcReadPortA, Func<byte> funcReadPortB, Action<byte, byte> actWritePortA, Action<byte, byte> actWritePortB) public Cia(Func<byte> funcReadPortA, Func<byte> funcReadPortB, Action<byte, byte> actWritePortA, Action<byte, byte> actWritePortB)
{ {
ReadPortA = funcReadPortA; ReadPortA = funcReadPortA;
ReadPortB = funcReadPortB; ReadPortB = funcReadPortB;
WritePortA = actWritePortA; WritePortA = actWritePortA;
WritePortB = actWritePortB; WritePortB = actWritePortB;
HardReset(); HardReset();
} }
static public byte DummyReadPort() static public byte DummyReadPort()
{ {
return 0x00; return 0x00;
} }
static public void DummyWritePort(byte val, byte direction) static public void DummyWritePort(byte val, byte direction)
{ {
// do nothing // do nothing
} }
public void HardReset() public void HardReset()
{ {
regs = new byte[0x10]; regs = new byte[0x10];
Write(0x0004, 0xFF); Write(0x0004, 0xFF);
Write(0x0005, 0xFF); Write(0x0005, 0xFF);
Write(0x0006, 0xFF); Write(0x0006, 0xFF);
Write(0x0007, 0xFF); Write(0x0007, 0xFF);
Write(0x000B, 0x01); Write(0x000B, 0x01);
} }
public void PerformCycle() public void PerformCycle()
{ {
unchecked unchecked
{ {
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
if (timerConfig[i] == 0) if (timerConfig[i] == 0)
TimerTick(i); TimerTick(i);
} }
} }
regs[0x04] = (byte)(timerValue[0] & 0xFF); regs[0x04] = (byte)(timerValue[0] & 0xFF);
regs[0x05] = (byte)(timerValue[0] >> 8); regs[0x05] = (byte)(timerValue[0] >> 8);
regs[0x06] = (byte)(timerValue[1] & 0xFF); regs[0x06] = (byte)(timerValue[1] & 0xFF);
regs[0x07] = (byte)(timerValue[1] >> 8); regs[0x07] = (byte)(timerValue[1] >> 8);
} }
public void PollSerial(ref bool bit) public void PollSerial(ref bool bit)
{ {
// this has the same effect as raising CNT // this has the same effect as raising CNT
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
switch (timerConfig[i]) switch (timerConfig[i])
{ {
case 1: case 1:
case 3: case 3:
TimerTick(i); TimerTick(i);
break; break;
} }
} }
if (shiftRegisterIsOutput) if (shiftRegisterIsOutput)
{ {
bit = ((regs[0x0C] & 0x01) != 0x00); bit = ((regs[0x0C] & 0x01) != 0x00);
regs[0x0C] >>= 1; regs[0x0C] >>= 1;
} }
else else
{ {
regs[0x0C] >>= 1; regs[0x0C] >>= 1;
if (bit) if (bit)
regs[0x0C] |= 0x80; regs[0x0C] |= 0x80;
} }
} }
public byte Read(ushort addr) public byte Read(ushort addr)
{ {
byte result = 0; byte result = 0;
addr &= 0x0F; addr &= 0x0F;
switch (addr) switch (addr)
{ {
case 0x00: case 0x00:
result = ReadPortA(); result = ReadPortA();
regs[addr] = result; regs[addr] = result;
break; break;
case 0x01: case 0x01:
result = ReadPortB(); result = ReadPortB();
regs[addr] = result; regs[addr] = result;
break; break;
case 0x0D: case 0x0D:
result = regs[addr]; result = regs[addr];
shiftRegisterInterrupt = false; shiftRegisterInterrupt = false;
timeOfDayAlarmInterrupt = false; timeOfDayAlarmInterrupt = false;
underflowTimerInterrupt[0] = false; underflowTimerInterrupt[0] = false;
underflowTimerInterrupt[1] = false; underflowTimerInterrupt[1] = false;
interrupt = false; interrupt = false;
UpdateInterruptReg(); UpdateInterruptReg();
break; break;
default: default:
result = regs[addr]; result = regs[addr];
break; break;
} }
return result; return result;
} }
public void TimerTick(int index) public void TimerTick(int index)
{ {
if (timerEnabled[index]) if (timerEnabled[index])
{ {
unchecked unchecked
{ {
timerValue[index]--; timerValue[index]--;
} }
if (timerValue[index] == 0xFFFF) if (timerValue[index] == 0xFFFF)
{ {
if (underflowTimerInterruptEnabled[index]) if (underflowTimerInterruptEnabled[index])
{ {
underflowTimerInterrupt[index] = true; underflowTimerInterrupt[index] = true;
interrupt = true; interrupt = true;
} }
// timer B can count on timer A's underflows // timer B can count on timer A's underflows
if (index == 0) if (index == 0)
{ {
switch (timerConfig[1]) switch (timerConfig[1])
{ {
case 2: case 2:
case 3: case 3:
TimerTick(1); TimerTick(1);
break; break;
} }
} }
} }
} }
} }
public void UpdateInterruptReg() public void UpdateInterruptReg()
{ {
byte result; byte result;
result = (byte)(shiftRegisterInterrupt ? 0x01 : 0x00); result = (byte)(shiftRegisterInterrupt ? 0x01 : 0x00);
result |= (byte)(timeOfDayAlarmInterrupt ? 0x02 : 0x00); result |= (byte)(timeOfDayAlarmInterrupt ? 0x02 : 0x00);
result |= (byte)(underflowTimerInterrupt[0] ? 0x04 : 0x00); result |= (byte)(underflowTimerInterrupt[0] ? 0x04 : 0x00);
result |= (byte)(underflowTimerInterrupt[1] ? 0x08 : 0x00); result |= (byte)(underflowTimerInterrupt[1] ? 0x08 : 0x00);
result |= (byte)(flagPinInterrupt ? 0x10 : 0x00); result |= (byte)(flagPinInterrupt ? 0x10 : 0x00);
result |= (byte)(interrupt ? 0x80 : 0x00); result |= (byte)(interrupt ? 0x80 : 0x00);
regs[0x0D] = result; regs[0x0D] = result;
} }
public void Write(ushort addr, byte val) public void Write(ushort addr, byte val)
{ {
bool allowWrite = true; bool allowWrite = true;
addr &= 0x0F; addr &= 0x0F;
switch (addr) switch (addr)
{ {
case 0x00: case 0x00:
WritePortA(val, regs[0x02]); WritePortA(val, regs[0x02]);
allowWrite = false; allowWrite = false;
break; break;
case 0x01: case 0x01:
WritePortB(val, regs[0x03]); WritePortB(val, regs[0x03]);
allowWrite = false; allowWrite = false;
break; break;
case 0x04: case 0x04:
timerValue[0] &= 0xFF00; timerValue[0] &= 0xFF00;
timerValue[0] |= val; timerValue[0] |= val;
break; break;
case 0x05: case 0x05:
timerValue[0] &= 0xFF; timerValue[0] &= 0xFF;
timerValue[0] |= (ushort)(val << 8); timerValue[0] |= (ushort)(val << 8);
break; break;
case 0x06: case 0x06:
timerValue[1] &= 0xFF00; timerValue[1] &= 0xFF00;
timerValue[1] |= val; timerValue[1] |= val;
break; break;
case 0x07: case 0x07:
timerValue[1] &= 0xFF; timerValue[1] &= 0xFF;
timerValue[1] |= (ushort)(val << 8); timerValue[1] |= (ushort)(val << 8);
break; break;
case 0x0D: case 0x0D:
if ((val & 0x01) != 0x00) if ((val & 0x01) != 0x00)
timerInterruptEnabled[0] = ((val & 0x80) != 0x00); timerInterruptEnabled[0] = ((val & 0x80) != 0x00);
if ((val & 0x02) != 0x00) if ((val & 0x02) != 0x00)
timerInterruptEnabled[1] = ((val & 0x80) != 0x00); timerInterruptEnabled[1] = ((val & 0x80) != 0x00);
if ((val & 0x04) != 0x00) if ((val & 0x04) != 0x00)
timeOfDayAlarmInterruptEnabled = ((val & 0x80) != 0x00); timeOfDayAlarmInterruptEnabled = ((val & 0x80) != 0x00);
if ((val & 0x08) != 0x00) if ((val & 0x08) != 0x00)
shiftRegisterInterruptEnabled = ((val & 0x80) != 0x00); shiftRegisterInterruptEnabled = ((val & 0x80) != 0x00);
if ((val & 0x10) != 0x00) if ((val & 0x10) != 0x00)
flagPinInterruptEnabled = ((val & 0x80) != 0x00); flagPinInterruptEnabled = ((val & 0x80) != 0x00);
allowWrite = false; allowWrite = false;
break; break;
case 0x0E: case 0x0E:
timerEnabled[0] = ((val & 0x01) != 0x00); timerEnabled[0] = ((val & 0x01) != 0x00);
timerUnderflowMonitor[0] = ((val & 0x02) != 0x00); timerUnderflowMonitor[0] = ((val & 0x02) != 0x00);
generatePositiveEdgeOnUnderflow[0] = ((val & 0x04) != 0x00); generatePositiveEdgeOnUnderflow[0] = ((val & 0x04) != 0x00);
stopOnUnderflow[0] = ((val & 0x08) != 0x00); stopOnUnderflow[0] = ((val & 0x08) != 0x00);
loadStartValue[0] = ((val & 0x10) != 0x00); loadStartValue[0] = ((val & 0x10) != 0x00);
timerConfig[0] = ((val & 0x20) >> 5); timerConfig[0] = ((val & 0x20) >> 5);
shiftRegisterIsOutput = ((val & 0x40) != 0x00); shiftRegisterIsOutput = ((val & 0x40) != 0x00);
palMode = ((val & 0x80) != 0x00); palMode = ((val & 0x80) != 0x00);
break; break;
case 0x0F: case 0x0F:
timerEnabled[1] = ((val & 0x01) != 0x00); timerEnabled[1] = ((val & 0x01) != 0x00);
timerUnderflowMonitor[1] = ((val & 0x02) != 0x00); timerUnderflowMonitor[1] = ((val & 0x02) != 0x00);
generatePositiveEdgeOnUnderflow[1] = ((val & 0x04) != 0x00); generatePositiveEdgeOnUnderflow[1] = ((val & 0x04) != 0x00);
stopOnUnderflow[1] = ((val & 0x08) != 0x00); stopOnUnderflow[1] = ((val & 0x08) != 0x00);
loadStartValue[1] = ((val & 0x10) != 0x00); loadStartValue[1] = ((val & 0x10) != 0x00);
timerConfig[1] = ((val & 0x60) >> 5); timerConfig[1] = ((val & 0x60) >> 5);
alarmWriteEnabled = ((val & 0x80) != 0x00); alarmWriteEnabled = ((val & 0x80) != 0x00);
break; break;
default: default:
break; break;
} }
if (allowWrite) if (allowWrite)
regs[addr] = val; regs[addr] = val;
} }
} }
} }

View File

@ -6,487 +6,487 @@ using System.Text;
namespace BizHawk.Emulation.Computers.Commodore64 namespace BizHawk.Emulation.Computers.Commodore64
{ {
public enum MemoryDesignation public enum MemoryDesignation
{ {
Disabled, Disabled,
RAM, RAM,
Basic, Basic,
Kernal, Kernal,
IO, IO,
Character, Character,
ROMLo, ROMLo,
ROMHi, ROMHi,
Vic, Vic,
Sid, Sid,
ColorRam, ColorRam,
Cia1, Cia1,
Cia2, Cia2,
Expansion1, Expansion1,
Expansion2 Expansion2
} }
public class MemoryLayout public class MemoryLayout
{ {
public MemoryDesignation Mem1000 = MemoryDesignation.RAM; public MemoryDesignation Mem1000 = MemoryDesignation.RAM;
public MemoryDesignation Mem8000 = MemoryDesignation.RAM; public MemoryDesignation Mem8000 = MemoryDesignation.RAM;
public MemoryDesignation MemA000 = MemoryDesignation.RAM; public MemoryDesignation MemA000 = MemoryDesignation.RAM;
public MemoryDesignation MemC000 = MemoryDesignation.RAM; public MemoryDesignation MemC000 = MemoryDesignation.RAM;
public MemoryDesignation MemD000 = MemoryDesignation.RAM; public MemoryDesignation MemD000 = MemoryDesignation.RAM;
public MemoryDesignation MemE000 = MemoryDesignation.RAM; public MemoryDesignation MemE000 = MemoryDesignation.RAM;
} }
public class Memory public class Memory
{ {
// chips // chips
public Cia cia1; public Cia cia1;
public Cia cia2; public Cia cia2;
public VicII vic; public VicII vic;
public Sid sid; public Sid sid;
// storage // storage
public Cartridge cart; public Cartridge cart;
public bool cartInserted = false; public bool cartInserted = false;
// roms // roms
public byte[] basicRom; public byte[] basicRom;
public byte[] charRom; public byte[] charRom;
public bool exRomPin = true; public bool exRomPin = true;
public bool gamePin = true; public bool gamePin = true;
public byte[] kernalRom; public byte[] kernalRom;
public MemoryLayout layout; public MemoryLayout layout;
// ram // ram
public byte cia2A; public byte cia2A;
public byte cia2B; public byte cia2B;
public byte[] colorRam; public byte[] colorRam;
public byte[] ram; public byte[] ram;
public ushort vicOffset; public ushort vicOffset;
// registers // registers
public byte busData; public byte busData;
public byte cpu00; // register $00 public byte cpu00; // register $00
public byte cpu01; // register $01 public byte cpu01; // register $01
public bool readTrigger = true; public bool readTrigger = true;
public bool writeTrigger = true; public bool writeTrigger = true;
public Memory(string sourceFolder, VicII newVic, Sid newSid, Cia newCia1, Cia newCia2) public Memory(string sourceFolder, VicII newVic, Sid newSid, Cia newCia1, Cia newCia2)
{ {
ram = new byte[0x10000]; ram = new byte[0x10000];
WipeMemory(); WipeMemory();
string basicFile = "basic"; string basicFile = "basic";
string charFile = "chargen"; string charFile = "chargen";
string kernalFile = "kernal"; string kernalFile = "kernal";
basicRom = File.ReadAllBytes(Path.Combine(sourceFolder, basicFile)); basicRom = File.ReadAllBytes(Path.Combine(sourceFolder, basicFile));
charRom = File.ReadAllBytes(Path.Combine(sourceFolder, charFile)); charRom = File.ReadAllBytes(Path.Combine(sourceFolder, charFile));
kernalRom = File.ReadAllBytes(Path.Combine(sourceFolder, kernalFile)); kernalRom = File.ReadAllBytes(Path.Combine(sourceFolder, kernalFile));
colorRam = new byte[0x1000]; colorRam = new byte[0x1000];
vic = newVic; vic = newVic;
sid = newSid; sid = newSid;
cia1 = newCia1; cia1 = newCia1;
cia2 = newCia2; cia2 = newCia2;
cpu00 = 0x2F; cpu00 = 0x2F;
cpu01 = 0x37; cpu01 = 0x37;
layout = new MemoryLayout(); layout = new MemoryLayout();
UpdateLayout(); UpdateLayout();
} }
public void ApplyCartridge(Cartridge newCart) public void ApplyCartridge(Cartridge newCart)
{ {
cart = newCart; cart = newCart;
cartInserted = true; cartInserted = true;
exRomPin = cart.exRomPin; exRomPin = cart.exRomPin;
gamePin = cart.gamePin; gamePin = cart.gamePin;
UpdateLayout(); UpdateLayout();
} }
public byte CIA2ReadPortA() public byte CIA2ReadPortA()
{ {
return cia2A; return cia2A;
} }
public byte CIA2ReadPortB() public byte CIA2ReadPortB()
{ {
return cia2B; return cia2B;
} }
public void CIA2WritePortA(byte val, byte direction) public void CIA2WritePortA(byte val, byte direction)
{ {
cia2A &= (byte)~direction; cia2A &= (byte)~direction;
cia2A |= (byte)(val & direction); cia2A |= (byte)(val & direction);
vicOffset = (ushort)((cia2A & 0x03) << 14); vicOffset = (ushort)((cia2A & 0x03) << 14);
} }
public void CIA2WritePortB(byte val, byte direction) public void CIA2WritePortB(byte val, byte direction)
{ {
cia2B &= (byte)~direction; cia2B &= (byte)~direction;
cia2B |= (byte)(val & direction); cia2B |= (byte)(val & direction);
} }
public MemoryDesignation GetDesignation(ushort addr) public MemoryDesignation GetDesignation(ushort addr)
{ {
MemoryDesignation result; MemoryDesignation result;
if (addr < 0x1000) if (addr < 0x1000)
{ {
result = MemoryDesignation.RAM; result = MemoryDesignation.RAM;
} }
else if (addr < 0x8000) else if (addr < 0x8000)
{ {
result = layout.Mem1000; result = layout.Mem1000;
} }
else if (addr < 0xA000) else if (addr < 0xA000)
{ {
result = layout.Mem8000; result = layout.Mem8000;
} }
else if (addr < 0xC000) else if (addr < 0xC000)
{ {
result = layout.MemA000; result = layout.MemA000;
} }
else if (addr < 0xD000) else if (addr < 0xD000)
{ {
result = layout.MemC000; result = layout.MemC000;
} }
else if (addr < 0xE000) else if (addr < 0xE000)
{ {
result = layout.MemD000; result = layout.MemD000;
} }
else else
{ {
result = layout.MemE000; result = layout.MemE000;
} }
if (result == MemoryDesignation.IO) if (result == MemoryDesignation.IO)
{ {
addr &= 0x0FFF; addr &= 0x0FFF;
if (addr < 0x0400) if (addr < 0x0400)
{ {
result = MemoryDesignation.Vic; result = MemoryDesignation.Vic;
} }
else if (addr < 0x0800) else if (addr < 0x0800)
{ {
result = MemoryDesignation.Sid; result = MemoryDesignation.Sid;
} }
else if (addr < 0x0C00) else if (addr < 0x0C00)
{ {
result = MemoryDesignation.ColorRam; result = MemoryDesignation.ColorRam;
} }
else if (addr < 0x0D00) else if (addr < 0x0D00)
{ {
result = MemoryDesignation.Cia1; result = MemoryDesignation.Cia1;
} }
else if (addr < 0x0E00) else if (addr < 0x0E00)
{ {
result = MemoryDesignation.Cia2; result = MemoryDesignation.Cia2;
} }
else if (addr < 0x0F00) else if (addr < 0x0F00)
{ {
result = MemoryDesignation.Expansion1; result = MemoryDesignation.Expansion1;
} }
else else
{ {
result = MemoryDesignation.Expansion2; result = MemoryDesignation.Expansion2;
} }
} }
return result; return result;
} }
public byte Peek(ushort addr) public byte Peek(ushort addr)
{ {
byte result; byte result;
if (addr == 0x0000) if (addr == 0x0000)
{ {
result = cpu00; result = cpu00;
} }
else if (addr == 0x0001) else if (addr == 0x0001)
{ {
result = cpu01; result = cpu01;
} }
else else
{ {
MemoryDesignation des = GetDesignation(addr); MemoryDesignation des = GetDesignation(addr);
switch (des) switch (des)
{ {
case MemoryDesignation.Basic: case MemoryDesignation.Basic:
result = basicRom[addr & 0x1FFF]; result = basicRom[addr & 0x1FFF];
break; break;
case MemoryDesignation.Character: case MemoryDesignation.Character:
result = charRom[addr & 0x0FFF]; result = charRom[addr & 0x0FFF];
break; break;
case MemoryDesignation.Vic: case MemoryDesignation.Vic:
result = vic.regs[addr & 0x3F]; result = vic.regs[addr & 0x3F];
break; break;
case MemoryDesignation.Sid: case MemoryDesignation.Sid:
result = sid.regs[addr & 0x1F]; result = sid.regs[addr & 0x1F];
break; break;
case MemoryDesignation.ColorRam: case MemoryDesignation.ColorRam:
result = colorRam[addr & 0x03FF]; result = colorRam[addr & 0x03FF];
break; break;
case MemoryDesignation.Cia1: case MemoryDesignation.Cia1:
result = cia1.regs[addr & 0x0F]; result = cia1.regs[addr & 0x0F];
break; break;
case MemoryDesignation.Cia2: case MemoryDesignation.Cia2:
result = cia2.regs[addr & 0x0F]; result = cia2.regs[addr & 0x0F];
break; break;
case MemoryDesignation.Expansion1: case MemoryDesignation.Expansion1:
result = 0; result = 0;
break; break;
case MemoryDesignation.Expansion2: case MemoryDesignation.Expansion2:
result = 0; result = 0;
break; break;
case MemoryDesignation.Kernal: case MemoryDesignation.Kernal:
result = kernalRom[addr & 0x1FFF]; result = kernalRom[addr & 0x1FFF];
break; break;
case MemoryDesignation.RAM: case MemoryDesignation.RAM:
result = ram[addr]; result = ram[addr];
break; break;
case MemoryDesignation.ROMHi: case MemoryDesignation.ROMHi:
result = cart.chips[0].data[addr & cart.chips[0].romMask]; result = cart.chips[0].data[addr & cart.chips[0].romMask];
break; break;
case MemoryDesignation.ROMLo: case MemoryDesignation.ROMLo:
result = cart.chips[0].data[addr & cart.chips[0].romMask]; result = cart.chips[0].data[addr & cart.chips[0].romMask];
break; break;
default: default:
return 0; return 0;
} }
} }
busData = result; busData = result;
return result; return result;
} }
public byte Read(ushort addr) public byte Read(ushort addr)
{ {
byte result; byte result;
if (addr == 0x0000) if (addr == 0x0000)
{ {
result = cpu00; result = cpu00;
} }
else if (addr == 0x0001) else if (addr == 0x0001)
{ {
result = cpu01; result = cpu01;
} }
else else
{ {
MemoryDesignation des = GetDesignation(addr); MemoryDesignation des = GetDesignation(addr);
switch (des) switch (des)
{ {
case MemoryDesignation.Basic: case MemoryDesignation.Basic:
result = basicRom[addr & 0x1FFF]; result = basicRom[addr & 0x1FFF];
break; break;
case MemoryDesignation.Character: case MemoryDesignation.Character:
result = charRom[addr & 0x0FFF]; result = charRom[addr & 0x0FFF];
break; break;
case MemoryDesignation.Vic: case MemoryDesignation.Vic:
result = vic.Read(addr); result = vic.Read(addr);
break; break;
case MemoryDesignation.Sid: case MemoryDesignation.Sid:
result = sid.Read(addr); result = sid.Read(addr);
break; break;
case MemoryDesignation.ColorRam: case MemoryDesignation.ColorRam:
result = ReadColorRam(addr); result = ReadColorRam(addr);
break; break;
case MemoryDesignation.Cia1: case MemoryDesignation.Cia1:
result = cia1.Read(addr); result = cia1.Read(addr);
break; break;
case MemoryDesignation.Cia2: case MemoryDesignation.Cia2:
result = cia2.Read(addr); result = cia2.Read(addr);
break; break;
case MemoryDesignation.Expansion1: case MemoryDesignation.Expansion1:
result = 0; result = 0;
break; break;
case MemoryDesignation.Expansion2: case MemoryDesignation.Expansion2:
result = 0; result = 0;
break; break;
case MemoryDesignation.Kernal: case MemoryDesignation.Kernal:
result = kernalRom[addr & 0x1FFF]; result = kernalRom[addr & 0x1FFF];
break; break;
case MemoryDesignation.RAM: case MemoryDesignation.RAM:
result = ram[addr]; result = ram[addr];
break; break;
case MemoryDesignation.ROMHi: case MemoryDesignation.ROMHi:
result = cart.Read(addr); result = cart.Read(addr);
break; break;
case MemoryDesignation.ROMLo: case MemoryDesignation.ROMLo:
result = cart.Read(addr); result = cart.Read(addr);
break; break;
default: default:
return 0; return 0;
} }
} }
busData = result; busData = result;
return result; return result;
} }
public byte ReadColorRam(ushort addr) public byte ReadColorRam(ushort addr)
{ {
return (byte)((busData & 0xF0) | (colorRam[addr & 0x03FF])); return (byte)((busData & 0xF0) | (colorRam[addr & 0x03FF]));
} }
public void UpdateLayout() public void UpdateLayout()
{ {
bool loRom = ((cpu01 & 0x01) != 0); bool loRom = ((cpu01 & 0x01) != 0);
bool hiRom = ((cpu01 & 0x02) != 0); bool hiRom = ((cpu01 & 0x02) != 0);
bool ioEnable = ((cpu01 & 0x04) != 0); bool ioEnable = ((cpu01 & 0x04) != 0);
if (loRom && hiRom && exRomPin && gamePin) if (loRom && hiRom && exRomPin && gamePin)
{ {
layout.Mem1000 = MemoryDesignation.RAM; layout.Mem1000 = MemoryDesignation.RAM;
layout.Mem8000 = MemoryDesignation.RAM; layout.Mem8000 = MemoryDesignation.RAM;
layout.MemA000 = MemoryDesignation.Basic; layout.MemA000 = MemoryDesignation.Basic;
layout.MemC000 = MemoryDesignation.RAM; layout.MemC000 = MemoryDesignation.RAM;
layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character; layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character;
layout.MemE000 = MemoryDesignation.Kernal; layout.MemE000 = MemoryDesignation.Kernal;
} }
else if (loRom && !hiRom && exRomPin) else if (loRom && !hiRom && exRomPin)
{ {
layout.Mem1000 = MemoryDesignation.RAM; layout.Mem1000 = MemoryDesignation.RAM;
layout.Mem8000 = MemoryDesignation.RAM; layout.Mem8000 = MemoryDesignation.RAM;
layout.MemA000 = MemoryDesignation.RAM; layout.MemA000 = MemoryDesignation.RAM;
layout.MemC000 = MemoryDesignation.RAM; layout.MemC000 = MemoryDesignation.RAM;
layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character; layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character;
layout.MemE000 = MemoryDesignation.RAM; layout.MemE000 = MemoryDesignation.RAM;
} }
else if (loRom && !hiRom && !exRomPin && !gamePin) else if (loRom && !hiRom && !exRomPin && !gamePin)
{ {
layout.Mem1000 = MemoryDesignation.RAM; layout.Mem1000 = MemoryDesignation.RAM;
layout.Mem8000 = MemoryDesignation.RAM; layout.Mem8000 = MemoryDesignation.RAM;
layout.MemA000 = MemoryDesignation.RAM; layout.MemA000 = MemoryDesignation.RAM;
layout.MemC000 = MemoryDesignation.RAM; layout.MemC000 = MemoryDesignation.RAM;
layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.RAM; layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.RAM;
layout.MemE000 = MemoryDesignation.RAM; layout.MemE000 = MemoryDesignation.RAM;
} }
else if ((!loRom && hiRom && gamePin) || (!loRom && !hiRom && !exRomPin)) else if ((!loRom && hiRom && gamePin) || (!loRom && !hiRom && !exRomPin))
{ {
layout.Mem1000 = MemoryDesignation.RAM; layout.Mem1000 = MemoryDesignation.RAM;
layout.Mem8000 = MemoryDesignation.RAM; layout.Mem8000 = MemoryDesignation.RAM;
layout.MemA000 = MemoryDesignation.RAM; layout.MemA000 = MemoryDesignation.RAM;
layout.MemC000 = MemoryDesignation.RAM; layout.MemC000 = MemoryDesignation.RAM;
layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character; layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character;
layout.MemE000 = MemoryDesignation.Kernal; layout.MemE000 = MemoryDesignation.Kernal;
} }
else if (!loRom && !hiRom && gamePin) else if (!loRom && !hiRom && gamePin)
{ {
layout.Mem1000 = MemoryDesignation.RAM; layout.Mem1000 = MemoryDesignation.RAM;
layout.Mem8000 = MemoryDesignation.RAM; layout.Mem8000 = MemoryDesignation.RAM;
layout.MemA000 = MemoryDesignation.RAM; layout.MemA000 = MemoryDesignation.RAM;
layout.MemC000 = MemoryDesignation.RAM; layout.MemC000 = MemoryDesignation.RAM;
layout.MemD000 = MemoryDesignation.RAM; layout.MemD000 = MemoryDesignation.RAM;
layout.MemE000 = MemoryDesignation.RAM; layout.MemE000 = MemoryDesignation.RAM;
} }
else if (loRom && hiRom && gamePin && !exRomPin) else if (loRom && hiRom && gamePin && !exRomPin)
{ {
layout.Mem1000 = MemoryDesignation.RAM; layout.Mem1000 = MemoryDesignation.RAM;
layout.Mem8000 = MemoryDesignation.ROMLo; layout.Mem8000 = MemoryDesignation.ROMLo;
layout.MemA000 = MemoryDesignation.Basic; layout.MemA000 = MemoryDesignation.Basic;
layout.MemC000 = MemoryDesignation.RAM; layout.MemC000 = MemoryDesignation.RAM;
layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character; layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character;
layout.MemE000 = MemoryDesignation.Kernal; layout.MemE000 = MemoryDesignation.Kernal;
} }
else if (!loRom && hiRom && !gamePin && !exRomPin) else if (!loRom && hiRom && !gamePin && !exRomPin)
{ {
layout.Mem1000 = MemoryDesignation.RAM; layout.Mem1000 = MemoryDesignation.RAM;
layout.Mem8000 = MemoryDesignation.RAM; layout.Mem8000 = MemoryDesignation.RAM;
layout.MemA000 = MemoryDesignation.ROMHi; layout.MemA000 = MemoryDesignation.ROMHi;
layout.MemC000 = MemoryDesignation.RAM; layout.MemC000 = MemoryDesignation.RAM;
layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character; layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character;
layout.MemE000 = MemoryDesignation.Kernal; layout.MemE000 = MemoryDesignation.Kernal;
} }
else if (loRom && hiRom && !gamePin && !exRomPin) else if (loRom && hiRom && !gamePin && !exRomPin)
{ {
layout.Mem1000 = MemoryDesignation.RAM; layout.Mem1000 = MemoryDesignation.RAM;
layout.Mem8000 = MemoryDesignation.ROMLo; layout.Mem8000 = MemoryDesignation.ROMLo;
layout.MemA000 = MemoryDesignation.ROMHi; layout.MemA000 = MemoryDesignation.ROMHi;
layout.MemC000 = MemoryDesignation.RAM; layout.MemC000 = MemoryDesignation.RAM;
layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character; layout.MemD000 = ioEnable ? MemoryDesignation.IO : MemoryDesignation.Character;
layout.MemE000 = MemoryDesignation.Kernal; layout.MemE000 = MemoryDesignation.Kernal;
} }
else if (!gamePin && exRomPin) else if (!gamePin && exRomPin)
{ {
layout.Mem1000 = MemoryDesignation.Disabled; layout.Mem1000 = MemoryDesignation.Disabled;
layout.Mem8000 = MemoryDesignation.ROMLo; layout.Mem8000 = MemoryDesignation.ROMLo;
layout.MemA000 = MemoryDesignation.Disabled; layout.MemA000 = MemoryDesignation.Disabled;
layout.MemC000 = MemoryDesignation.Disabled; layout.MemC000 = MemoryDesignation.Disabled;
layout.MemD000 = MemoryDesignation.IO; layout.MemD000 = MemoryDesignation.IO;
layout.MemE000 = MemoryDesignation.ROMHi; layout.MemE000 = MemoryDesignation.ROMHi;
} }
} }
public byte VicRead(ushort addr) public byte VicRead(ushort addr)
{ {
addr = (ushort)(addr & 0x1FFF); addr = (ushort)(addr & 0x1FFF);
if (addr >= 0x1000 && addr < 0x2000) if (addr >= 0x1000 && addr < 0x2000)
return charRom[addr & 0x0FFF]; return charRom[addr & 0x0FFF];
else else
return ram[addr | vicOffset]; return ram[addr | vicOffset];
} }
public void WipeMemory() public void WipeMemory()
{ {
for (int i = 0; i < 0x10000; i += 0x80) for (int i = 0; i < 0x10000; i += 0x80)
{ {
for (int j = 0; j < 0x40; j++) for (int j = 0; j < 0x40; j++)
ram[i + j] = 0x00; ram[i + j] = 0x00;
for (int j = 0x40; j < 0x80; j++) for (int j = 0x40; j < 0x80; j++)
ram[i + j] = 0xFF; ram[i + j] = 0xFF;
} }
} }
public void Write(ushort addr, byte val) public void Write(ushort addr, byte val)
{ {
if (addr == 0x0000) if (addr == 0x0000)
{ {
cpu00 = val; cpu00 = val;
} }
else if (addr == 0x0001) else if (addr == 0x0001)
{ {
cpu01 &= (byte)(~cpu00); cpu01 &= (byte)(~cpu00);
cpu01 |= (byte)(cpu00 & val); cpu01 |= (byte)(cpu00 & val);
UpdateLayout(); UpdateLayout();
} }
else else
{ {
MemoryDesignation des = GetDesignation(addr); MemoryDesignation des = GetDesignation(addr);
switch (des) switch (des)
{ {
case MemoryDesignation.Vic: case MemoryDesignation.Vic:
vic.Write(addr, val); vic.Write(addr, val);
break; break;
case MemoryDesignation.Sid: case MemoryDesignation.Sid:
sid.Write(addr, val); sid.Write(addr, val);
break; break;
case MemoryDesignation.ColorRam: case MemoryDesignation.ColorRam:
colorRam[addr & 0x03FF] = (byte)(val & 0x0F); colorRam[addr & 0x03FF] = (byte)(val & 0x0F);
break; break;
case MemoryDesignation.Cia1: case MemoryDesignation.Cia1:
cia1.Write(addr, val); cia1.Write(addr, val);
break; break;
case MemoryDesignation.Cia2: case MemoryDesignation.Cia2:
cia2.Write(addr, val); cia2.Write(addr, val);
break; break;
case MemoryDesignation.Expansion1: case MemoryDesignation.Expansion1:
break; break;
case MemoryDesignation.Expansion2: case MemoryDesignation.Expansion2:
break; break;
case MemoryDesignation.RAM: case MemoryDesignation.RAM:
ram[addr] = val; ram[addr] = val;
break; break;
default: default:
break; break;
} }
} }
busData = val; busData = val;
} }
} }
} }

View File

@ -5,41 +5,41 @@ using System.Text;
namespace BizHawk.Emulation.Computers.Commodore64 namespace BizHawk.Emulation.Computers.Commodore64
{ {
public enum SidMode public enum SidMode
{ {
Sid6581, Sid6581,
Sid8580 Sid8580
} }
public class Sid public class Sid
{ {
public byte[] regs; public byte[] regs;
public Sid() public Sid()
{ {
regs = new byte[0x20]; regs = new byte[0x20];
} }
public void PerformCycle() public void PerformCycle()
{ {
} }
public byte Read(ushort addr) public byte Read(ushort addr)
{ {
switch (addr & 0x1F) switch (addr & 0x1F)
{ {
default: default:
return 0; return 0;
} }
} }
public void Write(ushort addr, byte val) public void Write(ushort addr, byte val)
{ {
switch (addr & 0x1F) switch (addr & 0x1F)
{ {
default: default:
break; break;
} }
} }
} }
} }

File diff suppressed because it is too large Load Diff