Started filling the gaps in the Memory Map, getting up to 0x7FFF. Once complete, a lot of TODOs remain, the most important being the actual mapping of the cartridge.
This commit is contained in:
parent
a34bf45610
commit
f66d92f2a5
|
@ -8,6 +8,8 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
{
|
||||
public sealed partial class CP1610
|
||||
{
|
||||
private const string HLT_UNEXPECTED = "HLT is an unexpected behavior.";
|
||||
|
||||
private void Calc_FlagC(int result)
|
||||
{
|
||||
FlagC = ((result & 0x10000) != 0);
|
||||
|
@ -53,8 +55,7 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
switch (opcode)
|
||||
{
|
||||
case 0x000: // HLT
|
||||
// Unexpected behavior.
|
||||
throw new ArgumentException();
|
||||
throw new ArgumentException(HLT_UNEXPECTED);
|
||||
case 0x001: // SDBD
|
||||
FlagD = true;
|
||||
PendingCycles -= 4; TotalExecutedCycles += 4;
|
||||
|
@ -1015,7 +1016,7 @@ namespace BizHawk.Emulation.CPUs.CP1610
|
|||
ext = opcode & 0x10;
|
||||
// BEXT
|
||||
if (ext != 0)
|
||||
throw new NotImplementedException();
|
||||
throw new NotImplementedException("BEXT not implemented.");
|
||||
else
|
||||
{
|
||||
switch (cond)
|
||||
|
|
|
@ -7,13 +7,27 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
{
|
||||
public sealed partial class Intellivision
|
||||
{
|
||||
private const string INVALID = "Invalid memory address.";
|
||||
private const string UNOCCUPIED = "Unoccupied memory address.";
|
||||
private const string UNOCCUPIED_CART_READ = "Unoccupied memory address available to cartridge not mapped as"
|
||||
+ " readable.";
|
||||
private const string UNOCCUPIED_CART_WRITE = "Unoccupied memory address available to cartridge not mapped as"
|
||||
+ " writable.";
|
||||
private const string READ_ONLY_STIC = "This STIC Register alias is read-only.";
|
||||
private const string READ_ONLY_EXEC = "Executive ROM is read-only.";
|
||||
private const string READ_ONLY_GROM = "Graphics ROM is read-only.";
|
||||
private const string WRITE_ONLY_STIC = "This STIC Register alias is write-only.";
|
||||
private const string GARBAGE = "Memory address contains a garbage value, perhaps only in the Intellivision II.";
|
||||
private const string INTV2_EXEC = "Additional EXEC ROM, Intellivision II only.";
|
||||
|
||||
private ushort[] STIC_Registers = new ushort[64];
|
||||
private ushort[] Scratchpad_RAM = new ushort[240];
|
||||
private ushort[] PSG_Registers = new ushort[16];
|
||||
private ushort[] System_RAM = new ushort[352];
|
||||
private ushort[] Executive_ROM = new ushort[4096];
|
||||
private ushort[] Executive_ROM = new ushort[4096]; // TODO: Intellivision II support?
|
||||
private ushort[] Graphics_ROM = new ushort[2048];
|
||||
private ushort[] Graphics_RAM = new ushort[512];
|
||||
private ushort[] Cartridge = new ushort[23552]; // TODO: Resize as cartridge mapping grows.
|
||||
|
||||
public ushort ReadMemory(ushort addr)
|
||||
{
|
||||
|
@ -22,28 +36,203 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
switch (addr & 0xF000)
|
||||
{
|
||||
case 0x0000:
|
||||
if (addr >= 0x0100 && addr <= 0x01EF)
|
||||
if (addr <= 0x003F)
|
||||
// TODO: OK only during VBlank Period 1.
|
||||
core = STIC_Registers[addr];
|
||||
else if (addr <= 0x007F)
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
core = STIC_Registers[addr & 0x003F];
|
||||
else if (addr <= 0x00FF)
|
||||
throw new ArgumentException(UNOCCUPIED);
|
||||
else if (addr <= 0x01EF)
|
||||
core = Scratchpad_RAM[addr & 0x00EF];
|
||||
else if (addr >= 0x01F0 && addr <= 0x01FF)
|
||||
else if (addr <= 0x01FF)
|
||||
core = PSG_Registers[addr & 0x000F];
|
||||
else if (addr >= 0x0200 && addr <= 0x035F)
|
||||
else if (addr <= 0x035F)
|
||||
core = System_RAM[addr & 0x015F];
|
||||
else if (addr <= 0x03FF)
|
||||
// TODO: Intellivision II support?
|
||||
throw new ArgumentException(GARBAGE);
|
||||
else if (addr <= 0x04FF)
|
||||
// TODO: Actually map cartridge (on all but Intellivision II) RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
// TODO: Intellivision II support?
|
||||
throw new ArgumentException(INTV2_EXEC);
|
||||
else
|
||||
core = Cartridge[addr & 0x00FF];
|
||||
else if (addr <= 0x06FF)
|
||||
// TODO: Actually map cartridge RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[addr & 0x02FF];
|
||||
else if (addr <= 0x0CFF)
|
||||
// TODO: Actually map cartridge (only if no Intellivoice) RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[addr & 0x08FF];
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
// TODO: Actually map cartridge RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[addr & 0x0BFF];
|
||||
break;
|
||||
case 0x1000:
|
||||
core = Executive_ROM[addr & 0x0FFF];
|
||||
break;
|
||||
case 0x2000:
|
||||
// TODO: Actually map cartridge (only if no ECS) RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[(addr & 0x0FFF) + 0x0C00];
|
||||
break;
|
||||
case 0x3000:
|
||||
if (addr >= 0x3000 && addr <= 0x37FF)
|
||||
if (addr <= 0x37FF)
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
core = Graphics_ROM[addr & 0x07FF];
|
||||
else if (addr >= 0x3800 && addr <= 0x39FF)
|
||||
else if (addr <= 0x39FF)
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
core = Graphics_RAM[addr & 0x01FF];
|
||||
else if (addr <= 0x3BFF)
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
core = Graphics_RAM[addr & 0x01FF];
|
||||
else if (addr <= 0x3DFF)
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
core = Graphics_RAM[addr & 0x01FF];
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
core = Graphics_RAM[addr & 0x01FF];
|
||||
break;
|
||||
case 0x4000:
|
||||
if (addr <= 0x403F)
|
||||
{
|
||||
// TODO: Actually map cartridge (only if no ECS) RAM / ROM to decide which path to take.
|
||||
if (true)
|
||||
{
|
||||
// TODO: OK only during VBlank Period 1.
|
||||
if (addr == 0x4021)
|
||||
// TODO: Switch into Color Stack mode.
|
||||
core = STIC_Registers[0x0021];
|
||||
else
|
||||
throw new ArgumentException(WRITE_ONLY_STIC);
|
||||
}
|
||||
else
|
||||
core = Cartridge[(addr & 0x003F) + 0x1C00];
|
||||
}
|
||||
else if (addr <= 0x47FF)
|
||||
{
|
||||
// TODO: Actually map cartridge (only if no ECS) RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[(addr & 0x07FF) + 0x1C00];
|
||||
}
|
||||
else if (addr == 0x4800)
|
||||
{
|
||||
// TODO: Actually map cartridge RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[0x2400];
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Actually map cartridge RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[(addr & 0x0FFF) + 0x01C00];
|
||||
}
|
||||
break;
|
||||
case 0x5000:
|
||||
case 0x6000:
|
||||
if (addr <= 0x5014)
|
||||
{
|
||||
// TODO: Actually map cartridge RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[(addr & 0x0014) + 0x02C00];
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Actually map cartridge RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[(addr & 0x1FFF) + 0x02C00];
|
||||
}
|
||||
break;
|
||||
case 0x7000:
|
||||
if (addr == 0x7000)
|
||||
{
|
||||
/*
|
||||
TODO: Actually map cartridge (only if no ECS) RAM (confuses EXEC boot sequence) / ROM to decide
|
||||
which path to take.
|
||||
*/
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[0x04C00];
|
||||
}
|
||||
else if (addr <= 0x77FF)
|
||||
{
|
||||
// TODO: Actually map cartridge (only if no ECS) RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[(addr & 0x07FF) + 0x04C00];
|
||||
}
|
||||
else if (addr <= 0x79FF)
|
||||
{
|
||||
/*
|
||||
TODO: Actually map cartridge (only if no ECS) RAM (Do not because of GRAM alias) / ROM to decide
|
||||
which path to take.
|
||||
*/
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[(addr & 0x09FF) + 0x04C00];
|
||||
}
|
||||
else if (addr <= 0x7BFF)
|
||||
{
|
||||
/*
|
||||
TODO: Actually map cartridge (only if no ECS) RAM (Do not because of GRAM alias) / ROM to decide
|
||||
which path to take.
|
||||
*/
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[(addr & 0x0BFF) + 0x04C00];
|
||||
}
|
||||
else if (addr <= 0x7DFF)
|
||||
{
|
||||
/*
|
||||
TODO: Actually map cartridge (only if no ECS) RAM (Do not because of GRAM alias) / ROM to decide
|
||||
which path to take.
|
||||
*/
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[(addr & 0x0DFF) + 0x04C00];
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
TODO: Actually map cartridge (only if no ECS) RAM (Do not because of GRAM alias) / ROM to decide
|
||||
which path to take.
|
||||
*/
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_READ);
|
||||
else
|
||||
core = Cartridge[(addr & 0x0FFF) + 0x04C00];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
throw new ArgumentException(INVALID);
|
||||
}
|
||||
/*
|
||||
TODO: Fix Intellicart hook.
|
||||
|
@ -59,33 +248,195 @@ namespace BizHawk.Emulation.Consoles.Intellivision
|
|||
switch (addr & 0xF000)
|
||||
{
|
||||
case 0x0000:
|
||||
if (addr >= 0x0100 && addr <= 0x01EF)
|
||||
{
|
||||
if (addr <= 0x003F)
|
||||
STIC_Registers[addr] = value;
|
||||
else if (addr <= 0x007F)
|
||||
throw new ArgumentException(READ_ONLY_STIC);
|
||||
else if (addr <= 0x00FF)
|
||||
throw new ArgumentException(UNOCCUPIED);
|
||||
else if (addr <= 0x01EF)
|
||||
Scratchpad_RAM[addr & 0x00EF] = value;
|
||||
break;
|
||||
}
|
||||
else if (addr >= 0x01F0 && addr <= 0x01FF)
|
||||
{
|
||||
else if (addr <= 0x01FF)
|
||||
PSG_Registers[addr & 0x000F] = value;
|
||||
break;
|
||||
}
|
||||
else if (addr >= 0x0200 && addr <= 0x035F)
|
||||
{
|
||||
else if (addr <= 0x035F)
|
||||
System_RAM[addr & 0x015F] = value;
|
||||
break;
|
||||
}
|
||||
else if (addr <= 0x03FF)
|
||||
// TODO: Intellivision II support?
|
||||
throw new ArgumentException(GARBAGE);
|
||||
else if (addr <= 0x04FF)
|
||||
// TODO: Actually map cartridge (on all but Intellivision II) RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
// TODO: Intellivision II support?
|
||||
throw new ArgumentException(INTV2_EXEC);
|
||||
else
|
||||
Cartridge[addr & 0x00FF] = value;
|
||||
else if (addr <= 0x06FF)
|
||||
// TODO: Actually map cartridge RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_WRITE);
|
||||
else
|
||||
Cartridge[addr & 0x02FF] = value;
|
||||
else if (addr <= 0x0CFF)
|
||||
// TODO: Actually map cartridge (only if no Intellivoice) RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_WRITE);
|
||||
else
|
||||
Cartridge[addr & 0x08FF] = value;
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
// TODO: Actually map cartridge RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_WRITE);
|
||||
else
|
||||
Cartridge[addr & 0x0BFF] = value;
|
||||
break;
|
||||
case 0x1000:
|
||||
throw new ArgumentException(READ_ONLY_EXEC);
|
||||
case 0x2000:
|
||||
// TODO: Actually map cartridge (only if no ECS) RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_WRITE);
|
||||
else
|
||||
Cartridge[(addr & 0x0FFF) + 0x0C00] = value;
|
||||
break;
|
||||
case 0x3000:
|
||||
if (addr >= 0x3800 && addr <= 0x39FF)
|
||||
{
|
||||
if (addr <= 0x37FF)
|
||||
throw new ArgumentException(READ_ONLY_GROM);
|
||||
else if (addr <= 0x39FF)
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
Graphics_RAM[addr & 0x01FF] = value;
|
||||
break;
|
||||
else if (addr <= 0x3BFF)
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
Graphics_RAM[addr & 0x01FF] = value;
|
||||
else if (addr <= 0x3DFF)
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
Graphics_RAM[addr & 0x01FF] = value;
|
||||
else
|
||||
// TODO: OK only during VBlank Period 2.
|
||||
Graphics_RAM[addr & 0x01FF] = value;
|
||||
break;
|
||||
case 0x4000:
|
||||
if (addr <= 0x403F)
|
||||
{
|
||||
// TODO: Actually map cartridge (only if no ECS) RAM / ROM to decide which path to take.
|
||||
if (true)
|
||||
// TODO: OK only during VBlank Period 1.
|
||||
STIC_Registers[addr & 0x003F] = value;
|
||||
else
|
||||
Cartridge[(addr & 0x003F) + 0x1C00] = value;
|
||||
}
|
||||
else if (addr <= 0x47FF)
|
||||
{
|
||||
// TODO: Actually map cartridge (only if no ECS) RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_WRITE);
|
||||
else
|
||||
Cartridge[(addr & 0x07FF) + 0x1C00] = value;
|
||||
}
|
||||
else if (addr == 0x4800)
|
||||
{
|
||||
// TODO: Actually map cartridge (only if boot ROM at $7000) RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_WRITE);
|
||||
else
|
||||
Cartridge[0x2400] = value;
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
{
|
||||
// TODO: Actually map cartridge RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_WRITE);
|
||||
else
|
||||
Cartridge[(addr & 0x0FFF) + 0x01C00] = value;
|
||||
}
|
||||
break;
|
||||
case 0x5000:
|
||||
case 0x6000:
|
||||
if (addr <= 0x5014)
|
||||
{
|
||||
/*
|
||||
TODO: Actually map (only if boot ROM at $4800 or $7000) cartridge RAM / ROM to decide which path to
|
||||
take.
|
||||
*/
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_WRITE);
|
||||
else
|
||||
Cartridge[(addr & 0x0014) + 0x02C00] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_WRITE);
|
||||
else
|
||||
Cartridge[(addr & 0x1FFF) + 0x02C00] = value;
|
||||
}
|
||||
break;
|
||||
case 0x7000:
|
||||
if (addr == 0x7000)
|
||||
{
|
||||
/*
|
||||
TODO: Actually map cartridge (only if no ECS) RAM (confuses EXEC boot sequence) / ROM to decide
|
||||
which path to take.
|
||||
*/
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_WRITE);
|
||||
else
|
||||
Cartridge[0x04C00] = value;
|
||||
}
|
||||
else if (addr <= 0x77FF)
|
||||
{
|
||||
// TODO: Actually map cartridge (only if no ECS) RAM / ROM to decide which path to take.
|
||||
if (false)
|
||||
throw new ArgumentException(UNOCCUPIED_CART_WRITE);
|
||||
else
|
||||
Cartridge[(addr & 0x07FF) + 0x04C00] = value;
|
||||
}
|
||||
else if (addr <= 0x79FF)
|
||||
{
|
||||
/*
|
||||
TODO: Actually map cartridge (only if no ECS) RAM (Do not because of GRAM alias) / ROM to decide
|
||||
which path to take.
|
||||
*/
|
||||
if (true)
|
||||
Graphics_RAM[addr & 0x01FF] = value;
|
||||
else
|
||||
Cartridge[(addr & 0x09FF) + 0x04C00] = value;
|
||||
}
|
||||
else if (addr <= 0x7BFF)
|
||||
{
|
||||
/*
|
||||
TODO: Actually map cartridge (only if no ECS) RAM (Do not because of GRAM alias) / ROM to decide
|
||||
which path to take.
|
||||
*/
|
||||
if (true)
|
||||
Graphics_RAM[addr & 0x01FF] = value;
|
||||
else
|
||||
Cartridge[(addr & 0x0BFF) + 0x04C00] = value;
|
||||
}
|
||||
else if (addr <= 0x7DFF)
|
||||
{
|
||||
/*
|
||||
TODO: Actually map cartridge (only if no ECS) RAM (Do not because of GRAM alias) / ROM to decide
|
||||
which path to take.
|
||||
*/
|
||||
if (true)
|
||||
Graphics_RAM[addr & 0x01FF] = value;
|
||||
else
|
||||
Cartridge[(addr & 0x0DFF) + 0x04C00] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
TODO: Actually map cartridge (only if no ECS) RAM (Do not because of GRAM alias) / ROM to decide
|
||||
which path to take.
|
||||
*/
|
||||
if (true)
|
||||
Graphics_RAM[addr & 0x01FF] = value;
|
||||
else
|
||||
Cartridge[(addr & 0x0FFF) + 0x04C00] = value;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
throw new ArgumentException(INVALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue