;
;	SECURITY4.ASM	(revised 08/06/82)
;	by Keith Petersen and Bob Mathias
;
;THIS PROGRAM RUNS UP IN HIGH RAM.  IT GETS THERE
;BY BEING MOVED THERE WHEN 'MINICBBS' IS TYPED.
;
;THE PROGRAM IN HI RAM DOES THE FOLLOWING:
;
;LOADS AND EXECUTES FILE 'RIBBS.EXE' FROM USER 15
;ON DRIVE B:
;
;------------------------------------------------
;CHANGE THE FOLLOWING EQUATE TO AN AREA IN YOUR
;HI MEMORY WHERE THIS PROGRAM MAY PATCH ITSELF IN.
;
DEST	EQU	0C500H		;RUNNING LOCATION OF CODE
;
;------------------------------------------------
;
BASE	SET	0
ALTCPM	EQU	0		;PUT 1 HERE FOR ALTERNATE CPM
	IF	ALTCPM
BASE	SET	4200H
	ENDIF
PRINT	EQU	9
OPEN	EQU	15
STDMA	EQU	26
SGUSR	EQU	32		;SET/GET USER FUNCTION
BDOS	EQU	BASE+5
FCB	EQU	BASE+5CH 
FCBEXT	EQU	FCB+12
FCBRNO	EQU	FCB+32
;
CR	EQU	0DH
LF	EQU	0AH
;
	ORG	BASE+100H
;
;MOVE THE PROGRAM UP TO HI RAM AND JUMP TO IT.
;
MOVEUP	LXI	B,PEND-START+1		;NUMBER OF BYTES TO MOVE
	LXI	H,DEST+PEND-START+1	;END OF MOVED CODE
	LXI	D,SOURCE+PEND-START	;END OF SOURCE CODE
MVLP	LDAX	D		;GET BYTE
	DCX	H		;BUMP POINTERS
	MOV	M,A		;NEW HOME
	DCX	D
	DCX	B		;BUMP BYTE COUNT
	MOV	A,B		;CHECK IF ZERO
	ORA	C
	JNZ	MVLP		;IF NOT, DO SOME MORE
	PCHL			;JUMP TO "START"
;
SOURCE	EQU	$		;BOUNDARY MEMORY MARKER
;
OFFSET	EQU	DEST-SOURCE	;RELOC AMOUNT
;-----------------------------------------------;
;	THE FOLLOWING CODE GETS MOVED		;
;	 TO HI RAM LOCATED AT "DEST",		;
;	    WHERE IT IS EXECUTED.		;
;-----------------------------------------------;
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;XX   C A U T I O N :  IF MODIFYING ANYTHING 	XX
;XX 	IN THIS PROGRAM FROM HERE ON: 		XX
;XX  	A-L-L  LABELS MUST BE OF THE FORM:	XX
;XX	label	EQU	$+OFFSET		XX
;XX	IN ORDER THAT THE RELOCATION TO HI RAM 	XX
;XX	WORK SUCCESSFULLY.  FORGETTING TO	XX
;XX	SPECIFY '$+OFFSET' WILL CAUSE THE PRO-	XX
;XX	GRAM TO JMP INTO WHATEVER IS CURRENTLY	XX
;XX	IN LOW MEMORY, WITH UNPREDICTABLE	XX
;XX	RESULTS.  BE CAREFUL....		XX
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;
START	EQU	$+OFFSET
	LXI	SP,STACK	;SET UP LOCAL STACK POINTER
;
;SET USER NUMBER TO 15
;
	MVI	E,15		;E = USER 15
	MVI	C,SGUSR
	CALL	BDOS
;
;SAVE PAGE 0 TO RESTORE BEFORE JUMPING TO LOADED PROGRAM
;
	LXI	H,BASE+5CH
	LXI	D,PAGSAV
	MVI	B,100H-5CH
	CALL	MOVE
;
;LOAD AND EXECUTE FILE
;
	LXI	H,FILENAM	;SOURCE
	LXI	D,FCB		;DESTINATION
	MVI	B,13		;LENGTH
	CALL	MOVE		;MOVE THE NAME
;
;SET DMA ADDR TO 80H

	LXI	D,BASE+80H
	MVI	C,STDMA
	CALL	BDOS
;
;OPEN THE FILE
;
	LXI	D,FCB
	MVI	C,OPEN
	CALL	BDOS
;
;DID IT EXIST?
;
	INR	A		;A=> 0 MEANS "NO"
	JZ	BYERR		;NO FILE, EXIT ERROR MSG
;
OPENOK:	EQU	$+OFFSET
	LXI	D,BASE+100H	;POINT TO TPA
;
READLP:	EQU	$+OFFSET
	PUSH	D		;SAVE BUFFER ADDRESS
	PUSH	B
	PUSH	H
	MVI	C,STDMA
	CALL	BDOS
;
;READ A SECTOR
;
	LXI	D,FCB
	MVI	C,20		;READ
	CALL	BDOS
	POP	H
	POP	B
	ORA	A		;OK?
	JNZ	EOF		;NOT OK, MUST BE EOF
	POP	D		;GET DMA ADDR
	LXI	H,80H		;LENGTH OF 1 SECT.
	DAD	D		;CALC NEXT BUFF ADDR
	XCHG			;PUT IT BACK IN DE
	JMP	READLP		;LOOP
;
;GOT RETURN CODE ON READ, SEE IF ERROR OR EOF
;
EOF:	EQU	$+OFFSET
	POP	D		;DELETE STACKED BUFFER ADDR
;
;A HAS RETURN CODE FROM READ

	DCR	A		;EOF?
	JZ	RSDMA		;YES, EXIT
;
;READ ERROR - EXIT WITH MSG
;
BYERR:	EQU	$+OFFSET
	CALL	ERXIT		;PRINT:
	DB	CR,LF,'++DISK READ ERROR++',CR,LF,'$'
;
;EXIT WITH ERROR MESSAGE
;
ERXIT:	EQU	$+OFFSET
	POP	D
	MVI	C,9
	CALL	BDOS
	XRA	A
	STA	BASE+4		;SET DRIVE A:, USER 0
	JMP	BASE
;
;RESET DMA ADDRESS TO NORMAL
;
RSDMA:	EQU	$+OFFSET
	LXI	D,BASE+80H
	MVI	C,STDMA
	CALL	BDOS
;
; RESTORE PAGE 0
;
	LXI	H,PAGSAV
	LXI	D,BASE+5CH
	MVI	B,100H-5CH
	CALL	MOVE
;
;LEAVE WARM BOOT ADDRESS ON STACK, THEN EXECUTE RIBBS
;
	LXI	H,0
	PUSH	H
	JMP	BASE+100H	;EXECUTE MINICBBS
;
;MOVE (HL) TO (DE), LENGTH IN (B)
;
MOVE:	EQU	$+OFFSET
	MOV	A,M		;GET A BYTE
	STAX	D		;PUT AT NEW HOME
	INX	D		;BUMP POINTERS
	INX	H
	DCR	B		;DEC BYTE COUNT
	JNZ	MOVE		;IF MORE, DO IT
	RET			;IF NOT,RETURN
;
FILENAM	EQU	$+OFFSET
	DB	3,'RIBBS   EXE',0
;FILENAME GOES HERE^^^^^^^^^^^
;DRIVE NAME HERE^		^EXTENT NR.
;
PEND	EQU	$+OFFSET	;END OF RELOCATED CODE
;
	DS	40
STACK	EQU	$+OFFSET	;LOCAL STACK
;
PAGSAV	EQU	STACK+1		;ADDRESS OF PAGE 0 SAVE AREA
	END

