aboutsummaryrefslogtreecommitdiff
path: root/reloc.s
diff options
context:
space:
mode:
Diffstat (limited to 'reloc.s')
-rw-r--r--reloc.s97
1 files changed, 45 insertions, 52 deletions
diff --git a/reloc.s b/reloc.s
index c4c3c58..3702430 100644
--- a/reloc.s
+++ b/reloc.s
@@ -11,13 +11,11 @@
code_init = end_addr+6
table = end_addr+8
- zp_addr = FR0
- offset_lo = zp_addr
- offset_hi = zp_addr+1
- table_ptr = zp_addr+2 ; 2 bytes
- dest_ptr = table_ptr
- code_ptr = zp_addr+4 ; 2 bytes
- fixup = zp_addr+6
+ zp_addr = FR0
+ offset_pages = zp_addr ; 1 byte
+ table_ptr = zp_addr+1 ; 2 bytes
+ dest_ptr = table_ptr ; alias
+ code_ptr = zp_addr+3 ; 2 bytes
.org start_addr - 6
.word $ffff
@@ -25,14 +23,19 @@
.word end_addr - 1
_main:
- lda code_start
- sec
- sbc MEMLO
+ ; if MEMLO isn't on a page boundary, move it up to the next
+ ; page, e.g. $1cfc => $1d00.
+ lda MEMLO
+ beq memlo_00
+ inc MEMLO+1
+ lda #0
+ sta MEMLO
+memlo_00:
- sta offset_lo
lda code_start+1
+ sec
sbc MEMLO+1
- sta offset_hi
+ sta offset_pages
bcs memlo_ok
@@ -60,19 +63,37 @@ exitwait:
rts
memlo_ok:
- ; 1st fixup pass, hi bytes: table comes right after our code
- sta fixup
+ ; adjust addresses before moving the code
lda #<table
sta table_ptr
lda #>table
sta table_ptr+1
- jsr fixup_addrs
-
- ; 2nd fixup pass, lo bytes: table_ptr already points to table
- lda offset_lo
- sta fixup
- jsr fixup_addrs
+fixup_addrs:
+ ldy #1
+ lda (table_ptr),y
+ sta code_ptr+1
+ dey
+ lda (table_ptr),y
+ sta code_ptr
+ inc table_ptr ; point to next entry
+ bne tp1ok
+ inc table_ptr+1
+tp1ok:
+ inc table_ptr
+ bne tp2ok
+ inc table_ptr+1
+tp2ok:
+ ora code_ptr+1 ; quit if we hit $0000 in the table
+ beq fixup_done
+ lda (code_ptr),y ; Y still 0
+ sec
+ sbc offset_pages
+ sta (code_ptr),y
+ sec ; *should* already be set...
+ bcs fixup_addrs
+fixup_done:
+
; absolute addresses are fixed up, now move the code.
lda code_start
sta code_ptr
@@ -134,23 +155,18 @@ ceok:
bcc do_init
; fix up RUNAD
- lda RUNAD
- sec
- sbc offset_lo
lda RUNAD+1
- sbc offset_hi
+ sec
+ sbc offset_pages
+ sta RUNAD+1
do_init:
; if there's an init address, call it (just like DOS would).
lda code_init+1
beq done ; if hi byte is 0, assume lo byte is also 0.
- lda code_init ; subtract offset
sec
- sbc offset_lo
- sta code_init
- lda code_init+1
- sbc offset_lo
+ sbc offset_pages
sta code_init+1
jmp (code_init)
@@ -159,29 +175,6 @@ do_init:
done:
rts
-fixup_addrs:
- ldy #1
- lda (table_ptr),y
- sta code_ptr+1
- dey
- lda (table_ptr),y
- sta code_ptr
- inc table_ptr ; point to next entry
- bne tp1ok
- inc table_ptr+1
-tp1ok:
- inc table_ptr
- bne tp2ok
- inc table_ptr+1
-tp2ok:
- ora code_ptr+1 ; quit if we hit $0000 in the table
- beq done
- lda (code_ptr),y ; Y still 0
- sec
- sbc fixup
- sta (code_ptr),y
- jmp fixup_addrs
-
whoops_msg: .byte "MEMLO is too high! Press any key to exit.", EOL
whoops_len = (*-whoops_msg)