;	PRLOADER.ASM VERSION 1.0
;	11/3/80 BY RON FOWLER, WESTLAND, MICHIGAN
;
;
;	THIS PROGRAM IS A LOADER DESIGNED TO BE
;	ADDED TO A PROGRAM REQUIRING RELOCATION.
;	THE PROGRAM MUST BE OF TYPE PRL, AND THIS
;	CODE (IN HEX FORM) MUST BE ADDED TO IT
;	VIA DDT OR SID.  THE PROCEDURE IS:
;
;		A>DDT <FILENAME>.PRL
;		*IPRLOADER.HEX
;		*R
;		*^C
;		A>SAVE XX <FILENAME>.COM
;
;	THE FILE SIZE PARAMETER LOCATED IN THIS
;	CODE AT LOCATION 101H IS FILLED IN BY
;	GENMOD.COM IN THE PRL FILE.  THE FILE
;	RELOCATION ADDRESS AT 104H IS FILLED IN
;	BY THE USER, AND IF LEFT 0, WILL CAUSE
;	THE FILE TO LOAD UNDER THE CCP.  IF SET
;	TO 0001H, THE FILE WILL LOAD UNDER THE
;	BDOS, OVERLAYING THE CCP.
;
BDOS	EQU	5
BYE	EQU	1	;THIS SPECIALLY FOR BYE PGM
CPM2	EQU	1	;THIS NEEDED ONLY FOR BYE
COMUSR	EQU	15	;THIS TOO...USED WITH RBBS
;
;
	ORG	100H
;
	DB	01H	;LXI B
	DS	2	;GENMOD FILLS IN PGM SIZE HERE
	LXI	H,0	;PGM RUN ADRS, IF 0 OR 1 THEN IN TPA
	LXI	SP,200H ;MAKE SURE SPACE AVAILABLE WHEN MODIFYING THIS PGM
	LXI	D,200H	;ADRS OF PRL STUFF
	MOV	A,H	;IF H IS NZ, THEN WE HAVE..
	ORA	A	;..ADRS TO RELOCATE TO
	JNZ	MOVE
	MOV	A,L	;NO REL ADRS SUPPLIED, CHECK OPTIONS
	LHLD	6	;TOPMEM FOR LATER
	ORA	A	;IF ADRS WAS NOT ZERO..
	MOV	A,H
	JNZ	OVLCCP	;..THEN FORGET THE CCP
	SUI	8	;..ELSE SAVE SPACE FOR IT
OVLCCP: DCR	A 
	SUB	B	;SUBTRACT OUR PROGRAM SIZE
	MOV	H,A	;SAVE IN HL
;
;	AT THIS POINT, ADD IN ANY NECESSARY
;	CODE TO TEST L=6...THIS MAY BE NECESSARY
;	TO DETERMINE IF THIS CODE IS ALREADY IN
;	MEMORY
;
	MVI	L,0	;RELOC ADRS MUST BE ON PAGE BOUNDARY
MOVE:	XCHG		;SHIFT GEARS
	PUSH	B	;SAVE COUNT
	PUSH	D	;AND REL ADRS
MOVLOP: MOV	A,B	;CHECK COUNT FOR ZERO
	ORA	C
	JZ	RELOC	;EXIT LOOP WHEN COUNT=0
	DCX	B	;COUNTDOWN
	MOV	A,M	;PICK UP
	STAX	D	;PUT DOWN
	INX	D	;BUMP POINTERS
	INX	H
	JMP	MOVLOP	;AND LOOP
;
;	THE CODE HAS BEEN MOVED, NOW RELOCATE
;	IT AT IT'S NEW LOCATION.
;
RELOC:	POP	D	;GET RELOC ADRS
	POP	B	;GET BACK COUNT
	PUSH	H	;SAVE BITMAP POINTER
	MOV	H,D	;BASE PAGE ADDRESS IN H
RLOOP:	MOV	A,B	;TEST COUNT FOR ZERO
	ORA	C
	JZ	FINISH	;EXIT LOOP WHEN COUNT=0
	DCX	B	;BUMPDOWN COUNT
	MOV	A,E	;CHECK BYTE BOUNDARY..
	ANI	7	;..OF BIT MAP
	JNZ	NOT8	;SKIP IF NOT OUT OF BITS
	XTHL		;ELSE GET BITMAP POINTER
	MOV	A,M	;GET NEXT BYTE FROM BITMAP
	INX	H	;POINT AHEAD
	XTHL		;RESTORE THINGS
	MOV	L,A	;BITMAP BYTE GOES IN L
NOT8:	MOV	A,L	;TEST NEXT BIT
	RAL
	MOV	L,A	;PUT SHIFTED BIT BACK FOR NXT TIME
	JNC	NOTREL	;BITS THAT ARE ZERO ARE NOT RELOC'ED
	LDAX	D	;ELSE GET NEXT BYTE INTO ACCUMULATOR
	ADD	H	;ADD BASE PAGE
	STAX	D	;STORE IT BACK RELOCATED
NOTREL: INX	D	;BUMP PROGRAM POINTER
	JMP	RLOOP	;THEN LOOP
FINISH: POP	D
	MVI	L,0
	PUSH	H	;SAVE ADRS TO JMP TO FOR LATER
;
;	INSERT ANY CODE NEEDED BEFORE BRANCH
;	TO PROGRAM AT THIS POINT.
;
	IF	BYE	;DO THIS STUFF FOR BYE PROGRAM
	MVI	A,0C3H	;CLEAR ANY TRAPS SO SYSOP..
	STA	0	;CAN USER "BYE /A"
	XRA	A	;NEXT WARMBOOT TO USR0/DRV A
	STA	4
	MVI	C,14	;MAKE DRIVE A DEFAULT
	MOV	E,A	;LOG-IN DRIVE CP/M FUNCTION
	CALL	BDOS
	ENDIF		;OF (IF BYE)
;
	IF	CPM2 AND BYE ;SET USER 0
	MVI	C,32	;GET/SET USR CP/M FUNCTION
	MVI	E,COMUSR
	CALL	BDOS
	ENDIF		;OF (IF CPM2 AND BYE)
;
	RET		;TO ADRS PUSH'ED ABOVE


