;Modified to use the offset passed in A (A=0: real offset is 1 page) ;Bruce Morgen - June 13, 1987 ;This source is copyright 1984 by Jim Lopushinsky to discourage ;commercial use. ; ;This is the relocator subroutine that relocates PRL modules at [HL] ;to just below the top of TPA, and calls the RSX manager to integrate ;the relocated module. on entry: ; ; HL address of PRL module to relocate. It must be on a page ; boundary, and points to the 1 page PRL header. ; ; A zero -- Relocate just below Top of TPA. ; non-zero -- Relocate below the CCP. Only used by ; SETRSX to relocate the RSX manager. ; ;March 5/84 ;This code is written using Zilog mnemonics, although no Z80-specific ;instructions are used. I learned Zilog before Intel, and I find ;them easier to use and less confusing. ; .z80 public loadrsx bdos equ 5 loadrsx: ld e,a ;save relocate offset ; or a ;below the CCP? ; jp z,noccp ;nope. ; ld e,8 ;8 page offset for CCP noccp: ld a,l or a ;test for page boundary ld a,1 ret nz ;return with error if not page boundary inc hl ;point to PRL code length in PRL header ld c,(hl) ;get code length in BC inc hl ld b,(hl) ld a,(bdos+2) ;get top of TPA page sub e ;adjust for possibility of CCP dec a ;less 1 page dec bc sub b ;form target page address inc bc cp 15 ;must be greater than 0F00H jp c,nroom dec hl dec hl push hl ;save source address add hl,bc ;form address of bit map cp h ;are we ok? pop hl jp c,nroom ;out of memory ld d,a ;destination address in DE ld e,0 inc h ;adjust HL to point to start of code push de push bc call movebc ;move code into place pop bc ;length of module in BC pop de push de ld e,d ;relocation page offset in E dec e ;adjust relocation offset push hl ;bit map address on stack ld h,e ;relocation offset in H ld e,0 ;init to byte boundary reloclp: ld a,b or c ;are we done? jp z,reldon ;yep. dec bc ;decrement length left ld a,e ;get low byte of target address and 7 ;mod 8 jp nz,nobump ;not at byte boundary in bit map ex (sp),hl ;get bit map address ld a,(hl) ;get relocation bits inc hl ;adjust bit map address ex (sp),hl ;back to stack ld l,a ;relocation bits in L nobump: ld a,l ;get relocation bits rla ;shift into carry ld l,a jp nc,noadj ;jump if no need to adjust ld a,(de) ;get target byte add a,h ;adjust address ld (de),a ;put it back noadj: inc de ;increment target jp reloclp ;and loop for more ;......... ; ;Relocation complete. Call RSX manager to complete RSX chains. ; reldon: pop de pop de ;restore stack DE points to RSX just loaded ld e,18h ;point to loader flag ld a,(de) or a ;test loader flag jp z,notldr ;jump if not doing RSX manager ; ;If we are setting up the RSX manager, need to call it via JP (HL) ; ld h,d ;get address of RSX manager entry in HL ld l,6 ld bc,rsxret ;push return onto stack push bc ld c,59 ;call RSX manager function jp (hl) ;go to it notldr: ld c,59 ;call RSX manager function call bdos ;RSX manager includes RSX just loaded rsxret: xor a ;say we have no errors ret ; ;........... ; ;Here if insufficient memory for relocation ; ; nroom: ld a,2 ;return code or a ret ; ;........... ; ; ;MOVEBC Move [HL] to [DE] length in [BC] ; movebc: ld a,b or c ret z ld a,(hl) ld (de),a inc hl inc de dec bc jp movebc end