diff --git a/SourceGen/MainController.cs b/SourceGen/MainController.cs
index d6be468..0fbd915 100644
--- a/SourceGen/MainController.cs
+++ b/SourceGen/MainController.cs
@@ -797,7 +797,7 @@ namespace SourceGen {
///
/// Full pathname.
/// Data file contents.
- private byte[] LoadDataFile(string dataFileName) {
+ private static byte[] LoadDataFile(string dataFileName) {
byte[] fileData;
using (FileStream fs = File.Open(dataFileName, FileMode.Open, FileAccess.Read)) {
@@ -4093,15 +4093,10 @@ namespace SourceGen {
}
public void ShowFileHexDump() {
- OpenFileDialog fileDlg = new OpenFileDialog() {
- Filter = Res.Strings.FILE_FILTER_ALL,
- FilterIndex = 1
- };
- if (fileDlg.ShowDialog() != true) {
+ if (!OpenAnyFile(out string pathName)) {
return;
}
- string fileName = fileDlg.FileName;
- FileInfo fi = new FileInfo(fileName);
+ FileInfo fi = new FileInfo(pathName);
if (fi.Length > Tools.WpfGui.HexDumpViewer.MAX_LENGTH) {
string msg = string.Format(Res.Strings.OPEN_DATA_TOO_LARGE_FMT,
fi.Length / 1024, Tools.WpfGui.HexDumpViewer.MAX_LENGTH / 1024);
@@ -4111,7 +4106,7 @@ namespace SourceGen {
}
byte[] data;
try {
- data = File.ReadAllBytes(fileName);
+ data = File.ReadAllBytes(pathName);
} catch (Exception ex) {
// not expecting this to happen
MessageBox.Show(ex.Message);
@@ -4121,7 +4116,7 @@ namespace SourceGen {
// Create the dialog without an owner, and add it to the "unowned" list.
Tools.WpfGui.HexDumpViewer dlg = new Tools.WpfGui.HexDumpViewer(null,
data, mFormatter);
- dlg.SetFileName(Path.GetFileName(fileName));
+ dlg.SetFileName(Path.GetFileName(pathName));
dlg.Closing += (sender, e) => {
Debug.WriteLine("Window " + dlg + " closed, removing from unowned list");
mUnownedWindows.Remove(dlg);
@@ -4137,18 +4132,66 @@ namespace SourceGen {
}
public void SliceFiles() {
+ if (!OpenAnyFile(out string pathName)) {
+ return;
+ }
+
+ Tools.WpfGui.FileSlicer slicer = new Tools.WpfGui.FileSlicer(this.mMainWin, pathName,
+ mFormatter);
+ slicer.ShowDialog();
+ }
+
+ public void ConvertOmf() {
+ if (!OpenAnyFile(out string pathName)) {
+ return;
+ }
+
+ // Load the file here, so basic problems like empty / oversized files can be
+ // reported immediately.
+
+ byte[] fileData = null;
+ using (FileStream fs = File.Open(pathName, FileMode.Open, FileAccess.Read)) {
+ string errMsg = null;
+
+ if (fs.Length == 0) {
+ errMsg = Res.Strings.OPEN_DATA_EMPTY;
+ } else if (fs.Length < Tools.Omf.OmfFile.MIN_FILE_SIZE) {
+ errMsg = string.Format(Res.Strings.OPEN_DATA_TOO_SMALL_FMT, fs.Length);
+ } else if (fs.Length > Tools.Omf.OmfFile.MAX_FILE_SIZE) {
+ errMsg = string.Format(Res.Strings.OPEN_DATA_TOO_LARGE_FMT,
+ fs.Length / 1024, Tools.Omf.OmfFile.MAX_FILE_SIZE / 1024);
+ }
+ if (errMsg == null) {
+ fileData = new byte[fs.Length];
+ int actual = fs.Read(fileData, 0, (int)fs.Length);
+ if (actual != fs.Length) {
+ errMsg = Res.Strings.OPEN_DATA_PARTIAL_READ;
+ }
+ }
+
+ if (errMsg != null) {
+ MessageBox.Show(errMsg, Res.Strings.ERR_FILE_GENERIC_CAPTION,
+ MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+ }
+
+ Tools.Omf.WpfGui.OmfViewer ov =
+ new Tools.Omf.WpfGui.OmfViewer(this.mMainWin, pathName, fileData);
+ ov.ShowDialog();
+ }
+
+ private bool OpenAnyFile(out string pathName) {
OpenFileDialog fileDlg = new OpenFileDialog() {
Filter = Res.Strings.FILE_FILTER_ALL,
FilterIndex = 1
};
if (fileDlg.ShowDialog() != true) {
- return;
+ pathName = null;
+ return false;
}
- string pathName = Path.GetFullPath(fileDlg.FileName);
-
- Tools.WpfGui.FileSlicer slicer = new Tools.WpfGui.FileSlicer(this.mMainWin, pathName,
- mFormatter);
- slicer.ShowDialog();
+ pathName = Path.GetFullPath(fileDlg.FileName);
+ return true;
}
#endregion Tools
@@ -4240,16 +4283,11 @@ namespace SourceGen {
}
public void Debug_ApplesoftToHtml() {
- OpenFileDialog fileDlg = new OpenFileDialog() {
- Filter = Res.Strings.FILE_FILTER_ALL,
- FilterIndex = 1
- };
- if (fileDlg.ShowDialog() != true) {
+ if (!OpenAnyFile(out string basPathName)) {
return;
}
byte[] data;
- string basPathName = Path.GetFullPath(fileDlg.FileName);
try {
data = File.ReadAllBytes(basPathName);
} catch (IOException ex) {
@@ -4326,6 +4364,7 @@ namespace SourceGen {
ApplyUndoableChanges(cs);
}
+ // Disable "analyze uncategorized data" for best results.
public void Debug_ApplyPlatformSymbols() {
ChangeSet cs = new ChangeSet(1);
diff --git a/SourceGen/Res/Strings.xaml b/SourceGen/Res/Strings.xaml
index ebda1b4..c28d9ba 100644
--- a/SourceGen/Res/Strings.xaml
+++ b/SourceGen/Res/Strings.xaml
@@ -137,6 +137,7 @@ limitations under the License.
The file could not be opened: {0}.
Unable to read the entire file
File is too large ({0:N0} KiB, max is {1:N0} KiB).
+ File is too small ({0} bytes).
The file is {0:N0} bytes long, but the project expected {1:N0}.
The file has CRC {0}, but the project expected {1}.
Failed
diff --git a/SourceGen/Res/Strings.xaml.cs b/SourceGen/Res/Strings.xaml.cs
index a427e24..86fd659 100644
--- a/SourceGen/Res/Strings.xaml.cs
+++ b/SourceGen/Res/Strings.xaml.cs
@@ -255,6 +255,8 @@ namespace SourceGen.Res {
(string)Application.Current.FindResource("str_OpenDataLoadFailedFmt");
public static string OPEN_DATA_TOO_LARGE_FMT =
(string)Application.Current.FindResource("str_OpenDataTooLargeFmt");
+ public static string OPEN_DATA_TOO_SMALL_FMT =
+ (string)Application.Current.FindResource("str_OpenDataTooSmallFmt");
public static string OPEN_DATA_WRONG_CRC_FMT =
(string)Application.Current.FindResource("str_OpenDataWrongCrcFmt");
public static string OPEN_DATA_WRONG_LENGTH_FMT =
diff --git a/SourceGen/SourceGen.csproj b/SourceGen/SourceGen.csproj
index 16d0f7d..7f7cf90 100644
--- a/SourceGen/SourceGen.csproj
+++ b/SourceGen/SourceGen.csproj
@@ -85,6 +85,10 @@
GenTestRunner.xaml
+
+
+ OmfViewer.xaml
+
FileConcatenator.xaml
@@ -276,6 +280,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
diff --git a/SourceGen/Tools/Omf/OmfFile.cs b/SourceGen/Tools/Omf/OmfFile.cs
new file mode 100644
index 0000000..85d8cc0
--- /dev/null
+++ b/SourceGen/Tools/Omf/OmfFile.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2020 faddenSoft
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+
+namespace SourceGen.Tools.Omf {
+ ///
+ /// Apple IIgs OMF file.
+ ///
+ ///
+ /// References:
+ /// - "Apple IIgs Programmer's Workshop Reference". Chapter 7, page 228, describes
+ /// OMF v1.0 and v2.0.
+ /// - "Apple IIgs GS/OS Reference, for GS/OS System Software Version 5.0 and later".
+ /// Appendix F describes OMF v2.1, and Chapter 8 has some useful information about
+ /// how the loader works.
+ /// - "Undocumented Secrets of the Apple IIGS System Loader" by Neil Parker,
+ /// http://nparker.llx.com/a2/loader.html . Among other things it documents ExpressLoad
+ /// segments, something Apple apparently never did.
+ /// - Apple IIgs Tech Note #66, "ExpressLoad Philosophy".
+ ///
+ /// Related:
+ /// - https://www.brutaldeluxe.fr/products/crossdevtools/omfanalyzer/
+ /// - https://github.com/fadden/ciderpress/blob/master/reformat/Disasm.cpp
+ ///
+ public class OmfFile {
+ public const int MIN_FILE_SIZE = 37; // can't be smaller than v0 segment hdr
+ public const int MAX_FILE_SIZE = (1 << 24) - 1; // cap it at 16MB
+
+ // TODO:
+ // - has an overall file type (load, object, RTL)
+ // - determine with a prioritized series of "could this be ____" checks
+ // - holds list of OmfSegment
+ // - has a list of warnings and errors that arose during parsing
+ // - holds on to byte[] with data
+ // OmfSegment:
+ // - header (common data, plus name/value dict with version-specific fields for display)
+ // - ref back to OmfFile for byte[] access?
+ // - list of OmfRecord
+ // - file-type-specific stuff can be generated and cached in second pass, e.g.
+ // generate a full relocation dictionary for load files (can't do this until we
+ // know the overall file type, which we can't know until all segments have been
+ // processed a bit)
+ }
+}
diff --git a/SourceGen/Tools/Omf/WpfGui/OmfViewer.xaml b/SourceGen/Tools/Omf/WpfGui/OmfViewer.xaml
new file mode 100644
index 0000000..c55b04a
--- /dev/null
+++ b/SourceGen/Tools/Omf/WpfGui/OmfViewer.xaml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SourceGen/Tools/Omf/WpfGui/OmfViewer.xaml.cs b/SourceGen/Tools/Omf/WpfGui/OmfViewer.xaml.cs
new file mode 100644
index 0000000..cf92efa
--- /dev/null
+++ b/SourceGen/Tools/Omf/WpfGui/OmfViewer.xaml.cs
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2020 faddenSoft
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Windows;
+using System.Windows.Input;
+
+namespace SourceGen.Tools.Omf.WpfGui {
+ ///
+ /// Apple IIgs OMF file viewer.
+ ///
+ public partial class OmfViewer : Window, INotifyPropertyChanged {
+ private string mPathName;
+ private byte[] mFileData;
+
+ //private Brush mDefaultLabelColor = SystemColors.WindowTextBrush;
+
+ // INotifyPropertyChanged implementation
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ public class SegmentListItem {
+ public int SegNum { get; private set; }
+
+ // TODO: take OMFSegment obj
+ public SegmentListItem(int segNum) {
+ SegNum = segNum;
+ }
+ }
+
+ public List SegmentListItems { get; private set; } = new List();
+
+
+ public OmfViewer(Window owner, string pathName, byte[] data) {
+ InitializeComponent();
+ Owner = owner;
+ DataContext = this;
+
+ mPathName = pathName;
+ mFileData = data;
+
+ SegmentListItems.Add(new SegmentListItem(123));
+ SegmentListItems.Add(new SegmentListItem(456));
+ }
+
+ private void SegmentList_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
+ Debug.WriteLine("DCLICK");
+ }
+ }
+}
diff --git a/SourceGen/Tools/WpfGui/FileConcatenator.xaml.cs b/SourceGen/Tools/WpfGui/FileConcatenator.xaml.cs
index 997166e..3fe5ac9 100644
--- a/SourceGen/Tools/WpfGui/FileConcatenator.xaml.cs
+++ b/SourceGen/Tools/WpfGui/FileConcatenator.xaml.cs
@@ -20,10 +20,10 @@ using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Windows;
+using System.Windows.Controls;
using Microsoft.Win32;
using CommonUtil;
-using System.Windows.Controls;
namespace SourceGen.Tools.WpfGui {
///
diff --git a/SourceGen/Tools/WpfGui/FileSlicer.xaml.cs b/SourceGen/Tools/WpfGui/FileSlicer.xaml.cs
index 3ced1e0..82ecf13 100644
--- a/SourceGen/Tools/WpfGui/FileSlicer.xaml.cs
+++ b/SourceGen/Tools/WpfGui/FileSlicer.xaml.cs
@@ -14,18 +14,16 @@
* limitations under the License.
*/
using System;
-using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
+using System.Text;
using System.Windows;
-using System.Windows.Controls;
+using System.Windows.Media;
using Microsoft.Win32;
using Asm65;
-using System.Text;
-using System.Windows.Media;
namespace SourceGen.Tools.WpfGui {
///
diff --git a/SourceGen/WpfGui/MainWindow.xaml b/SourceGen/WpfGui/MainWindow.xaml
index 6f9b1c5..4413f38 100644
--- a/SourceGen/WpfGui/MainWindow.xaml
+++ b/SourceGen/WpfGui/MainWindow.xaml
@@ -64,6 +64,7 @@ limitations under the License.
+
@@ -221,6 +222,8 @@ limitations under the License.
CanExecute="IsProjectOpen" Executed="CloseCmd_Executed"/>
+
+