;**************************************************************** ; PRL FILE FORMAT RELOCATER FOR BIT MAPPED FILES ;**************************************************************** ; ; ; This small program block moves a bit map relocatable ; file from address 0200h above this module up to a spot ; below the CCP and then jumps to the base of the moved ; code. The DIGITAL RESEARCH RELOCATING ASSEMBLER and the ; companion LINKER permit the generation of the PRL file ; format. LINK will put the code size word in to address ; 101 and 102. The code spot is intended to be 0200h with ; the bit map immediately above the code. A one in the bit ; map indicates the location of a moved byte that requires ; a relocation address offset. ; ;*************************************************************** ; ; ;start point for the beginning of the mover module ; ORG 0100H ; ; ;GENERAL CP/M BDOS INTERFACE EQUATES. ; BDOS EQU 0005H ;FILE MANAGER ENTRANCE LOCATION CODE$START EQU 0200H ;LINK 80 CODE START POINT FOR ORG 0 FILE ; ; ;START POINT OF MOVER CODE ; DB 01H ;INSERT HEX FILE CODE FOR LXI B,XXXX DS 2 ;INSERT CODE SIZE FROM LINK .PRL FILE ;WITH DDT HERE LXI H,0 ;GET CCP STACK FOR LATER PASSING DAD SP ;TO RELOCATED PROGRAM LXI SP,CODE$START ;LET STACK WORK DOWN FROM 0200H PUSH H ;SAVE CCP POINTER ON OUR STACK ; PUSH B ;SAVE A COPY OF CODE SIZE ON STACK ; ; ;GET BDOS PAGE ADDRESS BOUNDARY ; LXI H,BDOS+2 ;PAGE ADDRESS OF BDOS BASE MOV A,M ;INTO (A) SUI 8 ;DECREASE SIZE FOR CCP SIZE ;OF EIGHT PAGES DCR A ;ONE MORE TIME TO ACCOUNT FOR ;..PARTIAL PAGE CODE SIZE SUB B ;SUBTRACT CODE SIZE IN TRUNC INTETGER SIZE ; MOV D,A ;(DE) = DESTINATION ADDRESS BASE MVI E,0 PUSH D ;SAVE LOAD ADDRESS FOR LATER JUMP TO CODE ; LXI H,CODE$START ;START MOVE POINTER TO (HL) ; ; ;LOOP TO MOVE CODE UP IN RAM UNDER CCP ; MOVLOOP: MOV A,B ;CHECK BYTE COUNT TO SEE IF ALL MOVED YET ORA C JZ MOVDONE ;EXIT LOOP IF DONE ; DCX B ;DECREMENT BYTES TO MOVE COUNT MOV A,M ;GET A BYTE TO MOVE STAX D ;SAVE AT DESTINATION ADDRESS INX D ;BUMP SOURCE DESTINATION POINTERS INX H JMP MOVLOOP ;GO MOVE MORE BYTES ; ; ;CODE MOVED SO SET UP TO SCAN BIT MAP ; MOVDONE: POP D ;GET BACK A COPY OF THE DESTINATION ADDR POP B ;RESET (BC) TO BYTE COUNT FOR BIT MAP SCAN PUSH H ;SAVE ADDRESS OF BIT MAP ON TOP OF STACK ; MOV H,D ;SET (H) TO RELOCATE PAGE OFFSET DCR H ; ; ;LOOP TO SCAN CODE BLOCK JUST MOVED AND TO ADD IN OFFSET OF EXECUTION ;PAGE ADDRESS ON ALL BYTES NEEDING RELOCATION. ; RELOCLOOP: MOV A,B ;CHECK BIT MAP COUNTER TO SEE IF RELOC DONE ORA C JZ RELOCDONE ;EXIT IF ALL BYTES CHECKED DCX B ;DECREASE BYTE COUNT MOV A,E ;IS (DE) ADDRESS MOD EIGHT BYTES? ANI 7 ;IF SO WE NEED NEXT BIT MAP BYTE JNZ SAMEBYTE ;STILL ON SAME BIT MAP BYTE ; ; ;GET NEXT BIT MAP BYTE VIA POINTER ON TOP OF STACK ; XTHL ;SAVE (HL) AND GET CURRENT MAP POINTER MOV A,M ;GET MAP BYTE TO (A) INX H ;INCREASE POINTER FOR NEXT TIME XTHL ;PUT POINTER BACK ONTO STACK MOV L,A ;MAP BYTE TO HOLDING RESISTER ; SAMEBYTE: MOV A,L ;FETCH OUR CURRENT BIT MAP BYTE RAL ;SHIFT BIT MAP BYTE FOR NEXT BIT MOV L,A ;SAVE SHIFTED ONE FOR NEXT PASS JNC NOOFFSET ;SKIP OFFSET ADD IF BIT WAS NOT ONE ; ; ;GET CODE BYTE AND ADD IN OFFSET IF MAP BIT WAS 1 ; LDAX D ;FETCH THE DESTINATION BYTE ADD H ;ADD IN OFFSET STAX D ;STORE BACK AWAY ; NOOFFSET: INX D ;INCREASE THE MOVED CODE BYTE POINTER JMP RELOCLOOP ;GO TO PROCESS MORE BYTES ; ; ;HERE WHEN THE RELOCATION IS DONE READY TO JUMP TO THE MOVED CODE ;REMEMBER THAT (H) HAS PAGE ADDRESS OF MOVED CODE. ; RELOCDONE: POP D ;GET BIT MAP POINTER OFF STACK MOV D,H INR D ;SET UP EXECUTION ADDRESS MVI E,0 ;MAKE (DE) AND EVEN PAGE BOUNDARY ADDRESS POP H ;GET THE SAVED CCP STACK POINTER SPHL ;RESET FOR FOING TO MOVED PROGRAM XCHG ;GET TRANSFER ADDRESS FROM (DE) PCHL ;OFF TO THE MOVED CODE AREA ; END ; ; ;+++...END OF FILE