ioctl.asm
来自「Dos6.0」· 汇编 代码 · 共 1,204 行 · 第 1/2 页
ASM
1,204 行
ss_while:
cmp [si].V_MODE,UNOCCUPIED ; while we have valid entries
jz ss_not_found
mov al,INT10_V_Mode
cmp al,0ffh ; if not issued by Int10 set mode,
jnz ss_from_set_mode
mov al,es:[di].RP_MODE ; load register for compare.
cmp [si].D_MODE,al ; match?
jnz ss_end_while
mov ax,es:[di].RP_COLORS ; yes...prepare next field
cmp [si].COLORS,ax ; match?
jnz ss_end_while
cmp es:[di].RESERVED2,0 ; yes, ensure reserved byte is zero
jnz ss_end_while
cmp es:[di].RP_MODE,GRAPHICS_MODE ; for graphics mode
jnz ss_not_graphic ; check the following:
mov ax,es:[di].RP_WIDTH ; screen width.
cmp [si].SCR_WIDTH,ax
jnz ss_end_while
mov ax,es:[di].RP_LENGTH ; screen length
cmp [si].SCR_LENGTH,ax
jnz ss_end_while ; ignore #rows and #coloumns
jmp short ss_found
ss_not_graphic:
mov ax,es:[di].RP_COLS ; the rows are matched
cmp [si].SCR_COLS,ax ; in the main routine
jnz ss_end_while
ss_found:
clc
jmp short ss_done
ss_from_set_mode:
cmp [si].V_MODE,al ; if V_MODE = AL, we are ok
jz ss_found
ss_end_while:
add si,type MODE_TABLE ; then, this is not the correct entry.
loop ss_while ; Let's find the next entry.
ss_not_found:
stc
ss_done:
mov INT10_V_Mode, 0FFh ; Done. Reset the value
ret
SET_SEARCH ENDP
; PROCEDURE_NAME: GET_SEARCH
; FUNCTION:
; THIS PROCEDURE SEARCHES THE VIDEO TABLE LOOKING FOR A MATCHING
; VIDEO MODE.
; AT ENTRY: DS:SI POINTS TO VIDEO TABLE
; AL CONTAINS THE MODE REQUESTED
; AT EXIT:
; NORMAL: CARRY CLEAR, DS:SI POINTS TO MATCHING RECORD
; ERROR: CARRY SET
; WARNING: TRASH CX
GET_SEARCH PROC NEAR
mov cx,MAX_VIDEO_TAB_NUM ; # of total tables
gs_while:
cmp [si].V_MODE,UNOCCUPIED ; while we're not pointing to
jz gs_error
cmp [si].V_MODE,al ; the right mode and we are still
jz gs_got_it
add si,TYPE MODE_TABLE ; point to the next mode
loop gs_while
gs_error:
stc ; no, set error flag
ret
gs_got_it:
clc
ret
GET_SEARCH ENDP
; PROCEDURE_NAME: SET_CURSOR_EMUL
; FUNCTION:
; THIS PROCEDURE SETS THE CURSOR EMULATION BIT OFF IN ROM BIOS. THIS
; IS TO PROVIDE A CURSOR ON THE EGA WITH THE 5154 LOADED WITH AN 8X8
; CHARACTER SET.
; AT ENTRY:
; AT EXIT:
; NORMAL: CURSOR EMULATION BIT SET FOR APPLICABLE HARDWARE
; ERROR: N/A
SET_CURSOR_EMUL PROC NEAR
test HDWR_FLAG,E5154_ACTIVE ; EGA with 5154?
jz sce_done
push si
push ds ; yes..so..
mov ax,ROM_BIOS ; check cursor emulation..
mov ds,ax
mov si,CURSOR_FLAG
mov al,BYTE PTR [si]
cmp cs:REQ_TXT_LENGTH,DEFAULT_LENGTH; >25 lines req?
jnz sce_cursor_on
and al,TURN_OFF ; no....set it OFF
jmp short sce_cursor_ok
sce_cursor_on:
or al,TURN_ON ; yes...set it ON
sce_cursor_ok:
mov BYTE PTR [si],AL
pop ds
pop si
sce_done:
ret ; return to calling module
SET_CURSOR_EMUL ENDP
; PROCEDURE_NAME: INT10_COM
; FUNCTION:
; THIS IS THE INTERRUPT 10H HANDLER TO CAPTURE THE FOLLOWING FUNCTIONS:
; AH=1H (SET CURSOR TYPE). CURSOR EMULATION IS PERFORMED IF WE HAVE
; AND EGA WITH A 5151 MONITOR, AND 43 LINES IS REQUESTED.
;M002; What is bellow was modified. The /L option was removed. But ansi
;M002; will still do a GET_IOCTL/SET_IOCTL for the application.
; AH=0H (SET MODE) SCREEN LENGTH IS MAINTAINED WHEN POSSIBLE. (IE. IN
; TEXT MODES ONLY.)
; AN004; Capturing Set Mode call and enforcing the # of Rows based on the
; previous Set_IOCTL request lines was a design mistake. ANSI cannot
; covers the all the application program out there which use INT 10h
; directly to make a full screen interface by their own way.
; This part of logic has been taken out by the management decision.
; Instead, for each set mdoe INT 10h function call, if it were not
; issued by SET_IOCTL procedures itself, or by DISPLAY.SYS program,
; then we assume that it was issued by an APPS, that usually does not
; know the new ANSI GET_IOCTL/SET_IOCTL interfaces.
; In this case, ANSI is going to call GET_IOCTL and SET_IOCTL function
; call - This is not to lose the local data consistency in ANSI.
; AT ENTRY:
; AT EXIT:
; NORMAL:
; ERROR:
INT10_COM PROC NEAR
sti ; restore interrupts
cmp ah,SET_CURSOR_CALL
jz SET_CURSOR_HANDLER
cmp ah,SET_MODE
jz SET_MODE_HANDLER
jmp DWORD PTR cs:ROM_INT10 ; no...pass it on.
SET_CURSOR_HANDLER:
push ax
test cs:HDWR_FLAG,E5151_ACTIVE ; do we have an EGA?
jz sch_goto_rom
cmp cs:REQ_TXT_LENGTH,DEFAULT_LENGTH
jz sch_goto_rom
cmp cs:GRAPHICS_FLAG,TEXT_MODE ; with 5151..so perform cursor mapping
jnz sch_goto_rom
cmp cl,8
jl sch_goto_rom
mov al,ch ; check for cursor..
and al,60h ; off emulation. J.K.
cmp al,20h
jz sch_goto_rom
mov al,ch ; start position for cursor
call MAP_DOWN
mov ch,al
mov al,cl ; end position for cursor
call MAP_DOWN
mov cl,al
sch_goto_rom:
pop ax
jmp DWORD PTR CS:ROM_INT10 ; continue interrupt processing
SET_MODE_HANDLER:
pushf ; prepare for IRET
mov cs:ANSI_SetMode_Call_Flag, 1 ; Used by INT2F_COM
call DWORD PTR CS:ROM_INT10 ; call INT10 routine
mov cs:ANSI_SetMode_Call_Flag, 0 ; Reset it
push bp
push es
push ds
push si
push di
push dx
push cx
push bx
push ax
push cs
pop ds
mov ah,REQ_VID_MODE ; get current mode..
pushf
call DWORD PTR ROM_INT10
and al,VIDEO_MASK ; mask bit 7 (refresh)
test In_Generic_IOCTL_Flag, (I_AM_IN_NOW + SET_MODE_BY_DISPLAY) ; Flag is on?
;If not (I_AM_IN_NOW or SET_MODE_BY_DISPLAY),
jnz smh_ioctl_done
; cmp SWITCH_L,0 ;M002; No more /L
; jnz smh_ioctl_done ;M002; No more /L
push ax ;Save mode
push es
push cs
pop es
mov di,offset My_IOCTL_Req_Packet
mov INT10_V_Mode,al ;Save current mode for SET_SEARCH
call Get_IOCTL
jc smh_set_ioctl_done
or In_Generic_IOCTL_Flag, CALLED_BY_INT10COM ;Do not set mode INT 10h again. Already done.
call Set_IOCTL
and In_Generic_IOCTL_Flag, not CALLED_BY_INT10COM
smh_set_ioctl_done:
pop es
pop ax ;Restore mode
mov INT10_V_Mode,0FFh
smh_ioctl_done:
lea si,VIDEO_MODE_TABLE
call GET_SEARCH ; look through table for mode selected.
jc smh_graphic_mode ; M001; if not found then
; M001; assume graphic mode
cmp [si].D_MODE,TEXT_MODE ; text mode?
jz smh_text_mode
smh_graphic_mode:
mov GRAPHICS_FLAG,GRAPHICS_MODE ; no, set graphics flag
jmp short smh_flag_done
smh_text_mode:
mov GRAPHICS_FLAG,TEXT_MODE ; set TEXT MODE
smh_flag_done:
; test In_Generic_IOCTL_Flag, I_AM_IN_NOW
; jnz smh_l_done ; M002; No more /L
; cmp Graphics_Flag,TEXT_MODE ; M002; No more /L
; jnz smh_l_done ; M002; No more /L
; cmp SWITCH_L,1 ; M002; No more /L
; jnz smh_l_done ; M002; No more /L
; call DO_ROWS ; M002; No more /L
smh_l_done:
;For each SET mode function int 10h function call, if it is not
;issued by ANSI GET_IOCTL and SET_IOCTL procedure themselves, we assume
;that the APPS, which usually does not know the ANSI GET_IOCTL/SET_IOCTL
;interfaces, intend to change the screen mode. In this case, ANSI is
;kind enough to call GET_IOCTL and SET_IOCTL function call for themselves.
pop ax
pop bx
pop cx
pop dx
pop di
pop si
pop ds
pop es
pop bp
iret
INT10_COM ENDP
; PROCEDURE_NAME: INT2F_COM
; FUNCTION:
; THIS IS THE INTERRUPT 2FH HANDLER TO CAPTURE THE FOLLOWING FUNCTIONS:
; ax=1A00H INSTALL REQUEST. ANSI WILL RETURN AL=FFH IF LOADED.
; AH=1A01H THIS IS THE INT2FH INTERFACE TO THE GENERIC IOCTL.
; NOTE: THE GET CHARACTERISTICS FUNCTION CALL WILL RETURN
; THE REQ_TXT_LENGTH IN THE BUFFER AS OPPOSED TO
; THE ACTUAL HARDWARE SCREEN_LENGTH
; Ax=1A02h This is an information passing from DISPLAY.SYS about
; the INT 10h, SET MODE call.
; AT ENTRY:
; AT EXIT:
; NORMAL:
; ERROR:
INT2F_COM PROC NEAR
sti
cmp ah,multANSI ; is this for ANSI?
jnz ic_goto_rom
cmp al,DA_INFO_2F
jle INT2F_HANDLER
ic_goto_rom:
jmp DWORD PTR CS:ROM_INT2F ; no....jump to old INT2F
INT2F_HANDLER:
cmp al,INSTALL_CHECK
jnz ih_not_check
; do install check
mov al,INSTALLED ; load value to indicate installed
clc ; clear error flag.
jmp ih_iret
ih_not_check:
cmp al,DA_INFO_2F ; IOCTL or INFO passing?
jbe ih_valid
jmp ih_iret
ih_valid:
push bp
push ax ; s
push cx ; a
push dx ; v
push ds ; e r
push es ; e
push di ; g
push si ; s.
push bx
push ds ; load ES with DS (for call)
pop es
mov di,dx ; load DI with dx (for call)
push cs ; setup local addressability
pop ds
cmp al,IOCTL_2F ; IOCTL request
jnz ih_not_ioctl
cmp cl,GET_FUNC ; get function requested.
jnz ih_not_get
call GET_IOCTL
jc ih_set_flags ; if no error and
cmp HDWR_FLAG,E5151_ACTIVE ; >25 lines supported
jl ih_set_flags
cmp [si].D_MODE,TEXT_MODE ; this is a text mode then..
jnz ih_set_flags
; cmp SWITCH_L,1 ; M002; No more /L
; jz ih_use_rtl ; M002; No more /L
cmp ANSI_SetMode_Call_Flag,1
jnz ih_use_rtl ; if not originated by ANSI thru AH=0, Int10
cmp Display_Loaded_Before_me,1 ; or Display.sys not loaded before ANSI,
jz ih_get_ok
ih_use_rtl:
mov bx,REQ_TXT_LENGTH ; then use REQ_TXT_LENGTH instead..
mov es:[di].RP_ROWS,bx
ih_get_ok:
clc
jmp short ih_set_flags
ih_not_get:
cmp cl,SET_FUNC
jnz ih_invalid
call SET_IOCTL ; set function requested.
jmp short ih_set_flags
; invalid function
ih_invalid:
mov ax,INVALID_FUNC ; load error and...
stc ; set error flag.
jmp short ih_set_flags ; Info. passing
ih_not_ioctl:
cmp es:[di].DA_INFO_LEVEL,0 ; 0 - DA_SETMODE_FLAG request
jnz ih_not_info
cmp es:[di].DA_SETMODE_FLAG,1
jnz ih_not_set
or In_Generic_IOCTL_Flag, SET_MODE_BY_DISPLAY ;Turn the flag on
jmp short ih_info_ok
ih_not_set:
and In_Generic_IOCTL_Flag, not SET_MODE_BY_DISPLAY ;Turn the flag off
jmp short ih_info_ok
ih_not_info:
cmp es:[di].DA_INFO_LEVEL,1 ; 1 = DA_L_STATA query
jnz ih_info_ok
; mov al,cs:[SWITCH_L] ; M002; No more /L
mov al,OFF ; M002; No more /L
mov es:[di].DA_L_STATE, al
ih_info_ok:
clc ; clear carry. There is no Error in DOS 4.00 for this call.
ih_set_flags:
pop bx ; restore all..
pop si
pop di ; registers except..
pop es
pop ds ; BP.
pop dx
pop cx
push ax ; save error condition
mov bp,sp ; setup frame pointer
mov ax,[bp+10] ; load stack flags
jc ih_error ; carry set???
and ax,NOT_CY ; no.. set carry off.
mov [bp+10],ax ; put back on stack.
pop ax ; remove error flag from stack
pop ax ; no error so bring back function call
XCHG ah,al ; exchange to show that ANSI present
jmp short ih_pop_bp
ih_error:
or ax,CY ; yes...set carry on.
mov [bp+10],ax ; put back on stack.
pop ax ; restore error flag
pop bp ; pop off saved value of ax (destroyed)
ih_pop_bp:
pop bp ; restore final register.
ih_iret:
ABORT: iret
INT2F_COM ENDP
; PROCEDURE_NAME: MAP_DOWN
; FUNCTION:
; THIS PROCEDURE MAPS THE CURSOR START (END) POSITION FROM A 14 PEL
; BOX SIZE TO AN 8 PEL BOX SIZE.
; AT ENTRY: AL HAS THE CURSOR START (END) TO BE MAPPED.
; AT EXIT:
; NORMAL: AL CONTAINS THE MAPPED POSITION FOR CURSOR START (END)
; ERROR: N/A
MAP_DOWN PROC NEAR
push bx
xor ah,ah ; clear upper byte of cursor position
mov bl,EIGHT ; multiply by current box size.
push dx ; al x
mul bl ; ---- = ---
pop dx ; 14 8
mov bl,FOURTEEN
div bl ; divide by box size expected.
pop bx
ret
MAP_DOWN ENDP
; PROCEDURE_NAME: SET_VIDEO_MODE
; FUNCTION:
; THIS PROCEDURE SETS THE VIDEO MODE SPECIFIED IN DS:[SI].V_MODE.
; AT ENTRY: DS:SI.V_MODE CONTAINS MODE NUMBER
; AT EXIT:
; NORMAL: MODE SET
; ERROR: N/A
SET_VIDEO_MODE PROC NEAR
test In_Generic_IOCTL_Flag,CALLED_BY_INT10COM
jnz svm_done
mov al,[si].V_MODE ; ..issue set mode
test HDWR_FLAG,LCD_ACTIVE
jnz svm_update_bios ; is this the LCD?
test HDWR_FLAG,VGA_ACTIVE ; or VGA? (done for BRECON card)
jz svm_update_done
svm_update_bios:
push ds ; yes...
mov bl,al ; save mode
mov ax,ROM_BIOS
mov ds,ax ; get equipment status flag..
mov ax,ds:[EQUIP_FLAG]
and ax,INIT_VID_MASK ; clear initial video bits..
cmp bl,MODE7 ; are we setting mono?
jz svm_mono
cmp bl,MODE15
jnz svm_color
svm_mono:
or ax,LCD_MONO_MODE ; yes...set bits as mono
jmp short svm_update_it
svm_color:
or ax,LCD_COLOR_MODE ; no...set bits as color
svm_update_it:
mov ds:[EQUIP_FLAG],ax ; replace updated flag.
mov al,bl ; restore mode.
pop ds
svm_update_done:
mov ah,SET_MODE ; set mode
int 10H
svm_done:
ret
SET_VIDEO_MODE ENDP
CODE ENDS
END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?