1
0
mirror of https://github.com/livingcomputermuseum/ContrAlto.git synced 2026-01-17 08:34:15 +00:00

151 lines
4.5 KiB
C#

using System;
using System.IO;
namespace Contralto.CPU
{
static class ControlROM
{
static ControlROM()
{
Init();
}
private static void Init()
{
LoadConstants(_constantRoms);
LoadACSource(_acSourceRoms);
}
public static ushort[] ConstantROM
{
get { return _constantRom; }
}
public static byte[] ACSourceROM
{
get { return _acSourceRom; }
}
private static void LoadConstants(RomFile[] romInfo)
{
_constantRom = new ushort[256];
foreach (RomFile file in romInfo)
{
//
// Each file contains 256 bytes, each byte containing one nybble in the low 4 bits.
//
using (FileStream fs = new FileStream(Path.Combine("ROM", file.Filename), FileMode.Open, FileAccess.Read))
{
int length = (int)fs.Length;
if (length != 256)
{
throw new InvalidOperationException("ROM file should be 256 bytes in length");
}
byte[] data = new byte[fs.Length];
fs.Read(data, 0, (int)fs.Length);
// OR in the data
for (int i = 0; i < length; i++)
{
_constantRom[file.StartingAddress + i] |= (ushort)((DataMapConstantRom(data[AddressMapConstantRom(i)]) & 0xf) << file.BitPosition);
}
}
}
// And invert all bits
for (int i = 0; i < _constantRom.Length; i++)
{
_constantRom[i] = (ushort)((~_constantRom[i]) & 0xffff);
}
}
private static void LoadACSource(RomFile romInfo)
{
_acSourceRom = new byte[256];
using (FileStream fs = new FileStream(Path.Combine("ROM", romInfo.Filename), FileMode.Open, FileAccess.Read))
{
int length = (int)fs.Length;
if (length != 256)
{
throw new InvalidOperationException("ROM file should be 256 bytes in length");
}
byte[] data = new byte[fs.Length];
fs.Read(data, 0, (int)fs.Length);
// Copy in the data, modifying the address as required.
for (int i = 0; i < length; i++)
{
_acSourceRom[i] = (byte)((~data[AddressMapACSourceRom(i)]) & 0xf);
}
}
}
private static int AddressMapConstantRom(int address)
{
// Descramble the address bits as they are in no sane order.
// (See 05a_AIM.pdf, pg. 5 (Page 9 of the orginal docs))
int[] addressMapping = { 7, 2, 1, 0, 3, 4, 5, 6 };
int mappedAddress = 0;
for (int i = 0; i < addressMapping.Length; i++)
{
if ((address & (1 << i)) != 0)
{
mappedAddress |= (1 << (addressMapping[i]));
}
}
return mappedAddress;
}
private static int DataMapConstantRom(int data)
{
// Reverse bits 0-4.
int mappedData = 0;
for (int i = 0; i < 4; i++)
{
if ((data & (1 << i)) != 0)
{
mappedData |= (1 << (3-i));
}
}
return mappedData;
}
private static int AddressMapACSourceRom(int data)
{
// Reverse bits 0-7.
int mappedData = 0;
for (int i = 0; i < 8; i++)
{
if ((data & (1 << i)) != 0)
{
mappedData |= (1 << (7 - i));
}
}
// And invert data lines
return (~mappedData) & 0xff;
}
private static RomFile[] _constantRoms =
{
new RomFile("c0", 0x000, 12),
new RomFile("c1", 0x000, 8),
new RomFile("c2", 0x000, 4),
new RomFile("c3", 0x000, 0),
};
private static RomFile _acSourceRoms = new RomFile("2kctl.u3", 0x000, 0);
private static ushort[] _constantRom;
private static byte[] _acSourceRom;
}
}