Date: Tue, 26 Jan 93 15:33:13 -0800 From: anton AT sting DOT Berkeley DOT EDU (Jeff Anton) To: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: new libgr driver for Trident 8900C Here is a new libgr driver for the Trident 8900C SVGA chipset. This driver is noteworthy in that it allows split read and write page mappings, which the other trident drivers for libgr don't use. This split page mapping is new to the 8900C. I have no idea what will occur if it is run on any other chip. I have put in extensive comments about the implementation in the code in the hope of dispelling the rumors that you can't read screen data from the trident chips sanely. Jeff Anton ----------------------- ; This is file TRI8900C.ASM ; ; revised for the 8900c by jeff anton 12/29/92 ; This is an experimental driver - it is ONLY for the Trident 8900C ; and makes use of very new features which have scant documentation. ; preliminary testing with intra-screen blitting and screen reading look good. ; Also added are the new text modes - untested ; ; Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954 ; ; This file is distributed under the terms listed in the document ; "copying.dj", available from DJ Delorie at the address above. ; A copy of "copying.dj" should accompany this file; if not, a copy ; should be available from where this file was obtained. This file ; may not be distributed without a verbatim copy of "copying.dj". ; ; This file is distributed WITHOUT ANY WARRANTY; without even the implied ; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; cseg segment byte public 'code' assume cs:cseg, ds:cseg, es:cseg, ss:nothing dw offset init_routine dw offset paging_routine dw 1 ; set to 1 if separate read & write windows or ; only 64K of video RAM (ie: no paging) def_tw dw 80 ; filled in by go32 if GO32 env. var. is set def_th dw 25 def_gw dw 640 def_gh dw 480 ;-------------------------------------------------------------------------- ; Entry: AX=mode selection ; 0=80x25 text ; 1=default text ; 2=text CX cols by DX rows ; 3=biggest text ; 4=320x200 graphics ; 5=default graphics ; 6=graphics CX width by DX height ; 7=biggest non-interlaced graphics ; 8=biggest graphics ; ; NOTE: This runs in real mode, but don't mess with the segment registers. ; ; Exit: CX=width (in pixels or characters) ; DX=height init_table label word dw offset init_0 dw offset init_1 dw offset init_2 dw offset init_3 dw offset init_4 dw offset init_5 dw offset init_6 dw offset init_7 dw offset init_8 init_routine proc far cmp ax,8 ja retins add ax,ax mov bx,ax jmp init_table[bx] init_0: ; 80x25 text mov si,offset bastxt jmp init_2c init_2_table label word dw 01h, 40, 25 bastxt: dw 03h, 80, 25 dw 50h, 80, 30 dw 51h, 80, 43 dw 52h, 80, 60 dw 53h, 132, 25 dw 54h, 132, 30 dw 55h, 132, 43 bigtxt: dw 56h, 132, 60 init_2_tend label word init_1: ; default text mov cx,def_tw mov dx,def_th ; fall through init_2: ; CX*DX text mov si,offset init_2_table-6 init_2a: add si,6 cmp [si+2],cx jb init_2b cmp [si+4],dx ; got a big enough one! jnb init_2c init_2b: cmp si,offset bigtxt jne init_2a init_2c: mov ax,[si] push si int 10h pop si mov cx,[si+2] mov dx,[si+4] retins: ret init_3: ; biggest text mov si,offset bigtxt jmp init_2c init_4: ; 320x200 graphics mov si,offset init_6_table jmp init_6c init_6_table label word dw 13h, 320, 200 dw 5ch, 640, 400 dw 5dh, 640, 480 nonint: dw 5eh, 800, 600 biggr: dw 62h, 1024, 768 init_6_tend label word init_5: ; default graphics - should be 640x480 if supported mov cx,def_gw mov dx,def_gh ; fall through init_6: ; CX*DX graphics mov si,offset init_6_table -6 init_6a: add si,6 cmp [si+2],cx jb init_6b cmp [si+4],dx ; got a big enough one! jnb init_6c init_6b: cmp si,offset biggr jne init_6a init_6c: mov ax,[si] push si int 10h pop si mov cx,[si+2] mov dx,[si+4] ret init_7: ; biggest non-interlaced graphics mov si,offset nonint jmp init_6c init_8: ; biggest graphics mov si,offset biggr jmp init_6c init_routine endp ;-------------------------------------------------------------------------- ; Entry: AH=read page ; AL=write page ; ; NOTE: This runs in protected mode! Don't mess with the segment registers! ; This code must be relocatable and may not reference any data! ; ; Exit: VGA configured. ; AX,BX,CX,DX,SI,DI may be trashed ; ; Code derived from VGAKIT version 3.4 ; Copyright 1988,89,90 John Bridges assume ds:nothing, es:nothing paging_routine proc far xor ax,0202h ; flip bit 1 on each page no mov cx,ax ; save pages into cx mov dx,3c4h ; read 3c5.b hardware version mov al,0bh ; to enable new mode and 64k pages (BPS) out dx,al ; 3c4 index register to 0bh inc dx ; switch to 3c5 in al,dx ; read 3c5.b mov dl,0ceh ; switch to 3ce mov al,6 ; index to 6 misc reg out dx,al ; ... inc dx ; switch to 3cf in al,dx ; read misc reg and al,0f3h ; clear bits 3 and 2 or al,4 ; set bit 2 out dx,al ; write back to misc reg mov al,0fh ; index to 0fh (unnamed register) dec dx ; back to 3ce out dx,al ; select register that enables source page map mov al,1 ; write a 1 to enable source page address inc dx ; up to 3cf out dx,al ; output that 1 to 3cf.f dec dx ; back to 3ce mov al,0eh ; index to 0eh (source page address reg) out dx,al ; ... inc dx ; up to 3cf mov al,ch ; get read page with bit 1 already flipped out dx,al ; out page to 3cf.e (source page address reg) mov dl,0c4h ; back to 3c4 mov al,0eh ; index to 0eh out dx,al ; select 3c5.e inc dx ; up to 3c5 mov al,cl ; get write page with bit 1 flipped out dx,al ; out page to 3c5.e ret paging_routine endp ;-------------------------------------------------------------------------- cseg ends end