Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1848 lines
38 KiB

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 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
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 ###
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