Path: utzoo!attcan!uunet!bellcore!att!pacbell.com!ucsd!orion.oac.uci.edu!ucivax!mziober From: mziober@trocadero.ics.uci.edu (Michael A. Ziober) Newsgroups: comp.sys.apple2 Subject: Re: relocatable code Message-ID: <2740BFFE.24064@ics.uci.edu> Date: 14 Nov 90 03:54:38 GMT References: <90Nov13.183431est.57621@ugw.utcs.utoronto.ca> Lines: 72 Nntp-Posting-Host: trocadero.ics.uci.edu In <90Nov13.183431est.57621@ugw.utcs.utoronto.ca> GRAY@ADMIN.HumberC.ON.CA (Kelly Gray) writes: >One way to locate a program in memory is to do some playing with the stack. >The following bit of code will locate itself wherever it may be. The only >restriction is that the motherboard ROM must be enabled since it needs to >use an RTS instruction at a known location. >IORTS EQU $FF58 ;Address of known RTS instruction in ROM >; >LOCATE SEI ;Disable interrupts for a moment Bad idea to just disable interrupts. > JSR IORTS ;This subroutine simply returns back, > TSX ;Leaving the return address above the stack > DEX ;Alter stack pointer to recover old return address > DEX > TXS ;Put altered pointer into stack pointer register > PLA ;Get PCL of old return address > STA LOC ;Save it > PLA ;Get PCH of old return address > STA LOC+1 ;Save it > CLI ;Restore interrupts again Likewise to just enable interrupts. > After this program fragment is done, the pointer at LOC will point to the >TSX instruction that follows the JSR to IORTS. Actually to the byte BEFORE the TSX or the last byte of the JSR IORTS. > From there it sould be an >easy matter to add an offset to this value to point it at your lookup table. >This code itself is completely relocatable. There is only one byte that must >be at a known address, and that is the RTS instruction at IORTS Although Apple has "guaranteed" an RTS at $FF58, the above code assumes that the ROMs are mapped in, as Kelly noted. On any Apple, location $FF58 may be mapped to RAM. Additionally, on a GS, if the shadow register is not set correctly, you probably won't find an RTS at $FF58 even with the ROMs mapped in. For these reasons, it is preferable to make no assumptions about the availability of the ROMs. Here is some code which makes virtually no assumptions about its runtime environment. It does assume that your assembler acts like LISA. I don't know about the Pascal or APW assemblers. Your favorite assembler might have syntax to force absolute addressing modes, don't ask me how. It's been years. ENTRY PHP ;save interrupt mask SEI ;disable interrupts to protect return address on stack LDA $0 ;save value at $0 PHA LDA #$60 ;store an RTS at $0 STA $0 HERE JSR $0 ;place return address on stack PLA ;restore value at $0 STA $0 TSX ;stack pointer->high byte of return address LDA $100-1,X ;must be absolute address $00FF, not zero page $FF LDY $100,X ;(256 * A) + Y = HERE + 2 PLP ;restore interrupt mask Please note that I do not have my handy-dandy 6502 reference handy so I am unable to verify the existence of the LDY abs,X instruction. But I'm pretty sure it's real. If not, I apologise for posting bogus code. Michael Ziober ICS senior & proud owner of an Apple ][ (no plus!) University of California, Irvine