;		LSTPATCH.ASM ver 1.0
;	      by Keith Petersen, W8SDZ
;		  (revised 12/29/84)
;
;This program moves an alternate list driver into high
;memory and then patches CP/M to use it instead of the
;regular CBIOS list routine.  The patch will remain
;intact until the next cold boot.
;
;Why this is useful: if your list driver is too long
;to fit into your CBIOS or the list STAT routine is
;not implemented, this program can be used to patch it
;in after CP/M is booted.  Another use would be if
;a temporary list driver is needed for an otherwise
;unimplemented port.
;
;------------------------------------------------
;Change the following equate to an area in your high
;memory where the alternate list driver may be located
;without interference to or from CP/M.
;
DEST	EQU	0FB80H		;running location of code
;
;------------------------------------------------
;
;Define I/O ports and status bits
;
LISTS	EQU	02H		;list status port
LISTD	EQU	03H		;list data port
LISRDY	EQU	80H		;list trans. buf. empty
;
CR	EQU	0DH		;carriage return
LF	EQU	0AH		;line feed
NULL	EQU	00H		;null character
BDOS	EQU	0005H		;BDOS entry adrs
;
	ORG	100H
;
;Move the console and list drivers up to high ram
;
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
;
;now patch cp/m to use the new drivers
	LHLD	1		;get CP/M jump table adrs
	LXI	D,13		;ready to add 13
	DAD	D		;HL = LISTOUT + 1
;
	MVI	M,LISOUT AND 0FFH ;modify LSB jmp adrs
	INX	H
	MVI	M,LISOUT SHR 8	  ;modify MSB jmp adrs
	LXI	D,29		  ;ready to add 29
	DAD	D		  ;hl = lststat + 1
	MVI	M,LSTSTAT AND 0FFH ;modify LSB jmp adrs
	INX	H
	MVI	M,LSTSTAT SHR 8	   ;modify MSB jmp adrs
;
;Print message saying what has been done, then exit to CP/M
	LXI	D,MSG		;point to message
	MVI	C,9		;bdos print string function
	JMP	BDOS		;print msg then return to CCP
;
MSG:	DB	'++Alternate LIST driver now patched++',CR,LF,'$'
;
SOURCE	EQU	$		;boundary memory marker
;
OFFSET	EQU	DEST-SOURCE	;reloc amount
;-----------------------------------------------;
;	The following code gets moved		;
;	to high RAM located at "DEST"		;
;-----------------------------------------------;
;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 high	xx
;xx	RAM 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
;
;This is the new list output routine
LISOUT	EQU	$+OFFSET
	IN	LISTS		;get list status
	ANI	LISRDY		;ready for character?
	JZ	LISOUT		;no, loop and wait
	MOV	A,C		;get character
	ANI	7FH		;strip parity
	OUT	LISTD		;send to printer
	CPI	LF		;was it a line feed?
	RNZ			;no, return
;
;Send null to printer to allow time for carriage to return
	MVI	C,NULL		;get a null
	CALL	LISOUT		;send it to printer
	MVI	C,LF		;restore line feed
	RET
;
;This is the new list status routine
LSTSTAT	EQU	$+OFFSET
	IN	LISTS		;get list status
	ANI	LISRDY		;ready for character?
	MVI	A,0
	RZ			;no, return with 0
	CMA			;else make it 0ffh
	RET
;
PEND	EQU	$+OFFSET	;end of relocated code
;
	END
