Metropoli BBS
VIEWER: chips450.asm MODE: TEXT (ASCII)
; XVD DRIVER FOR Chips&Technologies  VGA CHIPSET 82c450 or 82c453
;
; Lots of thanks goes to Finn Thoegersen, and all the people
; that helped compiling the vgadoc vga information files
; N.B. If you want to make the PS/2 version of this driver look into
;      XVDMode for more info

.386P
code32 segment para public use32
       assume cs:code32,ds:code32
       
                 include xvdriver.inc
                 include head32.inc
                 org 0
                 align byte ; KEEP BYTE ALIGNMENT TO AVOID
                            ; "align distortions"

__XVD_SIGNATURE db 'XVD0'
                ; XGE Video Driver TYPE ZERO, four byte file marker
                ; use it to see if the binary file is  an XVD driver
                ; now here comes the driver base relative offsets
                ; of every function supported
__XVDBiosCheck    dd offset XVDBiosCheck
                ; Returns carry clear if video bios is present
                ; sets vram video pages count into driver table
                ; and available display mode mask
                ; in: edi= XVD driver table , ebp= driver base offset
__XVDChipSetCheck dd offset XVDChipSetCheck
                ; Returns carry clear if chipset is present
                ; sets vram video pages count into driver table
                ; and availabl;e display mode mask
                ; in: edi= XVD driver table , ebp= driver base offset

                  ; currently BOTH of these must be successful
                  ; to "get safe access" to the graphics extensions.
                  ;
                  ; If __XVDBiosCheck fails you should want the user
                  ; that bios is not recognized but it is possible to
                  ; test for the chipset and then try to set
                  ; the video mode hoping the mode set values
                  ; are not different.
                  ;
                  ; A future XGE release will try to use VESA functions
                  ; to set the video mode if _XXVDBiosCheck fails
                  ; and then if _XVDChipSetCheck is successful
                  ; it will "unlock" the extensions thru direct chipset access.
                  ;
                  ; To use "extended" multi-page mode 13h you only have
                  ; to check for the chipset (the bios entry is the same
                  ; for all boards) but remember to include in the bios check
                  ; the code needed to "unlock" the vga extensions.
                  ;
                  ; both __XVDBiosCheck and __XVDChipSetCheck
                  ; must be called with:
                  ; edi= XVD driver table ptr
                  ; ebp= driver base address
                  ; _XVDVPages,_XVDTotRam,_XVDVModes and _XVDASize
                  ; will be updated to what the driver supports.

__XVDMode         dd offset XVDMode
                  ; Set video mode
                  ; eax=requested video mode
                  ; edi= XVD driver table ptr
                  ; ebp= driver base address
                  ; returns carry clear if successful


__XVDPage         dd offset XVDPage
                  ; Set the current "accessible"  64k video page
                  ; in: eax= video page number
                  ; out: edi= LINEAR address of video page
                  ;           (subtract _Code32Base to this to get
                  ;            the code32 relative offset)

__XVDVisible      dd offset XVDVisible
                  ; Set the base page of display buffer visible on screen
                  ; in: eax= video page number

__XVDOpen         dd offset unSupported
                  ; Opens the "linear aperture"
                  ; setting to the nearest aperture available on driver table
                  ; (the 386video module must write on _XVDAperture
                  ;  the "first" AVAILABLE PHYSICAL ADDRESS
                  ;  (nor a code32 relative address neither
                  ;   a "virtual memory" linear address, this functions
                  ;   needs a "raw" address).
                  ; edi=driver table, ebp=driver base address
                  ; Returns carry clear if successful

__XVDClose        dd offset unSupported
                  ; Closes the "linear aperture"
                  ; edi=driver table  ebp=driver base offset

__XVDLineSize     dd offset XVDLineSize
                  ; Set nex scanline width
                  ; in: eax= requested scanline size
                  ;     edi=driver table
                  ;     ebp=driver base address
                  ; out: nearest scanline size set into driver table
                  ;      but _DispX is not modified
                  ;      (this will be up to you)

__XVDSet1Pal      dd offset XVDSet1Pal
__XVDGet1Pal      dd offset XVDGet1Pal
__XVDSet256Pal    dd offset XVDSet256Pal
                  ; RGB palette handling functions
                  ; (identical to _Set1Pal,_Get1Pal,_Set256pal)
__XVDCardType     dd offset XVDCardType
                     ; driver-base relative pointer to ASCIIZ string
                     ; max. 30 character long
__XVDProgrammer   dd offset XVDProgrammer
                     ; driver-base relative pointer to ASCIIZ string
                     ; with multiple lines of text,max. 40 char each
                     ; (use the LF char (code 10h) to mark newlines)
__XVDNotes        dd offset XVDNotes
                     ; driver-base relative pointer to ASCIIZ string
                     ; with multiple lines of text,max. 40 char each
                     ; (use the LF char (code 10h) to mark newlines)
                     ; Of notes about the driver usage and supported display
                     ; cards

; video modes
the_mode dw 0003h,0013h,0078h,0079h
xsquar   dd 0000h,32,32,100
ysquar   dd 0000,24,24,100
; memory size limits
the_mem  db 1,1,4,5
the_dual db 1,2,8,10

modefailure:
        popad
unSupported:
        stc
        ret

XVDVisible:
        push eax
        push edx
        shl eax,14 ; from 64k count into eax to dword count into ah
        mov dx,3d4h
        mov al,0Ch
        cli
        out dx,ax    ; set high byte of vga screen start offset
        shr eax,8
        mov dx,3d6h
        mov al,0Ch
        out dx,ax    ; set the higher bits
        sti
        pop edx
        pop eax
        ret


XVDPage: 
         push eax
         push edx
         shl eax,12
         mov dx,3D6h
         mov al,10h
         out dx,ax
         mov edi,0A0000h
         pop edx
         pop eax
         ret

XVDLineSize:
        push edx
        cmp eax,(255*8)  ; max 2040 pixels/line
        jb tooscan
        mov eax,(255*8)
tooscan:add eax,7
        shr eax,3 ; scanline is in 8 byte multiples
        mov dx,3d4h
        mov ah,al
        mov al,13h
        out dx,ax
        shr eax,8
        shl eax,3
        mov [edi+_XVDScanLine],eax
        pop edx
        ret

XVDBiosCheck:
        pushad
        mov word ptr ds:V86ax,5F00h
        mov al,10h
        call dword ptr ds:_ExecINT
        cmp byte ptr ds:V86al,5Fh
        jne modefailure
        mov ebx,ds:V86ebx
        shr bl,4
        cmp bl,3
        je goodbios
        cmp bl,4
        jne modefailure
goodbios:
        mov cl,bh
        and cl,03h
        mov eax,2  ;
        inc ecx    ;
        shl eax,cl ; get total memory count
        mov [edi+_XVDVPages],eax
        mov ebx,3 ; supports text80x25 and 320x200 as default
        cmp eax,8 ;512K ??? there must be a 16bit internal path
                  ;so there is enough bandwidth for higher video modes
        jnbe rammed
        or bl,0Fh
rammed:
        mov [edi+_XVDVModes],ebx
        popad
        clc
        ret

XVDCardType db 'Chips&Tech 450/453 ISA BUS',0

XVDChipSetCheck:
        ; Chipset check is performed after the bios check
        ; you should save the "available ram" settings
        ; obtained from XVDBiosCheck
        ; and then check what the chipset check returned
        ; to be sure you are accessing the board the driver has been
        ; designed for.
        pushad
        ; enter ISA BOARD setup mode
        cli
        mov dx,46E8h
        in al,dx
        or al,10h  ; bit4=on
        and al,0F7h ;bit3=off
        out dx,al
        ; check for chipset marker
        mov dx,104h
        in al,dx
        mov ah,al
        ; exit ISA BOARD setup mode
        mov dx,46E8h
        in al,dx
        and al,0EFh ;bit4=off
        or al,008h ;bit3=on
        out dx,al
        sti
        cmp ah,0A5h ; Chips & Tech ?
        jne modefailure
        mov dx,3d6h
        xor al,al
        out dx,al
        inc edx
        in al,dx
        dec edx
        shr al,4
        cmp al,3
        je goodchip
        cmp al,4
        jne modefailure
goodchip:
        ; retry available memory check
        mov al,4
        out dx,al
        inc edx
        in al,dx
        and al,03h
        mov cl,al
        mov eax,2  ;
        inc ecx    ;
        shl eax,cl ; get total memory count
        mov [edi+_XVDTotRam],eax
        mov [edi+_XVDVPages],eax
        mov ebx,3 ; supports text80x25 and 320x200 as default
        cmp eax,8 ;512K ??? there must be a 16bit internal path
                  ;so there is enough bandwidth for higher video modes
        jnbe chrammed
        or bl,0Fh
chrammed:
        mov [edi+_XVDVModes],ebx
        popad
        clc
        ret

XVDProgrammer db 'Card:   Programmer',10
              db '82c450  Lorenzo Micheletto',10
              db '82c453  Lorenzo Micheletto',0

XVDMode: pushad
         mov word ptr  ds:V86ax,0003h ; text mode
         mov dword ptr [edi+_XVDCMode],0
         or eax,eax
         jz vid_mode
         cmp eax,4 ; only up to 640x480 on my C&T450
                   ; (don't know if it is the bios or other things)
         jnb modefailure  ; mode not supported

         mov ebx,[ebp+eax*4+xsquar]        ; set aspect ratio
         mov [edi+_XSquare],ebx            ;
         mov ebx,[ebp+eax*4+ysquar]        ;
         mov [edi+_YSquare],ebx            ;
         mov bx,[ebp+eax*2+the_mode]  ;
         mov ds:V86ax,bx ; set graphic mode
         mov [edi+_XVDCMode],eax
         mov al,10h
         call dword ptr ds:_ExecINT
         mov eax,[edi+_DispX]        ; set new scanline size
         mov [edi+_XVDScanLine],eax  ;

; 94h (R/W):  Setup Control Register for Microchannel boards
;bit 0-2  Reserved
;      3  Enables Adapter VGA if set
;      4  Enters Setup Mode if set
;    5-7  Reserved
;Note: This is the same register as 46E8h.
;
;100h (R):  Microchannel ID low
;bit 0-7  Bit 0-7 of Microchannel Card ID
;
;101h (R):  Microchannel ID high
;bit 0-7  Bit 8-15 of Microchannel Card ID
;
;102h (R/W):  Global Enable
;bit   0  VGA is enabled if set.
;
;103h (R/W):  Multiple Enable
;bit 0-3  Multiple VGA Enable
;      4  Must be 0 for proper operation of 82c455/6/7.
;      6  Extension registers at 3B6h/7h if set,
;         3D6h/7h if not.
;      7  Extension Registers Access Enable.
;         VGA Extension registers at 3d7h can only be
;         accessed if this bit is set.
;Note: This register only available in Setup Mode.
;
;104h (R):  Global ID (Setup)
;bit 0-7  Chip I/D.  0A5h if Chips and Tech Chip set.
;Note: this register can only be read if the chip is in setup mode (46E8h/94h
;      bit 4 is set)
;
;3C3h (R/W):  Setup Control PS/2
;bit   0  Enables motherboard VGA if set
;      4  Enters Setup mode if set
;
;
;46E8h (R/W):  Setup Control PC/AT Register
;bit 0-2  Reserved
;      3  Enables Adapter VGA if set
;      4  Enters Setup Mode if set
;    5-7  Reserved
;Note: This is the same register as 94h.

         ; N.B. if you look into vgadocXX.zip
         ; (the version i used was vgadoc3.zip uploaded from x2ftp.oulu.fi)
         ; look into the file describing YOUR card to see
         ; what specific SuperVGA ports you need to access to
         ; turn on extended paging and svga extensions
         ; THEN look into vga.txt to get an idea of what "standard" vga
         ; registers may need tweaking for "extended" 320x200 multipage mode
         ; THEN use DEBUG or other debugging tools to watch
         ; what are the video register values in "vga" or "svga" mode
         ; so you can decide what to do.
         cli
         ; enter C&T ISA/AT BOARD setup mode
         mov dx,46E8h
         in al,dx
         or al,10h  ; bit4=on
         and al,0F7h ; bit3=off
         out dx,al
         ; activate extension
         mov dx,103h
         in al,dx
         or al,80h ; bit7=on = extended registers accessible
         and al,0BFh ;bit6= off = extended ports at 3d6h/3d7h
         out dx,al
         ; exit C&T ISA/AT BOARD setup mode
         mov dx,46E8h
         in al,dx
         and al,0EFh ;bit4=off
         or  al,008h ;bit3=on
         out dx,al
         ; set cpu window to 64k (vga/svga)
         mov dx,3CEh
         mov ax,0606h
         out dx,al
         inc edx
         in  al,dx
         or  al,00000100b
         dec edx
         and al,11110111b
         xchg al,ah
         out dx,ax
         ; disable word/dword mode
         mov dx,3d4h
         mov ax,0E317h
         out dx,ax
         mov ax,00014h
         out dx,ax
         ; set single video page mode with extended paging (bit0)
         ; and "fully linear" display ram raster scanning (svga)
         mov dx,3d6h
         mov ax,050Bh
         out dx,ax
         ; allow the CTRC to cross bank boundaries
         mov al,4
         out dx,al
         inc edx
         in al,dx
         or al,24h  ; write buffer on & CRTC can cross banks
         out dx,al
         sti
         ; this release does not allows a "wide" (>2040) scanline
         popad
         clc
         ret

vid_mode:
         mov al,10h
         call dword ptr ds:_ExecINT
         popad
         clc
         ret

XVDNotes db 'XVD DRIVER FOR C&T 82c450',10
         db 'by Lorenzo Micheletto',10,10
         db 'Should be compatible with',10
         db 'C&T 82c450 cards too.',10,10
         db 'Supports 256 color video modes',10
         db '320x200,640x400,640x450',10
         db 'but needs at least 512k',10
         db 'for the last two',0

STATUS          = 03DAh ; status register port

IS_HVSYNC       = 01
IS_VSYNC        = 08


; palette ports
DACREAD         = 03C7h
DACWRITE        = 03C8h
DACDATA         = 03C9h

;----------------------------------------------------------------------------
; Set1Palette        al =  palette entry
;                    edx = bit 0..7   red
;                          bit 8..15  green
;                          bit 16..23 blue 
;                          bit 24..31 not used
                
XVDSet1Pal:
                ; al = palette index
                ; edx = (XBGR)
                push eax
                push ebx
                mov  ebx,edx
                push edx
                shr ebx,2   ; cut out lower bits to get VGA resolution
		mov     dx,DACWRITE
                and ebx,003F3F3Fh ; eliminate garbage bits
		cli
                out     dx,al  ; index
		inc	dx
                mov     al,bl
                out     dx,al  ; Red
                mov     al,bh
                shr     ebx,16
                out     dx,al  ; Green
                mov     al,bl
                out     dx,al  ; Blue
		sti
                pop edx
                pop ebx
                pop eax
		ret
                
XVDGet1Pal:
                ; al = palette index
                ; edx = (XBGR)
                push eax
                mov ds:V86bl,al
                xor edx,edx
                mov word ptr ds:V86ax,1015h
                mov al,10h
                call dword ptr ds:_ExecINT
                mov dl,ds:V86cl
                shl edx,16
                mov dh,ds:V86ch
                mov dl,ds:V86dh
                shl edx,2
                pop eax
                ret

XVDSet256Pal:
                ; esi = palette pointer
                pushad
                mov     ecx,256
		mov     dx,STATUS
                cli
into_vretrace:
		in      al,dx
                test    al,IS_VSYNC
		jnz     into_vretrace
outof_vretrace:
		in      al,dx
                test    al,IS_VSYNC
		jz      outof_vretrace
                ; now a full vretrace interval is available
                 
		mov     dx,DACWRITE
                xor     eax,eax
		out	dx,al
                inc     dx  ; move to DACDATA port
             nextp:
                mov eax,[esi]
                add esi,4
                shr eax,2           ; 8bit to 6bit color values
                and eax,003F3F3Fh   ;
                out dx,al ; Red
                mov al,ah
                out dx,al ; Green
                shr eax,16
                out dx,al ; Blue
                dec ecx
                jne nextp
                sti
                popad
		ret
     
code32  ends

	END
[ RETURN TO DIRECTORY ]