Remove TI83Hawk

This commit is contained in:
YoshiRulz 2025-01-11 00:52:14 +10:00
parent 89e94be8c1
commit 30cc02c9ff
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
17 changed files with 2 additions and 1290 deletions

View File

@ -4,7 +4,7 @@ An emulation project.
EmuHawk is a multi-system emulator written in C#. As well as quality-of-life features for casual players, it also has recording/playback and debugging tools, making it the first choice for TASers (Tool-Assisted Speedrunners). More info [below](#features-and-systems).
A7800Hawk, Atari2600Hawk, C64Hawk, ChannelFHawk, ColecoHawk, GBHawk, IntelliHawk, NesHawk, O2Hawk, PCEHawk, SMSHawk, TI83Hawk, VectrexHawk, and ZXHawk are bespoke emulation cores written in C#.
A7800Hawk, Atari2600Hawk, C64Hawk, ChannelFHawk, ColecoHawk, GBHawk, IntelliHawk, NesHawk, O2Hawk, PCEHawk, SMSHawk, VectrexHawk, and ZXHawk are bespoke emulation cores written in C#.
MSXHawk is a bespoke emulation core written in C++.
More info [below](#cores).
@ -357,7 +357,7 @@ Sega Master System | **Genplus-gx**, **SMSHawk**
Sega Saturn | **Saturnus**
SNES | **BSNES**, Faust, Snes9x
Super Game Boy | **BSNES**, **Gambatte**
TI-83 | **Emu83**, **TI83Hawk**
TI-83 | **Emu83**
TIC-80 | **TIC-80** reference implementation
TurboGrafx | HyperNyma, **PCEHawk**, **TurboNyma**
Uzebox | **Uzem**

View File

@ -50,8 +50,6 @@ namespace BizHawk.Client.Common
[ CoreNames.Gpgx, CoreNames.SMSHawk ]),
([ VSystemID.Raw.SNES ],
[ CoreNames.Snes9X, CoreNames.Bsnes115, CoreNames.SubBsnes115, CoreNames.Faust, CoreNames.Bsnes ]),
([ VSystemID.Raw.TI83 ],
[ CoreNames.Emu83, CoreNames.TI83Hawk ]),
};
public static Dictionary<string, string> GenDefaultCorePreferences()

View File

@ -233,7 +233,6 @@ namespace BizHawk.Client.EmuHawk
this.BarcodeReaderMenuItem = new BizHawk.WinForms.Controls.ToolStripMenuItemEx();
this.TI83SubMenu = new BizHawk.WinForms.Controls.ToolStripMenuItemEx();
this.KeypadMenuItem = new BizHawk.WinForms.Controls.ToolStripMenuItemEx();
this.LoadTIFileMenuItem = new BizHawk.WinForms.Controls.ToolStripMenuItemEx();
this.toolStripSeparator13 = new BizHawk.WinForms.Controls.ToolStripSeparatorEx();
this.paletteToolStripMenuItem = new BizHawk.WinForms.Controls.ToolStripMenuItemEx();
this.A7800SubMenu = new BizHawk.WinForms.Controls.ToolStripMenuItemEx();
@ -1557,7 +1556,6 @@ namespace BizHawk.Client.EmuHawk
//
this.TI83SubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.KeypadMenuItem,
this.LoadTIFileMenuItem,
this.toolStripSeparator13,
this.paletteToolStripMenuItem});
this.TI83SubMenu.Text = "TI83";
@ -1567,11 +1565,6 @@ namespace BizHawk.Client.EmuHawk
this.KeypadMenuItem.Text = "Keypad";
this.KeypadMenuItem.Click += new System.EventHandler(this.Ti83KeypadMenuItem_Click);
//
// LoadTIFileMenuItem
//
this.LoadTIFileMenuItem.Text = "Load TI-83 File...";
this.LoadTIFileMenuItem.Click += new System.EventHandler(this.Ti83LoadTIFileMenuItem_Click);
//
// paletteToolStripMenuItem
//
this.paletteToolStripMenuItem.Text = "Palette...";
@ -2643,7 +2636,6 @@ namespace BizHawk.Client.EmuHawk
private BizHawk.WinForms.Controls.ToolStripMenuItemEx ConfigContextMenuItem;
private BizHawk.WinForms.Controls.ToolStripMenuItemEx RewindOptionsMenuItem;
private BizHawk.WinForms.Controls.ToolStripMenuItemEx FirmwareMenuItem;
private BizHawk.WinForms.Controls.ToolStripMenuItemEx LoadTIFileMenuItem;
private BizHawk.WinForms.Controls.ToolStripMenuItemEx ClearSRAMContextMenuItem;
private BizHawk.WinForms.Controls.ToolStripSeparatorEx ShowMenuContextMenuSeparator;
private BizHawk.WinForms.Controls.ToolStripMenuItemEx StopAVContextMenuItem;

View File

@ -13,7 +13,6 @@ using BizHawk.Emulation.Cores.Atari.Atari2600;
using BizHawk.Emulation.Cores.Atari.Jaguar;
using BizHawk.Emulation.Cores.Atari.Lynx;
using BizHawk.Emulation.Cores.Calculators.Emu83;
using BizHawk.Emulation.Cores.Calculators.TI83;
using BizHawk.Emulation.Cores.ColecoVision;
using BizHawk.Emulation.Cores.Computers.Amiga;
using BizHawk.Emulation.Cores.Computers.AmstradCPC;
@ -894,34 +893,6 @@ namespace BizHawk.Client.EmuHawk
private void Ti83KeypadMenuItem_Click(object sender, EventArgs e)
=> Tools.Load<TI83KeyPad>();
private void Ti83LoadTIFileMenuItem_Click(object sender, EventArgs e)
{
if (Emulator is not TI83 ti83) return;
var result = this.ShowFileOpenDialog(
discardCWDChange: true,
filter: TI83ProgramFilesFSFilterSet,
initDir: Config.PathEntries.RomAbsolutePath(Emulator.SystemId));
if (result is null) return;
try
{
ti83.LinkPort.SendFileToCalc(File.OpenRead(result), true);
return;
}
catch (IOException ex)
{
if (this.ShowMessageBox3(
owner: null,
icon: EMsgBoxIcon.Question,
caption: "Upload Failed",
text: $"Invalid file format. Reason: {ex.Message} \nForce transfer? This may cause the calculator to crash.")
is not true)
{
return;
}
}
ti83.LinkPort.SendFileToCalc(File.OpenRead(result), false);
}
private DialogResult OpenTI83PaletteSettingsDialog(ISettingsAdapter settable)
{
using TI83PaletteConfig form = new(settable);
@ -933,7 +904,6 @@ namespace BizHawk.Client.EmuHawk
var result = Emulator switch
{
Emu83 => OpenTI83PaletteSettingsDialog(GetSettingsAdapterForLoadedCore<Emu83>()),
TI83 => OpenTI83PaletteSettingsDialog(GetSettingsAdapterForLoadedCore<TI83>()),
_ => DialogResult.None
};
if (result.IsOk()) AddOnScreenMessage("Palette settings saved");
@ -1386,9 +1356,6 @@ namespace BizHawk.Client.EmuHawk
};
items.Add(subNESHawkSubmenu);
// TI83Hawk
items.Add(CreateCoreSubmenu(VSystemCategory.Other, CoreNames.TI83Hawk, CreateSettingsItem("Palette...", (_, _) => OpenTI83PaletteSettingsDialog(GetSettingsAdapterFor<TI83>()))));
// TIC80
items.Add(CreateCoreSubmenu(VSystemCategory.PCs, CoreNames.TIC80, CreateGenericCoreConfigItem<TIC80>(CoreNames.TIC80)));
@ -1486,7 +1453,6 @@ namespace BizHawk.Client.EmuHawk
break;
case VSystemID.Raw.TI83:
TI83SubMenu.Visible = true;
LoadTIFileMenuItem.Visible = Emulator is TI83;
break;
case VSystemID.Raw.ZXSpectrum:
zXSpectrumToolStripMenuItem.Visible = true;

View File

@ -4275,7 +4275,6 @@ namespace BizHawk.Client.EmuHawk
var recommendedCore = currentCoreName switch
{
CoreNames.Snes9X => CoreNames.Bsnes115,
CoreNames.TI83Hawk => CoreNames.Emu83,
CoreNames.QuickNes => CoreNames.NesHawk,
CoreNames.Atari2600Hawk => CoreNames.Stella,
CoreNames.HyperNyma => CoreNames.TurboNyma,

View File

@ -589,7 +589,6 @@ namespace BizHawk.Client.EmuHawk
break;
case ConsoleID.TI83:
TryAddDomain("RAM"); // Emu83
TryAddDomain("Main RAM"); // TI83Hawk
break;
case ConsoleID.DS:
case ConsoleID.DSi:

View File

@ -21,7 +21,6 @@
<ItemGroup>
<Compile Update="Arcades/MAME/MAME.*.cs" DependentUpon="MAME.cs" />
<Compile Update="Calculators/Emu83/Emu83.*.cs" DependentUpon="Emu83.cs" />
<Compile Update="Calculators/TI83/TI83.*.cs" DependentUpon="TI83.cs" />
<Compile Update="Computers/Amiga/UAE.*.cs" DependentUpon="UAE.cs" />
<Compile Update="Computers/AppleII/AppleII.*.cs" DependentUpon="AppleII.cs" />
<Compile Update="Computers/Commodore64/C64.*.cs" DependentUpon="C64.cs" />

View File

@ -1,42 +0,0 @@
using BizHawk.Emulation.Cores.Components.Z80A;
namespace BizHawk.Emulation.Cores.Calculators.TI83
{
public partial class TI83
{
public readonly struct CpuLink(TI83 ti83) : IZ80ALink
{
public byte FetchMemory(ushort address)
=> ti83.ReadMemory(address);
public byte ReadMemory(ushort address)
=> ti83.ReadMemory(address);
public void WriteMemory(ushort address, byte value)
=> ti83.WriteMemory(address, value);
public byte ReadHardware(ushort address)
=> ti83.ReadHardware(address);
public void WriteHardware(ushort address, byte value)
=> ti83.WriteHardware(address, value);
public byte FetchDB()
=> 0xFF;
public void OnExecFetch(ushort address)
{
}
public void IRQCallback()
=> ti83.IRQCallback();
public void NMICallback()
=> ti83.NMICallback();
public void IRQACKCallback()
{
}
}
}
}

View File

@ -1,21 +0,0 @@
using System.Collections.Generic;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Calculators.TI83
{
public partial class TI83 : IDebuggable
{
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters() => _cpu.GetCpuFlagsAndRegisters();
public void SetCpuRegister(string register, int value) => _cpu.SetCpuRegister(register, value);
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem(new[] { "System Bus" });
[FeatureNotImplemented]
public void Step(StepType type) => throw new NotImplementedException();
public bool CanStep(StepType type) => false;
public long TotalExecutedCycles => _cpu.TotalExecutedCycles;
}
}

View File

@ -1,87 +0,0 @@
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Calculators.TI83
{
public partial class TI83 : IEmulator
{
public IEmulatorServiceProvider ServiceProvider { get; }
public ControllerDefinition ControllerDefinition => TI83Controller;
public bool FrameAdvance(IController controller, bool render, bool renderSound)
{
_controller = controller;
_lagged = true;
if (_tracer.IsEnabled())
{
_cpu.TraceCallback = s => _tracer.Put(s);
}
else
{
_cpu.TraceCallback = null;
}
_onPressed = controller.IsPressed("ON");
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)
{
_lagCount++;
}
_isLag = _lagged;
return true;
}
public int Frame
{
get => _frame;
private set => _frame = value;
}
public string SystemId => VSystemID.Raw.TI83;
public bool DeterministicEmulation => true;
public void ResetCounters()
{
Frame = 0;
_lagCount = 0;
_isLag = false;
}
public void Dispose()
{
}
}
}

View File

@ -1,25 +0,0 @@
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Calculators.TI83
{
public partial class TI83 : IInputPollable
{
private int _lagCount = 0;
private bool _lagged = true;
private bool _isLag = false;
public int LagCount
{
get => _lagCount;
set => _lagCount = value;
}
public IInputCallbackSystem InputCallbacks { get; } = new InputCallbackSystem();
public bool IsLagFrame
{
get => _isLag;
set => _isLag = value;
}
}
}

View File

@ -1,59 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Calculators.TI83
{
public partial class TI83
{
private readonly Dictionary<string, MemoryDomainByteArray> _byteArrayDomains = new Dictionary<string, MemoryDomainByteArray>();
private IMemoryDomains _memoryDomains;
private bool _memoryDomainsInit;
private void SetupMemoryDomains()
{
var domains = new List<MemoryDomain>();
var systemBusDomain = new MemoryDomainDelegate("System Bus", 0x10000, MemoryDomain.Endian.Little,
(addr) =>
{
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
return ReadMemory((ushort)addr);
},
(addr, value) =>
{
if (addr is < 0 or > 0xFFFF) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range");
WriteMemory((ushort)addr, value);
}, 1);
domains.Add(systemBusDomain);
SyncAllByteArrayDomains();
_memoryDomains = new MemoryDomainList(_byteArrayDomains.Values.Concat(domains).ToList());
((BasicServiceProvider) ServiceProvider).Register(_memoryDomains);
_memoryDomainsInit = true;
}
private void SyncAllByteArrayDomains()
{
SyncByteArrayDomain("Main RAM", _ram);
}
private void SyncByteArrayDomain(string name, byte[] data)
{
if (_memoryDomainsInit)
{
var m = _byteArrayDomains[name];
m.Data = data;
}
else
{
var m = new MemoryDomainByteArray(name, MemoryDomain.Endian.Little, data, true, 1);
_byteArrayDomains.Add(name, m);
}
}
}
}

View File

@ -1,53 +0,0 @@
using System.IO;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Calculators.TI83
{
public partial class TI83
{
private void SyncState(Serializer ser)
{
if (ser.IsWriter)
{
var ms = new MemoryStream();
ms.Close();
ms.ToArray();
}
ser.BeginSection(nameof(TI83));
_cpu.SyncState(ser);
ser.Sync("RAM", ref _ram, false);
ser.Sync("romPageLow3Bits", ref _romPageLow3Bits);
ser.Sync("romPageHighBit", ref _romPageHighBit);
ser.Sync("disp_mode", ref _displayMode);
ser.Sync("disp_move", ref _displayMove);
ser.Sync("disp_x", ref _displayX);
ser.Sync("disp_y", ref _displayY);
ser.Sync("m_CursorMoved", ref _cursorMoved);
ser.Sync("maskOn", ref _maskOn);
ser.Sync("onPressed", ref _onPressed);
ser.Sync("keyboardMask", ref _keyboardMask);
ser.Sync("m_LinkOutput", ref _linkOutput);
ser.Sync("VRAM", ref _vram, false);
ser.Sync("Frame", ref _frame);
ser.Sync("LagCount", ref _lagCount);
ser.Sync("IsLag", ref _isLag);
ser.Sync(nameof(ON_key_int), ref ON_key_int);
ser.Sync(nameof(ON_key_int_EN), ref ON_key_int_EN);
ser.Sync(nameof(TIM_1_int), ref TIM_1_int);
ser.Sync(nameof(TIM_1_int_EN), ref TIM_1_int_EN);
ser.Sync(nameof(TIM_frq), ref TIM_frq);
ser.Sync(nameof(TIM_mult), ref TIM_mult);
ser.Sync(nameof(TIM_count), ref TIM_count);
ser.Sync(nameof(TIM_hit), ref TIM_hit);
ser.EndSection();
if (ser.IsReader)
{
SyncAllByteArrayDomains();
}
}
}
}

View File

@ -1,45 +0,0 @@
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Calculators.TI83
{
public partial class TI83 : IVideoProvider
{
public int VirtualWidth => 96;
public int VirtualHeight => 64;
public int BufferWidth => 96;
public int BufferHeight => 64;
public int BackgroundColor => 0;
public int VsyncNumerator => NullVideo.DefaultVsyncNum;
public int VsyncDenominator => NullVideo.DefaultVsyncDen;
public int[] GetVideoBuffer()
{
// unflatten bit buffer
int[] pixels = new int[96 * 64];
int i = 0;
for (int y = 0; y < 64; y++)
{
for (int x = 0; x < 96; x++)
{
int offset = (y * 96) + x;
int buffByte = offset >> 3;
int buffBit = offset & 7;
int bit = (_vram[buffByte] >> (7 - buffBit)) & 1;
if (bit == 0)
{
unchecked
{
pixels[i++] = (int)_settings.BGColor;
}
}
else
{
pixels[i++] = (int)_settings.ForeColor;
}
}
}
return pixels;
}
}
}

View File

@ -1,503 +0,0 @@
using System.IO;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Components.Z80A;
// http://www.ticalc.org/pub/text/calcinfo/
namespace BizHawk.Emulation.Cores.Calculators.TI83
{
[Core(CoreNames.TI83Hawk, "zeromus")]
[ServiceNotApplicable(typeof(IBoardInfo), typeof(IRegionable), typeof(ISaveRam), typeof(ISoundProvider))]
public partial class TI83 : TI83Common, IEmulator, IVideoProvider, IDebuggable, IInputPollable
{
[CoreConstructor(VSystemID.Raw.TI83)]
public TI83(CoreLoadParameters<TI83CommonSettings, object> lp)
{
var ser = new BasicServiceProvider(this);
ServiceProvider = ser;
PutSettings(lp.Settings ?? new TI83CommonSettings());
_cpu = new Z80A<CpuLink>(new CpuLink(this));
_rom = lp.Comm.CoreFileProvider.GetFirmwareOrThrow(new("TI83", "Rom"));
LinkPort = new TI83LinkPort(this);
HardReset();
SetupMemoryDomains();
_tracer = new TraceBuffer(_cpu.TraceHeader);
ser.Register<ITraceable>(_tracer);
ser.Register<IDisassemblable>(_cpu);
ser.Register<IStatable>(new StateSerializer(SyncState));
LinkPort.SendFileToCalc(new MemoryStream(lp.Roms[0].RomData, false), false);
}
private readonly TraceBuffer _tracer;
private readonly Z80A<CpuLink> _cpu;
private readonly byte[] _rom;
// configuration
private IController _controller = NullController.Instance;
private byte[] _ram;
private byte[] _vram = new byte[0x300];
private int _romPageLow3Bits;
private int _romPageHighBit;
private byte _maskOn;
private bool _onPressed;
private int _keyboardMask;
private int _displayMode;
private int _displayMove;
private uint _displayX, _displayY;
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; }
private int _linkOutput;
internal int LinkOutput => _linkOutput;
internal bool LinkActive { get; set; }
internal int LinkInput { get; set; }
internal int LinkState => (_linkOutput | LinkInput) ^ 3;
private static readonly ControllerDefinition TI83Controller = new ControllerDefinition("TI83 Controller")
{
BoolButtons =
{
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "DOT",
"ON", "ENTER",
"DOWN", "LEFT", "UP", "RIGHT",
"PLUS", "MINUS", "MULTIPLY", "DIVIDE",
"CLEAR", "EXP", "DASH", "PARACLOSE", "TAN", "VARS", "PARAOPEN",
"COS", "PRGM", "STAT", "COMMA", "SIN", "MATRIX", "X",
"STO", "LN", "LOG", "SQUARED", "NEG1", "MATH", "ALPHA",
"GRAPH", "TRACE", "ZOOM", "WINDOW", "Y", "2ND", "MODE", "DEL",
},
}.MakeImmutable();
private byte ReadMemory(ushort addr)
{
byte ret;
int romPage = _romPageLow3Bits | (_romPageHighBit << 3);
if (addr < 0x4000)
{
ret = _rom[addr]; // ROM zero-page
}
else if (addr < 0x8000)
{
ret = _rom[(romPage * 0x4000) + addr - 0x4000]; // other rom page
}
else
{
ret = _ram[addr - 0x8000];
}
return ret;
}
private void WriteMemory(ushort addr, byte value)
{
if (addr < 0x4000)
{
// ROM zero-page
}
else if (addr < 0x8000)
{
// other rom page
}
else
{
_ram[addr - 0x8000] = value;
}
}
private void WriteHardware(ushort addr, byte value)
{
addr &= 0xFF;
switch (addr)
{
case 0: // PORT_LINK
_romPageHighBit = (value >> 4) & 1;
_linkOutput = value & 3;
if (LinkActive)
{
// Prevent rom calls from disturbing link port activity
if (LinkActive && _cpu.RegPC < 0x4000)
{
return;
}
LinkPort.Update();
}
break;
case 1: // PORT_KEYBOARD:
_lagged = false;
_keyboardMask = value;
////Console.WriteLine("write PORT_KEYBOARD {0:X2}",value);
break;
case 2: // PORT_ROMPAGE
_romPageLow3Bits = value & 0x7;
break;
case 3: // PORT_STATUS
// 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(6000000.0 / Math.Floor((double) TIM_mult / (2 * TIM_frq + 3)));
// 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);
WriteDispCtrl(value);
break;
case 17: // PORT_DISPDATA
////Console.WriteLine("write PORT_DISPDATA {0}",value);
WriteDispData(value);
break;
}
}
private byte ReadHardware(ushort addr)
{
addr &= 0xFF;
switch (addr)
{
case 0: // PORT_LINK
LinkPort.Update();
return (byte)((_romPageHighBit << 4) | (LinkState << 2) | LinkOutput);
case 1: // PORT_KEYBOARD:
////Console.WriteLine("read PORT_KEYBOARD");
return ReadKeyboard();
case 2: // PORT_ROMPAGE
return (byte)_romPageLow3Bits;
case 3: // PORT_STATUS
{
// Console.WriteLine("read PORT_STATUS");
// Bits:
// 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
return (byte)((_controller.IsPressed("ON") ? 0 : 8) |
(TIM_1_int ? 2 : 0) |
(ON_key_int ? 1 : 0));
}
case 4: // PORT_INTCTRL
// returns mirror of link port
return (byte)((_romPageHighBit << 4) | (LinkState << 2) | LinkOutput);
case 16: // PORT_DISPCTRL
// Console.WriteLine("read DISPCTRL");
break;
case 17: // PORT_DISPDATA
return ReadDispData();
}
return 0xFF;
}
private byte ReadKeyboard()
{
InputCallbacks.Call();
// ref TI-9X
int ret = 0xFF;
////Console.WriteLine("keyboardMask: {0:X2}",keyboardMask);
if ((_keyboardMask & 1) == 0)
{
if (_controller.IsPressed("DOWN")) ret ^= 1;
if (_controller.IsPressed("LEFT")) ret ^= 2;
if (_controller.IsPressed("RIGHT")) ret ^= 4;
if (_controller.IsPressed("UP")) ret ^= 8;
}
if ((_keyboardMask & 2) == 0)
{
if (_controller.IsPressed("ENTER")) ret ^= 1;
if (_controller.IsPressed("PLUS")) ret ^= 2;
if (_controller.IsPressed("MINUS")) ret ^= 4;
if (_controller.IsPressed("MULTIPLY")) ret ^= 8;
if (_controller.IsPressed("DIVIDE")) ret ^= 16;
if (_controller.IsPressed("EXP")) ret ^= 32;
if (_controller.IsPressed("CLEAR")) ret ^= 64;
}
if ((_keyboardMask & 4) == 0)
{
if (_controller.IsPressed("DASH")) ret ^= 1;
if (_controller.IsPressed("3")) ret ^= 2;
if (_controller.IsPressed("6")) ret ^= 4;
if (_controller.IsPressed("9")) ret ^= 8;
if (_controller.IsPressed("PARACLOSE")) ret ^= 16;
if (_controller.IsPressed("TAN")) ret ^= 32;
if (_controller.IsPressed("VARS")) ret ^= 64;
}
if ((_keyboardMask & 8) == 0)
{
if (_controller.IsPressed("DOT")) ret ^= 1;
if (_controller.IsPressed("2")) ret ^= 2;
if (_controller.IsPressed("5")) ret ^= 4;
if (_controller.IsPressed("8")) ret ^= 8;
if (_controller.IsPressed("PARAOPEN")) ret ^= 16;
if (_controller.IsPressed("COS")) ret ^= 32;
if (_controller.IsPressed("PRGM")) ret ^= 64;
if (_controller.IsPressed("STAT")) ret ^= 128;
}
if ((_keyboardMask & 16) == 0)
{
if (_controller.IsPressed("0")) ret ^= 1;
if (_controller.IsPressed("1")) ret ^= 2;
if (_controller.IsPressed("4")) ret ^= 4;
if (_controller.IsPressed("7")) ret ^= 8;
if (_controller.IsPressed("COMMA")) ret ^= 16;
if (_controller.IsPressed("SIN")) ret ^= 32;
if (_controller.IsPressed("MATRIX")) ret ^= 64;
if (_controller.IsPressed("X")) ret ^= 128;
}
if ((_keyboardMask & 32) == 0)
{
if (_controller.IsPressed("STO")) ret ^= 2;
if (_controller.IsPressed("LN")) ret ^= 4;
if (_controller.IsPressed("LOG")) ret ^= 8;
if (_controller.IsPressed("SQUARED")) ret ^= 16;
if (_controller.IsPressed("NEG1")) ret ^= 32;
if (_controller.IsPressed("MATH")) ret ^= 64;
if (_controller.IsPressed("ALPHA")) ret ^= 128;
}
if ((_keyboardMask & 64) == 0)
{
if (_controller.IsPressed("GRAPH")) ret ^= 1;
if (_controller.IsPressed("TRACE")) ret ^= 2;
if (_controller.IsPressed("ZOOM")) ret ^= 4;
if (_controller.IsPressed("WINDOW")) ret ^= 8;
if (_controller.IsPressed("Y")) ret ^= 16;
if (_controller.IsPressed("2ND")) ret ^= 32;
if (_controller.IsPressed("MODE")) ret ^= 64;
if (_controller.IsPressed("DEL")) ret ^= 128;
}
return (byte)ret;
}
private byte ReadDispData()
{
if (_cursorMoved)
{
_cursorMoved = false;
return 0x00; // not accurate this should be stale data or something
}
byte ret;
if (_displayMode == 1)
{
ret = _vram[(_displayY * 12) + _displayX];
}
else
{
int column = 6 * (int)_displayX;
int offset = (int)(_displayY * 12) + (column >> 3);
int shift = 10 - (column & 7);
ret = (byte)(((_vram[offset] << 8) | _vram[offset + 1]) >> shift);
}
DoDispMove();
return ret;
}
private void WriteDispData(byte value)
{
int offset;
if (_displayMode == 1)
{
offset = (int)(_displayY * 12) + (int)_displayX;
_vram[offset] = value;
}
else
{
int column = 6 * (int)_displayX;
offset = (int)(_displayY * 12) + (column >> 3);
if (offset < 0x300)
{
int shift = column & 7;
int mask = ~(252 >> shift);
int data = value << 2;
_vram[offset] = (byte)(_vram[offset] & mask | (data >> shift));
if (shift > 2 && offset < 0x2ff)
{
offset++;
shift = 8 - shift;
mask = ~(252 << shift);
_vram[offset] = (byte)(_vram[offset] & mask | (data << shift));
}
}
}
DoDispMove();
}
private void DoDispMove()
{
switch (_displayMove)
{
case 0:
_displayY--;
break;
case 1:
_displayY++;
break;
case 2:
_displayX--;
break;
case 3:
_displayX++;
break;
}
_displayX &= 0xF; // 0xF or 0x1F? dunno
_displayY &= 0x3F;
}
private void WriteDispCtrl(byte value)
{
if (value <= 1)
{
_displayMode = value;
}
else if (value >= 4 && value <= 7)
{
_displayMove = value - 4;
}
else if ((value & 0xC0) == 0x40)
{
// hardware scroll
}
else if ((value & 0xE0) == 0x20)
{
_displayX = (uint)(value & 0x1F);
_cursorMoved = true;
}
else if ((value & 0xC0) == 0x80)
{
_displayY = (uint)(value & 0x3F);
_cursorMoved = true;
}
else if ((value & 0xC0) == 0xC0)
{
// contrast
}
else if (value == 2)
{
}
else if (value == 3)
{
}
}
private void IRQCallback()
{
//Console.WriteLine("IRQ with vec {0} and cpu.InterruptMode {1}", _cpu.Regs[_cpu.I], _cpu.InterruptMode);
_cpu.FlagI = false;
}
private void NMICallback()
{
//Console.WriteLine("NMI");
_cpu.NonMaskableInterrupt = false;
}
private void HardReset()
{
_cpu.Reset();
_ram = new byte[0x8000];
for (int i = 0; i < 0x8000; i++)
{
_ram[i] = 0xFF;
}
_cpu.RegPC = 0;
_cpu.IFF1 = false;
_cpu.IFF2 = false;
_cpu.InterruptMode = 2;
_maskOn = 1;
_romPageHighBit = 0;
_romPageLow3Bits = 0;
_keyboardMask = 0;
_displayMode = 0;
_displayMove = 0;
_displayX = _displayY = 0;
}
}
}

View File

@ -1,405 +0,0 @@
using System.Collections.Generic;
using System.IO;
namespace BizHawk.Emulation.Cores.Calculators.TI83
{
public class TI83LinkPort
{
// Emulates TI linking software.
// See http://www.ticalc.org/archives/files/fileinfo/294/29418.html for documentation
// Note: Each hardware read/write to the link port calls tthe update method.
private readonly TI83 Parent;
private readonly Queue<byte> CurrentData = new Queue<byte>();
private Stream _currentFile;
private byte[] _variableData;
private Action _nextStep;
private ushort _bytesToSend;
private byte _bitsLeft;
private byte _currentByte;
private byte _stepsLeft;
private Status _currentStatus = Status.Inactive;
private enum Status
{
Inactive,
PrepareReceive,
PrepareSend,
Receive,
Send
}
public TI83LinkPort(TI83 parent)
{
Parent = parent;
}
public void Update()
{
if (_currentStatus == Status.PrepareReceive)
{
// Get the first byte, and start sending it.
_currentByte = CurrentData.Dequeue();
_currentStatus = Status.Receive;
_bitsLeft = 8;
_stepsLeft = 5;
}
if (_currentStatus == Status.PrepareSend && Parent.LinkState != 3)
{
_currentStatus = Status.Send;
_bitsLeft = 8;
_stepsLeft = 5;
_currentByte = 0;
}
if (_currentStatus == Status.Receive)
{
switch (_stepsLeft)
{
case 5:
// Receive step 1: Lower the other device's line.
Parent.LinkInput = ((_currentByte & 1) == 1) ? 2 : 1;
_currentByte >>= 1;
_stepsLeft--;
break;
case 4:
// Receive step 2: Wait for the calc to lower the other line.
if ((Parent.LinkState & 3) == 0)
{
_stepsLeft--;
}
break;
case 3:
// Receive step 3: Raise the other device's line back up.
Parent.LinkInput = 0;
_stepsLeft--;
break;
case 2:
// Receive step 4: Wait for the calc to raise its line back up.
if ((Parent.LinkState & 3) == 3)
{
_stepsLeft--;
}
break;
case 1:
// Receive step 5: Finish.
_bitsLeft--;
if (_bitsLeft == 0)
{
if (CurrentData.Count > 0)
{
_currentStatus = Status.PrepareReceive;
}
else
{
_currentStatus = Status.Inactive;
_nextStep?.Invoke();
}
}
else
{
// Next bit in the current byte.
_stepsLeft = 5;
}
break;
}
}
else if (_currentStatus == Status.Send)
{
switch (_stepsLeft)
{
case 5:
// Send step 1: Calc lowers a line.
if (Parent.LinkState != 3)
{
int bit = Parent.LinkState & 1;
int shift = 8 - _bitsLeft;
_currentByte |= (byte)(bit << shift);
_stepsLeft--;
}
break;
case 4:
// Send step 2: Lower our line.
Parent.LinkInput = Parent.LinkOutput ^ 3;
_stepsLeft--;
break;
case 3:
// Send step 3: wait for the calc to raise its line.
if ((Parent.LinkOutput & 3) == 0)
{
_stepsLeft--;
}
break;
case 2:
// Send step 4: raise the other devices lines.
Parent.LinkInput = 0;
_stepsLeft--;
break;
case 1:
// Send step 5: Finish
_bitsLeft--;
if (_bitsLeft == 0)
{
_bytesToSend--;
CurrentData.Enqueue(_currentByte);
if (_bytesToSend > 0)
{
_currentStatus = Status.PrepareSend;
}
else
{
_currentStatus = Status.Inactive;
_nextStep?.Invoke();
}
}
else
{
// Next bit in the current byte.
_stepsLeft = 5;
}
break;
}
}
}
public void SendFileToCalc(Stream fs, bool verify)
{
if (verify)
{
VerifyFile(fs);
}
fs.Seek(55, SeekOrigin.Begin);
_currentFile = fs;
SendNextFile();
}
private void VerifyFile(Stream fs)
{
// Verify the file format.
byte[] expected = { 0x2a, 0x2a, 0x54, 0x49, 0x38, 0x33, 0x2a, 0x2a, 0x1a, 0x0a, 0x00 };
byte[] actual = new byte[11];
fs.Seek(0, SeekOrigin.Begin);
fs.Read(actual, 0, 11);
// Check the header.
for (int n = 0; n < 11; n++)
{
if (expected[n] != actual[n])
{
fs.Close();
throw new IOException("Invalid Header.");
}
}
// Seek to the end of the comment.
fs.Seek(53, SeekOrigin.Begin);
int size = fs.ReadByte() + (fs.ReadByte() * 256);
if (fs.Length != size + 57)
{
fs.Close();
throw new IOException("Invalid file length.");
}
// Verify the checksum.
ushort checksum = 0;
for (int n = 0; n < size; n++)
{
checksum += (ushort)fs.ReadByte();
}
ushort actualChecksum = (ushort)(fs.ReadByte() + (fs.ReadByte() * 256));
if (checksum != actualChecksum)
{
fs.Close();
throw new IOException("Invalid Checksum.");
}
}
private void SendNextFile()
{
byte[] header = new byte[13];
if (!_currentFile.CanRead || _currentFile.Read(header, 0, 13) != 13)
{
// End of file.
_currentFile.Close();
return;
}
int size = header[2] + (header[3] * 256);
_variableData = new byte[size + 2];
_currentFile.Read(_variableData, 0, size + 2);
// Request to send the file.
CurrentData.Clear();
CurrentData.Enqueue(0x03);
CurrentData.Enqueue(0xC9);
foreach (byte b in header)
{
CurrentData.Enqueue(b);
}
// Calculate the checksum for the command.
ushort checksum = 0;
for (int n = 2; n < header.Length; n++)
{
checksum += header[n];
}
CurrentData.Enqueue((byte)(checksum % 256));
CurrentData.Enqueue((byte)(checksum / 256));
// Finalize the command.
_currentStatus = Status.PrepareReceive;
_nextStep = ReceiveReqAck;
Parent.LinkActive = true;
}
private void ReceiveReqAck()
{
Parent.LinkActive = false;
CurrentData.Clear();
// Prepare to receive the Aknowledgement response from the calculator.
_bytesToSend = 8;
_currentStatus = Status.PrepareSend;
_nextStep = SendVariableData;
}
private void SendVariableData()
{
// Check to see if out of memory first.
CurrentData.Dequeue();
CurrentData.Dequeue();
CurrentData.Dequeue();
CurrentData.Dequeue();
CurrentData.Dequeue();
if (CurrentData.Dequeue() == 0x36)
{
OutOfMemory();
}
else
{
CurrentData.Clear();
CurrentData.Enqueue(0x03);
CurrentData.Enqueue(0x56);
CurrentData.Enqueue(0x00);
CurrentData.Enqueue(0x00);
CurrentData.Enqueue(0x03);
CurrentData.Enqueue(0x15);
// Add variable data.
foreach (byte b in _variableData)
{
CurrentData.Enqueue(b);
}
// Calculate the checksum.
ushort checksum = 0;
for (int n = 2; n < _variableData.Length; n++)
{
checksum += _variableData[n];
}
CurrentData.Enqueue((byte)(checksum % 256));
CurrentData.Enqueue((byte)(checksum / 256));
_currentStatus = Status.PrepareReceive;
_nextStep = ReceiveDataAck;
Parent.LinkActive = true;
}
}
private void ReceiveDataAck()
{
Parent.LinkActive = false;
CurrentData.Clear();
// Prepare to receive the Aknowledgement response from the calculator.
_bytesToSend = 4;
_currentStatus = Status.PrepareSend;
_nextStep = EndTransmission;
}
private void EndTransmission()
{
CurrentData.Clear();
// Send the end transmission command.
CurrentData.Enqueue(0x03);
CurrentData.Enqueue(0x92);
CurrentData.Enqueue(0x00);
CurrentData.Enqueue(0x00);
_currentStatus = Status.PrepareReceive;
_nextStep = FinalizeFile;
Parent.LinkActive = true;
}
private void OutOfMemory()
{
_currentFile.Close();
Parent.LinkActive = false;
CurrentData.Clear();
// Prepare to receive the Aknowledgement response from the calculator.
_bytesToSend = 3;
_currentStatus = Status.PrepareSend;
_nextStep = EndOutOfMemory;
}
private void EndOutOfMemory()
{
CurrentData.Clear();
// Send the end transmission command.
CurrentData.Enqueue(0x03);
CurrentData.Enqueue(0x56);
CurrentData.Enqueue(0x01);
CurrentData.Enqueue(0x00);
_currentStatus = Status.PrepareReceive;
_nextStep = FinalizeFile;
Parent.LinkActive = true;
}
private void FinalizeFile()
{
// Resets the link software, and checks to see if there is an additional file to send.
CurrentData.Clear();
Parent.LinkActive = false;
_nextStep = null;
SendNextFile();
}
}
}

View File

@ -56,7 +56,6 @@ namespace BizHawk.Emulation.Cores
public const string SubBsnes115 = "SubBSNESv115+";
public const string SubGbHawk = "SubGBHawk";
public const string SubNesHawk = "SubNESHawk";
public const string TI83Hawk = "TI83Hawk";
public const string TIC80 = "TIC-80";
public const string TST = "T. S. T.";
public const string TurboNyma = "TurboNyma";