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:
brandman211 2012-07-30 22:25:00 +00:00
parent a34bf45610
commit f66d92f2a5
2 changed files with 382 additions and 30 deletions

View File

@ -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)

View File

@ -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);
}
}
}