$title ('CP/M V3.0 Relocate and Fix Up File') name relfix ; ;/* ; Copyright (C) 1979,1980,1981,1982 ; Digital Research ; P.O. Box 579 ; Pacific Grove, CA 93950 ; ; Revised: ; 05 Aug 82 by Bruce Skidmore ;*/ cseg extrn mon1 ;BDOS entry point extrn FCBin ;FCB for input extrn sctbfr ;sector buffer extrn offset ;relocation offset extrn prgsiz ;program size extrn bufsiz ;buffer size extrn bnkpg ;bnkbdos page extrn respg ;resbdos page extrn scbpg ;System Control Block page extrn biospg ;Bios page extrn reslen ;Resident System length extrn bnkoff ;Banked System offset extrn nonbnk ;Non Banked CP/M flag public bitmap ;bitmap buffer RelFix: public RelFix lxi d,bitmap mvi c,26 call mon1 ;set DMA address to bit map ; ;file loaded, ready for relocation lhld prgsiz mov b,h mov c,l ;BC = program size mov a,l ani 127 mov l,a jnz nofill ;if program size is an even number push h ;of sectors prefill the bitmap buffer push b lhld fcbin xchg mvi c,20 call mon1 pop b pop h ora a jnz errtn nofill: mov e,l ;L = offset into bitmap buffer mvi d,0 lxi h,bitmap dad d ;HL = bit map base mvi a,low(bitmap+128) sta btmptp ;save number of relocation bytes ;in left in bitmap buffer lxi d,sctbfr ;DE = base of program push h ;save bit map base in stack lda offset mov h,a ;H = relocation offset pgrel0: mov a,b ;bc=0? ora c jz ExitRelFix ; ; not end of the relocation, ; may be into next byte of bit map dcx b ;count length down mov a,e sui low(sctbfr) ani 111b ;0 causes fetch of next byte jnz pgrel3 ; fetch bit map from stacked address xthl lda btmptp cmp l jnz pgrel2 push b push d lhld FCBin xchg mvi c,20 call mon1 pop d pop b lxi h,bitmap ora a jnz errtn ;return with error condition pgrel2: mov a,m ;next 8 bits of map inx h xthl ;base address goes back to stack mov l,a ;l holds map as 8 bytes done pgrel3: mov a,l ral ;cy set to 1 if reloc necessary mov l,a ;back to l for next time around jnc pgrel4 ;skip relocation if cy=0 ; ; current address requires relocation ; push h ldax d ;if page = 0ffh inr a jnz test2 lda biospg ;then page = bios$page jmp endt test2: ;else inr a ;if page = 0feh jnz test3 lda scbpg ;then page = SCB$page push psw dcx d ;add 9ch to the offset(low byte) ldax d adi 09ch stax d inx d pop psw jmp endt test3: ;else inr a ;if page = 0fdh jnz test4 lda respg ;then page = resbdos$page jmp endt test4: ;else inr a ;if page = 0fch jnz test5 lda bnkpg ;then page = bnkbdos$page jmp endt test5: ;else inr a ;if page = 0fbh jnz test6 lda scbpg ;then page = scb$page jmp endt test6: ;else lda reslen mov h,a ;if non$banked and page >= reslen lda nonbnk ora a jz test7 ldax d sub h jc default ;then do; dcx d ;page$adr = page$adr - 1; mvi a,09ah stax d ;page = 9ah; inx d ;page$adr = page$adr + 1; lda scbpg ;page = scb$pg; jmp endt ;end; test7: ;else lda bnkoff mov l,a ;if page >= reslen ldax d sub h jc default add l ;then page = page - reslen jmp endt default: ;else lda offset ;page = page + offset mov h,a ldax d add h endt: stax d pop h pgrel4: inx d ;to next address jmp pgrel0 ;for another byte to relocate ExitRelFix: pop h lxi h,0 mov a,h ret errtn: pop h ;discard return address lxi h,0ffffh mov a,h ret ;return with error condition ; ; Local Data Segment ; bitmap: ds 128 ;bit map buffer btmptp: ds 1 ;bit low (bitmap+128) end