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