diff --git a/BizHawk.Emulation.Cores/Calculator/TI83.IEmulator.cs b/BizHawk.Emulation.Cores/Calculator/TI83.IEmulator.cs index 1d6b7be044..622664bcc7 100644 --- a/BizHawk.Emulation.Cores/Calculator/TI83.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Calculator/TI83.IEmulator.cs @@ -22,20 +22,35 @@ namespace BizHawk.Emulation.Cores.Calculators _cpu.TraceCallback = null; } - // I eyeballed this speed - for (int i = 0; i < 5; i++) - { - _onPressed = controller.IsPressed("ON"); + _onPressed = controller.IsPressed("ON"); - // and this was derived from other emus - for (int j = 0; j < 10000; j++) - { - _cpu.ExecuteOne(); - } - + if (_onPressed && ON_key_int_EN && !ON_key_int) + { + ON_key_int = 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++; if (_lagged) diff --git a/BizHawk.Emulation.Cores/Calculator/TI83.IStatable.cs b/BizHawk.Emulation.Cores/Calculator/TI83.IStatable.cs index 0539da2ae0..d2bd9192ca 100644 --- a/BizHawk.Emulation.Cores/Calculator/TI83.IStatable.cs +++ b/BizHawk.Emulation.Cores/Calculator/TI83.IStatable.cs @@ -69,6 +69,15 @@ namespace BizHawk.Emulation.Cores.Calculators ser.Sync("Frame", ref _frame); ser.Sync("LagCount", ref _lagCount); 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(); if (ser.IsReader) diff --git a/BizHawk.Emulation.Cores/Calculator/TI83.cs b/BizHawk.Emulation.Cores/Calculator/TI83.cs index dc70edff41..09b0928449 100644 --- a/BizHawk.Emulation.Cores/Calculator/TI83.cs +++ b/BizHawk.Emulation.Cores/Calculator/TI83.cs @@ -34,14 +34,6 @@ namespace BizHawk.Emulation.Cores.Calculators _rom = rom; 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(); SetupMemoryDomains(); @@ -57,8 +49,6 @@ namespace BizHawk.Emulation.Cores.Calculators private readonly byte[] _rom; // configuration - private readonly ushort _startPC; - private IController _controller; private byte[] _ram; @@ -75,6 +65,10 @@ namespace BizHawk.Emulation.Cores.Calculators private bool _cursorMoved; 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 public TI83LinkPort LinkPort { get; } @@ -169,7 +163,60 @@ namespace BizHawk.Emulation.Cores.Calculators _romPageLow3Bits = value & 0x7; break; 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; case 16: // PORT_DISPCTRL ////Console.WriteLine("write PORT_DISPCTRL {0}",value); @@ -198,22 +245,23 @@ namespace BizHawk.Emulation.Cores.Calculators { // Console.WriteLine("read PORT_STATUS"); // 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) // 2 - Unknown, but used // 3 - Set if ON key is up // 4-7 - Unknown - ////if (onPressed && maskOn) ret |= 1; - ////if (!onPressed) ret |= 0x8; - return (byte)((_controller.IsPressed("ON") ? _maskOn : 8) | (LinkActive ? 0 : 2)); + + return (byte)((_controller.IsPressed("ON") ? 0 : 8) | + (TIM_1_int ? 2 : 0) | + (ON_key_int ? 1 : 0)); } case 4: // PORT_INTCTRL - ////Console.WriteLine("read PORT_INTCTRL"); - return 0xFF; + // returns mirror of link port + return (byte)((_romPageHighBit << 4) | (LinkState << 2) | LinkOutput); case 16: // PORT_DISPCTRL - ////Console.WriteLine("read DISPCTRL"); + // Console.WriteLine("read DISPCTRL"); break; case 17: // PORT_DISPDATA @@ -447,7 +495,7 @@ namespace BizHawk.Emulation.Cores.Calculators _ram[i] = 0xFF; } - _cpu.RegPC = _startPC; + _cpu.RegPC = 0; _cpu.IFF1 = false; _cpu.IFF2 = false;