1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-06-12 08:29:29 +00:00

Add two options to OMF converter

First, make the per-segment comments and notes optional.

Second, add an "offset segment by $0100" feature that tries to shift
each segment forward 256 bytes.  Doing so avoids potential ambiguity
with direct page locations.

The 20212-reloc-data test no longer has the per-segment comments.
This commit is contained in:
Andy McFadden 2020-07-20 13:47:19 -07:00
parent 288a857e47
commit 6892040ea8
7 changed files with 106 additions and 80 deletions

View File

@ -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";

View File

@ -101,6 +101,25 @@ created with some basic attributes filled in.</p>
<p>Only "Load" files (S16, PIF, TOL, etc) may be converted. Compiler object
files and libraries contain unresolved references and are not supported.</p>
<p>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.</p>
<p>If "offset segment start by $0100" is checked, the converter will try
to shift the segment's load address from <code>$xx/0000</code> to
<code>$xx/0100</code>. This can make the generated code a little nicer
to work with because it removes potential ambiguity with direct page
addresses. For example, <code>LDA $56</code> and <code>LDA $0056</code>
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.</p>
<p>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.</p>
<p>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.</p>

View File

@ -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":{
},

View File

@ -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

View File

@ -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 {
/// </summary>
/// <param name="omfFile">OMF file to load.</param>
/// <param name="formatter">Text formatter.</param>
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;
}
/// <summary>
@ -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;
}

View File

@ -51,6 +51,7 @@ limitations under the License.
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0">
@ -95,10 +96,19 @@ limitations under the License.
IsReadOnly="True" VerticalScrollBarVisibility="Auto">
</TextBox>
<DockPanel Grid.Row="5" LastChildFill="False" Margin="0,16,0,0">
<Button DockPanel.Dock="Left" Content="Generate SourceGen Project" Padding="4,0"
IsEnabled="{Binding IsLoadFile}" Click="GenerateProject_Click"/>
<Button DockPanel.Dock="Right" Content="Cancel" Width="70" IsCancel="True"/>
<GroupBox Grid.Row="5" Header="Generate SourceGen Project" Padding="2,0" Margin="0,8,0,0">
<StackPanel>
<CheckBox Content="Offset segment start by $0100" Margin="0,4,0,0"
IsChecked="{Binding OffsetSegmentStart}"/>
<CheckBox Content="Add comments and notes for each segment" Margin="0,4,0,0"
IsChecked="{Binding AddNotes}"/>
<Button Content="Generate" Width="100" Margin="0,8" HorizontalAlignment="Left"
IsEnabled="{Binding IsLoadFile}" Click="GenerateProject_Click"/>
</StackPanel>
</GroupBox>
<DockPanel Grid.Row="6" LastChildFill="False" Margin="0,16,0,0">
<Button DockPanel.Dock="Right" Content="Close" Width="70" IsCancel="True"/>
</DockPanel>
</Grid>
</Window>

View File

@ -101,6 +101,22 @@ namespace SourceGen.Tools.Omf.WpfGui {
get { return mOmfFile.OmfFileKind == OmfFile.FileKind.Load; }
}
public bool OffsetSegmentStart {
get { return AppSettings.Global.GetBool(AppSettings.OMF_OFFSET_SEGMENT_START, true); }
set {
AppSettings.Global.SetBool(AppSettings.OMF_OFFSET_SEGMENT_START, value);
OnPropertyChanged();
}
}
public bool AddNotes {
get { return AppSettings.Global.GetBool(AppSettings.OMF_ADD_NOTES, false); }
set {
AppSettings.Global.SetBool(AppSettings.OMF_ADD_NOTES, value);
OnPropertyChanged();
}
}
/// <summary>
/// Constructor.
@ -166,7 +182,15 @@ namespace SourceGen.Tools.Omf.WpfGui {
}
private void GenerateProject_Click(object sender, RoutedEventArgs e) {
Loader loader = new Loader(mOmfFile, mFormatter);
Loader.Flags flags = 0;
if (AddNotes) {
flags |= Loader.Flags.AddNotes;
}
if (OffsetSegmentStart) {
flags |= Loader.Flags.OffsetSegmentStart;
}
Loader loader = new Loader(mOmfFile, mFormatter, flags);
if (!loader.Prepare()) {
// Unexpected. If there's a valid reason for this, we need to add details
// to the error message.