;*****************************************************;
;
;		ASSIGNMENT UTILITY
;
;		VERSION 1.0 05/77
;
;*****************************************************;


IOBYTE	EQU	3	;IO ASSIGNMENTS BYTE -  WHAT THIS PROGRAM SETS
STRLOC	EQU	80H	;WHERE CCP LEAVE ARGUMENT STRING
ENTRY	EQU	5	;SYSTEM CALL ENTRY POINT
REBOOT	EQU	0	;WHERE TO JMP TO REBOOT SYSTEM
TBASE	EQU	100H	;WHERE PROGRAM BEGINS

;EQUATES FOR ASCII CONTROL CHARACTERS
CTRLC	EQU	3
TAB	EQU	9
LF	EQU	0AH
CR	EQU	0DH
RUBOUT	EQU	7FH




	ORG TBASE

	JMP ASSIGN	;NORMAL ENTRY
	JMP DTEST	;DDT DEBUGGING ENTRY


; *********** DEVICE TABLES **************

;THESE TABLES GIVE THE LOGICAL DEVICE NAMES
;AND THE PHYSICAL DEVICE NAMES ASSOCIATED WITH EACH, AND THE
;CORRESPONDING IOBYTE VALUES.

;TO CHANGE DEVICE NAMES OR IOBYTE VALUES, THE USER
;NEED ONLY CHANGE THESE TABLES.


;LOGICAL DEVICE TABLE: NAMES ACCEPTED BEFORE '='
;	FORMAT: ASCII NAME (OMIT COLON), SPACE, MASK FOR
;		ZEROING IOBYTE FIELD RELATED TO NAME (1 BYTE),
;		ADDRESS OF PHYSICAL DEVICE TABLE FOR THIS LOG DEVICE.
;

LDEVTAB:		;A LONG AND A SHORT NAME FOR EACH --
	DB 'CON ',11111100B
	 DW CONFDEV
	DB 'CONSOLE ',11111100B
	 DW CONFDEV
	DB 'RDR ',11110011B
	 DW RDRFDEV
	DB 'READER ',11110011B
	 DW RDRFDEV
	DB 'PUN ',11001111B
	 DW PUNFDEV
	DB 'PUNCH ',11001111B
	 DW PUNFDEV
	DB 'LST ',00111111B
	 DW LSTFDEV
	DB 'LIST ',00111111B
	 DW LSTFDEV
	DB 0FFH		;THIS MARKS END OF TABLE


;PHYSICAL DEVICE NAME TABLES: NAMES ACCEPTABLE AFTER '='.
;ONE FOR EACH LOGICAL DEVICE.
;	FORMAT: NAME, SPACE, PROPERLY POSITIONED IOBYTE VALUE

CONFDEV:	;FOR CONSOLE - INPUT AND OUTPUT
	DB 'TTY ',0
	DB 'CRT ',1
	DB 'BATCH ',2	;BATCH MODE: INPUT LOGICAL READER, OUTPUT LIST.
	DB 'CON3 ',3	;FOR A USER-ADDED DEVICE
	DB 0FFH

RDRFDEV:	;SYSTEM READER DEVICE
	DB 'TTY ',0
	DB 'RDR ',100B		;HIGH SPEED READER (UNIMPLEMENTED)
	DB 'RDR2 ',1000B	;UNIMPLEMENTED - FOR USER-ADDED DEVICE
	DB 'RDR3 ',1100B	; DITTO
	DB 0FFH

PUNFDEV:	;SYSTEM PUNCH DEVICE
	DB 'TTY ',0
	DB 'PUN ',10000B	;HI SPEED PUNCH (UNIMPLEMENTED)
	DB 'PUN2 ',100000B	;UNIMPLEMENTED - FOR USER DEVICE
	DB 'PUN3 ',110000B	;DITTO
	DB 0FFH

LSTFDEV:	;SYSTEM LIST DEVICE
	DB 'TTY ',0
	DB 'CRT ',01000000B
	DB 'LPT ',10000000B	;IMSAI LINE PRINTER
	DB 'PRN ',10000000B	;SYNONYM FOR LPT
	DB 'LST3 ',11000000B	;FOR USER-ADDED DEVICE
	DB 0FFH
;



; ************* MAIN PROGRAM ********************


ASSIGN:
	LXI H,0! DAD SP! SHLD CALLERSP		;SAVE CALLER'S STACK
	LXI SP,STACK		;SET UP OURS
;
; ANALYZE AND EXECUTE GIVEN COMMAND
;
	LXI H,STRLOC	;STRING POINTER STAYS IN HL
;INPUT IS COUNT FOLLOWED BY CHARACTERS. PUT CR AT END.
	PUSH H
	MOV E,M			;COUNT
	MVI D,0! DAD D! INX H	;POINT CHR POSN AFTER END
	MVI M,CR		;PUT CR THERE
	POP H			;RESTORE POINTER TO BEGINNING

;IF NULL ARG, GO ASSIGN FROM  SWITCHES
	CALL PASS$SP! CPI CR! JZ ASSWITCHES

;PARSE LOGICAL DEVICE NAME
	DCX H! CALL SCANDVN	;SCAN NAME, SET C=LEN,DE=START

;ALLOW A SEPERATING CHARACTER IN ADDITION TO SPACES
	CPI '='! JZ PASSEP
	CPI '_'! JZ PASSEP
	CPI ','! JZ PASSEP
	DCX H		;ELSE CURRENT CHAR STARTS PHYS DEV NAME
PASSEP:	PUSH H		;SAVE STRING POINTER

;SEARCH LOGICAL DEVICE TABLE
	LXI H,LDEVTAB-4
	PUSH D
	MVI B,0! PUSH B
;LOOP OVER ENTRIES
SLDTL:	POP B! POP D! PUSH D! PUSH B
	INX H! INX H! INX H! INX H	;PASS DATA FOR PREVIOUS ENTRY
;LOOP OVER CHARS OF ENTRY
SLDEL:	MOV A,M			;CHAR OF ENTRY
	CPI 0FFH! JZ LDEVNF	;TEST FOR END OF TABLE
	CPI ' '! JZ ENDLENTRY	;TEST FOR END THIS ENTRY KEY
	LDAX D! CMP M! JZ SLDTL2	;COMPARE TO CHAR OF ARGUMENT
	INR B			;CHAR DOESN'T MATCH, FLAG AND CONTINUE
SLDTL2:	INX H! INX D! DCR C! JMP SLDEL	;KEEP TESTING  ENTRY
;END OF CURRENT ENTRY
ENDLENTRY: MOV A,C		;TEST FOR LENGTH CORRECT
	ORA B			;TEST FOR ALL CHARS MATCHING
	JNZ SLDTL		;IF EITHER WRONG, TRY
;FOUND IT, FETCH VALUES FROM TABLE
	INX H! MOV A,M! STA MASK	;MASK FOR CHANGING IOBYTE
	INX H! MOV A,M! INX H! MOV H,M! MOV L,A
				;LOCATION PHYS DEV TAB FOR THIS LOG DEV
	POP D! POP D		;CLEAR STACK
;
	XTHL		;PUT PHYS DEV TAB PTR, GET STRING POINTER
;

; PARSE PHYS DEV NAME
	CALL SCANDVN

;CHECK TERMINATING CHAR
	CPI CR! JNZ SYNER
;
	POP H		;DISCARD STRING PTR, GET PHYS DEV TBL LOC

;SEARCH PHYS DEV TABLE (HL)
;PARALLEL TO LOG DEV TABLE SEARCH ABOVE
	DCX H! DCX H		;ADJUST TABLE PTR FOR INX'S BELOW
	PUSH D
	MVI B,0! PUSH B
SFDTL:	POP B! POP D! PUSH D! PUSH B
	INX H! INX H
SFDEL:	MOV A,M
	CPI 0FFH! JZ FDEVNF
	CPI ' '! JZ ENDFENTRY
	LDAX D! CMP M! JZ SFDTL2
	INR B
SFDTL2:	INX H! INX D! DCR C! JMP SFDEL
ENDFENTRY: MOV A,C
	ORA B
	JNZ SFDTL
;FOUND IT
;UPDATE IOBYTE
	INX H
	LDA IOBYTE! MOV B,A
	LDA MASK! ANA B
	ORA M! STA IOBYTE
;DONE, EXIT TO CCP
	JMP GDEXIT

;
; DDT CHECKOUT MAIN PROGRAM
;
DTEST:	LXI SP,DSTACK
;INPUT STRING TO SAME PLACE CCP DOES & MAKE IT LOOK THE SAME
	LXI H,STRLOC-1		;BUFFER LOC
	MVI M,72		;LENGTH
	MVI C,10		;BUFFERED CONSOLE INPUT FUNCTION
	MOV D,H! MOV E,L
	CALL ENTRY
	MVI A,LF! CALL CONO	;ECHO LF AFTER CR
;NOW USE ASSIGN PROGRAM
	CALL ASSIGN
	RST 7			;THEN RETURN TO DDT
;


; ***** NORMAL FLOW OF PROGRAM ENDED ABOVE, EXECPTION CASES FOLLOW ******

;
; ASSIGN FROM SWITCHES
;
ASSWITCHES:
;GET USER TO CONFIRM, SINCE IF THERE'S A WRONG
; VALUE IN SWITHCES, HIS CONSOLE SOULD DISSAPPEAR
	LXI D,ASWMSG! CALL TMSG		;"SET SWITCHES, TYPE RETURN"
	MVI C,1! CALL ENTRY	;INPUT CHARACTER FROM CONSOLE
	CPI RUBOUT! JZ GDEXIT	;IGNORE IF RUBOUT
	CPI CTRLC! JZ REBOOT	;RELOAD SYSTEM ON ^C
	CPI CR! JNZ QUES	;"?" ON CHAR OTHER THAN CR
;NOW INPUT AND STORE SWITCHES
	IN 0FFH		;PUTS SWITCHES VALUE IN A
	STA IOBYTE	;STORE IT
	JMP GDEXIT

ASWMSG:	DB 'SET SWITCHES TO DESIRED IOBYTE VALUE, TYPE RETURN$'

;LOGICAL DEVICE NOT FOUND IN TABLE
LDEVNF:	CALL TDEVN	;TYPE DEVICE NAME AND COLON
	CALL INLMSGEXIT! DB ' UNRECOGNIZED LOGICAL DEVICE$'

;PHYSICAL DEVICE NOT FOUND IN TABLE
FDEVNF:	CALL TDEVN
	CALL INLMSGEXIT! DB ' NOT LEGAL PHYSICAL DEVICE FOR GIVEN LOGICAL DEVICE$'

;GENERAL SYNTAX ERROR: TYPE LINE AND ?
SYNER:	LXI D,STRLOC
	LDAX D! MOV C,A		;CHAR COUNT TO C
	INX D! CALL TDEVN	;TYPE LINE
QUES:	CALL INLMSGEXIT! DB ' ?$'
;

;
; ************* SUBROUTINES *******************
;

;PASS SPACES, GET CHARACTER
PASS$SP: INX H! MOV A,M! CPI ' '! JZ PASS$SP! RET


;SCAN DEVICE NAME (HL), RET BEG DE, COUNT C, NEXT CHAR A

SCANDVN:
SCD1:	INX H! MOV A,M! CPI ' '! JZ SCD1	;PASS PRECEDING SPACES
	PUSH H		;SAVE BEGINNING
	MVI C,0		;CHAR COUNTER (RUNS 1 HI)
	DCX H
;SCAN NAME INSELF
SCDL:	INR C! INX H! MOV A,M	;NEXT CHARACTER
	;END SCAN ON : = CR _ OR SPACE
	CPI ' '! JZ SCD4! CPI ':'! JZ SCD4! CPI CR! JZ SCD4
	CPI '='! JZ SCD4! CPI '_'! JNZ SCDL
;
SCD4:	DCR C! JZ SYNER		;ERROR IF NO CHARACTERS IN NAME
;PASS UP FOLLOWING COLON
	CPI ':'! JNZ $+4! INX H! MOV A,M
	POP D		;POINTER TO BEGINNING
SCD6:	CPI ' '! RNZ! INX H! MOV A,M! JMP SCD6	;PASS FOLLOWING SPACES


;TYPE DEVICE NAME AFTER SEARCH ERROR
;DE POINTS BEGINNING, C GIVES LENGTH

TDEVN:	XCHG
TDEVN1:	MOV A,M! CALL CONO! INX H! DCR C! JNZ TDEVN1
	MVI A,':'! JMP CONO

;TYPE MESSAGE FOLLOWING CALL AND EXIT

INLMSGEXIT:	POP D		;MESSAGE IS AT CALLING LOC

;TYPE MESSAGE (DE) AND ABORT

MSGABORT:	CALL TMSG

;ERROR RETURN TO CCP

EREXIT:	MVI A,1! JMP $+4

;GOOD RETURN TO CCP
GDEXIT:	XRA A
	CALL CRLF
	LHLD CALLERSP! SPHL! RET
;


;OUTPUT CRLF TO CONSOLE & CLOBBER DE

CRLF:	LXI D,CRLFM

;OUTPUT MESSAGE (DE) TO CONSOLE

TMSG:	PUSH PSW! PUSH B! PUSH D! PUSH H
	MVI C,9
	JMP CALLEN

CRLFM:	DB CR,LF,'$'

;OUTPUT CHARACTER (A) TO CONSOLE

CONO:	PUSH PSW! PUSH B! PUSH D! PUSH H
	MOV E,A! MVI C,2
CALLEN:	CALL ENTRY
RETREGS: POP H! POP D! POP B! POP PSW! RET



;
; ************ STORAGE **************
;
CALLERSP: DS 2		;CALLER'S STACK POINTER
MASK:	DS 1		;BIT MASK FOR IOBYTE FIELD TO CHANGE

	DS 40
STACK:	DS 10
DSTACK:	END DTEST
