Output big-endian macro for 64tass

If we see a big-endian value when generating code for 64tass, output
a macro and make use of it.

(issue #175)
This commit is contained in:
Andy McFadden committed 2025-09-04 11:30:05 -07:00
1 parent 5c21477cbe
commit 2c4fac9f76
9 files changed
+85 -29

No files matched your search

+32 -9
View File
@@ -118,6 +118,12 @@ namespace SourceGen.AsmGen {
/// </summary> /// </summary>
private CharEncoding.Encoding mCurrentEncoding; private CharEncoding.Encoding mCurrentEncoding;
/// <summary>
/// True if we defined macros for big-endian numeric values.
/// </summary>
private bool mBigEndianMacrosDefined;
private const string BIG_ENDIAN_16_MACRO = "bigendian";
/// <summary> /// <summary>
/// Output mode; determines how ORG is handled. /// Output mode; determines how ORG is handled.
/// </summary> /// </summary>
@@ -173,6 +179,8 @@ namespace SourceGen.AsmGen {
{ "StrDci", ".shift" } { "StrDci", ".shift" }
}); });
private const string MACRO_DIRECTIVE = ".macro";
// IGenerator // IGenerator
public void GetDefaultDisplayFormat(out PseudoOp.PseudoOpNames pseudoOps, public void GetDefaultDisplayFormat(out PseudoOp.PseudoOpNames pseudoOps,
@@ -355,7 +363,7 @@ namespace SourceGen.AsmGen {
// need that. // need that.
mCurrentEncoding = CharEncoding.Encoding.C64Petscii; mCurrentEncoding = CharEncoding.Encoding.C64Petscii;
CheckAsciiFormats(out bool hasAscii, out bool hasHighAscii); ScanFormats(out bool hasAscii, out bool hasHighAscii, out bool hasBigEndian);
if (hasHighAscii) { if (hasHighAscii) {
OutputLine(string.Empty, ".enc", '"' + HIGH_ASCII_ENC_NAME + '"', string.Empty); OutputLine(string.Empty, ".enc", '"' + HIGH_ASCII_ENC_NAME + '"', string.Empty);
OutputLine(string.Empty, ".cdef", "$20,$7e,$a0", string.Empty); OutputLine(string.Empty, ".cdef", "$20,$7e,$a0", string.Empty);
@@ -366,11 +374,17 @@ namespace SourceGen.AsmGen {
OutputLine(string.Empty, ".cdef", "$20,$7e,$20", string.Empty); OutputLine(string.Empty, ".cdef", "$20,$7e,$20", string.Empty);
mCurrentEncoding = CharEncoding.Encoding.Ascii; mCurrentEncoding = CharEncoding.Encoding.Ascii;
} }
if (hasBigEndian) {
OutputLine(BIG_ENDIAN_16_MACRO, MACRO_DIRECTIVE, string.Empty, string.Empty);
OutputLine(string.Empty, ".byte", "(\\1)>>8,(\\1)&$ff", string.Empty);
OutputLine(string.Empty, ".endmacro", string.Empty, string.Empty);
mBigEndianMacrosDefined = true;
}
} }
private void CheckAsciiFormats(out bool hasAscii, out bool hasHighAscii) { private void ScanFormats(out bool hasAscii, out bool hasHighAscii, out bool hasBigEndian) {
int offset = 0; int offset = 0;
hasAscii = hasHighAscii = false; hasAscii = hasHighAscii = hasBigEndian = false;
while (offset < Project.FileData.Length) { while (offset < Project.FileData.Length) {
Anattrib attr = Project.GetAnattrib(offset); Anattrib attr = Project.GetAnattrib(offset);
FormatDescriptor dfd = attr.DataDescriptor; FormatDescriptor dfd = attr.DataDescriptor;
@@ -380,9 +394,11 @@ namespace SourceGen.AsmGen {
hasAscii = true; hasAscii = true;
} else if (dfd.FormatSubType == FormatDescriptor.SubType.HighAscii) { } else if (dfd.FormatSubType == FormatDescriptor.SubType.HighAscii) {
hasHighAscii = true; hasHighAscii = true;
} else if (dfd.FormatType == FormatDescriptor.Type.NumericBE) {
hasBigEndian = true;
} }
} }
if (hasAscii && hasHighAscii) { if (hasAscii && hasHighAscii && hasBigEndian) {
return; return;
} }
@@ -541,15 +557,20 @@ namespace SourceGen.AsmGen {
break; break;
case FormatDescriptor.Type.NumericBE: case FormatDescriptor.Type.NumericBE:
opcodeStr = sDataOpNames.GetDefineBigData(length); opcodeStr = sDataOpNames.GetDefineBigData(length);
if ((string.IsNullOrEmpty(opcodeStr))) { if (string.IsNullOrEmpty(opcodeStr) && length == 2) {
// Nothing defined, output as comma-separated single-byte values. // Special handling for 16-bit big-endian operands.
GenerateShortSequence(offset, length, out opcodeStr, out operandStr); Debug.Assert(mBigEndianMacrosDefined);
} else { opcodeStr = BIG_ENDIAN_16_MACRO;
}
if (!(string.IsNullOrEmpty(opcodeStr))) {
UpdateCharacterEncoding(dfd); UpdateCharacterEncoding(dfd);
operand = RawData.GetWord(data, offset, length, true); operand = RawData.GetWord(data, offset, length, true);
operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable, operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable,
Localizer.LabelMap, dfd, operand, length, Localizer.LabelMap, dfd, operand, length,
PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix); PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix);
} else {
// Nothing defined, output as comma-separated single-byte values.
GenerateShortSequence(offset, length, out opcodeStr, out operandStr);
} }
break; break;
case FormatDescriptor.Type.Fill: case FormatDescriptor.Type.Fill:
@@ -784,11 +805,13 @@ namespace SourceGen.AsmGen {
// IGenerator // IGenerator
public void OutputLine(string label, string opcode, string operand, string comment) { public void OutputLine(string label, string opcode, string operand, string comment) {
// Break the line if the label is long and it's not a .EQ/.VAR directive. // Break the line if the label is long and it's not a .EQ/.VAR/.MACRO directive.
if (!string.IsNullOrEmpty(label) && !string.IsNullOrEmpty(opcode) && if (!string.IsNullOrEmpty(label) && !string.IsNullOrEmpty(opcode) &&
!string.Equals(opcode, sDataOpNames.EquDirective, !string.Equals(opcode, sDataOpNames.EquDirective,
StringComparison.InvariantCultureIgnoreCase) && StringComparison.InvariantCultureIgnoreCase) &&
!string.Equals(opcode, sDataOpNames.VarDirective, !string.Equals(opcode, sDataOpNames.VarDirective,
StringComparison.InvariantCultureIgnoreCase) &&
!string.Equals(opcode, MACRO_DIRECTIVE,
StringComparison.InvariantCultureIgnoreCase)) { StringComparison.InvariantCultureIgnoreCase)) {
if (mLabelNewLine == GenCommon.LabelPlacement.PreferSeparateLine || if (mLabelNewLine == GenCommon.LabelPlacement.PreferSeparateLine ||
@@ -3,6 +3,9 @@
.cpu "6502" .cpu "6502"
.enc "sg_hiascii" .enc "sg_hiascii"
.cdef $20,$7e,$a0 .cdef $20,$7e,$a0
bigendian .macro
.byte (\1)>>8,(\1)&$ff
.endmacro
* = $1000 * = $1000
bit L1448 bit L1448
jsr L14A8 jsr L14A8
@@ -29,7 +32,7 @@
.long $112233 .long $112233
.dword $11223344 .dword $11223344
.byte $11 .byte $11
.byte $11,$22 bigendian $1122
.byte $11,$22,$33 .byte $11,$22,$33
.byte $11,$22,$33,$44 .byte $11,$22,$33,$44
.fill 2,$00 .fill 2,$00
@@ -4,6 +4,9 @@
.cdef $20,$7e,$a0 .cdef $20,$7e,$a0
.enc "sg_ascii" .enc "sg_ascii"
.cdef $20,$7e,$20 .cdef $20,$7e,$20
bigendian .macro
.byte (\1)>>8,(\1)&$ff
.endmacro
* = $1000 * = $1000
lda $01 lda $01
lda $0102 lda $0102
@@ -68,13 +71,13 @@ more_ascii .byte 'h'
.byte $80 .byte $80
.word skipdata .word skipdata
.long skipdata .long skipdata
.byte $10,$5d bigendian skipdata
.byte <more_ascii .byte <more_ascii
.byte >more_ascii .byte >more_ascii
.word more_ascii .word more_ascii
.long more_ascii .long more_ascii
.dword more_ascii .dword more_ascii
.byte $10,$81 bigendian more_ascii
.byte '[' .byte '['
.byte '{' .byte '{'
.byte '|' .byte '|'
@@ -107,8 +110,8 @@ L10A4 nop
.byte 255 .byte 255
.word 1 .word 1
.word 65534 .word 65534
.byte $00,$02 bigendian 2
.byte $ff,$fd bigendian 65533
.long 66051 .long 66051
.long 16776957 .long 16776957
.dword 16909060 .dword 16909060
@@ -3,6 +3,9 @@
.cpu "6502" .cpu "6502"
.enc "sg_ascii" .enc "sg_ascii"
.cdef $20,$7e,$20 .cdef $20,$7e,$20
bigendian .macro
.byte (\1)>>8,(\1)&$ff
.endmacro
BMI1 = $30 ;opcode mnemonic BMI1 = $30 ;opcode mnemonic
zip = $cd zip = $cd
absl = $1029 absl = $1029
@@ -51,7 +54,7 @@ start lda #zip
.word start >> 8 .word start >> 8
.word start+1 .word start+1
.word start >> 8 .word start >> 8
.byte $fe,$ed bigendian absh
.long zip .long zip
.long absh .long absh
.long absh >> 8 .long absh >> 8
@@ -3,6 +3,9 @@
.cpu "65816" .cpu "65816"
.enc "sg_ascii" .enc "sg_ascii"
.cdef $20,$7e,$20 .cdef $20,$7e,$20
bigendian .macro
.byte (\1)>>8,(\1)&$ff
.endmacro
BMI1 = $30 ;opcode mnemonic BMI1 = $30 ;opcode mnemonic
zip = $cd zip = $cd
absl = $1029 absl = $1029
@@ -103,7 +106,7 @@ start clc
.word 0+(start & $ffff)+1 .word 0+(start & $ffff)+1
.word start >> 8 .word start >> 8
.word start >> 16 .word start >> 16
.byte $fe,$ed bigendian absh
.long zip .long zip
.long absh .long absh
.long absh >> 8 .long absh >> 8
@@ -4,6 +4,9 @@
.cdef $20,$7e,$a0 .cdef $20,$7e,$a0
.enc "sg_ascii" .enc "sg_ascii"
.cdef $20,$7e,$20 .cdef $20,$7e,$20
bigendian .macro
.byte (\1)>>8,(\1)&$ff
.endmacro
* = $1000 * = $1000
lda #'A' lda #'A'
lda #'A' | $80 lda #'A' | $80
@@ -42,10 +45,13 @@
.word 'd' .word 'd'
.enc "screen" .enc "screen"
.word 'd' .word 'd'
.byte $00,$45 .enc "sg_ascii"
.byte $00,$c5 bigendian 'E'
.byte $00,$c5 bigendian 'E' | $80
.byte $00,$45 .enc "none"
bigendian 'E'
.enc "screen"
bigendian 'E'
.byte $80 .byte $80
.enc "sg_ascii" .enc "sg_ascii"
.text "low ASCII str" .text "low ASCII str"
@@ -4,6 +4,9 @@
.cdef $20,$7e,$a0 .cdef $20,$7e,$a0
.enc "sg_ascii" .enc "sg_ascii"
.cdef $20,$7e,$20 .cdef $20,$7e,$20
bigendian .macro
.byte (\1)>>8,(\1)&$ff
.endmacro
* = $1000 * = $1000
lda #'A' lda #'A'
lda #'A' | $80 lda #'A' | $80
@@ -42,10 +45,13 @@
.word 'd' .word 'd'
.enc "screen" .enc "screen"
.word 'd' .word 'd'
.byte $00,$45 .enc "sg_ascii"
.byte $00,$c5 bigendian 'E'
.byte $00,$c5 bigendian 'E' | $80
.byte $00,$45 .enc "none"
bigendian 'E'
.enc "screen"
bigendian 'E'
.byte $80 .byte $80
.enc "sg_ascii" .enc "sg_ascii"
.text "low ASCII str" .text "low ASCII str"
@@ -4,6 +4,9 @@
.cdef $20,$7e,$a0 .cdef $20,$7e,$a0
.enc "sg_ascii" .enc "sg_ascii"
.cdef $20,$7e,$20 .cdef $20,$7e,$20
bigendian .macro
.byte (\1)>>8,(\1)&$ff
.endmacro
* = $1000 * = $1000
lda #'A' lda #'A'
lda #'A' | $80 lda #'A' | $80
@@ -42,10 +45,13 @@
.word 'd' .word 'd'
.enc "screen" .enc "screen"
.word 'd' .word 'd'
.byte $00,$45 .enc "sg_ascii"
.byte $00,$c5 bigendian 'E'
.byte $00,$c5 bigendian 'E' | $80
.byte $00,$45 .enc "none"
bigendian 'E'
.enc "screen"
bigendian 'E'
.byte $80 .byte $80
.enc "sg_ascii" .enc "sg_ascii"
.text "low ASCII str" .text "low ASCII str"
@@ -3,6 +3,9 @@
.cdef $20,$7e,$a0 .cdef $20,$7e,$a0
.enc "sg_ascii" .enc "sg_ascii"
.cdef $20,$7e,$20 .cdef $20,$7e,$20
bigendian .macro
.byte (\1)>>8,(\1)&$ff
.endmacro
PrintInlineL1String = $011000 PrintInlineL1String = $011000
PrintInlineL2String = $012000 PrintInlineL2String = $012000
PrintInlineDciString = $013000 PrintInlineDciString = $013000
@@ -48,7 +51,7 @@ PrintInlineRev8String rts
PrintInlineNullString rts PrintInlineNullString rts
data01 .word 4386 data01 .word 4386
.byte $33,$44 bigendian $3344
.dword $88776655 .dword $88776655
.byte $99,$88,$77,$66 .byte $99,$88,$77,$66
.byte 'f' .byte 'f'