PAGE	,132
TITLE	CONDEV	FANCY CONSOLE DRIVER
;******************************************************************************

;  Change Log:

;    Date    Who   #                      Description
;  --------  ---  ---  ------------------------------------------------------
;  06/01/90  MKS  C02  Bug#173.  ANSI was permitting you to go  one line below
;                      the bottom of the screen.  PROMPT $e[25;3H $e[1B will
;                      show you. (PYS: badly done. M005)
;******************************************************************************

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

;       ADDRESSES FOR I/O

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;------------------------------------------------------------------------------
; New functionality in DOS 4.00
; GHG fix scrolling flashes on Mod 25/30's
; P1767 VIDEO_MODE_TABLE not initialized correctly		10/16/87 J.K.
; D375 /X needs to be supported by ANSI sequence also		12/14/87 J.K.
; D397 /L option for Enforcing number of lines			12/17/87 J.K.
; D479  An option to disable the extended keyboard functions	02/12/88 J.K.
; P4241 AN001 fix be Revised to fix this problem		04/20/88 J.K.
; P4532 Scrolling has a snow for CGA adapter			04/27/88 J.K.
; P4533 In mode Dh, Eh, Fh, 10h and 13h, Scrolling not working	04/27/88 J.K.
; P4766 In mode 11h, and 12h erase display leaves bottom 5	05/24/88 F.G.
;------------------------------------------------------------------------------

INCLUDE	DEVSYM.INC
INCLUDE	ANSI.INC		;equates and structures
INCLUDE	VECTOR.INC

BREAK	<ANSI driver code>

PUBLIC	SWITCH_X		; /X option for extended keyboard redefinition support
PUBLIC  SWITCH_R                ; /R option for using screen readers
PUBLIC	SCAN_LINES
PUBLIC	VIDEO_MODE_TABLE
PUBLIC	VIDEO_TABLE_MAX
PUBLIC	MAX_VIDEO_TAB_NUM	;P1767
PUBLIC	PTRSAV
PUBLIC	ERR1
PUBLIC	ERR2
PUBLIC	EXT_16
PUBLIC	BRKKY
PUBLIC	COUT
PUBLIC	BASE
PUBLIC	MODE
PUBLIC	MAXCOL
PUBLIC	EXIT
PUBLIC	NO_OPERATION
PUBLIC	HDWR_FLAG
PUBLIC	SWITCH_L
PUBLIC	SWITCH_K
PUBLIC	SWITCH_S		; M008 /S for screensize option setting.
PUBLIC	fhavek09		; M006

PUBLIC	CON$READ
PUBLIC	CON$RDND
PUBLIC	CON$FLSH
PUBLIC	CON$WRIT
PUBLIC	VIDEO
PUBLIC	CUU
PUBLIC	CUD
PUBLIC	CUF
PUBLIC	CUB
PUBLIC	CUP
PUBLIC	ED
PUBLIC	CPR
PUBLIC	SM
PUBLIC	RM
PUBLIC	SGR
PUBLIC	DSR
PUBLIC	KEYASN
PUBLIC	EXTKEY
PUBLIC	PSCP
PUBLIC	PRCP

IFDEF	JAPAN
PUBLIC	ROW_ADJ
ENDIF

CODE	SEGMENT PUBLIC BYTE

	ASSUME CS:CODE,DS:NOTHING,ES:NOTHING
;-----------------------------------------------

;	C O N - CONSOLE DEVICE DRIVER


EXTRN	CON$INIT	: NEAR		; ANSI initialization code
EXTRN	GENERIC_IOCTL	: NEAR		; Generic IOCTL code
EXTRN	REQ_TXT_LENGTH	: WORD		; current text length
EXTRN	GRAPHICS_FLAG	: BYTE		; graphics flag

ATTRIB	EQU	CHARDEV+DEVIOCTL+DEV320+ISSPEC+ISCOUT+ISCIN
CONDEV:	SYSDEV	<-1,ATTRIB,STRATEGY,ENTRY,'CON     '>	; Matches CON

;--------------------------------------------------------------

;	COMMAND JUMP TABLES
CONTBL:
	DW	CON$INIT
	DW	NO_OPERATION
	DW	NO_OPERATION
	DW	NO_OPERATION
	DW	CON$READ
	DW	CON$RDND
	DW	NO_OPERATION
	DW	CON$FLSH
	DW	CON$WRIT
	DW	CON$WRIT
	DW	NO_OPERATION
	DW	NO_OPERATION
	DW	NO_OPERATION
	DW	NO_OPERATION
	DW	NO_OPERATION
	DW	NO_OPERATION
	DW	NO_OPERATION
	DW	NO_OPERATION
	DW	NO_OPERATION
	DW	GENERIC_IOCTL		; generic IOCTL routine offset
MAX_CMD	EQU	($ - CONTBL)/2		; size of CONTBL

CMDTABL DB	'A'
	DW	CUU			; cursor up
	DB	'B'
	DW	CUD			; cursor down
	DB	'C'
	DW	CUF			; cursor forward
	DB	'D'
	DW	CUB			; cursor back
	DB	'H'
	DW	CUP			; cursor position
	DB	'J'
	DW	ED			; erase display
	DB	'K'
	DW	EL			; erase line
	DB	'R'
	DW	CPR			; cursor postion report
	DB	'f'
	DW	CUP			; cursor position
	DB	'h'
	DW	SM			; set mode
	DB	'l'
	DW	RM			; reset mode
	DB	'm'
	DW	SGR			; select graphics rendition
	DB	'n'
	DW	DSR			; device status report
	DB	'p'
	DW	KEYASN			; key assignment
	DB	'q'			; dynamic support of /X option through ansi sequence
	DW	EXTKEY			; esc[0q = reset it. esc[1q = set it
	DB	's'
	DW	PSCP			; save cursor postion
	DB	'u'
	DW	PRCP			; restore cursor position
IFDEF	JAPAN
	DB	'M'
	DW	DELETE			; delete line
	DB	'L'
	DW	INSERT			; insert line
ENDIF
	DB	00

GRMODE	DB	00,00000000B,00000111B
	DB	01,11111111B,00001000B
	DB	04,11111000B,00000001B
	DB	05,11111111B,10000000B
	DB	07,11111000B,01110000B
	DB	08,10001000B,00000000B
	DB	30,11111000B,00000000B
	DB	31,11111000B,00000100B
	DB	32,11111000B,00000010B
	DB	33,11111000B,00000110B
	DB	34,11111000B,00000001B
	DB	35,11111000B,00000101B
	DB	36,11111000B,00000011B
	DB	37,11111000B,00000111B
	DB	40,10001111B,00000000B
	DB	41,10001111B,01000000B
	DB	42,10001111B,00100000B
	DB	43,10001111B,01100000B
	DB	44,10001111B,00010000B
	DB	45,10001111B,01010000B
	DB	46,10001111B,00110000B
	DB	47,10001111B,01110000B
	DB	0FFH

;---------------------------------------------------
;	Device entry point


PTRSAV	DD	0

BUF1:	BUF_DATA <>			; Next CON Buffer area

STRATP	PROC	FAR

STRATEGY:
	mov	word ptr cs:[PTRSAV],bx
	mov	word ptr cs:[PTRSAV+2],es
	ret

STRATP	ENDP

ENTRY:
	push	si
	push	ax
	push	cx
	push	dx
	push	di
	push	bp
	push	ds
	push	es
	push	bx

; Check if header link has to be set	(Code ported from
;						DISPLAY.SYS)

	lea	bx,BUF1
	mov	di,OFFSET CONDEV	; CON Device header

	mov	CONPTR.DEV_HDRO,di
	mov	CONPTR.DEV_HDRS,cs
	cld				; all moves forward

	cmp	CONPTR.CON_STRAO, -1
	jne	L4			; has been linked to DOS CON
	cmp	CONPTR.CON_STRAS, -1
	jne	L4			; has been linked to DOS CON
					; next device header :	ES:[DI]
	lds	si,dword ptr CONPTR.DEV_HDRO
	les	di,HP.SDEVNEXT

L1:					; while pointer to next device header
	push	es			; is not -1
	pop	ax
	cmp	ax,-1
	jne	NOT0FFFF		; leave if both offset and segment are
	cmp	di,-1			; 0FFFFH
	je	L4

NOT0FFFF:
	push	di
	push	si
	mov	cx,8
	lea	di,NHD.SDEVNAME
	lea	si,HP.SDEVNAME
	repe	cmpsb
	pop	si
	pop	di
	and	cx,cx
					; Exit if name is found in linked hd.
	jnz	L3			; Name is not found
					; Name is found in the linked header
	mov	ax,NHD.SDEVSTRAT	; Get the STRATEGY address
	mov	CONPTR.CON_STRAO,ax
	mov	ax,es
X1:	mov	CONPTR.CON_STRAS,ax

	mov	ax,NHD.SDEVINT	 	; Get the INTERRUPT address
	mov	CONPTR.CON_INTRO,ax
	mov	ax,es
X2:	mov	CONPTR.CON_INTRS,ax

	jmp	SHORT L4		; Device Name
L3:
	les	di,NHD.SDEVNEXT
	jmp	L1
L4:
	lds	bx,cs:[PTRSAV]		; GET PONTER TO I/O PACKET

	mov	cx,word ptr ds:[bx].COUNT

	mov	al,byte ptr ds:[bx].CMD
	cbw
	mov	si,OFFSET CONTBL
	add	si,ax
	add	si,ax
	cmp	al,MAX_CMD		; not a call for ANSI...chain to lower device
	ja	NO_OPERATION

ifdef   KOREA                                   ; <MSCH>
        mov     ah, byte ptr ds:[bx].media
endif   ; KOREA

	les	di,dword ptr ds:[bx].TRANS

	; Following code, supplied by Compaq, is the "hit-it-on-the-head"
	; approach to solving the problem of resetting the screen length
	; after a character set reload.	We should try to find a better
	; approach.	For now this will stay in. - MGD

	push	ax			; SAVE AX
	mov	ax,40H			; GET ROM VAR
	mov	ds,ax			;

	mov	al,ds:[84h]		; GET MAX NUM OF ROWS
	cmp	al,0			; Q:ZERO
	jne	ENTRY10			; jmp IF NO
	mov	al,24			; SET TO 24 ROWS
ENTRY10:				;
	push	cs
	pop	ds

	ASSUME	ds:CODE

	inc	al			; BUMP FOR ONE BASED
	mov	byte ptr [REQ_TXT_LENGTH],al ; SET LENGTH TO 40:84H VALUE.	*F
	pop	ax			; RESTORE AX

	jmp	word ptr [si]		; GO DO COMMAND

;=====================================================
;=
;=	SUBROUTINES SHARED BY MULTIPLE DEVICES
;=
;=====================================================
;----------------------------------------------------------

;	EXIT - ALL ROUTINES RETURN THROUGH THIS PATH

BUS$EXIT:				; DEVICE BUSY EXIT
	mov	ah,00000011B
	jmp	SHORT ERR1

NO_OPERATION:
	call	PASS_CONTROL		; Pass control to lower CON
	jmp	SHORT ERR2

ERR$EXIT:
	mov	ah,10000001B		; MARK ERROR RETURN
	jmp	SHORT ERR1

EXITP	PROC	FAR

EXIT:	mov	ah,00000001B

ifdef   KOREA
INTERIM$EXIT:                           ; <MSCH>
endif   ; KOREA

ERR1:	lds	bx,cs:[PTRSAV]
	mov	word ptr [bx].STATUS,ax	; MARK OPERATION COMPLETE
ERR2:
	pop	bx
	pop	es
	pop	ds
	pop	bp
	pop	di
	pop	dx
	pop	cx
	pop	ax
	pop	si
	ret				; RESTORE REGS and RETURN
EXITP	ENDP


;	PASS CONTROL

;	This calls the attached device to perform any further
;	action on the call!


PASS_CONTROL	PROC
	lea	si,BUF1
	les	bx,cs:[PTRSAV]			; pass the request header to the
	call	dword ptr cs:[si].CON_STRAO	; CON strategy routine.
	call	dword ptr cs:[si].CON_INTRO	; interrupt the CON
	ret
PASS_CONTROL	ENDP
;-----------------------------------------------

;	BREAK KEY HANDLING

BRKKY:
	mov	byte ptr cs:ALTAH,3	; INDICATE BREAK KEY SET
INTRET: iret


;	WARNING - Variables are very order dependent, be careful
;		 when adding new ones!	- c.p.

WRAP		DB	0		; 0 = WRAP, 1 = NO WRAP
ASNPTR		DW	4
STATE		DW	S1
MODE		DB	3		;*
MAXCOL		DB	79		;*
COL		DB	0
ROW		DB	0
SAVCR		DW	0
INQ		DB	0
PRMCNT		LABEL	BYTE
PRMCNTW 	DW	0
KEYCNT		DB	0
KEYPTR		DW	BUF
REPORT		DB	ESC_CHAR,'[00;00R',CR	;CURSOR POSTION REPORT BUFFER
ALTAH		DB	0			;Special key handling

SAVE_CHAR	DW	0			; Temp storage for char/attr for new scroll code

EXT_16		DB	0		; Extended INT 16h flag
SWITCH_X	DB	OFF		; /X flag
SWITCH_L	DB	OFF		; DCR397; 1= /L flag entered.
SWITCH_K	DB	OFF		; To control EXT_16
fhavek09	DB	OFF		; M006
SCAN_LINES	DB	?		; flag for available scan lines (VGA)
HDWR_FLAG	DW	0		; byte of flags indicating video support
SWITCH_S	DB	OFF		; M008; /S flag
SWITCH_R        DB      OFF             ; /R flag for screen readers

ifdef   KOREA                           ;
REQ_TYPE        DB      0               ;
EXT_REQ_TYPE    DB      0               ;
LEADBYTE        DB      0               ;
TRAILBYTE       DB      0               ;
ECSPRE          DB      0               ;
endif   ; KOREA                         ;

VIDEO_MODE_TABLE	LABEL	BYTE	; table containing applicable
MODE_TABLE	<>			; video modes and corresponding
MODE_TABLE	<>			; data.
MODE_TABLE	<>			; this table is initialized at
MODE_TABLE	<>			; INIT time
MODE_TABLE	<>			
MODE_TABLE	<>
MODE_TABLE	<>
MODE_TABLE	<>
MODE_TABLE	<>
MODE_TABLE	<>
MODE_TABLE	<>
MODE_TABLE	<>
MODE_TABLE	<>
MODE_TABLE	<>
MODE_TABLE	<>

ifdef	KOREA				;  The KOREAN video mode
MODE_TABLE   <>                         ;  have 4 more than standard
MODE_TABLE   <>                         ;  VGA  card
MODE_TABLE   <>                         ;
MODE_TABLE   <>                         ;
endif   ; KOREA                         ;

VIDEO_TABLE_MAX	EQU	$		; maximum address for video table
MAX_VIDEO_TAB_NUM	EQU	($-VIDEO_MODE_TABLE)/TYPE MODE_TABLE ;P1767 Max number of table


IFDEF		DBCS
dbcs_flag	DB	0		; 0=single, 1=lead byte, 2=tail byte
ENDIF
IFDEF		JAPAN
new_mode	DB	0		; mode for '>'
row_adj		DB	0		; for ESC[>1l
ENDIF

;-------------------------------------------------------------

;	CHROUT - WRITE OUT CHAR IN AL USING CURRENT ATTRIBUTE

ATTRW		LABEL	WORD
ATTR		DB	00000111B		; CHARACTER ATTRIBUTE
BPAGE		DB	0			; BASE PAGE
BASE		DW	0b800h
SCREEN_SEG 	DW	00000h

chrout:

ifdef   KOREA                   ; <MSCH>
;
        cmp     [leadbyte],1    ; Is the previous byte a lead byte?  ; KeyW
        jnz     TestDBCSRange   ; No,
        mov     byte ptr [leadbyte],0
        mov     byte ptr [trailbyte],1   ; Mark that this is trail byte of ECS
        jmp     short OUTCHR
;
;
; Note : TestECS routine is hard coded. If you have the different code range,
;        you should change some codes below.
; 1990/11/9 This routine is changed to use IsDBCS routines.
;
TestDBCSRange:
        mov     byte ptr [trailbyte], 0 ; Mark it as a non trail byte
        call    IsDBCSleadbyte
        jnz     realout                 ; Jump if one byte code
;
;       CMP     AL, 0A1H                ;
;       JB      REALOUT                 ;
;       CMP     AL, 0FEH                ;
;       JA      REALOUT                 ;

        mov     byte ptr [leadbyte], 1  ;  it as a lead byte
        mov     ah, [col]               ;
        cmp     ah, [maxcol]            ;
        jnz     outchr                  ;
;                                       ;
; Decide the position to print the Lead byte which is on the column boundary.
;
        cmp     [wrap],0                ;
        jz      skip1                   ;
        dec     [col]                   ;
        cmp     [ecspre],1              ;
        jnz     oneback1                ;
        dec     [col]                   ;
oneback1:                               ;
        call    setit1                  ;
        jmp     short outchr            ;
skip1:                                  ;
        push    ax                      ;
        call    outchr1                 ;
        pop     ax                      ;
        jmp     short outchr            ;
realout:
endif   ; KOREA                         ;

	cmp	al,13
	jnz	trylf
	mov	[COL],0

ifdef	KOREA
	jmp	setit
else
IFDEF	JAPAN
	jmp	setit
ELSE
	jmp	short setit
ENDIF
endif   ; KOREA

trylf:	cmp	al,10
	jz	lf
	cmp	al,7
	jnz	tryback
torom:
	mov	bx,[ATTRW]
	and	bl,7
	mov	ah,14
	int	10h
ret5:	ret

tryback:
	cmp	al,8
	jnz	outchr
	cmp	[COL],0
	jz	ret5
	dec	[COL]
	jmp	short setit

outchr:
	mov	bx,[ATTRW]
	mov	cx,1
	mov	ah,9
	int	10h
	inc	[COL]
	mov	al,[COL]
	cmp	al,[MAXCOL]
	jbe	setit
	cmp	[wrap],0
	jz	outchr1
	dec	[COL]

ifdef   KOREA
;
;       Set boundary position for DBCS code.
;               No lead byte can arrive here.
;
        cmp     [trailbyte],1
        jnz     onebk
        dec     [col]
onebk:
        call    setit1
;
; We don't need ECSPRE change, because we have enough time to deal with it.
; Wait for another character to change ECSPRE.
;
endif	; KOREA

	ret
outchr1:
	mov	[COL],0
lf:	inc	[ROW]
	mov	ah,30			; GHG	Fix for ROUNDUP/PALACE
	mov	al,MODE		 	; GHG	Fix for ROUNDUP/PALACE
	cmp	al,11H			; GHG	Fix for ROUNDUP/PALACE
	je	LF2			; GHG	Fix for ROUNDUP/PALACE
	cmp	al,12H			; GHG	Fix for ROUNDUP/PALACE
	je	LF2			; GHG	Fix for ROUNDUP/PALACE

	cmp	GRAPHICS_FLAG,GRAPHICS_MODE
	jne	tmplab1
	mov	ah,DEFAULT_LENGTH
	jmp	short tmplab2
tmplab1:
	mov	ah,byte ptr [REQ_TXT_LENGTH]
tmplab2:
LF2:					; GHG	Fix for ROUNDUP/PALACE
IFDEF JAPAN
	sub	ah,row_adj
ENDIF
	cmp	[ROW],AH		; GHG	Fix for ROUNDUP/PALACE
	jb	setit
	dec	ah			; GHG	Fix for ROUNDUP/PALACE
	mov	[ROW],AH		; GHG	Fix for ROUNDUP/PALACE
	call	scroll

setit:

ifdef	   KOREA
preset:
        xor     al, al
        cmp     [trailbyte],al
        jz      noDBCStrail
        inc     al
noDBCStrail:
        mov     [ecspre], al
setit1:
endif   ; KOREA

	mov	dh,row
	mov	dl,col
	mov	bh,[bpage]
	mov	ah,2
	int	10h
	ret

;Writing a LF char through Teletype function to scroll the screen
;has a side effect of changing the color of the cursor when the PROMPT
;setting in PTM P4241 is used. AN001 uses this method to fix the strobing
;problem of the palace machine.	The old method of scrolling used to directly
;write into video buffer.	The old method has been used by AN001 for
;CGA adater of mode 2 or 3 only.
;To solve P4241, but to maintain the fix of the strobing problem of palace
;machine, we return back to the old logic but the old logic has to be
;Revised for the displays above CGA level.	For the adapters above
;CGA display, we don't need to turn off/on the video - this will causes
;a strobing, if you use do this,	for Palace machine.
;This logic will be only applied to mode 2 and 3 only.

; Following code is bug fix supplied by Compaq - MGD
scroll:

ifdef	KOREA				; Responsible for ROM
        mov     al, 10
        jmp     torom
else
IFDEF	JAPAN				; ### if JAPAN ###

	xor	cx,cx
	cmp	GRAPHICS_FLAG,GRAPHICS_MODE
	jnz	scroll10		; if nor graphic
	mov	dh,DEFAULT_LENGTH
	xor	bh,bh
	jmp	short scroll20
scroll10:
	mov	dh,byte ptr [REQ_TXT_LENGTH]
	mov	bh,[ATTR]
scroll20:
	sub	dh,row_adj
	dec	dh
	mov	dl,[MAXCOL]
	mov	ax,0601h		; scroll up
	int	10h
	jmp	short setit

else					; ### if Not JAPAN ###

;  Because of screen reader problem, /R switch was added.
;  If Switch_R set all line feeds go to torom. Bug #1241- msdos6:

        cmp     SWITCH_R,OFF
	je	is_2or3		 	; if off, goto test mode
	mov	al,10			; if ON send the line feed to the ROM
	jmp	torom			; exit

is_2or3:
	mov	al,mode		 	; get display mode
	cmp	al,4			;Q: mode less than 4?
	jc	is_text		 	;Y: perform kludge
	cmp	al,7			;N: Q: monochrome mode?
	je	is_text		 	;   Y: perform kludge
	mov	al,10			; send the line feed to the ROM
	jmp	torom			; exit

is_text:
	mov	ah,8			; read char/attr at cursor pos
	mov	bh,[bpage]
	int	10h
	mov	[save_char],ax		; save char/attribute

	mov	ah,9			; write char at cursor pos
	mov	bx,[ATTRW]		; use current attribute
	mov	cx,1
	int	10h

	mov	al,10			; send the line feed to the ROM
	call	torom
	mov	ah,3			; read cursor pos
	int	10h
	push	dx			; save it
	mov	ah,2			; set cursor position
	dec	dh			; (to row-1)
	int	10h

	mov	ax,[save_char]		; retrieve saved char/attr
	mov	bl,ah
	mov	ah,9			; write it back to the screen
	mov	cx,1
	int	10h

	pop	dx			; retrieve new cursor position
	mov	ah,2			; set cursor position
	int	10h
	ret
ENDIF					; ### end if Not JAPAN ###
endif   ; KOREA


;------------------------------------------------------

;	CONSOLE READ ROUTINE

CON$READ:
	jcxz	CON$EXIT

ifdef   KOREA                           ;
        mov     [req_type], 0           ;
        mov     [ext_req_type], 10h     ;
        test    ah, 00000001b           ;
        jz      con$loop                ;
        mov     [req_type], 0f0h        ; ; Get Interim mode
        mov     [ext_req_type], 0f8h    ;
        cmp     cx, 1                   ;
        jnz     con$ndisp               ;
                                        ;
        call    chrin                   ;
        stosb                           ;
        cmp     ah, 0f0h                ; ; Is this an interim code ?
        jnz     con$exit                ;
        mov     ah, 00000101b           ;
        jmp     interim$exit            ; ; return to DOS with interim flag set
con$ndisp:                              ;
        call    chrin                   ;
        cmp     ah, 0f0h                ; ; Is this an interim code ?
        jz      con$ndisp               ; ; Skip the interims
        stosb                           ;
        LOOP    CON$NDISP               ;
        JMP     EXIT                    ;
endif   ; KOREA


CON$LOOP:
	push	cx			; SAVE COUNT
	call	CHRIN			; GET CHAR IN AL
	pop	cx
	stosb				; STORE CHAR AT ES:DI
	loop	CON$LOOP
CON$EXIT:
	jmp	EXIT
;---------------------------------------------------------

;	INPUT SINGLE CHAR INTO AL

CHRIN:	xor	ax,ax
	xchg	al,ALTAH		; GET CHARACTER & ZERO ALTAH
	or	al,al
	jnz	KEYRET

INAGN:	cmp	KEYCNT,0
	jnz	KEY5A

ifdef   KOREA
        mov     ah, [req_type]
else
	xor	ah,AH
endif   ; KOREA

	cmp	EXT_16,ON		; extended interrupt available?
	jne	tmplab3

ifdef   KOREA
        mov     ah, [ext_req_type]
else
	mov	ah,10h			; yes..perform extended call
endif	; KOREA

	INT	16h

ifdef   KOREA
        cmp     ah, 0f0h
        jz      keyret1                 ; Breief return for the interim code
endif   ; KOREA

	cmp	SWITCH_X,OFF		; /X switch used?
	jne	tmplab5
	call	CHECK_FOR_REMAP 	; no....map to normal call

tmplab5:
	call	SCAN			; check for redefinition
	jz	tmplab4			; no redefinition?....and
	cmp	SWITCH_X,ON		; /X switch used?
	jne	tmplab4
	call	CHECK_FOR_REMAP 	; then remap..
	or	bx,bx			; reset zero flag for jump test in old code

	jmp	short tmplab4

;	extended interrupt not available

tmplab3:
	int	16h

ifdef   KOREA
        cmp     ah, 0f0h
        jz      keyret1
endif   ; KOREA

	call	SCAN			; check for redefinition

tmplab4:
	jnz	ALT10			; IF NO MATCH JUST RETURN IT

	dec	cx
	dec	cx
	inc	bx
	inc	bx
	cmp	al,0			; check whether keypacket is an extended one
	jz	tmplab7
	cmp	al,0e0h
	jnz	tmplab6

ifdef   KOREA
        cmp     ah, 0f0h
        jb      mschtmp2
        cmp     ah, 0f2h
        jbe     tmplab7
mschtmp2:
endif   ; KOREA

	cmp	SWITCH_X,1
	jnz	tmplab6
tmplab7:
	dec	cx			; adjust pointers
	inc	bx			; appropiately
tmplab6:
	mov	KEYCNT,cl
	mov	KEYPTR,bx
KEY5A:					; Jmp here to get rest of translation
	call	KEY5			; GET FIRST KEY FROM TRANSLATION
ALT10:
	or	ax,ax			; Check for non-key after BREAK
	jz	INAGN
	or	al,al			; SPECIAL CASE?
	jnz	KEYRET
	mov	ALTAH,ah		; STORE SPECIAL KEY
KEYRET:

ifdef   KOREA
        mov     ah, 0f1h
keyret1:
endif   ; KOREA

	ret

KEY5:	mov	bx,KEYPTR		; GET A KEY FROM TRANSLATION TABLE
	mov	ax,word ptr [bx]
	dec	KEYCNT
	inc	bx
	or	al,al
	jnz	KEY6
	inc	bx
	dec	KEYCNT
KEY6:	mov	KEYPTR,bx
	ret

SCAN:	mov	bx,OFFSET BUF
KEYLP:	mov	cl,byte ptr [bx]
	xor	ch,ch
	or	cx,cx
	jz	NOTFND
	cmp	al,0			; check whether extended keypacket
	jz	tmplab8
	cmp	al,0e0h			; extended must be enabled with /x
	jnz	tmplab9

ifdef   KOREA                           ; Jump when Hangeul char
        cmp     ah, 0f0h
        jb      mschtmp1
        cmp     ah, 0f2h
        jbe     tmplab9
mschtmp1:
endif   ; KOREA

	cmp	SWITCH_X,ON
	jnz	tmplab9
tmplab8:
	cmp	ax,word ptr [bx+1]	; yes...compare the word
	jmp	short tmplab10
tmplab9:
	cmp	al,byte ptr [bx+1]	; no...compare the byte
tmplab10:
	jz	MATCH
	add	bx,cx
	jmp	KEYLP
NOTFND:	or	bx,bx
MATCH:	ret
;--------------------------------------------------------------

;	KEYBOARD NON DESTRUCTIVE READ, NO WAIT

CON$RDND:
	mov	al,[ALTAH]
	or	al,al

ifdef   KOREA
        jnz     To_RDEXIT
else
	jnz	RDEXIT
endif   ; KOREA

	cmp	[KEYCNT],0
	jz	RD1
	mov	bx,[KEYPTR]
	mov	al,byte ptr [bx]

ifdef   KOREA
to_rdexit:
        jmp     rdexit
else
	jmp	SHORT RDEXIT
endif   ; KOREA

RD1:

ifdef   KOREA
        mov     [req_type], 1
        mov     [ext_req_type], 11H
        test    ah, 00000001b
        jz      rd11
        mov     [req_type], 0f1h
        mov     [ext_req_type], 0f9H
RD11:
        mov     ah, [req_type]
        cmp     ext_16, on
        jnz     tmplab11
        mov     ah, [ext_req_type]
else
        mov     ah,1
	cmp	EXT_16,ON
	jnz	tmplab11
	add	ah,10h			; yes....adjust to extended call
endif	; KOREA

tmplab11:
	int	16h
	jz	CheckForEvent
	or	ax,ax
	jnz	RD2

ifdef   KOREA
        mov     ah, [req_type]
        and     ah, 11111110b
else
        mov     ah,0
endif   ; KOREA

	cmp	EXT_16,ON		; extended interrupt available?
	jne	tmplab12

ifdef   KOREA
        mov     ah, [ext_req_type]
        and     ah, 11111110b
else
	mov	ah,10h			; yes..perform extended call
endif   ; KOREA

	int	16h
	cmp	SWITCH_X,OFF		; /X switch used?
	jnz	tmplab13
	call	CHECK_FOR_REMAP		; no....map to normal call
	jmp	short tmplab13
tmplab12:
	int	16h
tmplab13:
	jmp	CON$RDND

RD2:

ifdef   KOREA
        cmp     ah, 0f0h
        jz      rdexit
endif   ; KOREA

	call	SCAN
	jz	tmplab14		; if no redefinition
	cmp	EXT_16,ON
	jnz	tmplab14		; and extended INT16 used
	cmp	SWITCH_X,ON		; and /x used
	jnz	tmplab14

	call	CHECK_FOR_REMAP		; remap to standard call
	or	bx,bx			; reset zero flag for jump test in old code

tmplab14:
	jnz	RDEXIT

	mov	al,byte ptr [bx+2]
	cmp	byte ptr [bx+1],0
	jnz	RDEXIT
	mov	al,byte ptr [bx+3]
RDEXIT: lds	bx,[PTRSAV]
	mov	[bx].MEDIA,al
EXVEC:	jmp	EXIT

; M006 - begin

CheckForEvent:
	cmp	fhavek09,0
	jz	CONBUS			; return with busy status if not k09

	les	bx,[ptrsav]
	assume	es:nothing
	test	es:[bx].status,0400h	; system wait enabled?
	jz	CONBUS			;  return with busy status if not

;	need to wait for ibm response to request for code
;	on how to use the system wait call.

	mov	ax,4100h		; wait on an external event
	xor	bl,bl			; wait for any event
	int	15h			; call rom for system wait

; M006 - end

CONBUS: jmp	BUS$EXIT
;--------------------------------------------------------------

;	KEYBOARD FLUSH ROUTINE

CON$FLSH:
	mov	[ALTAH],0		; Clear out holding buffer
	mov	[KEYCNT],0

ifdef   KOREA
        mov     ah, 0f3h
        int     16h
 ReadNullByte:                          ; We may have final char
        mov     ah, 0f1h
        int     16h
        jz      FlushDone
        mov     ah, 0f0h
        int     16h
        jmp     short   ReadNullByte
FlushDone:
else
Flush:	mov	ah,1
	cmp	EXT_16,ON		; if extended call available
	jnz	tmplab15
	add	ah,10h			; then use it
tmplab15:

	int	16h
	jz	FlushDone
	mov	ah,0

	cmp	EXT_16,ON		; if extended call available
	jnz	tmplab16
	add	ah,10h			; use it
tmplab16:
	int	16h
	jmp	Flush
FlushDone:
endif   ; KOREA

	jmp	EXVEC
;----------------------------------------------------------

;	CONSOLE WRITE ROUTINE

CON$WRIT:
	jcxz	EXVEC

ifdef   KOREA
        test    ah, 00000001b
        jnz     con$lp_nac      ;OUT CHAR WITHOUT CURSOR ADVANCING
endif   ; KOREA

CON$LP: mov	al,es:[di]		; GET CHAR
	inc	di
	call	OUTC			; OUTPUT CHAR
	loop	CON$LP			; REPEAT UNTIL ALL THROUGH
	jmp	EXVEC

ifdef   KOREA
con$lp_nac:
        mov     al, es:[di]
        inc     di
        call    outchr_nac      ;OUTPUT CHAR WITHOUT CURSOR MOVE
        loop    con$lp_nac      ;REPEAT UNTIL ALL THROUGH
        jmp     exit

outchr_nac:
        push    ax
        push    si
        push    di
        push    bp
        mov     ah, 0feh        ;OUTPUT CHAR WITHOUT CURSOR ADVANCING
        mov     bl, 7           ;SET FOREGROUND COLOR
        int     10h             ;CALL ROM BIOS
        pop     bp
        pop     di
        pop     si
        pop     ax
        ret
endif

COUT:	sti
	push	ds
	push	cs
	pop	ds
	call	OUTC
	pop	ds
	Iret

OUTC:	push	ax
	push	bx
	push	cx
	push	dx
	push	si
	push	di
	push	es
	push	bp

	mov	[BASE],0b800h
	xchg	ax,si			; SAVE CHARACTER TO STUFF
	mov	ax,40h			; POINT TO ROS BIOS
	mov	ds,ax
	mov	ax,ds:[49h]		; AL=MODE, AH=MAX COL
	dec	ah			; ANSI NEEDS 0-79 OR 0-39
	mov	word ptr cs:[MODE],ax	; SAVE MODE and MAX COL
	cmp	al,7
	jnz	NOT_BW
	mov	word ptr cs:[BASE],0B000H
NOT_BW: mov	al,ds:[62H]		; GET ACTIVE PAGE
	mov	cs:[BPAGE],al
	cbw
	add	ax,ax
	mov	bx,ax
	mov	ax,ds:[bx+50H]		; AL=COL, AH=ROW
	mov	word ptr cs:[COL],ax	; SAVE ROW and COLUMN
	mov	ax,ds:[4EH]		; GET START OF SCREEN SEG
	mov	cl,4
	shr	ax,cl			; CONVERT TO A SEGMENT
	push	cs
	pop	ds
	mov	[SCREEN_SEG],ax
	xchg	ax,si			; GET BACK CHARACTER IN AL

	call	VIDEO
	pop	bp
	pop	es
	pop	di
	pop	si
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret


;----------------------------------------------------------

;	OUTPUT SINGLE CHAR IN AL TO VIDEO DEVICE

VIDEO:	mov	si,OFFSET STATE
	jmp	[si]

S2:	cmp	al,'['
	jz	S22

ifdef   KOREA
        cmp     al, '$'
        jnz     chk_off
        mov     word ptr [si], offset S8
        ret
chk_off:
        cmp     al, '('
        jnz     jmp_S1
        mov     word ptr [si], offset S10
        ret
jmp_S1:
endif   ; KOREA

	jmp	S1
S22:	mov	word ptr [si],OFFSET S3
	xor	bx,bx
	mov	word ptr INQ,bx
	jmp	SHORT S3B

S3:	cmp	al,';'
	jnz	S3C
S3A:	inc	PRMCNT
S3B:	call	GETPTR
	xor	ax,ax
	mov	word ptr [bx],ax	; DEFAULT VALUE IS ZERO
	ret

S3C:	cmp	al,'0'
	jb	S3D
	cmp	al,'9'
	ja	S3D
	call	GETPTR
	sub	al,'0'
	xchg	al,byte ptr [bx]
	mov	ah,10
	mul	ah			; *10
	add	byte ptr [bx],al	; movE IN DIGIT
	ret

S3D:	cmp	al,'='
	jz	S3ret
	cmp	al,'?'
	jz	S3ret
IFDEF JAPAN
	cmp	al,'>'
	jz	s3f
ENDIF
	cmp	al,'"'			; BEGIN QUOTED STRING
	jz	S3E
	cmp	al,"'"
	jnz	S7
S3E:	mov	word ptr [si],OFFSET S4
	mov	[INQ],al
S3ret:	ret

IFDEF JAPAN
s3f:
	mov	new_mode,1
	jmp	short s3ret
ENDIF


;	ENTER QUOTED STRINGS


S4:	cmp	al,[INQ]		; CHECK FOR STRING TERMINATOR
	jnz	S4A
	dec	PRMCNT			; TERMINATE STRING
	mov	word ptr [si],OFFSET S3
	ret

S4A:	call	GETPTR
	mov	byte ptr [bx],al
	mov	word ptr [si],OFFSET S4
	jmp	S3A

;	LOOK FOR ANSI COMMAND SPECIFIED IN AL


	PUBLIC	S7
S7:	mov	bx,OFFSET CMDTABL-3

S7A:	add	bx,3
	cmp	byte ptr [bx],0
	jz	S1B
	cmp	byte ptr [bx],al
	jnz	S7A

S7B:	mov	ax,word ptr [bx+1]	; AX = JUMP addRESS
	mov	bx,OFFSET BUF
	inc	bx
	add	bx,ASNPTR		; BX = PTR TO PARM LIST
	mov	DL,byte ptr [bx]
	xor	DH,DH			; DX = FIRST PARAMETER
	mov	cx,dx
	or	cx,cx
	jnz	S7C
	inc	cx			; CX = DX, CX=1 IF DX=0
S7C:	jmp	ax			; AL = COMMAND

S1:	cmp	al,ESC_CHAR		; ESCAPE SEQUENCE?
	jnz	S1B
IFDEF	DBCS
	mov	dbcs_flag,0
ENDIF
IFDEF	JAPAN
	mov	new_mode,0
ENDIF
	mov	word ptr [si],OFFSET S2
	ret

S1B:

ifndef  KOREA                           ; IN KOREA, WE ALREADY handled
IFDEF DBCS
	cmp	dbcs_flag,1
	jz	set_dbcs		; if it was lead byte
	cmp	dbcs_flag,2
	jnz	@f			; if it was not tail byte
	mov	dbcs_flag,0		; reset
@@:
	call	IsDBCSLeadByte
	jnz	@f			; if this is not lead byte
set_dbcs:
	inc	dbcs_flag
@@:
	cmp	dbcs_flag,1
	jnz	@f
	mov	dl,col
	cmp	dl,maxcol
	jnz	@f
	push	ax
	mov	al,' '
	call	chrout
	pop	ax
@@:
ENDIF
endif   ; NOT KOREA

	call	CHROUT
S1A:	mov	word ptr [STATE],OFFSET S1
	ret

ifdef   KOREA
S8:     cmp     al, ')'
        jnz     s1
        mov     word ptr [si], offset S9
        ret
S9:     cmp     al, '1'
        jnz     S1
han_on:
        mov     ah, 0f2h
        mov     al, 08h                 ; Hangeul input mode on
        int     16h
        ret

S10:    cmp     al, '2'
        jnz     S1
han_off:
        mov     ah, 0f2h
        mov     al, 00h
        int     16h
        ret
endif   ; KOREA

MOVCUR:					;C02
	cmp	byte ptr [bx],AH
	jz	SETCUR
	add	byte ptr [bx],al
	loop	MOVCUR
SETCUR: mov	dx,word ptr COL
;*C05	xor	bx,bx
	mov	ah,0fh			;*C05
	int	10h			;*C05
	mov	ah,2
	int	16
	jmp	S1A

CUP:
					
IFDEF	JAPAN				; ### if JAPAN ###
	cmp	GRAPHICS_FLAG,GRAPHICS_MODE
	jnz	tmplab17		; if not graphic mode
	mov	ah,DEFAULT_LENGTH
	jmp	short tmplab18
tmplab17:
	mov	ah,byte ptr [REQ_TXT_LENGTH]
tmplab18:
	sub	ah,row_adj
	cmp	cl,ah
ELSE
	cmp	GRAPHICS_FLAG,GRAPHICS_MODE
	jnz	tmplab17
	cmp	cl,DEFAULT_LENGTH
	jmp	short tmplab18
tmplab17:
	cmp	cl,byte ptr [REQ_TXT_LENGTH]
tmplab18:
ENDIF					; ### end if JAPAN ###

	ja	SETCUR
	mov	al,MAXCOL
	mov	ch,byte ptr [bx+1]
	or	ch,CH
	jz	CUP1
	dec	CH
CUP1:	cmp	al,CH
	ja	CUP2
	mov	ch,al
CUP2:	xchg	cl,CH
	dec	CH
	mov	word ptr COL,cx
	jmp	SETCUR

CUF:	mov	ah,MAXCOL
	mov	al,1
CUF1:	mov	bx,OFFSET COL
	jmp	MOVCUR

CUB:	mov	ax,00FFH
	jmp	CUF1

CUU:	mov	ax,00FFH
CUU1:	mov	bx,OFFSET ROW
	jmp	MOVCUR

CUD:
	cmp	GRAPHICS_FLAG,GRAPHICS_MODE
	jnz	tmplab19
	mov	ah,DEFAULT_LENGTH
	jmp	short tmplab20
tmplab19:
	mov	ah,byte ptr [REQ_TXT_LENGTH]
	dec	ah			; M005; REQ_TXT_LENGTH is not 0 based
tmplab20:
IFDEF JAPAN
	sub	ah,row_adj
ENDIF
	mov	al,1
	jmp	CUU1

ExtKey:
	cmp	dl, 0			; DL = previous parameter
	jne	ExtKey_1
	mov	Switch_X, OFF		; reset it if 0.
	jmp	S1A
ExtKey_1:
	cmp	dl, 1			; 1 ?
	je	SetExtKey
	jmp	S1A			; ignore it
SetExtKey:
	mov	Switch_X, ON		; set it if 1.
	jmp	S1A

PSCP:	mov	ax,word ptr COL
	mov	SAVCR,ax
	jmp	SETCUR

PRCP:	mov	ax,SAVCR
	mov	word ptr COL,ax
	jmp	SETCUR

SGR:	xor	cx,cx
	xchg	cl,PRMCNT
	call	GETPTR
	inc	cx
SGR1:	mov	al,byte ptr [bx]
	push	bx
	mov	bx,OFFSET GRMODE
SGR2:	mov	ah,byte ptr [bx]
	add	bx,3
	cmp	ah,0FFH
	jz	SGR3
	cmp	ah,al
	jnz	SGR2
	mov	ax,word ptr [bx-2]
	and	ATTR,al
	or	ATTR,AH
SGR3:	pop	bx
	inc	bx
	loop	SGR1
	jmp	SETCUR

IFDEF JAPAN				; ### if JAPAN ###
ED:
	mov	bl,dl			; save function no.
	mov	dh,30
	mov	al,MODE
	cmp	al,11h
	je	ed20			; if graphic 640X480
	cmp	al,12h
	je	ed20			; if graphic 640X480
	cmp	GRAPHICS_FLAG,GRAPHICS_MODE
	jnz	ed10			; if not graphic mode
	mov	dh,DEFAULT_LENGTH
	jmp	short ed20
ed10:
	mov	dh,byte ptr [REQ_TXT_LENGTH]
ed20:
	sub	dh,row_adj
	dec	dh			; last row
	mov	dl,MAXCOL
	xor	cx,cx
	cmp	bl,0
	jz	ed_func0
	cmp	bl,1
	jz	ed_func1
	mov	word ptr COL,cx		; ESC[2J
	jmp	short ed_30
ed_func0:				; ESC[0J
	push	dx
	mov	cx,word ptr COL
	mov	dh,ch
	mov	dl,MAXCOL
	call	erase			; erase to eol
	pop	dx
	mov	ch,ROW
	cmp	ch,dh
	jz	ed_end			; if at bottom
	inc	ch
	mov	cl,0
	jmp	short ed_30
ed_func1:				; ESC[1J
	mov	dx,word ptr COL
	mov	ch,dh
	mov	cl,0
	call	erase			; erase from top
	mov	dh,ROW
	cmp	dh,0
	jz	ed_end
	dec	dh
	mov	dl,MAXCOL
	xor	cx,cx
ed_30:
	call	erase
ed_end:
	jmp	setcur

EL:
	cmp	dl,1
	jz	el_func1
	cmp	dl,2
	jz	el_func2
	mov	cx,word ptr COL		; ESC[0K
	mov	dh,ch
	mov	dl,MAXCOL
	jmp	short el_10
el_func1:
	mov	dx,word ptr COL		; ESC[1K
	mov	ch,dh
	mov	cl,0
	jmp	short el_10
el_func2:
	mov	ch,ROW			; ESC[2K
	mov	dh,ch
	mov	cl,0
	mov	dl,MAXCOL
el_10:
	call	erase
	jmp	setcur

erase:
	cmp	GRAPHICS_FLAG,GRAPHICS_MODE	; if we are in graphics mode,
	jnz	erase10
	xor	bh,bh			; then use 0 as attribute
	jmp	short erase20
erase10:
	mov	bh,ATTR			; else use ATTR
erase20:
	mov	ax,0600H		; clear
	int	10h
	ret

else					; ### if Not JAPAN ###

ED:	xor	cx,cx
	mov	word ptr COL,cx
	mov	DH,30
	mov	al,MODE
	cmp	al,11H
	je	ERASE
	cmp	al,12H
	je	ERASE

	cmp	GRAPHICS_FLAG,GRAPHICS_MODE
	jnz	tmplab21
	mov	dh,DEFAULT_LENGTH
	jmp	short tmplab22
tmplab21:
	mov	dh,byte ptr [REQ_TXT_LENGTH]
tmplab22:
ERASE:	mov	DL,MAXCOL

	cmp	GRAPHICS_FLAG,GRAPHICS_MODE	; if we are in graphics mode,
	jnz	tmplab23
	xor	bh,bh			;	then use 0 as attribute
	jmp	short tmplab24
tmplab23:
	mov	bh,ATTR			;	else use ATTR
tmplab24:
	mov	ax,0600H
	int	16
ED3:	jmp	SETCUR

EL:	mov	cx,word ptr COL
	mov	DH,CH
	jmp	ERASE

ENDIF					; ### end if Not JAPAN ###

IFDEF JAPAN				; ### if JAPAN ###
delete:
	mov	ah,6			; scroll up
	jmp	short insdel
insert:
	mov	ah,7			; scroll down
insdel:
	mov	al,cl			; set scroll number
	mov	COL,0			; set to top of row
	mov	cx,word ptr COL
	cmp	GRAPHICS_FLAG,GRAPHICS_MODE
	jnz	line10			; if not graphic mode
	mov	dh,DEFAULT_LENGTH
	xor	bh,bh			; attribute
	jmp	short line20
line10:
	mov	bh,ATTR
	mov	dh,byte ptr [REQ_TXT_LENGTH]
line20:
	sub	dh,row_adj
	dec	dh
	mov	dl,MAXCOL
	int	10h			; scroll
	jmp	setcur
ENDIF					; ### end if JAPAN ###

BIN2ASC:mov	DL,10
	inc	AL
	xor	ah,AH
	div	dl
	add	ax,'00'
	ret
DSR:	mov	ah,REQ_CRSR_POS
	push	bx
	xor	bh,bh
	int	10h
	pop	bx
	push	dx
	mov	al,dh			;REPORT CURRENT CURSOR POSITION
	call	BIN2ASC
	mov	word ptr REPORT+2,ax
	pop	dx
	mov	al,DL
	call	BIN2ASC
	mov	word ptr REPORT+5,ax
	mov	[KEYCNT],9
	mov	[KEYPTR],OFFSET REPORT
CPR:	jmp	S1A

RM:	mov	cl,1
	jmp	SHORT SM1

SM:	xor	cx,cx
SM1:	mov	al,DL

IFDEF JAPAN
	cmp	new_mode,1
	jz	nmode
ENDIF

	cmp	al,MODE7		;	if mode isn't (0-6, 13-19)
	jl	tmplab25		;	then skip	(cas -- signed?)
	cmp	al,MODE13
	jl	tmplab26
	cmp	al,MODE19
	jg	tmplab26

tmplab25:
	test	HDWR_FLAG,LCD_ACTIVE	; is this the LCD?
	jz	tmplab25a		; skip if not

	push	ds			; WGR yes...
	push	ax			; WGR save mode
	mov	ax,ROM_BIOS
	mov	ds,ax			; WGR get equipment status flag..
	mov	ax,DS:[EQUIP_FLAG]
	and	ax,INIT_VID_MASK	; WGR clear initial video bits..
	or	ax,LCD_COLOR_MODE	; WGR .....set bits as color
	mov	ds:[EQUIP_FLAG],ax 	; WGR replace updated flag.
	pop	ax			; WGR restore mode.
	pop	ds

tmplab25a:

	mov	ah,SET_MODE		; WGR yes....set mode..
	int	10H
	jmp	short tmplab27

tmplab26:
	cmp	al,7			; then if 7, wrap at EOL
	jnz	tmplab27
	mov	[WRAP],CL		; WGR yes....wrap...
tmplab27:
	jmp	CPR

IFDEF JAPAN				; ### if JAPAN ###
nmode:
	mov	new_mode,0
	cmp	al,1
	jz	row_mode		; set row mode
	cmp	al,5
	jz	cur_mode		; set cursor mode
	jmp	cpr
row_mode:
	mov	row_adj,0
	jcxz	row_mode_ret		; if set mode
	cmp	GRAPHICS_FLAG,GRAPHICS_MODE
	jnz	row_mode10		; if not graphic mode
	mov	ah,DEFAULT_LENGTH
	jmp	short row_mode20
row_mode10:
	mov	ah,byte ptr [REQ_TXT_LENGTH]
row_mode20:
	dec	ah
	cmp	row,ah
	jb	row_mode_30		; if cursor not at bottom row
	dec	row
	call	scroll
row_mode_30:
	inc	row_adj
row_mode_ret:
	jmp	cpr
cur_mode:
	push	cx
	mov	ah,3			; get cursor
	mov	bh,bpage
	int	10h
	pop	ax
	or	ax,ax
	jz	cur_mode10		; if for cursor off
	and	ch,11011111b		; cursor on
	jmp	short cur_mode20
cur_mode10:
	or	ch,00100000b		; corsor off
cur_mode20:
	mov	ah,1			; set cursor
	int	10h
	jmp	cpr
ENDIF					; ### end if JAPAN ###

KEYASN: xor	dx,dx
	xchg	DL,PRMCNT		;GET CHARACTER COUNT
	inc	dx
	inc	dx

	call	GETPTR
	mov	ax,word ptr [bx]	;GET CHARACTER TO BE ASSIGNED
	call	SCAN			;LOOK IT UP
	jnz	KEYAS1

	mov	di,bx			;DELETE OLD DEFINITION
	sub	ASNPTR,cx
	mov	KEYCNT,0		; This delete code shuffles the
					; key definition table all around.
					; This will cause all sorts of trouble
					; if we are in the middle of expanding
					; one of the definitions being shuffled.
					; So shut off the expansion.
	mov	si,di
	add	si,cx
	mov	cx,OFFSET BUF+ASNMAX
	sub	cx,si
	cld
	push	es			; SAVE USER'S ES
	push	CS
	pop	es			; SET UP ES addRESSABILITY
	rep	movsb
	pop	es			; RESTORE ES

KEYAS1: call	GETPTR
	cmp	DL,3
	jb	KEYAS3
	mov	byte ptr [bx-1],DL	; SET LENGTH
	add	ASNPTR,dx		; REMEMBER END OF LIST
	add	bx,dx
	cmp	ASNPTR,ASNMAX		; Too much???
	jb	KEYAS3			; No
	sub	bx,dx			; Next three instructions undo the above
	sub	ASNPTR,dx
KEYAS3: mov	byte ptr [bx-1],00
	mov	STATE,OFFSET S1		; RETURN
	ret

GETPTR: mov	bx,ASNPTR
	inc	bx
	add	bx,PRMCNTW
	cmp	bx,ASNMAX + 8
	jb	GET1
	dec	PRMCNT
	jmp	GETPTR
GET1:	add	bx,OFFSET BUF
	ret




; CHECK_FOR_REMAP:

; This function esnures that the keypacket
; passed to it in AX is mapped to a standard INT16h call



CHECK_FOR_REMAP PROC NEAR
	cmp	al,0e0h			; extended key?
	jnz	tmplab28

ifdef   KOREA
        cmp     ah, 0f0h
        jb      mschtmp
        cmp     ah, 0f2h
        jbe     tmplab28
mschtmp:
endif   ; KOREA

	or	ah,ah			; probably, but check for alpha character
	jz	tmplab28
	xor	al,al			; if not an alpha, map extended to standard
tmplab28:
	ret
CHECK_FOR_REMAP ENDP

IFDEF DBCS

;	Test if the character is DBCS Lead Byte

;	input:	AL = character to check
;	outpit:	ZF = 1 if DBCS Lead Byte

	public	DBCSLeadByteTable
DBCSLeadByteTable	dd	0

IsDBCSLeadByte		proc	near
	push	ax
	push	si
	push	ds
	lds	si,cs:DBCSLeadByteTable
idlb_check:
	cmp	word ptr [si],0
	jz	idlb_not		; if end of table
	cmp	al,[si]
	jb	idlb_next		; if below low value
	cmp	al,[si+1]
	jbe	idlb_yes		; if below high value
idlb_next:
	add	si,2			; do next
	jmp	short idlb_check
idlb_not:
	or	al,1			; reset ZF
	jmp	short idlb_end
idlb_yes:
	and	al,0			; set ZF
idlb_end:
	pop	ds
	pop	si
	pop	ax
	ret
IsDBCSLeadByte		endp
ENDIF


BUF	DB	4,00,72H,16,0
	DB	ASNMAX+8-5 DUP (?)

CODE	ENDS
	END

