home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
screen
/
advid105.arc
/
AD_VIDEO.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-04-12
|
33KB
|
1,347 lines
PAGE 60,132
TITLE ad_video.sys version 1.05 April 12, 1989
;
; Copyright (c) Andan Software 1989
;
; This SYS-program replace some of the BIOS Video routines so video access
; from other program goes faster.
;
; It is loaded as an installable device driver with the
; command 'device=ad_video.sys' in the config.sys file.
;
;
; Shareware: This source code may be copied if no fee is charged and if no
; changes are done, for educate purposes only.
;
;
; Please help us distribute AD_VIDEO by copying it in it's unmodified
; form. Please make a contribution to us for using this program. We
; recommend a contribution of $10 for students, $20 for private use and
; $40 for companies. Send an international check or money order to:
;
; Seffle Instrument AB
; P.O. Box 25
; S-661 00 SÄFFLE
; SWEDEN
;
; Telephone +46 533 17250
;
; Mark the payment with "AnDan Software Video BIOS Version 1.05".
; You may use Visa or MasterCard if you write a letter with your
; payment, card number, expiration date, and your signature.
;
; For Swedish users: Telefon: 0533-17250
; Postgiro: 509517-9
; Bankgiro: 720-6733
;
;
;
;
;
;
; Revision history:
;
; Vers: Date: Comments:
;
; 1.00 890402 First release
; 1.01 890403 Set cursor position corrected when setting in non-
; active page. Write TTY corrected, didn't handle
; attributes right. Some smaller optimations have been
; done.
; 1.02 890405 Set cursor position corrected, again.
; The video position wasn't calculated correctly for
; other pages than page 0.
; The vidoe memory position is calculated only in
; the setcur function. Due to some badly written programs
; like ProComm Plus, two cursor savings are needed.
; 1.03 890408 Fixed calculation to work with more than 25 lines on
; other videopages than page zero. To use this a label
; must be defined, se below.
; 1.04 890410 The BIOS funtions scroll up and down have been
; implemented.
; 1.05 890412 Scroll up/down did only handle one row at time.
; Write teletype optimized better.
;
;
;
;
; Syntax:
;
; device=[path]ad_video.sys [/w] [/bNNNN] [/d]
;
; /w Waits before each video memory access, used to prevent "snow"
; This option is valid only for when 'ega' is undefined, see below
; /bNNNN Loop value NNNN to be used with the Bell, default 800
; /d Use DOS to set new value to interrupt table
;
;
; Use MASM with the following options to produce different styles
; of ad_video.sys:
;
; /dwaitio Waits are inserted after all I/O accesses
; /dwideio 16 bits I/O is used whenever possible
; /dega More then 25 lines are supported, /w option not available
; May be used only on EGA or VGA cards
;
;
; AD_VIDEO.SYS replaces the following Video BIOS functions:
;
; 2 Set cursor position
; 3 Read cursor position
; 6 Scroll active page up
; 7 Scroll active page down
; 8 Read attribute/character at cursor
; 9 Write attribute/character at cursor
; 10 Write character at cursor
; 14 Write teletype to active page
;
; AD_VIDEO.SYS should be loaded before any programs that filters and uses
; these functions.
;
;
; AD_VIDEO.SYS filters the following Video BIOS functions:
;
; 0 Set video mode
;
;
;
;
; Equates and macros for different styles of the program
;
io_wait MACRO
ifdef waitio
jmp $+2
endif
ENDM
bios SEGMENT AT 0
ASSUME ds:bios
ORG 410H
equip_flag DW ?
ORG 449H
crt_mode DB ?
crt_cols DW ?
crt_len DW ?
crt_start DW ?
cursor_posn DW 8 DUP(?)
cursor_mode DW ?
active_page DB ?
addr_6845 DW ?
crt_mode_set DB ?
crt_palette DB ?
bios ENDS
sys SEGMENT PARA PUBLIC 'CODE'
ASSUME cs:sys,ds:sys,ss:nothing,es:nothing
;
;
; Device handling
;
;
next_off DW -1
next_seg DW -1
DW 1000000000000000B
DW stategy ;Strategy entry point
intp DW interrupt ;Interrupt entry point
DB '$ADVIDEO' ;8 byte character device name or
;number of units
ptr_cmd DD ?
stategy PROC FAR
mov WORD PTR cs:[ptr_cmd],bx
mov WORD PTR cs:[ptr_cmd+2],es
ret
stategy ENDP
;
;
; New Interrupt entry point (after initialization):
;
newint PROC FAR
push ds
push bx
lds bx,cs:[ptr_cmd]
mov WORD PTR ds:[bx+03],8002H
pop bx
pop ds
ret
newint ENDP
;
;
; Resident code and data
;
;
wait_mode DB 0
dos_mode DB 0
bell_loop DW 800
video_mem DW 0B800H
functablep DW OFFSET functable1
mem_pos DW 8 DUP(?)
cur_pos DW 8 DUP(?) ;This is needed due to bad programs
ASSUME cs:sys,ds:bios,ss:nothing,es:nothing
;
; New INT 10H routine
;
int10h PROC FAR
sti
push ds
push bx
xor bx,bx
mov ds,bx
cmp ah,19
ja jump_bios
mov bl,ah
shl bl,1
add bx,cs:[functablep]
jmp cs:[bx]
int10h ENDP
jump_bios: pop bx
pop ds
DB 0EAH ;Jump far direct
old10h_o DW 0
old10h_s DW 0
functable1 DW OFFSET func00 ;00 Set videmode
DW OFFSET jump_bios ;01 Set cursor type
DW OFFSET jump_bios ;02 Set cursor position
DW OFFSET jump_bios ;03 Read cursor position
DW OFFSET jump_bios ;04 Read light pen position
DW OFFSET jump_bios ;05 Select active display page
DW OFFSET jump_bios ;06 Scroll active page up
DW OFFSET jump_bios ;07 Scroll active page down
DW OFFSET jump_bios ;08 Read attribute/character at cursor
DW OFFSET jump_bios ;09 Write attribute/character at cursor
DW OFFSET jump_bios ;10 Write character at cursor
DW OFFSET jump_bios ;11 Set color palette
DW OFFSET jump_bios ;12 Write dot
DW OFFSET jump_bios ;13 Read dot
DW OFFSET jump_bios ;14 Write teletype to active page
DW OFFSET jump_bios ;15 Current video state
DW OFFSET jump_bios ;16 Set palette registers
DW OFFSET jump_bios ;17 Character generator
DW OFFSET jump_bios ;18 Reserved
DW OFFSET jump_bios ;19 Write string
functable2 DW OFFSET func00 ;00 Set videmode
DW OFFSET jump_bios ;01 Set cursor type
DW OFFSET func02 ;02 Set cursor position
DW OFFSET func03 ;03 Read cursor position
DW OFFSET jump_bios ;04 Read light pen position
DW OFFSET jump_bios ;05 Select active display page
DW OFFSET func06 ;06 Scroll active page up
DW OFFSET func07 ;07 Scroll active page down
DW OFFSET func08 ;08 Read attribute/character at cursor
DW OFFSET func09 ;09 Write attribute/character at cursor
DW OFFSET func10 ;10 Write character at cursor
DW OFFSET jump_bios ;11 Set color palette
DW OFFSET jump_bios ;12 Write dot
DW OFFSET jump_bios ;13 Read dot
DW OFFSET func14 ;14 Write teletype to active page
DW OFFSET jump_bios ;15 Current video state
DW OFFSET jump_bios ;16 Set palette registers
DW OFFSET jump_bios ;17 Character generator
DW OFFSET jump_bios ;18 Reserved
DW OFFSET jump_bios ;19 Write string
;
; beep
;
; ax,cx,dx destroyed
;
beep PROC NEAR
mov al,10110110B
out 43H,al
jmp $+2
mov al,33H
out 42H,al
jmp $+2
mov al,05H
out 42H,al
jmp $+2
in al,61H
jmp $+2
mov ah,al
or al,3
out 61H,al
mov cx,cs:[bell_loop]
beep1: xor al,al
beep2: dec al
jnz beep2
loop beep1
mov al,ah
out 61H,al
ret
beep ENDP
;
; setcur
;
; in: bh = display page
; dx = cursor position
; ds = 0
;
; ax,bx,cx,dx destroyed
;
;
; Calculates current position for Alpha 80x25 modes:
;
; pos = page*[crt_len]+(row*80+col)*2
;
setcur PROC NEAR
ifdef ega
xor al,al
mov ah,dh ;AX = row * 256
shr ax,1 ;AX = row * 128
shr ax,1 ;AX = row * 64
mov cx,ax
shr ax,1 ;AX = row * 32
shr ax,1 ;AX = row * 16
add ax,cx ;AX = row * 16 + row * 64 = row * 80
mov cl,dl
xor ch,ch
add ax,cx ;AX = row * 80 + col
shl ax,1 ;AX = (row * 80 + col) * 2
mov cx,ax
mov bl,bh
xor bh,bh
mov ax,bx
shl bl,1 ;BX = page * 2
mov [bx+OFFSET cursor_posn],dx
mov cs:[bx+OFFSET cur_pos],dx ;This is needed due to bad programs
mul [crt_len] ;DX:AX = page * [crt_len] (DX assumed to be zero)
add ax,cx
mov cs:[bx+OFFSET mem_pos],ax
shr bl,1
cmp bl,[active_page]
jnz setcur1
else
;
; Old method, didn't handle more then 25 rows for other pages than zero
;
; pos = page*4096+(row*80+col)*2 =
; = (page*2048+row*80+col)*2 =
; = ((page*256+row*10)*8+col)*2
;
mov cx,2
mov al,dh ;AL = row
shl al,cl ;AL = row * 4
add al,dh ;AL = row * 4 + row = row * 5
xor ah,ah
shl ax,1 ;AX = row * 10
add ah,bh ;AX = page * 256 + row * 10
inc cl
shl ax,cl ;AX = (page * 256 + row * 10) * 8
mov cl,dl
add ax,cx ;AX = (page * 256 + row * 10) * 8 + col
shl ax,1 ;AX = (page * 2048 + row * 80 + col) * 2
mov cl,bh ;CX = page
mov bx,cx
shl bl,1 ;BX = page * 2
mov [bx+OFFSET cursor_posn],dx
mov cs:[bx+OFFSET cur_pos],dx ;This is needed due to bad programs
mov cs:[bx+OFFSET mem_pos],ax
cmp cl,[active_page]
jnz setcur1
endif
mov bx,ax
mov dx,[addr_6845]
shr bx,1
ifdef wideio
mov al,0EH
mov ah,bh
out dx,ax
io_wait
inc al
mov ah,bl
out dx,ax
else
mov al,0EH
out dx,al
io_wait
inc dx
mov al,bh
out dx,al
io_wait
dec dx
mov al,0FH
out dx,al
io_wait
inc dx
mov al,bl
out dx,al
endif
setcur1: ret
setcur ENDP
;
;
; Calculation macro, used when cursor position is changed by programs without
; calling BIOS.
;
;
calcpos MACRO
ifdef ega
xor al,al
mov ah,dh ;AX = row * 256
shr ax,1 ;AX = row * 128
shr ax,1 ;AX = row * 64
mov cx,ax
shr ax,1 ;AX = row * 32
shr ax,1 ;AX = row * 16
add ax,cx ;AX = row * 16 + row * 64 = row * 80
mov cl,dl
xor ch,ch
add ax,cx ;AX = row * 80 + col
shl ax,1 ;AX = (row * 80 + col) * 2
mov cx,ax
mov cs:[bx+OFFSET cur_pos],dx ;This is needed due to bad programs
mov ax,bx
shr ax,1
mul [crt_len] ;DX:AX = page * [crt_len] (DX assumed to be zero)
add ax,cx
mov cs:[bx+OFFSET mem_pos],ax
mov bx,ax
else
;
; Old method, didn't handle more then 25 rows for other pages than zero
;
mov cx,2
mov al,dh ;AL = row
shl al,cl ;AL = row * 4
add al,dh ;AL = row * 4 + row = row * 5
xor ah,ah
shl ax,cl ;AX = row * 20
add ah,bl ;AX = page * 512 + row * 20
shl ax,cl ;AX = (page * 512 + row * 20) * 4
mov cl,dl
add ax,cx ;AX = (page * 512 + row * 20) * 4 + col
shl ax,1 ;AX = (page * 2048 + row * 80 + col) * 2
mov cs:[bx+OFFSET cur_pos],dx
mov cs:[bx+OFFSET mem_pos],ax
mov bx,ax
endif
ENDM
init_pos PROC NEAR
mov bx,OFFSET functable1
mov al,[crt_mode]
cmp al,07H
jz init_pos1
cmp al,02H
jb init_pos3
cmp al,03H
ja init_pos3
init_pos1: xor cx,cx
init_pos2: push cx
mov bx,cx
shl bl,1
mov dx,[bx+OFFSET cursor_posn]
mov bh,cl
call setcur
pop cx
inc cl
cmp cl,8
jc init_pos2
mov bx,OFFSET functable2
init_pos3: mov cs:[functablep],bx
ret
init_pos ENDP
;00 Set videmode
func00: pop bx
pushf
call DWORD PTR cs:[old10h_o]
push ax
push bx
push cx
push dx
call init_pos
pop dx
pop cx
pop bx
pop ax
pop ds
iret
;02 Set cursor position
func02: pop bx
push ax
push bx
push cx
push dx
call setcur
pop dx
pop cx
pop bx
pop ax
pop ds
iret
;03 Read cursor position
func03: pop bx
mov cx,bx
mov bl,bh
xor bh,bh
shl bl,1
mov dx,[bx+OFFSET cursor_posn]
mov bx,cx
mov cx,[cursor_mode]
pop ds
iret
;08 Read attribute/character at cursor
func08: pop bx
push bx
push dx
push es
;
; Read char
;
; in: bh = page
;
; out: al = char
; ah = attribute
;
; bx,dx,es destroyed
;
mov dx,cs:[video_mem]
mov es,dx
mov bl,bh
xor bh,bh
shl bl,1
mov dx,[bx+OFFSET cursor_posn] ;This is needed due to bad programs
cmp dx,cs:[bx+OFFSET cur_pos] ;This is needed due to bad programs
jnz rcharcalc ;This is needed due to bad programs
mov bx,cs:[bx+OFFSET mem_pos]
rchar0:
ifndef ega
cmp cs:[wait_mode],0
jnz rchar2
endif
mov ax,es:[bx]
rchar1: pop es
pop dx
pop bx
pop ds
iret
ifndef ega
rchar2: mov ah,1
mov dx,3DAH
rchar3: in al,dx
test al,ah
jnz rchar3
cli
rchar4: in al,dx
test al,ah
jz rchar4
mov ax,es:[bx]
sti
jmp rchar1
endif
rcharcalc: push cx
calcpos
pop cx
jmp rchar0
;09 Write attribute/character at cursor
func09: pop bx
push ax
push bx
push cx
push dx
push es
mov ah,bl
;
; Write char and attribut
;
; in: bh = page
; al = char
; ah = attribute
; cx = count
;
; bx,cx,dx,es destroyed
;
mov dx,cs:[video_mem]
mov es,dx
mov bl,bh
xor bh,bh
shl bl,1
mov dx,[bx+OFFSET cursor_posn] ;This is needed due to bad programs
cmp dx,cs:[bx+OFFSET cur_pos] ;This is needed due to bad programs
jnz wachrcalc ;This is needed due to bad programs
mov bx,cs:[bx+OFFSET mem_pos]
wachr0:
ifndef ega
cmp cs:[wait_mode],0
jnz wachr3
endif
wachr1: mov es:[bx],ax
add bx,2
loop wachr1
wachr2: pop es
pop dx
pop cx
pop bx
pop ax
pop ds
iret
ifndef ega
wachr3: push ax
mov ah,1
mov dx,3DAH
wachr4: in al,dx
test al,ah
jnz wachr4
cli
wachr5: in al,dx
test al,ah
jz wachr5
pop ax
mov es:[bx],ax
sti
add bx,2
loop wachr3
jmp wachr2
endif
wachrcalc: push ax
push cx
calcpos
pop cx
pop ax
jmp wachr0
;10 Write character at cursor
func10: pop bx
push ax
push bx
push cx
push dx
push es
;
; Write char
;
; in: bh = page
; al = char
; cx = count
;
; bx,cx,dx,es destroyed
;
mov dx,cs:[video_mem]
mov es,dx
mov bl,bh
xor bh,bh
shl bl,1
mov dx,[bx+OFFSET cursor_posn] ;This is needed due to bad programs
cmp dx,cs:[bx+OFFSET cur_pos] ;This is needed due to bad programs
jnz wcharcalc ;This is needed due to bad programs
mov bx,cs:[bx+OFFSET mem_pos]
wchar0:
ifndef ega
cmp cs:[wait_mode],0
jnz wchar3
endif
wchar1: mov es:[bx],al
add bx,2
loop wchar1
wchar2: pop es
pop dx
pop cx
pop bx
pop ax
pop ds
iret
ifndef ega
wchar3: push ax
mov ah,1
mov dx,3DAH
wchar4: in al,dx
test al,ah
jnz wchar4
cli
wchar5: in al,dx
test al,ah
jz wchar5
pop ax
mov es:[bx],al
sti
add bx,2
loop wchar3
jmp wchar2
endif
wcharcalc: push ax
push cx
calcpos
pop cx
pop ax
jmp wchar0
;
; scroll
;
; in: ax = Value to add to si and di for next row
; bh = Attribute on blanked line
; bl = Number of rows to scroll
; dh = Number of rows
; dl = Number of columns
; di = Destination address in video memory
; si = Source address in video memory
;
; ax,bx,cx,dx,di,si,es,ds destroyed
;
scroll PROC NEAR
ifndef ega
cmp cs:[wait_mode],0
jz scroll0b
push dx
mov cx,ax
mov dx,3DAH
scroll0a: in al,dx
test al,8
jz scroll0a
mov al,25H
mov dx,3D8H
out dx,al
mov ax,cx
pop dx
scroll0b:
endif
mov cx,cs:[video_mem]
mov es,cx
mov ds,cx
xor ch,ch
cld
and bl,bl
jz scroll4
sub dh,bl
jz scroll2
scroll1: mov cl,dl
rep movsw
add di,ax
add si,ax
dec dh
jnz scroll1
scroll2: xchg ax,bx
mov dh,al
mov al,32
scroll3: mov cl,dl
rep stosw
add di,bx
dec dh
jnz scroll3
ifndef ega
cmp cs:[wait_mode],0
jz scroll3a
xor ax,ax
mov ds,ax
mov al,[crt_mode_set]
mov dx,3D8H
out dx,al
scroll3a:
endif
ret
scroll4: mov bl,dh
jmp scroll2
scroll ENDP
;06 Scroll active page up
func06: pop bx
push ax
push bx
push cx
push dx
push si
push di
push es
mov bl,al
mov ah,al
xor al,al ;AX = rows * 256
shr ax,1 ;AX = rows * 128
mov si,ax
shr ax,1 ;AX = rows * 64
shr ax,1 ;AX = rows * 32
add si,ax ;SI = rows * 160
xor al,al
mov ah,ch ;AX = row * 256
shr ax,1 ;AX = row * 128
shr ax,1 ;AX = row * 64
mov di,ax
shr ax,1 ;AX = row * 32
shr ax,1 ;AX = row * 16
add ax,di ;AX = row * 16 + row * 64 = row * 80
add al,cl
adc ah,0 ;AX = row * 80 + col
shl ax,1 ;AX = (row * 80 + col) * 2
add ax,[crt_start]
mov di,ax
add si,ax
sub dx,cx
inc dh
inc dl
mov al,80
sub al,dl
cbw ;Due to bugs in other programs
shl ax,1
call scroll
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop ds
iret
;07 Scroll active page down
func07: pop bx
push ax
push bx
push cx
push dx
push si
push di
push es
mov bl,al
mov ah,al
xor al,al ;AX = rows * 256
shr ax,1 ;AX = rows * 128
mov si,ax
shr ax,1 ;AX = rows * 64
shr ax,1 ;AX = rows * 32
add si,ax ;SI = rows * 160
xor al,al
mov ah,dh ;AX = row * 256
shr ax,1 ;AX = row * 128
shr ax,1 ;AX = row * 64
mov di,ax
shr ax,1 ;AX = row * 32
shr ax,1 ;AX = row * 16
add ax,di ;AX = row * 16 + row * 64 = row * 80
add al,cl
adc ah,0 ;AX = row * 80 + col
shl ax,1 ;AX = (row * 80 + col) * 2
add ax,[crt_start]
mov di,ax
sub ax,si
mov si,ax
sub dx,cx
inc dh
inc dl
mov ax,80
add al,dl
shl ax,1
neg ax
call scroll
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop ds
iret
;14 Write teletype to active page
wttycalc: push ax
push cx
ifdef ega
push dx
endif
calcpos
ifdef ega
pop dx
endif
pop cx
pop ax
jmp SHORT w_tty1
ifndef ega
w_tty2: push ax
push dx
mov ah,1
mov dx,3DAH
w_tty3: in al,dx
test al,ah
jnz w_tty3
cli
w_tty4: in al,dx
test al,ah
jz w_tty4
pop dx
pop ax
mov es:[bx],al
sti
jmp SHORT w_tty5
endif
func14_bell: push cx
call beep
pop cx
jmp func14ret
func14_bs: and dl,dl
jz func14ret
dec dl
sub bx,2
jmp SHORT func14c1
func14: pop bx
push ax
push bx
push dx
push si
push es
mov dx,cs:[video_mem]
mov es,dx
mov bl,[active_page]
xor bh,bh
shl bl,1
mov si,bx
mov dx,[si+OFFSET cursor_posn]
cmp dx,cs:[si+OFFSET cur_pos] ;This is needed due to bad programs
jnz wttycalc ;This is needed due to bad programs
mov bx,cs:[si+OFFSET mem_pos]
w_tty1: cmp al,8
jz func14_bs
cmp al,13
jz func14_cr
cmp al,10
jz func14_lf
cmp al,7
jz func14_bell
ifndef ega
cmp cs:[wait_mode],0
jnz w_tty2
endif
mov es:[bx],al
w_tty5: inc dl
cmp dl,80
jae func14nl
add bx,2
func14c1: mov [si+OFFSET cursor_posn],dx
mov cs:[si+OFFSET cur_pos],dx ;This is needed due to bad programs
func14c2: mov cs:[si+OFFSET mem_pos],bx
mov dx,[addr_6845]
shr bx,1
ifdef wideio
mov al,0EH
mov ah,bh
out dx,ax
io_wait
inc al
mov ah,bl
out dx,ax
else
mov al,0EH
out dx,al
io_wait
inc dx
mov al,bh
out dx,al
io_wait
dec dx
mov al,0FH
out dx,al
io_wait
inc dx
mov al,bl
out dx,al
endif
func14ret: pop es
pop si
pop dx
pop bx
pop ax
pop ds
iret
func14_cr: mov al,dl
xor ah,ah
shl ax,1
sub bx,ax
xor dl,dl
jmp SHORT func14c1
func14_lf1: inc dh
add bx,160
jmp SHORT func14c1
func14nl: xor dl,dl
sub bx,79*2
func14_lf: cmp dh,24
jb func14_lf1
mov [si+OFFSET cursor_posn],dx
mov cs:[si+OFFSET cur_pos],dx ;This is needed due to bad programs
push si
push di
push cx
mov di,[crt_start]
mov si,di
add si,160
mov ax,es
mov ds,ax
cld
mov cx,80*24
ifndef ega
cmp cs:[wait_mode],0
jz scrllx0b
mov dx,3DAH
scrllx0a: in al,dx
test al,8
jz scrllx0a
mov al,25H
mov dx,3D8H
out dx,al
scrllx0b:
endif
mov ah,es:[bx+1]
mov al,32
rep movsw
mov cl,80
rep stosw
xor ax,ax
mov ds,ax
ifndef ega
cmp cs:[wait_mode],0
jz scrllx3a
mov al,[crt_mode_set]
mov dx,3D8H
out dx,al
scrllx3a:
endif
pop cx
pop di
pop si
jmp func14c2
endofprog EQU $
ASSUME cs:sys,ds:sys,ss:nothing,es:nothing
;
;
; Interrupt entry point of the device driver:
;
interrupt PROC FAR
pushf
push ds
push es
push si
push di
push bp
push ax
push bx
push cx
push dx
lds bx,cs:[ptr_cmd]
mov al,ds:[bx+02]
and al,al
jnz no_init
jmp init
no_init: mov WORD PTR ds:[bx+03],8002H
intret: pop dx
pop cx
pop bx
pop ax
pop bp
pop di
pop si
pop es
pop ds
popf
ret
interrupt ENDP
asc_dec: xor ax,ax
mov cx,10
mov bh,ch
asc_dec1: mov bl,es:[si]
sub bl,'0'
jb asc_dec2
cmp bl,10
jae asc_dec2
mul cx
add ax,bx
inc si
jmp asc_dec1
asc_dec2: ret
;
;
; Initialization of device driver
;
;
; Note, Only 6 words left on stack !!
; No MS-DOS calls are allowed, except 01H to 0CH and 30H !!
;
text1 DB 13,10,10,'AnDan Software Video BIOS Version 1.05',13,10,10,'$'
text2 DB 7,'WRONG ARGUMENT TO AD_VIDEO.SYS !!',13,10,'$'
init: mov ax,OFFSET endofprog
mov ds:[bx+14],ax ;End address offset
mov ds:[bx+16],cs ;End address segment
mov WORD PTR ds:[bx+03],0100H
mov si,[bx+18]
mov ax,[bx+20]
mov es,ax
mov ax,cs
mov ds,ax
cld
mov ax,OFFSET newint
mov [intp],ax
mov dx,OFFSET text1
mov ah,09H
int 21H
init1: lods BYTE PTR es:[si]
cmp al,' '
ja init1
jb init7
init2: lods BYTE PTR es:[si]
cmp al,' '
jz init2
jb init7
cmp al,'/'
jnz init6
lods BYTE PTR es:[si]
ifndef ega
cmp al,'W'
jz init4
cmp al,'w'
jz init4
endif
cmp al,'D'
jz init5
cmp al,'d'
jz init5
cmp al,'B'
jz init3
cmp al,'b'
jnz init6
init3: call asc_dec
mov [bell_loop],ax
jmp init2
ifndef ega
init4: mov [wait_mode],1
jmp init2
endif
init5: mov [dos_mode],1
jmp init2
init6: mov dx,OFFSET text2
mov ah,09H
int 21H
;
; Initialize resident code
;
init7: xor ax,ax
mov es,ax
ASSUME es:bios
mov ax,es:[equip_flag]
and al,30H
cmp al,30H
jnz init7a
mov [video_mem],0B000H
init7a: mov ax,3510H
int 21H
mov [old10h_o],bx
mov ax,es
mov [old10h_s],ax
cmp [dos_mode],0
jnz init8
xor ax,ax
mov es,ax
mov ax,cs
cli
mov es:[10H*4+2],ax
mov WORD PTR es:[10H*4],OFFSET int10h
sti
jmp SHORT init9
init8: mov ax,2510H
mov dx,OFFSET int10h
int 21H
init9: xor ax,ax
mov ds,ax
call init_pos
jmp intret
sys ENDS
END