IntelliHawk:
-Cleanup. -Added "Total Executed Cycles" to the log. -By observing the aforementioned data, I realized that the docs probably meant to say 14934 instead of 14394. --By adjusting this...TITLE SCREEN! --Still, there are definitely discrepancies with the log that imply that I'm far from done. -Enabled ANDR and XOR because they were executed during the title sequence, though it's hard to tell if it should at this point.
This commit is contained in:
parent
461e6c6cea
commit
7ad002d5ce
|
@ -26,7 +26,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
static CP1610()
|
||||
{
|
||||
if (Logging)
|
||||
{
|
||||
Log = new StreamWriter("log_CP1610.txt");
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
|
@ -35,7 +37,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
Interruptible = false;
|
||||
FlagS = FlagC = FlagZ = FlagO = FlagI = FlagD = false;
|
||||
for (int register = 0; register <= 6; register++)
|
||||
{
|
||||
Register[register] = 0;
|
||||
}
|
||||
RegisterPC = RESET;
|
||||
}
|
||||
|
||||
|
@ -47,6 +51,10 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
public void SetIntRM(bool value)
|
||||
{
|
||||
IntRM = value;
|
||||
if (IntRM)
|
||||
{
|
||||
Interrupted = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBusRq(bool value)
|
||||
|
@ -67,9 +75,14 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
public void LogData()
|
||||
{
|
||||
if (!Logging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Log.WriteLine("Total Executed Cycles = {0}", TotalExecutedCycles);
|
||||
for (int register = 0; register <= 5; register++)
|
||||
{
|
||||
Log.WriteLine("R{0:d} = {1:X4}", register, Register[register]);
|
||||
}
|
||||
Log.WriteLine("SP = {0:X4}", RegisterSP);
|
||||
Log.WriteLine("PC = {0:X4}", RegisterPC);
|
||||
Log.WriteLine("S = {0}", FlagS);
|
||||
|
@ -81,7 +94,13 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
Log.WriteLine("INTRM = {0}", IntRM);
|
||||
Log.WriteLine("BUSRQ = {0}", BusRq);
|
||||
Log.WriteLine("BUSAK = {0}", BusAk);
|
||||
//Log.WriteLine("MSYNC = {0}", MSync);
|
||||
/*
|
||||
Log.WriteLine("MSYNC = {0}", MSync);
|
||||
Log.WriteLine("0x28 = {0}", ReadMemory(0x28));
|
||||
Log.WriteLine("0x29 = {0}", ReadMemory(0x29));
|
||||
Log.WriteLine("0x2A = {0}", ReadMemory(0x2A));
|
||||
Log.WriteLine("0x2B = {0}", ReadMemory(0x2B));
|
||||
*/
|
||||
Log.Flush();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
addr = (ushort)(((decle2 << 8) & 0xFC00) | (decle3 & 0x3FF));
|
||||
result = "J";
|
||||
if (dest != 0x7)
|
||||
{
|
||||
result += "SR";
|
||||
}
|
||||
// ff indicates how to affect the Interrupt (I) flag in the CP1610
|
||||
switch (decle2 & 0x3)
|
||||
{
|
||||
|
@ -52,7 +54,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
return UNKNOWN;
|
||||
}
|
||||
if (dest != 0x3)
|
||||
{
|
||||
result += " R" + dest + ",";
|
||||
}
|
||||
result += string.Format(" ${0:X4}", addr);
|
||||
addrToAdvance = 3;
|
||||
return result;
|
||||
|
@ -122,13 +126,17 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
case 0x035:
|
||||
result = "NOP";
|
||||
if ((opcode & 0x1) != 0)
|
||||
{
|
||||
result += " 1";
|
||||
}
|
||||
return result;
|
||||
case 0x036:
|
||||
case 0x037:
|
||||
result = "SIN";
|
||||
if ((opcode & 0x1) != 0)
|
||||
{
|
||||
result += " 1";
|
||||
}
|
||||
return result;
|
||||
case 0x038:
|
||||
case 0x039:
|
||||
|
@ -151,7 +159,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
dest = (byte)(opcode & 0x3);
|
||||
result = "SWAP R" + dest;
|
||||
if (((opcode >> 2) & 0x1) != 0)
|
||||
{
|
||||
result += ", 1";
|
||||
}
|
||||
return result;
|
||||
case 0x048:
|
||||
case 0x049:
|
||||
|
@ -164,7 +174,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
dest = (byte)(opcode & 0x3);
|
||||
result = "SLL R" + dest;
|
||||
if (((opcode >> 2) & 0x1) != 0)
|
||||
{
|
||||
result += ", 1";
|
||||
}
|
||||
return result;
|
||||
case 0x050:
|
||||
case 0x051:
|
||||
|
@ -177,7 +189,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
dest = (byte)(opcode & 0x3);
|
||||
result = "RLC R" + dest;
|
||||
if (((opcode >> 2) & 0x1) != 0)
|
||||
{
|
||||
result += ", 1";
|
||||
}
|
||||
return result;
|
||||
case 0x058:
|
||||
case 0x059:
|
||||
|
@ -190,7 +204,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
dest = (byte)(opcode & 0x3);
|
||||
result = "SLLC R" + dest;
|
||||
if (((opcode >> 2) & 0x1) != 0)
|
||||
{
|
||||
result += ", 1";
|
||||
}
|
||||
return result;
|
||||
case 0x060:
|
||||
case 0x061:
|
||||
|
@ -203,7 +219,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
dest = (byte)(opcode & 0x3);
|
||||
result = "SLR R" + dest;
|
||||
if (((opcode >> 2) & 0x1) != 0)
|
||||
{
|
||||
result += ", 1";
|
||||
}
|
||||
return result;
|
||||
case 0x068:
|
||||
case 0x069:
|
||||
|
@ -216,7 +234,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
dest = (byte)(opcode & 0x3);
|
||||
result = "SAR R" + dest;
|
||||
if (((opcode >> 2) & 0x1) != 0)
|
||||
{
|
||||
result += ", 1";
|
||||
}
|
||||
return result;
|
||||
case 0x070:
|
||||
case 0x071:
|
||||
|
@ -229,7 +249,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
dest = (byte)(opcode & 0x3);
|
||||
result = "RRC R" + dest;
|
||||
if (((opcode >> 2) & 0x1) != 0)
|
||||
{
|
||||
result += ", 1";
|
||||
}
|
||||
return result;
|
||||
case 0x078:
|
||||
case 0x079:
|
||||
|
@ -242,7 +264,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
dest = (byte)(opcode & 0x3);
|
||||
result = "SARC R" + dest;
|
||||
if (((opcode >> 2) & 0x1) != 0)
|
||||
{
|
||||
result += ", 1";
|
||||
}
|
||||
return result;
|
||||
case 0x080:
|
||||
case 0x081:
|
||||
|
@ -718,7 +742,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
cond = opcode & 0xF;
|
||||
ext = opcode & 0x10;
|
||||
if (ext != 0)
|
||||
{
|
||||
result = "BEXT";
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cond)
|
||||
|
@ -777,10 +803,14 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
{
|
||||
// Branch in the reverse direction by negating the offset and subtracting 1.
|
||||
if (((opcode >> 5) & 0x1) != 0)
|
||||
{
|
||||
offset = (ushort)(-offset - 1);
|
||||
}
|
||||
result += string.Format(" ${0:X4}", offset);
|
||||
if (ext != 0)
|
||||
{
|
||||
result += string.Format(", ${0:X1}", opcode & 0x8);
|
||||
}
|
||||
}
|
||||
addrToAdvance = 2;
|
||||
return result;
|
||||
|
|
|
@ -47,9 +47,13 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
ushort value;
|
||||
// Auto-decrement the stack pointer if it's the memory register.
|
||||
if (mem == 0x6)
|
||||
{
|
||||
RegisterSP--;
|
||||
}
|
||||
if (!FlagD)
|
||||
{
|
||||
value = ReadMemory(Register[mem]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Double Byte Data.
|
||||
|
@ -58,7 +62,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
}
|
||||
// Auto-increment the memory register if it does so on write.
|
||||
if (mem >= 0x4 && mem != 0x6)
|
||||
{
|
||||
Register[mem]++;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -67,13 +73,19 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
if (!FlagD)
|
||||
{
|
||||
if (mem != 0x6)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 11;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Double Byte Data.
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
public void Indirect_Set(byte mem, byte src)
|
||||
|
@ -81,11 +93,14 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
WriteMemory(Register[mem], Register[src]);
|
||||
// Auto-increment the memory register if it does so on read.
|
||||
if (mem >= 0x4)
|
||||
{
|
||||
Register[mem]++;
|
||||
}
|
||||
}
|
||||
|
||||
public int Execute()
|
||||
{
|
||||
int cycles = 0;
|
||||
/*
|
||||
Take an interrupt if the previous instruction was interruptible, interrupts are enabled, and IntRM has a
|
||||
falling edge.
|
||||
|
@ -103,7 +118,10 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
Interruptible = false;
|
||||
Indirect_Set(6, 7);
|
||||
RegisterPC = INTERRUPT;
|
||||
return 28;
|
||||
cycles = 28;
|
||||
PendingCycles -= cycles;
|
||||
TotalExecutedCycles += cycles;
|
||||
return cycles;
|
||||
}
|
||||
if (Logging)
|
||||
{
|
||||
|
@ -115,7 +133,7 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
}
|
||||
byte dest, src, mem;
|
||||
ushort dest_value, src_value, mem_read, addr, addr_read, offset;
|
||||
int cycles = 0, decle2, decle3, result = 0, twos, status_word, lower, sign, cond, ext;
|
||||
int decle2, decle3, result = 0, twos, status_word, lower, sign, cond, ext;
|
||||
//int ones, carry;
|
||||
bool branch = false;
|
||||
bool FlagD_prev = FlagD;
|
||||
|
@ -148,8 +166,10 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
// aaaaaaaaaaaaaaaa indicates the address to where the CP1610 should Jump
|
||||
addr = (ushort)(((decle2 << 8) & 0xFC00) | (decle3 & 0x3FF));
|
||||
if (dest != 0x7)
|
||||
{
|
||||
// Store the return address.
|
||||
Register[dest] = (ushort)(RegisterPC & 0xFFFF);
|
||||
}
|
||||
// ff indicates how to affect the Interrupt (I) flag in the CP1610
|
||||
switch (decle2 & 0x3)
|
||||
{
|
||||
|
@ -357,8 +377,10 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
dest = (byte)(opcode & 0x3);
|
||||
result = Register[dest] << 1;
|
||||
if (((opcode >> 2) & 0x1) == 0)
|
||||
{
|
||||
// Single shift.
|
||||
cycles = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Double shift.
|
||||
|
@ -385,8 +407,10 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
result = (dest_value << 1) | (FlagC ? 1 : 0);
|
||||
FlagC = ((dest_value & 0x8000) != 0);
|
||||
if (((opcode >> 2) & 0x1) == 0)
|
||||
{
|
||||
// Single rotate.
|
||||
cycles = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Double rotate.
|
||||
|
@ -415,8 +439,10 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
result = dest_value << 1;
|
||||
FlagC = ((dest_value & 0x8000) != 0);
|
||||
if (((opcode >> 2) & 0x1) == 0)
|
||||
{
|
||||
// Single shift.
|
||||
cycles = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Double shift.
|
||||
|
@ -442,8 +468,10 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
dest = (byte)(opcode & 0x3);
|
||||
result = Register[dest] >> 1;
|
||||
if (((opcode >> 2) & 0x1) == 0)
|
||||
{
|
||||
// Single shift.
|
||||
cycles = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Double shift.
|
||||
|
@ -469,8 +497,10 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
sign = dest_value & 0x8000;
|
||||
result = (dest_value >> 1) | sign;
|
||||
if (((opcode >> 2) & 0x1) == 0)
|
||||
{
|
||||
// Single shift.
|
||||
cycles = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Double shift.
|
||||
|
@ -497,8 +527,10 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
result = (dest_value >> 1) | ((FlagC ? 1 : 0) << 15);
|
||||
FlagC = ((dest_value & 0x1) != 0);
|
||||
if (((opcode >> 2) & 0x1) == 0)
|
||||
{
|
||||
// Single rotate.
|
||||
cycles = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Double rotate.
|
||||
|
@ -527,8 +559,10 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
result = (dest_value >> 1) | sign;
|
||||
FlagC = ((dest_value & 0x1) != 0);
|
||||
if (((opcode >> 2) & 0x1) == 0)
|
||||
{
|
||||
// Single shift.
|
||||
cycles = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Double shift.
|
||||
|
@ -614,9 +648,13 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
Calc_FlagZ(result);
|
||||
Register[dest] = (ushort)result;
|
||||
if (dest == 0x6 || dest == 0x7)
|
||||
{
|
||||
cycles = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
cycles = 6;
|
||||
}
|
||||
Interruptible = true;
|
||||
break;
|
||||
// ADDR
|
||||
|
@ -922,16 +960,15 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
case 0x1BD:
|
||||
case 0x1BE:
|
||||
case 0x1BF:
|
||||
throw new NotImplementedException();
|
||||
//src = (byte)((opcode >> 3) & 0x7);
|
||||
//dest = (byte)(opcode & 0x7);
|
||||
//result = Register[dest] & Register[src];
|
||||
//Calc_FlagS(result);
|
||||
//Calc_FlagZ(result);
|
||||
//Register[dest] = (ushort)result;
|
||||
//cycles = 6;
|
||||
//Interruptible = true;
|
||||
//break;
|
||||
src = (byte)((opcode >> 3) & 0x7);
|
||||
dest = (byte)(opcode & 0x7);
|
||||
result = Register[dest] & Register[src];
|
||||
Calc_FlagS(result);
|
||||
Calc_FlagZ(result);
|
||||
Register[dest] = (ushort)result;
|
||||
cycles = 6;
|
||||
Interruptible = true;
|
||||
break;
|
||||
// XORR
|
||||
case 0x1C0:
|
||||
case 0x1C1:
|
||||
|
@ -1079,7 +1116,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
ext = opcode & 0x10;
|
||||
// BEXT
|
||||
if (ext != 0)
|
||||
{
|
||||
throw new ArgumentException(UNEXPECTED_BEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cond)
|
||||
|
@ -1159,7 +1198,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
cycles = 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
cycles = 7;
|
||||
}
|
||||
Interruptible = true;
|
||||
break;
|
||||
// MVO
|
||||
|
@ -1700,18 +1741,17 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
case 0x3C5:
|
||||
case 0x3C6:
|
||||
case 0x3C7:
|
||||
throw new NotImplementedException();
|
||||
//dest = (byte)(opcode & 0x7);
|
||||
//addr = ReadMemory(RegisterPC++);
|
||||
//dest_value = Register[dest];
|
||||
//addr_read = ReadMemory(addr);
|
||||
//result = dest_value ^ addr_read;
|
||||
//Calc_FlagS(result);
|
||||
//Calc_FlagZ(result);
|
||||
//Register[dest] = (ushort)result;
|
||||
//cycles = 10;
|
||||
//Interruptible = true;
|
||||
//break;
|
||||
dest = (byte)(opcode & 0x7);
|
||||
addr = ReadMemory(RegisterPC++);
|
||||
dest_value = Register[dest];
|
||||
addr_read = ReadMemory(addr);
|
||||
result = dest_value ^ addr_read;
|
||||
Calc_FlagS(result);
|
||||
Calc_FlagZ(result);
|
||||
Register[dest] = (ushort)result;
|
||||
cycles = 10;
|
||||
Interruptible = true;
|
||||
break;
|
||||
// XOR@
|
||||
case 0x3C8:
|
||||
case 0x3C9:
|
||||
|
@ -1781,7 +1821,9 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
break;
|
||||
}
|
||||
if (FlagD == FlagD_prev)
|
||||
{
|
||||
FlagD = false;
|
||||
}
|
||||
PendingCycles -= cycles;
|
||||
TotalExecutedCycles += cycles;
|
||||
return cycles;
|
||||
|
|
|
@ -15,7 +15,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
int index = 0;
|
||||
// Combine every two bytes into a word.
|
||||
while (index + 1 < Rom.Length)
|
||||
{
|
||||
Data[(index / 2) + 0x2C00] = (ushort)((Rom[index++] << 8) | Rom[index++]);
|
||||
}
|
||||
/*
|
||||
for (int index = 0; index < Rom.Length; index++)
|
||||
Data[index + 0x2C00] = Rom[index];
|
||||
|
@ -32,17 +34,27 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
case 0x0000:
|
||||
dest = addr - 0x0400;
|
||||
if (addr <= 0x03FF)
|
||||
{
|
||||
break;
|
||||
if (addr <= 0x04FF)
|
||||
}
|
||||
else if (addr <= 0x04FF)
|
||||
{
|
||||
// OK on all but Intellivision 2.
|
||||
return Data[dest];
|
||||
}
|
||||
else if (addr <= 0x06FF)
|
||||
{
|
||||
return Data[dest];
|
||||
}
|
||||
else if (addr <= 0x0CFF)
|
||||
{
|
||||
// OK if no Intellivoice.
|
||||
return Data[dest];
|
||||
}
|
||||
else
|
||||
{
|
||||
return Data[dest];
|
||||
}
|
||||
case 0x2000:
|
||||
dest = (addr - 0x2000) + 0x0C00;
|
||||
// OK if no ECS.
|
||||
|
@ -50,34 +62,50 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
case 0x4000:
|
||||
dest = (addr - 0x4000) + 0x1C00;
|
||||
if (addr <= 0x47FF)
|
||||
{
|
||||
// OK if no ECS.
|
||||
return Data[dest];
|
||||
}
|
||||
else if (addr == 0x4800)
|
||||
{
|
||||
// return Data[dest];
|
||||
// For now, assume unmapped. TODO: Fix.
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Data[dest];
|
||||
}
|
||||
case 0x5000:
|
||||
case 0x6000:
|
||||
dest = (addr - 0x5000) + 0x2C00;
|
||||
if (addr <= 0x5014)
|
||||
{
|
||||
return Data[dest];
|
||||
}
|
||||
else
|
||||
{
|
||||
return Data[dest];
|
||||
}
|
||||
case 0x7000:
|
||||
dest = (addr - 0x7000) + 0x4C00;
|
||||
if (addr == 0x7000)
|
||||
{
|
||||
// OK if no ECS.
|
||||
// return Data[dest];
|
||||
// For now, assume unmapped. TODO: Fix.
|
||||
return null;
|
||||
}
|
||||
else if (addr <= 0x77FF)
|
||||
{
|
||||
// OK if no ECS.
|
||||
return Data[dest];
|
||||
}
|
||||
else
|
||||
{
|
||||
// OK if no ECS.
|
||||
return Data[dest];
|
||||
}
|
||||
case 0x8000:
|
||||
dest = (addr - 0x8000) + 0x5C00;
|
||||
// OK. Avoid STIC alias at $8000-$803F.
|
||||
|
@ -87,9 +115,13 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
case 0xB000:
|
||||
dest = (addr - 0x9000) + 0x6C00;
|
||||
if (addr <= 0xB7FF)
|
||||
{
|
||||
return Data[dest];
|
||||
}
|
||||
else
|
||||
{
|
||||
return Data[dest];
|
||||
}
|
||||
case 0xC000:
|
||||
dest = (addr - 0xC000) + 0x9C00;
|
||||
// OK. Avoid STIC alias at $C000-$C03F.
|
||||
|
@ -104,9 +136,13 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
case 0xF000:
|
||||
dest = (addr - 0xF000) + 0xCC00;
|
||||
if (addr <= 0xF7FF)
|
||||
{
|
||||
return Data[dest];
|
||||
}
|
||||
else
|
||||
{
|
||||
return Data[dest];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -120,8 +156,10 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
case 0x0000:
|
||||
dest = addr - 0x0400;
|
||||
if (addr <= 0x03FF)
|
||||
{
|
||||
break;
|
||||
if (addr <= 0x04FF)
|
||||
}
|
||||
else if (addr <= 0x04FF)
|
||||
{
|
||||
// OK on all but Intellivision 2.
|
||||
Data[dest] = value;
|
||||
|
|
|
@ -57,7 +57,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
int offset = 0;
|
||||
// Check to see if the header is valid.
|
||||
if (Rom[offset++] != 0xA8 || Rom[offset++] != (0xFF ^ Rom[offset++]))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
ushort crc, expected;
|
||||
// Parse for data segments.
|
||||
for (int segment = 0; segment < Rom[1]; segment++)
|
||||
|
@ -70,7 +72,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
ushort start = (ushort)(upper_start << 8);
|
||||
ushort end = (ushort)((upper_end << 8) | 0xFF);
|
||||
if (end < start)
|
||||
{
|
||||
throw new ArgumentException("Ranges can't start higher than they end.");
|
||||
}
|
||||
for (int addr = start; addr <= end; addr++)
|
||||
{
|
||||
ushort data;
|
||||
|
@ -83,7 +87,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
}
|
||||
expected = (ushort)((Rom[offset++] << 8) | Rom[offset++]);
|
||||
if (expected != crc)
|
||||
{
|
||||
throw new ArgumentException("Invalid CRC.");
|
||||
}
|
||||
}
|
||||
// Parse for memory attributes.
|
||||
for (int range = 0; range < 32; range++)
|
||||
|
@ -91,7 +97,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
byte attributes = Rom[offset + (range >> 1)];
|
||||
// Every second 2K block is stored in the upper 4 bits.
|
||||
if ((range & 0x1) != 0)
|
||||
{
|
||||
attributes = (byte)(attributes >> 4);
|
||||
}
|
||||
attributes &= 0xF;
|
||||
MemoryAttributes[range] = new bool[4];
|
||||
// Readable.
|
||||
|
@ -109,25 +117,35 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
int index;
|
||||
// The lower and upper 2K in a 4K range are 16 addresses away from each other.
|
||||
if ((range & 0x1) != 0)
|
||||
{
|
||||
index = offset + 16 + (range >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = offset + 32 + (range >> 1);
|
||||
}
|
||||
int range_start = range * 2048;
|
||||
ushort start = (ushort)((((Rom[index] >> 4) & 0x07) << 8) + range_start);
|
||||
ushort end = (ushort)((((Rom[index]) & 0x07) << 8) + 0xFF + range_start);
|
||||
if (end < start)
|
||||
{
|
||||
throw new ArgumentException("Ranges can't start higher than they end.");
|
||||
}
|
||||
FineAddresses[range] = new ushort[2];
|
||||
FineAddresses[range][0] = start;
|
||||
FineAddresses[range][1] = end;
|
||||
}
|
||||
crc = 0xFFFF;
|
||||
for (int index = 0; index < 48; index++)
|
||||
{
|
||||
crc = UpdateCRC16(crc, Rom[offset++]);
|
||||
}
|
||||
expected = (ushort)((Rom[offset++] << 8) | (Rom[offset++] & 0xFF));
|
||||
// Check if there is an invalid CRC for the memory attributes / fine addresses.
|
||||
if (expected != crc)
|
||||
{
|
||||
throw new ArgumentException("Invalid CRC.");
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
@ -136,7 +154,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
int range = addr / 2048;
|
||||
bool[] attributes = MemoryAttributes[range];
|
||||
if (attributes[0] && addr >= FineAddresses[range][0] && addr <= FineAddresses[range][1])
|
||||
{
|
||||
return Data[addr];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -148,9 +168,13 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
{
|
||||
// Only write lower 8 bits if the Narrow attribute is set.
|
||||
if (attributes[2])
|
||||
{
|
||||
value &= 0xFF;
|
||||
}
|
||||
if (attributes[3])
|
||||
{
|
||||
throw new NotImplementedException("Bank-switched memory attribute not implemented.");
|
||||
}
|
||||
Data[addr] = value;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -25,17 +25,25 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
public void LoadExecutiveRom(string path)
|
||||
{
|
||||
var erom = File.ReadAllBytes(path);
|
||||
if (erom.Length != 8192) throw new ApplicationException("EROM file is wrong size - expected 8192 bytes");
|
||||
if (erom.Length != 8192)
|
||||
{
|
||||
throw new ApplicationException("EROM file is wrong size - expected 8192 bytes");
|
||||
}
|
||||
int index = 0;
|
||||
// Combine every two bytes into a word.
|
||||
while (index + 1 < erom.Length)
|
||||
{
|
||||
ExecutiveRom[index / 2] = (ushort)((erom[index++] << 8) | erom[index++]);
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadGraphicsRom(string path)
|
||||
{
|
||||
GraphicsRom = File.ReadAllBytes(path);
|
||||
if (GraphicsRom.Length != 2048) throw new ApplicationException("GROM file is wrong size - expected 2048 bytes");
|
||||
if (GraphicsRom.Length != 2048)
|
||||
{
|
||||
throw new ApplicationException("GROM file is wrong size - expected 2048 bytes");
|
||||
}
|
||||
}
|
||||
|
||||
public Intellivision(CoreComm comm, GameInfo game, byte[] rom)
|
||||
|
@ -73,7 +81,7 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
public void FrameAdvance(bool render, bool rendersound)
|
||||
{
|
||||
Frame++;
|
||||
Cpu.AddPendingCycles(14394 + 3791);
|
||||
Cpu.AddPendingCycles(14934);
|
||||
while (Cpu.GetPendingCycles() > 0)
|
||||
{
|
||||
int cycles = Cpu.Execute();
|
||||
|
|
|
@ -26,93 +26,147 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
{
|
||||
case 0x0000:
|
||||
if (addr <= 0x007F)
|
||||
{
|
||||
// STIC.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x00FF)
|
||||
{
|
||||
// Unoccupied.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x01EF)
|
||||
{
|
||||
core = (ushort)(ScratchpadRam[addr - 0x0100] & 0x00FF);
|
||||
}
|
||||
else if (addr <= 0x01FF)
|
||||
{
|
||||
// PSG.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x035F)
|
||||
{
|
||||
core = SystemRam[addr - 0x0200];
|
||||
}
|
||||
else if (addr <= 0x03FF)
|
||||
{
|
||||
// TODO: Garbage values for Intellivision II.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x04FF)
|
||||
{
|
||||
// TODO: Additional EXEC ROM for Intellivision II.
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x1000:
|
||||
core = (ushort)(ExecutiveRom[addr - 0x1000] & 0x3FF);
|
||||
break;
|
||||
case 0x3000:
|
||||
if (addr <= 0x37FF)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
core = (byte)(GraphicsRom[addr - 0x3000] & 0x00FF);
|
||||
}
|
||||
else if (addr <= 0x39FF)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
core = (byte)(GraphicsRam[addr - 0x3800] & 0x00FF);
|
||||
}
|
||||
else if (addr <= 0x3BFF)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
core = (byte)(GraphicsRam[addr - 0x3A00] & 0x00FF);
|
||||
}
|
||||
else if (addr <= 0x3DFF)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
core = (byte)(GraphicsRam[addr - 0x3C00] & 0x00FF);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
core = (byte)(GraphicsRam[addr - 0x3E00] & 0x00FF);
|
||||
}
|
||||
break;
|
||||
case 0x7000:
|
||||
if (addr <= 0x77FF)
|
||||
{
|
||||
// Available to cartridges.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x79FF)
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x7BFF)
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x7DFF)
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
case 0xB000:
|
||||
if (addr <= 0xB7FF)
|
||||
{
|
||||
// Available to cartridges.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0xB9FF)
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0xBBFF)
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0xBDFF)
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
case 0xF000:
|
||||
if (addr <= 0xF7FF)
|
||||
{
|
||||
// Available to cartridges.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0xF9FF)
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0xFBFF)
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0xFDFF)
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write-only Graphics RAM.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (CoreComm.MemoryCallbackSystem.HasRead)
|
||||
|
@ -121,13 +175,21 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
}
|
||||
|
||||
if (cart != null)
|
||||
{
|
||||
return (ushort)cart;
|
||||
}
|
||||
else if (stic != null)
|
||||
{
|
||||
return (ushort)stic;
|
||||
}
|
||||
else if (psg != null)
|
||||
{
|
||||
return (ushort)psg;
|
||||
}
|
||||
else if (core != null)
|
||||
{
|
||||
return (ushort)core;
|
||||
}
|
||||
return UNMAPPED;
|
||||
}
|
||||
|
||||
|
@ -140,11 +202,15 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
{
|
||||
case 0x0000:
|
||||
if (addr <= 0x007F)
|
||||
{
|
||||
// STIC.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x00FF)
|
||||
{
|
||||
// Unoccupied.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x01EF)
|
||||
{
|
||||
ScratchpadRam[addr - 0x0100] = (byte)(value & 0x00FF);
|
||||
|
@ -161,19 +227,25 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
return true;
|
||||
}
|
||||
else if (addr <= 0x03FF)
|
||||
{
|
||||
// Read-only garbage values for Intellivision II.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x04FF)
|
||||
{
|
||||
// Read-only additional EXEC ROM for Intellivision II.
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x1000:
|
||||
// Read-only Executive ROM.
|
||||
break;
|
||||
case 0x3000:
|
||||
if (addr <= 0x37FF)
|
||||
{
|
||||
// Read-only Graphics ROM.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x39FF)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
|
@ -200,8 +272,10 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
}
|
||||
case 0x7000:
|
||||
if (addr <= 0x77FF)
|
||||
{
|
||||
// Available to cartridges.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x79FF)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
|
@ -230,8 +304,10 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
case 0xA000:
|
||||
case 0xB000:
|
||||
if (addr <= 0xB7FF)
|
||||
{
|
||||
// Available to cartridges.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0xB9FF)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
|
@ -258,8 +334,10 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
}
|
||||
case 0xF000:
|
||||
if (addr <= 0xF7FF)
|
||||
{
|
||||
// Available to cartridges.
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0xF9FF)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
|
|
|
@ -18,7 +18,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
public ushort? ReadPSG(ushort addr)
|
||||
{
|
||||
if (addr >= 0x01F0 && addr <= 0x01FF)
|
||||
{
|
||||
return Register[addr - 0x01F0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,19 +72,25 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
{
|
||||
// TODO: OK only during VBlank Period 1.
|
||||
if (addr == 0x0021)
|
||||
{
|
||||
Fgbg = false;
|
||||
}
|
||||
return Register[addr];
|
||||
}
|
||||
else if (addr <= 0x007F)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
return Register[addr - 0x0040];
|
||||
}
|
||||
break;
|
||||
case 0x4000:
|
||||
if (addr <= 0x403F)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 1.
|
||||
if (addr == 0x4021)
|
||||
{
|
||||
Fgbg = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x8000:
|
||||
|
@ -92,7 +98,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
{
|
||||
// TODO: OK only during VBlank Period 1.
|
||||
if (addr == 0x8021)
|
||||
{
|
||||
Fgbg = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xC000:
|
||||
|
@ -100,7 +108,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
{
|
||||
// TODO: OK only during VBlank Period 1.
|
||||
if (addr == 0xC021)
|
||||
{
|
||||
Fgbg = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -116,20 +126,26 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
{
|
||||
// TODO: OK only during VBlank Period 1.
|
||||
if (addr == 0x0021)
|
||||
{
|
||||
Fgbg = true;
|
||||
}
|
||||
Register[addr] = value;
|
||||
return true;
|
||||
}
|
||||
else if (addr <= 0x007F)
|
||||
{
|
||||
// Read-only STIC.
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x4000:
|
||||
if (addr <= 0x403F)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 1.
|
||||
if (addr == 0x4021)
|
||||
{
|
||||
Fgbg = true;
|
||||
}
|
||||
Register[addr - 0x4000] = value;
|
||||
return true;
|
||||
}
|
||||
|
@ -139,7 +155,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
{
|
||||
// TODO: OK only during VBlank Period 1.
|
||||
if (addr == 0x8021)
|
||||
{
|
||||
Fgbg = true;
|
||||
}
|
||||
Register[addr & 0x003F] = value;
|
||||
return true;
|
||||
}
|
||||
|
@ -149,7 +167,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
{
|
||||
// TODO: OK only during VBlank Period 1.
|
||||
if (addr == 0xC021)
|
||||
{
|
||||
Fgbg = true;
|
||||
}
|
||||
Register[addr - 0xC000] = value;
|
||||
return true;
|
||||
}
|
||||
|
@ -160,16 +180,20 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
|
||||
public void Execute(int cycles)
|
||||
{
|
||||
PendingCycles -= cycles;
|
||||
TotalExecutedCycles += cycles;
|
||||
if (PendingCycles <= 0)
|
||||
{
|
||||
Sr1 = !Sr1;
|
||||
if (Sr1)
|
||||
AddPendingCycles(14394 - 3791 + 530);
|
||||
{
|
||||
AddPendingCycles(14934 - 3791);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPendingCycles(3791);
|
||||
}
|
||||
}
|
||||
PendingCycles -= cycles;
|
||||
TotalExecutedCycles += cycles;
|
||||
}
|
||||
|
||||
public int ColorToRGBA(int color)
|
||||
|
@ -226,7 +250,7 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
bool gram = ((card & 0x0800) != 0);
|
||||
int card_num = card >> 3;
|
||||
int fg = card & 0x0007;
|
||||
int bg = 0x000000;
|
||||
int bg;
|
||||
if (Fgbg)
|
||||
{
|
||||
bg = ((card >> 9) & 0x0008) | ((card >> 11) & 0x0004) | ((card >> 9) & 0x0003);
|
||||
|
@ -264,23 +288,33 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
{
|
||||
// The rightmost column does not get displayed.
|
||||
if (card_col == 19 && squares_col == 7)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int color;
|
||||
int pixel = buffer_offset + (squares_row * 159) + squares_col;
|
||||
// Determine the color of the quadrant the pixel is in.
|
||||
if (squares_col < 4)
|
||||
{
|
||||
if (squares_row < 4)
|
||||
{
|
||||
color = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (squares_row < 4)
|
||||
{
|
||||
color = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = 3;
|
||||
}
|
||||
}
|
||||
FrameBuffer[pixel] = ColorToRGBA(colors[color]);
|
||||
}
|
||||
|
@ -294,7 +328,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
// Cycle through the Color Stack registers.
|
||||
ColorSP++;
|
||||
if (ColorSP > 0x002B)
|
||||
{
|
||||
ColorSP = 0x0028;
|
||||
}
|
||||
}
|
||||
bg = ReadMemory(ColorSP) & 0x000F;
|
||||
}
|
||||
|
@ -305,21 +341,31 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
int row_mem = (card_num * 8) + pict_row;
|
||||
byte row;
|
||||
if (gram)
|
||||
{
|
||||
row = (byte)ReadMemory((ushort)(0x3800 + row_mem));
|
||||
}
|
||||
else
|
||||
{
|
||||
row = (byte)ReadMemory((ushort)(0x3000 + row_mem));
|
||||
}
|
||||
for (int pict_col = 0; pict_col < 8; pict_col++)
|
||||
{
|
||||
// The rightmost column does not get displayed.
|
||||
if (card_col == 19 && pict_col == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int pixel = buffer_offset + (pict_row * 159) + (7 - pict_col);
|
||||
// If the pixel is on, give it the FG color.
|
||||
if ((row & 0x1) != 0)
|
||||
{
|
||||
// The pixels go right as the bits get less significant.
|
||||
FrameBuffer[pixel] = ColorToRGBA(fg);
|
||||
}
|
||||
else
|
||||
{
|
||||
FrameBuffer[pixel] = ColorToRGBA(bg);
|
||||
}
|
||||
row >>= 1;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue