diff options
author | B. Watson <urchlay@slackware.uk> | 2025-04-23 06:36:00 -0400 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2025-04-23 06:36:00 -0400 |
commit | 8158e2e1b60484c8c12da62afbd439d810e96c3e (patch) | |
tree | f30742bcd6a57c63f0d1c26b0bbca3f3ccdd3b89 | |
parent | 3a120e78480a3b43c5cf32d9e6efae5a698abd38 (diff) | |
download | atari8-self-relocator-8158e2e1b60484c8c12da62afbd439d810e96c3e.tar.gz |
reloc.s: optimize for size.
-rw-r--r-- | README.txt | 32 | ||||
-rw-r--r-- | autorun.sys | bin | 1206 -> 1117 bytes | |||
-rw-r--r-- | reloc.s | 37 |
3 files changed, 45 insertions, 24 deletions
@@ -34,7 +34,7 @@ it'll actually run in its new location. Unfortunately, the code can only be relocated by multiples of 256 bytes. The low bytes aren't adjusted. So unless MEMLO happens to -contain $FF in its low byte, some memory will be wasted (up to 256 +contain $FF in its low byte, some memory will be wasted (up to 255 bytes). The code from Insight: Atari is doesn't produce self-relocating @@ -229,30 +229,32 @@ $09 $40 ; hi byte of LDA $4015 operand $10 $40 ; hi byte of LDA $4016 $00 $00 ; terminator -Low byte relocation table: - -$01 $40 ; lo byte of JSR $4007 operand -$04 $40 ; lo byte of JSR $400E operand -$08 $40 ; lo byte of LDA $4015 operand -$0F $40 ; lo byte of LDA $4016 -$00 $00 ; terminator - Program loads from $4000 to $4016. If MEMLO was $1CFC, the relocator -will move the program to $1CFC - $1D12 and set MEMLO to $1D13. The +will move the program to $1D00 - $1D16 and set MEMLO to $1D17. The operand of the first instruction (was JSR $4007) will be altered -to $1D03 (aka $4007 - $4000 + $1CFC), which is the address that the +to $1D07 (aka $4007 - $4000 + $1CFC), which is the address that the subroutine got relocated to. The original program assembled to a 32-byte file. The relocatable -version will be around 200 bytes: 28 bytes for the original file -(minus its INITAD segment), ~128 bytes for the relocator code, 8 bytes -for the address table, and 20 bytes for the two relocation tables. +version will be around 400 bytes: 28 bytes for the original file +(minus its INITAD segment), ~300 bytes for the relocator code, 8 +bytes for the address table, and 10 bytes for the relocation table. However, the relocator and tables are only used once, and can be overwritten afterwards (so they count as free memory). Relocation Table Format -Bitmap. +Current implementation: + +A list of addresses that need to be adjusted (high bytes of absolute +addresses), 2 bytes each, terminated with $00 $00. + +Possible future implementation: + +Bitmap. One bit per byte in the file. 1 if the address needs +adjusting, 0 if not. This *probably* will actually be smaller than +the list of addresses. Also has the advantage of being a fixed size, +easily calculated/predicted. The relocator is 256 bytes long or less. The GR.0 display list with a 16K cart in is at $7C20. diff --git a/autorun.sys b/autorun.sys Binary files differindex 41fc439..2ef3512 100644 --- a/autorun.sys +++ b/autorun.sys @@ -1,4 +1,8 @@ +; uncomment to enable user-friendly "MEMLO is too high" error. +; adds ~80 bytes to the code size (40% larger). + ;verbose_memlo_check = 1 + .export _main .include "atari.inc" @@ -39,6 +43,7 @@ memlo_00: bcs memlo_ok + .ifdef verbose_memlo_check ; whoops, MEMLO is too high whoops: ldx #0 @@ -61,22 +66,31 @@ exitwait: lda #0 sta COLOR2 rts + .else + lda #$40 + sta COLOR2 +freeze: bne freeze + .endif memlo_ok: - ; adjust addresses before moving the code + ; adjust addresses before 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 - inc table_ptr ; point to next entry + + ; point to next table entry + inc table_ptr bne tp1ok inc table_ptr+1 tp1ok: @@ -84,7 +98,8 @@ tp1ok: bne tp2ok inc table_ptr+1 tp2ok: - ora code_ptr+1 ; quit if we hit $0000 in the table + + 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 @@ -127,7 +142,6 @@ move_loop: dex bne move_loop - ; bump MEMLO to point one byte past the end of the moved code. lda code_end sec @@ -136,12 +150,13 @@ move_loop: lda code_end+1 sbc code_start+1 sta code_end+1 - inc code_end - bne ceok - inc code_end+1 ; code_end is now the code length + 1 byte -ceok: + ;inc code_end + ;bne ceok + ;inc code_end+1 ; code_end is now the code length + 1 byte +;ceok: lda code_end - clc + ;clc + sec adc MEMLO sta MEMLO lda code_end+1 @@ -175,11 +190,15 @@ do_init: done: rts + .ifdef verbose_memlo_check whoops_msg: .byte "MEMLO is too high! Press any key to exit.", EOL whoops_len = (*-whoops_msg) + .endif end_addr: + .out .sprintf("reloc.s code size $%04x (%d)", (* - start_addr), (* - start_addr)) + ; this was for testing only. mkrelocxex.c adds the init address. ; .word INITAD ; .word INITAD+1 |