Added support for TI83 group files, and added checks to ensure the file follows the proper format.

This commit is contained in:
thebrick448 2013-09-17 04:11:13 +00:00
parent 88a9b95b15
commit a40bda3263
3 changed files with 109 additions and 41 deletions

View File

@ -630,9 +630,12 @@ namespace BizHawk.Emulation.Consoles.Calculator
public Link LinkPort; public Link LinkPort;
public class Link public class Link
{ {
byte[] FileData;
readonly TI83 Parent; readonly TI83 Parent;
private FileStream CurrentFile;
private int FileBytesLeft;
private byte[] VariableData;
private Action NextStep; private Action NextStep;
private Queue<byte> CurrentData = new Queue<byte>(); private Queue<byte> CurrentData = new Queue<byte>();
private ushort BytesToSend; private ushort BytesToSend;
@ -786,26 +789,77 @@ namespace BizHawk.Emulation.Consoles.Calculator
} }
} }
public void SendFileToCalc(FileStream FS) public void SendFileToCalc(FileStream FS, bool Verify)
{ {
if (Verify)
VerifyFile(FS);
FS.Seek(55, SeekOrigin.Begin);
CurrentFile = FS;
SendNextFile();
}
private void VerifyFile(FileStream FS)
{
//Verify the file format.
byte[] Expected = new byte[] { 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); FS.Seek(53, SeekOrigin.Begin);
int Size = FS.ReadByte() + FS.ReadByte() * 256; int Size = FS.ReadByte() + FS.ReadByte() * 256;
if (FS.Length != Size + 57) if (FS.Length != Size + 57)
throw new FormatException("Invalid calculator file."); {
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]; byte[] Header = new byte[13];
FS.Read(Header, 0, 13); if (!CurrentFile.CanRead || CurrentFile.Read(Header, 0, 13) != 13)
{
//End of file.
CurrentFile.Close();
return;
}
FileData = new byte[Size - 13]; int Size = Header[2] + Header[3] * 256;
FS.Read(FileData, 0, Size - 13); VariableData = new byte[Size + 2];
CurrentFile.Read(VariableData, 0, Size + 2);
//Request to send the file. //Request to send the file.
CurrentData.Clear(); CurrentData.Clear();
CurrentData.Enqueue(0x03); CurrentData.Enqueue(0x03);
CurrentData.Enqueue(0xC9); CurrentData.Enqueue(0xC9);
foreach (byte B in Header) foreach (byte B in Header)
CurrentData.Enqueue(B); CurrentData.Enqueue(B);
@ -858,13 +912,13 @@ namespace BizHawk.Emulation.Consoles.Calculator
CurrentData.Enqueue(0x15); CurrentData.Enqueue(0x15);
//Add variable data. //Add variable data.
foreach (byte B in FileData) foreach (byte B in VariableData)
CurrentData.Enqueue(B); CurrentData.Enqueue(B);
//Calculate the checksum. //Calculate the checksum.
ushort Checksum = 0; ushort Checksum = 0;
for (int n = 2; n < FileData.Length; n++) for (int n = 2; n < VariableData.Length; n++)
Checksum += FileData[n]; Checksum += VariableData[n];
CurrentData.Enqueue((byte)(Checksum % 256)); CurrentData.Enqueue((byte)(Checksum % 256));
CurrentData.Enqueue((byte)(Checksum / 256)); CurrentData.Enqueue((byte)(Checksum / 256));
@ -903,6 +957,7 @@ namespace BizHawk.Emulation.Consoles.Calculator
private void OutOfMemory() private void OutOfMemory()
{ {
CurrentFile.Close();
Parent.LinkActive = false; Parent.LinkActive = false;
CurrentData.Clear(); CurrentData.Clear();
@ -932,6 +987,7 @@ namespace BizHawk.Emulation.Consoles.Calculator
CurrentData.Clear(); CurrentData.Clear();
Parent.LinkActive = false; Parent.LinkActive = false;
NextStep = null; NextStep = null;
SendNextFile();
} }
} }
} }

View File

@ -2599,5 +2599,25 @@ namespace BizHawk.MultiClient
{ {
new RewindConfig().ShowDialog(); new RewindConfig().ShowDialog();
} }
private void loadTIFileToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog OFD = new OpenFileDialog();
if (OFD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
try
{
(Global.Emulator as TI83).LinkPort.SendFileToCalc(File.OpenRead(OFD.FileName), true);
}
catch (IOException ex)
{
string Message = string.Format("Invalid file format. Reason: {0} \nForce transfer? This may cause the calculator to crash.", ex.Message);
if (MessageBox.Show(Message, "Upload Failed", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
(Global.Emulator as TI83).LinkPort.SendFileToCalc(File.OpenRead(OFD.FileName), false);
}
}
}
} }
} }

View File

@ -4201,14 +4201,6 @@ namespace BizHawk.MultiClient
} }
} }
private void loadTIFileToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog OFD = new OpenFileDialog();
if (OFD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
(Global.Emulator as TI83).LinkPort.SendFileToCalc(File.OpenRead(OFD.FileName));
}
private void newRamSearchToolStripMenuItem_Click(object sender, EventArgs e) private void newRamSearchToolStripMenuItem_Click(object sender, EventArgs e)
{ {
new NewRamSearch().Show(); new NewRamSearch().Show();