	ORG	0DA00H	;ORIGIN FOR 56K SYSTEM

; This is the User Area source file from the North Star
; branded CP/M version 2.2, Rev 1.2.0 QD
;
; 6-10-17   Mike Douglas
;	Add FASTOFF assembly option to turn off drive
;	motors whenever CONIN is called. Since disk
;	activity is complete whenever a program is
;	waiting on user input, CONIN serves well as
;	a "disk idle" indicator. By turning the drive
;	motor off at this point, the long 9.6 sec wait
;	to remove or swap disks is avoided. Also, the
;	urge to type commands fast to beat the disk
;	shutdown is also avoided.
;
;***** USER AREA ***** USER AREA ***** USER AREA *****
;      SEQUENTIAL BASIC INPUT OUTPUT SYSTEM
;      PERFORMS CHARACTER INPUT/OUTPUT FOR THE
;      CP/M SEQUENTIAL DEVICES - CONSOLE & LIST
;
;THESE ROUTINES ARE FOR STANDARD HORIZON SYSTEMS
;MAY BE REPLACED IN EITHER THE SYSGEN-RAM-IMAGE AT
; 3200H-33FFH, OR IN SECTOR 8 (IN THE SYSTEM TRACK AREA),
; OR IN ITS ACTUAL EXECUTABLE LOCATION (DA00H-DBFFH IN 56K)

; Select FASTOFF disk option here (see revision history above)

FASTOFF	EQU	1

DISKOFF	EQU	0EB17H		;FDC reset command

;
;****** BEGINNING OF JUMP VECTOR **********************
;
USERBASE EQU	$	;MARK ORIGIN OF USER AREA
	JMP	INIT	;COLD BOOT INIT (USART & PARITY SETUP)
	JMP	CONTST	;CONSOLE TEST FOR INPUT
	JMP	CINL	;CONSOLE INPUT (LEFT PORT)
	JMP	COUTL	;CONSOLE OUTPUT(LEFT PORT)
PRTSER	JMP	COUTR	;SERIAL PRINTER(RIGHT SERIAL PORT)
	JMP	COUTL	;PUNCH TO CONSOLE
	JMP	CINL	;PAPER TAPE READER FROM CONSOLE
	JMP	PRTTST	;TEST PRINTER STATUS - NULL IMPLEMENTATION
PRTPAR	JMP	COUTP	;PARALLEL PRINTER (IF CPMGEN TOLD PARALLEL)
PRTP18	JMP	COUTP18	;PARALLEL PRINTER HUNG ON HD-18
;*** CPMGEN ALTERS BIOS+10H TO JUMP TO "PRTSER" OR "PRTPAR"
;     DEPENDING UPON PRINTER INTERFACE ANSWER.
;
;****** END OF DEFINED JUMP VECTOR ****************************
;
;
;
;
;*** STANDARD HORIZON USART I/O ROUTINES ***
;
;INPUT FROM STANDARD (LEFT) SERIAL PORT
CINL	EQU	$

 IF FASTOFF
	LDA	DISKOFF	;RESET DISK CONTROLLER (MOTOR OFF)
 ENDIF
	
CINLL	IN	3	;GET STATUS FOR LEFT SERIAL PORT
	NOP		;ROOM FOR PATCHING 
	ANI	2	;RCVR READY ?
	JZ	CINLL	;NO, KEEP TESTING
	IN	2	;GET THE ACTUAL CHARACTER
	NOP		;ROOM FOR PATCHING 
	ANI	7FH	;STRIP PARITY BIT (D7)
	RET		;RETURN WITH CHAR IN A REGISTER
;
;INPUT FROM SECONDARY (RIGHT) SERIAL PORT
CINR	IN	5	;GET STATUS FOR RIGHT SERIAL PORT
	NOP		;ROOM FOR PATCHING 
	ANI	2	;RCVR READY ?
	JZ	CINR	;NO, LOOP TILL RECEIVED
	IN	4	;GET CHAR FROM DATA PORT
	NOP		;ROOM FOR PATCHING 
	ANI	7FH
	RET
;
;INPUT FROM PARALLEL PORT
CINP	IN	6	;MOTHERBOARD STATUS
	ANI	2	;PI FLAG
	JZ	CINP	;LOOP UNTIL DATA
	IN	0	;READ DATA FROM PARALLEL PORT
	PUSH	PSW	;SAVE BYTE
	MVI	A,30H	;RESET VALUE
	OUT	6	;RESET PI FLAG
	POP	PSW	;RESTORE INPUT BYTE
	NOP		;ROOM FOR PATCHING
	ANI	7FH	;CLEAR PARITY BIT
	RET
;
;CONSOLE INPUT PENDING TEST
CONTST	IN	3	;GET LEFT USART STATUS
	NOP		;ROOM FOR PATCHING
	ANI	2	;HAS BYTE BEEN RECEIVED?
	RZ		;NO, RETURN WITH ZERO IN A
	MVI	A,0FFH	;YES, RETURN WITH FFH IN A
	RET
;
;OUTPUT TO CONSOLE OR STANDARD (LEFT) SERIAL PORT
COUTL	IN	3	;GET STATUS
	NOP		;ROOM FOR PATCHING
	ANI	1	;IS TX READY?
	JZ	COUTL	;NO, LOOP UNTIL IT IS
	MOV	A,C	;GET BYTE TO SEND
	NOP		;ROOM FOR PATCHING
	OUT	2	;SEND IT
	RET		;DONE
;
;OUTPUT TO SECONDARY (RIGHT) SERIAL PORT (PRINTER)
COUTR	IN	5	;GET USART STATUS
	NOP		;ROOM FOR PATCHING
	ANI	1	;IS TX READY?
	JZ	COUTR	;LOOP TIL READY
	MOV	A,C	;BYTE FROM C TO A
	NOP		;ROOM FOR PATCHING
	OUT	4	;SEND BYTE VIA DATA PORT
	RET		;DONE
;
;OUTPUT TO PARALLEL PORT - IF CPMGEN TOLD THAT PRINTER
;       IS PARALLEL, JUMP VECTOR ALTERED TO JUMP HERE
COUTP	IN	6	;MOTHERBOARD STATUS
	ANI	1	;TEST PO FLAG
	JZ	COUTP	;EXTERNAL DEVICE NOT READY YET
	MVI	A,20H	;RESET THE FLAG
	OUT	6
	MOV	A,C	;CHAR TO BE SENT TO A
	NOP		;ROOM FOR PATCHING
TOGGLEP	ORI	80H	;SET STROBE FALSE
	OUT	0	;SEND CHARACTER
	XRI	80H	;TOGGLE STROBE TO TRUE
	OUT	0	;KEEP SENDING
	XRI	80H	;TOGGLE STROBE BACK TO FALSE
	OUT	0
	RET		;DONE
;
;
;NULL IMPLEMENTATION OF PRINTER TEST
PRTTST	XRA	A	;LEAVE ZERO IN A
	RET		;DONE
;
;*********** INITIALIZATION CODE ****************
;******* PERFORMED ONLY ON COLD BOOTSTRAP *******
INIT	NOP		;THREE NOP'S FOR PATCHING
	NOP
	NOP
;
;INITIALIZE MOTHER BOARD AND SERIAL PORTS
	XRA	A	;ZERO A
	OUT	6	;INIT MOTHERBOARD
	OUT	6	;REPETITIVELY
	OUT	6
	OUT	6
;STANDARD (LEFT) SERIAL PORT INITIALIZATION
	MVI	A,0CEH	;2 STOP BITS, 16X CLOCK
	OUT	3	;& 8 DATA BITS, NO PARITY
	MVI	A,37H	;CMD: RTS,ER,RXF,DTR,TXEN
	OUT	3
;SECONDARY(RIGHT)SERIAL PORT INITIALIZATION
	MVI	A,0CEH	;2 STOP BITS, 16X CLOCK
	OUT	5	;& 8 DATA BITS, NO PARITY
	MVI	A,37H	;CMD: RTS,ER,RXF,DTR,TXEN
	OUT	5
;
;PARITY INITIALIZATION
	MVI	A,40H	;DISABLE PARITY LOGIC
	OUT	0C0H	;BEFORE READING UNWRITTEN RAM
	LXI	H,0	;PREPARE TO CYCLE THROUGH RAM
;BEFORE SETTING PARITY FOR EACH KILOBYTE, CHECK IF REALLY RAM
TINKCK	MOV	A,M	;GET FIRST BYTE OF KBYTE
	CMA		;FORM ITS COMPLEMENT
	MOV	M,A	;CHANGE IT IN RAM
	CMP	M	;SEE IF CHANGED IN RAM
	CMA		;RESTORE IT
;***NOTE, THESE FEW BYTES BETTER NOT BE ON A 1K BOUNDARY
	MOV	M,A	;FOR THEY COULD ZAP THEMSELVES!!!
	JZ	TINPAR	;IS RAM, GO INITIALIZE IT
	INR	H	;NOT RAM, SO SKIP OVER
	INR	H	;THIS KILOBYTE
	INR	H
	JMP	TINKADV	;SKIP OVER INIT CODE
TINPAR	MOV	B,M	;READ BYTE FROM RAM
	MOV	M,B	;RESTORE IT WITH CORRECT PARITY
	INR	L	;INCREMENT LOW ORDER ADDR BYTE
	JNZ	TINPAR	;LOOP IF NOT END OF 256B BLOCK
TINKADV	INR	H	;INCREMENT BLOCK NUMBER
	JZ	TINU	;WRAPPED AROUND, EXIT
	MOV	A,H	;SEE IF ON 1K BOUNDARY
	ANI	3
	JNZ	TINPAR	;NO, TIGHT LOOP THRU ONE KILOBYTE
	JMP	TINKCK	;YES, TEST NEW KB FOR REAL RAM
;
;PARITY ALL CORRECT, ENABLE PARITY TESTING
TINU	MVI	A,41H	;TURN PARITY ON
	OUT	0C0H	;ON RAM BOARDS
;
;REMOVE ANY JUNK APPEARING IN INPUT PORTS
	IN	2	;FROM STD PORT
	IN	4	;FROM SECOND PORT
;
;INIT PARALLEL PORTS
	MVI	A,30H	;RESET PAR. INPUT FLAG
	OUT	6
	MVI	A,60H	;SET PAR. OUTPUT  FLAG
	OUT	6
;WRAP IT UP BY SENDING A CR TO THE PRINTER & EXIT
	MVI	C,0DH	;A CARRIAGE RETURN
	JMP	USERBASE-700H+15 ;GOTO PRINT JUMP IN BIOS VECTOR
;******* END OF INITIALIZATION CODE *********
;
;**** PARALLEL PRINTER OUTPUT WHEN HUNG ON HD-18 HARD DISK
COUTP18	MVI	A,20H	;SET COMMAND MODE
	OUT	6
	MVI	A,0FEH	;SELECT CONTROLLER 101
	OUT	0
	MVI	A,0E1H	;SET CTLER TO I/O MODE
	OUT	0
	MVI	A,60H	;SET DATA MODE
	OUT	6
P18WAIT	IN	6	;TEST CTLER'S PO FLAG
	ANI	8	;FOR READY
	JZ	P18WAIT	;LOOP UNTIL READY
	IN	0	;CLEAR CONTROLLER'S PO FLAG
	MOV	A,C	;CHARACTER TO SEND
	ORI	80H	;SET STROBE FALSE
	OUT	0	;PUT CHAR IN PORT
	XRI	80H	;TOGGLE STROBE *TRUE
	OUT	0
	XRI	80H
	OUT	0
	MVI	A,20H	;BACK TO COMMAND MODE
	OUT	6
	MVI	A,0FFH	;DESELECT CONTROLLER
	OUT	0
	RET		;DONE
;
;
; THE LAST 80H BYTES OF THIS 512 BYTE USER AREA IS NEEDED
; BY THE DISK BIOS FOR  TWO  SPECIAL  PURPOSES.
; 1. SUPPORT NON-STANDARD DISK CONTROLLER PROM ADDRESSES
; 2. AUTOSTART HDBOOT AND SUPPLY THE WORK-FILE PATHNAME
;    FOR NORTH STAR HARD DISK SYSTEMS.
;
; IF YOU HAVE NEITHER A NORTH STAR HARD DISK  
; NOR A NON-STANDARD MDS PROM ADDRESSES,
; THEN YOU MAY FREELY OVERWRITE THE AREA AND USE THE
; ENTIRETY OF SECTOR 8 IN THE SYSTEM TRACK AREA.
;
; IF YOU DO HAVE A HARD DISK OR NON-STANDARD MDS PROMS,
; THEN YOU MUST LEAVE THE LAST 80H BYTES INTACT.
; IN THE SYSGEN RAM IMAGE, YOU MUST LEAVE 3380H THRU
; 33FFH UNMODIFIED, USE ONLY 3200H-337FH FOR YOUR 
; REPLACEMENT USER AREA
