Intellivision Implement STIC access restrictions

Big accuracy improvement
This commit is contained in:
alyosha-tas 2016-12-22 21:07:31 -05:00 committed by GitHub
parent 9cd47a2058
commit 35d86388a4
3 changed files with 219 additions and 118 deletions

View File

@ -40,10 +40,10 @@ namespace BizHawk.Emulation.Cores.Intellivision
int cycles = _cpu.Execute(); int cycles = _cpu.Execute();
_psg.generate_sound(cycles); _psg.generate_sound(cycles);
if (delay_cycles>=0) if (delay_cycles>=0 && _stic.active_display)
delay_cycles += cycles; delay_cycles += cycles;
if (delay_timer>0) if (delay_timer> 0 && _stic.active_display)
{ {
delay_timer -= cycles; delay_timer -= cycles;
if (delay_timer<=0) if (delay_timer<=0)
@ -53,7 +53,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
} }
if (delay_cycles>=800) if (delay_cycles>= 800 && _stic.active_display)
{ {
delay_cycles = -1; delay_cycles = -1;
delay_timer = 110; delay_timer = 110;
@ -63,12 +63,20 @@ namespace BizHawk.Emulation.Cores.Intellivision
Connect(); Connect();
} }
_stic.Background(); // set up VBlank variables
_stic.Mobs(); _stic.in_vb_1 = true;
_stic.in_vb_2 = true;
if (_stic.active_display)
{
_stic.Background();
_stic.Mobs();
}
_stic.active_display = false;
_stic.Sr1 = false; _stic.Sr1 = false;
_cpu.PendingCycles = (3791 + _cpu.GetPendingCycles()); _cpu.PendingCycles = (2900 + _cpu.GetPendingCycles());
while (_cpu.GetPendingCycles() > 0) while (_cpu.GetPendingCycles() > 0)
{ {
@ -77,6 +85,18 @@ namespace BizHawk.Emulation.Cores.Intellivision
Connect(); Connect();
} }
// vblank phase 2
_cpu.PendingCycles = (891 + _cpu.GetPendingCycles());
_stic.in_vb_1 = false;
while (_cpu.GetPendingCycles() > 0)
{
int cycles = _cpu.Execute();
//_psg.generate_sound(cycles);
Connect();
}
_stic.in_vb_2 = false;
} }
private int _frame; private int _frame;

View File

@ -74,28 +74,38 @@ namespace BizHawk.Emulation.Cores.Intellivision
case 0x3000: case 0x3000:
if (addr <= 0x37FF) if (addr <= 0x37FF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
core = (byte)(GraphicsRom[addr - 0x3000] & 0x00FF); {
core = (byte)(GraphicsRom[addr - 0x3000] & 0x00FF);
}
} }
else if (addr <= 0x39FF) else if (addr <= 0x39FF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
core = (byte)(GraphicsRam[addr - 0x3800] & 0x00FF); {
core = (byte)(GraphicsRam[addr - 0x3800] & 0x00FF);
}
} }
else if (addr <= 0x3BFF) else if (addr <= 0x3BFF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
core = (byte)(GraphicsRam[addr - 0x3A00] & 0x00FF); {
core = (byte)(GraphicsRam[addr - 0x3A00] & 0x00FF);
}
} }
else if (addr <= 0x3DFF) else if (addr <= 0x3DFF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
core = (byte)(GraphicsRam[addr - 0x3C00] & 0x00FF); {
core = (byte)(GraphicsRam[addr - 0x3C00] & 0x00FF);
}
} }
else else
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
core = (byte)(GraphicsRam[addr - 0x3E00] & 0x00FF); {
core = (byte)(GraphicsRam[addr - 0x3E00] & 0x00FF);
}
} }
break; break;
case 0x7000: case 0x7000:
@ -252,27 +262,39 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
else if (addr <= 0x39FF) else if (addr <= 0x39FF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0x3800] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0x3800] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else if (addr <= 0x3BFF) else if (addr <= 0x3BFF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0x3A00] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0x3A00] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else if (addr <= 0x3DFF) else if (addr <= 0x3DFF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0x3C00] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0x3C00] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else else
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0x3E00] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0x3E00] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
case 0x7000: case 0x7000:
if (addr <= 0x77FF) if (addr <= 0x77FF)
@ -282,27 +304,39 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
else if (addr <= 0x79FF) else if (addr <= 0x79FF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else if (addr <= 0x7BFF) else if (addr <= 0x7BFF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else if (addr <= 0x7DFF) else if (addr <= 0x7DFF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else else
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
case 0x9000: case 0x9000:
case 0xA000: case 0xA000:
@ -314,27 +348,40 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
else if (addr <= 0xB9FF) else if (addr <= 0xB9FF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0xB800] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0xB800] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else if (addr <= 0xBBFF) else if (addr <= 0xBBFF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0xBA00] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0xBA00] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else if (addr <= 0xBDFF) else if (addr <= 0xBDFF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0xBC00] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0xBC00] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else else
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0xBE00] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0xBE00] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
case 0xF000: case 0xF000:
if (addr <= 0xF7FF) if (addr <= 0xF7FF)
@ -344,27 +391,39 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
else if (addr <= 0xF9FF) else if (addr <= 0xF9FF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0xF800] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0xF800] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else if (addr <= 0xFBFF) else if (addr <= 0xFBFF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0xFA00] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0xFA00] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else if (addr <= 0xFDFF) else if (addr <= 0xFDFF)
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0xFC00] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0xFC00] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
else else
{ {
// TODO: OK only during VBlank Period 2. if (_stic.in_vb_2 | !_stic.active_display)
GraphicsRam[addr - 0xFE00] = (byte)(value & 0x00FF); {
return true; GraphicsRam[addr - 0xFE00] = (byte)(value & 0x00FF);
return true;
}
return false;
} }
} }

View File

@ -9,6 +9,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
public sealed class STIC : IVideoProvider public sealed class STIC : IVideoProvider
{ {
public bool Sr1, Sr2, Sst, Fgbg = false; public bool Sr1, Sr2, Sst, Fgbg = false;
public bool active_display, in_vb_1, in_vb_2 = false;
private ushort[] Register = new ushort[64]; private ushort[] Register = new ushort[64];
private ushort ColorSP = 0x0028; private ushort ColorSP = 0x0028;
@ -32,6 +33,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
ser.Sync("Sr1", ref Sr1); ser.Sync("Sr1", ref Sr1);
ser.Sync("Sr2", ref Sr2); ser.Sync("Sr2", ref Sr2);
ser.Sync("Sst", ref Sst); ser.Sync("Sst", ref Sst);
ser.Sync("active_display", ref active_display);
ser.Sync("in_vb_1", ref in_vb_1);
ser.Sync("in_vb_2", ref in_vb_2);
ser.Sync("Fgbg", ref Fgbg); ser.Sync("Fgbg", ref Fgbg);
ser.Sync("Toal_executed_cycles", ref TotalExecutedCycles); ser.Sync("Toal_executed_cycles", ref TotalExecutedCycles);
ser.Sync("Pending_Cycles", ref PendingCycles); ser.Sync("Pending_Cycles", ref PendingCycles);
@ -138,46 +142,56 @@ namespace BizHawk.Emulation.Cores.Intellivision
case 0x0000: case 0x0000:
if (addr <= 0x003F) if (addr <= 0x003F)
{ {
// TODO: OK only during VBlank Period 1. if (in_vb_1 | !active_display)
if (addr == 0x0021) {
{ if (addr == 0x0021)
Fgbg = false; {
Fgbg = false;
}
return Register[addr];
} }
return Register[addr];
} }
else if (addr <= 0x007F) else if (addr <= 0x007F)
{ {
// TODO: OK only during VBlank Period 2. if (in_vb_2 | !active_display)
return Register[addr - 0x0040]; {
return Register[addr - 0x0040];
}
} }
break; break;
case 0x4000: case 0x4000:
if (addr <= 0x403F) if (addr <= 0x403F)
{ {
// TODO: OK only during VBlank Period 1. if (in_vb_1 | !active_display)
if (addr == 0x4021)
{ {
Fgbg = false; if (addr == 0x4021)
{
Fgbg = false;
}
} }
} }
break; break;
case 0x8000: case 0x8000:
if (addr <= 0x803F) if (addr <= 0x803F)
{ {
// TODO: OK only during VBlank Period 1. if (in_vb_1 | !active_display)
if (addr == 0x8021)
{ {
Fgbg = false; if (addr == 0x8021)
{
Fgbg = false;
}
} }
} }
break; break;
case 0xC000: case 0xC000:
if (addr <= 0xC03F) if (addr <= 0xC03F)
{ {
// TODO: OK only during VBlank Period 1. if (in_vb_1 | !active_display)
if (addr == 0xC021)
{ {
Fgbg = false; if (addr == 0xC021)
{
Fgbg = false;
}
} }
} }
break; break;
@ -192,57 +206,73 @@ namespace BizHawk.Emulation.Cores.Intellivision
case 0x0000: case 0x0000:
if (addr <= 0x003F) if (addr <= 0x003F)
{ {
// TODO: OK only during VBlank Period 1. if (in_vb_1 | !active_display)
if (addr == 0x0021)
{ {
Fgbg = true; if (addr == 0x0021)
{
Fgbg = true;
}
if (addr == 0x0020)
{
active_display = true;
}
Register[addr] = register_mask(addr, value);
return true;
} }
//Console.WriteLine(value);
//Console.WriteLine(addr);
Register[addr] = register_mask(addr,value);
return true;
}
else if (addr <= 0x007F)
{
// Read-only STIC.
break;
} }
break; break;
case 0x4000: case 0x4000:
if (addr <= 0x403F) if (addr <= 0x403F)
{ {
// TODO: OK only during VBlank Period 1. if (in_vb_1 | !active_display)
if (addr == 0x4021)
{ {
Fgbg = true; if (addr == 0x4021)
{
Fgbg = true;
}
if (addr == 0x4020)
{
active_display = true;
}
Register[addr - 0x4000] = register_mask(addr - 0x4000, value);
return true;
} }
Register[addr - 0x4000] = register_mask(addr - 0x4000, value);
return true;
} }
break; break;
case 0x8000: case 0x8000:
if (addr <= 0x803F) if (addr <= 0x803F)
{ {
// TODO: OK only during VBlank Period 1. if (in_vb_1 | !active_display)
if (addr == 0x8021)
{ {
Fgbg = true; if (addr == 0x8021)
{
Fgbg = true;
}
if (addr == 0x8020)
{
active_display = true;
}
Register[addr & 0x003F] = register_mask(addr & 0x003F, value);
return true;
} }
Register[addr & 0x003F] = register_mask(addr & 0x003F, value);
return true;
} }
break; break;
case 0xC000: case 0xC000:
if (addr <= 0xC03F) if (addr <= 0xC03F)
{ {
// TODO: OK only during VBlank Period 1. if (in_vb_1 | !active_display)
if (addr == 0xC021)
{ {
Fgbg = true; if (addr == 0xC021)
{
Fgbg = true;
}
if (addr == 0xC020)
{
active_display = true;
}
Register[addr - 0xC000] = register_mask(addr - 0xC000, value);
return true;
} }
Register[addr - 0xC000] = register_mask(addr - 0xC000, value);
return true;
} }
break; break;
} }
@ -310,7 +340,6 @@ namespace BizHawk.Emulation.Cores.Intellivision
int card_num = card >> 3; int card_num = card >> 3;
int fg = card & 0x0007; int fg = card & 0x0007;
int bg; int bg;
if (Fgbg) if (Fgbg)
{ {
bg = ((card >> 9) & 0x0008) | ((card >> 11) & 0x0004) | ((card >> 9) & 0x0003); bg = ((card >> 9) & 0x0008) | ((card >> 11) & 0x0004) | ((card >> 9) & 0x0003);
@ -348,7 +377,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
if (colors[z]==7) if (colors[z]==7)
{ {
colors[z] = ReadMemory(ColorSP) & 0x000F; colors[z] = Register[ColorSP] & 0x000F;
square_col[z] = 0; square_col[z] = 0;
} }
else else
@ -417,7 +446,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
ColorSP = 0x0028; ColorSP = 0x0028;
} }
} }
bg = ReadMemory(ColorSP) & 0x000F; bg = Register[ColorSP] & 0x000F;
} }
} }
for (int pict_row = 0; pict_row < 8; pict_row++) for (int pict_row = 0; pict_row < 8; pict_row++)
@ -836,13 +865,6 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
} }
for (int z=0;z<8;z++)
{
//Console.WriteLine(z);
//Console.WriteLine(Register[z + 24]);
}
} }
// end of Mobs function, we now have collision and graphics data for the mobs // end of Mobs function, we now have collision and graphics data for the mobs