TITLE	'LOAD CPM 10 DEC 87 RHP'
;LOADS CPM AS A FILE AND MOVES IT INTO POSITION
;BASED ON PRLMOVE.ASM
;
;FILE: PRLMOVE.ASM
;FROM LIFELINES VOL II,NO 8
;
;ENTERED 3 DEC 84 RHP
;
;*******************************************************
;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 INTO ADDRESS
;101 AND 102. THE CODE SPOT IS INTENDED TO BE 0200H WITH
;THE BIT MAP IMMEDIATLY ABOVE THE CODE. A ONE IN THE 
;BIT MAP INDICATES THE LOCATION OF A MOVED BYTE THAT
;REQUIRES A RELOCATION ADDRESS OFFSET.
;
;REVAMPED TO MOVE CPM CCP/BDOS/BIOS TO TOP OF MEMORY
;
;*******************************************************
;
;START POINT FOR THE BEGINNING OF THE MOVER PROGRAM
;
	ORG 	0100H
;
;GENERAL CPM BDOS EQUATES
;
BDOS	EQU	0005H		;FILE MANAGER ENTRANCE LOC.
CODEST:	EQU	0200H		;LINK 80 CODE START POINT
				; FOR ORG 0 FILE
MEMTOP:	EQU	0DFFFH		;TOP OF AVAILABLE MEMORY
CPMLG:	EQU	016H		;CCP+BDOS=1600H
;
;START POINT OF MOVER CODE
;
START:	DB 	01H		;LOAD CODE SIZE AT START+1
	DS	2		;SIMULATE LXI B,XXXX FOR OLAY
;	LXI	H,0000H		;GET CCP STACK FOR LATER
;	DAD	SP		; PASSING TO RELOCATED PRGM
	LXI	SP,CODEST	;STACK WORKS DOWN FROM CODE
;	PUSH	H		;SAVE OLD STACK ON NEW STACK
	PUSH	B		;SAVE CODE SIZE ON NEW STACK
;
;GET BDOS PAGE ADDRESS BOUNDRY (HI MEMORY)
;
;	LXI	H,BDOS+2	;PAGE ADDRESS OF BDOS CODE
	LXI	H,MEMTOP	;*POINT AT TOP OF MEMORY
;	MOV	A,M		;INTO A
	MOV	A,H		;HI MEM PAGE
;	SUI	8		;DOWN 8 PAGES FOR CCP
	DCR	A		;ONCE MORE FOR PAGE FRACTION
	SUB	B		;- CODE SIZE IN TRNC INT SIZE
	MOV	D,A		;DE=DESTINATION BASE
	MVI	E,0		
	PUSH	D		;SAVE ADDR FOR JUMP TO CODE
	LXI	H,CODEST	;START MOVE POINTER TO HL
;
;LOOP TO MOVE CODE UP IN RAM UNDER CCP (HI MEMORY)
;
MOVLOOP:MOV	A,B		;CHK BYTE CNT, ALL MOVED YET?
	ORA	C
	JZ	MOVDONE		;EXIT OP IF DONE
	DCX	B		;DECR BYTES TO MOVE COUNT
	MOV	A,M		;MOVE THE BYTE
	STAX	D		;PUT AT DEST ADDR
	INX	D		;NEXT DEST
	INX	H		;NEXT SOURCE
	JMP	MOVLOOP		;KEEP ON TRUCKING
;
;CODE MOVED, NOW SCAN THE BIT MAP
;
MOVDONE:POP	D		;GET DEST ADDR
	POP	B		;GET BYTE COUNT
	PUSH 	H 		;SAVE BIT MAP ADDR ON STACK
	MOV	H,D		;SET H TO RELOC 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 CNTER,RELOC COMPL?
	ORA	C
	JZ	RELOCDONE	;ALL BYTES DONE
	DCX	B		;DEC BYTE COUNT
	MOV	A,E		;IS DE ADDR MOD 8 BYTES?
	ANI	07H		;IF SO,NEED NEXT BIT MAP BYTE
	JNZ	SAMEBYTE	;STILL ON SAME BIT MAP BYTE
;
;GET NEXT BIT MAP BYTE VIA POINTER ON STACK
;
	XTHL			;SAVE HL & GET CURNT MAP PNTR
	MOV	A,M		;MAP BYTE TO A
	INX	H		;BUMP POINTER FOR NEXT TIME
	XTHL			;REPLACE POINTER ON STACK
	MOV	L,A		;MAP BYTE TO HOLDING REG.
;
SAMEBYTE:
	MOV	A,L		;GET CURRENT BIT MAP BYTE
	RAL			;SHIFT ONE BIT
	MOV	L,A		;SAVE SHFTD BIT FOR NXT PASS
	JNC	NOOFFSET	;0=NO OFFSET NEEDED
;
;GET CODE BYTE AND ADD IN OFFSET IF MAP BIT WAS 1
;
	LDAX	D		;GET THE DEST BYTE
	ADD	H		;ADD THE OFFSET
	STAX	D		;PUT IT BACK
;
NOOFFSET:
	INX	D		;BUMP THE MOVED CODE BYTE PTR
	JMP	RELOCLOOP	;BACK FOR MORE BYTES
;
; THE RELOC IS DONE & READY TO JUMP TO THE MOVED CODE
;H HAS PAGE ADDRESS OF THE MOVED CODE
;
RELOCDONE:
;	POP	D		;GET BIT MAP PNTR OFF STACK
	MOV	D,H
	INR	D		;SET UP EXECUTION ADDR
	ADI	CPMLG		;*POINT TO COLD BOOT
	MVI	E,0		;MAKE DE AN EVEN PAGE BOUNDRY
;	POP	H		;GET THE CCP STACK POINTER
;	SPHL			;RESET TO GO TO MOVED PROGRAM
	XCHG			;GET TRANSFER ADDR FROM DE
	PCHL			;JUMP TO THE NEW CODE
;
END
;
;	END OF FILE PRLMOVE.ASM
;
