diff options
Diffstat (limited to 'reloc.s')
-rw-r--r-- | reloc.s | 79 |
1 files changed, 41 insertions, 38 deletions
@@ -18,8 +18,10 @@ 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 + dest_ptr = zp_addr+3 ; 2 bytes + code_ptr = zp_addr+5 ; 2 bytes + shfreg = zp_addr+7 ; 1 byte + pagecount = zp_addr+8 ; 1 byte .org start_addr - 6 .word $ffff @@ -41,7 +43,7 @@ memlo_00: sbc MEMLO+1 sta offset_pages - bcs memlo_ok + bcs relocate_code .ifdef verbose_memlo_check ; whoops, MEMLO is too high, print message and wait for keystroke @@ -72,74 +74,75 @@ exitwait: freeze: bne freeze ; wait for the user to press Reset. .endif -memlo_ok: - ; adjust addresses before moving the code. +relocate_code: + ; adjust addresses while moving the code. ; point to the relocation table... lda #<table sta table_ptr lda #>table sta table_ptr+1 -fixup_addrs: - ; walk the reloc table - ldy #1 - lda (table_ptr),y - sta code_ptr+1 - dey - lda (table_ptr),y - sta code_ptr - - ; point to next table entry - inc table_ptr - bne tp1ok - inc table_ptr+1 -tp1ok: - inc table_ptr - bne tp2ok - inc table_ptr+1 -tp2ok: - - ora code_ptr+1 ; A still has code_ptr, 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. + ; ...and to the code we're moving... lda code_start sta code_ptr lda code_start+1 sta code_ptr+1 + + ; ...and to the destination we're moving to. lda MEMLO sta dest_ptr lda MEMLO+1 sta dest_ptr+1 - ; x = (code_end >> 8) - (code_start >> 8) + 2 + ; pagecount = (code_end >> 8) - (code_start >> 8) + 2 lda code_end+1 sec sbc code_start+1 tax inx inx - ldy #0 + stx pagecount + + ldx #0 + lda (table_ptr,x) + sta shfreg ; this moves a page at a time, meaning if code_end isn't ; on an even page boundary, we move a little more than ; needed. it won't hurt anything, and it follows the ; KISS principle. + ldy #0 move_loop: lda (code_ptr),y + pha + cpx #8 + bne shiftit + + ; bump bitmap pointer + inc table_ptr + bne tpok + inc table_ptr+1 + +tpok: + ; get next byte of bitmap + ldx #0 + lda (table_ptr,x) + sta shfreg + +shiftit: + inx + pla + asl shfreg + bcc dontadj + sbc offset_pages + +dontadj: sta (dest_ptr),y iny bne move_loop inc code_ptr+1 inc dest_ptr+1 - dex + dec pagecount bne move_loop ; bump MEMLO to point one byte past the end of the moved code. |