ioctl.asm
来自「Dos6.0」· 汇编 代码 · 共 1,204 行 · 第 1/2 页
ASM
1,204 行
PAGE ,132
TITLE ANSI Generic IOCTL Code
;******************************************************************************
; Change Log:
; Date Who # Description
; -------- --- --- ------------------------------------------------------
; 06/29/90 MKS C04 Bug#1150. Video 7 Fastwrite VGA has problems if a
; Hercules mono board is the active display.
;******************************************************************************
;****************** START OF SPECIFICATIONS **************************
; MODULE NAME: IOCTL.ASM
; DESCRIPTIVE NAME: PERFORM THE GENERIC IOCTL CALL IN ANSI.SYS
; FUNCTION: THE GENERIC DEVICE IOCTL IS USED TO SET AND GET THE
; MODE OF THE DISPLAY DEVICE ACCORDING TO PARAMETERS PASSED
; IN A BUFFER. ADDITIONALLY, THE CALL CAN TOGGLE THE
; USE OF THE INTENSITY BIT, AND CAN LOAD THE 8X8 CHARACTER
; SET, EFFECTIVELY GIVING MORE LINES PER SCREEN. THE
; AVAILABILITY OF THIS FUNCTION VARIES STRONGLY WITH HARDWARE
; ATTACHED.
; ENTRY POINT: GENERIC_IOCTL
; INPUT: LOCATION OF REQUEST PACKET STORED DURING STRATEGY CALL.
; AT EXIT:
; NORMAL: CARRY CLEAR - DEVICE CHARACTERISTICS SET
; ERROR: CARRY SET - ERROR CODE IN AX.
; AX = 1 - INVALID FUNCTION. EXTENDED ERROR = 20
; AX = 10 - UNSUPPORTED FUNCTION ON CURRENT HARDWARE.
; EXTENDED ERROR = 29
; AX = 12 - DISPLAY.SYS DOES NOT HAVE 8X8 RAM CHARACTER SET.
; EXTENDED ERROR = 31
; INTERNAL REFERENCES:
; ROUTINES: GET_IOCTL - PERFORMS THE GET DEVICE CHARACTERISTICS
; SET_IOCTL - PERFORMS THE SET DEVICE CHARACTERISTICS
; GET_SEARCH - SEARCHES THE INTERNAL VIDEO TABLE FOR THE
; CURRENT MODE MATCH
; SET_SEARCH - SEARCHES THE INTERNAL VIDEO TABEL FOR THE
; CURRENT MODE MATCH
; SET_CURSOR_EMUL - SETS THE BIT THAT CONTROLS CURSOR EMULATION
; INT10_COM - INTERRUPT 10H HANDLER TO KEEP CURRENT SCREEN SIZE
; INT2F_COM - INTERRUPT 2FH INTERFACE TO GENERIC IOCTL
; MAP_DOWN - PERFORMS CURSOR TYPE MAPPING FOR EGA WITH MONOCHROME
; SET_VIDEO_MODE - SETS THE VIDEO MODE
; DATA AREAS: SCAN_LINE_TABLE - HOLDS SCAN LINE INFORMATION FOR PS/2
; FUNC_INFO - BUFFER FOR PS/2 FUNCTIONALITY CALL.
; EXTERNAL REFERENCES:
; ROUTINES: INT 10H SERVICES
; DATA AREAS: VIDEO_MODE_TABLE - INTERNAL TABLE FOR CHARACTERISTICS TO MODE
; MATCH-UPS
; NOTES:
; REVISION HISTORY:
; Label: "DOS ANSI.SYS Device Driver"
; "Version 4.00 (C) Copyright 1988 Microsoft"
; "Licensed Material - Program Property of Microsoft"
;****************** END OF SPECIFICATIONS ****************************
;Modification history *********************************************************
; P1350 Codepage switching not working on EGA 10/10/87 J.K.
; P1626 ANSI does not allow lines=43 with PS2,Monochrome 10/15/87 J.K.
; p1774 Lines=43 after selecting cp 850 does not work 10/20/87 J.K.
; p1740 MODE CON LINES command causes problem with PE2 w PS/210/24/87 J.K.
; p2167 Does'nt say EGA in medium resol. cannot do 43 lines 10/30/87 J.K.
; p2236 After esc [=0h, issuing INT10h,AH=fh returns mode=1. 11/3/87 J.K.
; p2305 With ANSI loaded, loading RDTE hangs the system 11/06/87 J.K.
; P2617 Order dependecy problem with Display.sys 11/23/87 J.K.
; p2716 HOT key of VITTORIA does not work properly 12/03/87 J.K.
; d398 /L option for Enforcing the number of lines 12/17/87 J.K.
; D425 For OS2 compatibiltiy box, /L option status query 01/14/88 J.K.
; P5699 Moving selecting alternate print screen routine to only when it
; 10/26/88 is needed. OEM EGA cards don't support the call it, so they
; K. Sayers couldn't (shift) print screen at all when the alt. routine was
; invoked during initialization.
;******************************************************************************
INCLUDE DEVSYM.INC
INCLUDE ANSI.INC
INCLUDE MULT.INC
PUBLIC GENERIC_IOCTL
PUBLIC SET_IOCTL
PUBLIC GET_IOCTL
PUBLIC SET_SEARCH
PUBLIC GET_SEARCH
PUBLIC SET_CURSOR_EMUL
PUBLIC FUNC_INFO
PUBLIC MAX_SCANS
PUBLIC INT10_COM
PUBLIC SET_MODE_HANDLER
PUBLIC SET_CURSOR_HANDLER
PUBLIC ROM_INT10
PUBLIC INT2F_COM
PUBLIC INT2F_HANDLER
PUBLIC ROM_INT2F
PUBLIC ABORT
PUBLIC MAP_DOWN
PUBLIC SET_VIDEO_MODE
PUBLIC REQ_TXT_LENGTH
PUBLIC GRAPHICS_FLAG
PUBLIC DO_ROWS
PUBLIC Display_Loaded_Before_Me
CODE SEGMENT PUBLIC BYTE
ASSUME CS:CODE,DS:CODE
EXTRN PTRSAV:DWORD
EXTRN NO_OPERATION:NEAR
EXTRN ERR1:NEAR
EXTRN VIDEO_MODE_TABLE:BYTE
EXTRN MAX_VIDEO_TAB_NUM:ABS
EXTRN HDWR_FLAG:WORD
EXTRN SCAN_LINES:BYTE
EXTRN SWITCH_L:Byte ;Defined in ANSI.ASM
IFDEF JAPAN
EXTRN row_adj:byte
ENDIF
SCAN_LINE_TABLE LABEL BYTE
SCAN_LINE_STR <200,000000001B,0> ; 200 scan lines
SCAN_LINE_STR <344,000000010B,1> ; 350 scan lines
SCAN_LINE_STR <400,000000100B,2> ; 400 scan lines
SCANS_AVAILABLE EQU ($ - SCAN_LINE_TABLE)/TYPE SCAN_LINE_STR
;This is used when ANSI calls Get_IOCTL, Set_IOCTL by itself.
In_Generic_IOCTL_flag db 0
I_AM_IN_NOW EQU 00000001b
SET_MODE_BY_DISPLAY EQU 00000010b ;Display.sys calls Set mode INT 10h.
CALLED_BY_INT10COM EQU 00000100b ;To prevent from calling set mode int 10h again.
INT10_V_Mode db 0ffh ;Used by INT10_COM
My_IOCTL_Req_Packet REQ_PCKT <0,0,0Eh,0,?,0,?,?,?,?,?>
FUNC_INFO INFO_BLOCK <> ;data block for functionality call
ROM_INT10 DW ? ;segment and offset of original..
DW ? ;interrupt 10h vector.
ROM_INT2F DW ? ;segment and offset of original..
DW ? ;interrupt 2Fh vector.
INTENSITY_FLAG DW OFF ;intensity flag initially off
REQ_TXT_LENGTH DW DEFAULT_LENGTH ;requested text screen length
SCAN_DESIRED DB 0 ;scan lines desired
MAX_SCANS DB 0 ;maximum scan line setting
GRAPHICS_FLAG DB TEXT_MODE ;flag for graphics mode
Display_Loaded_Before_Me db 0 ;flag
ANSI_SetMode_Call_Flag db 0 ;Ansi is issuing INT10,AH=0.
ALT_PRT_SC_INVOKED DB FALSE ;indicates that have already set up alternat print screen routine
; PROCEDURE_NAME: GENERIC_IOCTL
; FUNCTION:
; TO GET OR SET DEVICE CHARACTERISTICS ACCORDING TO THE BUFFER PASSED
; IN THE REQUEST PACKET.
; AT ENTRY:
; AT EXIT:
; NORMAL: CARRY CLEAR - DEVICE CHARACTERISTICS SET
; ERROR: CARRY SET - ERROR CODE IN AL. (SEE MODULE DESCRIPTION ABOVE).
; NOTE: THIS PROC IS PERFORMED AS A JMP AS WITH THE OLD ANSI CALLS.
GENERIC_IOCTL:
les bx,[PTRSAV] ; establish addressability to request header
mov al,es:[bx].MINORFUNCTION
les di,es:[bx].GENERICIOCTL_PACKET ; point to request packet
cmp al,GET_FUNC ; is this get subfunction?
jnz gi_not_get
call GET_IOCTL ; yes...execute routine
jmp short gi_check_error
gi_not_get:
cmp al,SET_FUNC ; is this the set subfunction?
jnz gi_none
call SET_IOCTL ; yes....execute routine
gi_check_error:
jnc gi_done ; branch if no error
or ax,CMD_ERROR ; yes...set error bit in status
gi_done:
or ax,DONE ; add done bit to status
jmp ERR1 ; return with status in ax
gi_none:
jmp NO_OPERATION ; call lower CON device
; PROCEDURE_NAME: GET_IOCTL
; FUNCTION:
; THIS PROCEDURE RETURNS DEVICE CHARACTERISTICS.
; AT ENTRY: ES:DI POINTS TO REQUEST BUFFER
; AT EXIT:
; NORMAL: CARRY CLEAR - REQUEST BUFFER CONTAINS DEVICE CHARACTERISTICS
; ERROR: CARRY SET - ERROR CONDITION IN AX
GET_IOCTL PROC NEAR
cmp es:[di].INFO_LEVEL,0 ; check for valid info level
jnz gi_invalid
cmp es:[di].DATA_LENGTH,TYPE MODE_TABLE+1 ; and buffer size
jge gi_valid
gi_invalid:
mov ax,INVALID_FUNC ; not valid...unsupported
stc ; function..set error flag and
ret
gi_valid:
mov es:[di].INFO_LEVEL+1,0 ; set reserved byte to 0.
mov ah,REQ_VID_MODE ; request current video mode
int 10H
and al,VIDEO_MASK
lea si,VIDEO_MODE_TABLE ; point to resident video table
call GET_SEARCH ; perform search
jnc gi_supported ; found?
mov ax,NOT_SUPPORTED ; no....load unsupported function
ret ; carry already set
gi_supported:
push di ;Save Request Buffer pointer
mov WORD PTR es:[di].DATA_LENGTH,(TYPE MODE_TABLE)+1 ;length of data is struc size
inc si ; skip mode value
add di,RP_FLAGS ; point to flag word
; VGA,MCGA: VALUE RETURNED FROM FUNCTIONALITY CALL
; EGA: VALUE LAST SET THROUGH IOCTL. DEFAULT IS BLINKING.
; CGA,MONO: BLINKING
cmp al,7 ; M004; Monochrome screen?
mov ax,OFF ; assume CGA,MONO
; (we always have blink).
jz gi_flags_done ; M004;
cmp HDWR_FLAG,MCGA_ACTIVE ; if we have an EGA or better
jl gi_flags_done
test HDWR_FLAG,VGA_ACTIVE ; VGA supported?
jz gi_as_intensity_flag
push es ; yes...prepare for
push di ; functionality call
push ds
pop es
lea di,FUNC_INFO ; point to data block
mov ah,FUNC_CALL ; load function number
xor bx,bx ; implementation type 0
int 10H
mov INTENSITY_FLAG,OFF ; assume no intensity
test es:[di].MISC_INFO,INT_BIT ; is blink bit set?
jnz gi_intensity_is_fine ; if not no intensity
inc INTENSITY_FLAG ; we want intensity
gi_intensity_is_fine:
pop di ; restore registers
pop es
gi_as_intensity_flag:
mov ax,INTENSITY_FLAG ; write the control flag..
gi_flags_done:
stosw ; write the control flag..
; point to next field (display)
mov cx,(TYPE MODE_TABLE)-1 ; load count
rep movsb ; transfer data from video table
; to request packet
sub si,TYPE MODE_TABLE ; point back to start of mode data
ifdef JAPAN
dec di ; point to number of rows
dec di
ENDIF
cmp [si].D_MODE,TEXT_MODE ; if we are in text mode and
jnz gi_row_counted
cmp [si].SCR_ROWS,DEFAULT_LENGTH ; length <> 25 then we have an EGA or VGA
jz gi_row_counted
ifndef JAPAN
dec di ; point back to length entry in req packet
dec di
ENDIF
push ds
mov ax,ROM_BIOS ; load ROM BIOS data area segment
mov ds,ax
mov al,BYTE PTR ds:[NUM_ROWS] ; load current number of rows
cbw
inc ax ; add 1 to row count
mov WORD PTR es:[di],ax ; and copy to request packet
pop ds
gi_row_counted:
ifdef JAPAN
mov al,row_adj
xor ah,ah
sub es:[di],ax ; support ESC[>1l
ENDIF
xor ax,ax ; no errors
clc ; clear error flag
pop di ; Restore Request Buffer pointer
ret ; return to calling module
GET_IOCTL ENDP
; PROCEDURE_NAME: SET_IOCTL
; FUNCTION:
; THIS PROCEDURE SETS THE VIDEO MODE AND CHARACTER SET ACCORDING
; TO THE CHARACTERSTICS PROVIDED.
; AT ENTRY:
; ES:[DI] POINTS TO REQUEST BUFFER
; AT EXIT:
; NORMAL: CLEAR CARRY - VIDEO MODE SET
; ERROR: CARRY SET - ERROR CONDITION IN AX
SET_IOCTL PROC NEAR
or In_Generic_IOCTL_Flag, I_AM_IN_NOW ; Signal GENERIC_IOCTL request being processed
push REQ_TXT_LENGTH ; save old value in case of error
cmp es:[di].INFO_LEVEL,0 ; check for valid info level
jnz si_invalid
cmp es:[di].DATA_LENGTH,TYPE MODE_TABLE+1 ; ane buffer size
jnz si_invalid
mov ax,es:[di].RP_FLAGS ; test for invalid flags
test ax,INVALID_FLAGS
jnz si_invalid
test es:[di].RP_FLAGS,ON ; if intensity is requested and..
jz si_valid
cmp HDWR_FLAG,MCGA_ACTIVE ; hardware does not support it
jge si_valid
si_invalid:
mov ax,INVALID_FUNC ; not valid...unsupported..
jmp si_failed
si_valid:
call SET_SEARCH ; search table for match
jnc si_mode_valid
si_not_supp:
jmp si_not_supported
si_mode_valid:
cmp [si].D_MODE,TEXT_MODE ; is a text mode being requested?
jz si_do_text_mode
call SET_VIDEO_MODE
jmp si_end_ok
si_do_text_mode:
mov ax,es:[di].RP_ROWS ; save new requested value.
mov REQ_TXT_LENGTH,ax
cmp ax,DEFAULT_LENGTH ; is it just 25 lines needed?
jz si_display_ok
mov ax,DISPLAY_CHECK
int 2FH
cmp al,INSTALLED ; or is DISPLAY.SYS not there?
jnz si_display_ok
mov ax,CHECK_FOR_FONT
int 2FH ; or if it is does it have the..
jnc si_display_ok
mov ax,NOT_AVAILABLE ; DISPLAY.SYS does not have the font
jmp si_failed
si_display_ok:
cmp [si].SCR_ROWS,UNOCCUPIED
jz si_is_vga
test HDWR_FLAG,VGA_ACTIVE
jz si_non_vga
si_is_vga:
mov ax,1A00h ;Get currently active adap.;C04
int 10h ;VGA interrupt ;C04
mov ax,REQ_TXT_LENGTH ; restore AX
cmp bl,7 ;Q: non_vga adapter? ;C04
jb si_non_vga ;Yes so do other stuff ;C04
process_vga:
mov cl,3 ; ax loaded with length requested
shl ax,cl ; mulitply by 8 to get scan lines
lea bx,SCAN_LINE_TABLE ; load bx with scan line table start
mov cx,SCANS_AVAILABLE ; total number of scan lines settings
pv_while:
cmp ax,[bx].NUM_LINES ; pointing at the right setting?
jz pv_found
add bx,TYPE SCAN_LINE_STR ; not this setting..point to next
loop pv_while
jmp short si_not_supp
pv_found:
mov dl,[bx].REP_1BH
test SCAN_LINES,dl ; does the hardware have it?
jz si_not_supp
mov cl,[bx].REP_12H ; yes, store value to set it
mov SCAN_DESIRED,cl
cmp REQ_TXT_LENGTH,DEFAULT_LENGTH ; 25 lines requested?
jnz pv_scan_ok
mov al,MAX_SCANS ; desired scan setting should be..
mov SCAN_DESIRED,AL ; the maximum.
pv_scan_ok:
; following added to overcome problems with rolling
; screens in QBX and WZMAIL. Problem still exists when switching between
; mono and VGA screens when ANSI is loaded with /L.
test In_Generic_IOCTL_Flag,CALLED_BY_INT10COM
jnz si_set_mode_done
mov ah,ALT_SELECT ; set the appropriate number..
mov bl,SELECT_SCAN ; of scan lines..
mov al,SCAN_DESIRED
int 10H
jmp short si_processed
si_non_vga:
mov ax,REQ_TXT_LENGTH
cmp ax,DEFAULT_LENGTH ; see if length requested..
jz si_cursor_emul ; is valid
cmp ax,[si].SCR_ROWS
jnz si_not_supported
si_cursor_emul:
call SET_CURSOR_EMUL
si_processed:
call SET_VIDEO_MODE
si_set_mode_done:
call DO_ROWS
cmp ALT_PRT_SC_INVOKED,FALSE ; If not set up already
jnz si_printscreen_ok
cmp es:[di].RP_ROWS,DEFAULT_LENGTH ; and needed because lines (or 30?)
jle si_printscreen_ok
cmp HDWR_FLAG,MCGA_ACTIVE ; and if we have EGA or better then.. (supported)
jl si_printscreen_ok
mov ah,ALT_SELECT ; issue select alternate print..
mov BL,ALT_PRT_SC ; screen routine call..
int 10H
mov ALT_PRT_SC_INVOKED,TRUE ; mark that it was done
si_printscreen_ok:
call SET_CURSOR_EMUL ; yes..ensure cursor emulation
; is set accordingly.
cmp HDWR_FLAG,MCGA_ACTIVE ; for the EGA and better...
jl si_end_ok
cmp [si].V_MODE,7 ; M004; and not monochrome
jz si_end_ok
xor bx,bx ; bx: 1=intensity on, 0: off
; assume off
test es:[di].RP_FLAGS,ON
jz si_intensity_ok
inc bx ; user wants intensity
si_intensity_ok:
mov INTENSITY_FLAG,bx
mov ax,BLINK_TOGGLE
xor bl,ON ; bl is opposite
; of INTENSITY_FLAG
int 10H
si_end_ok:
and In_Generic_IOCTL_Flag, NOT I_AM_IN_NOW ; Turn the flag off
pop ax ; forget old REQ_TXT_LENGTH
xor ax,ax ; clear error register
clc ; clear error flag
ret
si_not_supported:
mov ax,NOT_SUPPORTED
si_failed:
and In_Generic_IOCTL_Flag, NOT I_AM_IN_NOW ; Turn the flag off
pop REQ_TXT_LENGTH ; error...so restore old value.
stc ; set error flag
ret
SET_IOCTL ENDP
; Procedure name: DO_ROWS
; Function:
; Only called for TEXT_MODE.
; If (REQ_TXT_LENGTH <> DEFAULT_LENGTH) &
; (DISPLAY.SYS not loaded or CODEPAGE not active)
; then
; LOAD ROM 8X8 charater.
DO_ROWS PROC NEAR
cmp req_txt_length, DEFAULT_LENGTH
je dr_exit
mov ax,LOAD_8X8 ; load 8x8 ROM font
xor bl,bl
int 10H ; M003;
mov ax,SET_BLOCK_0 ; activate block = 0
xor bl,bl
int 10H ; M003;
dr_exit:
ret
DO_ROWS ENDP
; PROCEDURE_NAME: SET_SEARCH
; FUNCTION:
; THIS PROCEDURE SEARCHES THE RESIDENT VIDEO TABLE IN ATTEMPT TO
; FIND A MODE THAT MATCHES THE CHARACTERISTICS REQUESTED.
; AT ENTRY:
; AT EXIT:
; NORMAL: CARRY CLEAR - SI POINTS TO APPLICABLE RECORD
; ERROR: CARRY SET
; When INT10_V_Mode <> 0FFH, then assumes that the user
; issuing INT10h, Set mode function call. Unlike Generic IOCTL
; set mode call, the user already has taken care of the video mode.
; So, we also find the matching V_MODE.
; WARNING: TRASH CX
SET_SEARCH PROC NEAR
lea si,VIDEO_MODE_TABLE ; point to video table
mov cx,MAX_VIDEO_TAB_NUM ; load counter, # of tables
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?