2025-04-27 07:49:33 -04:00

1226 lines
29 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
ifdef JAPAN
push word ptr row_adj
endif
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.
ifdef JAPAN
mov row_adj,0
cmp ax,DEFAULT_LENGTH-1
jnz @f
mov row_adj,1
inc ax
@@:
endif
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
ifdef JAPAN
pop ax ; throw old row_adj
endif
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
ifdef JAPAN
pop word ptr row_adj
endif
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
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..
ifdef JAPAN
sub bl,row_adj
endif
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