;
;	Pass - Command to enable priviledged use of a ZCMD system
;		running under secure mode.
;		By Paul S. Traina -- OxGate Node 001 Sysop
;				     (author of ZCMD's "secure" section)
;		Version 2.2 - 4/13/83
;
;	To run pass do the following:
;		A>PASS <password>  -  To enable wheel mode
;		A>PASS<cr>	   -  To enable wheel mode without
;		Password: <password>     any echo of password
;		A>PASS -	   -  To disable wheel mode manually
;
; Thanks to Don Brown for MAXUSR/MAXDRV set/reset idea & code.
;
FALSE	EQU	0
TRUE	EQU	NOT FALSE
CR	EQU	13		;termination character
PSTRING	EQU	9		;BDOS Print a string
ENABLE	EQU	0FFh		;this is poked into WHEEL
BASE	EQU	0000h		;set to 4200h for trs80/heath cp/m
BDOS	EQU	BASE+05h	;bdos location
WHEEL	EQU	BASE+3Eh	;location of wheel byte
FCB	EQU	BASE+5Ch	;file control block+1
;
VERBOSE	EQU	FALSE		;true if let the guy know he blew it or made it
BYE	EQU	TRUE		;true if running ByeII
MAXUSR	EQU	9		;maxusr in normal mode
MAXDRV	EQU	2		;maxdrv in normal mode
WHLUSR	EQU	15		;maxusr in wheel mode
WHLDRV	EQU	2		;maxdrv in wheel mode
;
	ORG	BASE+100h
;
SELECT:	LDA	FCB+1		;see what we are supposed to do
	CPI	' '		;don't echo pasword (someone looking over
	JZ	GETPASS		;your shoulder?)
	CPI	'-'		;disable wheel mode (become humble again)
	JZ	DISABLE
;
;	No, we have a JCL, so let's read it in...
;
COMPARE:
	LXI	H,PASSWD	;set up all the pointers
	LXI	D,FCB+1		;location of password buffer
	MVI	B,PWEND-PASSWD	;number of characters of real password
CKPASS:	LDAX	D		;trial password to A
	CMP	M		;check for a match
	RNZ			;return to CCP (beware of skewed stacks)
	INX	H		;HL=HL+1
	INX	D		;DE=DE+1
	DCR	B		;B=B-1
	JNZ	CKPASS		;if B>0 then CKPASS
;
	IF	BYE
	MVI	A,WHLUSR	;Store priviledged MAXUSR
	MVI	C,WHLDRV	;Store priviledged MAXDRV
	CALL	INSTALL		;Install priviledges for bye
	ENDIF
;
	MVI	A,ENABLE	;Set enable flag
	STA	WHEEL
	RET			;return to CCP (watch stack or else...)
;
;	Disable wheel mode, and return to normal mode
;
DISABLE:
	IF	BYE
	MVI	A,MAXUSR	;Store UnPriviledged MAXUSR
	MVI	C,MAXDRV	;Store UnPriviledged MAXDRV
	CALL	INSTALL		;..Deinstall Priviledges for Bye
	ENDIF
;
	XRA	A		;disable wheel flag
	STA	WHEEL
	RET			;soft-return to CCP
;
GETPASS:
	MVI	C,9
	LXI	D,PMSG
	CALL	BDOS
	LXI	H,FCB+1		;ok, use the fcb as a buffer
GETLOOP:
	PUSH	H		;save HL
LOOP1:	MVI	C,6		;use direct console i/o
	MVI	E,0FFH		;input a character
	CALL	BDOS		;get character into A
	ORA	A		;set flags
	JZ	LOOP1		;no character found, try again
	POP	H		;restore HL
	ANI	95		;lowercase to uppercase (indiscriminate but
				;effective)
	CPI	CR		;is it a <cr>?
	JZ	COMPARE
	MOV	M,A		;store character in fcb
	INX	H		;increment pointers
	JMP	GETLOOP		;loop until we get a <cr>
;
INSTALL:
	LHLD	0001h		;Point to cold boot vector
	DCX	H		;Point to high byte
	MOV	D,M		;..Store in D
	DCX	H		;Point to low byte
	MOV	E,M		;..Store in E
	LXI	H,6		;Maxusr bytes above cold boot
	DAD	D		;Add HL & DE, point to maxusr
	MOV	M,A		;Assign new maxusr for bye
	INX	H		;Point to maxdrv
	MOV	M,C		;Assign new maxdrv for bye
	RET
;
PMSG:	DB	'Password? $'
PASSWD:	DB	'YOURPW'	;Password shouldn't be more than 8 chars
				;or somethings may die exotically.
PWEND:
;
	END
