dos_compilers/Mix Power C v1/SCREEN.ASM

1572 lines
46 KiB
NASM
Raw Normal View History

2024-07-02 00:26:34 +02:00
;
; Low level graphics functions
;
; Copyright (c) Mix Software 1988
;
global
LONGNAME equ >FFFF
SHORTNAME equ >FFFF
PARM1 equ 6
HERCMODE equ 99
HRES equ 6
GBW equ 4
GCOLOR equ 5
MONO equ 7
PENCOLOR equ >FF
TRANSPAR equ >FE
endglobal
include fillm.asm
;
; ------------------------------------------------------------
;
; Clear the screen
; clrscrn2(attribute)
; unsigned int attribute;
;
idt clrscrn2
def clrscrn2
fref getvmode
fref setvmode
fref crt_lock
lfref crt_unlock
dref _vapage
dref _vusemem
;
attrib equ PARM1
;
clrscrn2 push bp
mov bp,sp
callfar getvmode
cmp al,GBW
jb text
cmp al,MONO
jnz graphic
text mov ax,>0600
xor cx,cx
mov bh,[bp][%attrib]
mov dx,>184f
int >10
xor dx,dx ; set cursor to 0,0
mov bh,%[_vapage]
mov ah,2
int >10
pop bp
retfar
graphic cmp al,HERCMODE
jz clrherc
cmp [_vusemem],0
jz nomem
cmp al,HRES
jz clrhres
cmp al,GBW
jz clrlres
cmp al,GCOLOR
jz clrlres
nomem push ax ; save current mode
; mov ax,MONO ; set to text format
; push ax
; callfar setvmode ; reset to previous mode
; pop ax
; mov ax,>0600 ; clear with bios scroll
; xor cx,cx
; mov bh,[bp][%attrib]
; mov dx,>184f
; int >10
callfar setvmode
add sp,%2
pop bp
retfar
clrherc callfar crt_lock
cmp [_vapage],0
jnz page1
mov ax,>b000
jmps herc1
page1 mov ax,>b800
herc1 mov es,ax
mov cx,>4000
onebit xor ax,ax
test %[bp][%attrib],%1 ; white or black
jz clear
dec ax ; set to all 1
clear xor di,di
cld
rep
stosw
callfar crt_unlock
pop bp
retfar
clrhres callfar crt_lock
mov ax,>b800
mov es,ax
mov cx,>2000
jmps onebit
clrlres callfar crt_lock
mov ax,>b800
mov es,ax
mov ax,[bp][%attrib]
and ax,>0003
mov dl,al
mov cl,2
shl al,cl
or al,dl
mov dl,al
add cl,cl
shl al,cl
or al,dl
mov ah,al
mov cx,>2000
jmps clear
end
;
; ------------------------------------------------------------
;int setvmode(int mode);
; attempts to set video to mode
; returns actual video mode
; stores actual video mode in _vmode
; ------------------------------------------------------------
idt setvmode
def setvmode
ref _vmode
ref _vpages
ref _vmaxh
ref _vminh
ref _vmaxv
ref _vminv
ref _vlimits
fref getvmode
dref $$XTRC
dref $$XTRC2
; ------------------------------------------------------------
;
; 8086
; tos --> bp
; return offset
; return segment
mode equ 6
;
;***** hercules junk *****
;
; port addresses
index equ 03b4h
cntrl equ 03b8h
config equ 03bfh
;
; control codes
scrn_on equ 8
grph equ 2
twopage equ 3
onepage equ 1
;
; tables
gtable db 35h,2dh,2eh,07h
db 5bh,02h,57h,57h
db 02h,03h,00h,00h
;
;************************
;
;
default equ >FF
setcpu 8086
setvmode push bp
mov bp,sp
mov al,%[bp][%mode] ;get mode argument
cmp al,default
jnz svmode
mov al,[dfltmode]
cmp al,default
jz exit ; mode was never changed
jmps setmode
svmode cmp %[dfltmode],default ; first time?
jnz setmode
callfar getvmode
mov %[dfltmode],al
mov al,%[bp][%mode] ;get mode argument
setmode mov [_vminh],0
mov [_vminv],0
cmp al,HERCMODE ;check for hercules mode
je hgraph ;set video to hercules graphics mode
cmp [_vmode],HERCMODE
jnz setbios
call clrherc
setbios mov ah,0 ;call set mode function of int 10h
int 10h
mov ah,15 ;call get mode function of int 10h
int 10h
xor ah,ah
mov [_vmode],ax ;store mode in global variable
cmp ax,[_vlimits]
ja nolimits
mov bx,ax
add bx,bx
add bx,bx
add bx,%2
mov dx,[_vlimits][bx]
mov [_vmaxh],dx
add bx,%2
mov dx,[_vlimits][bx]
mov [_vmaxv],dx
mov ax,[_vmode]
exit pop bp ;get frame pointer
retseg ;return
nolimits mov [_vmaxh],-1
mov [_vmaxv],-1
mov ax,[_vmode]
pop bp
retseg
;
hgraph call setherc
mov [_vmaxh],719
mov [_vmaxv],347
mov al,twopage
cmp %[_vpages],2
jge cont
mov al,onepage
cont mov dx,config
; out dx,al
db >ee
mov al,grph
mov si,gtable
mov bx,0
mov cx,4000h
push ax
push bx
push cx
; change mode but without scrn_on
mov dx,cntrl
; out dx,al
db >ee
; intialize the 6845
mov ax,ds
mov es,ax
mov dx,index
mov cx,12
xor ah,ah
parms mov al,ah
; out dx,al
db >ee
inc dx
segcs
lodsb
; out dx,al
db >ee
inc ah
dec dx
loop parms
pop cx
;
mov ax,>b000
cld
mov es,ax
xor di,di
pop ax
rep
stosw
;
cmp %[_vpages],2
jl continue
mov cx,>4000
mov ax,>b800
mov es,ax
xor di,di
xor ax,ax
rep
stosw
;
; scrn_on, page 0
continue mov dx,cntrl
pop ax
add al,scrn_on
; out dx,al
db >ee
mov al,HERCMODE
xor ah,ah
mov [_vmode],ax
pop bp
retseg
;
; if CTrace is present, notify it about hercules mode
;
setherc cmp [$$XTRC2],0
jz goback
push ax
mov ah,3
calltrc push bx
mov bx,2
callseg [$$XTRC]
pop bx
pop ax
goback ret
clrherc cmp [$$XTRC2],0
jz goback
push ax
mov ah,4
jmps calltrc
;
dorg 0
dfltmode dw >FFFF
end
;
;int getvmode(void);
; getvmode sets global variable _vmode to current video mode
; and returns current video mode
;********************************************************************
idt getvmode
def getvmode
ref _vmode
ref _vvpage
;********************************************************************
;
; 8086
; tos --> return offset
; return segment
;
setcpu 8086
getvmode mov ax,[_vmode]
cmp al,HERCMODE
jne continue
retseg
continue push bp ;save bp
mov ah,15 ;call get mode function of int 10h
int 10h
xor ah,ah
mov [_vmode],ax ;store mode in global variable
mov bl,bh
xor bh,bh
mov [_vvpage],bx ;store visual page in global variable
pop bp ;restore bp
retseg ;return
end
;
;int setvpage(int page);
; sets video visual page
; stores the video visual page number in _vvpage
; returns current video visual page number
;********************************************************************
idt setvpage
def setvpage
ref _vmode
ref _vvpage
;********************************************************************
;
; 8086
; tos --> bp
; return offset
; return segment
page equ 6
;
;***** hercules junk *****
;
; control port address
cntrl equ 03b8h
;
; control codes
page0 equ 0ah
page1 equ 8ah
;
;************************
;
;
setcpu 8086
setvpage push bp
mov bp,sp
cmp %[_vmode],HERCMODE
je hpage
mov ah,15 ;call get page function of int 10h
int 10h
push ax
mov al,%[bp][%page] ;get page argument
mov ah,5 ;call select page function of int 10h
int 10h
exit mov al,bh
xor ah,ah
mov [_vvpage],ax ;store mode in global variable
pop ax
xor ah,ah
pop bp ;restore bp
retseg ;return
;
hpage push [_vvpage]
mov bh,%[bp][%page] ;get page argument
mov dx,cntrl
mov al,page0 ;set al to page0
or bh,bh
jz continue
mov bh,1 ;return page number 1
mov al,page1 ;set al to page1
; out dx,al
continue db >ee
jmp exit
end
;
; -----------------------------------------------------------------
;
; void writedot(int row, int col, int color);
; writes a dot of color at coordinates (row, col).
; for HERCMODE, color of 1 turns dot on, 0 turns dot off,
;
idt writedot
def writedot
ref _vmode
ref _vapage
ref _vmaxh
ref _vminh
ref _vmaxv
ref _vminv
ref _v_color
fref crt_lock
lfref crt_unlock
;
;
; 8086
; tos --> bp
; return offset
; return segment
row equ 6
col equ 8
color equ 10
VGA256 equ >13
;
;
setcpu 8086
writedot push bp
mov bp,sp
mov cx,[bp][%col] ;cx = col
cmp cx,[_vmaxh] ;clip to screen boundary
ja exit
cmp cx,[_vminh]
jb exit
mov dx,[bp][%row] ;dx = row
cmp dx,[_vmaxv]
ja exit
cmp dx,[_vminv]
jb exit
mov al,%[bp][%color] ;al = color
cmp al,TRANSPAR
jz exit
cmp al,PENCOLOR
jnz w1
mov al,%[_v_color]
w1 cmp %[_vmode],HERCMODE
je hwrite
cmp %[_vmode],VGA256
jae w2
and al,>7F ; remove sign(xor flag) bit
w2 mov ah,12 ;use writedot funtion of int 10h
mov bx,[_vapage]
; mov cx,[bp][%col] ;cx = col
; mov dx,[bp][%row] ;dx = row
int 10h
exit pop bp ;restore
retseg ;return
;
hwrite mov bh,al
callfar crt_lock
mov dx,>b000 ;dx = page 0
cmp %[_vapage],0
je setes
mov dx,>b800 ;dx = page 1
setes mov es,dx
mov ax,[bp][%row]
mov si,ax
and si,>0003
mov cl,13
shl si,cl ; (y % 4) * 0x2000
shr ax,1
shr ax,1 ; y/4
mul [k90]
add si,ax
mov ax,[bp][%col]
mov cx,ax
shr ax,1 ; x/8
shr ax,1
shr ax,1
add si,ax
and cx,>0007 ; x % 8
mov ah,>80
jcxz bitset
shr ah,cl
bitset seges
mov al,[si] ; previous contents
cmp bh,%0
jz turnoff
or al,ah ; set the bit
jmps setvalue
turnoff not ah
and al,ah ; clear the bit
setvalue seges
mov %[si],al
callfar crt_unlock
pop bp
retseg
dorg 0
k90 dw 90
end
;
; -----------------------------------------------------------------
;
; int readdot(int row, int col);
; returns the color of the dot at coordinates (row, col).
; for HERCMODE, a return value of 1 means dot on, 0 means dot off
;
idt readdot
def readdot
ref _vmode
ref _vapage
fref crt_lock
lfref crt_unlock
;
row equ 6
col equ 8
;
;
readdot push bp
mov bp,sp
cmp %[_vmode],HERCMODE
je hread
mov ah,13
mov bx,[_vapage]
mov cx,[bp][%col]
mov dx,[bp][%row]
int 10h
pop bp
xor ah,ah
retseg
;
hread callfar crt_lock
mov dx,>b000 ;dx = page 0
cmp %[_vapage],0
je setes
mov dx,>b800 ;dx = page 1
setes mov es,dx
mov ax,[bp][%row]
mov si,ax
and si,>0003
mov cl,13
shl si,cl ; (y % 4) * 0x2000
shr ax,1
shr ax,1 ; y/4
mul [k90]
add si,ax
mov ax,[bp][%col]
mov cx,ax
shr ax,1 ; x/8
shr ax,1
shr ax,1
add si,ax
and cx,>0007 ; x % 8
neg cx
add cx,%7
seges
mov al,%[si] ; read 8 pixels
jcxz mask ; alrerady in position
shr al,cl
mask and ax,>0001
push ax
callfar crt_unlock
pop ax
pop bp
retseg
dorg 0
k90 dw 90
end
;
;void writech(int c);
; writes character ch at current position in active page
; returns ch
;********************************************************************
idt writech
def writech
ref _vapage
;********************************************************************
;
; tos --> bp
; return offset
; return segment
c equ 6
;
;
setcpu 8086
writech push bp
mov bp,sp
mov al,%[bp][%c] ;get character
mov ah,10 ;use write character of int 10h
mov bh,%[_vapage] ;set active page
mov cx,1 ;write one character
int 10h ;write ch
pop bp ;restore bp
xor ah,ah
retseg
end
;
;void writechs(int c, int attr, int n);
; writes c with attribute attr n times at current position in active page
;********************************************************************
idt writechs
def writechs
ref _vapage
;********************************************************************
;
; 8086
; tos --> bp
; return offset
; return segment
c equ 6
attr equ 8
n equ 10
;
;
setcpu 8086
writechs push bp
mov bp,sp
mov cx,[bp][%n] ;get number of times to write
mov bl,%[bp][%attr] ;get attribute of character
mov al,%[bp][%c] ;get character
mov ah,9 ;set write attribute of int 10h
mov bh,%[_vapage] ;set active page
int 10h ;write character/attribute n times
pop bp ;restore bp
xor ah,ah
retseg
end
;void poscurs(int row, int col);
; positions cursor in active page
;
idt poscurs
def poscurs
ref _vapage
;
; tos --> bp
; return offset
; return segment
row equ 6
col equ 8
;
;
setcpu 8086
poscurs push bp
mov bp,sp
mov dh,%[bp][%row]
mov dl,%[bp][%col]
mov bh,%[_vapage]
mov ah,2
int 10h
pop bp
retseg
end
;int cursrow(void);
; returns row position of cursor in active page
;
;***********************************************************
idt cursrow
def cursrow
ref _vapage
;***********************************************************
; tos -> bp
; return offset
; return segment
;
setcpu 8086
cursrow push bp
mov ah,3
mov bh,%[_vapage]
int 10h
mov al,dh
pop bp
xor ah,ah
retseg
end
;int curscol(void);
; returns row position of cursor in active page
;
;***********************************************************
idt curscol
def curscol
ref _vapage
;***********************************************************
; tos -> bp
; return offset
; return segment
;
setcpu 8086
curscol push bp
mov ah,3
mov bh,%[_vapage]
int 10h
mov al,dl
pop bp
xor ah,ah
retseg
end
;
; ------------------------------------------------------------
;
; int flood(x_size, y_size);
;
; Fill a rectangular area with the current pattern.
; Current graphics cursor defines the upper left corner of the area
;
idt flood
def flood
dref _vxcurs ; position
dref _vycurs
dref _vmode ; current mode
dref _vf_pat ; pattern
dref _vf_wid ; width of pattern
dref _vf_hgt ; width of pattern
dref _v_color ; pen color
dref _vapage ; active page
dref _vusemem ; direct access to memory
dref _vmaxh ; screen limit
dref _vmaxv
fref _vhwhere
fref _v4where
fref _v6where
fref crt_lock
lfref crt_unlock
xlimit equ 0
ylimit equ 2
xstart equ 4
xmax equ 6
memorg equ 8
nextrow equ 10
localsz equ nextrow+2
x_size equ localsz+PARM1
y_size equ localsz+PARM1+2
;
flood push bp
sub sp,localsz
mov bp,sp
cmp [bp][%x_size],0
jle done01
cmp [bp][%y_size],0
jg fl001
done01 jmp done
fl001 mov ax,[_vf_pat]
mov [bp][%xstart],ax
add ax,[_vf_wid]
mov [bp][%xlimit],ax
mov ax,[_vf_wid]
mul [_vf_hgt]
add ax,[_vf_pat]
mov [bp][%ylimit],ax
mov ax,[_vxcurs]
add ax,[bp][%x_size]
cmp ax,[_vmaxh]
jna limit1
mov bx,[_vmaxh] ; beyond screen boundary
sub ax,bx
sub [bp][%x_size],ax
mov bx,ax
limit1 mov [bp][%xmax],ax
mov ax,[bp][%y_size]
add ax,[_vycurs]
cmp ax,[_vmaxv]
jna limit2
mov ax,[_vmaxv]
inc ax
sub ax,[_vycurs]
jz done01
mov [bp][%y_size],ax
limit2 mov al,[_vmode] ; check current mode
cmp al,HERCMODE
jz herc
cmp [_vusemem],0
jz bios
cmp al,HRES
jz cga6
cmp al,GBW
jz cga4i
cmp al,GCOLOR
jz cga4i
;
; fill using the bios
;
bios mov si,[_vf_pat]
mov dx,[_vycurs]
mov cx,[_vxcurs]
mov bx,[_vapage]
jmps bitset
nextbit inc cx ; next x coordinate
cmp cx,[bp][%xmax]
jae nexty
cmp si,[bp][%xlimit]
jb bitset
mov si,[bp][%xstart]
bitset lodsb ; next color in pattern
cmp al,TRANSPAR
jz nextbit
cmp al,PENCOLOR
jnz bitput
mov al,[_v_color]
bitput mov ah,>0c
int >10
jmps nextbit
nexty dec [bp][%y_size]
jz done
inc dx ; next y coordinate
mov si,[bp][%xstart]
add si,[_vf_wid]
cmp si,[bp][%ylimit]
jb setxlim
mov si,[_vf_pat]
setxlim mov [bp][%xstart],si
mov ax,si
add ax,[_vf_wid]
mov [bp][%xlimit],ax
mov cx,[_vxcurs]
jmps bitset
done lea sp,[bp][%localsz]
pop bp
retfar
cga4i jmp cga4
;
herc callfar crt_lock
callfar _vhwhere ; calculate memory address
mov ax,incyh
mov [bp][%nextrow],ax
jmps onebit
cga6 callfar crt_lock
callfar _v6where
mov ax,incy6
mov [bp][%nextrow],ax
;
onebit mov ch,cl ; save bit offset
mov [bp][%memorg],di ; save memory address
mov dx,[bp][%x_size] ; horizontal counter
seges
mov bl,[di] ; get first group of pixels
mov si,[bp][%xstart]
jmps hbitset
hnextbit inc cl ; next x coordinate
cmp cl,8 ; next byte?
jnz h001
seges
mov [di],bl ; save current group
inc di ; get next 8 pixels
seges
mov bl,[di]
xor cl,cl
h001 dec dx
jz hnexty ; end of row
cmp si,[bp][%xlimit]
jb hbitset
mov si,[bp][%xstart]
hbitset lodsb ; next color in pattern
cmp al,TRANSPAR
jz hnextbit
cmp al,PENCOLOR
jnz hbitput
mov al,[_v_color]
hbitput and al,1
ror al,1
mov ah,>7f
cmp cl,0
jz h002
ror ah,cl
shr al,cl
h002 and bl,ah ; mask previous contents
or bl,al ; set new bit
jmps hnextbit
hnexty seges
mov [di],bl ; save last 8 pixels
dec [bp][%y_size]
jz donemem1
mov di,[bp][%memorg]
call [bp][%nextrow]
mov [bp][%memorg],di
mov si,[bp][%xstart]
add si,[_vf_wid]
cmp si,[bp][%ylimit]
jb h004
mov si,[_vf_pat]
h004 mov [bp][%xstart],si
mov ax,si
add ax,[_vf_wid]
mov [bp][%xlimit],ax
mov cl,ch ; reset bit number
mov dx,[bp][%x_size] ; horizontal counter
seges
mov bl,[di]
jmps hbitset
donemem1 jmp donemem
;
cga4 callfar crt_lock
callfar _v4where
mov ax,incy4
mov [bp][%nextrow],ax
;
twobit shl cl,1
mov ch,cl ; save bit offset
mov [bp][%memorg],di ; save memory address
mov dx,[bp][%x_size] ; horizontal counter
seges
mov bl,[di] ; get first group of pixels
mov si,[bp][%xstart]
jmps set4
next4 add cl,%2 ; next x coordinate
cmp cl,8 ; next byte?
jnz t001
seges
mov [di],bl ; save current group
inc di ; get next 4 pixels
seges
mov bl,[di]
xor cl,cl
t001 dec dx
jz nexty4 ; end of row
cmp si,[bp][%xlimit]
jb set4
mov si,[bp][%xstart]
set4 lodsb ; next color in pattern
cmp al,TRANSPAR
jz next4
cmp al,PENCOLOR
jnz put4
mov al,[_v_color]
put4 and al,3
ror al,1
ror al,1
mov ah,>3f
cmp cl,0
jz t002
ror ah,cl
shr al,cl
t002 and bl,ah ; mask previous contents
or bl,al ; set new bit
jmps next4
nexty4 seges
mov [di],bl ; save last 8 pixels
dec [bp][%y_size]
jz donemem
mov di,[bp][%memorg]
call [bp][%nextrow]
mov [bp][%memorg],di
mov si,[bp][%xstart]
add si,[_vf_wid]
cmp si,[bp][%ylimit]
jb t004
mov si,[_vf_pat]
t004 mov [bp][%xstart],si
mov ax,si
add ax,[_vf_wid]
mov [bp][%xlimit],ax
mov cl,ch ; reset bit number
mov dx,[bp][%x_size] ; horizontal counter
seges
mov bl,[di]
jmps set4
donemem callfar crt_unlock
jmp done
;
; add 1 to the y coordinate (hercules)
;
incyh add di,>2000 ; next y coordinate
cmp di,>8000
jb incyh1
sub di,>8000-90D
incyh1 ret
;
; add 1 to the y coordinate (cga)
;
incy6 add di,>2000 ; next y coordinate
cmp di,>4000
jb incy61
sub di,>4000-80D
incy61 ret
;
; add 1 to the y coordinate (cga)
;
incy4 add di,>2000 ; next y coordinate
cmp di,>4000
jb incy41
sub di,>4000-80D
incy41 ret
end
;
; ------------------------------------------------------------
;
; int plotch(char c);
;
; Write a character to the screen in graphics mode.
; For modes 4,5,6,99 the horizontal position is rounded to the
; nearest mulitple of 8 (byte boundary)
; For other modes, the bios is used.
;
idt plotch
def plotch
dref _vchpat1 ; character font table
dref _vxcurs ; position
dref _vycurs
dref _vmode ; current mode
dref _v_color ; pen color
dref _vapage ; active page
fref _vhwhere
fref _v4where
fref _v6where
fref crt_lock
lfref crt_unlock
;
plotch push bp
mov bp,sp
mov si,[bp][%PARM1] ; fetch value of character
cmp si,>7f
ja exit
shl si,1
shl si,1
shl si,1
add si,_vchpat1 ; si = address of pattern
mov al,[_vmode] ; check current mode
cmp al,HERCMODE
jz herc
cmp al,HRES
jz cga6i
cmp al,GBW
jz cga4i
cmp al,GCOLOR
jz cga4i
;
; write a character using write dot
;
mov ah,[si]
mov di,8*8 ; 64 points
mov dx,[_vycurs]
mov cx,[_vxcurs]
mov bx,[_vapage]
jmps next
nextbit inc cx ; next x coordinate
test di,>0007
jnz next
sub cx,%8 ; next row of pattern
inc dx
inc si
mov ah,[si]
next xor al,al
shl ah,1
push ax
jnc putbit
mov al,[_v_color] ; bit is on
putbit mov ah,>0c
int >10
pop ax
dec di
jnz nextbit
done add [_vxcurs],%8
exit pop bp
retfar
cga4i jmp cga4
cga6i jmp cga6
;
; write a character to hercules monochrome graphics card
; si contains address of character pattern
;
herc callfar crt_lock
callfar _vhwhere
mov dx,[_v_color]
jcxz hbyte
; write to hercules (not on byte boundary)
mov dh,8
hnbnext mov bx,>ff00
ror bx,cl
seges
and bx,[di] ; remove previous bits
lodsb
test dl,%1
jnz posh2
not al
posh2 xor ah,ah
ror ax,cl ; bring into position
or bx,ax
seges
mov [di],bx
add di,>2000
cmp di,>8000
jb nexth2
sub di,>8000-90D
nexth2 dec dh
jnz hnbnext
doneh callfar crt_unlock
jmps done
; write to hercules, character on byte boundary
hbyte mov cx,8
puth lodsb
test dl,%1
jnz posh
not al
posh seges
mov [di],al
add di,>2000
cmp di,>8000
jb nexth
sub di,>8000-90D
nexth loop puth
jmp doneh
;
cga6 callfar crt_lock
callfar _v6where
mov dx,[_v_color]
jcxz cgabyte
; write to cga mode 6 (not on byte boundary)
mov dh,8
cga6nxt mov bx,>ff00
ror bx,cl
seges
and bx,[di] ; remove previous bits
lodsb
test dl,%1
jnz pos62
not al
pos62 xor ah,ah
ror ax,cl ; bring into position
or bx,ax
seges
mov [di],bx
add di,>2000
cmp di,>4000
jb next62
sub di,>4000-80D
next62 dec dh
jnz cga6nxt
done6 callfar crt_unlock
jmp done
cgabyte mov cx,8
put6 lodsb
test dl,%01
jnz pos6
not al
pos6 seges
mov [di],al
add di,>2000
cmp di,>4000
jb next6
sub di,>4000-80D
next6 loop put6
jmp done6
;
cga4 callfar crt_lock
callfar _v4where
mov ax,[_v_color] ; get color of pen
jcxz cga4byte
shl cl,1
mov dl,cl ; save starting offset
push di
mov dh,8 ; number of rows
cga4row mov ch,8 ; bits per row
lodsb
cga4lp1 xor ah,ah
shl al,1
jnc cga4zero
mov ah,[_v_color]
and ah,>3
ror ah,1
ror ah,1
cga4zero mov bh,>3f ; mask previous contents
cmp cl,0
jz cga4set
shr ah,cl ; move color into position
ror bh,cl
cga4set seges
and bh,[di]
or bh,ah
seges
mov [di],bh ; set pixel
add cl,%2
cmp cl,6
jbe cga4nxt
inc di
xor cl,cl
cga4nxt dec ch
jnz cga4lp1
mov cl,dl ; restore bit offset
pop di ; restore origin
add di,>2000 ; next row address
cmp di,>4000
jb cga4a
sub di,>4000-80D
cga4a push di
dec dh
jnz cga4row
pop di
done4 callfar crt_unlock
jmp done
; cga mode 4 or 5 on byte boundary
cga4byte mov ax,[_v_color]
xor dx,dx
mov cx,8
makemask shl dl,1
shl dl,1
or dl,al
loop makemask
mov dh,dl
mov cx,8
put4 lodsb
push cx
mov cx,8
make4 shr al,1 ; replicate bits
rcr bx,1
sar bx,1
loop make4
pop cx
and bx,dx
xchg bh,bl
seges
mov [di],bx
add di,>2000
cmp di,>4000
jb next4
sub di,>4000-80D
next4 loop put4
jmp done4
end
;
; Generate memory address for a point on the screen
; Hercules graphics card
; Returns address in es:di and bit number in cl
;
idt _vhwhere
def _vhwhere
dref _vxcurs
dref _vycurs
dref _vapage
;
_vhwhere mov ax,[_vycurs]
mov di,ax
and di,>0003
mov cl,13
shl di,cl ; (y % 4) * 0x2000
mov cl,2
shr ax,cl ; y/4
shl ax,1 ; (y/4) * 0x02
add di,ax
shl ax,cl ; (y/4) * 0x08
add di,ax
shl ax,1 ; (y/4) * 0x10
add di,ax
shl ax,cl ; (y/4) * 0x40
add di,ax
mov ax,[_vxcurs]
mov cx,ax
and cx,>0007 ; bit number
shr ax,1 ; x/8
shr ax,1
shr ax,1
add di,ax ; di = memory address
mov ax,>b000 ; select segment for active page
cmp %[_vapage],0
je sethpage
mov ax,>b800
sethpage mov es,ax
retfar
end
;
; Generate memory address for a point on the screen
; CGA high resolution (mode 6)
; Returns address in es:di and bit number in cl
;
idt _v6where
def _v6where
dref _vxcurs
dref _vycurs
;
_v6where mov ax,[_vycurs]
mov di,ax
and di,>0001
mov cl,13
shl di,cl ; (y % 2) * 0x2000
shr ax,1 ; y/2
mov cl,4
shl ax,cl ; (y/2) * 0x10
add di,ax
shl ax,1
shl ax,1 ; ax = (y/2) * 0x40
add di,ax
mov ax,[_vxcurs]
mov cx,ax
and cx,>0007
shr ax,1 ; x/8
shr ax,1
shr ax,1
add di,ax
mov ax,>b800 ; segment of cga memory
mov es,ax
retfar
end
;
; Generate memory address for a point on the screen
; CGA low resolution (mode 4 or 5)
; Returns address in es:di and bit number in cl
;
idt _v4where
def _v4where
dref _vxcurs
dref _vycurs
;
_v4where mov ax,[_vycurs]
mov di,ax
and di,>0001
mov cl,13
shl di,cl ; (y % 2) * 0x2000
shr ax,1 ; y/2
mov cl,4
shl ax,cl ; (y/2) * 0x10
add di,ax
shl ax,1
shl ax,1 ; ax = (y/2) * 0x40
add di,ax
mov ax,[_vxcurs]
mov cx,ax
and cx,>0003
shr ax,1 ; x/4
shr ax,1
add di,ax
mov ax,>b800 ; segment of cga memory
mov es,ax
retfar
end
;
; ------------------------------------------------------------
;
; crt_lock - lock the crt contents into physical screen memory
; crt_lock should be called before the program writes directly
; to screen memory
;
idt crt_lock
def crt_lock
dref $$XTRC
dref $$XTRC2
;
needmem equ PARM1-2
crt_lock cmp [$$XTRC2],0
jnz request
retfar
request push bx
mov bx,2
mov ah,1
calltrc callseg [$$XTRC]
pop bx
xor ax,ax
retfar
end
;
; ------------------------------------------------------------
;
; crt_unlock - release the crt contents from screen memory
;
idt crt_unlock
IF LONGNAME
LDEF crt_unlock
ENDIF
IF SHORTNAME
DEF crt_unlo
ENDIF
dref $$XTRC
dref $$XTRC2
;
needmem equ PARM1-2
crt_unlo cmp [$$XTRC2],0
jnz request
retfar
request push bx
mov bx,2
mov ah,2
calltrc callseg [$$XTRC]
pop bx
xor ax,ax
retfar
end
;
; ------------------------------------------------------------
;
idt _vdata
ddef _vmode
ddef _vpages
ddef _vapage
ddef _vvpage
ddef _vmaxh
ddef _vminh
ddef _vmaxv
ddef _vminv
ddef _vattr
ddef _vlimits
ddef _vusemem
ddef _v_color
ddef _vl_dpat
ddef _vl_pat
ddef _vl_psiz
ddef _vxcurs
ddef _vycurs
ddef _vf_pat
ddef _vf_wid
ddef _vf_hgt
;
dorg 0
_vmode dw >ffff ; screen mode
_vpages dw >0002 ; number of pages (graphics)
_vapage dw >0000 ; active page
_vvpage dw >0000 ; visible page
_vmaxh dw >ffff ; horizontal boundaries
_vminh dw >0000
_vmaxv dw >ffff ; vertical boundaries
_vminv dw >0000
_vattr dw 7 ; attribute for scroll functions
_vusemem dw 1 ; use direct access to screen memory
_v_color dw >FF ; pen color
_vl_dpat dw >FF ; default color for lines
_vl_pat dw _vl_dpat ; line style
_vl_psiz dw 1 ; size of line style
_vxcurs dw 0 ; graphics cursor
_vycurs dw 0
_vf_pat dw _vl_dpat ; default fill pattern
_vf_wid dw 1 ; width of fill pattern
_vf_hgt dw 1 ; height of fill pattern
_vlimits dw 16 ; Maximum in table
dw 39,24,39,24,79,24,79,24 ; 0..3 (text)
dw 319,199,319,199,639,199 ; 4..6 (graphics)
dw 79,24 ; 7 (monochome)
dw 159,199,319,199,639,199 ; 8..10 (pc Jr)
dw 0,0,0,0 ; 11..12 (undefined)
dw 319,199,639,199,639,349 ; 13..15 (EGA)
dw 639,349 ; 16 (EGA)
;
end
;
; Table of bit patterns for characters in graphics mode.
; Characters fill an 8x8 cell.
; Only the first 128 character codes are present.
;
idt _vchpat1
ddef _vchpat1
;
dorg 0
_vchpat1 db >00,>00,>00,>00,>00,>00,>00,>00 ; 00
db >7e,>81,>a5,>81,>bd,>99,>81,>7e ; 01
db >7e,>ff,>db,>ff,>c3,>e7,>ff,>7e ; 02
db >6c,>fe,>fe,>fe,>7c,>38,>10,>00 ; 03
db >10,>38,>7c,>fe,>7c,>38,>10,>00 ; 04
db >38,>7c,>38,>fe,>fe,>7c,>38,>7c ; 05
db >10,>10,>38,>7c,>fe,>7c,>38,>7c ; 06
db >00,>00,>18,>3c,>3c,>18,>00,>00 ; 07
db >ff,>ff,>e7,>c3,>c3,>e7,>ff,>ff ; 08
db >00,>3c,>66,>42,>42,>66,>3c,>00 ; 09
db >ff,>c3,>99,>bd,>bd,>99,>c3,>ff ; 0a
db >0f,>07,>0f,>7d,>cc,>cc,>cc,>78 ; 0b
db >3c,>66,>66,>66,>3c,>18,>7e,>18 ; 0c
db >3f,>33,>3f,>30,>30,>70,>f0,>e0 ; 0d
db >7f,>63,>7f,>63,>63,>67,>e6,>c0 ; 0e
db >99,>5a,>3c,>e7,>e7,>3c,>5a,>99 ; 0f
db >80,>e0,>f8,>fe,>f8,>e0,>80,>00 ; 10
db >02,>0e,>3e,>fe,>3e,>0e,>02,>00 ; 11
db >18,>3c,>7e,>18,>18,>7e,>3c,>18 ; 12
db >66,>66,>66,>66,>66,>00,>66,>00 ; 13
db >7f,>db,>db,>7b,>1b,>1b,>1b,>00 ; 14
db >3e,>63,>38,>6c,>6c,>38,>cc,>78 ; 15
db >00,>00,>00,>00,>7e,>7e,>7e,>00 ; 16
db >18,>3c,>7e,>18,>7e,>3c,>18,>ff ; 17
db >18,>3c,>7e,>18,>18,>18,>18,>00 ; 18
db >18,>18,>18,>18,>7e,>3c,>18,>00 ; 19
db >00,>18,>0c,>fe,>0c,>18,>00,>00 ; 1a
db >00,>30,>60,>fe,>60,>30,>00,>00 ; 1b
db >00,>00,>c0,>c0,>c0,>fe,>00,>00 ; 1c
db >00,>24,>66,>ff,>66,>24,>00,>00 ; 1d
db >00,>18,>3c,>7e,>ff,>ff,>00,>00 ; 1e
db >00,>ff,>ff,>7e,>3c,>18,>00,>00 ; 1f
db >00,>00,>00,>00,>00,>00,>00,>00 ; 20
db >30,>78,>78,>30,>30,>00,>30,>00 ; 21 !
db >6c,>6c,>6c,>00,>00,>00,>00,>00 ; 22 "
db >6c,>6c,>fe,>6c,>fe,>6c,>6c,>00 ; 23 #
db >30,>7c,>c0,>78,>0c,>f8,>30,>00 ; 24 $
db >00,>c6,>cc,>18,>30,>66,>c6,>00 ; 25 %
db >38,>6c,>38,>76,>dc,>cc,>76,>00 ; 26 &
db >60,>60,>c0,>00,>00,>00,>00,>00 ; 27 '
db >18,>30,>60,>60,>60,>30,>18,>00 ; 28 (
db >60,>30,>18,>18,>18,>30,>60,>00 ; 29 )
db >00,>66,>3c,>ff,>3c,>66,>00,>00 ; 2a *
db >00,>30,>30,>fc,>30,>30,>00,>00 ; 2b +
db >00,>00,>00,>00,>00,>30,>30,>60 ; 2c ,
db >00,>00,>00,>fc,>00,>00,>00,>00 ; 2d -
db >00,>00,>00,>00,>00,>30,>30,>00 ; 2e .
db >06,>0c,>18,>30,>60,>c0,>80,>00 ; 2f /
db >7c,>c6,>ce,>de,>f6,>e6,>7c,>00 ; 30 0
db >30,>70,>30,>30,>30,>30,>fc,>00 ; 31 1
db >78,>cc,>0c,>38,>60,>cc,>fc,>00 ; 32 2
db >78,>cc,>0c,>38,>0c,>cc,>78,>00 ; 33 3
db >1c,>3c,>6c,>cc,>fe,>0c,>1e,>00 ; 34 4
db >fc,>c0,>f8,>0c,>0c,>cc,>78,>00 ; 35 5
db >38,>60,>c0,>f8,>cc,>cc,>78,>00 ; 36 6
db >fc,>cc,>0c,>18,>30,>30,>30,>00 ; 37 7
db >78,>cc,>cc,>78,>cc,>cc,>78,>00 ; 38 8
db >78,>cc,>cc,>7c,>0c,>18,>70,>00 ; 39 9
db >00,>30,>30,>00,>00,>30,>30,>00 ; 3a :
db >00,>30,>30,>00,>00,>30,>30,>60 ; 3b ;
db >18,>30,>60,>c0,>60,>30,>18,>00 ; 3c <
db >00,>00,>fc,>00,>00,>fc,>00,>00 ; 3d =
db >60,>30,>18,>0c,>18,>30,>60,>00 ; 3e >
db >78,>cc,>0c,>18,>30,>00,>30,>00 ; 3f ?
db >7c,>c6,>de,>de,>de,>c0,>78,>00 ; 40 @
db >30,>78,>cc,>cc,>fc,>cc,>cc,>00 ; 41 A
db >fc,>66,>66,>7c,>66,>66,>fc,>00 ; 42 B
db >3c,>66,>c0,>c0,>c0,>66,>3c,>00 ; 43 C
db >f8,>6c,>66,>66,>66,>6c,>f8,>00 ; 44 D
db >fe,>62,>68,>78,>68,>62,>fe,>00 ; 45 E
db >fe,>62,>68,>78,>68,>60,>f0,>00 ; 46 F
db >3c,>66,>c0,>c0,>ce,>66,>3e,>00 ; 47 G
db >cc,>cc,>cc,>fc,>cc,>cc,>cc,>00 ; 48 H
db >78,>30,>30,>30,>30,>30,>78,>00 ; 49 I
db >1e,>0c,>0c,>0c,>cc,>cc,>78,>00 ; 4a J
db >e6,>66,>6c,>78,>6c,>66,>e6,>00 ; 4b K
db >f0,>60,>60,>60,>62,>66,>fe,>00 ; 4c L
db >c6,>ee,>fe,>fe,>d6,>c6,>c6,>00 ; 4d M
db >c6,>e6,>f6,>de,>ce,>c6,>c6,>00 ; 4e N
db >38,>6c,>c6,>c6,>c6,>6c,>38,>00 ; 4f O
db >fc,>66,>66,>7c,>60,>60,>f0,>00 ; 50 P
db >78,>cc,>cc,>cc,>dc,>78,>1c,>00 ; 51 Q
db >fc,>66,>66,>7c,>6c,>66,>e6,>00 ; 52 R
db >78,>cc,>e0,>70,>1c,>cc,>78,>00 ; 53 S
db >fc,>b4,>30,>30,>30,>30,>78,>00 ; 54 T
db >cc,>cc,>cc,>cc,>cc,>cc,>fc,>00 ; 55 U
db >cc,>cc,>cc,>cc,>cc,>78,>30,>00 ; 56 V
db >c6,>c6,>c6,>d6,>fe,>ee,>c6,>00 ; 57 W
db >c6,>c6,>6c,>38,>38,>6c,>c6,>00 ; 58 X
db >cc,>cc,>cc,>78,>30,>30,>78,>00 ; 59 Y
db >fe,>c6,>8c,>18,>32,>66,>fe,>00 ; 5a Z
db >78,>60,>60,>60,>60,>60,>78,>00 ; 5b [
db >c0,>60,>30,>18,>0c,>06,>02,>00 ; 5c \
db >78,>18,>18,>18,>18,>18,>78,>00 ; 5d ]
db >10,>38,>6c,>c6,>00,>00,>00,>00 ; 5e ^
db >00,>00,>00,>00,>00,>00,>00,>ff ; 5f _
db >30,>30,>18,>00,>00,>00,>00,>00 ; 60 `
db >00,>00,>78,>0c,>7c,>cc,>76,>00 ; 61 a
db >e0,>60,>60,>7c,>66,>66,>dc,>00 ; 62 b
db >00,>00,>78,>cc,>c0,>cc,>78,>00 ; 63 c
db >1c,>0c,>0c,>7c,>cc,>cc,>76,>00 ; 64 d
db >00,>00,>78,>cc,>fc,>c0,>78,>00 ; 65 e
db >38,>6c,>60,>f0,>60,>60,>f0,>00 ; 66 f
db >00,>00,>76,>cc,>cc,>7c,>0c,>f8 ; 67 g
db >e0,>60,>6c,>76,>66,>66,>e6,>00 ; 68 h
db >30,>00,>70,>30,>30,>30,>78,>00 ; 69 i
db >0c,>00,>0c,>0c,>0c,>cc,>cc,>78 ; 6a j
db >e0,>60,>66,>6c,>78,>6c,>e6,>00 ; 6b k
db >70,>30,>30,>30,>30,>30,>78,>00 ; 6c l
db >00,>00,>cc,>fe,>fe,>d6,>c6,>00 ; 6d m
db >00,>00,>f8,>cc,>cc,>cc,>cc,>00 ; 6e n
db >00,>00,>78,>cc,>cc,>cc,>78,>00 ; 6f o
db >00,>00,>dc,>66,>66,>7c,>60,>f0 ; 70 p
db >00,>00,>76,>cc,>cc,>7c,>0c,>1e ; 71 q
db >00,>00,>dc,>76,>66,>60,>f0,>00 ; 72 r
db >00,>00,>7c,>c0,>78,>0c,>f8,>00 ; 73 s
db >10,>30,>7c,>30,>30,>34,>18,>00 ; 74 t
db >00,>00,>cc,>cc,>cc,>cc,>76,>00 ; 75 u
db >00,>00,>cc,>cc,>cc,>78,>30,>00 ; 76 v
db >00,>00,>c6,>d6,>fe,>fe,>6c,>00 ; 77 w
db >00,>00,>c6,>6c,>38,>6c,>c6,>00 ; 78 x
db >00,>00,>cc,>cc,>cc,>7c,>0c,>f8 ; 79 y
db >00,>00,>fc,>98,>30,>64,>fc,>00 ; 7a z
db >1c,>30,>30,>e0,>30,>30,>1c,>00 ; 7b {
db >18,>18,>18,>00,>18,>18,>18,>00 ; 7c |
db >e0,>30,>30,>1c,>30,>30,>e0,>00 ; 7d }
db >76,>dc,>00,>00,>00,>00,>00,>00 ; 7e ~
db >00,>10,>38,>6c,>c6,>c6,>fe,>00 ; 7f
end