commodore64: G64 disk format support
This commit is contained in:
parent
7bd469d514
commit
d29eecb4f6
|
@ -87,6 +87,8 @@
|
||||||
<Compile Include="Computers\Commodore64\CartridgeMappers.cs" />
|
<Compile Include="Computers\Commodore64\CartridgeMappers.cs" />
|
||||||
<Compile Include="Computers\Commodore64\Cia.cs" />
|
<Compile Include="Computers\Commodore64\Cia.cs" />
|
||||||
<Compile Include="Computers\Commodore64\DataPort.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\IMedia.cs" />
|
||||||
<Compile Include="Computers\Commodore64\Input.cs" />
|
<Compile Include="Computers\Commodore64\Input.cs" />
|
||||||
<Compile Include="Computers\Commodore64\PRGFile.cs" />
|
<Compile Include="Computers\Commodore64\PRGFile.cs" />
|
||||||
|
|
|
@ -12,21 +12,136 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
//
|
//
|
||||||
// 2kb ram, mapped 0000-07FF
|
// 2kb ram, mapped 0000-07FF
|
||||||
// two 6522 VIA chips, mapped at 1800 (communication to C64) and 1C00 (drive mechanics)
|
// two 6522 VIA chips, mapped at 1800 (communication to C64) and 1C00 (drive mechanics)
|
||||||
|
// drive ROM, mapped C000-FFFF
|
||||||
|
|
||||||
public MOS6502X cpu;
|
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 via0;
|
||||||
public Via via1;
|
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();
|
HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Eject()
|
||||||
|
{
|
||||||
|
disk = null;
|
||||||
|
}
|
||||||
|
|
||||||
public void HardReset()
|
public void HardReset()
|
||||||
{
|
{
|
||||||
cpu = new MOS6502X();
|
cpu = new MOS6502X();
|
||||||
|
ram = new byte[0x800];
|
||||||
via0 = new Via();
|
via0 = new Via();
|
||||||
via1 = 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
|
|
||||||
// source
|
// source
|
||||||
public Cartridge cart;
|
public Cartridge cart;
|
||||||
|
public Drive1541 diskDrive;
|
||||||
public string extension;
|
public string extension;
|
||||||
public byte[] inputFile;
|
public byte[] inputFile;
|
||||||
public List<IMedia> mediaAttached = new List<IMedia>();
|
public List<IMedia> mediaAttached = new List<IMedia>();
|
||||||
|
@ -74,6 +75,13 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
// initialize media
|
// initialize media
|
||||||
switch (extension.ToUpper())
|
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":
|
case @".PRG":
|
||||||
if (inputFile.Length > 2)
|
if (inputFile.Length > 2)
|
||||||
mediaAttached.Add(new PRGFile(inputFile, mem, cpu));
|
mediaAttached.Add(new PRGFile(inputFile, mem, cpu));
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,23 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
public int SR;
|
public int SR;
|
||||||
public int[] TC;
|
public int[] TC;
|
||||||
public int[] TL;
|
public int[] TL;
|
||||||
|
|
||||||
|
public ViaRegs()
|
||||||
|
{
|
||||||
|
// power on state
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte this[int addr]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// set register
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Via
|
public class Via
|
||||||
|
|
Loading…
Reference in New Issue