; dossys11/asm
;
*TITLE	'<DOS+II - SYS11/SYS - Series A.00>'
;
;	THIS SYSTEM IS HIGH RESIDING (2200-27FF)
;	IT CONTAINS THE FOLLOWING ROUTINES:
;
;	1 -	$ROUTE	- ROUTE DEVICE
;	2 -	$RESET	- RESET DEVICE
;	3 -	$SET	- SET DEVICE
;	4 -	$LINK	- LINK DEVICE
;	5 -	$FILTER - FILTER DEVICE
;
;	Created: 23-JUN-82	SJP/MSS
;	Revised: 23-JUN-82	SJP/MSS
;
*EJECT
;	LOCAL SUPPORT EQUIVALENCES
;
BADF	EQU	1		;BAD FUNCTION CALL
ERR3	EQU	3		;PARAMETER ERROR
ERR47	EQU	47		;PARAMETER NOT FOUND
ERR68	EQU	68		;ILLEGAL DEVICESPEC
ETX	EQU	3		;END OF TEXT
CR	EQU	13		;CARRIAGE RETURN
;
LD	EQU	01		;LD BC,NNNN
BUFER1	EQU	1A00H		;GENERAL BUFFER
DCB@1	EQU	BUFER1
;
;	EXTERNAL SVC EQUIVALENCES
;
VDCHAR	EQU	8		;VIDEO CHARACTER
BINDEC	EQU	21		;BINARY/DECIMAL CONV
BINHEX	EQU	24		;BINARY/HEX CONV
ERROR	EQU	39		;POST ERROR MESSAGE
OPEN	EQU	40		;OPEN DEVICE/FILE
CLOSE	EQU	42		;CLOSE DEVICE/FILE
EVAL	EQU	83		;EVALUATE CMD LINE
RUN	EQU	85		;LOAD/RUN PROGRAM
FEXT	EQU	88		;PLACE DEFAULT EXTENSIOND
;
;	EXTERNAL SUPPORT EQUIVALENCES
;
SVC	EQU	08H		;EXECUTE SVC
OVERLY	EQU	18H		;OVERLAY LOADER
;
DEVTBL	EQU	0100H		;DEVICE TABLE
DATAK7	EQU	0173H		;top free memory
TOPMEM	EQU	DATAK7		;TOP AVAIL MEMORY
REGSAV	EQU	0303H		;SAVE REGISTERS
LOCDCB	EQU	032AH		;LOCATE DCB
FETMEM	EQU	0330H		;FETCH AVAIL MEMORY
RECMEM	EQU	0333H		;RECLAIME MEMORY
;
*EJECT
;	TABLE OF VECTORED ROUTINES
;
	ORG	2200H		;HIGH OVERLAY
;
START	DEFW	RETURN		;0  - NOTHING DONE
	DEFW	ROUTE		;1  - ROUTE DEVICE
	DEFW	RESET		;2  - RESET DEVICE
	DEFW	SET		;3  - SET DEVICE
	DEFW	LINK		;4  - LINK DEVICE
	DEFW	FILTER		;5  - FILTER DEVICE
	DEFW	UNDEF		;6  - UNDEFINED
	DEFW	UNDEF		;7  - UNDEFINED
	DEFW	UNDEF		;8  - UNDEFINED
	DEFW	UNDEF		;9  - UNDEFINED
	DEFW	UNDEF		;10 - UNDEFINED
	DEFW	UNDEF		;11 - UNDEFINED
	DEFW	UNDEF		;12 - UNDEFINED
	DEFW	UNDEF		;13 - UNDEFINED
	DEFW	UNDEF		;14 - UNDEFINED
	DEFW	UNDEF		;15 - UNDEFINED
;
;	UNDEFINED ROUTINE HANDLER
;
UNDEF	LD	A,BADF		;BAD FUNCTION CALL
	OR	A		;NZ STATUS
	RET			;EXIT
;
*EJECT
;	$ROUTE/$LINK DEVICE ROUTINE
;
;	ENT	HL =>	COMMAND LINE
;
ROUTE	LD	A,10H		;BIT 5
	DEFB	LD
LINK	LD	A,20H		;BIT 4
;
	LD	(RLFLG),A	;SAVE FLAG
	LD	IX,PBLOCK1	;IX => PARAM BLOCK
	LD	A,EVAL		;EVAL CMD LINE
	RST	SVC		;DO IT!
	JP	NZ,POSTE	;POST ERROR
	LD	A,(IX+0)	;GET FIELDS
	AND	7		;ANY?
	JP	NZ,RLDEV	;ROUTE/LINK
;
;	DISPLAY DEVICE STATUS/SETTINGS
;
DDEV	LD	IX,DEVTBL	;DEVICE TABLE
	LD	B,0		;DEVICE COUNT
;
DDEV1	LD	A,'$'           ;PHY DEVICE
	CALL	DSP$		;OUTPUT
	JP	NZ,POSTE	;IF ERROR
	LD	E,B		;MAX DEVICES
	LD	D,0
	CALL	ODEC		;OUTPUT!
	CALL	Z,OUTSP 	;BLANK
	CALL	Z,DNAME 	;DEVICE NAME
	CALL	Z,DDEV2 	;DEVICE INFO
	JP	NZ,POSTE	;POST ERROR
	LD	DE,4		;OFFSET
	ADD	IX,DE		;NEXT
	LD	A,7		;LAST DEVICE
	INC	B		;NEXT
	CP	B		;DONE?
	JR	NC,DDEV1	;TIL DONE
RETURN	XOR	A		;ALL OK!
	RET
;
;	OUTPUT DEVICE INFORMATION
;
;	ENT	IX =>	TABLE ENTRY
;
DDEV2	CALL	REGSAV		;SAVE REG
	LD	E,(IX+0)
	LD	D,(IX+1)	;DE => DCB
	PUSH	DE
	POP	IX		;IX => DCB
	LD	E,' '           ;TAB
	LD	A,'<'           ;ASSUME OUTPUT
	BIT	0,(IX+0)	;INPUT?
	JR	NZ,$+3		;IF YES
	LD	A,E		;TAB
	CALL	DSP$		;DISPLAY
	RET	NZ
	LD	A,'-'
	CALL	DSP$		;DISPLAY
	RET	NZ
	LD	A,'>'
	BIT	1,(IX+0)	;OUTPUT?
	JR	NZ,$+3		;IF YES
	LD	A,E
	CALL	DSP$		;DISPLAY
	RET	NZ
	LD	A,E
	CALL	DSP$		;DISPLAY
	RET	NZ
;
	BIT	4,(IX+0)	;ROUTED?
	LD	HL,MES1 	;'ROUTED'
	CALL	NZ,LINE$	;IF YES
	RET	NZ
	BIT	4,(IX+0)	;ROUTED?
	JR	NZ,DDEV6	;IF ROUTED
;
	BIT	3,(IX+0)	;NIL?
	LD	HL,MES3 	;'NIL'
	CALL	NZ,LINE$	;IF YES
	RET	NZ
	BIT	3,(IX+0)	;NIL?
	JR	NZ,DDEV3	;IF NIL
	LD	E,(IX+1)
	LD	D,(IX+2)	;DE = DRIVER ADD
	CALL	OHEX		;OUTPUT HEX ADD
	RET	NZ
;
DDEV3	BIT	5,(IX+0)	;LINKED?
	JR	Z,DDEV5 	;IF NOT
	LD	HL,MES2 	;'LINK'
	CALL	LINE$		;OUTPUT
	RET	NZ
;
DDEV6	CALL	OUTSP		;TAB
	RET	NZ		;IF ERROR
	LD	L,(IX+3)
	LD	H,(IX+4)	;DE => ROUTE/LINK DCB
	BIT	7,(HL)		;GET TYPE
	JR	NZ,DDEV4	;IF FILE
	CALL	DSRCH		;SEARCH FOR DEVICE
	JR	Z,DDEV7 	;IF FOUND
	CALL	NZ,OHEX 	;OUTPUT USER ADDRESS
	RET	NZ
	JR	DDEV5		;SKIP
;
DDEV7	LD	E,(IX+2)
	LD	D,(IX+3)	;DE => DEVICE NAME
	CALL	DNAME		;OUTPUT NAME
	RET	NZ
	JR	DDEV5		;SKIP
;
DDEV4	LD	DE,DCB@1+1	;TEMP DCB
	PUSH	DE		;SAVE
	LD	BC,40		;COUNT
	LDIR			;COPY!
	POP	DE		;DE => DCB
	CALL	FNAME		;FILE NAME
	RET	NZ
;
DDEV5	LD	A,CR		;C/R
	JP	DSP$		;DISPLAY
;
*EJECT
;	ROUTE/LINK DEVICE HERE
;
RLDEV	LD	A,(IX+0)	;EVAL FLAGS
	CPL
	AND	6		;SOURCE & DEST?
	JP	NZ,ERR2 	;MISSING SPEC!
	LD	A,(DCB@1)	;GET SOURCE DEVICE
	AND	0FH		;IGNORE FLAGS
	LD	E,A		;E = DEVICE ?
	CP	8		;VALID?
	JP	NC,ERR1 	;ILLEGAL DEVICE SPEC!
;
;	RESET SOURCE DEVICE
;
	CALL	DRESET		;RESET DEVICE
	JP	NZ,POSTE	;POST ERROR
	LD	A,(DCB@2)	;DEVICE #
	AND	0FH		;IGNORE FLAGS
	LD	D,A		;D = DEVICE ?
	SUB	E		;RESET ONLY?
	RET	Z		;ALL DONE!
;
;	ROUTE/LINK TO DEVICE
;
	LD	A,D		;DEST DEVICE
	CP	8		;VALID?
	JR	NC,RLDEV1	;MUST BE FILE
	CALL	LOCDCB		;LOCATE DCB
	PUSH	IX
	POP	DE		;DE => DEST DCB
	JR	RLDEV3		;SET UP ROUTE/LINK
;
;	ROUTE/LINK TO DISK FILE
;
RLDEV1	LD	DE,DCB@2+1+39	;DE => END DEST DCB
	LD	BC,256+40	;SPACE NEEDED
	CALL	FETMEM		;FETCH MEMORY
	JP	NZ,POSTE	;IF ERROR
	LD	(OLIST),HL	;I/O BUFFER
	DEC	BC		;DEC COUNT
	ADD	HL,BC		;HL => LAST BYTE
	EX	DE,HL		;SWAP FOR MOVE
	LD	BC,40		;DCB LENGTH
	LDDR			;MOVE DEST DCB
;
	LD	HL,EXT1 	;'TXT'
	INC	DE		;DE => DCB
	LD	A,FEXT		;PLACE DEFAULT EXT
	RST	SVC		;DO IT!
	LD	A,(DCB@1)	;SOURCE DEVICE
	AND	0FH		;DEVICE #
	CALL	LOCDCB		;LOCATE DCB
	LD	A,3		;OPEN CODE
	BIT	1,(IX+0)	;INPUT?
	JR	Z,$+4		;SKIP
	LD	A,2		;OPEN CODE
	LD	(OLIST+9),A	;PLACE IN OPEN LIST
	LD	HL,OLIST	;HL => OPEN LIST
	LD	A,OPEN		;OPEN FILE
	RST	SVC		;DO IT!
	JP	NZ,POSTE	;POST ERROR
;
;	SET-UP ACTUAL ROUTE/LINK
;
RLDEV3	LD	A,(DCB@1)	;SOURCE DEVICE #
	AND	0FH		;IGNORE FLAGS
	CALL	LOCDCB		;LOCATE DCB
	LD	(IX+3),E
	LD	(IX+4),D	;SET DCB ADDRESS
	LD	A,(IX+0)	;GET DCB TYPE
RLFLG	EQU	$+1
	OR	0		;ROUTE/LINK
	LD	(IX+0),A	;SET DCB TYE
	XOR	A		;NO ERRORS
	RET
;
*EJECT
;	$RESET - RESET DEVICE
;
;	ENT	HL =>	COMMAND LINE
;
RESET	LD	IX,PBLOCK2	;IX => PARAM LIST
	LD	A,EVAL		;EVAL CMD LINE
	RST	SVC		;DO IT!
	JP	NZ,POSTE	;POST ERROR
	BIT	2,(IX+0)	;SOURCE EVAL?
	JR	Z,RESET1	;MISSING SPEC!
	LD	A,(DCB@1)	;GET DEVICE #
	AND	0FH		;IGNORE FLAGS
	LD	E,A		;E = DEVICE ?
	CP	8		;DEVICE?
	JP	NC,ERR1 	;ILLEGAL DEVICE SPEC!
	JP	DRESET		;RESET DEVICE
;
RESET1	LD	E,0		;START GLOBAL
RESET2	CALL	DRESET		;DO IT!
	RET	NZ		;IF ERROR
	LD	A,7		;LAST DEVICE
	INC	E		;NEXT DEVICE
	CP	E		;DONE?
	JR	NC,RESET2	;IF NOT
	XOR	A		;NO ERROR
	RET
;
*EJECT
;	$SET - SET DEVICE W/DRIVER
;
;	ENT	HL =>	COMMAND LINE
;
SET	LD	IX,PBLOCK1	;IX => PARAM BLOCK
	LD	A,EVAL		;EVAL CMD LINE
	RST	SVC		;DO IT!
	JP	NZ,POSTE	;POST ERROR
	LD	A,(IX+0)	;EVAL FLAGS
	CPL
	AND	6		;SOURCE & DEST?
	JP	NZ,ERR2 	;MISSING SPEC!
;
	LD	A,(DCB@1)	;GET DCB TYPE
	BIT	6,A		;FILESPEC?
	JP	NZ,ERR1 	;ILLEGAL DEVICE SPEC!
	AND	0FH		;IGNORE FLAGS
	LD	E,A		;E = DEVICE ?
	CALL	DRESET		;RESET DEVICE
	LD	A,E		;GET DEVICE ?
	CALL	LOCDCB		;LOCATE DCB
	LD	A,(DCB@2)	;DEST DEVICE
	BIT	6,A		;FILE SPEC?
	JR	NZ,SET3 	;IF YES
	AND	0FH		;IGNORE FLAGS
	LD	D,A		;D = DEST DEV ?
	LD	A,E		;SOURCE DEVICE
	CP	8		;CHAR DEVICE?
	JR	NC,SET1 	;IF NOT
	CP	D		;RESET NIL?
	JP	NZ,ERR1 	;ILLEGAL DEVICE SPEC!
	JR	SET2		;SKIP
;
;	INTERNAL DRIVER HANDLER
;
SET1	LD	A,D		;DEST DEVICE
	CP	8		;FILE DEVICE?
	JP	C,ERR1		;IF NOT
	PUSH	IX		;SAVE
	PUSH	IX
	CALL	LOCDCB		;LOCATE DCB
	PUSH	IX
	POP	HL		;HL => DEST DCB
	POP	DE		;DE => SOURCE DCB
	LD	BC,3		;TYPE+DRIVER
	LDIR			;MOVE!
	POP	IX		;IX => SOURCE
	SET	0,(IX+5)	;FORCE LOG-IN
;
;	CURRENT DRIVER ACTIVE
;
SET2	RES	3,(IX+0)	;DEVICE ACTIVE
	RET
;
;	EXTERNAL DRIVER HANDLER
;
SET3	LD	DE,DCB@2+1	;DE => DCB
	PUSH	HL		;SAVE CMD LINE
	LD	HL,EXT3 	;'DVR'
	LD	A,FEXT		;PLACE DEFAULT EXT
	RST	SVC		;DO IT!
	POP	HL		;GET CMD LINE
	LD	A,RUN		;LOAD/RUN
	JP	SVC		;EXECUTE DRIVER
;
*EJECT
;	$FILTER - FILTER DEVICE
;
;	ENT	HL =>	COMMAND LINE
;
*INCL	FILTER
;
*EJECT
;	BIN TO ASCII HEX OUTPUT
;
;	ENT	DE =	BINARY WORD
;
OHEX	CALL	REGSAV		;SAVE REGISTERS
	LD	HL,MES0 	;TEMP BUFFER
	LD	B,0		;BIN TO HEX
	LD	A,BINHEX	;SVC #
	RST	SVC		;DO IT!
	JP	LINE$		;OUTPUT
;
;	BIN TO DECIMAL OUTPUT
;
ODEC	CALL	REGSAV		;SAVE REG
	LD	HL,MES4 	;HL => ASCII STORE
	LD	B,0		;BIN TO DEC
	LD	A,BINDEC	;SVC #
	RST	SVC		;DO IT!
	INC	HL
	INC	HL
	INC	HL		;2 DIGITS
;
;	OUTPUT LINE TO DISPLAY
;
LINE$	LD	A,(HL)		;GET CHAR
	INC	HL		;NEXT
	CP	ETX		;END TEXT?
	RET	Z		;DONE!
	CALL	DSP$		;OUTPUT
	RET	NZ		;IF ERROR
	JR	LINE$		;TIL DONE
;
;	OUTPUT CHAR TO DISPLAY
;
;	ENT	A =	CHARACTER
;
DSP$	PUSH	BC		;SAVE
	LD	B,A		;B = CHAR
	LD	A,VDCHAR	;VIDEO CHARACTER
	RST	SVC		;DO IT!
	POP	BC		;RESTORE
	RET
;
;	RESET I/O DEVICE
;
;	ENT	 E =	DEVICE NUMBER
;
DRESET	CALL	REGSAV		;SAVE REGISTERS
	LD	A,E		;GET DEVICE ?
	CALL	LOCDCB		;GET DCB
	LD	E,(IX+3)
	LD	D,(IX+4)	;DE => DCB
	LD	A,(IX+0)	;GET TYPE
	AND	30H		;ROUTE/LINK?
	RET	Z		;IF NOT
	LD	A,(DE)		;ROUTE/LINK DCB
	AND	80H		;FILE?
	JR	Z,DREST1	;IF NOT
	LD	A,CLOSE 	;SVC ?
	RST	SVC		;CLOSE FILE!
	PUSH	AF		;SAVE STATUS
	EX	DE,HL		;HL => DCB
	DEC	H		;HL => I/O BUFFER
	LD	BC,256+40	;BLOCK LENGTH
	CALL	RECMEM		;RECLAIME MEMORY
	POP	AF		;GET STATUS
;
DREST1	RES	4,(IX+0)	;RESET ROUTE
	RES	5,(IX+0)	;RESET LINK
	RET
;
;	SEARCH FOR DEVICE IN TABLE
;
;	ENT	HL =>	DCB ADDRESS
;
;	EXT	IX =>	TABLE ENTRY
;
DSRCH	PUSH	BC		;SAVE REG
	PUSH	DE
	LD	IX,DEVTBL	;IX => TABLE
	LD	B,8		;DEVICE COUNT
	LD	DE,4		;OFFSET
;
DSRCH1	LD	A,(IX+0)	;GET LSB ADD
	CP	L		;MATCH?
	JR	NZ,DSRCH2	;IF NOT
	LD	A,(IX+1)	;GET MSB ADD
	CP	H		;MATCH?
	JR	Z,DSRCH3	;IF YES
DSRCH2	ADD	IX,DE		;IX => NEXT ENTRY
	DJNZ	DSRCH1		;TIL DFOUND
;
DSRCH3	POP	DE		;RESTORE
	POP	BC
	RET
;
;	DISPLAY DEVICE NAME
;
;	ENT	IX =>	TABLE ENTRY
;
DNAME	LD	A,'@'           ;DEVICE SPEC
	CALL	DSP$		;DISPLAY
	RET	NZ
	LD	A,(IX+2)	;1ST CHAR
	CALL	DSP$		;DISPLAY
	RET	NZ
	LD	A,(IX+3)	;2ND CHAR
	CALL	DSP$		;DISPLAY
	RET	NZ
;
OUTSP	LD	A,' '           ;SPACE
	JP	DSP$		;DISPLAY
;
;	DISPLAY FILE NAME
;
;	ENT	DE =>	OPEN FILE DCB
;
FNAME	CALL	RETDCB		;GET FILE NAME
	RET	NZ		;I/O ERROR
	PUSH	HL		;SAVE
	EX	DE,HL		;HL => FILE NAME
	CALL	LINE$		;DISPLAY
	POP	HL		;RESTORE
	RET
;
RETDCB	LD	A,3-1<4+4	;COMMAND/OVERLAY
	RST	OVERLY		;GO!
;
;	POST ERROR MESSAGE
;
ERR1	LD	A,ERR68 	;'INVALID DEVICESPEC'
	DEFB	LD
ERR2	LD	A,ERR47 	;'PARAMETER NOT FOUND'
;
POSTE	AND	7FH		;NO ABORT
	LD	B,A		;B = ERROR
POSTEB	LD	A,ERROR 	;POST ERROR MESSAGE
	RST	SVC		;DO IT!
	XOR	A		;NO ERRORS
	RET
;
*EJECT
;	MESSAGES AND TEXT STRINGS
;
MES0	DEFM	'0000H'
	DEFB	ETX
MES4	DEFM	'00000'
	DEFB	ETX
MES1	DEFM	'ROUTE'
	DEFB	ETX
MES2	DEFM	' LINK'
	DEFB	ETX
MES3	DEFM	'NIL  '
	DEFB	ETX
;
EXT1	DEFM	'TXT'
EXT2	DEFM	'FLT'
EXT3	DEFM	'DVR'
;
;	$OPEN PARAMETER LIST
;
OLIST	DEFW	0		;BUFADR
	DEFW	0		;RECADR
	DEFW	0		;EOFADR
	DEFM	'W'             ;READ/WRITE
	DEFB	0		;LRL=256
	DEFM	'F'             ;FIXED
	DEFB	0		;OPEN CODE
;
;	TWO FIELD $EVAL BLOCK
;
PBLOCK1 DEFB	0		;FLAGS
	DEFW	DCB@1		;SOURCE FIELD
	DEFW	DCB@2		;DEST FIELD
	DEFW	DCB@2		;USING FIELD
	DEFW	PLIST1		;PARAMETER LIST
;
;	ONE FIELD $EVAL BLOCK
;
PBLOCK2 DEFB	0		;FLAGS
	DEFW	DCB@1		;SOURCE FIELD
	DEFW	DCB@1		;DEST FIELD
	DEFW	DCB@1		;USING FIELD
	DEFW	PLIST1		;PARAMETER LIST
;
;	DUMMY $PARAM LIST
;
PLIST1	DEFB	0		;NO PARAMETERS
;
;	RESERVED DATA AREAS
;
DCB@2	DEFS	41		;DEST FIELD
;
ZZZZZ	EQU	$
	END	START
 