private void SetType(Types.AssemblerType Type) { for (int i = 0; i < comboAssemblerType.Items.Count; ++i) { GR.Generic.Tupel <string, Types.AssemblerType> entry = (GR.Generic.Tupel <string, Types.AssemblerType>)comboAssemblerType.Items[i]; if (entry.second == Type) { comboAssemblerType.SelectedIndex = i; break; } } }
public override void OnClose() { GR.Generic.Tupel <string, Types.AssemblerType> entry = (GR.Generic.Tupel <string, Types.AssemblerType>)comboAssemblerType.SelectedItem; if (entry == null) { Element.AssemblerType = C64Studio.Types.AssemblerType.AUTO; } else { Element.AssemblerType = entry.second; } }
private void FollowChain(int Track, int Sector, GR.Collections.Map <GR.Generic.Tupel <int, int>, GR.Memory.ByteBuffer> UsedSectors, GR.Memory.ByteBuffer Filename, List <string> Errors) { int fileTrack = Track; int fileSector = Sector; while (fileTrack != 0) { GR.Generic.Tupel <int, int> location = new GR.Generic.Tupel <int, int>(fileTrack, fileSector); if ((UsedSectors[location].Length > 0) && (UsedSectors[location] != Filename)) { Errors.Add("Sector " + location.first + ", Track " + location.second + " is referenced by more than one file"); } int newTrack = Tracks[fileTrack - 1].Sectors[fileSector].Data.ByteAt(0); int newSector = Tracks[fileTrack - 1].Sectors[fileSector].Data.ByteAt(1); if (newTrack == 0) { return; } if ((newTrack < 1) || (newTrack > Tracks.Count)) { Errors.Add("Reference to invalid track " + newTrack + " encountered in track " + fileTrack + ", Sector " + fileSector); return; } fileTrack = newTrack; fileSector = newSector; } }
public bool Disassemble(int DataStartAddress, GR.Collections.Set <int> JumpedAtAddresses, GR.Collections.Map <int, string> NamedLabels, DisassemblerSettings Settings, out string Disassembly, out int FirstLineWithOpcode) { StringBuilder sb = new StringBuilder(); Disassembly = ""; FirstLineWithOpcode = 1; if (JumpedAtAddresses.Count == 0) { return(false); } int progStepPos = JumpedAtAddresses.First; GR.Collections.Set <ushort> accessedAddresses = new GR.Collections.Set <ushort>(); GR.Collections.Set <int> addressesToCheck = new GR.Collections.Set <int>(JumpedAtAddresses); GR.Collections.Set <int> addressesChecked = new GR.Collections.Set <int>(); GR.Collections.Set <ushort> probableLabel = new GR.Collections.Set <ushort>(); // check for basic header int sysAddress = -1; if (HasBASICJumpAddress(DataStartAddress, out sysAddress)) { progStepPos = sysAddress; addressesToCheck.Add(progStepPos); } /* * else * { * // automatically check at data start address * addressesToCheck.Add( DataStartAddress ); * }*/ int codeStartPos = progStepPos; GR.Collections.Map <ushort, GR.Generic.Tupel <Tiny64.Opcode, ushort> > disassembly = new GR.Collections.Map <ushort, GR.Generic.Tupel <Tiny64.Opcode, ushort> >(); while (addressesToCheck.Count > 0) { progStepPos = addressesToCheck.First; //Debug.Log( "check address:" + progStepPos ); addressesToCheck.Remove(progStepPos); if (addressesChecked.ContainsValue(progStepPos)) { continue; } while (true) { if (progStepPos < DataStartAddress) { break; } /* * sb.Append( "Jumped to address before data\r\n" ); * Disassembly = sb.ToString(); * return false; * }*/ if (progStepPos >= DataStartAddress + m_SourceData.Length) { // reached the end break; } Tiny64.Opcode opcode = null; bool outsideData = false; if (!DisassembleInstruction(m_SourceData, DataStartAddress, progStepPos, out opcode, out outsideData)) { if (!outsideData) { sb.Append("Failed to disassemble data $" + m_SourceData.ByteAt(progStepPos - DataStartAddress).ToString("X2") + " at location " + progStepPos + "($" + progStepPos.ToString("X4") + ")\r\n"); Disassembly = sb.ToString(); return(false); } } if (outsideData) { break; } addressesChecked.Add(progStepPos); //Debug.Log( "Mnemonic: " + OpcodeToString( opcode, Data, progStepPos + 1 - DataStartAddress ) ); //Debug.Log( progStepPos.ToString( "X4" ) + ": " + MnemonicToString( opcode, Data, DataStartAddress, progStepPos ) ); if ((opcode.ByteValue == 0x4c) || // jmp (opcode.ByteValue == 0x20)) // jsr { // absolute jump accessedAddresses.Add(m_SourceData.UInt16At(progStepPos + 1 - DataStartAddress)); addressesToCheck.Add(m_SourceData.UInt16At(progStepPos + 1 - DataStartAddress)); //Debug.Log( "access address " + Data.UInt16At( progStepPos + 1 ).ToString( "X4" ) ); } else if (opcode.ByteValue == 0x6c) // jmp indirect { probableLabel.Add(m_SourceData.UInt16At(progStepPos + 1 - DataStartAddress)); } else if (opcode.Addressing == Tiny64.Opcode.AddressingType.RELATIVE) { int targetAddress = (sbyte)m_SourceData.ByteAt(progStepPos + 1 - DataStartAddress) + 2 + progStepPos; probableLabel.Add((ushort)targetAddress); addressesToCheck.Add(targetAddress); accessedAddresses.Add((ushort)targetAddress); } disassembly[(ushort)progStepPos] = new GR.Generic.Tupel <Tiny64.Opcode, ushort>(opcode, m_SourceData.UInt16At(progStepPos + 1)); if ((opcode.ByteValue == 0x40) || // rts (opcode.ByteValue == 0x60) || // rti (opcode.ByteValue == 0x4c)) // jmp { // end of code here break; } //string output = MnemonicToString( opcode, Data, DataStartAddress, progStepPos ); //Debug.Log( output ); progStepPos += opcode.NumOperands + 1; } } progStepPos = codeStartPos; //foreach ( KeyValuePair<ushort,GR.Generic.Tupel<Opcode, ushort>> instruction in disassembly ) // remove potential labels that are not in our code GR.Collections.Set <ushort> addressesToRemove = new GR.Collections.Set <ushort>(); foreach (var accessedAddress in accessedAddresses) { if (!disassembly.ContainsKey(accessedAddress)) { addressesToRemove.Add(accessedAddress); } } foreach (var addressToRemove in addressesToRemove) { accessedAddresses.Remove(addressToRemove); } sb.Append("* = $"); sb.AppendLine(DataStartAddress.ToString("x4")); if (!Settings.AddLineAddresses) { foreach (var namedLabel in NamedLabels) { sb.Append(namedLabel.Value); sb.Append(" = $"); sb.AppendLine(namedLabel.Key.ToString("X4")); } if (NamedLabels.Count > 0) { sb.AppendLine(); } } int trueAddress = DataStartAddress; bool hadBytes = false; int hadBytesStart = 0; int localLineIndex = 1; while (trueAddress < DataStartAddress + m_SourceData.Length) { if (disassembly.ContainsKey((ushort)trueAddress)) { if (hadBytes) { sb.Append(DisassembleBinary(m_SourceData, DataStartAddress, hadBytesStart, trueAddress - hadBytesStart, Settings)); hadBytes = false; } GR.Generic.Tupel <Tiny64.Opcode, ushort> instruction = disassembly[(ushort)trueAddress]; if (Settings.AddLineAddresses) { sb.Append("$"); sb.Append(trueAddress.ToString("X4") + ": "); } if (DataStartAddress == trueAddress) { FirstLineWithOpcode = localLineIndex; } ++localLineIndex; if (accessedAddresses.ContainsValue((ushort)trueAddress)) { // line break in front of named label sb.AppendLine(); if (Settings.AddLineAddresses) { sb.Append("$"); sb.Append(trueAddress.ToString("X4") + ": "); } if (NamedLabels.ContainsKey(trueAddress)) { sb.AppendLine(NamedLabels[trueAddress]); } else { sb.Append("label_" + trueAddress.ToString("x4") + "\r\n"); } if (Settings.AddLineAddresses) { sb.Append("$"); sb.Append(trueAddress.ToString("X4") + ": "); } } else if (NamedLabels.ContainsKey(trueAddress)) { // line break in front of named label sb.AppendLine(); if (Settings.AddLineAddresses) { sb.Append("$"); sb.Append(trueAddress.ToString("X4") + ": "); } sb.AppendLine(NamedLabels[trueAddress]); if (Settings.AddLineAddresses) { sb.Append("$"); sb.Append(trueAddress.ToString("X4") + ": "); } } if (Settings.AddAssembledBytes) { sb.Append(" "); sb.Append(instruction.first.ByteValue.ToString("X2")); switch (instruction.first.NumOperands) { case 0: sb.Append(" "); break; case 1: sb.Append(" "); sb.Append(m_SourceData.ByteAt(trueAddress + 1 - DataStartAddress).ToString("X2")); sb.Append(" "); break; case 2: sb.Append(" "); sb.Append(m_SourceData.ByteAt(trueAddress + 1 - DataStartAddress).ToString("X2")); sb.Append(" "); sb.Append(m_SourceData.ByteAt(trueAddress + 1 - DataStartAddress + 1).ToString("X2")); break; } } sb.Append(" " + MnemonicToString(instruction.first, m_SourceData, DataStartAddress, trueAddress, accessedAddresses, NamedLabels)); sb.Append("\r\n"); trueAddress += instruction.first.NumOperands + 1; } else { if (!hadBytes) { hadBytes = true; hadBytesStart = trueAddress; } ++trueAddress; } } if (hadBytes) { sb.Append(DisassembleBinary(m_SourceData, DataStartAddress, hadBytesStart, trueAddress - hadBytesStart, Settings)); hadBytes = false; } Disassembly = sb.ToString(); return(true); }