-Fixed the memory mapping. I don't know why I thought I'd be able to just mask addresses to the length of the segment and think it'd work...

-Tried two methods of parsing the ROM file. Neither of them worked.
This commit is contained in:
brandman211 2012-08-01 17:45:37 +00:00
parent 5a28f54454
commit 97727ab658
2 changed files with 102 additions and 70 deletions

View File

@ -11,205 +11,236 @@ namespace BizHawk.Emulation.Consoles.Intellivision
public int Parse(byte[] Rom) public int Parse(byte[] Rom)
{ {
// TODO: Actually parse the ROM. // TODO: Fix.
return 1; 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];
*/
return Rom.Length;
} }
public ushort? Read(ushort addr) public ushort? Read(ushort addr)
{ {
// TODO: Check if address is RAM / ROM. // TODO: Check if address is RAM / ROM.
int dest;
switch (addr & 0xF000) switch (addr & 0xF000)
{ {
case 0x0000: case 0x0000:
dest = addr - 0x0400;
if (addr <= 0x03FF) if (addr <= 0x03FF)
break; break;
if (addr <= 0x04FF) if (addr <= 0x04FF)
// OK on all but Intellivision 2. // OK on all but Intellivision 2.
return Data[addr & 0x00FF]; return Data[dest];
else if (addr <= 0x06FF) else if (addr <= 0x06FF)
return Data[addr & 0x02FF]; return Data[dest];
else if (addr <= 0x0CFF) else if (addr <= 0x0CFF)
// OK if no Intellivoice. // OK if no Intellivoice.
return Data[addr & 0x08FF]; return Data[dest];
else else
return Data[addr & 0x0BFF]; return Data[dest];
case 0x2000: case 0x2000:
dest = (addr - 0x2000) + 0x0C00;
// OK if no ECS. // OK if no ECS.
return Data[(addr & 0x0FFF) + 0x0C00]; return Data[dest];
case 0x4000: case 0x4000:
dest = (addr - 0x4000) + 0x1C00;
if (addr <= 0x47FF) if (addr <= 0x47FF)
// OK if no ECS. // OK if no ECS.
return Data[(addr & 0x07FF) + 0x1C00]; return Data[dest];
else if (addr == 0x4800) else if (addr == 0x4800)
return Data[0x2400]; return Data[dest];
else else
return Data[(addr & 0x0FFF) + 0x1C00]; return Data[dest];
case 0x5000: case 0x5000:
case 0x6000: case 0x6000:
dest = (addr - 0x5000) + 0x2C00;
if (addr <= 0x5014) if (addr <= 0x5014)
return Data[(addr & 0x0014) + 0x2C00]; return Data[dest];
else else
return Data[(addr & 0x1FFF) + 0x2C00]; return Data[dest];
case 0x7000: case 0x7000:
dest = (addr - 0x7000) + 0x4C00;
if (addr == 0x7000) if (addr == 0x7000)
// OK if no ECS. // OK if no ECS.
return Data[0x04C00]; return Data[dest];
else if (addr <= 0x77FF) else if (addr <= 0x77FF)
// OK if no ECS. // OK if no ECS.
return Data[(addr & 0x07FF) + 0x4C00]; return Data[dest];
else else
// OK if no ECS. // OK if no ECS.
return Data[(addr & 0x0FFF) + 0x4C00]; return Data[dest];
case 0x8000: case 0x8000:
dest = (addr - 0x8000) + 0x5C00;
// OK. Avoid STIC alias at $8000-$803F. // OK. Avoid STIC alias at $8000-$803F.
return Data[(addr & 0x0FFF) + 0x5C00]; return Data[dest];
case 0x9000: case 0x9000:
case 0xA000: case 0xA000:
case 0xB000: case 0xB000:
dest = (addr - 0x9000) + 0x6C00;
if (addr <= 0xB7FF) if (addr <= 0xB7FF)
return Data[(addr & 0x27FF) + 0x6C00]; return Data[dest];
else else
return Data[(addr & 0x2FFF) + 0x6C00]; return Data[dest];
case 0xC000: case 0xC000:
dest = (addr - 0xC000) + 0x9C00;
// OK. Avoid STIC alias at $C000-$C03F. // OK. Avoid STIC alias at $C000-$C03F.
return Data[(addr & 0x0FFF) + 0x9C00]; return Data[dest];
case 0xD000: case 0xD000:
return Data[(addr & 0x0FFF) + 0xAC00]; dest = (addr - 0xD000) + 0xAC00;
return Data[dest];
case 0xE000: case 0xE000:
dest = (addr - 0xE000) + 0xBC00;
// OK if no ECS. // OK if no ECS.
return Data[(addr & 0x0FFF) + 0xBC00]; return Data[dest];
case 0xF000: case 0xF000:
dest = (addr - 0xF000) + 0xCC00;
if (addr <= 0xF7FF) if (addr <= 0xF7FF)
return Data[(addr & 0x07FF) + 0xCC00]; return Data[dest];
else else
return Data[(addr & 0x0FFF) + 0xCC00]; return Data[dest];
} }
return null; return null;
} }
public bool Write(ushort addr, ushort value) public bool Write(ushort addr, ushort value)
{ {
int dest;
// TODO: Check if address is RAM / ROM. // TODO: Check if address is RAM / ROM.
switch (addr & 0xF000) switch (addr & 0xF000)
{ {
case 0x0000: case 0x0000:
dest = addr - 0x0400;
if (addr <= 0x03FF) if (addr <= 0x03FF)
break; break;
if (addr <= 0x04FF) if (addr <= 0x04FF)
{ {
// OK on all but Intellivision 2. // OK on all but Intellivision 2.
Data[addr & 0x00FF] = value; Data[dest] = value;
return true; return true;
} }
else if (addr <= 0x06FF) else if (addr <= 0x06FF)
{ {
Data[addr & 0x02FF] = value; Data[dest] = value;
return true; return true;
} }
else if (addr <= 0x0CFF) else if (addr <= 0x0CFF)
{ {
// OK if no Intellivoice. // OK if no Intellivoice.
Data[addr & 0x08FF] = value; Data[dest] = value;
return true; return true;
} }
else else
{ {
Data[addr & 0x0BFF] = value; Data[dest] = value;
return true; return true;
} }
case 0x2000: case 0x2000:
dest = (addr - 0x2000) + 0x0C00;
// OK if no ECS. // OK if no ECS.
Data[(addr & 0x0FFF) + 0x0C00] = value; Data[dest] = value;
return true; return true;
case 0x4000: case 0x4000:
dest = (addr - 0x4000) + 0x1C00;
if (addr <= 0x47FF) if (addr <= 0x47FF)
{ {
// OK if no ECS. // OK if no ECS.
Data[(addr & 0x07FF) + 0x1C00] = value; Data[dest] = value;
return true; return true;
} }
else if (addr == 0x4800) else if (addr == 0x4800)
{ {
// OK only if boot ROM at $7000. // OK only if boot ROM at $7000.
Data[0x2400] = value; Data[dest] = value;
return true; return true;
} }
else else
{ {
Data[(addr & 0x0FFF) + 0x1C00] = value; Data[dest] = value;
return true; return true;
} }
case 0x5000: case 0x5000:
case 0x6000: case 0x6000:
dest = (addr - 0x5000) + 0x2C00;
if (addr <= 0x5014) if (addr <= 0x5014)
{ {
// OK only if boot ROM at $4800 or $7000. // OK only if boot ROM at $4800 or $7000.
Data[(addr & 0x0014) + 0x2C00] = value; Data[dest] = value;
return true; return true;
} }
else else
{ {
Data[(addr & 0x1FFF) + 0x2C00] = value; Data[dest] = value;
return true; return true;
} }
case 0x7000: case 0x7000:
dest = (addr - 0x7000) + 0x4C00;
if (addr == 0x7000) if (addr == 0x7000)
{ {
// RAM at $7000 confuses EXEC boot sequence. // RAM at $7000 confuses EXEC boot sequence.
Data[0x04C00] = value; Data[dest] = value;
return true; return true;
} }
else if (addr <= 0x77FF) else if (addr <= 0x77FF)
{ {
// OK if no ECS. // OK if no ECS.
Data[(addr & 0x07FF) + 0x4C00] = value; Data[dest] = value;
return true; return true;
} }
else else
{ {
// Do not map RAM here due to GRAM alias. // Do not map RAM here due to GRAM alias.
Data[(addr & 0x0FFF) + 0x4C00] = value; Data[dest] = value;
return true; return true;
} }
case 0x8000: case 0x8000:
dest = (addr - 0x8000) + 0x5C00;
// OK. Avoid STIC alias at $8000-$803F. // OK. Avoid STIC alias at $8000-$803F.
Data[(addr & 0x0FFF) + 0x5C00] = value; Data[dest] = value;
return true; return true;
case 0x9000: case 0x9000:
case 0xA000: case 0xA000:
case 0xB000: case 0xB000:
dest = (addr - 0x9000) + 0x6C00;
if (addr <= 0xB7FF) if (addr <= 0xB7FF)
{ {
Data[(addr & 0x27FF) + 0x6C00] = value; Data[dest] = value;
return true; return true;
} }
else else
{ {
// Do not map RAM here due to GRAM alias. // Do not map RAM here due to GRAM alias.
Data[(addr & 0x2FFF) + 0x6C00] = value; Data[dest] = value;
return true; return true;
} }
case 0xC000: case 0xC000:
dest = (addr - 0xC000) + 0x9C00;
// OK. Avoid STIC alias at $C000-$C03F. // OK. Avoid STIC alias at $C000-$C03F.
Data[(addr & 0x0FFF) + 0x9C00] = value; Data[dest] = value;
return true; return true;
case 0xD000: case 0xD000:
Data[(addr & 0x0FFF) + 0xAC00] = value; Data[(addr & 0x0FFF) + 0xAC00] = value;
return true; return true;
case 0xE000: case 0xE000:
dest = (addr - 0xE000) + 0xBC00;
// OK if no ECS. // OK if no ECS.
Data[(addr & 0x0FFF) + 0xBC00] = value; Data[dest] = value;
return true; return true;
case 0xF000: case 0xF000:
dest = (addr - 0xF000) + 0xCC00;
if (addr <= 0xF7FF) if (addr <= 0xF7FF)
{ {
Data[(addr & 0x07FF) + 0xCC00] = value; Data[dest] = value;
return true; return true;
} }
else else
{ {
// Do not map RAM here due to GRAM alias. // Do not map RAM here due to GRAM alias.
Data[(addr & 0x0FFF) + 0xCC00] = value; Data[dest] = value;
return true; return true;
} }
} }

View File

@ -21,6 +21,7 @@ namespace BizHawk.Emulation.Consoles.Intellivision
{ {
ushort? cart = Cart.Read(addr); ushort? cart = Cart.Read(addr);
ushort? core = null; ushort? core = null;
int dest;
switch (addr & 0xF000) switch (addr & 0xF000)
{ {
case 0x0000: case 0x0000:
@ -29,16 +30,16 @@ namespace BizHawk.Emulation.Consoles.Intellivision
core = STIC_Registers[addr]; core = STIC_Registers[addr];
else if (addr <= 0x007F) else if (addr <= 0x007F)
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
core = STIC_Registers[addr & 0x003F]; core = STIC_Registers[addr - 0x0040];
else if (addr <= 0x00FF) else if (addr <= 0x00FF)
// Unoccupied. // Unoccupied.
break; break;
else if (addr <= 0x01EF) else if (addr <= 0x01EF)
core = Scratchpad_RAM[addr & 0x00EF]; core = Scratchpad_RAM[addr - 0x0100];
else if (addr <= 0x01FF) else if (addr <= 0x01FF)
core = PSG_Registers[addr & 0x000F]; core = PSG_Registers[addr - 0x01F0];
else if (addr <= 0x035F) else if (addr <= 0x035F)
core = System_RAM[addr & 0x015F]; core = System_RAM[addr - 0x0200];
else if (addr <= 0x03FF) else if (addr <= 0x03FF)
// TODO: Garbage values for Intellivision II. // TODO: Garbage values for Intellivision II.
break; break;
@ -47,24 +48,24 @@ namespace BizHawk.Emulation.Consoles.Intellivision
break; break;
break; break;
case 0x1000: case 0x1000:
core = Executive_ROM[addr & 0x0FFF]; core = Executive_ROM[addr - 0x1000];
break; break;
case 0x3000: case 0x3000:
if (addr <= 0x37FF) if (addr <= 0x37FF)
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
core = Graphics_ROM[addr & 0x07FF]; core = Graphics_ROM[addr - 0x3000];
else if (addr <= 0x39FF) else if (addr <= 0x39FF)
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
core = Graphics_RAM[addr & 0x01FF]; core = Graphics_RAM[addr - 0x3800];
else if (addr <= 0x3BFF) else if (addr <= 0x3BFF)
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
core = Graphics_RAM[addr & 0x01FF]; core = Graphics_RAM[addr - 0x3A00];
else if (addr <= 0x3DFF) else if (addr <= 0x3DFF)
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
core = Graphics_RAM[addr & 0x01FF]; core = Graphics_RAM[addr - 0x3C00];
else else
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
core = Graphics_RAM[addr & 0x01FF]; core = Graphics_RAM[addr - 0x3E00];
break; break;
case 0x4000: case 0x4000:
if (addr <= 0x403F) if (addr <= 0x403F)
@ -169,17 +170,17 @@ namespace BizHawk.Emulation.Consoles.Intellivision
break; break;
else if (addr <= 0x01EF) else if (addr <= 0x01EF)
{ {
Scratchpad_RAM[addr & 0x00EF] = value; Scratchpad_RAM[addr - 0x0100] = value;
return true; return true;
} }
else if (addr <= 0x01FF) else if (addr <= 0x01FF)
{ {
PSG_Registers[addr & 0x000F] = value; PSG_Registers[addr - 0x01F0] = value;
return true; return true;
} }
else if (addr <= 0x035F) else if (addr <= 0x035F)
{ {
System_RAM[addr & 0x015F] = value; System_RAM[addr - 0x0200] = value;
return true; return true;
} }
else if (addr <= 0x03FF) else if (addr <= 0x03FF)
@ -199,32 +200,32 @@ namespace BizHawk.Emulation.Consoles.Intellivision
else if (addr <= 0x39FF) else if (addr <= 0x39FF)
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0x3800] = value;
return true; return true;
} }
else if (addr <= 0x3BFF) else if (addr <= 0x3BFF)
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0x3A00] = value;
return true; return true;
} }
else if (addr <= 0x3DFF) else if (addr <= 0x3DFF)
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0x3C00] = value;
return true; return true;
} }
else else
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0x3E00] = value;
return true; return true;
} }
case 0x4000: case 0x4000:
if (addr <= 0x403F) if (addr <= 0x403F)
{ {
// TODO: OK only during VBlank Period 1. // TODO: OK only during VBlank Period 1.
STIC_Registers[addr & 0x003F] = value; STIC_Registers[addr - 0x4000] = value;
return true; return true;
} }
break; break;
@ -273,32 +274,32 @@ namespace BizHawk.Emulation.Consoles.Intellivision
else if (addr <= 0xB9FF) else if (addr <= 0xB9FF)
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0xB800] = value;
return true; return true;
} }
else if (addr <= 0xBBFF) else if (addr <= 0xBBFF)
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0xBA00] = value;
return true; return true;
} }
else if (addr <= 0xBDFF) else if (addr <= 0xBDFF)
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0xBC00] = value;
return true; return true;
} }
else else
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0xBE00] = value;
return true; return true;
} }
case 0xC000: case 0xC000:
if (addr <= 0x803F) if (addr <= 0x803F)
{ {
// TODO: OK only during VBlank Period 1. // TODO: OK only during VBlank Period 1.
STIC_Registers[addr & 0x003F] = value; STIC_Registers[addr - 0xC000] = value;
return true; return true;
} }
break; break;
@ -309,25 +310,25 @@ namespace BizHawk.Emulation.Consoles.Intellivision
else if (addr <= 0xF9FF) else if (addr <= 0xF9FF)
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0xF800] = value;
return true; return true;
} }
else if (addr <= 0xFBFF) else if (addr <= 0xFBFF)
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0xFA00] = value;
return true; return true;
} }
else if (addr <= 0xFDFF) else if (addr <= 0xFDFF)
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0xFC00] = value;
return true; return true;
} }
else else
{ {
// TODO: OK only during VBlank Period 2. // TODO: OK only during VBlank Period 2.
Graphics_RAM[addr & 0x01FF] = value; Graphics_RAM[addr - 0xFE00] = value;
return true; return true;
} }
} }