commodore64: G64 disk format support

This commit is contained in:
saxxonpike 2012-11-14 01:50:17 +00:00
parent 7bd469d514
commit d29eecb4f6
6 changed files with 226 additions and 1 deletions

View File

@ -87,6 +87,8 @@
<Compile Include="Computers\Commodore64\CartridgeMappers.cs" />
<Compile Include="Computers\Commodore64\Cia.cs" />
<Compile Include="Computers\Commodore64\DataPort.cs" />
<Compile Include="Computers\Commodore64\Disk.cs" />
<Compile Include="Computers\Commodore64\G64.cs" />
<Compile Include="Computers\Commodore64\IMedia.cs" />
<Compile Include="Computers\Commodore64\Input.cs" />
<Compile Include="Computers\Commodore64\PRGFile.cs" />

View File

@ -12,21 +12,136 @@ namespace BizHawk.Emulation.Computers.Commodore64
//
// 2kb ram, mapped 0000-07FF
// two 6522 VIA chips, mapped at 1800 (communication to C64) and 1C00 (drive mechanics)
// drive ROM, mapped C000-FFFF
public MOS6502X cpu;
public int cyclesPerRevolution;
public int cyclesPerSecond;
public Disk disk;
public byte[] ram;
public byte[] rom;
public double rpm;
public Via via0;
public Via via1;
public Drive1541()
public Drive1541(byte[] driveRom, Region driveRegion)
{
rom = new byte[driveRom.Length];
Array.Copy(driveRom, rom, driveRom.Length);
switch (driveRegion)
{
case Region.NTSC:
cyclesPerSecond = 14318181 / 14;
break;
case Region.PAL:
cyclesPerSecond = 14318181 / 18;
break;
}
HardReset();
}
public void Eject()
{
disk = null;
}
public void HardReset()
{
cpu = new MOS6502X();
ram = new byte[0x800];
via0 = new Via();
via1 = new Via();
SetRPM(300.0);
}
public void Insert(Disk newDisk)
{
disk = newDisk;
}
public byte Peek(ushort addr)
{
if (addr < 0x0800)
{
return ram[addr];
}
else if (addr >= 0x1800 && addr < 0x1810)
{
return via0.regs[addr];
}
else if (addr >= 0x1C00 && addr < 0x1C10)
{
return via1.regs[addr];
}
else if (addr >= 0xC000)
{
return rom[addr & 0x3FFF];
}
return 0xFF;
}
public void PerformCycle()
{
}
public void Poke(ushort addr, byte val)
{
if (addr < 0x0800)
{
ram[addr] = val;
}
else if (addr >= 0x1800 && addr < 0x1810)
{
via0.regs[addr] = val;
}
else if (addr >= 0x1C00 && addr < 0x1C10)
{
via1.regs[addr] = val;
}
}
public byte Read(ushort addr)
{
if (addr < 0x0800)
{
return ram[addr];
}
else if (addr >= 0x1800 && addr < 0x1810)
{
return via0.regs[addr];
}
else if (addr >= 0x1C00 && addr < 0x1C10)
{
return via1.regs[addr];
}
else if (addr >= 0xC000)
{
return rom[addr & 0x3FFF];
}
return 0xFF;
}
public void SetRPM(double newRPM)
{
rpm = newRPM;
cyclesPerRevolution = (int)((double)cyclesPerSecond / newRPM / (double)60);
}
public void Write(ushort addr, byte val)
{
if (addr < 0x0800)
{
ram[addr] = val;
}
else if (addr >= 0x1800 && addr < 0x1810)
{
via0.regs[addr] = val;
}
else if (addr >= 0x1C00 && addr < 0x1C10)
{
via1.regs[addr] = val;
}
}
}
}

View File

@ -20,6 +20,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
// source
public Cartridge cart;
public Drive1541 diskDrive;
public string extension;
public byte[] inputFile;
public List<IMedia> mediaAttached = new List<IMedia>();
@ -74,6 +75,13 @@ namespace BizHawk.Emulation.Computers.Commodore64
// initialize media
switch (extension.ToUpper())
{
case @".G64":
diskDrive = new Drive1541(File.ReadAllBytes(Path.Combine(romPath, @"1541dos")), Region.NTSC);
diskDrive.Insert(G64.Read(inputFile));
break;
case @".D64":
diskDrive = new Drive1541(File.ReadAllBytes(Path.Combine(romPath, @"1541dos")), Region.NTSC);
break;
case @".PRG":
if (inputFile.Length > 2)
mediaAttached.Add(new PRGFile(inputFile, mem, cpu));

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Computers.Commodore64
{
public class Disk
{
public class Track
{
public int bits;
public byte[] data;
public int density;
public int index;
}
public List<Track> tracks = new List<Track>();
public bool valid;
}
}

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Computers.Commodore64
{
public static class G64
{
public static Disk Read(byte[] source)
{
MemoryStream mem = new MemoryStream(source);
BinaryReader reader = new BinaryReader(mem);
Disk result = new Disk();
string id = new string(reader.ReadChars(8));
if (id == @"GCR-1541")
{
int trackCount;
int[] trackOffsetTable = new int[84];
int[] trackSpeedTable = new int[84];
reader.ReadByte(); //version
trackCount = reader.ReadByte();
reader.ReadInt16(); //max track size in bytes
for (int i = 0; i < 84; i++)
trackOffsetTable[i] = reader.ReadInt32();
for (int i = 0; i < 84; i++)
trackSpeedTable[i] = reader.ReadInt32();
for (int i = 0; i < 84; i++)
{
if (trackOffsetTable[i] > 0)
{
int trackLength;
byte[] trackData;
Disk.Track track = new Disk.Track();
mem.Position = trackOffsetTable[i];
trackLength = reader.ReadInt16();
trackData = reader.ReadBytes(trackLength);
track.bits = trackLength * 8;
track.data = trackData;
track.density = trackSpeedTable[i];
track.index = i;
result.tracks.Add(track);
}
}
}
result.valid = (result.tracks.Count > 0);
return result;
}
public static void Write(Disk source)
{
}
}
}

View File

@ -18,6 +18,23 @@ namespace BizHawk.Emulation.Computers.Commodore64
public int SR;
public int[] TC;
public int[] TL;
public ViaRegs()
{
// power on state
}
public byte this[int addr]
{
get
{
return 0xFF;
}
set
{
// set register
}
}
}
public class Via