home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Serving the Web
/
ServingTheWeb1995.disc1of1.iso
/
connect
/
tcpip
/
crynwr
/
pktd11b
/
pixel.asm
< prev
next >
Wrap
Assembly Source File
|
1992-08-05
|
7KB
|
380 lines
;put into the public domain by Russell Nelson, nelson@crynwr.com
;code to do graphics at 320x200x256 on both EGAs and VGAs.
; we want to be able to call these routines as if they were real addresses,
; and we don't want to have to index into a table. Therefore, the init_vid
; routine will copy the correct set of addresses into the following locations.
address_list label word
;After calling open_vid, you can't change es, di, dx, or ah.
;al and bx will get trashed, but they need not be preserved.
open_vid dw ? ;enter with cx,dx=initial point.
move_right dw ? ;move the point right.
move_left dw ? ;move the point left.
move_up dw ? ;move the point up.
move_down dw ? ;move the point down.
set_bit dw ? ;set the pixel at the point to al.
set_line dw ? ;set the row of pixels at the point to
;the list of cx pixels at ds:si.
close_vid dw ? ;clean up after open_vid
uninit_vid dw ? ;clean up after init_vid, return to text mode.
address_end label word
ega_adrs dw init_vid_ega, open_vid_ega, move_right_ega, move_left_ega
dw move_up_ega, move_down_ega, set_bit_ega, set_line_ega
dw close_vid_ega, uninit_vid_ega
vga_adrs dw init_vid_vga, open_vid_vga, move_right_vga, move_left_vga
dw move_up_vga, move_down_vga, set_bit_vga, set_line_vga
dw close_vid_vga, uninit_vid_vga
init_vid:
;test for VGA.
mov ax,1a00h
int 10h
cmp al,1ah
mov si,offset vga_adrs
ifndef FORCE_EGA
je have_vga
endif
mov si,offset ega_adrs
have_vga:
lodsw ;get the init_vid_* routine.
push ds
pop es
mov di,offset address_list
mov cx,(offset address_end - offset address_list) / 2
rep movsw
jmp ax ;jump to the proper init_vid routine.
init_vid_vga:
mov ax,13h ;put the screen into vga mode.
int 10h
call pal_save ;save the palette
call pal_setgrey ;set to a gray palette.
ret
uninit_vid_vga:
call pal_restore
mov ax,3h ;put the screen into text mode.
int 10h
ret
init_vid_ega:
mov ax,10h ;put the screen into ega mode.
int 10h
mov ax,1000h ;change the palette entry for 7
mov bx,77Q*256 + 7 ; to 77 octal.
int 10h
mov ax,1000h ;. .
mov bx,007Q*256 + 08h
int 10h
mov ax,1000h ;. .
mov bx,010Q*256 + 09h
int 10h
mov ax,1000h ;. .
mov bx,020Q*256 + 0ah
int 10h
mov ax,1000h ;. .
mov bx,030Q*256 + 0bh
int 10h
mov ax,1000h ;. .
mov bx,040Q*256 + 0ch
int 10h
mov ax,1000h ;. .
mov bx,050Q*256 + 0dh
int 10h
mov ax,1000h ;. .
mov bx,060Q*256 + 0eh
int 10h
mov ax,1000h ;. .
mov bx,070Q*256 + 0fh
int 10h
ret
uninit_vid_ega:
mov ax,3h ;put the screen into text mode.
int 10h
ret
pal_save:
;Save existing palette
mov ax,1017h ;get all palette registers.
mov bx,0 ;first palette register.
mov cx,256 ;read all palette registers.
push ds
pop es
mov dx,offset save_dacs
int 10h
ret
pal_setgrey:
mov di,offset gray_dacs
mov al,0
pal_setgrey_1:
mov cx,3 * 256 / 64 ;3 colors, 256 grays, 64 slots.
rep stosb
inc al
cmp al,64
jb pal_setgrey_1
mov dx,offset gray_dacs
jmp short pal_set
pal_restore:
mov dx,offset save_dacs
pal_set:
mov ax,1012h ;set all palette registers.
mov bx,0 ;first palette register.
mov cx,256 ;read all palette registers.
push ds
pop es
int 10h
ret
open_vid_vga:
;enter with cx,dx = point on screen.
;exit with es:di,ah -> byte/bit on screen.
mov ax,0a000h
mov es,ax
mov ax,320 ;width of screen.
mul dx
add ax,cx ;add the offset in.
mov di,ax ;remember our pointer.
ret
move_right_vga:
inc di
ret
move_left_vga:
dec di
ret
move_up_vga:
sub di,320 ;width of screen.
ret
move_down_vga:
add di,320 ;width of screen.
ret
set_line_vga:
;enter with the current pixel set up, ds:si -> row of pixels, cx=number of
;pixels. Exit with the same point set up.
push di
shr cx,1
rep movsw
jnc set_line_vga_1
movsb
set_line_vga_1:
pop di
ret
set_bit_vga:
mov es:[di],al
ret
close_vid_vga:
ret
; the EGA code follows. It uses a group of four pixels to achieve the
; appearance of 14 different graylevels.
open_vid_ega:
;enter with cx,dx = point on screen.
;exit with es:di,ah -> byte/bit on screen.
mov ax,0a000h
mov es,ax
mov ax,640/8*2 ;bytes per scan line * scan lines per pixel
mul dx
mov di,ax
mov ax,cx ;/8*2
shr ax,1
shr ax,1
add di,ax
mov dx,03ceh ;graphics controller
mov ax,0205h ;write mode 2.
out dx,al
inc dx
mov al,ah
out dx,al
dec dx
mov al,08h ;select bitmap register.
out dx,al
inc dx
shl cx,1 ;compute the bit.
and cl,7
mov ah,80h
shr ah,cl
ret
move_right_ega:
shr ah,1 ;move right by a bit.
ror ah,1 ;move right by another bit,
adc di,0 ; and handle byte increment.
ret
move_left_ega:
rol ah,1 ;move left by a bit,
adc di,0 ; and handle byte increment.
shl ah,1 ;move left by another bit.
ret
move_up_ega:
sub di,80*2 ;width of screen.
ret
move_down_ega:
add di,80*2 ;width of screen.
ret
set_line_ega:
;enter with the current pixel set up, ds:si -> row of pixels, cx=number of
;pixels. Exit with the same point set up.
push ax
push di
set_line_ega_1:
lodsb
call set_bit
;beginning of in-line move_right
shr ah,1 ;move right by a bit.
ror ah,1 ;move right by another bit,
adc di,0 ; and handle byte increment.
;end of in-line move_right
loop set_line_ega_1
pop di
pop ax
ret
set_bit_ega:
mov bl,al
xor bh,bh
mov al,ah
out dx,al
mov al,ulpal[bx]
xchg es:[di],al ;store the palette value.
mov al,llpal[bx]
xchg es:[di+80],al ;store the palette value.
shr ah,1 ;move right by a bit.
mov al,ah
out dx,al
mov al,urpal[bx]
xchg es:[di],al ;store the palette value.
mov al,lrpal[bx]
xchg es:[di+80],al ;store the palette value.
shl ah,1 ;restore the bit.
ret
close_vid_ega:
mov al,0ffh ;mask = all ones.
out dx,al
dec dx
mov ax,0005h ;write mode 0
out dx,al
inc dx
mov al,ah
out dx,al
ret
ulpal db 20 dup(00h)
db 20 dup(09h)
db 20 dup(0bh)
db 20 dup(0fh)
db 20 dup(0fh)
db 20 dup(0fh)
db 20 dup(0fh)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(07h)
db 20 dup(07h)
db 20 dup(07h)
db 20 dup(07h)
urpal db 20 dup(00h)
db 20 dup(00h)
db 20 dup(0ch)
db 20 dup(0eh)
db 20 dup(0fh)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(07h)
llpal db 20 dup(00h)
db 20 dup(0ch)
db 20 dup(0ch)
db 20 dup(0dh)
db 20 dup(0fh)
db 20 dup(0fh)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(07h)
db 20 dup(07h)
lrpal db 20 dup(00h)
db 20 dup(0ah)
db 20 dup(0bh)
db 20 dup(0bh)
db 20 dup(0fh)
db 20 dup(0fh)
db 20 dup(0fh)
db 20 dup(0fh)
db 20 dup(08h)
db 20 dup(08h)
db 20 dup(07h)
db 20 dup(07h)
db 20 dup(07h)
save_dacs db 256 * 3 dup(?)
gray_dacs db 256 * 3 dup(?)