1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-12-01 07:50:37 +00:00

Add 20212-reloc-data test

This test exercises the relocation data feature.  The test file is
generated from a multi-segment OMF file that was hex-edited to have
specific attributes (see 20212-reloc-data-lnk.S for instructions).
The test also serves as a way to exercise the OMF converter.

Also, implement the Bank Relative flag.
This commit is contained in:
Andy McFadden 2020-07-05 17:17:44 -07:00
parent 4782cae116
commit 4e70edc90c
16 changed files with 1013 additions and 5 deletions

View File

@ -165,6 +165,8 @@ namespace SourceGen {
// Check for a relocation. It'll be at offset+1 because it's on the operand, // Check for a relocation. It'll be at offset+1 because it's on the operand,
// not the opcode byte. (Make sure to check the length, or an RTS followed // not the opcode byte. (Make sure to check the length, or an RTS followed
// by relocated data will freak out.) // by relocated data will freak out.)
// TODO(someday): this won't get the second byte of an MVN/MVP, which is fine
// since we don't currently support two formats on one instruction.
if (mAnalysisParams.UseRelocData) { if (mAnalysisParams.UseRelocData) {
if (attr.Length > 1 && mProject.RelocList.TryGetValue(offset + 1, if (attr.Length > 1 && mProject.RelocList.TryGetValue(offset + 1,
out DisasmProject.RelocData reloc)) { out DisasmProject.RelocData reloc)) {

View File

@ -130,7 +130,7 @@ limitations under the License.
<system:String x:Key="str_MsgVisualizationIgnored">Visualization ignored</system:String> <system:String x:Key="str_MsgVisualizationIgnored">Visualization ignored</system:String>
<system:String x:Key="str_NoFilesAvailable">no files available</system:String> <system:String x:Key="str_NoFilesAvailable">no files available</system:String>
<system:String x:Key="str_NoExportedSymbolsFound">No exported symbols found.</system:String> <system:String x:Key="str_NoExportedSymbolsFound">No exported symbols found.</system:String>
<system:String x:Key="str_OmfSegCommentFmt">Segment {0:D2}: Kind={1}, Attrs={2}, Name='{3}'</system:String> <system:String x:Key="str_OmfSegCommentFmt">Segment {0:D2}: Kind={1}; Attrs={2}; Name='{3}'</system:String>
<system:String x:Key="str_OmfSegHdrCommentFmt">Segment {0:D2}: {3} {1,-9} Name='{2}', Length={4}</system:String> <system:String x:Key="str_OmfSegHdrCommentFmt">Segment {0:D2}: {3} {1,-9} Name='{2}', Length={4}</system:String>
<system:String x:Key="str_OmfSegNoteFmt">Seg{0:D2}: {1} '{2}'</system:String> <system:String x:Key="str_OmfSegNoteFmt">Seg{0:D2}: {1} '{2}'</system:String>
<system:String x:Key="str_OpenDataDoesntExist">The file doesn't exist.</system:String> <system:String x:Key="str_OpenDataDoesntExist">The file doesn't exist.</system:String>

Binary file not shown.

View File

@ -0,0 +1,326 @@
### 6502bench SourceGen dis65 v1.0 ###
{
"_ContentVersion":4,
"FileDataLength":255,
"FileDataCrc32":-527039020,
"ProjectProps":{
"CpuName":"65816",
"IncludeUndocumentedInstr":false,
"TwoByteBrk":false,
"EntryFlags":12780031,
"AutoLabelStyle":"Simple",
"AnalysisParams":{
"AnalyzeUncategorizedData":true,
"DefaultTextScanMode":"LowHighAscii",
"MinCharsForString":4,
"SeekNearbyTargets":true,
"UseRelocData":true,
"SmartPlpHandling":true},
"PlatformSymbolFileIdentifiers":["RT:Apple/Cxxx-IO.sym65",
"RT:Apple/IIgs-ROM.sym65",
"RT:Apple/GSOS.sym65"],
"ExtensionScriptFileIdentifiers":["RT:Apple/GSOS.cs",
"RT:Apple/IIgs-Toolbox.cs"],
"ProjectSyms":{
}},
"AddressMap":[{
"Offset":0,
"Addr":196608},
{
"Offset":110,
"Addr":327648},
{
"Offset":142,
"Addr":327680},
{
"Offset":162,
"Addr":144470},
{
"Offset":188,
"Addr":524288},
{
"Offset":242,
"Addr":393216}],
"TypeHints":[{
"Low":0,
"High":0,
"Hint":"Code"}],
"StatusFlagOverrides":{
},
"Comments":{
},
"LongComments":{
"0":{
"Text":"Segment 02: Kind=Code; Attrs=NoSpecial; Name=\u0027 \u0027",
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0},
"110":{
"Text":"Segment 03: Kind=Data; Attrs=BankRel, Dynamic; Name=\u0027PosFFE0 \u0027",
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0},
"162":{
"Text":"Segment 04: Kind=Code; Attrs=NoSpecial; Name=\u0027Bank2 \u0027",
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0},
"188":{
"Text":"Segment 05: Kind=Code; Attrs=AbsBank, Dynamic; Name=\u0027Bank8 \u0027",
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0},
"242":{
"Text":"Segment 06: Kind=Data; Attrs=0; Name=\u0027Filler \u0027",
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0}},
"Notes":{
"0":{
"Text":"Seg02: 03/0000 \u0027 \u0027",
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0},
"110":{
"Text":"Seg03: 04/ffe0 \u0027PosFFE0 \u0027",
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0},
"162":{
"Text":"Seg04: 02/3456 \u0027Bank2 \u0027",
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0},
"188":{
"Text":"Seg05: 08/0000 \u0027Bank8 \u0027",
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0},
"242":{
"Text":"Seg06: 06/0000 \u0027Filler \u0027",
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0}},
"UserLabels":{
},
"OperandFormats":{
},
"LvTables":{
},
"Visualizations":[],
"VisualizationAnimations":[],
"VisualizationSets":{
},
"RelocList":{
"82":{
"Width":2,
"Shift":0,
"Value":196677},
"91":{
"Width":2,
"Shift":0,
"Value":196695},
"94":{
"Width":2,
"Shift":0,
"Value":200773},
"98":{
"Width":2,
"Shift":0,
"Value":196717},
"5":{
"Width":3,
"Shift":0,
"Value":196608},
"85":{
"Width":2,
"Shift":-8,
"Value":196677},
"88":{
"Width":1,
"Shift":-16,
"Value":196677},
"10":{
"Width":3,
"Shift":0,
"Value":144470},
"14":{
"Width":3,
"Shift":0,
"Value":524288},
"18":{
"Width":3,
"Shift":0,
"Value":144470},
"31":{
"Width":3,
"Shift":0,
"Value":524313},
"102":{
"Width":3,
"Shift":0,
"Value":327648},
"105":{
"Width":3,
"Shift":0,
"Value":327648},
"100":{
"Width":2,
"Shift":0,
"Value":327648},
"22":{
"Width":2,
"Shift":0,
"Value":144470},
"63":{
"Width":2,
"Shift":0,
"Value":144478},
"35":{
"Width":2,
"Shift":0,
"Value":524313},
"47":{
"Width":2,
"Shift":0,
"Value":524313},
"60":{
"Width":2,
"Shift":0,
"Value":524326},
"76":{
"Width":2,
"Shift":0,
"Value":524313},
"25":{
"Width":1,
"Shift":0,
"Value":144470},
"27":{
"Width":1,
"Shift":-8,
"Value":144470},
"29":{
"Width":1,
"Shift":-16,
"Value":144470},
"38":{
"Width":1,
"Shift":0,
"Value":524313},
"40":{
"Width":1,
"Shift":-8,
"Value":524313},
"42":{
"Width":1,
"Shift":-16,
"Value":524313},
"50":{
"Width":2,
"Shift":-8,
"Value":524313},
"53":{
"Width":1,
"Shift":-16,
"Value":524313},
"66":{
"Width":1,
"Shift":-16,
"Value":144478},
"67":{
"Width":1,
"Shift":-16,
"Value":524326},
"79":{
"Width":1,
"Shift":-16,
"Value":524313},
"110":{
"Width":3,
"Shift":0,
"Value":327648},
"167":{
"Width":2,
"Shift":0,
"Value":144494},
"163":{
"Width":3,
"Shift":0,
"Value":144470},
"193":{
"Width":2,
"Shift":0,
"Value":524313},
"189":{
"Width":3,
"Shift":0,
"Value":524288},
"213":{
"Width":3,
"Shift":0,
"Value":524313},
"217":{
"Width":3,
"Shift":0,
"Value":144470}}}

View File

@ -0,0 +1,140 @@
.cpu "65816"
.enc "sg_ascii"
.cdef $20,$7e,$20
;Segment 02: Kind=Code; Attrs=NoSpecial; Name=' '
* = $030000
.al
.xl
L30000 clc
xce
.as
.xs
sep #$30
lda L30000
nop
jsl _L23456
jsl _L80000
lda _L23456
lda _L23456 & $ffff
lda #<_L23456
lda #>_L23456
lda #`_L23456
lda _L80019
lda @w_L80019 & $ffff
lda #<_L80019
lda #>_L80019
lda #`_L80019
nop
rep #$30
.al
.xl
lda #_L80019 & $ffff
lda #_L80019 >> 8
lda #_L80019 >> 16
nop
lda #$000f
ldx #_L80026 & $ffff
ldy #_L2345E & $ffff
mvn #(`_L2345E)+6,#`_L2345E
nop
_L30045 pea $0000
pea $f000
pea _L80019 & $ffff
pea _L80019 >> 16
pea _L30045 & $ffff
pea _L30045 >> 8
_L30057 pea _L30045 >> 16
pea _L30057 & $ffff
pea $1045
nop
jmp _L3006D
.word _L4FFE0 & $ffff
.long _L4FFE0
.long _L4FFE0
.byte $00
_L3006D rts
;Segment 03: Kind=Data; Attrs=BankRel, Dynamic; Name='PosFFE0 '
.logical $04ffe0
_L4FFE0 .long _L4FFE0
.byte $00
.byte $00
.byte $01
.byte $02
.byte $03
.byte $04
.byte $05
.byte $06
.byte $07
.byte $08
.byte $09
.byte $0a
.byte $0b
.byte $0c
.byte $0d
.byte $0e
.byte $0f
.byte $10
.byte $11
.byte $12
.byte $13
.byte $14
.byte $15
.byte $16
.byte $17
.byte $18
.byte $19
.byte $1a
.byte $1b
.here
.logical $050000
.byte $1c
.byte $1d
.byte $1e
.byte $1f
.text " !",$22,"#$%&'()*+,-./"
;Segment 04: Kind=Code; Attrs=NoSpecial; Name='Bank2 '
.here
.logical $023456
.as
.xs
_L23456 lda _L23456
jsr _L2346E
rtl
_L2345E .fill 16,$00
_L2346E nop
rts
;Segment 05: Kind=Code; Attrs=AbsBank, Dynamic; Name='Bank8 '
.here
.logical $080000
_L80000 lda _L80000
lda @w_L80019 & $ffff
nop
lda $010000
lda $020000
lda L30000
lda _L80000
rtl
_L80019 .long _L80019
.byte $00
.long _L23456
.byte $00
.byte $80
.byte $00
.byte $10
.byte $08
.byte $00
_L80026 .text "This is a test."
.byte $00
;Segment 06: Kind=Data; Attrs=0; Name='Filler '
.here
.logical $060000
.text "hello, world!"
.here

View File

@ -0,0 +1,128 @@
;Segment 02: Kind=Code; Attrs=NoSpecial; Name=' '
org $030000
mx %00
L30000 clc
xce
mx %11
sep #$30
ldal L30000
nop
jsl :L23456
jsl :L80000
ldal :L23456
lda :L23456
lda #<:L23456
lda #>:L23456
lda #^:L23456
ldal :L80019
lda: :L80019
lda #<:L80019
lda #>:L80019
lda #^:L80019
nop
rep #$30
mx %00
lda #:L80019
lda #>:L80019
lda #^:L80019
nop
lda #$000f
ldx #:L80026
ldy #:L2345E
mvn #^:L2345E+$60000,#^:L2345E
nop
:L30045 pea $0000
pea $f000
pea :L80019
pea ^:L80019
pea :L30045
pea >:L30045
:L30057 pea ^:L30045
pea :L30057
pea $1045
nop
jmp :L3006D
dw :L4FFE0
adr :L4FFE0
adr :L4FFE0
dfb $00
:L3006D rts
;Segment 03: Kind=Data; Attrs=BankRel, Dynamic; Name='PosFFE0 '
org $04ffe0
:L4FFE0 adr :L4FFE0
dfb $00
dfb $00
dfb $01
dfb $02
dfb $03
dfb $04
dfb $05
dfb $06
dfb $07
dfb $08
dfb $09
dfb $0a
dfb $0b
dfb $0c
dfb $0d
dfb $0e
dfb $0f
dfb $10
dfb $11
dfb $12
dfb $13
dfb $14
dfb $15
dfb $16
dfb $17
dfb $18
dfb $19
dfb $1a
dfb $1b
org $050000
dfb $1c
dfb $1d
dfb $1e
dfb $1f
asc ' !"#$%&',27,'()*+,-./'
;Segment 04: Kind=Code; Attrs=NoSpecial; Name='Bank2 '
org $023456
mx %11
:L23456 ldal :L23456
jsr :L2346E
rtl
:L2345E ds 16
:L2346E nop
rts
;Segment 05: Kind=Code; Attrs=AbsBank, Dynamic; Name='Bank8 '
org $080000
:L80000 ldal :L80000
lda: :L80019
nop
ldal $010000
ldal $020000
ldal L30000
ldal :L80000
rtl
:L80019 adr :L80019
dfb $00
adr :L23456
dfb $00
dfb $80
dfb $00
dfb $10
dfb $08
dfb $00
:L80026 asc 'This is a test.'
dfb $00
;Segment 06: Kind=Data; Attrs=0; Name='Filler '
org $060000
asc 'hello, world!'

View File

@ -0,0 +1,12 @@
;ACME can't handle 65816 code that lives outside bank zero
* = $0000
!pseudopc $030000 {
!hex 18fbe230af000003ea2256340222000008af563402ad5634a956a934a902af19
!hex 0008ad1900a919a900a908eac230a91900a90008a90800eaa90f00a22600a05e
!hex 34540208eaf40000f400f0f41900f40800f44500f40003f40300f45700f44510
!hex ea4c6d00e0ffe0ff04e0ff040060e0ff0400000102030405060708090a0b0c0d
!hex 0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d
!hex 2e2faf563402206e346b00000000000000000000000000000000ea60af000008
!hex ad1900eaaf000001af000002af000003af0000086b1900080056340200800010
!hex 080054686973206973206120746573742e0068656c6c6f2c20776f726c6421
} ;!pseudopc

View File

@ -0,0 +1,139 @@
.setcpu "65816"
;Segment 02: Kind=Code; Attrs=NoSpecial; Name=' '
; .segment "SEG000"
.org $030000
.a16
.i16
L30000: clc
xce
.a8
.i8
sep #$30
lda L30000
nop
jsl @L23456
jsl @L80000
lda f:@L23456
lda @L23456 & $ffff
lda #<@L23456
lda #>@L23456
lda #^@L23456
lda f:@L80019
lda a:@L80019 & $ffff
lda #<@L80019
lda #>@L80019
lda #^@L80019
nop
rep #$30
.a16
.i16
lda #@L80019 & $ffff
lda #@L80019 >> 8
lda #@L80019 >> 16
nop
lda #$000f
ldx #@L80026 & $ffff
ldy #@L2345E & $ffff
mvn #^@L2345E+6,#^@L2345E
nop
@L30045: pea $0000
pea $f000
pea @L80019 & $ffff
pea @L80019 >> 16
pea @L30045 & $ffff
pea @L30045 >> 8
@L30057: pea @L30045 >> 16
pea @L30057 & $ffff
pea $1045
nop
jmp @L3006D & $ffff
.word @L4FFE0 & $ffff
.faraddr @L4FFE0
.faraddr @L4FFE0
.byte $00
@L3006D: rts
;Segment 03: Kind=Data; Attrs=BankRel, Dynamic; Name='PosFFE0 '
; .segment "SEG001"
.org $04ffe0
@L4FFE0: .faraddr @L4FFE0
.byte $00
.byte $00
.byte $01
.byte $02
.byte $03
.byte $04
.byte $05
.byte $06
.byte $07
.byte $08
.byte $09
.byte $0a
.byte $0b
.byte $0c
.byte $0d
.byte $0e
.byte $0f
.byte $10
.byte $11
.byte $12
.byte $13
.byte $14
.byte $15
.byte $16
.byte $17
.byte $18
.byte $19
.byte $1a
.byte $1b
; .segment "SEG002"
.org $050000
.byte $1c
.byte $1d
.byte $1e
.byte $1f
.byte " !",$22,"#$%&'()*+,-./"
;Segment 04: Kind=Code; Attrs=NoSpecial; Name='Bank2 '
; .segment "SEG003"
.org $023456
.a8
.i8
@L23456: lda @L23456
jsr @L2346E & $ffff
rtl
@L2345E: .res 16,$00
@L2346E: nop
rts
;Segment 05: Kind=Code; Attrs=AbsBank, Dynamic; Name='Bank8 '
; .segment "SEG004"
.org $080000
@L80000: lda @L80000
lda a:@L80019 & $ffff
nop
lda $010000
lda $020000
lda L30000
lda @L80000
rtl
@L80019: .faraddr @L80019
.byte $00
.faraddr @L23456
.byte $00
.byte $80
.byte $00
.byte $10
.byte $08
.byte $00
@L80026: .byte "This is a test."
.byte $00
;Segment 06: Kind=Data; Attrs=0; Name='Filler '
; .segment "SEG005"
.org $060000
.byte "hello, world!"

View File

@ -0,0 +1,21 @@
# 6502bench SourceGen generated linker script for 20212-reloc-data
MEMORY {
MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$30000, size=110;
# MEM001: file=%O, start=$4ffe0, size=32;
# MEM002: file=%O, start=$50000, size=20;
# MEM003: file=%O, start=$23456, size=26;
# MEM004: file=%O, start=$80000, size=54;
# MEM005: file=%O, start=$60000, size=13;
}
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;
}
FEATURES {}
SYMBOLS {}

View File

@ -0,0 +1,17 @@
; Copyright 2020 faddenSoft. All Rights Reserved.
; See the LICENSE.txt file for distribution terms (Apache 2.0).
;
; Segment #3 : code, load at specific address ($02/3456)
REL ;generate relocatable code
BANK2_START ENT
start ldal start
jsr later
rtl
BANK2_MOV_DST ENT
ds 16
later nop
rts

View File

@ -0,0 +1,30 @@
; Copyright 2020 faddenSoft. All Rights Reserved.
; See the LICENSE.txt file for distribution terms (Apache 2.0).
;
; Assembler: Merlin 32
;
; Segment #4 : code, loads somewhere in bank 8
REL ;generate relocatable code
BANK2_START EXT
BANK8_START ENT
start ldal start
lda addr
nop
ldal $010000
ldal $020000
ldal $030000
ldal $080000
rtl
BANK8_ADDR ENT
addr
adrl addr
adrl BANK2_START
dfb $80
adrl $081000
BANK8_MOV_SRC ENT
asc 'This is a test.',$00

View File

@ -0,0 +1,11 @@
; Copyright 2020 faddenSoft. All Rights Reserved.
; See the LICENSE.txt file for distribution terms (Apache 2.0).
;
; Assembler: Merlin 32
;
; Segment #5 : filler
REL ;generate relocatable code
asc 'hello, world!'

View File

@ -0,0 +1,60 @@
; Copyright 2020 faddenSoft. All Rights Reserved.
; See the LICENSE.txt file for distribution terms (Apache 2.0).
;
; Merlin 32 link file.
;
; According to the documentation we can use ORG directives to set the segment
; load addresses, but in practice Merlin 32 rejects them. Also, DS
; directives are ignored, and KND uses a different default value than
; what the documentation says.
;
; cf. https://github.com/apple2accumulator/merlin32/issues/39
;
; Instructions:
; - Assemble this file with Merlin32. It will pull everything in.
; - Open out.20212 with the segment viewer and find the start offsets
; of the segments. Set the ORG field with a hex editor. It's a
; 4-byte field at +$18. (Easy way in a v2.0 header: find the start
; of the SEGNAME and back up $1e bytes.)
; "PosFFE0" -> E0 FF 00
; "Bank2" -> 56 34 02
; "Bank8" -> 00 10 08
; - Convert out.20212 to "20212-reloc-data" with OMF converter.
; - The project file generally requires no edits, except to delete the
; header comment. Leaving the segment-start comments in seems fine.
DSK out.20212 ;output file name, must be ProDOS-compat
TYP $b3 ;S16
XPL ;add ~ExpressLoad
; Segment #1
ASM 20212-reloc-data-main.S
KND $1000 ;Code; NoSpec
; SNA <default>
; Segment #2
ASM 20212-reloc-data-relover.S
KND $8101 ;Data; Dynamic, BankRel
ALI None
; BSZ 0
; ORG $00ffe0 ;load in any bank, at $ffe0
SNA PosFFE0
; Segment #3
ASM 20212-reloc-data-bank2.S
KND $1000
DS 256
; ORG $023456 ;load exactly here
SNA Bank2
; Segment #4
ASM 20212-reloc-data-bank8.S
KND $8800 ;Code; Dynamic, AbsBank
; ORG $081000 ;load in bank 8, at any address
SNA Bank8
; Segment #5
ASM 20212-reloc-data-filler.S
KND $0001 ;Data
SNA Filler

View File

@ -0,0 +1,80 @@
; Copyright 2020 faddenSoft. All Rights Reserved.
; See the LICENSE.txt file for distribution terms (Apache 2.0).
;
; Assembler: Merlin 32
;
; Segment #1 : code; main segment, loads anywhere
BANK2_START EXT
BANK2_MOV_DST EXT
BANK8_START EXT
BANK8_ADDR EXT
BANK8_MOV_SRC EXT
ADDR_FFE0 EXT
REL ;generate relocatable code
start
clc
xce
sep #$30
mx %11
ldal start
nop
jsl BANK2_START
jsl BANK8_START
ldal BANK2_START
lda BANK2_START
lda #<BANK2_START
lda #>BANK2_START
lda #^BANK2_START
ldal BANK8_ADDR
lda BANK8_ADDR
lda #<BANK8_ADDR
lda #>BANK8_ADDR
lda #^BANK8_ADDR
nop
; Do some stuff with 16-bit registers. Merlin 32 treats <>^ as shift
; operations rather than byte selectors.
rep #$30
mx %00
lda #<BANK8_ADDR
lda #>BANK8_ADDR
lda #^BANK8_ADDR
nop
; Check MVN/MVP. Handing them correctly requires having two different
; symbol refs on a single instruction.
lda #15
ldx #BANK8_MOV_SRC
ldy #BANK2_MOV_DST
mvn #^BANK8_MOV_SRC,#^BANK2_MOV_DST
nop
check_pea
pea $0000
pea $f000
pea BANK8_ADDR
pea ^BANK8_ADDR
pea check_pea
pea >check_pea
pea ^check_pea
pea check_pea+18
pea check_pea+$1000
nop
jmp :skipdata
; Generate 2/3/4-byte refs. The OMF reloc entry generated by Merlin32
; for ADRL is only 3 bytes wide.
dw ADDR_FFE0
adr ADDR_FFE0
adrl ADDR_FFE0
:skipdata
rts

View File

@ -0,0 +1,15 @@
; Copyright 2020 faddenSoft. All Rights Reserved.
; See the LICENSE.txt file for distribution terms (Apache 2.0).
;
; Assembler: Merlin 32
;
; Segment #2 : data, loads at $FFE0 in arbitrary bank and overflows
REL ;generate relocatable code
ADDR_FFE0 ENT
start adrl start
hex 000102030405060708090a0b0c0d0e0f
hex 101112131415161718191a1b1c1d1e1f
hex 202122232425262728292a2b2c2d2e2f

View File

@ -157,6 +157,9 @@ namespace SourceGen.Tools.Omf {
// would mean you can't set the "absolute bank" flag to position code or // would mean you can't set the "absolute bank" flag to position code or
// data in bank 0. I'm going to assume that's intentional, since people // data in bank 0. I'm going to assume that's intentional, since people
// (a) shouldn't be doing that, and (b) can use DP/Stack instead (?). // (a) shouldn't be doing that, and (b) can use DP/Stack instead (?).
//
// It also means that "bank relative" can't be used to set the position
// to zero, which is probably fine since you can do that with ALIGN=$10000.
continue; continue;
} }
@ -195,15 +198,30 @@ namespace SourceGen.Tools.Omf {
int addr; int addr;
if (omfSeg.Org != 0) { // We want to put the segment at a specific offset in an arbitrary bank
// Specific address requested. // if ORG is nonzero, the BankRel flag is set, and the AbsBank flag is clear.
bool bankRel = omfSeg.Org != 0 &&
(omfSeg.Attrs & OmfSegment.SegmentAttribute.BankRel) != 0 &&
(omfSeg.Attrs & OmfSegment.SegmentAttribute.AbsBank) == 0;
// We want to put the segment at an arbitrary offset in a specific bank
// if ORG is nonzero, the BankRel flag is clear, and the AbsBank flag is set.
bool fixedBank = omfSeg.Org != 0 &&
(omfSeg.Attrs & OmfSegment.SegmentAttribute.BankRel) == 0 &&
(omfSeg.Attrs & OmfSegment.SegmentAttribute.AbsBank) != 0;
// We want to put the segment at a specific offset and bank
// if ORG is nonzero, and BankRel and FixedBank are either both set or
// both clear.
bool fixedAddr = omfSeg.Org != 0 && (bankRel ^ fixedBank) == false;
if (fixedAddr || fixedBank) {
// Specific bank requested.
addr = omfSeg.Org; addr = omfSeg.Org;
if ((omfSeg.Attrs & OmfSegment.SegmentAttribute.AbsBank) != 0) { if ((omfSeg.Attrs & OmfSegment.SegmentAttribute.AbsBank) != 0) {
// just keep the bank // just keep the bank
addr &= 0x00ff0000; addr &= 0x00ff0000;
} }
} else { } else {
// Find next available spot with enough space. // Find next available bank with enough space.
while (true) { while (true) {
while (nextBank < 256 && inUse[nextBank]) { while (nextBank < 256 && inUse[nextBank]) {
nextBank++; nextBank++;
@ -225,11 +243,20 @@ namespace SourceGen.Tools.Omf {
} }
addr = nextBank << 16; addr = nextBank << 16;
if (bankRel) {
// TODO(maybe): reject if incompatible with BANKSIZE
addr |= omfSeg.Org & 0x0000ffff;
}
// Advance nextBank. We do this by identifying the last address touched, // Advance nextBank. We do this by identifying the last address touched,
// and moving to the next bank. // then incrementing the bank number.
int lastAddr = addr + omfSeg.Length - 1; int lastAddr = addr + omfSeg.Length - 1;
nextBank = (lastAddr >> 16) + 1; nextBank = (lastAddr >> 16) + 1;
if (nextBank >= 0x0100) {
// Overflowed the 65816 address space.
Debug.WriteLine("Bank exceeded $ff");
return false;
}
} }
SegmentMapEntry ent = new SegmentMapEntry(omfSeg, addr); SegmentMapEntry ent = new SegmentMapEntry(omfSeg, addr);