;  DISK OPERATING SYSTEM
;  OF CP/NET NOS  NO DISK OPERATION
;
;  1982.8.30.  FOR NOS
;
TITLE	BASIC OPERATING SYSTEM FOR NOS CP/NET SYSTEM
;
;  EQUATIONS OF SYSTEM POINTER IN LOWER ADDRESS
;
RBOOT	EQU	0		;SYSTEM REBOOT ENTRY
IOSTS	EQU	3		;I/O STATUS
CDISK	EQU	4		;CURRENT DISK & USER CODE
ENBDS	EQU	5		;BDOS ENTRY
SYSDM	EQU	80H		;SYSTEM DMA ADDRESS
;
;  BDOS USER CODE AREA
;
BDOS:
	DB	0,0,0,0,0,0
;
BDOSS:				;ENTRY OF BDOS FROM +6
	JMP	BDOST
;
;  ERROR PROCESS ROUTINE TABLE
;
AFLRW:	DW	EFLRW		;DISK READ WRITE ERROR
ADRIV:	DW	EDRIV		;DISK SELECT ERROR
ADKCG:	DW	EDKCG		;R/O DISK ERROR
ADKCH:	DW	EDKCH		;R/O FILE ERROR
;
;  MAIN ROUTINE OF BDOS
;  INPUT
;   C:NUMBER OF BDOS FUNCTION
;  DE:PARAMETER OF INPUT
;  OUTPUT
;   A:PARAMETER OF OUTPUT WHEN ONE BYTE OR LOWER DATA
;   B:PARAMETER OF OUTPUT HIGHER DATA WHEN DOUBLE BYTES
;  HL:PARAMETER OF DOUBLE BYTES
;
BDOST:
	XCHG
	SHLD	INPAR		;SAVE INPUT PARAMETER
	XCHG
	LXI	H,0
	SHLD	OTPAR		;CLEAR OUTPUT PARAMETERS
	DAD	SP
	SHLD	INSTK		;SAVE STACK POINTER
	LXI	SP,STACK	;SET BDOS STACK
	LXI	H,BDOSE		;END OF ROUTINE
	PUSH	H		;SAVE RETURN ADDRESS
	MOV	A,C
	CPI	41
	RNC			;CALL NUMBER OVER
	MOV	C,E		;SAVE ONE BYTE DATA
	LXI	H,MINDX		;MAIN INDEX OF FUNCTION
	MOV	E,A
	MVI	D,0
	DAD	D
	DAD	D
	MOV	E,M
	INX	H
	MOV	D,M		;GET ROUTINE ADDRESS
	LHLD	INPAR		;GET INPUT PARAMETER
	XCHG
	PCHL			;TO EACH ROUTINE
;
;  MAIN INDEX OF BODS FUNCTIONS
;
MINDX:
	DW	WBOOT		;BOOT	  			0
	DW	MCNIN		;CONSOLE INPUT
	DW	MCNOT		;CONSOLE OUTPUT
	DW	MREAD		;READER INPUT
	DW	PUNCH		;PUNCHER OUTPUT
	DW	LIST		;LIST OUTPUT			5
	DW	MDCIO		;DIRECT CONSOLE I/O
	DW	MGIOB		;GET I/O BYTE
	DW	MSIOB		;SET I/O BYTE
	DW	MBFPR		;PRINT STRING
	DW	MBFRD		;READ CONSOLE BUFFER    	10
	DW	MSNCN		;GET CONSOLE STATUS
	DW	MVSNM		;GET VERSION NUMBER
	DW	MSNCR		;INITIALIZE
	DW	MDVSL		;SELECT DRIVE
	DW	MDKDUM		;OPEN FILE			15
	DW	MDKDUM		;CLOSE FILE
	DW	MDKDUM		;SEARCH FILE
	DW	MDKDUM		;SEARCH FOR NEXT
	DW	MDKDUM		;DELETE FILE
	DW	MDKDUM		;READ SEQUENTIAL		20
	DW	MDKDUM		;WRITE SEQUENTIAL
	DW	MDKDUM		;MAKE FILE
	DW	MDKDUM		;RENAME FILE
	DW	MSNCR		;GET LOG-IN VECTOR
	DW	MSNCR		;GET CURRENT DRIVE		25
	DW	MSNCR		;SET DMA ADDRESS
	DW	MDKDUM		;GET ALLOCATION MAP POINT
	DW	MDKDUM		;SET WRITE PROTECT FLAG
	DW	MDKDUM		;GET WRITE PROTECT FLAG ADDRESS
	DW	MDKDUM		;SET FILE ATTRIBUTES		30
	DW	MDKDUM		;GET DISK PARAMETER ADDRESS
	DW	MUSER		;SET OR GET USER CODE
	DW	MDKDUM		;READ RANDOM
	DW	MDKDUM		;WRITE RANDOM
	DW	MDKDUM		;COMPUTE FILE SIZE		35
	DW	MDKDUM		;GET RANDOM RECODE
	DW	MDKDUM		;RESET DRIVE
	DW	MSNCR		;NOT USE
	DW	MSNCR		;NOT USE
	DW	MDKDUM		;WRITE RANDOM WITH FILL ZERO	40
;
;  ERROR COMMENT OUT ROUTINES
;
;  DISK READ WRITE ERROR
;
EFLRW:
	LXI	H,CFLRW
	CALL	ERPRN		;"BDOS ERR ON "X": BAD SECTOR"
	CPI	03H		;CONTROL-C "REBOOT CODE"
	JZ	RBOOT		;TO REBOOT
	RET
;
;  DISK SELECT ERROR
;
EDRIV:
	LXI	H,CDRIV		;"SELECT"
	JMP	EDKCH+3
;
;  READ ONLY ERROR
;
EDKCG:
	LXI	H,CDKCG		;"R/O"
	JMP	EDKCH+3
EDKCH:
	LXI	H,CDKCH		;"FILE R/O"
	CALL	ERPRN		;"BDOS ERR ON "X": ..."
	LXI	H,CDISK
	MOV	A,M
	ANI	0F0H
	MOV	M,A		;TO DISK A:
	JMP	RBOOT		;TO REBOOT
;
;  ERROR COMMENT CODES
;
CERPN:	DB	'Bdos Err On : $'
CFLRW:	DB	'Bad Sector$'
CDRIV:	DB	'Select$'
CDKCH:	DB	'File '
CDKCG:	DB	'R/O$'
;
;  ERROR COMMENT OUT & KEY RESPONSE WAIT
;  INPUT
;  HL:ADDRESS OF COMMENT
;
ERPRN:
	PUSH	H		;SAVE COMMENT INDEX
	CALL	CRLF		;CARRIAGE RETURN & LINE FEED
	LDA	NDRIV		;DRIVE NUMBER
	ADI	'A'
	STA	CERPN+12	;SET CODE TO COMMENT
	LXI	B,CERPN
	CALL	BFPRN		;"BDOS ERR ON "X": "
	POP	B
	CALL	BFPRN		;PRINT EACH COMMENT
;
;  CONSOLE I/O ROUTINES
;
;  CONSOLE INPUT WITH CONSOLE INTERRUPT CODE CHECK
;  OUTPUT
;   A:CODE OF INPUT
;
CONSI:
	LXI	H,INCON		;CONSOLE INTERRUPT CODE
	MOV	A,M		;GET CODE
	MVI	M,0		;CLEAR CODE
	ORA	A
	RNZ			;NOW CODE HAS BEEN SET
	JMP	CONIN		;TO NORMAL CONSOLE INPUT
;
;  CONSOLE INPUT WITH CONTROL CODE TREATMENT
;
CONCI:
	CALL	CONSI		;CONSOLE INPUT
	CALL	CONCK		;CONTROL CODE CHECK
	RC			;CONTROL CODE
	PUSH	PSW		;NORMAL CODE
	MOV	C,A
	CALL	PRINS		;PRINT WITH TAB TREATMENT
	POP	PSW
	RET
;
;  CONTROL CODE CHECK EXCEPT CR,LF,HTAB,BACK SPACE
;  INPUT
;   A:CODE
;  OUTPUT
;  CF:ON CONTROL CODE
;
CONCK:
	CPI	0DH		;CARRIAGE RETURN
	RZ
	CPI	0AH		;LINE FEED
	RZ
	CPI	09H		;HORIZONTAL TAB
	RZ
	CPI	08H		;BACK SPACE
	RZ
	CPI	20H		;SPACE
	RET
;
;  CONSOLE INTERRUPT CHECK ROUTINE
;  OUTPUT
;   A:0=NO INTERRUPT, 1=INTERRUPTED & CODE IS IN "INCON"
;
CONIT:
	LDA	INCON		;CONSOLE INTERRUPT CODE
	ORA	A
	JNZ	CONIG+3		;NOW INTERRUPTED
	CALL	CONST		;GET STATUS
	ANI	1		;CHECK READY
	RZ			;NO INPUT
	CALL	CONIN		;GET INPUT
	CPI	13H		;CONTROL-S "FREEZE"
	JNZ	CONIG
	CALL	CONIN		;FREEZE THE SYSTEM TO NEXT INPUT
	CPI	03H		;CONTROL-C "REBOOT"
	JZ	RBOOT		;NOW REBOOT
	XRA	A		;NOW CODE IS IGNORED
	RET
CONIG:				;GET CODE
	STA	INCON		;SET CODE
	MVI	A,1		;SET FLAG OF GETTING
	RET
;
;  PRINT TO CONSOLE WITH CONSOLE INTERRUPT CHECK
;  INPUT
;   C:PRINT CODE
;
PRINT:
	LDA	ECHKL		;GET ECHO KILL MODE
	ORA	A
	JNZ	PRINK		;NOW ECHO KILL
	PUSH	B
	CALL	CONIT		;CHECK CONSOLE INTERRUPT
	POP	B		;GET PRINT CODE
	PUSH	B
	CALL	CONOT		;CONSOLE OUT THE CHARACTER
	POP	B		;GET PRINT CODE
	PUSH	B
	LDA	OTLST		;GET LIST OUT MODE
	ORA	A
	CNZ	LIST		;LIST OUT
	POP	B
PRINK:
	MOV	A,C
	LXI	H,PCARI		;CARRIAGE POSITION
	CPI	7FH
	RZ			;DELETE CODE
	INR	M		;UP THE CARRIAGE POSITION
	CPI	20H
	RNC			;NOW PRINTING CHARACTER
	DCR	M		;CONTROL CODE
	MOV	A,M
	ORA	A
	RZ
	MOV	A,C
	CPI	08H		;BACK SPACE
	JNZ	$+5
	DCR	M
	RET
	CPI	0AH		;LINE FEED
	RNZ			;NOT LINE FEED
	MVI	M,0		;RESET THE COUNTER
	RET
;
;  PRINT WITH CONTROL CODE VISIBLE
;  INPUT
;   C:CODE
;
PRINC:
	MOV	A,C
	CALL	CONCK		;CONTROL CODE CHECK
	JNC	PRINS		;NORMAL CODE
	PUSH	PSW		;CONTROL CODE
	MVI	C,5EH		;UPER ARROW IS CONTROL CODE MARK
	CALL	PRINT
	POP	PSW
	ORI	40H		;MAKE TO VISIBLE CODE
	MOV	C,A
;
;   2:CONSOLE OUTPUT
;
MCNOT:
PRINS:
	MOV	A,C
	CPI	09H		;HORIZONTAL TAB
	JNZ	PRINT		;OTHER CODE
	MVI	C,20H
	CALL	PRINT		;SPACE PRINT
	LDA	PCARI
	ANI	07H		;CHECK CARRIAGE POSITION
	JNZ	$-10		;TO TAB LOOP
	RET
;
;  BACK SPACE WITH ERASE ON CRT
;
BACKS:
	CALL	BACK
	MVI	C,20H
	CALL	CONOT		;ERASE
BACK:
	MVI	C,08H
	JMP	CONOT
;
;  PRINT "#" & CRLF
;
NCRLF:
	MVI	C,23H		;"#"
	CALL	PRINT
	CALL	CRLF
NCRLL:
	LDA	PCARI		;GET CARIAGE POSITION
	LXI	H,PPROM
	CMP	M
	RNC
	MVI	C,20H
	CALL	PRINT
	JMP	NCRLL
;
;  CARIAGE RETURN & LINE FEED
;
CRLF:
	MVI	C,0DH		;CARRIAGE RETURN
	CALL	PRINT
	MVI	C,0AH		;LINE FEED
	JMP	PRINT
;
;  BUFFERED CHARACTER PRINT END BY "$"
;  INPUT
;  BC:BUFFER TOP ADDRESS
;
BFPRN:
	LDAX	B		;GET CODE
	CPI	24H		;"$"
	RZ			;END CODE
	INX	B
	PUSH	B
	MOV	C,A
	CALL	PRINS		;PRINT WITH TAB TREATMENT
	POP	B
	JMP	BFPRN		;TO NEXT CODE
;
;  10:READ CONSOLE BUFFER
;
MBFRD:
	LDA	PCARI
	STA	PPROM		;SET PROMPT POSITION
	LHLD	INPAR		;GET CHARACTER BUFFER
	MOV	C,M		;GET MAXIMUM BUFFER LENGTH
	INX	H
	PUSH	H		;SAVE POINTER OF CURRENT LENGTH COUNTER
	MVI	B,0		;RESET COUNTER
STREL:				;ONE CHARACTER LOOP
	PUSH	B
	PUSH	H
	CALL	CONSI
	POP	H
	POP	B
	CPI	0DH		;CARIAGE RETURN
	JZ	STREE		;GET END CODE
	CPI	0AH		;LINE FEED
	JZ	STREE		;GET END CODE
	CPI	08H		;BACK SPACE
	JNZ	STREK
	MOV	A,B
	ORA	A
	JZ	STREL		;COUNT IS ZERO
	DCR	B
	LDA	PCARI
	STA	ECHKL		;SET ECHO KILL COUNT
	JMP	STREI
STREK:
	CPI	7FH		;RUBOUT IS LAST CHARACTER DELETE
	JNZ	STREA
	MOV	A,B
	ORA	A		;COUNTER CHECK
	JZ	STREL		;THERE IS NO CHARACTER
	MOV	A,M		;GET LAST CODE
	DCR	B		;DOWN OF POINTER & COUNTER
	DCX	H
	JMP	STRES		;TO PRINT
STREA:
	CPI	05H		;CONTROL-E "ONLY LINE CHANGE"
	JNZ	STREB
	PUSH	B
	PUSH	H
	CALL	CRLF		;LINE CHANGE
	XRA	A
	STA	PPROM		;PROMPT POSITION TOP
	JMP	STREL+2		;TO NEXT READ
STREB:
	CPI	10H		;CONTROL-P "LIST MODE CHANGE"
	JNZ	STREC
	PUSH	H
	LXI	H,OTLST		;LIST OUT MODE
	MVI	A,01H
	SUB	M		;CHANGE LIST OUT MODE
	MOV	M,A
	POP	H
	JMP	STREL		;TO NEXT
STREC:
	CPI	18H		;CONTROL-X CANCEL OF NOW SET
	JNZ	STREY
	POP	H
STREX:				;CANSEL BY ERASE
	LDA	PPROM		;PROMPT POSITION
	LXI	H,PCARI
	CMP	M
	JNC	MBFRD		;NOW TO TOP
	DCR	M
	CALL	BACKS		;ERASE BACK
	JMP	STREX		;ERASE LOOP
STREY:
	CPI	15H		;CONTROL-U "CANCEL OF NOW SET"
	JNZ	STREF
	CALL	NCRLF		;"#" & CR,LF
	POP	H
	JMP	MBFRD		;TO START POINT
STREF:
	CPI	12H		;CONTROL-R "CHANGE LINE & PRINT LEFT CODES"
	JNZ	STREN		;NORMAL CODE
STREI:
	PUSH	B
	CALL	NCRLF		;"#" & CR,LF
	POP	B
	POP	H		;GET POINTERS
	PUSH	H
	PUSH	B
STREG:				;PRINT LEFT CODES
	MOV	A,B		;COUNT OF LEFT CODE
	ORA	A
	JZ	STREH		;END OF PRINT
	INX	H
	MOV	C,M		;GET CODE
	DCR	B
	PUSH	B
	PUSH	H
	CALL	PRINC		;PRINT WITH CONTROL CODE VISIBLE
	POP	H
	POP	B
	JMP	STREG		;TO NEXT CHARACTER PRINT
STREH:
	PUSH	H
	LDA	ECHKL
	ORA	A
	JZ	STREL+2		;NORMAL MODE
	LXI	H,PCARI
	SUB	M
	STA	ECHKL
	CALL	BACKS		;BACK TO LAST POSITION
	LXI	H,ECHKL
	DCR	M
	JNZ	$-7
	JMP	STREL+2
STREN:				;NORMAL CODES
	INX	H
	MOV	M,A		;SET CODE & POINTER UP
	INR	B		;COUNTER UP
STRES:				;ECHO PRINT
	PUSH	B
	PUSH	H
	MOV	C,A
	CALL	PRINC		;PRINT WITH CONTROL CODE VISIBLE
	POP	H
	POP	B
	MOV	A,M
	CPI	03H		;CONTROL-C "REBOOT"
	MOV	A,B
	JNZ	$+8
	CPI	01H		;THE FIRST CODE
	JZ	RBOOT		;TO REBOOT
	CMP	C
	JC	STREL		;TO NEXT READ
STREE:
	POP	H		;BUFFER FULL OR CR END
	MOV	M,B
	MVI	C,0DH
	JMP	PRINT		;PRINT CARRIAGE RETURN & END
;
;   1:CONSOLE INPUT
;
MCNIN:
	CALL	CONCI		;CONSOLE INPUT
	JMP	MOPST
;
;   3:READER INPUT
;
MREAD:
	CALL	READR		;READ ONE BYTE
	JMP	MOPST
;
;   6:DIRECT CONSOLE I/O
;  INPUT
;   C:-1  INPUT    -2 GET STATUS    OTHER OUTPUT
;
MDCIO:
	MOV	A,C
	INR	A
	JZ	MDCIS		;INPUT MODE
	INR	A
	JZ	CONST		;STATUS READ
	JMP	CONOT		;DIRECT OUT
MDCIS:
	CALL	CONST
	ORA	A
	JZ	BDOSE		;NOT READY
	CALL	CONIN		;CONSOLE INPUT
	JMP	MOPST
;
;   7:GET I/O BYTE
;
MGIOB:
	LDA	IOSTS		;GET DATA
	JMP	MOPST
;
;   8:SET I/O BYTE
;
MSIOB:
	LXI	H,IOSTS
	MOV	M,C		;SET DATA
	RET
;
;   9:PRINT STRING  TERMINATED BY "$"
;
MBFPR:
	XCHG
	MOV	C,L
	MOV	B,H		;GET INDEX POINT
	JMP	BFPRN		;PRINT
;
;  11:GET CONSOLE STATUS
;
MSNCN:
	CALL	CONIT
MOPST:
	STA	OTPAR		;SET OUTPUT PARAMETER
MSNCR:
	RET
;
;  SET ERROR FLAG TO OUTPUT PARAMETER AREA
;
STOTP:
	MVI	A,1
	JMP	MOPST
;
;  12:GET VERSION NUMBER
;
MVSNM:
	MVI	A,22H		;VERSION 2.2
	JMP	MOPST
;
;  32:SET OR GET USER NUMBER
;
MUSER:
	LDA	INPAR
	CPI	-1
	JNZ	MUSES		;SET MODE
	LDA	MDUSR		;GET MODE
	JMP	MOPST
;
MUSES:				;SET MODE
	ANI	1FH
	STA	MDUSR
	RET
;
;  DATA AREA FOR BASIC I/O
;
ECHKL:	DB	0		;ECHO KILL COUNT
PPROM:	DB	0		;PROMPT POSITION
PCARI:	DB	0		;CONSOLE CARRIAGE POSITION COUNTER
OTLST:	DB	0		;LIST OUTPUT MODE  0 NOT OUT
INCON:	DB	0		;CONSOLE INTERRUPT CODE
INSTK:	DS	2		;USER STACK POINTER SAVE BUFFER
	DS	48
STACK:				;SYSTEM STACK
MDUSR:	DB	0		;USER MODE
NDRIV:	DB	0		;DRIVE NUMBER
INPAR:	DW	0000H		;INPUT PARAMETER BUFFER
OTPAR:	DW	0000H		;OUTPUT PARAMETER BUFFER
;
;  DISK OPERATION ROUTINES
;
;  14:SELECT DISK
;
MDVSL:
	LDA	INPAR		;GET DISK NUMBER
	STA	NDRIV		;SET AS CURRENT DISK
;
;  ERROR ROUTINES
;
DNERR:				;DRIVE NUMBER ERROR
	LXI	H,ADRIV
ERROR:				;JUMP TO EACH ROUTINE
	MOV	E,M
	INX	H
	MOV	D,M
	XCHG
	PCHL
;
;  DUMMY FOR DISK OPERATION
;
MDKDUM:
	LXI	H,-1
	SHLD	OTPAR		;SET ERROR FLAG TO OUTPUT DATA
	RET
;
;  BDOS END PROCESS
;
BDOSE:
	LHLD	INSTK
	SPHL			;SET STACK POINTER
	LHLD	OTPAR
	MOV	A,L
	MOV	B,H		;SET RETURN PARAMETER
	RET
;
;
	ORG	(($-BDOS+256) AND 0FF00H)-1
	DB	0
;
;
;  POINTERS TO BASIC I/O SYSTEM
;
BOOT	EQU	$		;COLD START BOOTING
WBOOT	EQU	$+3		;WARM BOOTING
CONST	EQU	$+6		;CONSOLE STATUS
CONIN	EQU	$+9		;CONSOLE INPUT
CONOT	EQU	$+12		;CONSOLE OUTPUT
LIST	EQU	$+15		;LIST OUTPUT
PUNCH	EQU	$+18		;PUNCH OUTPUT
READR	EQU	$+21		;READER INPUT
HOME	EQU	$+24		;MOVE DISK TO TRACK ZERO
SELDK	EQU	$+27		;SELECT DISK DRIVE
SETRK	EQU	$+30		;SET TRACK NUMBER
SETSC	EQU	$+33		;SET SECTOR NUMBER
SETDM	EQU	$+36		;SET DMA ADDRESS
READ	EQU	$+39		;READ ONE SECTOR
WRITE	EQU	$+42		;WRITE ONE SECTOR
LISTS	EQU	$+45		;LIST STATUS
SCTRN	EQU	$+48		;SECTOR TRANSLATE
;
;
	END
