diff --git a/SourceGen/AppSettings.cs b/SourceGen/AppSettings.cs index f662b12..9d17e8e 100644 --- a/SourceGen/AppSettings.cs +++ b/SourceGen/AppSettings.cs @@ -138,6 +138,10 @@ namespace SourceGen { public const string EXPORT_LONG_LABEL_NEW_LINE = "export-long-label-new-line"; public const string EXPORT_GENERATE_IMAGE_FILES = "export-generate-image-files"; + // OMF export settings. + public const string OMF_ADD_NOTES = "omf-add-notes"; + public const string OMF_OFFSET_SEGMENT_START = "omf-offset-segment-start"; + // Internal debugging features. public const string DEBUG_MENU_ENABLED = "debug-menu-enabled"; diff --git a/SourceGen/RuntimeData/Help/tools.html b/SourceGen/RuntimeData/Help/tools.html index ae1bff3..fc1d4a0 100644 --- a/SourceGen/RuntimeData/Help/tools.html +++ b/SourceGen/RuntimeData/Help/tools.html @@ -101,6 +101,25 @@ created with some basic attributes filled in.

Only "Load" files (S16, PIF, TOL, etc) may be converted. Compiler object files and libraries contain unresolved references and are not supported.

+

To convert a file, extract it from the Apple II disk image, using a +mode that does not modify the original (e.g. extract with "configure to +preserve Apple II formats" in CiderPress). Open it with the OMF +Converter tool. Click "Generate" to create a modified binary and a +SourceGen project file.

+ +

If "offset segment start by $0100" is checked, the converter will try +to shift the segment's load address from $xx/0000 to +$xx/0100. This can make the generated code a little nicer +to work with because it removes potential ambiguity with direct page +addresses. For example, LDA $56 and LDA $0056 +may be interpreted as the same thing by the assembler, requiring +generation of operand width disambiguators. By shifting the initial +address we avoid the potential ambiguity.

+

Check "add comments and notes for each segment" to add a long comment +and a note at the start of each segment. The comments include the +segment name, type, and optional flags. The notes just provide a quick +way to jump to a segment.

+

The binary generated by the tool is not in OMF format and will not execute on an Apple IIgs. To be functional, the sources must be assembled by a program capable of generating OMF output, such as Merlin.

diff --git a/SourceGen/SGTestData/20212-reloc-data.dis65 b/SourceGen/SGTestData/20212-reloc-data.dis65 index 0f16e2e..b240371 100644 --- a/SourceGen/SGTestData/20212-reloc-data.dis65 +++ b/SourceGen/SGTestData/20212-reloc-data.dis65 @@ -19,6 +19,8 @@ "SmartPlbHandling":true}, "PlatformSymbolFileIdentifiers":["RT:Apple/Cxxx-IO.sym65", +"RT:Apple/C08x-DiskII.sym65", +"RT:Apple/E0Cxxx-IO.sym65", "RT:Apple/IIgs-ROM.sym65", "RT:Apple/GSOS.sym65"], "ExtensionScriptFileIdentifiers":["RT:Apple/GSOS.cs", @@ -60,66 +62,10 @@ }, "LongComments":{ -"0":{ -"Text":"Segment 02: Kind=Code; Attrs=NoSpecial; Name=\u0027 \u0027", -"BoxMode":false, -"MaxWidth":80, -"BackgroundColor":0}, - -"143":{ -"Text":"Segment 03: Kind=Data; Attrs=BankRel, Dynamic; Name=\u0027PosFFE0 \u0027", -"BoxMode":false, -"MaxWidth":80, -"BackgroundColor":0}, - -"195":{ -"Text":"Segment 04: Kind=Code; Attrs=NoSpecial; Name=\u0027Bank2 \u0027", -"BoxMode":false, -"MaxWidth":80, -"BackgroundColor":0}, - -"230":{ -"Text":"Segment 05: Kind=Code; Attrs=AbsBank, Dynamic; Name=\u0027Bank8 \u0027", -"BoxMode":false, -"MaxWidth":80, -"BackgroundColor":0}, - -"284":{ -"Text":"Segment 06: Kind=Data; Attrs=0; Name=\u0027Filler \u0027", -"BoxMode":false, -"MaxWidth":80, -"BackgroundColor":0}}, +}, "Notes":{ -"0":{ -"Text":"Seg02: 03/0000 \u0027 \u0027", -"BoxMode":false, -"MaxWidth":80, -"BackgroundColor":0}, - -"143":{ -"Text":"Seg03: 04/ffe0 \u0027PosFFE0 \u0027", -"BoxMode":false, -"MaxWidth":80, -"BackgroundColor":0}, - -"195":{ -"Text":"Seg04: 02/3456 \u0027Bank2 \u0027", -"BoxMode":false, -"MaxWidth":80, -"BackgroundColor":0}, - -"230":{ -"Text":"Seg05: 08/0000 \u0027Bank8 \u0027", -"BoxMode":false, -"MaxWidth":80, -"BackgroundColor":0}, - -"284":{ -"Text":"Seg06: 06/0000 \u0027Filler \u0027", -"BoxMode":false, -"MaxWidth":80, -"BackgroundColor":0}}, +}, "UserLabels":{ }, diff --git a/SourceGen/SGTestData/Source/20212-reloc-data-lnk.S b/SourceGen/SGTestData/Source/20212-reloc-data-lnk.S index 81a207d..4934cc6 100644 --- a/SourceGen/SGTestData/Source/20212-reloc-data-lnk.S +++ b/SourceGen/SGTestData/Source/20212-reloc-data-lnk.S @@ -19,9 +19,9 @@ ; "PosFFE0" -> E0 FF 00 ; "Bank2" -> 56 34 02 ; "Bank8" -> 00 10 08 -; - Convert out.20212 to "20212-reloc-data" with OMF converter. -; - The project file generally requires no edits, except to delete the -; header comment. Leaving the segment-start comments in seems fine. +; - Convert out.20212 to "20212-reloc-data" with OMF converter. Disable +; "offset segment by $0100" and "add comments and notes". +; - The project file requires no edits, except to delete the header comment. DSK out.20212 ;output file name, must be ProDOS-compat TYP $b3 ;S16 diff --git a/SourceGen/Tools/Omf/Loader.cs b/SourceGen/Tools/Omf/Loader.cs index db1716a..4014878 100644 --- a/SourceGen/Tools/Omf/Loader.cs +++ b/SourceGen/Tools/Omf/Loader.cs @@ -31,8 +31,15 @@ namespace SourceGen.Tools.Omf { public class Loader { private const string IIGS_SYSTEM_DEF = "Apple IIgs (GS/OS)"; + [Flags] + public enum Flags { + AddNotes = 1 << 0, + OffsetSegmentStart = 1 << 1, + } + private OmfFile mOmfFile; private Formatter mFormatter; + private Flags mFlags; private byte[] mLoadedData; private DisasmProject mNewProject; @@ -57,11 +64,12 @@ namespace SourceGen.Tools.Omf { /// /// OMF file to load. /// Text formatter. - public Loader(OmfFile omfFile, Formatter formatter) { + public Loader(OmfFile omfFile, Formatter formatter, Flags flags) { Debug.Assert(omfFile.OmfFileKind == OmfFile.FileKind.Load); mOmfFile = omfFile; mFormatter = formatter; + mFlags = flags; } /// @@ -259,6 +267,19 @@ namespace SourceGen.Tools.Omf { } } + // If possible, shift the address to xx/$0100. This is useful because it means + // we won't have to put width disambiguators on any data accesses to $00xx + // locations. We can't do this if the address is fixed, aligned to a 64K + // boundary, or is too large. + if ((mFlags & Flags.OffsetSegmentStart) != 0 && !fixedAddr && !bankRel && + omfSeg.Align <= 0x0100 && omfSeg.Length <= (65536-256)) { + if ((addr & 0x0000ffff) == 0x0000) { + addr |= 0x0100; + } else { + Debug.Assert(false, "Unexpected nonzero bank address found"); + } + } + SegmentMapEntry ent = new SegmentMapEntry(omfSeg, addr); mSegmentMap.Add(ent); } @@ -352,20 +373,22 @@ namespace SourceGen.Tools.Omf { // can straddle multiple pages.) AddAddressEntries(proj, ent, bufOffset, cs); - // Add a comment identifying the segment and its attributes. - string segCmt = string.Format(Res.Strings.OMF_SEG_COMMENT_FMT, - ent.Segment.SegNum, ent.Segment.Kind, ent.Segment.Attrs, ent.Segment.SegName); - uc = UndoableChange.CreateLongCommentChange(bufOffset, null, - new MultiLineComment(segCmt)); - cs.Add(uc); + if ((mFlags & Flags.AddNotes) != 0) { + // Add a comment identifying the segment and its attributes. + string segCmt = string.Format(Res.Strings.OMF_SEG_COMMENT_FMT, + ent.Segment.SegNum, ent.Segment.Kind, ent.Segment.Attrs, ent.Segment.SegName); + uc = UndoableChange.CreateLongCommentChange(bufOffset, null, + new MultiLineComment(segCmt)); + cs.Add(uc); - // Add a note identifying the segment. - string segNote = string.Format(Res.Strings.OMF_SEG_NOTE_FMT, - ent.Segment.SegNum, mFormatter.FormatAddress(ent.Address, true), - ent.Segment.SegName); - uc = UndoableChange.CreateNoteChange(bufOffset, null, - new MultiLineComment(segNote)); - cs.Add(uc); + // Add a note identifying the segment. + string segNote = string.Format(Res.Strings.OMF_SEG_NOTE_FMT, + ent.Segment.SegNum, mFormatter.FormatAddress(ent.Address, true), + ent.Segment.SegName); + uc = UndoableChange.CreateNoteChange(bufOffset, null, + new MultiLineComment(segNote)); + cs.Add(uc); + } bufOffset += ent.Segment.Length; } diff --git a/SourceGen/Tools/Omf/WpfGui/OmfViewer.xaml b/SourceGen/Tools/Omf/WpfGui/OmfViewer.xaml index 773aef4..e80d806 100644 --- a/SourceGen/Tools/Omf/WpfGui/OmfViewer.xaml +++ b/SourceGen/Tools/Omf/WpfGui/OmfViewer.xaml @@ -51,6 +51,7 @@ limitations under the License. + @@ -95,10 +96,19 @@ limitations under the License. IsReadOnly="True" VerticalScrollBarVisibility="Auto"> - -