
	PAGE 84,132
	TITLE Interrupt 09H re-vector for the IBM PCjr

;	This program is designed to re-vector interrupt 09H to
;	allow the reading of PORT 60H during interrupt 09H. The
;	current routine available in the PCjr BIOS does not
;	facilitate this function. The program is originated to
;	allow VisiWord ver 1.2 to run on the jr.

;	This program is structured as a .COM file.

;	Original version written by Jeff McKee
;	Date 05/01/86

DATA0000	SEGMENT AT 0000H
DUMMY	LABEL	FAR
DATA0000	ENDS

REVECTOR	SEGMENT PARA PUBLIC
	ASSUME	CS:REVECTOR,DS:REVECTOR,ES:REVECTOR,SS:NOTHING
	ORG	005CH
CODE_AREA	EQU	$
	ORG	100H
START:	JMP	SHORT BEGIN


;	NEW INTERRUPT 09H CODE

ROUTINE_NAME	DB	'KBREDIR'       ;NAME TO CHECK FOR PREVIOUS INSTALL
NAME_LN 	EQU	$-ROUTINE_NAME	;LENGTH OF NAME
NEW09H: IN	AL,60H			;GET SCAN CODE FROM PORT A
	PUSHF				;SIMULATE INTERRUPT
	CALL	DUMMY			;SET UP DUMMY VECTOR
VDATA	EQU	$-4			;POINTER FOR VECTOR ADDRESS
	IRET				;RETURN FROM INTERRUPT
NEW9LN	EQU	$-ROUTINE_NAME		;SET UP CODE LENGTH

BAD_VERSION	DB	'Requires DOS 2.00 or greater',13,10,10,'$'

BEGIN:	PUSH	ES			;SAVE ES AND DS FOR EXIT
	CLD				;FORWARD DIRECTION
	MOV	AH,30H			;GET DOS VERSION NUMBER
	INT	21H
	OR	AL,AL			;CHECK FOR VALID VERSION
	JNZ	CHK_RNG 		;JUMP TO RANGE CHECK IF VALID
WRONG_DOS:
	MOV	SI,OFFSET BAD_VERSION	;	OADDRESS OF MESSAGE
CHAR_LOOP:
	LODS	BAD_VERSION		;	ET A CHARACTER
	CMP	AL,'$'                  ;IS THIS THE END OF THE STRING?
	JZ	EXIT_DOS		;JUMP IF SO
	MOV	AH,0EH			;WRITE TTY TO SCREEN
	INT	10H
	JMP	CHAR_LOOP		;	OANOTHER CHARACTER
EXIT_DOS:
	POP	ES			;RECOVER ES
	INT	20H			;RETURN TO DOS
CHK_RNG:
	CMP	AL,02H			;CHECK MAJOR VERSION
	JB	WRONG_DOS		;JUMP IF NOT 2.XX OR ABOVE
	MOV	AX,3509H		;	ET VECTOR FUNCTION
	INT	21H			;GET OLD INT9 VECTOR
	MOV	DI,OFFSET CODE_AREA	;GET ADDRESS TO SEARCH FOR STRING
	MOV	SI,OFFSET ROUTINE_NAME	;	ET ADDRESS OF SEARCH STRING
	MOV	CX,NAME_LN		;	ET LENGTH OF SEARCH STRING
	REP	CMPSB			;SEE IF ALREADY INSTALLED
	JZ	EXIT_DOS		;JUMP IF INSTALLED
	MOV	DI,OFFSET VDATA 	;GET ADDRESS FOR LONG CALL
	MOV	[DI],BX 		;STORE THE OFFSET
	ADD	DI,2			;ADD 2 FOR SEGMENT
	MOV	[DI],ES 		;AND STORE THE SEGMENT
	MOV	SI,OFFSET ROUTINE_NAME	;GET ADDRESS OF CODE
	MOV	DI,OFFSET CODE_AREA	;AND DESTINATION ADDRESS
	MOV	CX,NEW9LN		;	ET LENGTH OF CODE
	POP	ES			;RECOVER ES
	REP	MOVSB			;MOVE THE CODE DOWN IN MEMORY
	MOV	DX,OFFSET CODE_AREA+NAME_LN
	MOV	AX,2509H		;SET VECTOR FUNCTION
	INT	21H			;RE-VECTOR INTERRUPT 09H
	MOV	DX,NEW9LN		;GET CODE LENGTH
	MOV	CL,4			;SET SHIFT COUNT FOR LN/16
	SHR	DX,CL			;DIVIDE BY 16
	INC	DX			;ADD 1 FOR GOOD MEASURE
	MOV	AX,3100H		;TERMINATE AND REMAIN RESIDENT
	INT	21H
REVECTOR	ENDS
	END	START
