page 70, 132 ;---------------------------------------------------------------------- ; Module Name :VESA452.asm ; Program Name :VESA452.com ; Description :This program traps Video BIOS Fuction calls made from an ; Application program. It is a TSR(Terminate & Stay Resident) ; program. ; Date :February 26, 1990 ; Version :1.0 ; Programmer :Rakesh K. Jain ; Copyright (C) Chips and Technologies, Inc. 1990 ;---------------------------------------------------------------------- include vesa.inc ; to include VESA structures & constants include vesa452.inc ; 452 related stuff ; ; Code Segment Starts ; code segment assume cs:code, ds:code, ss:code, es:code org 100h ;for making the program .COM type begin : jmp main ; jump to the initialization part ;------------------------------------------------------------------ ; This routine stores BIOS Video Function Number into a Buffer ; and then calls BIOS fuction. ;------------------------------------------------------------------ VideoHandler proc near ; look for functions to be implemented here cmp ah, VESA_FUNCTIONS jnz VHNotVGACntlFun ; Its a VESA function call VESAFunctions iret VHNotVGACntlFun: pushf ;Push Flags to compensate for IRET callfar oldvect dw 0 dw 0 ;Old Video Interrupt Vector iret VideoHandler endp VESAFunctions proc near cmp al, MAX_FUNCTIONS ja VESAFNotAValidFunction cmp al,5 ; Window Control function jnz @F push cs call near ptr SuperVGASetCPUMemWin ; This is far call ret @@: pushem ; dont change ax, bx order xor ah, ah shl ax, 1 ; ax = function index xchg ax, bx mov bx, cs:DispatchTable[bx] ; function ptr in bx xchg ax, bx call ax DirectReturn: popem ; dont change ax, bx order mov ax, cs:Status ret VESAFNotAValidFunction: cmp al, 70h jne @f call SetChipsWindowSize mov ax, 704fh ret @@: cmp al, 71h jne @f call GetChipsWindowSize mov ax, 714fh ret @@: xor al, al ; function not supported ret VESAFunctions endp SuperVGAInfo proc near ; ; copy our info structure ; cld ; play it safe, don't assume things mov ax, cs mov ds, ax ; Set our data segment mov si, OFFSET VGAInfo mov cx, (SIZE VGAInfoBlock) / 2 rep movsw IF (SIZE VGAInfoBlock) AND 1 movsb ENDIF if 0 ;** we assume that 82C452 presence is already been checked, when we installed this TSR ; ; Look for 82C452 (CHIPS Super VGA) ; call ReadChipsVGAId ; Id is returned in ah ; ; if VGA is identified as Chips product then look for specific VGA ; look for Chips Id ; cmp ah, CHIPS_ID ; is it chips Id? jnz VGACError00 ; non Chips VGA/EGA ; ; VGA is identified as Chips VGA ; mov ah, 80H ; open extended registers at 3d6/3d7H call ExtRegs call ReadVGATypeNRev mov bl, ah ; place this info to proper reg and ah, 0F0H ; test VGA type cmp ah, CHIPSVGA_452 jnz VGACFNot452 ; ; 82C452 is found, return success ; endif ;**0 mov Status, SUCCESS SHL 8 + VESA_FUNCTIONS ret if 0 ;** Presence of 82c452 is alraedy been checked VGACError00: VGACFNot452: mov Status, FAILURE SHL 8 + VESA_FUNCTIONS ret endif ;** 0 SuperVGAInfo endp SuperVGAModeInfo proc near cld ; play it safe mov ax, cs mov ds, ax ; Set our data segment mov si, OFFSET ModeInfo mov ax, cx ; VESA Mode No ****** to be changed to bx mov dx, di ; save di in dx mov bx, es ; save es in bx call VESAToInternalMode call InternalModeToIndex mov ax, di ; al = Mode Index mov ah, SIZE ModeInfoBlock mul ah ; ax = +(SIZE ModeInfoBlock)*Index add si, ax ; si = ModeInfo+(SIZE ModeInfoBlock)*Index mov di, dx ; restore di mov es, bx ; restore es mov cx, OBLG_INFO_SIZE test [si].ModeAttributes, MA_EXT_INFO jz @F add cx, EXT_INFO_SIZE @@: push di ; save start address rep movsb pop di ; restore start adress mov ax, word ptr ChipsNoOfWindows ; al = # of Windows, ah = Window Size cmp al, 1 ; Is there only 1 windows supported jz @F ; By default we enable only one window mov es:[di].WinBAttributes,WIN_ATTR ; Enable second window also cmp ah, 64 ; Is it Dual page 64K ? jz @F ; Yes, we are all set mov es:[di].WinBSegment, WINB_NADDR ; change selector to dual page 32K windows @@: mov byte ptr es:[di].WinSize, ah ; copy size of the window mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS ret SuperVGAModeInfo endp SuperVGASetMode proc near mov ax, bx ; ax = VESA Mode call VESAToInternalMode ; ax = Internal Mode (BIOS Mode) mov bx, ax ; save internal mode and ah, ah ; see if ah = 0 jnz SVSMError int 10H ; call BIOS to set mode ; did BIOS set the mode ? mov ax, 40h mov ds, ax mov di, 49h and bl, NOT 80H ; Clear Not-clear-memory bit cmp [di], bl jnz SVSMError ; ; find out what value is to be programmed in the GR06 and XR0B to select ; proper CPU address window. We have table of these value so we have ; to compute index to the table first. There are 4 entries in the table. ; NumberOfWin SizeofWin XR0B GR06 (Low) ; 1 64 K 0 4 ; 1 128K 0 0 ; 2 32 K 2 4 ; 2 64 K 2 0 ; We assume that # of windows and windows size will always have these values ; cmp bl, 6ah ; For all standard modes and 132 column modes jb StandardModes ; don't bother about paging etc mov bx, word ptr cs:ChipsNoOfWindows ; bl = # of Windows, bh = Window Size mov cl, 6 ; # of bits to be shifted shr bl, 1 ; 'C' if bl = 1, bl = 0/1 adc cl, 0 ; cl = 6/5 shr bh, cl ; bl = 0/1 shl bl, 1 add bl, bh xor bh, bh ; bx = index into the table shl bx, 1 ; each entry is one word mov dx, 3ceh ; dx = Graphics Controller addr mov al, 6 out dx, al inc dx in al, dx and al, 11110011b ; clear memory size bits or al, cs:WinRegTable[bx] ; GR06 value out dx, al mov ah, 80h ; Open extended registers call ExtRegs mov dx, EGA_BASE + EXTR_ADDR mov al, 0bh out dx, al inc dx in al, dx ; read current value and al, 11111101b ; clear dual page bit or al, cs:WinRegTable[bx+1] ; XR0B value out dx, al StandardModes: mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS ret SVSMError: mov cs:Status, FAILURE SHL 8 + VESA_FUNCTIONS ret SuperVGASetMode endp SuperVGAGetMode proc near mov ax, 0F00H int 10H xor ah, ah mov bx, ax ; save this info in bx call InternalModeToVesa jnc @F xchg ax, bx @@: pop dx ; get return addr pop ax ; pop bx in ax ******* push bx ; push mode to be returned push dx ; mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS ret SuperVGAGetMode endp SuperVGAVideoState proc near mov ah, 1cH ; ah = BIOS function to save/restore VIDEO state mov al, dl ; al = subfunction push ax ; save function push cx test cx, VS_SUPERVGA_STATE jz SVVSNotSuperVGA0 ; ; Super VGA state ; cmp al, VS_GET_BUFSIZE jnz SVVSNotBufSize ; ; get buf size function ; cmp cx, VS_SUPERVGA_STATE ; if it is SUPERVGA_STATE only jnz @F ; save cx, ax and call BIOS ; only SUPERVGA_STATE mov bx, SUPERVGA_SIZE pop cx pop ax ; restore sunfunction jmp SVVSNotSuperVGA1 ; don't call BIOS SVVSNotBufSize: cmp al, VS_SAVE_STATE jnz SVVSNotSaveState ; ; save state function ; es:bx --> pointer to buffer, bx will be updated by routine ; call SaveSuperVGAState jmp short @F SVVSNotSaveState: cmp al, VS_RESTORE_STATE jnz SVVSNotRestoreState ; ; restore state function ; es:bx --> pointer to buffer, bx will be updated by routine ; call RestoreSuperVGAState SVVSNotRestoreState: SVVSNotSuperVGA0: @@: int 10H pop cx ; restore requested state pop ax ; restore subfunction function test cx, VS_SUPERVGA_STATE jz SVVSNotSuperVGA1 ; super vga function cmp al, VS_GET_BUFSIZE ; is it GET_BUFSIZE function ? jnz @F ; no add bx, SUPERVGA_SIZE ; add # of full block SVVSNotSuperVGA1: pop dx ; pop return address pop ax ; pop bx in ax ******* push bx ; put bx on stack push dx ; push new address @@: mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS ret SuperVGAVideoState endp SuperVGASetCPUMemWin proc far cmp bh,01 je SuperVGAMapVideoMem push dx ; save page mov ah, 80h call ExtRegs pop dx ; restore page mov ah, dl ; ah = page # mov al, PAGE_REG_A and bl, 01 ; consider only LSB add al, bl ;** push dx ; Save dx mov dx, EGA_BASE+EXTR_ADDR out dx, ax mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS ;** pop dx ; Restore dx ret SuperVGASetCPUMemWin endp SuperVGAMapVideoMem proc near mov ah, 80h call ExtRegs mov al, PAGE_REG_A and bl, 01 ; consider only LSB add al, bl mov dx, EGA_BASE+EXTR_ADDR out dx,al inc dx in al,dx xor ah,ah mov dx,ax mov cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS ret SuperVGAMapVideoMem endp SuperVGADACCntl proc near ret SuperVGADACCntl endp ;---------------------------------------------------------------------- ; This routine saves extended registers into a buffer. ; 2 bytes per register are saved. High byte contains reg value and low ; byte reg index. ; ; Entry: ; es:bx --> pointer to buffer (2 bytes per extended reg) ; Destroyed: ; ds, si, di, dx & flags ; Preseeved: ; ax, cx, and bx updated, to be used by BIOS later ;----------------------------------------------------------------------- SaveSuperVGAState proc near push cx push ax ; save important regs mov ah, 80H call ExtRegs ; Open extended registers mov ax, cs mov ds, ax ; ds = cs (our data seg) mov si, OFFSET ExtRegIndex ; pointer to ext reg indices table mov di, bx ; buffer pointer mov dx, EGA_BASE+EXTR_ADDR mov cx, NEXTREGS ; # of ext regs to be saved SAVSLoop: lodsb ; load ext reg index in al mov ah, al ; ah = al = index out dx, al ; index the port inc dx ; dx = data port (3d7) in al, dx ; read value dec dx ; dx = address port xchg al, ah ; ah = value, al = index stosw ; store it loop SAVSLoop ; do till all regs are over add bx, 2*NEXTREGS ; increment pointer for BIOS fuction pop ax pop cx ; restore important regs ret SaveSuperVGAState endp ;---------------------------------------------------------------------- ; This routine restores extended registers from user buffer ; Entry: ; es:bx --> pointer to buffer (2 bytes per extended reg) ; Destroyed: ; ds, si, dx & flags ; Preseeved: ; ax, cx, and bx updated, to be used by BIOS later ;----------------------------------------------------------------------- RestoreSuperVGAState proc near push cx push ax ; save important regs mov ah, 80H call ExtRegs ; Open extended registers mov ax, es mov ds, ax mov si, bx ; ds:si --> pointer to save regs mov dx, EGA_BASE+EXTR_ADDR mov cx, NEXTREGS RSVSLoop: lodsw out dx, ax ; output value to appropriate port loop RSVSLoop add bx, 2*NEXTREGS ; increment pointer for BIOS fuction pop ax ; restore important regs pop cx ret RestoreSuperVGAState endp ;--------------------------------------------------------------------- ; This routine converts user given mode into a 82C452 BIOS mode number ; Entry: ; ax = VESA mode ; Exit: ; if 'C' is clear, ax = internal mode (60H to 7BH) ; else Error... ax not changed ; Destroyed: ; es, cx, di ;---------------------------------------------------------------------- VESAToInternalMode proc near mov di, cs mov es, di mov di, OFFSET VESAModeTable mov cx, NMODES push ax and ah, NOT 80h ; clear memory-not-clear bit repnz scasw ; scan til value matches jnz VESATIMInvalidMode sub di, OFFSET VESAModeTable shr di, 1 ; Offset to byte table mov al, cs:InternalModeTable[di-1] xor ah, ah pop cx ; pop the original mode number and ch,80h ; extract 15th bit or al,ch ; and OR it to mode number clc ; cheer on success ret VESATIMInvalidMode: pop cx ; balance the stack stc ; weep on failuare ret VESAToInternalMode endp ;--------------------------------------------------------------------- ; This routine converts internal mode into a VESA given mode number ; Entry: ; ax = internal mode ; Exit: ; if 'C' is clear, ax = internal mode (60H to 7BH) ; else Error... ; Destroyed: ; es, cx, di ;---------------------------------------------------------------------- InternalModeToVESA proc near mov di, cs mov es, di mov di, OFFSET InternalModeTable mov cx, NMODES repnz scasb ; scan til value matches jnz IMTVESAInvalidMode sub di, OFFSET InternalModeTable shl di, 1 ; Offset to word table mov al, cs:InternalModeTable[di-2] clc ; cheer on success ret IMTVESAInvalidMode: stc ; weep on failuare ret InternalModeToVESA endp ;--------------------------------------------------------------------- ; This routine converts an Internal mode into an index (0 to NMODES-1) ; Entry: ; ax = Internal mode ; Exit: ; if 'C' is clear, di = index of internal mode table (0 to NMODES -1) ; else Error... ; Destroyed: ; es, cx, di ;---------------------------------------------------------------------- InternalModeToIndex proc near mov di, cs mov es, di mov di, OFFSET InternalModeTable mov cx, NMODES repnz scasb ; scan til value matches jnz IMTIInvalidMode sub di, OFFSET InternalModeTable+1 clc ; cheer on success ret IMTIInvalidMode: stc ; weep on failuare ret InternalModeToIndex endp ExtRegs proc near ;--------------------------------------------------------------------- ; Opens extended register space at 3d6/3d7H ; Entry: ; ah = 80/40H to open extended register space at 3d6/3b6H ; ah = 0 to close extended register space ; Destroyed: ; ax, dx ; Output: ; None ;--------------------------------------------------------------------- ; place VGA in setup mode mov dx, cs:SetupAddr mov al, byte ptr cs:SetupData[0] ; value to place vga in setup mode cli ; Disable interrupts out dx, al ; enable/disable extended registers push dx ; save setup address mov dx, 103h mov al, ah ; open extended register at 3d6/3d7H out dx, al pop dx ; restore setup address ; take VGA out of setup mode mov al, byte ptr cs:SetupData[1] ; value to take vga out of setup mode out dx, al sti ; Enable interrupt ret ExtRegs endp ;------------------------------------------------------------------------ SetChipsWindowSize proc near mov word ptr cs:ChipsNoOfWindows, dx ;** .ERRNZ OFFSET ChipsWindowSize - OFFSET ChipsNoOfWindows -1 ret SetChipsWindowSize endp ;------------------------------------------------------------------------ GetChipsWindowSize proc near mov dx, word ptr cs:ChipsNoOfWindows ;** .ERRNZ OFFSET ChipsWindowSize - OFFSET ChipsNoOfWindows -1 ret GetChipsWindowSize endp ;--------------------------------------------------------------------- ; Resident Data Declaration ;--------------------------------------------------------------------- marker db 'VESA for 82C452' marklen EQU $ - marker msg1 db 'VESA Program already installed', NL, EOS DispatchTable dw OFFSET SuperVGAInfo dw OFFSET SuperVGAModeInfo dw OFFSET SuperVGASetMode dw OFFSET SuperVGAGetMode dw OFFSET SuperVGAVideoState dw OFFSET SuperVGASetCPUMemWin dw OFFSET SuperVGAMapVideoMem dw OFFSET SuperVGADACCntl Status dw 0 ; status of every call SetupAddr dw 46e8h ; setup port for PC/AT SetupData dw 0e1eh ; setup data for PC/AT ChipsNoOfWindows db 1 ;** for two undocumented functions ChipsWindowSize db 64 ;** for two undocumented functions .ERRNZ OFFSET ChipsWindowSize - ChipsNoOfWindows -1 ; don't break sequence WinRegTable db 04, 00 ; values for GR06 bit 3,2 and XR0B bit 1 db 00, 00 db 04, 02 db 00, 02 ExtRegIndex LABEL BYTE defextregs <02H,05H,0AH,0BH,0CH,0DH,0EH,10H,11H,20H,21H,22H,23H,24H> defextregs <28H,2BH,30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,3AH> ;;****** db XR04,XR06,XR14,XR15,XR16,XR18,XR19,XR1A,XR1B,XR1C,XR1D,XR1E NEXTREGS equ $ - ExtRegIndex IF (2*NEXTREGS) AND BLOCKSIZE -1 PARTIAL_BLOCK equ 1 ; if partial block add one more block ELSE PARTIAL_BLOCK equ 0 ENDIF SUPERVGA_SIZE equ (((2*NEXTREGS)/BLOCKSIZE) + PARTIAL_BLOCK) VESAModeTable dw 102h,71h,104h,100h,101h,7Ah,END_OF_MODES ; This table hold VESA mode numbers. ; This the one which is passed to the user in VGAInfo VESAModeTableLen equ ($ - VESAModeTable -2)/2 InternalModeTable db 70h,71h,72h,78h,79h,7Ah ; This table holds internal modes corresponding to VESA modes. ; Like VESA mode 100 is mapped to internal (BIOS) mode 70H ; If any new VESA mode is added, the Internal Mode Table ; should be reordered so that new VESA mode and Internal ; Mode are in same position in the respective tables and ; also parameter sequence in InitModeInfo macro should be ; changed correspondingly NMODES equ $ - InternalModeTable .ERRNZ NMODES - VESAModeTableLen ; give error on size missmatch of two tables ModeInfo label ModeInfoBlock InitModeInfo <,,,,,> VGAInfo VGAInfoBlock <> ; use default values ChipsString db 'CHIPS 82C452, the Super VGA', 0 ProgSize label word ;Create Label to get Size of the Program ;---------------------------------------------------------------------- ; ************************ End of Resident Code ********************* ;---------------------------------------------------------------------- main proc near getvector VideoInt mov ax, OFFSET marker - OFFSET VideoHandler mov cx, marklen mov di, bx add di, ax ; es:[di] Pointer to Previous Marker String mov si, OFFSET marker cld repe cmpsb jcxz AlreadyLoaded jmp short start AlreadyLoaded : print msg1 int 20h ;Exit to DOS start : ; ; Look for 82C452 VGA ; call ReadChipsVGAId cmp ah, CHIPS_ID ; is it chips Id? jnz error_exit ; Chis VGA is not present mov ah, 80h ; open extended reg at 3d6/3d7 call ExtRegs call ReadVGATypeNRev and ah, 0f0h ; extract upper nibble cmp ah, CHIPSVGA_452 jz ChipsVGAPresent ; Chips 82C452 is present error_exit: print msg4 int 20h ;Exit to DOS ChipsVGAPresent: ; our VGA is present print msg0 ;Initial Message ; ; Look for command line parameter for monitor ; es, ds, and cs are same ; mov ax, cs mov es, ax ; es = ds = cs mov di, 80H ; offset of command trail area mov cl, [di] ; al = # of chars in command trail and cl, cl jz MainDefaultMonitor inc di mov al, '+' ; For MultiSync + monitor xor ch, ch ; cx = n chars repnz scasb ; read first char jnz MainDefaultMonitor ; ; MultiSync Plus Monitor ; inc monitor print msg3 .errnz MULTISYNC_PLUS -1 MainDefaultMonitor: ; by default 'monitor' is 0 for MultiSync II ; ; Initialize VGAInfo structure ; mov si, OFFSET VGAInfo mov ax, OFFSET ChipsString mov WORD PTR [si].OEMString, ax mov WORD PTR [si].OEMString+2, ds mov ax, OFFSET VESAModeTable mov WORD PTR [si].VideoModePtr, ax mov WORD PTR [si].VideoModePtr+2, ds ; ; Initialize ModeInfo structure tables ; mov cx, NMODES ; # of modes table support mov si, OFFSET ModeInfo xor bx, bx ; bx = index mov dl, monitor ; monitor type MainModeInfoLoop: mov al, InternalModeTable[bx] ; al = internal mode ; according to table cmp dl, MULTISYNC_PLUS jz MainMultiSyncPlus ; ; not a MultiSync Plus monitor. Disable Mode 71H, & 72H ; cmp al, 71H jb MainCommon ; Not 960x720 1024x768 16 col mode cmp al, 72H ja MainCommon ; if(mode > 72H) ; ; mode 71H & 72H can not be handled by MultiSyncII. Disable them. ; and [si].ModeAttributes, NOT MA_HW_SUPP jmp short MainCommon ; done ;** jmp short @F ; do it down MainMultiSyncPlus: ; all modes are supported ;** cmp al, 70H ;** jz @F ; MultiSyncPlus can not handle at 40MHz ;** cmp al, 79H ;** jbe MainCommon ;**; ;**; modes 70, 7a, 7b can not be handled by MultiSyncPlus. Diasable them. ;**; ;**@@: ;** and [si].ModeAttributes, NOT MA_BIOS_INIT MainCommon: mov ax, OFFSET SuperVGASetCPUMemWin mov WORD PTR [si].WinFuncPtr, ax mov WORD PTR [si].WinFuncPtr+2, ds inc bx ; increase index add si, SIZE ModeInfoBlock loop MainModeInfoLoop ; ; Install interrupt handler ; call ChgVdoVector ;Save Current Video Vector and ;Change it to New Handler ; ; Terminate But Stay Resident ; mov ah, TSR ;TSR Function Number mov al, 0 ;Return code mov dx, OFFSET ProgSize ;Size of the program in bytes mov cl, 4 shr dx, cl ;dx = ProgSize/16 (Size in Paragraphs) inc dx int 21h main endp ;------------------------------------------------------------------ ; This routine saves current Video Vector ; and initialize it with New Video Interrupt Handler ;------------------------------------------------------------------ ChgVdoVector proc near getvector VideoInt mov oldvect, bx mov oldvect+2, es ;Save Old Vector ; Set Video Vector to New Handler setvector VideoInt, VideoHandler ret ChgVdoVector endp ReadChipsVGAId proc near ;--------------------------------------------------------------------- ; read chips global Id register ; Entry: ; None ; Destroyed: ; ax, dx ; Output: ; ah = CHIPS Id (0A5H if successful) ;---------------------------------------------------------------------- ; Find which machine Microchannel/AT mov ah,0c0h ; Find out system configuration int 15H ; Microchannel or AT mov dx,46e8h ; Assume VGA Setup Port for PC/AT mov ax,0e1eh ; al = 1eH to put VGA in Setup Mode ; ah = 0eH to place VGA in normal mode jc @F ; call not successful, assume PC/AT test byte ptr es:[bx+5],2 ; Is it Microchannel Machine ? jz @F ; No, We already have proper values mov dx,094h ; Yes, Microchannel values mov ax,0ffdfh ; al = df, ah = ff for microchannel @@: mov cs:SetupAddr, dx ; save it for use in GrOpenExtRegs mov cs:SetupData, ax ; save it for use in GrOpenExtRegs cli ; Don't interrupt while doing serious business out dx,al push dx ; save port mov dx,104h ; CHIPS ID Port in al,dx pop dx ; CHIPS VGA Setup Port xchg al,ah ; Save ID in ah, al = value to get outof setup port out dx,al sti ; Serious business is over ret ReadChipsVGAId endp ReadVGATypeNRev proc near ;---------------------------------------------------------------------- ; read chip type and rev no ; Entry: ; None ; Destroyed: ; ax, dx ; Output: ; ah = Chips type and revision no ;---------------------------------------------------------------------- mov dx, EGA_BASE+EXTR_ADDR xor al, al ; al = XR00 out dx, al inc dx in al, dx ; al = chips type and rev no mov ah, al ; return the info in ah ret ReadVGATypeNRev endp ;---------------------------------------------------------------------- ; Transient data declaration ;---------------------------------------------------------------------- msg0 db 'VESA452 - VESA BIOS Extension Version 1.0 for 82C452 Super VGA Controller', NL db 'Release Version 0.2',NL,NL db 'Copyright (C) Chips and Technologies, Inc. 1990. ',NL db NL db 'A "+" on command line enables all the modes supported by the video BIOS.',NL db 'Default is NEC MultiSync II or equivalent monitor supported modes.',NL db NL,EOS msg3 db 'Monitor supported is MultiSync Plus',NL,EOS msg4 db 'Chips and Technologies Super VGA 82C452 is not present.',NL db TAB, 'VESA driver is not installed.',NL,EOS monitor db MULTISYNC_II ; default for MultiSync II code ends end begin