home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
America's Premier Sharewa…& Public Domain Software
/
Americas_Premiere_Shareware_for_1993.iso
/
wallpapr
/
tseng.a86
< prev
next >
Wrap
Text File
|
1992-09-18
|
22KB
|
1,052 lines
COMMENT %
GRAPHIC WORKSHOP Tseng ET3000/ET4000 SVGA screen driver
COPYRIGHT (C) 1990 ALCHEMY MINDWORKS INC.
VERSION 1.1
portions copyright (C) 1990,1991 Gregory D. Weeks
permision granted for Alchemy Mindworks to distribute.
This driver was adapted from the skeletal driver
supplied with graphic workshop 3.4. It will drive
Tseng ET4000 and ET3000 equipped SVGA cards. The Tseng
cards are capable of up to 1024x768 in 256 colors. This
driver must be installed after assembly for the
monitor type.
This driver is designed to be assembled with A86.
%
VERSION EQU 1 ;VERSION NUMBER
SUBVERSION EQU 2 ;SUBVERSION NUMBER
_AOFF EQU 6 ;STACK OFFSET
; these are the maximum possible screen sizes
TLI_WIDE EQU 1024 ;maximum screen width in pixels
TLI_DEEP EQU 768 ;maximum screen depth in lines
TLI_SCREENSEG EQU 0A000H ;segment of tseng card video buffer
TLI_BYTES EQU 128 ;maximum width of planar modes in bytes
;THIS MACRO SELECTS AN EGA PLANE
EGAPLANE MACRO
MOV AL,2
MOV DX,03C4H
OUT DX,AL
INC DX
MOV AL,#1
OUT DX,AL
#EM
ORG 0000H ;ORIGIN FOR LOADABLE DRIVER
DB 'ALCHDRV2' ;SIGNATURE - DON'T CHANGE THIS
;THE FOLLOWING ARE THE POINTERS TO THE CALLABLE ROUTINES AND THE COMMON
;DATA. THE SEGMENTS ARE FILLED IN BY GRAPHIC WORKSHOP. DON'T CHANGE ANYTHING.
DISPATCH:
DW VGA_on ;FAR POINTER TO VGA MODE SELECT
DW ?
DW VGA_line ;FAR POINTER TO VGA LINE DISPLAY
DW ?
DW VGA_OFF ;FAR POINTER TO VGA MODE DESELECT
DW ?
DW VGA_PALETTE ;FAR POINTER TO VGA PALETTE SET
DW ?
DW VGA_OVERSCAN ;FAR POINTER TO VGA OVERSCAN SET
DW ?
DW EGA_ON ;FAR POINTER TO EGA MODE SELECT
DW ?
DW EGA_LINE ;FAR POINTER TO EGA LINE DISPLAY
DW ?
DW EGA_OFF ;FAR POINTER TO EGA MODE DESELECT
DW ?
DW EGA_PALETTE ;FAR POINTER TO EGA PALETTE SET
DW ?
DW MONO_ON ;FAR POINTER TO MONO MODE SELECT
DW ?
DW MONO_FRAME ;FAR POINTER TO MONO PAGE DISPLAY
DW ?
DW MONO_LINE ;FAR POINTER TO MONO LINE DISPLAY
DW ?
DW MONO_OFF ;FAR POINTER TO MONO MODE DESELECT
DW ?
DW 0,0 ;NULL ONE
DW 0,0 ;NULL TWO
DW 0,0 ;NULL THREE
DW 0,0 ;NULL FOUR
V_VGAWIDE DW TLI_WIDE ;VGA SCREEN WIDTH
V_VGADEEP DW TLI_DEEP ;VGA SCREEN DEPTH
V_VGASCRNSEG DW TLI_SCREENSEG ;VGA SCREEN SEGMENT
V_EGAWIDE DW TLI_WIDE ;EGA SCREEN WIDTH
V_EGADEEP DW TLI_DEEP ;EGA SCREEN DEPTH
V_EGABYTES DW TLI_BYTES ;EGA SCREEN BYTES
V_EGASCRNSEG DW TLI_SCREENSEG ;EGA SCREEN SEGMENT
V_MONOWIDE DW TLI_WIDE ;MONO SCREEN WIDTH
V_MONODEEP DW TLI_DEEP ;MONO SCREEN DEPTH
V_MONOBYTES DW TLI_BYTES ;BYTE WIDTH ON MONOCHROME SCREEN
V_MONOSCRNSEG DW TLI_SCREENSEG ;MONOCHROME SCREEN SEGMENT
;THESE VERSION NUMBERS REFLECT THE DRIVER TEMPLATE VERSION AND THE
;VERSION OF THE DRIVER ITSELF. YOU CAN CHANGE THE SUBVERSION VALUE
;TO REFLECT CHANGES IN YOUR DRIVER. THE VERSION VALUE MUST REMAIN
;UNCHANGED OR GRAPHIC WORKSHOP MAY REJECT YOUR DRIVER.
DW VERSION
DW SUBVERSION
;THE DESCRIPTION APPEARS IN THE F10 "ABOUT" BOX IN GRAPHIC
;WORKSHOP WHEN AN EXTERNAL DRIVER IS BEING USED. IT CAN'T
;EXCEED 24 CHARACTERS AND MUST BE NULL TERMINATED
Card_Type: DB 'Tseng ET3000/4000',0
Installed dw 0
dw Mode_Pointer
;THIS ROUTINE SELECTS THE VGA 256 COLOUR MODE
;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
VGA_on:
call Install
push bp
mov bp,sp
push ds
mov ds,cs
mov ax,[bp+_AOFF] ; cols
mov bx,[bp+_AOFF+2] ; rows
mov si,w VGA_mode_pointer
call pick_mode
mov V_VGAWIDE,ax
mov V_VGADEEP,bx
mov ax,cx
int 10h
mov cx,V_VGADEEP ;depth of screen in the current mode
sub dx,dx
mov bx,dx
mov si,SCREENTABLE
mov di,Row_seg
mov [si],dx
mov [di],bl
add si,2
inc di
dec cx
l2:
add dx,V_VGAWIDE
jnc >l1
inc bl
or b[di-1],80h
l1:
mov [si],dx
mov [di],bl
add si,2
inc di
loop l2
pop ds,bp
retf
;THIS ROUTINE DISPLAYS A VGA LINE
;THE FIRST ARGUMENT ON THE STACK (2 WORDS) IS A FAR POINTER TO
;THE LINE. THE SECOND ARGUMENT IS THE LENGTH OF THE LINE IN PIXELS
VGA_line:
push bp
mov bp,sp
push ds
push es
mov si,[bp + _AOFF + 0] ;OFFSET OF SOURCE
mov ds,[bp + _AOFF + 2] ;SEGMENT OF SOURCE
mov bx,[bp + _AOFF + 6] ;GET LINE NUMBER
cmp bx,cs:V_VGADEEP
jge SHOWVGAX
mov al,cs:[Row_seg + bx]
shl bx,1
mov di,cs:[screentable + bx]
cld
mov cx,[bp + _AOFF + 4]
cmp cx,0
je SHOWVGAX
cmp cx,cs:V_VGAWIDE
jl >l1
mov cx,cs:V_VGAWIDE
l1:
test al,80h
jnz > l2
call select_write_seg
mov es,cs:V_VGASCRNSEG
shr cx,1 ;convert to word moves
jc >l3
rep movsw
jmp >l4
l3:
rep movsw
movsb
l4:
jmp SHOWVGAX
; from here down is for the few lines that cross segment
; boundary's. This routine is slower than the previous rep movsw's.
l2:
call select_write_seg
mov bl,al
mov es,cs:V_VGASCRNSEG
l1:
movsw
cmp di,0
jne >l2
mov al,bl
inc al
call select_write_seg
l2:
dec cx
cmp cx,2
je >l5
loop l1
jmp >l3
l5:
movsb
l3:
SHOWVGAX:
pop es,ds,bp
retf
;THIS ROUTINE SETS THE VGA PALETTE
;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO
;THE PALETTE DATA. THE SECOND ARGUMENT IS THE NUMBER OF COLOURS.
VGA_PALETTE:
PUSH BP
MOV BP,SP
PUSH DS
MOV SI,[BP + _AOFF + 0] ;OFFSET OF SOURCE
MOV DS,[BP + _AOFF + 2] ;SEGMENT OF SOURCE
MOV CX,[BP + _AOFF + 4] ;NUMBER OF COLOURS
CMP CX,0 ;CHECK FOR NASTIES
JG GVP0
JMP GVPX
;WE'LL SET THE PALLETTE USING DIRECT REGISTERS RATHER
;THAN A BIOS CALL AS IT LOOKS NICER, however if
;gray scale suming is active, we'll use the BIOS
GVP0:
cmp cs:b gray_VGA,0
je >l2
push si,cx
mov es,ds
mov di,si
l1:
lodsb
shr al,1
shr al,1
stosb
lodsb
shr al,1
shr al,1
stosb
lodsb
shr al,1
shr al,1
stosb
loop l1
pop cx,si
mov dx,si
mov bx,0
mov ax,1012h
int 10h
jmp GVPX
l2:
MOV DX,03C6H
MOV AL,0FFH
OUT DX,AL
MOV BX,0
GVP1: PUSH CX
MOV DX,03C8H
MOV AL,BL
INC BX
OUT DX,AL
INC DX
LODSB
SHR AL,1
SHR AL,1
OUT DX,AL
LODSB
SHR AL,1
SHR AL,1
OUT DX,AL
LODSB
SHR AL,1
SHR AL,1
OUT DX,AL
POP CX
LOOP GVP1
GVPX:
POP DS
POP BP
RETF
gray_VGA db 0
;THIS ROUTINE SETS THE VGA OVERSCAN.
;THE FIRST STACK ARGUMENT IS THE COLOUR NUMBER.
VGA_OVERSCAN:
PUSH BP
MOV BP,SP
MOV AX,1001H
MOV BX,[BP + _AOFF + 0]
XCHG BH,BL
INT 10H
POP BP
RETF
;THIS ROUTINE SELECTS THE EGA 16 COLOUR MODE
;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
EGA_on:
call Install
push bp
mov bp,sp
push ds
mov ds,cs
mov ax,[bp+_AOFF] ; cols
mov bx,[bp+_AOFF+2] ; rows
mov si,w EGA_mode_pointer
call pick_mode
mov V_EGAWIDE,ax
mov V_EGADEEP,bx
add ax,7
shr ax,1
shr ax,1
shr ax,1
mov V_EGABYTES,AX
mov ax,cx
int 10h
mov cx,V_EGADEEP ;depth of screen in the current mode
sub dx,dx
mov bx,dx
mov si,SCREENTABLE
mov di,Row_seg
mov [si],dx
mov [di],bl
add si,2
inc di
dec cx
EGA_on1:
add dx,V_EGABYTES
jnc >l1
inc bl
l1:
mov [si],dx
mov [di],bl
add si,2
inc di
loop EGA_on1
pop ds,bp
retf
;THIS ROUTINE DISPLAYS AN EGA LINE
;THE FIRST ARGUMENT ON THE STACK (2 WORDS) IS A FAR POINTER TO
;THE LINE. THE SECOND ARGUMENT IS THE LENGTH OF THE LINE IN BYTES
EGA_LINE:
PUSH BP
MOV BP,SP
PUSH DS
PUSH ES
MOV SI,[BP + _AOFF + 0] ;OFFSET OF SOURCE
MOV DS,[BP + _AOFF + 2] ;SEGMENT OF SOURCE
MOV BX,[BP + _AOFF + 6] ;GET LINE NUMBER
CMP BX,cs:V_EGADEEP
if GE jmp long SHOWEGAX
mov al,cs:[Row_seg+bx]
call select_write_seg
SHL BX,1
MOV DI,CS:[SCREENTABLE+BX]
MOV AX,0A000H
MOV ES,AX
MOV BX,[BP + _AOFF + 4] ;LENGTH OF MOVE IN BYTES
shr bx,1 ; convert to word moves
jc >l3
MOV CX,BX
EGAPLANE 1
CLD
PUSH DI
rep movsw
POP DI
MOV CX,BX
EGAPLANE 2
PUSH DI
rep movsw
POP DI
MOV CX,BX
EGAPLANE 4
PUSH DI
rep movsw
POP DI
MOV CX,BX
EGAPLANE 8
PUSH DI
rep movsw
POP DI
EGAPLANE 0FH
jmp >l4
l3:
MOV CX,BX
EGAPLANE 1
CLD
PUSH DI
rep movsw
movsb
POP DI
MOV CX,BX
EGAPLANE 2
PUSH DI
rep movsw
movsb
POP DI
MOV CX,BX
EGAPLANE 4
PUSH DI
rep movsw
movsb
POP DI
MOV CX,BX
EGAPLANE 8
PUSH DI
rep movsw
movsb
POP DI
EGAPLANE 0FH
l4:
SHOWEGAX: POP ES
POP DS
POP BP
RETF
;THIS ROUTINE SETS THE EGA PALETTE
;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO
;THE PALETTE DATA. THE SECOND ARGUMENT IS THE NUMBER OF COLOURS.
EGA_PALETTE:
PUSH BP
MOV BP,SP
PUSH DS
MOV SI,[BP + _AOFF + 0] ;OFFSET OF SOURCE
MOV DS,[BP + _AOFF + 2] ;SEGMENT OF SOURCE
MOV CX,[BP + _AOFF + 4] ;NUMBER OF COLOURS
SUB BX,BX
CMP CX,16
JLE EGA_PALETTE1
MOV CX,16
EGA_PALETTE1: MOV BH,[SI]
MOV AX,1000H
INT 10H
INC BL
INC SI
LOOP EGA_PALETTE1
POP DS
POP BP
RETF
;THIS ROUTINE SELECTS THE 2 COLOUR MODE
;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
MONO_on:
call Install
push bp
mov bp,sp
push ds
mov ds,cs
mov ax,[bp+_AOFF] ; cols
mov bx,[bp+_AOFF+2] ; rows
mov si,w MONO_mode_pointer
call pick_mode
mov V_MONOWIDE,ax
mov V_MONODEEP,bx
add ax,7
shr ax,1
shr ax,1
shr ax,1
mov V_MONOBYTES,AX
mov ax,cx
int 10h
mov cx,V_MONODEEP ;depth of screen in the current mode
sub dx,dx
mov bx,dx
mov si,SCREENTABLE
mov di,Row_seg
mov [si],dx
mov [di],bl
add si,2
inc di
dec cx
MONO_on1:
add dx,V_MONOBYTES
jnc >l1
inc bl
l1:
mov [si],dx
mov [di],bl
add si,2
inc di
loop MONO_on1
pop ds,bp
retf
UPDATE_MOVE EQU 2
UPDATE_PAD EQU 4
UPDATE_ADJUST EQU 6
;THIS ROUTINE DISPLAYS A FULL MONOCHROME PAGE
;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO THE PAGE
;THE SECOND ARGUMENT IS THE WIDTH OF THE BITMAP (IN BYTES)
;THE THIRD ARGUMENT IS THE NUMBER OF LINES TO DISPLAY
;NOTE: THE SOURCE BUFFER MAY BE BIGGER THAN 64K.
MONO_FRAME:
PUSH BP
MOV BP,SP
SUB SP,UPDATE_ADJUST
PUSH DS
PUSH ES
MOV AX,cs:V_MONOSCRNSEG ;POINT TO THE SCREEN
MOV ES,AX
MOV AX,[BP + _AOFF + 4] ;GET THE WIDTH OF MOVE
MOV [BP - UPDATE_MOVE],AX ;SAVE IT LOCALLY
MOV WORD PTR [BP - UPDATE_PAD],0 ;SET ADJUSTMENT
CMP AX,cs:V_MONOBYTES ;IF THE MOVE IS LESS THAN
JL UPDATE0 ;SCREEN WIDTH, GO FOR IT
SUB AX,cs:V_MONOBYTES ;ELSE, SET MOVE WIDTH
MOV [BP - UPDATE_PAD],AX ;...AND THE AMOUNT TO
MOV AX,cs:V_MONOBYTES ;...ADJUST THE POINTER
MOV [BP - UPDATE_MOVE],AX ;...AFTER EACH LINE
UPDATE0: MOV SI,[BP + _AOFF + 0] ;OFFSET OF BITMAP
MOV DS,[BP + _AOFF + 2] ;SEGMENT OF BITMAP
MOV CX,[BP + _AOFF + 6] ;NUMBER OF LINES
CLD ;CLEAR DIRECTION FLAG
SUB BX,BX
UPDATE1: PUSH CX ;SAVE COUNT (LINE NUMBER)
shr bx,1 ;select the proper segment for the line
mov al,cs:[Row_seg+bx] ; actually only needed for the 1024x768 mode
shl bx,1 ; but it's only done once per line and it's
call select_write_seg ; fairly quick so I didn't add the extra code
; to bypass it in the other modes
MOV DI,CS:[SCREENTABLE + BX]
ADD BX,2 ;POINT TO NEXT LINE
MOV CX,[BP - UPDATE_MOVE] ;GET THE MOVE SIZE
shr cx,1 ; convert to word moves
jc >l3
rep movsw
jmp >l4
l3:
rep movsw
movsb
l4:
ADD SI,[BP - UPDATE_PAD] ;ADJUST THE POINTER
CMP SI,0F800H ;ARE WE WITHIN 2K OF TOP?
JL UPDATE2 ;IF NOT, CARRY ON
MOV AX,SI ;SEE HOW MANY SEGMENTS ARE
MOV CL,4 ;...IN SI (SI DIV 4)
SHR AX,CL
MOV CX,DS ;ADD THEM TO THE DATA SEGMENT
ADD CX,AX ;...(YOU CAN'T JUST ADD DS,AX)
MOV DS,CX
AND SI,000FH ;ADJUST SI (SI MOD 16)
UPDATE2: POP CX ;GET COUNT BACK
LOOP UPDATE1 ;DECREMENT AND LOOP
POP ES
POP DS
ADD SP,UPDATE_ADJUST
POP BP
RETF
;THIS ROUTINE DISPLAYS A SINGLE MONOCHROME LINE
;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO THE LINE
;THE SECOND ARGUMENT IS THE LINE NUMBER
;THE THIRD ARGUMENT IS THE WIDTH OF THE BITMAP (IN BYTES)
MONO_LINE:
PUSH BP
MOV BP,SP
PUSH DS
PUSH ES
MOV AX,cs:V_MONOSCRNSEG ;POINT TO THE SCREEN
MOV ES,AX
MOV CX,[BP + _AOFF + 6] ;GET THE WIDTH OF MOVE
CMP CX,0
JE MONO_LINE2
CMP CX,cs:V_MONOBYTES
JL MONO_LINE1
MOV CX,cs:V_MONOBYTES
MONO_LINE1: MOV SI,[BP + _AOFF + 0] ;OFFSET OF BITMAP
MOV DS,[BP + _AOFF + 2] ;SEGMENT OF BITMAP
MOV BX,[BP + _AOFF + 4] ;NUMBER OF LINE
mov al,cs:[Row_seg+bx]
call select_write_seg
SHL BX,1
CLD ;CLEAR DIRECTION FLAG
MOV DI,CS:[SCREENTABLE + BX]
shr cx,1 ; convert to word moves
jc >l3
rep movsw
jmp >l4
l3:
rep movsw
movsb
l4:
MONO_LINE2: POP ES
POP DS
POP BP
RETF
; this routine selects text mode
VGA_off:
EGA_off:
Mono_off:
mov ax,0003h
int 10h
retf
;
;
; this is the installation routine
Install:
jmp cs:[Install_Pointer]
Install_it:
call find_chip
call find_mem_size
mov ax,near_return
mov cs:Install_Pointer,ax
; test for gray scale summing
mov ax,1b00h
mov es,cs
mov di,screentable
mov bx,0
int 10h
mov al,es:[screentable+2dh]
and al,00000010xb
mov cs:gray_VGA,al
ret
;
even
Install_Pointer dw Install_it
;
; these are the segment selection routines
select_write_seg_a dw select_4_write_seg
select_read_seg_a dw select_4_read_seg
;
select_write_seg:
jmp cs:[select_write_seg_a]
;
select_read_seg:
jmp cs:[select_read_seg_a]
;
select_no_segment_mode:
push ax
mov ax,near_return
mov cs:select_write_seg_a,ax
mov cs:select_read_seg_a,ax
pop ax
near_return:
ret
;
select_3_mode:
push ax
mov ax,select_3_write_seg
mov cs:select_write_seg_a,ax
mov ax,select_3_read_seg
mov cs:select_read_seg_a,ax
pop ax
ret
;
select_4_mode:
push ax
mov ax,select_4_write_seg
mov cs:select_write_seg_a,ax
mov ax,select_4_read_seg
mov cs:select_read_seg_a,ax
pop ax
ret
;
GDC_seg_sel equ 03cdh
;
select_3_write_seg:
push ax,dx
and al,7
mov ah,al
mov dx,GDC_seg_sel
in al,dx
and al,00111000xb
or al,01000000xb
or al,ah
out dx,al
pop dx,ax
ret
;
select_3_read_seg:
push ax,dx
and al,7
mov ah,al
mov dx,GDC_seg_sel
in al,dx
and al,00000111xb
or al,01000000xb
shl ah,1
shl ah,1
shl ah,1
or al,ah
out dx,al
pop dx,ax
ret
;
select_4_write_seg:
push ax,dx
and al,0fh
mov ah,al
mov dx,GDC_seg_sel
in al,dx
and al,0f0h
or al,ah
out dx,al
pop dx,ax
ret
;
select_4_read_seg:
push ax,dx
and al,0fh
mov ah,al
mov dx,GDC_seg_sel
in al,dx
and al,0fh
shl ah,1
shl ah,1
shl ah,1
shl ah,1
or al,ah
out dx,al
pop dx,ax
ret
;
; these routines test chip type and memory size
fill_seg_test:
push cx
mov cx,80h ; use 128 bytes to flush the cache
mov di,0
cld
rep stosb
pop cx
ret
;
; returns 0123h in ax if segments are selecting properly
test_for_memory:
push bx,cx,dx,es,di
mov ax,TLI_screenseg
mov es,ax
l1:
call select_write_seg
call fill_seg_test
inc al
cmp al,3
jng l1
mov al,0
call select_read_seg
mov bl,es:[0] ;segment 0
inc al
call select_read_seg
mov bh,es:[0] ;segment 1
inc al
call select_read_seg
mov dl,es:[0] ;segment 2
inc al
call select_read_seg
mov dh,es:[0] ;segment 3
mov cx,4
shl bl,cl
or bh,bl
mov cx,4
shl dl,cl
or dh,dl
mov ah,bh
mov al,dh
pop di,es,dx,cx,bx
ret
;
find_chip:
mov ax,002dh ; a common mode that uses more than 64k
int 10h
call select_3_mode
call test_for_memory
cmp ax,0123h
jne >l1
; chip is an ET3000
mov ax,cs:[VGA_lock_table+2]
cmp ax,400
jne >l3
mov ax,350
mov cs:[VGA_lock_table+2],ax
mov ax,2dh
mov cs:[VGA_lock_table+8],ax
l3:
mov ax,cs:[VGA_mode_table+12]
cmp ax,400
jne >l3
mov ax,350
mov ax,cs:[VGA_mode_table+12]
mov ax,2dh
mov cs:[VGA_mode_table+18],ax
l3:
jmp >l2
l1:
call select_4_mode
call test_for_memory
cmp ax,0123h
jne >l1
; chip is an ET4000
jmp >l2
l1:
; chip type is unknown select no paging
call select_no_segment_mode
l2:
ret
;
; this routine finds the memory size on the card
; for 1024k check page F
; 512k page 7
; 256k page 3
; 64k page 0 (assumed if other pages aren't there)
find_mem_size:
push ds,es
mov ds,cs
mov ax,TLI_screenseg
mov es,ax
mov ax,000fh
mov cx,ax
l1:
call select_write_seg
call fill_seg_test
dec al
cmp al,0ffh
loop l1
mov al,0fh
call select_read_seg
mov bl,es:[0]
cmp bl,0fh
jne >l1
mov bl,3
jmp >l5
l1:
mov al,7
call select_read_seg
mov bl,es:[0]
cmp bl,7
jne >l1
mov bl,2
jmp >l5
l1:
mov al,3
call select_read_seg
mov bl,es:[0]
cmp bl,3
jne >l1
mov bl,1
jmp >l5
l1:
mov bl,0
l5:
mov ax,Installed
mov al,bl
mov Installed,ax
pop es,ds
ret
;
;
;this part goes through all available modes to try to find one that is
; larger than the picture or the same size as the picture.
pick_mode:
mov di,si
l3:
cmp ax,[si]
ja >l1
cmp bx,[si+2]
jbe >l2
l1:
add si,10
cmp w[si],0
jne l3
sub si,10
l2:
; this part goes backwards through the list of modes to make sure the card
; and monitor can handle the mode. if the lock mode is something that
; the hardware can't handle, the mode defaults to the first mode in the
; table
mov cx,Installed
sub dx,dx
mov dl,ch ; cx is memory available
mov ch,dh ; dx is the monitor
l2:
cmp cx,[si+4]
jl >l1
cmp dx,3
je >l4 ; any mode monitor
cmp dx,[si+6]
je >l4 ; monitor and required are the same
cmp w[si+6],0
je >l4 ; VGA monitor is all that's needed
; this lets an 8514 monitor select the 1024x768 mode if the picture
; requires an 800x600 mode
cmp dx,2
jne >l1 ;not an 8514 monitor
cmp w[si+6],1
jne >l1 ;not 800x600 mode
cmp cx,[si+16]
jne >l1 ;insufficient memory for 1024x768 mode
add si,10
jmp >l4 ;select next mode in table
l1:
cmp di,si
jne >l1 ;not a lock mode
add si,12 ;change from lock mode to first mode in table
jmp >l4
l1:
sub si,10
jmp l2
l4:
mov ax,[si]
mov bx,[si+2]
mov cx,[si+8]
ret
;
even
;THIS IS A LINE START LOOKUP TABLE
SCREENTABLE: DW TLI_DEEP DUP(?) ;LINE START TABLE
Row_seg: db TLI_deep dup(?) ;segments for the lines
;These are the modes supported. the tables have the format:
; columns,rows,memory,monitor,mode
; where memory is 0 64k standard VGA
; 1 256k
; 2 512k
; 3 1024k
;
; and monitor is 0 standard VGA
; 1 800x600 capable Multisync
; 2 1024x768 interlace capable 8514 equivalent
; 3 1024x768 interlace capable multisync
;
Mode_Pointer:
VGA_mode_pointer dw VGA_mode_table
EGA_mode_pointer dw EGA_mode_table
Mono_mode_pointer dw Mono_mode_table
VGA_lock_table:
dw 320,200,0,0,13h
dw 0
VGA_mode_table:
dw 320,200,0,0,13h
dw 640,400,1,0,2fh ; 640,350,1,0,2DH for ET3000
dw 640,480,2,0,2eh
dw 800,600,2,1,30h
dw 1024,768,3,2,38h
dw 0
EGA_lock_table:
dw 640,480,0,0,12h
dw 0
EGA_mode_table:
dw 320,200,0,0,0dh
dw 640,200,0,0,0eh
dw 640,350,0,0,10h
dw 640,480,0,0,12h
dw 800,600,1,1,29h
dw 1024,768,2,2,37h
dw 0
Mono_lock_table:
dw 640,480,0,0,11h
dw 0
Mono_mode_table:
dw 320,200,0,0,0dh
dw 640,200,0,0,0eh
dw 640,350,0,0,10h
dw 640,480,0,0,11h
dw 800,600,1,1,29h
dw 1024,768,2,2,37h
dw 0