From 8dba2c1de605ee9011cae7a0dfc7aea3edb2d848 Mon Sep 17 00:00:00 2001
From: Andy McFadden
Date: Wed, 16 Jul 2025 08:20:05 -0700
Subject: [PATCH] Allow formatting of 32-bit address tables
These are actually 24-bit address tables, with an extra byte to pad
each entry to an even number of bytes, so the GUI refers to them as
"24-bit + pad byte". The extra byte is not included in the address
calculation, and is simply skipped over.
(issue #171)
---
SourceGen/WpfGui/FormatAddressTable.xaml | 11 ++++---
SourceGen/WpfGui/FormatAddressTable.xaml.cs | 33 ++++++++++++++-------
docs/sgmanual/mainwin.html | 8 +++--
3 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/SourceGen/WpfGui/FormatAddressTable.xaml b/SourceGen/WpfGui/FormatAddressTable.xaml
index 16b0c32..abc1524 100644
--- a/SourceGen/WpfGui/FormatAddressTable.xaml
+++ b/SourceGen/WpfGui/FormatAddressTable.xaml
@@ -55,6 +55,8 @@ limitations under the License.
Content="16-bit" Checked="WidthRadio_CheckedChanged"/>
+
@@ -87,7 +89,7 @@ limitations under the License.
Checked="HighByte_CheckedChanged"/>
-
+
@@ -134,9 +136,10 @@ limitations under the License.
+
public List AllTargetOffsets { get; private set; }
+ ///
+ /// True if the addresses are 24-bit or 32-bit, and thus include the bank byte.
+ ///
+ public bool IsBankEnabled {
+ get { return width24Radio.IsChecked == true || width32Radio.IsChecked == true; }
+ }
+
///
/// If set, targets are offset by one for RTS/RTL.
///
@@ -194,6 +201,7 @@ namespace SourceGen.WpfGui {
if (mProject.CpuDef.HasAddr16) {
// Disable the 24-bit option. Having 16-bit selected will disable the rest.
width24Radio.IsEnabled = false;
+ width32Radio.IsEnabled = false;
}
mUpdating = false;
@@ -210,16 +218,11 @@ namespace SourceGen.WpfGui {
}
mUpdating = true; // no re-entry
- // handled with XAML bindings
- //lowThirdPartRadio.Enabled = width24Radio.Checked;
- //highThirdPartRadio.Enabled = width24Radio.Checked;
- //bankByteGroupBox.Enabled = width24Radio.Checked;
-
lowSecondPartRadio.IsEnabled = true;
// If the user selects "constant" for high byte or bank byte, then there is no
// 3rd part available for low/high, so we need to turn those back off.
- if (width24Radio.IsChecked == true) {
+ if (width24Radio.IsChecked == true || width32Radio.IsChecked == true) {
bool haveThree = !(highConstantRadio.IsChecked == true ||
bankConstantRadio.IsChecked == true);
lowThirdPartRadio.IsEnabled = haveThree;
@@ -268,6 +271,7 @@ namespace SourceGen.WpfGui {
}
private void WidthRadio_CheckedChanged(object sender, RoutedEventArgs e) {
+ OnPropertyChanged(nameof(IsBankEnabled));
UpdateControls();
}
@@ -320,7 +324,7 @@ namespace SourceGen.WpfGui {
} else {
minDiv = 2;
}
- } else {
+ } else /*24 or 32*/ {
if (highConstantRadio.IsChecked == true) {
if (bankConstantRadio.IsChecked == true) {
minDiv = 1;
@@ -334,6 +338,9 @@ namespace SourceGen.WpfGui {
minDiv = 3;
}
}
+ if (width32Radio.IsChecked == true) {
+ minDiv++;
+ }
}
IncompatibleSelectionVisibility = InvalidConstantVisibility = false;
@@ -404,7 +411,7 @@ namespace SourceGen.WpfGui {
} else {
highOff = -1; // use constant
}
- if (width24Radio.IsChecked == true) {
+ if (width24Radio.IsChecked == true || width32Radio.IsChecked == true) {
if (bankNthPartRadio.IsChecked == true) {
// Use whichever part isn't being used by the other two.
if (lowOff != 0 && highOff != 0) {
@@ -435,6 +442,8 @@ namespace SourceGen.WpfGui {
if (IsSplitTable) {
// Split table, so stride is 1 and each section start is determined by the span.
+ // We don't change anything for the 32-bit width, because we would be ignoring
+ // those bytes anyway.
stride = 1;
lowOff *= span;
highOff *= span;
@@ -448,6 +457,9 @@ namespace SourceGen.WpfGui {
if (bankOff >= 0) {
stride++;
}
+ if (width32Radio.IsChecked == true) {
+ stride++;
+ }
}
Debug.WriteLine("FormatAddressTable: stride=" + stride + " span=" + span +
@@ -481,7 +493,8 @@ namespace SourceGen.WpfGui {
bank = (byte) bankConst;
}
- // This is the target address.
+ // This is the target address. We're currently ignoring the extra byte in 32-bit
+ // addresses.
int addr = ((bank << 16) | (high << 8) | low) + adj;
// Map it to a target label. Start by looking for an offset inside file bounds.
@@ -546,7 +559,7 @@ namespace SourceGen.WpfGui {
// 24-bit table, i.e. low then bank then high. This is not really
// a thing, but we should either prevent it or punt to single-byte
// like we do for split tables.
- Debug.Assert(stride >= 1 && stride <= 3);
+ Debug.Assert(stride >= 1 && stride <= 4);
newDfds.Add(offsets[0 + i * stride], FormatDescriptor.Create(stride,
new WeakSymbolRef(targetLabel, WeakSymbolRef.Part.Low), isBigEndian));
}
diff --git a/docs/sgmanual/mainwin.html b/docs/sgmanual/mainwin.html
index b448503..b5b3e89 100644
--- a/docs/sgmanual/mainwin.html
+++ b/docs/sgmanual/mainwin.html
@@ -588,9 +588,11 @@ complicated dialog is split into sections.
- Address Characteristics: select whether the table has 16-bit
addresses or 24-bit addresses. (24-bit addresses are disabled if you
- don't have the CPU set to 65816.) If the table is split into individual
- sub-tables for low bytes and high bytes, check the Parts are split
- across sub-tables box. If the address parts are being pushed
+ don't have the CPU set to 65816.) If each 24-bit address is stored as
+ a 32-bit value, use the "24-bit + pad byte" option.
+ If the table is split into individual sub-tables for low bytes and high
+ bytes, check the Parts are split across sub-tables box.
+ If the address parts are being pushed
on the stack for an
RTS/RTL,
check the Adjusted for RTS/RTL box to adjust them by 1.
- Low Byte Source: indicate which part of the table or word holds the