1
0
mirror of https://github.com/fadden/6502bench.git synced 2025-02-18 08:30:28 +00:00

Attempt to generate segment names for cc65

This worked, sort of.  The problem is that SourceGen will revert to
hex output in certain situations, such as a broken symbolic
reference.  There happens to be one in the ZIPPY example, and it's
on a relative branch.

The goal with the segment stuff is to allow cc65 to treat the
source as relocatable code.  In that context, a relative branch to
an absolute address doesn't make any sense, so the assembler reports
a range error.

We don't currently have a mechanism that guarantees no references
are broken (and no affordance for finding them), so we can't make
this mode the default yet.

Instead, we continue to use the generic config, but generate the
correct set of lines as comments.

(issue #39)
This commit is contained in:
Andy McFadden 2018-11-18 14:36:03 -08:00
parent 17f0faa845
commit 2065f4ef9e
43 changed files with 179 additions and 21 deletions

View File

@ -85,8 +85,20 @@ namespace SourceGen {
}
/// <summary>
/// Returns the address map entry index associated with the specified offset, or -1
/// if there is no address map entry there.
/// Returns the Nth entry in the address map.
/// </summary>
public AddressMapEntry this[int i] {
get { return mAddrList[i]; }
}
/// <summary>
/// Number of entries in the address map.
/// </summary>
public int Count { get { return mAddrList.Count; } }
/// <summary>
/// Returns the Address value of the address map entry associated with the specified
/// offset, or -1 if there is no address map entry there. The offset must match exactly.
/// </summary>
public int Get(int offset) {
foreach (AddressMapEntry ad in mAddrList) {
@ -97,6 +109,20 @@ namespace SourceGen {
return -1;
}
/// <summary>
/// Returns the index of the address map entry that contains the given offset.
/// We assume the offset is valid.
/// </summary>
private int IndexForOffset(int offset) {
for (int i = 1; i < mAddrList.Count; i++) {
if (mAddrList[i].Offset > offset) {
return i - 1;
}
}
return mAddrList.Count - 1;
}
/// <summary>
/// Adds, updates, or removes a map entry.
/// </summary>
@ -165,20 +191,6 @@ namespace SourceGen {
return false;
}
/// <summary>
/// Returns the index of the address map entry that contains the given offset.
/// We assume the offset is valid.
/// </summary>
private int IndexForOffset(int offset) {
for (int i = 1; i < mAddrList.Count; i++) {
if (mAddrList[i].Offset > offset) {
return i - 1;
}
}
return mAddrList.Count - 1;
}
/// <summary>
/// Returns true if the given address falls into the range spanned by the
/// address map entry.

View File

@ -253,10 +253,18 @@ namespace SourceGen.AsmGen {
sw.WriteLine("MEMORY {");
sw.WriteLine(" MAIN: file=%O, start=%S, size=65536;");
for (int i = 0; i < Project.AddrMap.Count; i++) {
AddressMap.AddressMapEntry ame = Project.AddrMap[i];
sw.WriteLine(string.Format("# MEM{0:D3}: file=%O, start=${1:x4}, size={2};",
i, ame.Addr, ame.Length));
}
sw.WriteLine("}");
sw.WriteLine("SEGMENTS {");
sw.WriteLine(" CODE: load=MAIN, type=rw;");
for (int i = 0; i < Project.AddrMap.Count; i++) {
sw.WriteLine(string.Format("# SEG{0:D3}: load=MEM{0:D3}, type=rw;", i));
}
sw.WriteLine("}");
sw.WriteLine("FEATURES {}");
@ -489,6 +497,22 @@ namespace SourceGen.AsmGen {
// IGenerator
public void OutputOrgDirective(int offset, int address) {
// Linear search for offset. List should be small, so this should be quick.
int index = 0;
foreach (AddressMap.AddressMapEntry ame in Project.AddrMap) {
if (ame.Offset == offset) {
break;
}
index++;
}
mLineBuilder.Clear();
TextUtil.AppendPaddedString(mLineBuilder, ";", mColumnWidths[0]);
TextUtil.AppendPaddedString(mLineBuilder, SourceFormatter.FormatPseudoOp(" .segment"),
mColumnWidths[1]);
mLineBuilder.AppendFormat("\"SEG{0:D3}\"", index);
OutputLine(mLineBuilder.ToString());
OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(sDataOpNames.OrgDirective),
SourceFormatter.FormatHexValue(address, 4), string.Empty);
}

View File

@ -447,11 +447,7 @@ namespace SourceGen.AsmGen {
// of a pair of ops (.logical <addr> to open, .here to end). Omitting the .here
// causes an error.
if (offset == 0) {
// Set the "compile offset", which determines where assembled code goes in the
// output file. This
//
// This is different from the "program counter", which determines how code is
// actually assembled.
// Set the "compile offset" to the initial address.
OutputLine("*", "=", SourceFormatter.FormatHexValue(Project.AddrMap.Get(0), 4),
string.Empty);
} else {

View File

@ -1,4 +1,5 @@
.setcpu "65816"
; .segment "SEG000"
.org $1000
.a8
.i8

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 1000-allops-value-65816
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=588;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,4 +1,5 @@
.setcpu "65816"
; .segment "SEG000"
.org $1000
.a8
.i8

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 1001-allops-zero-65816
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=588;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,4 +1,5 @@
.setcpu "65816"
; .segment "SEG000"
.org $1000
.a8
.i8

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 1002-embedded-instructions
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=101;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,4 +1,5 @@
.setcpu "65816"
; .segment "SEG000"
.org $1000
.a8
.i8

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 1003-flags-and-branches
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=298;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,4 +1,5 @@
.setcpu "65816"
; .segment "SEG000"
.org $1000
.a8
.i8

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 1004-data-recognition
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=196;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,4 +1,5 @@
.setcpu "6502X"
; .segment "SEG000"
.org $1000
jsr L1035
jsr L1038

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 2000-allops-value-6502
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=598;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,4 +1,5 @@
.setcpu "6502X"
; .segment "SEG000"
.org $1000
jsr L1035
jsr L1038

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 2001-allops-zero-6502
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=598;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,4 +1,5 @@
.setcpu "65C02"
; .segment "SEG000"
.org $1000
jsr L1014
jsr L108A

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 2002-allops-value-65C02
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=489;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,4 +1,5 @@
.setcpu "65C02"
; .segment "SEG000"
.org $1000
jsr L1014
jsr L108A

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 2003-allops-zero-65C02
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=489;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,5 +1,6 @@
;Project file was edited to get all big-endian data types.
.setcpu "6502"
; .segment "SEG000"
.org $1000
rts

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 2004-numeric-types
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=631;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,5 +1,6 @@
;Project file was edited to get zero-length strings and reverse DCI.
.setcpu "6502"
; .segment "SEG000"
.org $1000
rts

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 2005-string-types
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=3132;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,5 +1,6 @@
;Project file was edited for some ASCII operands.
.setcpu "65816"
; .segment "SEG000"
.org $1000
.a8
.i8

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 2006-operand-formats
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=125;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -9,6 +9,7 @@ absh = $feed
biggie = $123456
thirty2 = $12345678 ;32-bit constant test
; .segment "SEG000"
.org $012345
.a8
.i8
@ -123,6 +124,7 @@ skipdata: lda #biggie >> 16 -1
nextchunk: jml L1000_1
; .segment "SEG001"
.org $1000
L1000_1: nop
L1000: nop

View File

@ -1,9 +1,13 @@
# 6502bench SourceGen generated linker script for 2007-labels-and-symbols
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$12345, size=279;
# MEM001: file=%O, start=$1000, size=416;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
# SEG001: load=MEM001, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,4 +1,5 @@
.setcpu "65816"
; .segment "SEG000"
.org $1000
.a8
.i8
@ -9,6 +10,7 @@
jsr L1107
jmp L2000
; .segment "SEG001"
.org $1100
L1100: bit L1100
L1103: lda #$11
@ -17,6 +19,7 @@ L1107: ldy #$11
per L1103
bra L1103
; .segment "SEG002"
.org $1100
L1100_0: bit L1100_0
lda #$22
@ -25,6 +28,7 @@ L1105: ldx #$22
per L1105
jmp L1105
; .segment "SEG003"
.org $1100
L1100_1: bit L1100_1
lda #$33
@ -33,17 +37,20 @@ L1107_0: ldy #$33
per L1107_0
bra L1107_0
; .segment "SEG004"
.org $2000
L2000: bit L2000
beq $2018
bra L2020
; .segment "SEG005"
.org $2020
L2020: bit L2020
beq offend+1
brl L2080
offend: nop
; .segment "SEG006"
.org $2080
L2080: bit L2080
lda offend
@ -58,18 +65,22 @@ L2080: bit L2080
beq L2100
.byte $ad
; .segment "SEG007"
.org $2100
L2100: nop
nop
jmp L3000
; .segment "SEG008"
.org $2800
.byte $00
.byte $28
.res 14,$00
; .segment "SEG009"
.org $2820
.res 18,$00
; .segment "SEG010"
.org $3000
L3000: bit L3000
lda #$44
@ -79,6 +90,7 @@ L3000: bit L3000
ulabel: .byte $00
.byte $01
; .segment "SEG011"
.org $3100
L3100: .byte $02
@ -91,6 +103,7 @@ fwd: bit fwd
beq L3182
.byte $ea
.byte $ea
; .segment "SEG012"
.org $3180
.byte $00
.byte $01
@ -104,6 +117,7 @@ L3182: bit L3182
label1: .byte $ea
.byte $ea
; .segment "SEG013"
.org $3200
L3200: bit L3200
.byte $00

View File

@ -1,9 +1,37 @@
# 6502bench SourceGen generated linker script for 2008-address-changes
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=13;
# MEM001: file=%O, start=$1100, size=14;
# MEM002: file=%O, start=$1100, size=15;
# MEM003: file=%O, start=$1100, size=14;
# MEM004: file=%O, start=$2000, size=7;
# MEM005: file=%O, start=$2020, size=9;
# MEM006: file=%O, start=$2080, size=32;
# MEM007: file=%O, start=$2100, size=5;
# MEM008: file=%O, start=$2800, size=16;
# MEM009: file=%O, start=$2820, size=18;
# MEM010: file=%O, start=$3000, size=14;
# MEM011: file=%O, start=$3100, size=23;
# MEM012: file=%O, start=$3180, size=18;
# MEM013: file=%O, start=$3200, size=5;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
# SEG001: load=MEM001, type=rw;
# SEG002: load=MEM002, type=rw;
# SEG003: load=MEM003, type=rw;
# SEG004: load=MEM004, type=rw;
# SEG005: load=MEM005, type=rw;
# SEG006: load=MEM006, type=rw;
# SEG007: load=MEM007, type=rw;
# SEG008: load=MEM008, type=rw;
# SEG009: load=MEM009, type=rw;
# SEG010: load=MEM010, type=rw;
# SEG011: load=MEM011, type=rw;
# SEG012: load=MEM012, type=rw;
# SEG013: load=MEM013, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,6 +1,7 @@
.setcpu "65816"
longsym = $123456
; .segment "SEG000"
.org $1000
.a8
.i8
@ -9,6 +10,7 @@ longsym = $123456
sep #$30
jmp L0000
; .segment "SEG001"
.org $0000
L0000: bit a:L0000
L0003: lda L0000
@ -26,14 +28,17 @@ lodat: .byte $00
L0016: lda lodat+1
.byte $82,$a5,$ff
; .segment "SEG002"
.org $0080
L0080: bit a:L0080
jml L440000
; .segment "SEG003"
.org $ffc0
LFFC0: bit LFFC0
LFFC3: .byte $82,$3d,$00
; .segment "SEG004"
.org $440000
L440000: cmp L440000
L440004: lda L440000
@ -47,6 +52,7 @@ L440004: lda L440000
dat44: .word dat44 & $ffff
.faraddr dat44
; .segment "SEG005"
.org $44ffc0
L44FFC0: cmp L44FFC0
high44: beq L44FFCB
@ -55,6 +61,7 @@ high44: beq L44FFCB
L44FFCB: jml L2000
; .segment "SEG006"
.org $2000
L2000: bit L2000
pea dat44 & $ffff

View File

@ -1,9 +1,23 @@
# 6502bench SourceGen generated linker script for 2009-branches-and-banks
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=7;
# MEM001: file=%O, start=$0000, size=27;
# MEM002: file=%O, start=$0080, size=7;
# MEM003: file=%O, start=$ffc0, size=6;
# MEM004: file=%O, start=$440000, size=28;
# MEM005: file=%O, start=$44ffc0, size=15;
# MEM006: file=%O, start=$2000, size=29;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
# SEG001: load=MEM001, type=rw;
# SEG002: load=MEM002, type=rw;
# SEG003: load=MEM003, type=rw;
# SEG004: load=MEM004, type=rw;
# SEG005: load=MEM005, type=rw;
# SEG006: load=MEM006, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,4 +1,5 @@
.setcpu "65816"
; .segment "SEG000"
.org $1000
.a8
.i8
@ -48,6 +49,7 @@ L107A: sta L107A+1
.byte $80
dat81: .byte $81
; .segment "SEG001"
.org $2000
L2000: .byte $82
.byte $83

View File

@ -1,9 +1,13 @@
# 6502bench SourceGen generated linker script for 2010-target-adjustment
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=133;
# MEM001: file=%O, start=$2000, size=12;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
# SEG001: load=MEM001, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,4 +1,5 @@
.setcpu "6502"
; .segment "SEG000"
.org $1000
.byte $03
.byte $02

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 2011-hinting
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=63;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,6 +1,7 @@
.setcpu "65816"
REALLYLONGLABELNAME = $8888 ;that's a long name
; .segment "SEG000"
.org $1000
.a8
.i8

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 2012-label-localizer
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=87;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -19,6 +19,7 @@ plataddr = $3000 ;address only in platform file
;Short, unboxed comment here!!
; Two spaces after. More hyp-
;hens?
; .segment "SEG000"
.org $1000
lda #$01 ;Comment!
;Comment rulers can be helpful in findin the edges of notes. Comments are hyph-

View File

@ -1,9 +1,11 @@
# 6502bench SourceGen generated linker script for 2013-notes-and-comments
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=98;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
}
FEATURES {}
SYMBOLS {}

View File

@ -1,5 +1,6 @@
;6502bench SourceGen v1.1.0-dev1
.setcpu "65816"
; .segment "SEG000"
.org $1000
.a8
.i8
@ -284,6 +285,7 @@ L122A: sbc (L0080),y
sbc a:L0086,x
inc a:L0086,x
sbc f:L0089,x
; .segment "SEG001"
.org $0080
L0080: bit z:L0082
L0082: bit L0082

View File

@ -1,9 +1,13 @@
# 6502bench SourceGen generated linker script for 2014-label-dp
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=588;
# MEM001: file=%O, start=$0080, size=13;
}
SEGMENTS {
CODE: load=MAIN, type=rw;
# SEG000: load=MEM000, type=rw;
# SEG001: load=MEM001, type=rw;
}
FEATURES {}
SYMBOLS {}