TI-83 Upgrade

- Fix power on Behaviour
- Fix cycle timing
- Fix timer interrupt frequency
- NOTE: 'ON' buton on virtual calculator doesn't work since it's only a 'click', need to use shortcut key to turn the calculator on
This commit is contained in:
alyosha-tas 2017-10-20 10:32:22 -04:00 committed by GitHub
parent 5e0a373c6f
commit 3c6dcf1dc3
3 changed files with 101 additions and 29 deletions

View File

@ -22,20 +22,35 @@ namespace BizHawk.Emulation.Cores.Calculators
_cpu.TraceCallback = null; _cpu.TraceCallback = null;
} }
// I eyeballed this speed _onPressed = controller.IsPressed("ON");
for (int i = 0; i < 5; i++)
{
_onPressed = controller.IsPressed("ON");
// and this was derived from other emus if (_onPressed && ON_key_int_EN && !ON_key_int)
for (int j = 0; j < 10000; j++) {
{ ON_key_int = true;
_cpu.ExecuteOne();
}
_cpu.FlagI = true; _cpu.FlagI = true;
} }
// see: http://wikiti.brandonw.net/index.php?title=83:Ports:04
// for timer interrupt frequency
// CPU frequency is 6MHz
for (int i = 0; i < 100000; i++)
{
_cpu.ExecuteOne();
TIM_count++;
if (TIM_count >= TIM_hit)
{
TIM_count = 0;
if (TIM_1_int_EN)
{
TIM_1_int = true;
_cpu.FlagI = true;
}
}
}
Frame++; Frame++;
if (_lagged) if (_lagged)

View File

@ -69,6 +69,15 @@ namespace BizHawk.Emulation.Cores.Calculators
ser.Sync("Frame", ref _frame); ser.Sync("Frame", ref _frame);
ser.Sync("LagCount", ref _lagCount); ser.Sync("LagCount", ref _lagCount);
ser.Sync("IsLag", ref _isLag); ser.Sync("IsLag", ref _isLag);
ser.Sync("ON_key_int", ref ON_key_int);
ser.Sync("ON_key_int_EN", ref ON_key_int_EN);
ser.Sync("TIM_1_int", ref TIM_1_int);
ser.Sync("TIM_1_int_EN", ref TIM_1_int_EN);
ser.Sync("TIM_frq", ref TIM_frq);
ser.Sync("TIM_mult", ref TIM_mult);
ser.Sync("TIM_count", ref TIM_count);
ser.Sync("TIM_hit", ref TIM_hit);
ser.EndSection(); ser.EndSection();
if (ser.IsReader) if (ser.IsReader)

View File

@ -34,14 +34,6 @@ namespace BizHawk.Emulation.Cores.Calculators
_rom = rom; _rom = rom;
LinkPort = new TI83LinkPort(this); LinkPort = new TI83LinkPort(this);
// different calculators (different revisions?) have different initPC. we track this in the game database by rom hash
// if( *(unsigned long *)(m_pRom + 0x6ce) == 0x04D3163E ) m_Regs.PC.W = 0x6ce; //KNOWN
// else if( *(unsigned long *)(m_pRom + 0x6f6) == 0x04D3163E ) m_Regs.PC.W = 0x6f6; //UNKNOWN
if (game["initPC"])
{
_startPC = ushort.Parse(game.OptionValue("initPC"), NumberStyles.HexNumber);
}
HardReset(); HardReset();
SetupMemoryDomains(); SetupMemoryDomains();
@ -57,8 +49,6 @@ namespace BizHawk.Emulation.Cores.Calculators
private readonly byte[] _rom; private readonly byte[] _rom;
// configuration // configuration
private readonly ushort _startPC;
private IController _controller; private IController _controller;
private byte[] _ram; private byte[] _ram;
@ -75,6 +65,10 @@ namespace BizHawk.Emulation.Cores.Calculators
private bool _cursorMoved; private bool _cursorMoved;
private int _frame; private int _frame;
public bool ON_key_int, ON_key_int_EN;
public bool TIM_1_int, TIM_1_int_EN;
public int TIM_frq, TIM_mult, TIM_count, TIM_hit;
// Link Cable // Link Cable
public TI83LinkPort LinkPort { get; } public TI83LinkPort LinkPort { get; }
@ -169,7 +163,60 @@ namespace BizHawk.Emulation.Cores.Calculators
_romPageLow3Bits = value & 0x7; _romPageLow3Bits = value & 0x7;
break; break;
case 3: // PORT_STATUS case 3: // PORT_STATUS
_maskOn = (byte)(value & 1); // controls ON key interrupts
if ((value & 0x1) == 0)
{
ON_key_int = false;
ON_key_int_EN = false;
}
else
{
ON_key_int_EN = true;
}
// controls first timer interrupts
if ((value & 0x2) == 0)
{
TIM_1_int = false;
TIM_1_int_EN = false;
}
else
{
TIM_1_int_EN = true;
}
// controls second timer, not yet implemented and unclear how to differentiate
if ((value & 0x4) == 0)
{
}
else
{
}
// controls low power mode, not yet implemeneted
if ((value & 0x8) == 0)
{
}
else
{
}
break;
case 4: // PORT_INTCTRL
// controls ON key interrupts
TIM_frq = value & 6;
TIM_mult = ((value & 0x10) == 0x10) ? 1800 : 1620;
TIM_hit = (int)Math.Floor((double)TIM_mult / (3 + TIM_frq * 2));
TIM_hit = (int)Math.Floor((double)6000000 / TIM_hit);
// Bit 0 is some form of memory mapping
// Bit 5 controls reset
// Bit 6-7 controls battery power compare (not implemented, will always return full power)
break; break;
case 16: // PORT_DISPCTRL case 16: // PORT_DISPCTRL
////Console.WriteLine("write PORT_DISPCTRL {0}",value); ////Console.WriteLine("write PORT_DISPCTRL {0}",value);
@ -198,22 +245,23 @@ namespace BizHawk.Emulation.Cores.Calculators
{ {
// Console.WriteLine("read PORT_STATUS"); // Console.WriteLine("read PORT_STATUS");
// Bits: // Bits:
// 0 - Set if ON key is down and ON key is trapped // 0 - Set if ON key Interrupt generated
// 1 - Update things (keyboard etc) // 1 - Update things (keyboard etc)
// 2 - Unknown, but used // 2 - Unknown, but used
// 3 - Set if ON key is up // 3 - Set if ON key is up
// 4-7 - Unknown // 4-7 - Unknown
////if (onPressed && maskOn) ret |= 1;
////if (!onPressed) ret |= 0x8; return (byte)((_controller.IsPressed("ON") ? 0 : 8) |
return (byte)((_controller.IsPressed("ON") ? _maskOn : 8) | (LinkActive ? 0 : 2)); (TIM_1_int ? 2 : 0) |
(ON_key_int ? 1 : 0));
} }
case 4: // PORT_INTCTRL case 4: // PORT_INTCTRL
////Console.WriteLine("read PORT_INTCTRL"); // returns mirror of link port
return 0xFF; return (byte)((_romPageHighBit << 4) | (LinkState << 2) | LinkOutput);
case 16: // PORT_DISPCTRL case 16: // PORT_DISPCTRL
////Console.WriteLine("read DISPCTRL"); // Console.WriteLine("read DISPCTRL");
break; break;
case 17: // PORT_DISPDATA case 17: // PORT_DISPDATA
@ -447,7 +495,7 @@ namespace BizHawk.Emulation.Cores.Calculators
_ram[i] = 0xFF; _ram[i] = 0xFF;
} }
_cpu.RegPC = _startPC; _cpu.RegPC = 0;
_cpu.IFF1 = false; _cpu.IFF1 = false;
_cpu.IFF2 = false; _cpu.IFF2 = false;