104 lines
4.4 KiB
NASM
104 lines
4.4 KiB
NASM
|
|
; Relocatable code stub for Supermon 64 by Jim Butterfield
|
|
; This code was disassembled from the original Supermon+64 V1.2 binary.
|
|
|
|
; The relocation stub starts at the Start of Variables pointer (VARTAB) and
|
|
; works backwards through the Supermon64 machine code, copying it to the top
|
|
; of basic memory pointer (MEMSIZ), and decrementing the pointer as it goes.
|
|
; Relative addresses that need to be adjusted are marked with a $36 byte
|
|
; immediately following them. Since we're working backwards, the marker is
|
|
; encountered first, then the high byte, then the low byte of the address
|
|
; needing to be adjusted. The relative addresses are calculated such that
|
|
; adding the top of memory to them will yield the absolute address of the
|
|
; jump target in the relocated code.
|
|
|
|
; build.py will build a relocatable Supermon64 binary from this stub plus
|
|
; standard Supermon64 binaries assembled to two different pages.
|
|
|
|
; ----------------------------------------------------------------------------
|
|
; variables
|
|
|
|
SOURCE = $22 ; first temp variable
|
|
TOPMEM = $24 ; highest address available to BASIC
|
|
LASTBYT = $26 ; previous byte encountered
|
|
VARTAB = $2D ; pointer to start of BASIC variable storage area
|
|
FRETOP = $33 ; pointer to bottom of string text storage area
|
|
TARGET = $37 ; end of basic memory/start of machine code (aka MEMSIZ)
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
; basic header
|
|
|
|
* = $0801
|
|
|
|
; 100 PRINT "{DOWN}SUPERMON+64 JIM BUTTERFIELD"
|
|
; 110 SYS(PEEK(43)+256*PEEK(44)+71)
|
|
|
|
.BYTE $29,$08,$64,$00,$99,$20,$22,$11
|
|
.TEXT "SUPERMON+64 JIM BUTTERFIELD"
|
|
.BYTE $22,$00,$43,$08,$6E,$00,$9E,$28
|
|
.BYTE $C2,$28,$34,$33,$29,$AA,$32,$35
|
|
.BYTE $36,$AC,$C2,$28,$34,$34,$29,$AA
|
|
.BYTE $37,$31,$29,$00,$00,$00,$00,$00
|
|
.BYTE $00
|
|
|
|
; ----------------------------------------------------------------------------
|
|
; relocator stub
|
|
|
|
LDA VARTAB ; start copying from the start of basic variables
|
|
STA SOURCE
|
|
LDA VARTAB+1
|
|
STA SOURCE+1
|
|
LDA TARGET ; start copying to the end of BASIC memory
|
|
STA TOPMEM
|
|
LDA TARGET+1
|
|
STA TOPMEM+1
|
|
LOOP LDY #$00 ; no offset from pointers
|
|
LDA SOURCE ; decrement two-byte source address
|
|
BNE NB1
|
|
DEC SOURCE+1
|
|
NB1 DEC SOURCE
|
|
LDA (SOURCE),Y ; get byte currently pointed to by SOURCE
|
|
CMP #$36 ; check for address marker ($36)
|
|
BNE NOADJ ; skip address adjustment unless found
|
|
LDA SOURCE ; decrement two-byte source address
|
|
BNE NB2
|
|
DEC SOURCE+1
|
|
NB2 DEC SOURCE
|
|
LDA (SOURCE),Y ; get byte currently pointed to by SOURCE
|
|
CMP #$36 ; check for second consecutive marker ($36)
|
|
BEQ DONE ; if found, we're done with relocation
|
|
STA LASTBYT ; if not, save byte for later
|
|
LDA SOURCE ; decrement two-byte source address
|
|
BNE NB3
|
|
DEC SOURCE+1
|
|
NB3 DEC SOURCE
|
|
LDA (SOURCE),Y ; current byte is low byte of relative address
|
|
CLC
|
|
ADC TOPMEM ; calc absolute low byte by adding top of memory
|
|
TAX ; save absolute low byte in X
|
|
LDA LASTBYT ; previous byte is high byte of relative address
|
|
ADC TOPMEM+1 ; calc absolute high byte by adding top of memory
|
|
PHA ; save absolute high byte on stack
|
|
LDA TARGET ; decrement two-byte target address
|
|
BNE NB4
|
|
DEC TARGET+1
|
|
NB4 DEC TARGET
|
|
PLA ; retrieve absolute high byte from stack
|
|
STA (TARGET),Y ; save it to the target address
|
|
TXA ; retrieve absolute low byte from stack
|
|
NOADJ PHA ; save current byte on stack
|
|
LDA TARGET ; decrement two-byte target address
|
|
BNE NB5
|
|
DEC TARGET+1
|
|
NB5 DEC TARGET
|
|
PLA ; retrieve current byte from stack
|
|
STA (TARGET),Y ; save it in the target address
|
|
CLC ; clear carry for unconditional loop
|
|
BCC LOOP ; rinse, repeat
|
|
DONE LDA TARGET ; fix pointer to string storage
|
|
STA FRETOP
|
|
LDA TARGET+1
|
|
STA FRETOP+1
|
|
JMP (TARGET) ; jump to the beginning of the relocated code
|