diff --git a/BizHawk.Emulation/Consoles/Intellivision/Cartridge.cs b/BizHawk.Emulation/Consoles/Intellivision/Cartridge.cs index bb33de0fb8..79900fdd20 100644 --- a/BizHawk.Emulation/Consoles/Intellivision/Cartridge.cs +++ b/BizHawk.Emulation/Consoles/Intellivision/Cartridge.cs @@ -11,205 +11,236 @@ namespace BizHawk.Emulation.Consoles.Intellivision public int Parse(byte[] Rom) { - // TODO: Actually parse the ROM. - return 1; + // TODO: Fix. + 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) { // TODO: Check if address is RAM / ROM. + int dest; switch (addr & 0xF000) { case 0x0000: + dest = addr - 0x0400; if (addr <= 0x03FF) break; if (addr <= 0x04FF) // OK on all but Intellivision 2. - return Data[addr & 0x00FF]; + return Data[dest]; else if (addr <= 0x06FF) - return Data[addr & 0x02FF]; + return Data[dest]; else if (addr <= 0x0CFF) // OK if no Intellivoice. - return Data[addr & 0x08FF]; + return Data[dest]; else - return Data[addr & 0x0BFF]; + return Data[dest]; case 0x2000: + dest = (addr - 0x2000) + 0x0C00; // OK if no ECS. - return Data[(addr & 0x0FFF) + 0x0C00]; + return Data[dest]; case 0x4000: + dest = (addr - 0x4000) + 0x1C00; if (addr <= 0x47FF) // OK if no ECS. - return Data[(addr & 0x07FF) + 0x1C00]; + return Data[dest]; else if (addr == 0x4800) - return Data[0x2400]; + return Data[dest]; else - return Data[(addr & 0x0FFF) + 0x1C00]; + return Data[dest]; case 0x5000: case 0x6000: + dest = (addr - 0x5000) + 0x2C00; if (addr <= 0x5014) - return Data[(addr & 0x0014) + 0x2C00]; + return Data[dest]; else - return Data[(addr & 0x1FFF) + 0x2C00]; + return Data[dest]; case 0x7000: + dest = (addr - 0x7000) + 0x4C00; if (addr == 0x7000) // OK if no ECS. - return Data[0x04C00]; + return Data[dest]; else if (addr <= 0x77FF) // OK if no ECS. - return Data[(addr & 0x07FF) + 0x4C00]; + return Data[dest]; else // OK if no ECS. - return Data[(addr & 0x0FFF) + 0x4C00]; + return Data[dest]; case 0x8000: + dest = (addr - 0x8000) + 0x5C00; // OK. Avoid STIC alias at $8000-$803F. - return Data[(addr & 0x0FFF) + 0x5C00]; + return Data[dest]; case 0x9000: case 0xA000: case 0xB000: + dest = (addr - 0x9000) + 0x6C00; if (addr <= 0xB7FF) - return Data[(addr & 0x27FF) + 0x6C00]; + return Data[dest]; else - return Data[(addr & 0x2FFF) + 0x6C00]; + return Data[dest]; case 0xC000: + dest = (addr - 0xC000) + 0x9C00; // OK. Avoid STIC alias at $C000-$C03F. - return Data[(addr & 0x0FFF) + 0x9C00]; + return Data[dest]; case 0xD000: - return Data[(addr & 0x0FFF) + 0xAC00]; + dest = (addr - 0xD000) + 0xAC00; + return Data[dest]; case 0xE000: + dest = (addr - 0xE000) + 0xBC00; // OK if no ECS. - return Data[(addr & 0x0FFF) + 0xBC00]; + return Data[dest]; case 0xF000: + dest = (addr - 0xF000) + 0xCC00; if (addr <= 0xF7FF) - return Data[(addr & 0x07FF) + 0xCC00]; + return Data[dest]; else - return Data[(addr & 0x0FFF) + 0xCC00]; + return Data[dest]; } return null; } public bool Write(ushort addr, ushort value) { + int dest; // TODO: Check if address is RAM / ROM. switch (addr & 0xF000) { case 0x0000: + dest = addr - 0x0400; if (addr <= 0x03FF) break; if (addr <= 0x04FF) { // OK on all but Intellivision 2. - Data[addr & 0x00FF] = value; + Data[dest] = value; return true; } else if (addr <= 0x06FF) { - Data[addr & 0x02FF] = value; + Data[dest] = value; return true; } else if (addr <= 0x0CFF) { // OK if no Intellivoice. - Data[addr & 0x08FF] = value; + Data[dest] = value; return true; } else { - Data[addr & 0x0BFF] = value; + Data[dest] = value; return true; } case 0x2000: + dest = (addr - 0x2000) + 0x0C00; // OK if no ECS. - Data[(addr & 0x0FFF) + 0x0C00] = value; + Data[dest] = value; return true; case 0x4000: + dest = (addr - 0x4000) + 0x1C00; if (addr <= 0x47FF) { // OK if no ECS. - Data[(addr & 0x07FF) + 0x1C00] = value; + Data[dest] = value; return true; } else if (addr == 0x4800) { // OK only if boot ROM at $7000. - Data[0x2400] = value; + Data[dest] = value; return true; } else { - Data[(addr & 0x0FFF) + 0x1C00] = value; + Data[dest] = value; return true; } case 0x5000: case 0x6000: + dest = (addr - 0x5000) + 0x2C00; if (addr <= 0x5014) { // OK only if boot ROM at $4800 or $7000. - Data[(addr & 0x0014) + 0x2C00] = value; + Data[dest] = value; return true; } else { - Data[(addr & 0x1FFF) + 0x2C00] = value; + Data[dest] = value; return true; } case 0x7000: + dest = (addr - 0x7000) + 0x4C00; if (addr == 0x7000) { // RAM at $7000 confuses EXEC boot sequence. - Data[0x04C00] = value; + Data[dest] = value; return true; } else if (addr <= 0x77FF) { // OK if no ECS. - Data[(addr & 0x07FF) + 0x4C00] = value; + Data[dest] = value; return true; } else { // Do not map RAM here due to GRAM alias. - Data[(addr & 0x0FFF) + 0x4C00] = value; + Data[dest] = value; return true; } case 0x8000: + dest = (addr - 0x8000) + 0x5C00; // OK. Avoid STIC alias at $8000-$803F. - Data[(addr & 0x0FFF) + 0x5C00] = value; + Data[dest] = value; return true; case 0x9000: case 0xA000: case 0xB000: + dest = (addr - 0x9000) + 0x6C00; if (addr <= 0xB7FF) { - Data[(addr & 0x27FF) + 0x6C00] = value; + Data[dest] = value; return true; } else { // Do not map RAM here due to GRAM alias. - Data[(addr & 0x2FFF) + 0x6C00] = value; + Data[dest] = value; return true; } case 0xC000: + dest = (addr - 0xC000) + 0x9C00; // OK. Avoid STIC alias at $C000-$C03F. - Data[(addr & 0x0FFF) + 0x9C00] = value; + Data[dest] = value; return true; case 0xD000: Data[(addr & 0x0FFF) + 0xAC00] = value; return true; case 0xE000: + dest = (addr - 0xE000) + 0xBC00; // OK if no ECS. - Data[(addr & 0x0FFF) + 0xBC00] = value; + Data[dest] = value; return true; case 0xF000: + dest = (addr - 0xF000) + 0xCC00; if (addr <= 0xF7FF) { - Data[(addr & 0x07FF) + 0xCC00] = value; + Data[dest] = value; return true; } else { // Do not map RAM here due to GRAM alias. - Data[(addr & 0x0FFF) + 0xCC00] = value; + Data[dest] = value; return true; } } diff --git a/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs b/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs index da988a3d50..bbe05a2cc3 100644 --- a/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs +++ b/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs @@ -21,6 +21,7 @@ namespace BizHawk.Emulation.Consoles.Intellivision { ushort? cart = Cart.Read(addr); ushort? core = null; + int dest; switch (addr & 0xF000) { case 0x0000: @@ -29,16 +30,16 @@ namespace BizHawk.Emulation.Consoles.Intellivision core = STIC_Registers[addr]; else if (addr <= 0x007F) // TODO: OK only during VBlank Period 2. - core = STIC_Registers[addr & 0x003F]; + core = STIC_Registers[addr - 0x0040]; else if (addr <= 0x00FF) // Unoccupied. break; else if (addr <= 0x01EF) - core = Scratchpad_RAM[addr & 0x00EF]; + core = Scratchpad_RAM[addr - 0x0100]; else if (addr <= 0x01FF) - core = PSG_Registers[addr & 0x000F]; + core = PSG_Registers[addr - 0x01F0]; else if (addr <= 0x035F) - core = System_RAM[addr & 0x015F]; + core = System_RAM[addr - 0x0200]; else if (addr <= 0x03FF) // TODO: Garbage values for Intellivision II. break; @@ -47,24 +48,24 @@ namespace BizHawk.Emulation.Consoles.Intellivision break; break; case 0x1000: - core = Executive_ROM[addr & 0x0FFF]; + core = Executive_ROM[addr - 0x1000]; break; case 0x3000: if (addr <= 0x37FF) // TODO: OK only during VBlank Period 2. - core = Graphics_ROM[addr & 0x07FF]; + core = Graphics_ROM[addr - 0x3000]; else if (addr <= 0x39FF) // TODO: OK only during VBlank Period 2. - core = Graphics_RAM[addr & 0x01FF]; + core = Graphics_RAM[addr - 0x3800]; else if (addr <= 0x3BFF) // TODO: OK only during VBlank Period 2. - core = Graphics_RAM[addr & 0x01FF]; + core = Graphics_RAM[addr - 0x3A00]; else if (addr <= 0x3DFF) // TODO: OK only during VBlank Period 2. - core = Graphics_RAM[addr & 0x01FF]; + core = Graphics_RAM[addr - 0x3C00]; else // TODO: OK only during VBlank Period 2. - core = Graphics_RAM[addr & 0x01FF]; + core = Graphics_RAM[addr - 0x3E00]; break; case 0x4000: if (addr <= 0x403F) @@ -169,17 +170,17 @@ namespace BizHawk.Emulation.Consoles.Intellivision break; else if (addr <= 0x01EF) { - Scratchpad_RAM[addr & 0x00EF] = value; + Scratchpad_RAM[addr - 0x0100] = value; return true; } else if (addr <= 0x01FF) { - PSG_Registers[addr & 0x000F] = value; + PSG_Registers[addr - 0x01F0] = value; return true; } else if (addr <= 0x035F) { - System_RAM[addr & 0x015F] = value; + System_RAM[addr - 0x0200] = value; return true; } else if (addr <= 0x03FF) @@ -199,32 +200,32 @@ namespace BizHawk.Emulation.Consoles.Intellivision else if (addr <= 0x39FF) { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0x3800] = value; return true; } else if (addr <= 0x3BFF) { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0x3A00] = value; return true; } else if (addr <= 0x3DFF) { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0x3C00] = value; return true; } else { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0x3E00] = value; return true; } case 0x4000: if (addr <= 0x403F) { // TODO: OK only during VBlank Period 1. - STIC_Registers[addr & 0x003F] = value; + STIC_Registers[addr - 0x4000] = value; return true; } break; @@ -273,32 +274,32 @@ namespace BizHawk.Emulation.Consoles.Intellivision else if (addr <= 0xB9FF) { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0xB800] = value; return true; } else if (addr <= 0xBBFF) { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0xBA00] = value; return true; } else if (addr <= 0xBDFF) { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0xBC00] = value; return true; } else { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0xBE00] = value; return true; } case 0xC000: if (addr <= 0x803F) { // TODO: OK only during VBlank Period 1. - STIC_Registers[addr & 0x003F] = value; + STIC_Registers[addr - 0xC000] = value; return true; } break; @@ -309,25 +310,25 @@ namespace BizHawk.Emulation.Consoles.Intellivision else if (addr <= 0xF9FF) { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0xF800] = value; return true; } else if (addr <= 0xFBFF) { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0xFA00] = value; return true; } else if (addr <= 0xFDFF) { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0xFC00] = value; return true; } else { // TODO: OK only during VBlank Period 2. - Graphics_RAM[addr & 0x01FF] = value; + Graphics_RAM[addr - 0xFE00] = value; return true; } }