diff --git a/PluginCommon/Interfaces.cs b/PluginCommon/Interfaces.cs
index 4014c83..d1e1c45 100644
--- a/PluginCommon/Interfaces.cs
+++ b/PluginCommon/Interfaces.cs
@@ -448,7 +448,9 @@ namespace PluginCommon {
StringL16,
StringDci,
Dense,
- Fill
+ Fill,
+ Uninit,
+ Junk
}
///
@@ -473,5 +475,7 @@ namespace PluginCommon {
HighAscii,
C64Petscii,
C64Screen
+
+ // skipping alignment sub-types for now
}
}
diff --git a/SourceGen/AsmGen/AsmAcme.cs b/SourceGen/AsmGen/AsmAcme.cs
index 3c7c72c..fd67ac6 100644
--- a/SourceGen/AsmGen/AsmAcme.cs
+++ b/SourceGen/AsmGen/AsmAcme.cs
@@ -136,6 +136,7 @@ namespace SourceGen.AsmGen {
//DefineBigData4
{ "Fill", "!fill" },
{ "Dense", "!hex" },
+ { "Uninit", "!skip" },
//Junk
{ "Align", "!align" },
{ "StrGeneric", "!text" }, // can use !xor for high ASCII
@@ -458,16 +459,19 @@ namespace SourceGen.AsmGen {
opcodeStr = operandStr = null;
OutputDenseHex(offset, length, labelStr, commentStr);
break;
+ case FormatDescriptor.Type.Uninit:
case FormatDescriptor.Type.Junk:
+ bool canAlign = (dfd.FormatType == FormatDescriptor.Type.Junk);
int fillVal = Helper.CheckRangeHoldsSingleValue(data, offset, length);
- if (fillVal >= 0 && GenCommon.CheckJunkAlign(offset, dfd, Project.AddrMap)) {
+ if (canAlign && fillVal >= 0 &&
+ GenCommon.CheckJunkAlign(offset, dfd, Project.AddrMap)) {
// !align ANDVALUE, EQUALVALUE [, FILLVALUE]
opcodeStr = sDataOpNames.Align;
int alignVal = 1 << FormatDescriptor.AlignmentToPower(dfd.FormatSubType);
operandStr = (alignVal - 1).ToString() +
",0," + formatter.FormatHexValue(fillVal, 2);
- } else if (fillVal >= 0) {
- // treat same as Fill
+ } else if (fillVal >= 0 && (length > 1 || fillVal == 0x00)) {
+ // If multi-byte, or single byte and zero, treat same as Fill.
opcodeStr = sDataOpNames.Fill;
operandStr = length + "," + formatter.FormatHexValue(fillVal, 2);
} else {
diff --git a/SourceGen/AsmGen/AsmCc65.cs b/SourceGen/AsmGen/AsmCc65.cs
index 0ad57ba..0306d50 100644
--- a/SourceGen/AsmGen/AsmCc65.cs
+++ b/SourceGen/AsmGen/AsmCc65.cs
@@ -136,6 +136,7 @@ namespace SourceGen.AsmGen {
//DefineBigData4
{ "Fill", ".res" },
{ "Dense", ".byte" }, // really just just comma-separated bytes
+ { "Uninit", ".res" },
//Junk
{ "StrGeneric", ".byte" },
//StrReverse
@@ -447,13 +448,14 @@ namespace SourceGen.AsmGen {
opcodeStr = operandStr = null;
OutputDenseHex(offset, length, labelStr, commentStr);
break;
+ case FormatDescriptor.Type.Uninit:
case FormatDescriptor.Type.Junk:
// The ca65 .align directive has a dependency on the alignment of the
// segment as a whole. We're not currently declaring multiple segments,
// so we can't use .align without generating complaints.
int fillVal = Helper.CheckRangeHoldsSingleValue(data, offset, length);
- if (fillVal >= 0) {
- // treat same as Fill
+ if (fillVal >= 0 && (length > 1 || fillVal == 0x00)) {
+ // If multi-byte, or single byte and zero, treat same as Fill.
opcodeStr = sDataOpNames.Fill;
operandStr = length + "," + formatter.FormatHexValue(fillVal, 2);
} else {
diff --git a/SourceGen/AsmGen/AsmMerlin32.cs b/SourceGen/AsmGen/AsmMerlin32.cs
index 3a69e67..4e5513b 100644
--- a/SourceGen/AsmGen/AsmMerlin32.cs
+++ b/SourceGen/AsmGen/AsmMerlin32.cs
@@ -130,6 +130,7 @@ namespace SourceGen.AsmGen {
//DefineBigData4
{ "Fill", "ds" },
{ "Dense", "hex" },
+ { "Uninit", "ds" },
//Junk
//Align
{ "StrGeneric", "asc" },
@@ -312,6 +313,7 @@ namespace SourceGen.AsmGen {
opcodeStr = operandStr = null;
OutputDenseHex(offset, length, labelStr, commentStr);
break;
+ case FormatDescriptor.Type.Uninit:
case FormatDescriptor.Type.Junk:
int fillVal = Helper.CheckRangeHoldsSingleValue(data, offset, length);
if (fillVal >= 0) {
@@ -324,6 +326,12 @@ namespace SourceGen.AsmGen {
} else {
operandStr = "\\," + formatter.FormatHexValue(fillVal, 2);
}
+ } else if (length == 1 && fillVal != 0x00) {
+ // Single-byte HEX looks better than "ds 1,$xx", and will match up
+ // with adjacent multi-byte junk/uninit.
+ multiLine = true;
+ opcodeStr = operandStr = null;
+ OutputDenseHex(offset, length, labelStr, commentStr);
} else {
if (fillVal == 0) {
operandStr = length.ToString();
diff --git a/SourceGen/AsmGen/AsmTass64.cs b/SourceGen/AsmGen/AsmTass64.cs
index 01c71f1..5c02c34 100644
--- a/SourceGen/AsmGen/AsmTass64.cs
+++ b/SourceGen/AsmGen/AsmTass64.cs
@@ -155,6 +155,7 @@ namespace SourceGen.AsmGen {
//DefineBigData4
{ "Fill", ".fill" },
{ "Dense", ".byte" }, // not really dense, just comma-separated bytes
+ { "Uninit", ".fill" },
//Junk
{ "Align", ".align" },
{ "StrGeneric", ".text" },
@@ -552,16 +553,20 @@ namespace SourceGen.AsmGen {
opcodeStr = operandStr = null;
OutputDenseHex(offset, length, labelStr, commentStr);
break;
+ case FormatDescriptor.Type.Uninit:
+ // TODO: use the special syntax for uninit byte/word/dword if possible.
case FormatDescriptor.Type.Junk:
+ bool canAlign = (dfd.FormatType == FormatDescriptor.Type.Junk);
int fillVal = Helper.CheckRangeHoldsSingleValue(data, offset, length);
- if (fillVal >= 0 && GenCommon.CheckJunkAlign(offset, dfd, Project.AddrMap)) {
+ if (canAlign && fillVal >= 0 &&
+ GenCommon.CheckJunkAlign(offset, dfd, Project.AddrMap)) {
// .align [, ]
opcodeStr = sDataOpNames.Align;
int alignVal = 1 << FormatDescriptor.AlignmentToPower(dfd.FormatSubType);
operandStr = alignVal.ToString() +
"," + formatter.FormatHexValue(fillVal, 2);
- } else if (fillVal >= 0) {
- // treat same as Fill
+ } else if (fillVal >= 0 && (length > 1 || fillVal == 0x00)) {
+ // If multi-byte, or single byte and zero, treat same as Fill.
opcodeStr = sDataOpNames.Fill;
operandStr = length + "," + formatter.FormatHexValue(fillVal, 2);
} else {
diff --git a/SourceGen/CodeAnalysis.cs b/SourceGen/CodeAnalysis.cs
index 3b584a2..3990d5e 100644
--- a/SourceGen/CodeAnalysis.cs
+++ b/SourceGen/CodeAnalysis.cs
@@ -1271,6 +1271,8 @@ namespace SourceGen {
return FormatDescriptor.Type.StringDci;
case DataType.Fill:
return FormatDescriptor.Type.Fill;
+ case DataType.Uninit:
+ return FormatDescriptor.Type.Uninit;
case DataType.Dense:
return FormatDescriptor.Type.Dense;
default:
diff --git a/SourceGen/DisasmProject.cs b/SourceGen/DisasmProject.cs
index 9bb5c8f..c9f4674 100644
--- a/SourceGen/DisasmProject.cs
+++ b/SourceGen/DisasmProject.cs
@@ -1648,7 +1648,7 @@ namespace SourceGen {
if (mAnattribs[symOffset].Symbol != null &&
mAnattribs[symOffset].Symbol.Label == dfd.SymbolRef.Label) {
Messages.Add(new MessageList.MessageEntry(
- MessageList.MessageEntry.SeverityLevel.Warning,
+ MessageList.MessageEntry.SeverityLevel.Error,
offset,
MessageList.MessageEntry.MessageType.NonAddrLabelRef,
dfd.SymbolRef.Label,
@@ -1766,7 +1766,8 @@ namespace SourceGen {
offset += attr.Length;
if (attr.DataDescriptor != null &&
- attr.DataDescriptor.FormatType == FormatDescriptor.Type.Junk) {
+ (attr.DataDescriptor.FormatType == FormatDescriptor.Type.Uninit ||
+ attr.DataDescriptor.FormatType == FormatDescriptor.Type.Junk)) {
ByteCounts.JunkByteCount += attr.Length;
} else {
ByteCounts.DataByteCount += attr.Length;
diff --git a/SourceGen/FormatDescriptor.cs b/SourceGen/FormatDescriptor.cs
index 9fd836e..fb0ea2d 100644
--- a/SourceGen/FormatDescriptor.cs
+++ b/SourceGen/FormatDescriptor.cs
@@ -61,6 +61,7 @@ namespace SourceGen {
Dense, // raw data, represented as compactly as possible
Fill, // fill memory with a value
+ Uninit, // uninitialized data storage area
Junk // contents of memory are not interesting
}
@@ -91,6 +92,8 @@ namespace SourceGen {
// Fill; no sub-types
+ // Uninit; no sub-types
+
// Junk; data may exist for alignment purposes. Sub-type indicates boundary.
// (SubType=None indicates no alignment)
Align2, // must be consecutive ascending powers of 2
@@ -497,6 +500,9 @@ namespace SourceGen {
case Type.Fill:
retstr += "fill";
break;
+ case Type.Uninit:
+ retstr += "uninitialized data";
+ break;
case Type.Junk:
retstr += "unaligned junk";
break;
diff --git a/SourceGen/PseudoOp.cs b/SourceGen/PseudoOp.cs
index 52d3631..cfb4572 100644
--- a/SourceGen/PseudoOp.cs
+++ b/SourceGen/PseudoOp.cs
@@ -78,6 +78,7 @@ namespace SourceGen {
public string DefineBigData4 { get; private set; }
public string Fill { get; private set; }
public string Dense { get; private set; }
+ public string Uninit { get; private set; }
public string Junk { get; private set; }
public string Align { get; private set; }
public string StrGeneric { get; private set; }
@@ -129,6 +130,7 @@ namespace SourceGen {
a.DefineBigData4 == b.DefineBigData4 &&
a.Fill == b.Fill &&
a.Dense == b.Dense &&
+ a.Uninit == b.Uninit &&
a.Junk == b.Junk &&
a.Align == b.Align &&
a.StrGeneric == b.StrGeneric &&
@@ -242,6 +244,7 @@ namespace SourceGen {
{ "DefineBigData4", ".dbd4" },
{ "Fill", ".fill" },
{ "Dense", ".bulk" },
+ { "Uninit", ".ds" },
{ "Junk", ".junk" },
{ "Align", ".align" },
@@ -275,6 +278,7 @@ namespace SourceGen {
case FormatDescriptor.Type.NumericLE:
case FormatDescriptor.Type.NumericBE:
case FormatDescriptor.Type.Fill:
+ case FormatDescriptor.Type.Uninit:
case FormatDescriptor.Type.Junk:
return 1;
case FormatDescriptor.Type.Dense: {
@@ -356,6 +360,10 @@ namespace SourceGen {
po.Opcode = opNames.Fill;
po.Operand = length + "," + formatter.FormatHexValue(data[offset], 2);
break;
+ case FormatDescriptor.Type.Uninit:
+ po.Opcode = opNames.Uninit;
+ po.Operand = length.ToString();
+ break;
case FormatDescriptor.Type.Junk:
if (dfd.FormatSubType != FormatDescriptor.SubType.None) {
po.Opcode = opNames.Align;
diff --git a/SourceGen/Res/Strings.xaml b/SourceGen/Res/Strings.xaml
index 32e2092..bae056e 100644
--- a/SourceGen/Res/Strings.xaml
+++ b/SourceGen/Res/Strings.xaml
@@ -185,7 +185,7 @@ limitations under the License.
C64 Screen Code
{1} CPU @ {2} MHz
Show
- {0:F1}KB ({1:F1}% code, {2:F1}% data, {3:F1}% junk)
+ {0:F1}KB ({1:F1}% code, {2:F1}% data, {3:F1}% uninit/junk)
Ready
DCI string has mixed data
DCI string not terminated
diff --git a/SourceGen/SGTestData/20000-numeric-types b/SourceGen/SGTestData/20000-numeric-types
index bdeee08..60267ea 100644
Binary files a/SourceGen/SGTestData/20000-numeric-types and b/SourceGen/SGTestData/20000-numeric-types differ
diff --git a/SourceGen/SGTestData/20000-numeric-types.dis65 b/SourceGen/SGTestData/20000-numeric-types.dis65
index 7ff704c..39897e3 100644
--- a/SourceGen/SGTestData/20000-numeric-types.dis65
+++ b/SourceGen/SGTestData/20000-numeric-types.dis65
@@ -1,8 +1,8 @@
### 6502bench SourceGen dis65 v1.0 ###
{
-"_ContentVersion":3,
-"FileDataLength":1200,
-"FileDataCrc32":1114187983,
+"_ContentVersion":5,
+"FileDataLength":1227,
+"FileDataCrc32":516168842,
"ProjectProps":{
"CpuName":"6502",
"IncludeUndocumentedInstr":false,
@@ -14,7 +14,9 @@
"DefaultTextScanMode":"LowHighAscii",
"MinCharsForString":4,
"SeekNearbyTargets":true,
-"SmartPlpHandling":true},
+"UseRelocData":false,
+"SmartPlpHandling":true,
+"SmartPlbHandling":true},
"PlatformSymbolFileIdentifiers":[],
"ExtensionScriptFileIdentifiers":["PROJ:20000-numeric-types.cs"],
@@ -23,15 +25,24 @@
"AddressMap":[{
"Offset":0,
-"Addr":4096},
+"Addr":4096,
+"Length":-1024,
+"PreLabel":"",
+"IsRelative":false},
{
"Offset":1032,
-"Addr":5128},
+"Addr":5128,
+"Length":-1024,
+"PreLabel":"",
+"IsRelative":false},
{
"Offset":1048,
-"Addr":5160}],
+"Addr":5160,
+"Length":-1024,
+"PreLabel":"",
+"IsRelative":false}],
"TypeHints":[{
"Low":0,
"High":0,
@@ -230,6 +241,60 @@
"Length":1,
"Format":"NumericLE",
"SubFormat":"Binary",
+"SymbolRef":null},
+
+"1200":{
+"Length":1,
+"Format":"Uninit",
+"SubFormat":"None",
+"SymbolRef":null},
+
+"1201":{
+"Length":2,
+"Format":"Uninit",
+"SubFormat":"None",
+"SymbolRef":null},
+
+"1203":{
+"Length":3,
+"Format":"Uninit",
+"SubFormat":"None",
+"SymbolRef":null},
+
+"1206":{
+"Length":4,
+"Format":"Uninit",
+"SubFormat":"None",
+"SymbolRef":null},
+
+"1210":{
+"Length":1,
+"Format":"Uninit",
+"SubFormat":"None",
+"SymbolRef":null},
+
+"1211":{
+"Length":2,
+"Format":"Uninit",
+"SubFormat":"None",
+"SymbolRef":null},
+
+"1213":{
+"Length":3,
+"Format":"Uninit",
+"SubFormat":"None",
+"SymbolRef":null},
+
+"1216":{
+"Length":4,
+"Format":"Uninit",
+"SubFormat":"None",
+"SymbolRef":null},
+
+"1221":{
+"Length":5,
+"Format":"Uninit",
+"SubFormat":"None",
"SymbolRef":null}},
"LvTables":{
@@ -245,4 +310,10 @@
"VisualizationAnimations":[],
"VisualizationSets":{
"1160":{
-"Tags":["vis000488"]}}}
+"Tags":["vis000488"]}},
+
+"RelocList":{
+},
+
+"DbrValues":{
+}}
diff --git a/SourceGen/SGTestData/Expected/20000-numeric-types_64tass.S b/SourceGen/SGTestData/Expected/20000-numeric-types_64tass.S
index f572c4a..6951418 100644
--- a/SourceGen/SGTestData/Expected/20000-numeric-types_64tass.S
+++ b/SourceGen/SGTestData/Expected/20000-numeric-types_64tass.S
@@ -88,4 +88,15 @@ L14A8 .fill 8,$8b
.fill 8,$8c
.byte %10001100
.fill 7,$8c
+ .byte $90
+ .byte $92,$91
+ .byte $95,$94,$93
+ .byte $99,$98,$97,$96
+ .fill 1,$00
+ .fill 2,$00
+ .fill 3,$00
+ .fill 4,$00
+ .byte $80
+ .fill 5,$00
+ .byte $80
.here
diff --git a/SourceGen/SGTestData/Expected/20000-numeric-types_acme.S b/SourceGen/SGTestData/Expected/20000-numeric-types_acme.S
index 65415a8..15f866b 100644
--- a/SourceGen/SGTestData/Expected/20000-numeric-types_acme.S
+++ b/SourceGen/SGTestData/Expected/20000-numeric-types_acme.S
@@ -84,4 +84,15 @@ L14A8 !fill 8,$8b
!fill 8,$8c
!byte %10001100
!fill 7,$8c
+ !hex 90
+ !hex 9291
+ !hex 959493
+ !hex 99989796
+ !fill 1,$00
+ !fill 2,$00
+ !fill 3,$00
+ !fill 4,$00
+ !byte $80
+ !fill 5,$00
+ !byte $80
}
diff --git a/SourceGen/SGTestData/Expected/20000-numeric-types_cc65.S b/SourceGen/SGTestData/Expected/20000-numeric-types_cc65.S
index 65ad205..f691f95 100644
--- a/SourceGen/SGTestData/Expected/20000-numeric-types_cc65.S
+++ b/SourceGen/SGTestData/Expected/20000-numeric-types_cc65.S
@@ -85,3 +85,14 @@ L14A8: .res 8,$8b
.res 8,$8c
.byte %10001100
.res 7,$8c
+ .byte $90
+ .byte $92,$91
+ .byte $95,$94,$93
+ .byte $99,$98,$97,$96
+ .res 1,$00
+ .res 2,$00
+ .res 3,$00
+ .res 4,$00
+ .byte $80
+ .res 5,$00
+ .byte $80
diff --git a/SourceGen/SGTestData/Expected/20000-numeric-types_merlin32.S b/SourceGen/SGTestData/Expected/20000-numeric-types_merlin32.S
index c103745..80bae86 100644
--- a/SourceGen/SGTestData/Expected/20000-numeric-types_merlin32.S
+++ b/SourceGen/SGTestData/Expected/20000-numeric-types_merlin32.S
@@ -82,3 +82,14 @@ L14A8 ds 8,$8b
ds 8,$8c
dfb %10001100
ds 7,$8c
+ hex 90
+ hex 9291
+ hex 959493
+ hex 99989796
+ ds 1
+ ds 2
+ ds 3
+ ds 4
+ dfb $80
+ ds 5
+ dfb $80
diff --git a/SourceGen/SGTestData/Source/20000-numeric-types.S b/SourceGen/SGTestData/Source/20000-numeric-types.S
index 166b499..60ae98f 100644
--- a/SourceGen/SGTestData/Source/20000-numeric-types.S
+++ b/SourceGen/SGTestData/Source/20000-numeric-types.S
@@ -71,3 +71,16 @@ dref ds 16,$85 ;has a data reference
ds 16,$8a ;EDIT: add visualization
cref ds 16,$8b ;has a code reference
ds 16,$8c ;EDIT: format byte as binary
+
+; Some uninitialized data for the "uninit" op.
+ dfb $90
+ dw $9192
+ adr $939495
+ adrl $96979899
+ ds 1
+ ds 2
+ ds 3
+ ds 4
+ dfb $80
+ ds 5
+ dfb $80
diff --git a/SourceGen/WpfGui/EditAppSettings.xaml b/SourceGen/WpfGui/EditAppSettings.xaml
index c6ba446..5a580a1 100644
--- a/SourceGen/WpfGui/EditAppSettings.xaml
+++ b/SourceGen/WpfGui/EditAppSettings.xaml
@@ -661,7 +661,12 @@ limitations under the License.
VerticalAlignment="Center" Margin="{StaticResource TBS}"
Text=".placeho" MaxLength="12"
FontFamily="{StaticResource GeneralMonoFont}"/>
-
+
+
+
diff --git a/SourceGen/WpfGui/EditDataOperand.xaml.cs b/SourceGen/WpfGui/EditDataOperand.xaml.cs
index 6bc6da6..d88981f 100644
--- a/SourceGen/WpfGui/EditDataOperand.xaml.cs
+++ b/SourceGen/WpfGui/EditDataOperand.xaml.cs
@@ -507,7 +507,7 @@ namespace SourceGen.WpfGui {
// Check for run of bytes (2 or more of the same thing). Remember that
// we check this one region at a time, and each region could have different
- // bytes, but so long as the bytes are all the same within a region we're good.
+ // bytes, but so long as the bytes are all the same within each region we're good.
if (radioFill.IsEnabled && count > 1 &&
DataAnalysis.RecognizeRun(mFileData, rng.Low, rng.High) == count) {
// LGTM
@@ -897,6 +897,9 @@ namespace SourceGen.WpfGui {
case FormatDescriptor.Type.Fill:
preferredFormat = radioFill;
break;
+ case FormatDescriptor.Type.Uninit:
+ preferredFormat = radioUninit;
+ break;
case FormatDescriptor.Type.Junk:
preferredFormat = radioJunk;
break;
@@ -1070,6 +1073,8 @@ namespace SourceGen.WpfGui {
type = FormatDescriptor.Type.Dense;
} else if (radioFill.IsChecked == true) {
type = FormatDescriptor.Type.Fill;
+ } else if (radioUninit.IsChecked == true) {
+ type = FormatDescriptor.Type.Uninit;
} else if (radioJunk.IsChecked == true) {
type = FormatDescriptor.Type.Junk;
JunkAlignmentItem comboItem = (JunkAlignmentItem)junkAlignComboBox.SelectedItem;
diff --git a/SourceGen/WpfGui/EditInstructionOperand.xaml.cs b/SourceGen/WpfGui/EditInstructionOperand.xaml.cs
index ce4d590..fb4c975 100644
--- a/SourceGen/WpfGui/EditInstructionOperand.xaml.cs
+++ b/SourceGen/WpfGui/EditInstructionOperand.xaml.cs
@@ -682,6 +682,8 @@ namespace SourceGen.WpfGui {
case FormatDescriptor.Type.StringDci:
case FormatDescriptor.Type.Dense:
case FormatDescriptor.Type.Fill:
+ case FormatDescriptor.Type.Uninit:
+ case FormatDescriptor.Type.Junk:
default:
// Unexpected; used to be data?
break;
diff --git a/docs/sgmanual/editors.html b/docs/sgmanual/editors.html
index c705caf..5abb2f9 100644
--- a/docs/sgmanual/editors.html
+++ b/docs/sgmanual/editors.html
@@ -252,9 +252,14 @@ the data file, each address will be assigned a label.
The "Bulk Data" items can represent large chunks of data compactly.
The "fill" option is only available if all selected bytes have the
-same value.
-If a region of bytes is irrelevant, perhaps used only as padding, you
-can mark it as "junk". If it appears to be adding bytes to reach a
+same value.
+If a region of bytes is used for data storage, but the initial values
+don't matter, you can mark it as "uninitialized data". (The code
+generated will usually use an initialized bulk data directive rather
+than a "leave space" directive, because SourceGen wants to guarantee
+that the assembled binary matches the original.)
+If a region of bytes is irrelevant, e.g. dead code or padding,
+you can mark it as "junk". If it appears to be adding bytes to reach a
power-of-two address boundary, you can designate it as an alignment
directive. If you have multiple regions selected, only options that
work for all regions will be shown.
diff --git a/docs/sgmanual/intro-details.html b/docs/sgmanual/intro-details.html
index 743cc77..07d4f2c 100644
--- a/docs/sgmanual/intro-details.html
+++ b/docs/sgmanual/intro-details.html
@@ -899,6 +899,9 @@ code generator figure out the implementation details.
the assembler that the width has changed.
.DBANK - specifies what value the Data Bank Register holds
(65816 only). Used when matching operands to labels.
+ .DS - identifies space set aside for variable storage. The storage
+ is initialized by the program before first use, so the values
+ in the binary don't actually matter.
.JUNK - indicates that the data in a range of bytes is irrelevant.
(When generating sources, this will become .FILL or .BULK
depending on the contents of the memory region and the assembler's
diff --git a/docs/sgmanual/mainwin.html b/docs/sgmanual/mainwin.html
index 2b534dd..b187772 100644
--- a/docs/sgmanual/mainwin.html
+++ b/docs/sgmanual/mainwin.html
@@ -84,6 +84,10 @@ saved in the application settings file.
If you hover your mouse over them, a tooltip with an explanation will
appear.
+A status bar at the bottom displays a summary of the amount of
+code, data, and uninitialized data (variable storage or junk) found
+in the program. These values are updated as you work.
+