-Separated the STIC and PSG memory map logic into new objects.

-Foreground / Background | Color Stack Mode
--Actually made a boolean for it (FGBG).
--Reading from a write-only STIC alias of $21 does change the STIC into Color Stack mode, but it doesn't actually read.
--Color stack mode is enabled when $21 or its alias is read and it is disabled (FGBG) when written its written, both having to occur during VBlank Period 1.
---This is what I gathered from the wiki, but I'm confused as to why it says that "The STIC stays in this mode until the program accesses location $21 again." I'm assuming this doesn't mean the mode changes on every access because then I don't understand why a read would change to a different mode than a write.
--FGBG is disabled by default. I don't think it matters.
This commit is contained in:
brandman211 2012-08-08 23:05:55 +00:00
parent 2fc36dca9b
commit 5239b4f55b
8 changed files with 174 additions and 84 deletions

View File

@ -118,6 +118,8 @@
<Compile Include="Consoles\Intellivision\Intellicart.cs" />
<Compile Include="Consoles\Intellivision\Intellivision.cs" />
<Compile Include="Consoles\Intellivision\MemoryMap.cs" />
<Compile Include="Consoles\Intellivision\PSG.cs" />
<Compile Include="Consoles\Intellivision\STIC.cs" />
<Compile Include="Consoles\Nintendo\NES\APU.cs" />
<Compile Include="Consoles\Nintendo\NES\BoardSystem.cs" />
<Compile Include="Consoles\Nintendo\NES\Boards\AVE-NINA.cs" />

View File

@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Consoles.Intellivision
return Rom.Length;
}
public ushort? Read(ushort addr)
public ushort? ReadCart(ushort addr)
{
// TODO: Check if address is RAM / ROM.
int dest;
@ -111,7 +111,7 @@ namespace BizHawk.Emulation.Consoles.Intellivision
return null;
}
public bool Write(ushort addr, ushort value)
public bool WriteCart(ushort addr, ushort value)
{
int dest;
// TODO: Check if address is RAM / ROM.

View File

@ -131,7 +131,7 @@ namespace BizHawk.Emulation.Consoles.Intellivision
return offset;
}
public ushort? Read(ushort addr)
public ushort? ReadCart(ushort addr)
{
int range = addr / 2048;
bool[] attributes = MemoryAttributes[range];
@ -140,7 +140,7 @@ namespace BizHawk.Emulation.Consoles.Intellivision
return null;
}
public bool Write(ushort addr, ushort value)
public bool WriteCart(ushort addr, ushort value)
{
int range = addr / 2048;
bool[] attributes = MemoryAttributes[range];

View File

@ -12,6 +12,8 @@ namespace BizHawk.Emulation.Consoles.Intellivision
CP1610 Cpu;
ICart Cart;
STIC Stic;
PSG Psg;
public void LoadExecutive_ROM()
{
@ -55,6 +57,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision
Cpu.WriteMemory = WriteMemory;
Cpu.LogData();
Stic = new STIC();
Psg = new PSG();
CoreOutputComm = new CoreOutputComm();
}

View File

@ -9,9 +9,7 @@ namespace BizHawk.Emulation.Consoles.Intellivision
{
private const ushort UNMAPPED = 0xFFFF;
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]; // TODO: Intellivision II support?
private ushort[] Graphics_ROM = new ushort[2048];
@ -19,25 +17,24 @@ namespace BizHawk.Emulation.Consoles.Intellivision
public ushort ReadMemory(ushort addr)
{
ushort? cart = Cart.Read(addr);
ushort? cart = Cart.ReadCart(addr);
ushort? stic = Stic.ReadSTIC(addr);
ushort? psg = Psg.ReadPSG(addr);
ushort? core = null;
int dest;
switch (addr & 0xF000)
{
case 0x0000:
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 - 0x0040];
if (addr <= 0x007F)
// STIC.
break;
else if (addr <= 0x00FF)
// Unoccupied.
break;
else if (addr <= 0x01EF)
core = Scratchpad_RAM[addr - 0x0100];
else if (addr <= 0x01FF)
core = PSG_Registers[addr - 0x01F0];
// PSG.
break;
else if (addr <= 0x035F)
core = System_RAM[addr - 0x0200];
else if (addr <= 0x03FF)
@ -67,15 +64,6 @@ namespace BizHawk.Emulation.Consoles.Intellivision
// TODO: OK only during VBlank Period 2.
core = Graphics_RAM[addr - 0x3E00];
break;
case 0x4000:
if (addr <= 0x403F)
{
if (addr == 0x4021)
// TODO: OK only during VBlank Period 1.
// TODO: Switch into Color Stack mode.
core = STIC_Registers[0x0021];
}
break;
case 0x7000:
if (addr <= 0x77FF)
// Available to cartridges.
@ -92,15 +80,6 @@ namespace BizHawk.Emulation.Consoles.Intellivision
else
// Write-only Graphics RAM.
break;
case 0x8000:
if (addr <= 0x803F)
{
if (addr == 0x8021)
// TODO: OK only during VBlank Period 1.
// TODO: Switch into Color Stack mode.
core = STIC_Registers[0x0021];
}
break;
case 0xB000:
if (addr <= 0xB7FF)
// Available to cartridges.
@ -117,15 +96,6 @@ namespace BizHawk.Emulation.Consoles.Intellivision
else
// Write-only Graphics RAM.
break;
case 0xC000:
if (addr <= 0xC03F)
{
if (addr == 0xC021)
// TODO: OK only during VBlank Period 1.
// TODO: Switch into Color Stack mode.
core = STIC_Registers[0x0021];
}
break;
case 0xF000:
if (addr <= 0xF7FF)
// Available to cartridges.
@ -145,25 +115,25 @@ namespace BizHawk.Emulation.Consoles.Intellivision
}
if (cart != null)
return (ushort)cart;
else if (core == null)
return UNMAPPED;
else if (stic != null)
return (ushort)stic;
else if (psg != null)
return (ushort)psg;
else if (core != null)
return (ushort)core;
return UNMAPPED;
}
public bool WriteMemory(ushort addr, ushort value)
{
bool cart = Cart.Write(addr, value);
bool cart = Cart.WriteCart(addr, value);
bool stic = Stic.WriteSTIC(addr, value);
bool psg = Psg.WritePSG(addr, value);
switch (addr & 0xF000)
{
case 0x0000:
if (addr <= 0x003F)
{
// TODO: OK only during VBlank Period 1.
STIC_Registers[addr] = value;
return true;
}
else if (addr <= 0x007F)
// Read-only STIC.
if (addr <= 0x007F)
// STIC.
break;
else if (addr <= 0x00FF)
// Unoccupied.
@ -175,8 +145,8 @@ namespace BizHawk.Emulation.Consoles.Intellivision
}
else if (addr <= 0x01FF)
{
PSG_Registers[addr - 0x01F0] = value;
return true;
// PSG.
break;
}
else if (addr <= 0x035F)
{
@ -221,14 +191,6 @@ namespace BizHawk.Emulation.Consoles.Intellivision
Graphics_RAM[addr - 0x3E00] = value;
return true;
}
case 0x4000:
if (addr <= 0x403F)
{
// TODO: OK only during VBlank Period 1.
STIC_Registers[addr - 0x4000] = value;
return true;
}
break;
case 0x7000:
if (addr <= 0x77FF)
// Available to cartridges.
@ -257,14 +219,6 @@ namespace BizHawk.Emulation.Consoles.Intellivision
Graphics_RAM[addr & 0x01FF] = value;
return true;
}
case 0x8000:
if (addr <= 0x803F)
{
// TODO: OK only during VBlank Period 1.
STIC_Registers[addr & 0x003F] = value;
return true;
}
break;
case 0x9000:
case 0xA000:
case 0xB000:
@ -295,14 +249,6 @@ namespace BizHawk.Emulation.Consoles.Intellivision
Graphics_RAM[addr - 0xBE00] = value;
return true;
}
case 0xC000:
if (addr <= 0x803F)
{
// TODO: OK only during VBlank Period 1.
STIC_Registers[addr - 0xC000] = value;
return true;
}
break;
case 0xF000:
if (addr <= 0xF7FF)
// Available to cartridges.
@ -332,7 +278,7 @@ namespace BizHawk.Emulation.Consoles.Intellivision
return true;
}
}
return cart;
return (cart || stic || psg);
}
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Consoles.Intellivision
{
public sealed class PSG
{
private ushort[] Registers = new ushort[16];
public ushort? ReadPSG(ushort addr)
{
if (addr >= 0x01F0 && addr <= 0x01FF)
return Registers[addr - 0x01F0];
return null;
}
public bool WritePSG(ushort addr, ushort value)
{
if (addr >= 0x01F0 && addr <= 0x01FF)
{
Registers[addr - 0x01F0] = value;
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Consoles.Intellivision
{
public sealed class STIC
{
private ushort[] Registers = new ushort[64];
private bool FGBG = false;
public ushort? ReadSTIC(ushort addr)
{
switch (addr & 0xF000)
{
case 0x0000:
if (addr <= 0x003F)
{
// TODO: OK only during VBlank Period 1.
if (addr == 0x0021)
FGBG = false;
return Registers[addr];
}
else if (addr <= 0x007F)
// TODO: OK only during VBlank Period 2.
return Registers[addr - 0x0040];
break;
case 0x4000:
if (addr <= 0x403F)
{
// TODO: OK only during VBlank Period 1.
if (addr == 0x4021)
FGBG = false;
}
break;
case 0x8000:
if (addr <= 0x803F)
{
// TODO: OK only during VBlank Period 1.
if (addr == 0x8021)
FGBG = false;
}
break;
case 0xC000:
if (addr <= 0xC03F)
{
// TODO: OK only during VBlank Period 1.
if (addr == 0xC021)
FGBG = false;
}
break;
}
return null;
}
public bool WriteSTIC(ushort addr, ushort value)
{
switch (addr & 0xF000)
{
case 0x0000:
if (addr <= 0x003F)
{
// TODO: OK only during VBlank Period 1.
if (addr == 0x0021)
FGBG = true;
Registers[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;
Registers[addr - 0x4000] = value;
return true;
}
break;
case 0x8000:
if (addr <= 0x803F)
{
// TODO: OK only during VBlank Period 1.
if (addr == 0x8021)
FGBG = true;
Registers[addr & 0x003F] = value;
return true;
}
break;
case 0xC000:
if (addr <= 0xC03F)
{
// TODO: OK only during VBlank Period 1.
if (addr == 0xC021)
FGBG = true;
Registers[addr - 0xC000] = value;
return true;
}
break;
}
return false;
}
}
}

View File

@ -8,7 +8,7 @@ namespace BizHawk
public interface ICart
{
int Parse(byte[] Rom);
ushort? Read(ushort addr);
bool Write(ushort addr, ushort value);
ushort? ReadCart(ushort addr);
bool WriteCart(ushort addr, ushort value);
}
}