diff options
Diffstat (limited to 'reloc.s')
-rw-r--r-- | reloc.s | 97 |
1 files changed, 45 insertions, 52 deletions
@@ -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) |