	PAGE	64,132
	TITLE	GOLD key from NUMLOCK
	NAME	GOLD
;
; This program maps the NUM LOCK key (scan code 45H) to another key
; (default is F1, scan code 3BH) for use with Kermit emulating a DEC VTxxx
; terminal.
;
; Version 2.4 -	June 1992
;		Fixed spurious recognition of PAUSE key as GOLD (caused by
;		presence of 45H in six byte sequence for PAUSE)
; Version 2.3 - June 1992
;		Added facility to have modifier (CTRL, SHIFT, ALT)
;		for chosen key
; Version 2.2 -	February 1992
;		Added safety checks to installation code
; Version 2.1 - June 1991
;		Changed default multiplex ID to 09FH (was 0DCH) to avoid
;		problems with some versions of the KEYB program.
; Version 2.0 - March 1991
;		SHIFT and NUM LOCK acts as normal NUM LOCK
;		ALT and NUM LOCK inverts current GOLD status
;		Fix for problem with some clone BIOSes
;		Fix non-detection of BIOS intercept support
;		Use INT 09H if interrupt intercept not available
;
; Bob Eager
;	rde@ukc.ac.uk		USENET (preferred over ibmpcug)
;	rde@ibmpcug.co.uk	USENET
;	100016,2770		CompuServe
;	+44 227 367270		Telephone
;
; You may distribute this program freely as long as all of the files that
; make up the package (see the documentation file) are kept with it (including
; this source file) and you don't try to make money from it either by selling
; it directly or incorporating it into a product you sell.
;
; Values for exit status:
;
;	0	- success
;	1	- could not install program
;	2	- no BIOS support present
;	3	- unsupported DOS version (< 3.0)
;	4	- invalid parameter
;
; Constants
; ---------
;
	CR	= 0DH			; Carriage return
	LF	= 0AH			; Linefeed
	TAB	= 09H			; Tab
;
	ID	= 0DCH			; Multiplex ID
;
	NUMSCAN	= 045H			; Num Lock scan code
	P1SCAN	= 0E1H			; Pause scan code byte 1
	P2SCAN	= 01DH			; Pause scan code byte 2
;
	CSEG	SEGMENT BYTE PUBLIC 'CODE'
;
	$BEGIN	EQU	$
;
	ORG	0100H
;
	ASSUME	CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG
;
	SUBTTL	Data areas
	PAGE+
;
; The following jump to the initialisation code also provides three bytes
; of storage, which are used later by the resident part of the code.
;
BEGIN:	JMP	INIT			; jump to initialisation code
;
; Redefine storage for the above jump
;
	ORG	BEGIN
MBIT	EQU	THIS BYTE		; Make/Break bit
	ORG	BEGIN+1
ONOFF	EQU	THIS BYTE		; On/Off flag (0=off, initially on)
	ORG	BEGIN+2
SHFLAG	EQU	THIS BYTE		; Shift bits changed flag (0=No, 1=Yes)
;
; Back to normal storage allocation
;
	ORG	BEGIN+3
;
; The following four values may be changed if required.
;
; MPID		is the multiplex ID, and will only need alteration if some
;		other TSR is using the same value. Choose another at random
;		until it works!
; NEWKEY	is the make code value for the key to replace NUM LOCK.
;			Examples:
;				3B	- F1
;				1E	- A
;		See a key code table (e.g. in IBM Technical Reference Manual)
;		for the rest.
; MODE		is used to force a particular operation mode; it is particularly
;		useful when a BIOS says that it supports the keyboard intercept
;		function, but doesn't.
; MODBIT	is a way of specifying that a particular modifier key (CTRL,
;		ALT, or SHIFT) should be forced down when the replacement
;		keystroke is transmitted. Set as follows:
;			08H	- ALT
;			04H	- CTRL
;			02H	- left SHIFT
;			01H	- right SHIFT
;		These bits may be combined (e.g. 0CH for CTRL+ALT). Either
;		SHIFT key will generally work.
;
MPID	DB	09FH			; 102H Multiplex ID ** DO NOT MOVE **
NEWKEY	DB	03BH			; 103H Replacement key ** DO NOT MOVE **
;NEWKEY	DB	01EH			; 103H Replacement key ** DO NOT MOVE **
MODE	DB	0			; 104H Mode selector ** DO NOT MOVE **
					;	00H = auto
					;	01H = use INT 15H
					;	02H = use INT 09H
MODBIT	DB	00H			; 105H Replacement key modifier bit
;MODBIT	DB	08H			; 105H Replacement key modifier bit
					; *** DO NOT MOVE ***
SAVESH	DB	0			; Saved copy of shift flags
STATE	DB	0			; State for PAUSE recognition
;					; 0 = normal scan
;					; 1 = after E1
;					; 2 = after E1 1D
;
INTOFF	DW	?			; Old interrupt vector offset
INTSEG	DW	?			; Old interrupt vector segment
I2FOFF	DW	?			; Old INT 2FH offset
I2FSEG	DW	?			; Old INT 2FH segment
;
	SUBTTL	INT 2FH (multiplex) handler
	PAGE+
;
; This INT 2FH handler is hooked into the MS-DOS multiplex interrupt.
;
;	Input parameters:
;
;		AH	= handler ID (MPID for this program)
;			  Calls with unrecognised handler IDs are passed on
;		AL	= function code
;				00	- get installation status
;				01	- get GOLD status
;				02	- set GOLD status
;
;	Output parameters:
;
;		AL	= result
;				Get installation status:
;					FFH	- Already installed
;				Get GOLD status:
;					00H	- OFF
;					01H	- ON
;				Set GOLD status:
;					00H	- OK
;
I2FHAN	PROC	FAR
;
	ASSUME	CS:CSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
;
	CMP	AH,MPID			; for this program?
	JE	I2FH10			; j if so
	JMP	DWORD PTR I2FOFF	; else use old handler
;
I2FH10:	OR	AL,AL			; AL=0, get installation status?
	JNE	I2FH20			; j if not
	MOV	AL,0FFH			; indicate already installed
	IRET				; and return
;
I2FH20:	DEC	AL			; AL=1, get GOLD status?
	JNE	I2FH30			; j if not
	MOV	AL,ONOFF		; get value
	IRET				; and return
;
I2FH30:	DEC	AL			; AL=2, set GOLD status?
	JNE	I2FH40			; j if not
	MOV	ONOFF,DL		; set new value, drop through
;
I2FH40:	IRET				; and return
;
I2FHAN	ENDP
;
	SUBTTL	INT 15H (system services) handler
	PAGE+
;
; This INT 15H handler is hooked into the BIOS system services interrupt.
; It is used only if the keyboard interrupt intercept capability is available
; in the BIOS.
;
;	Input parameters:
;		AH	- function. Only 4FH (keyboard intercept) is handled;
;			  other values cause the action to be passed to the
;			  previous handler.
;		AL	- scan code for key just pressed
;
;	Output parameters:
;		AL	- input scan code, or mapped version of it.
;		CY	- set to indicate that keystroke is to be processed.
;		All other register contents are preserved.
;
	ASSUME	CS:CSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
;
I15HAN	PROC	FAR
;
	CMP	AH,4FH			; keyboard intercept function?
	JE	I15H10			; j if so
	JMP	DWORD PTR INTOFF	; else call old handler
;
I15H10:	PUSH	AX			; save register
	PUSH	AX			; save again
	XOR	AL,AL			; set zero
	XCHG	AL,SHFLAG		; get and clear flags bit
	OR	AL,AL			; set condition flags
	JZ	I15H15			; j if not currently changed
	PUSH	DS			; save data segment
	MOV	AX,40H			; BIOS data segment
	MOV	DS,AX			; address it
	MOV	AL,CSEG:SAVESH		; get saved keyboard flags
	MOV	DS:[17H],AL		; restore them
	POP	DS			; recover data segment
I15H15:	POP	AX			; recover register
	CMP	STATE,0			; normal state?
	JE	I15H17			; j if so
	CMP	STATE,1			; had just one PAUSE byte?
	JE	I15H16			; j if so
	MOV	STATE,0			; else in state 2 - reset state...
	JMP	I15H60			; ...and skip checks
;
I15H16:	CMP	AL,P2SCAN		; got second byte now?
	JE	I15H18			; j if so, => state 2
	DEC	STATE			; else reset state
	JMP	SHORT I15H19		; and perform normal checks
;
I15H17:	CMP	AL,P1SCAN		; possible PAUSE sequence?
	JNE	I15H19			; j if not, else => state 1
;
I15H18:	INC	STATE			; update state
	JMP	SHORT I15H60		; skip checks
;
I15H19:	MOV	AH,AL			; copy scan code
	AND	AH,80H			; isolate make/break bit
	MOV	MBIT,AH			; save it
	AND	AL,7FH			; mask out make/break bit
	CMP	AL,NUMSCAN		; NUM LOCK?
	JNE	I15H60			; j if not - just return
;
; NUM LOCK has been pressed. Check for SHIFT (retain normal action).
;
	PUSH	DS			; save segment
	MOV	AX,40H			; BIOS data segment
	MOV	DS,AX			; address BIOS data segment
	MOV	AL,DS:[17H]		; get keyboard flags
	POP	DS			; recover segment
	AND	AL,0FH			; mask out lock status
	MOV	AH,AL			; take copy for later comparison
	CMP	ONOFF,0			; is GOLD on?
	JE	I15H20			; j if not - do nothing here
	AND	AL,03H			; mask out ALT and CTRL status
	JE	I15H20			; j if not shifted
	CMP	AH,AL			; see if just SHIFT
	JE	I15H60			; if so, treat as normal NUM LOCK call
;
; Check for ALT (invert GOLD status). This needs to work whether GOLD is
; ON or OFF.
;
I15H20:	MOV	AL,AH			; recover shift status bits
	AND	AL,08H			; mask out CTRL and SHIFT status
	JE	I15H40			; j if not ALT - pass through
	CMP	AH,AL			; see if just ALT
	JNE	I15H40			; j if not - pass through
	TEST	MBIT,80H		; make operation?
	JNE	I15H30			; j if not - ignore
	XOR	ONOFF,1			; flip GOLD ON/OFF flag
;
I15H30:	CLC				; absorb keystroke
	POP	AX			; recover register
	RETF	2			; return, preserving flags
;
I15H40:	CMP	ONOFF,0			; is GOLD on?
	JE	I15H60			; j if not - do nothing
;
I15H50:	PUSH	DS			; save data segment
	MOV	AX,40H			; BIOS data segment
	MOV	DS,AX			; address BIOS data segment
	MOV	AH,DS:[17H]		; get keyboard flags
	MOV	AL,CSEG:MODBIT		; get extra modifier
	OR	AL,AH			; combine with existing ones
	MOV	DS:[17H],AL		; update keyboard flags
	POP	DS			; recover segment
	MOV	SAVESH,AH		; save old flags
	INC	SHFLAG			; mark changed
	POP	AX			; recover register
	MOV	AL,NEWKEY		; set replacement scan code
	OR	AL,MBIT			; include make/break bit, drop through
	STC				; make sure keystroke processed
	RETF	2			; return, preserving flags
;
I15H60:	STC				; make sure keystroke processed
	POP	AX			; recover register
	RETF	2			; return, preserving flags
;
I15HAN	ENDP
;
I15LEN	=	$ - I15HAN		; length of INT 15H handler
;
	SUBTTL	INT 09H (keyboard interrupt) handler
	PAGE+
;
; This INT 09H handler is hooked into the keyboard interrupt vector.
; It is used only if the keyboard interrupt intercept facility is not
; available in the BIOS, and is moved in memory so that the space occupied
; by the INT 15H handler is not wasted.
;
;	Input parameters:
;		No explicit inputs. Implicit input from the keyboard
;		hardware.
;
;	Output parameters:
;		No explicit outputs. Control is passed to the normal keyboard
;		interrupt handler unless the keystroke is to be modified or
;		absorbed. Modified keystrokes are placed into the BIOS input
;		buffer.
;		All registers are preserved.
;
I09HAN	PROC	FAR
;
	PUSH	AX			; save register
	IN	AL,60H			; get next character from hardware
	PUSH	AX			; save character
	XOR	AL,AL			; set zero
	XCHG	AL,SHFLAG		; get and clear flags bit
	OR	AL,AL			; set condition flags
	JZ	I09H05			; j if not currently changed
	PUSH	DS			; save data segment
	MOV	AX,40H			; BIOS data segment
	MOV	DS,AX			; address it
	MOV	AL,CSEG:SAVESH		; get saved keyboard flags
	MOV	DS:[17H],AL		; restore them
	POP	DS			; recover data segment
I09H05:	POP	AX			; recover character
	CMP	STATE,0			; normal state?
	JE	I09H07			; j if so
	CMP	STATE,1			; had just one PAUSE byte?
	JE	I09H06			; j if so
	MOV	STATE,0			; else in state 2 - reset state...
	JMP	I09H80			; ...and skip checks
;
I09H06:	CMP	AL,P2SCAN		; got second byte now?
	JE	I09H08			; j if so, => state 2
	DEC	STATE			; else reset state
	JMP	SHORT I09H09		; and perform normal checks
;
I09H07:	CMP	AL,P1SCAN		; possible PAUSE sequence?
	JNE	I09H09			; j if not, else => state 1
;
I09H08:	INC	STATE			; update state
	JMP	I09H80			; skip checks
;
I09H09:	MOV	AH,AL			; copy scan code
	AND	AH,80H			; isolate make/break bit
	MOV	MBIT,AH			; save it
	AND	AL,7FH			; mask out make/break bit
	CMP	AL,NUMSCAN		; NUM LOCK?
	JE	I09H10			; j if so
	JMP	I09H80			; else just pass on to original handler
;
; NUM LOCK has been pressed. Check for SHIFT (retain normal action).
;
I09H10:	PUSH	DS			; save segment
	MOV	AX,40H			; BIOS data segment
	MOV	DS,AX			; address BIOS data segment
	MOV	AL,DS:[17H]		; get keyboard flags
	POP	DS			; recover segment
	AND	AL,0FH			; mask out lock status
	MOV	AH,AL			; take copy for later comparison
	CMP	ONOFF,0			; is GOLD on?
	JE	I09H20			; j if not - do nothing here
	AND	AL,03H			; mask out ALT and CTRL status
	JE	I09H20			; j if not shifted
	CMP	AH,AL			; see if just SHIFT
	JNE	I09H20			; j if not
	JMP	I09H80			; else treat as normal NUM LOCK call
;
; Check for ALT (invert GOLD status). This needs to work whether GOLD is
; ON or OFF.
;
I09H20:	MOV	AL,AH			; recover shift status bits
	AND	AL,08H			; mask out CTRL and SHIFT status
	JE	I09H30			; j if not ALT - pass through
	CMP	AH,AL			; see if just ALT
	JNE	I09H30			; j if not - pass through
	TEST	MBIT,80H		; make operation?
	JNE	I09H70			; j if not - ignore
	XOR	ONOFF,1			; flip GOLD ON/OFF flag
	JMP	SHORT I09H70		; absorb keystroke and exit
;
I09H30:	CMP	ONOFF,0			; is GOLD on?
	JE	I09H80			; j if not - pass through
;
I09H40:	TEST	MBIT,80H		; break code?
	JNZ	I09H70			; j if so - ignore
	PUSH	DS			; save segment
	PUSH	SI			; save register
	PUSH	BX			; save register
	MOV	AX,40H			; BIOS data segment
	MOV	DS,AX			; address it
	MOV	BX,DS:[1CH]		; get offset of next slot in buffer
	MOV	SI,BX			; save for later
	ADD	BX,2			; advance pointer
	CMP	BX,DS:[82H]		; time to wrap?
	JNZ	I09H50			; j if not
	MOV	BX,DS:[80H]		; else do it
;
I09H50:	CMP	BX,DS:[1AH]		; buffer is full?
	JZ	I09H60			; j if so - discard character
	MOV	AH,NEWKEY		; set replacement scan code
	XOR	AL,AL			; extended code
	MOV	WORD PTR [SI],AX	; set into buffer
	MOV	DS:[1CH],BX		; save updated buffer pointer
	MOV	AH,DS:[17H]		; get keyboard flags
	MOV	AL,CSEG:MODBIT		; get extra modifier
	OR	AL,AH			; combine with existing ones
	MOV	DS:[17H],AL		; update keyboard flags
	MOV	CSEG:SAVESH,AH		; save old flags
	INC	SHFLAG			; mark changed
;
I09H60:	POP	BX			; recover register
	POP	SI			; recover register
	POP	DS			; recover segment
;
; Clear the keyboard port, acknowledging the character.
;
I09H70:	IN	AL,61H			; get control port
	MOV	AH,AL			; copy for later reset
	OR	AL,80H			; set bit to acknowledge
	JMP	SHORT $+2		; wait for settle
	OUT	61H,AL			; do the acknowledge
	JMP	SHORT $+2		; wait for settle
	MOV	AL,AH			; get original setting
	OUT	61H,AL			; put it back
	JMP	SHORT $+2		; wait for settle
	MOV	AL,20H			; End-Of-Interrupt
	OUT	20H,AL			; send to interrupt controller
	POP	AX			; recover register
	IRET				; return without calling original
;
I09H80:	POP	AX			; recover register
	JMP	DWORD PTR INTOFF	; jump to original interrupt handler
;
I09HAN	ENDP
;
I09LEN	=	$ - I09HAN		; length of INT 09H handler
;
	SUBTTL	Initialisation code
	PAGE+
;
; This is the program initialisation code. It is not present in the resident
; copy of the program.
;
	ASSUME	CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG
;
INIT:	MOV	ONOFF,1			; set initial value
	MOV	SHFLAG,0		; set initial value
	MOV	STATE,0			; set initial value
;
; Select the operating mode
;
	CMP	MODE,2			; force INT 09H to be used?
	JE	INIT50			; j if so
	PUSH	ES			; save ES
	MOV	AH,0C0H			; see if keyboard intercept supported
	INT	15H			; get system configuration parameters
	JNC	INIT10			; j if configuration call supported
	POP	ES			; recover ES
	JMP	SHORT INIT20		; try for INT 09H mode
;
INIT10:	TEST	BYTE PTR ES:[BX+5],10H	; see if intercept flag set
	POP	ES			; recover ES
	JNE	INIT30			; j if intercept supported - use it
;
INIT20:	CMP	MODE,1			; force INT 15H mode?
	JNE	INIT40			; j if not - use INT 09H mode
	LEA	DX,MES0			; 'Sorry - this machine does not...'
	MOV	AH,9			; output message
	INT	21H			; do it
	MOV	AX,4C02H		; exit with error status
	INT	21H
;
INIT30:	MOV	MODE,1			; select INT 15H mode
	JMP	SHORT INIT50		; check DOS version now
;
INIT40:	MOV	MODE,2			; select INT 09H mode
;
; The INT 2FH code will work only on DOS 3.0 and above. See if it is OK
; to use it.
;
INIT50:	MOV	AX,3000H		; get DOS version
	INT	21H			; returns minor in AH, major in AL
	CMP	AL,3			; see if 3 or greater
	JGE	INIT60			; j if so - OK
	LEA	DX,MES1			; 'Sorry - DOS 3.0 or above is...'
	MOV	AH,9			; output message
	INT	21H			; do it
	MOV	AX,4C03H		; exit with error status
	INT	21H
;
; See if already installed
;
INIT60:	MOV	AH,MPID			; multiplex ID
	XOR	AL,AL			; function 00H
	XOR	BX,BX			; zero for safety
	XOR	CX,CX			; zero for safety
	XOR	DX,DX			; zero for safety
	INT	2FH			; call multiplex
	PUSH	CS			; restore DS in case corrupted...
	POP	DS			; ...by other program
	PUSH	CS			; restore ES...
	POP	ES			; ...for same reason
	OR	AL,AL			; see if OK to install (AL unchanged)
	JZ	INIT70			; j if so
	CMP	AL,0FFH			; already installed?
	JE	INIT100			; j if so - skip installation
	LEA	DX,MES2			; 'Cannot install program'
	MOV	AH,9			; output message
	INT	21H			; do it
	MOV	AX,4C01H		; exit with error status
	INT	21H
;
; Program is not installed; install it now.
;
INIT70:	PUSH	ES			; save segment
	MOV	AX,352FH		; get old INT 2FH handler
	INT	21H			; returns value in ES:BX
	MOV	I2FOFF,BX		; save offset
	MOV	I2FSEG,ES		; save segment
	LEA	DX,I2FHAN		; point to new INT 2FH handler
	MOV	AX,252FH		; set INT 2FH vector
	INT	21H			; from DS:DX
;
; Perform installation conditional on the selected mode
;
	CMP	MODE,1			; use INT 15H mode?
	JNE	INIT80			; j if not - set up for INT 09H
;
; Use the INT 15H code, which uses the BIOS keyboard interrupt intercept
;
	MOV	AX,3515H		; get old INT 15H handler
	INT	21H			; returns value in ES:BX
	MOV	INTOFF,BX		; save offset
	MOV	INTSEG,ES		; save segment
	LEA	DX,I15HAN		; point to new INT 15H handler
	MOV	AX,2515H		; set INT 15H vector
	INT	21H			; from DS:DX
	POP	ES			; recover segment
	MOV	WORD PTR INTLEN,I15LEN	; save interrupt routine length
	JMP	SHORT INIT90		; rejoin common code
;
; Use the INT 09H code, which uses the keyboard hardware interrupt
;
INIT80:	MOV	AX,3509H		; get old INT 09H handler
	INT	21H			; returns value in ES:BX
	MOV	INTOFF,BX		; save offset
	MOV	INTSEG,ES		; save segment
	LEA	DX,I15HAN		; point to new INT 09H handler
					; (where it WILL be)
	MOV	AX,2509H		; set INT 09H vector
	INT	21H			; from DS:DX
	POP	ES			; recover segment
	MOV	CX,I09LEN		; get interrupt routine length
	MOV	INTLEN,CX		; save it
	CLD				; autoincrement
	MOV	SI,OFFSET I09HAN	; get address of interrupt routine
	MOV	DI,OFFSET I15HAN	; where to move it
	REP	MOVSB			; do so
;
; Complete installation
;
INIT90:	INC	BYTE PTR RESFLAG	; remember to stay resident
;
; The program is now installed. Handle parameters.
;
INIT100:CLD				; autoincrement
	MOV	SI,81H			; offset of command tail
	MOV	DI,81H			; put characters back in same place
;
INIT110:LODSB				; get next command character
	CMP	AL,CR			; end of command?
	JE	INIT130			; j if so
	CMP	AL,'a'			; check if lower case alphabetic
	JL	INIT120			; j if not
	CMP	AL,'z'			; check range
	JG	INIT120			; j if not in range
	SUB	AL,'a'-'A'		; convert to upper case
;
INIT120:STOSB				; return possibly modified character
	JMP	INIT110			; keep scanning
;
INIT130:MOV	SI,81H			; back to start of command tail
;
INIT140:LODSB				; get next character
	CMP	AL,' '			; space?
	JE	INIT140			; j if so - ignore
	CMP	AL,TAB			; tab?
	JE	INIT140			; j if so - ignore
	CMP	AL,CR			; end of parameters?
	JE	INIT150			; j if so
	DEC	SI			; point back to first non-space
	MOV	BX,SI			; save pointer
	MOV	CX,2			; check for ON
	LEA	DI,ON			; 'ON'
	REP	CMPSB			; matched?
	JE	INIT190			; j if so
	MOV	SI,BX			; recover pointer
	MOV	CX,3			; check for OFF
	LEA	DI,OFF			; 'OFF'
	REP	CMPSB			; matched?
	JE	INIT180			; j if so
	LEA	DX,MES4			; 'Parameter must be ON or OFF'
	MOV	AH,9			; output message
	INT	21H			; do it
	MOV	AX,4C01H		; indicate error
	INT	21H			; and exit
;
; No parameter given - just report status unless initial installation
;
INIT150:LEA	DX,MES3			; 'GOLD is '
	MOV	AH,9			; output message
	INT	21H			; do it
	MOV	AH,MPID			; multiplex ID
	MOV	AL,1			; request status
	INT	2FH			; returns AL=0 for OFF, AL=1 for ON
	OR	AL,AL			; test value
	JNZ	INIT160			; j if ON
	LEA	DX,OFF			; 'OFF'
	JMP	SHORT INIT170		; join common code
;
INIT160:LEA	DX,ON			; 'ON'
;
INIT170:MOV	AH,9			; output message
	INT	21H			; do it
	JMP	SHORT INIT220		; use common code
;
INIT180:XOR	DL,DL			; clear flag
	JMP	SHORT INIT200		; jump to setting code
;
INIT190:MOV	DL,1			; set flag
;
; AL now contains the required GOLD setting flag. Check that the rest of
; the command line is blank, then if all is OK set the flag appropriately.
;
INIT200:LODSB				; get next character
	CMP	AL,' '			; space?
	JE	INIT200			; j if so - ignore
	CMP	AL,TAB			; tab?
	JE	INIT200			; j if so - ignore
	CMP	AL,CR			; end of parameters?
	JE	INIT210			; j if so
	LEA	DX,MES5			; 'Invalid parameter'
	MOV	AH,9			; output message
	INT	21H			; do it
	MOV	AX,4C04H		; indicate error
	INT	21H			; and exit
;
; The command line is OK. Set the GOLD flag.
;
INIT210:MOV	AH,MPID			; multiplex ID
	MOV	AL,2			; set flag from DL
	INT	2FH			; set new flag value in resident copy
;
; If this is not the first load of GOLD, just exit.
;
INIT220:TEST	BYTE PTR RESFLAG,1	; make resident?
	JNE	INIT230			; j if so
	MOV	AX,4C00H		; else just exit with success
	INT	21H
;
; This is the first load of GOLD; terminate and stay resident
;
INIT230:MOV	ES,ES:[2CH]		; get environment segment
	MOV	AH,49H			; free memory for it
	INT	21H			; do it
	MOV	DX,OFFSET I15HAN	; size of common part
	ADD	DX,INTLEN		; add size of interrupt routine
	ADD	DX,15			; round to next paragraph
	MOV	CL,4			; amount to shift
	SHR	DX,CL			; convert to paragraphs
	MOV	AX,3100H		; exit with success status
	INT	21H			; and stay resident
;
INTLEN	DW	?			; Size of selected interrupt handler
RESFLAG	DB	0			; Set to 1 if to stay resident
;
ON	DB	'ON',CR,LF,'$'
OFF	DB	'OFF',CR,LF,'$'
MES0	DB	'Sorry - this machine does not support the GOLD utility',CR,LF
	DB	'if the interrupt intercept mode is selected'
	DB	CR,LF,'$'
MES1	DB	'Sorry - DOS 3.0 or above is required for the GOLD utility'
	DB	CR,LF,'$'
MES2	DB	'Sorry - cannot install the GOLD utility',CR,LF,'$'
MES3	DB	'GOLD is $'
MES4	DB	'Parameter must be ON or OFF',CR,LF,'$'
MES5	DB	'Invalid parameter',CR,LF,'$'
;
INFO	DB	'====GOLD version 2.4===='
;
CSEG	ENDS
;
	END	BEGIN
