home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
pascal
/
library
/
dos
/
tp_fast
/
version4
/
tpfscrn.asm
< prev
next >
Wrap
Assembly Source File
|
1991-11-14
|
75KB
|
1,221 lines
; _______________________________________________________________
; | |
; | CopyRight (c) 1990,1991 Steven Lutrov |
; |_______________________________________________________________|____
; | | |
; | program title : fastgrp.asm | | ___
; | author : Steven Lutrov | | |
; | revision : 4.00 | | |
; | date : 1990-11-11 | | |
; | language : turbo assembler | | |
; | | | |
; | description : assembly functions for graphics screen | | |
; | : movement and primitive screen management. | | |
; | : tested on turbo pascal 6.0 | | |
; | | | |
; |_______________________________________________________________| | |
; | | |
; |________________________________________________________________| |
; | |
; |_________________________________________________________________|
;
code segment word public
assume cs:code,ds:data
public screendown,screenleft,screenright,screenup,fillscreen
public drawbox,copyclear,restorescreen,savescreen,scrollx,scrolly
data segment
extrn video_buff : word
extrn snow_check :byte;
extrn TPFError :byte;
data ends
;-------------------------------------------------------------------------------
;procedure screendown(box :pointer; var x,y :byte;; xx,y :byte;);
;-------------------------------------------------------------------------------
;
screendown proc far
push bp ;preserve register bp
mov bp,sp ;set stack frame
push ds ;save turbo's ds
mov dx,video_buff ;grab video_buff
push dx ;save it
les di,dword ptr[bp+14] ;es:di pts to x
mov al,snow_check ;grab snow_check
mov [bp+16],al ;save on stack
sub cx,cx ;
mov cl,es:[di] ;get column position
jcxz screendf1 ;quit if column is zero
dec cx ;count from zero
cmp cx,79 ;in range?
jna screendg1 ;jump ahead if so
screendf1: jmp screendm1 ;else quit
screendg1: mov ax,[bp+20] ;segment of box
mov es,ax ;load in es
mov di,[bp+18] ;offset of box
mov byte ptr[bp+7],0 ;zero out high byte
mov ax,[bp+6] ;y to ax
dec ax ;dec for test
cmp ax,24 ;in range?
jna screendh1 ;jump ahead if so
jmp screendm1 ;else quit routine
screendh1: inc ax ;readjust
mov byte ptr[bp+9],0 ;zero out high byte
mov bx,[bp+8] ;xx to bx
dec bx ;dec for test
cmp bx,79 ;in range?
jna screendi1 ;jump ahead if so
jmp screendm1 ;else quit
screendi1: inc bx ;readjust
mul bl ;xx times y
shl ax,1 ;double for attributes
add ax,di ;offset to end of box
mov [bp+14],ax ;end of box ptr to stack
mov di,ax ;pt es:di to end of box
lds si,dword ptr[bp+10] ;point ds:si to y
sub ax,ax ;
mov al,[si] ;get y value
dec ax ;count from zero
cmp ax,24 ;in range?
jna screendk1 ;jump ahead if so
screendj1: jmp screendm1 ;else quit
screendk1: mov bx,ax ;copy in bx
add bx,[bp+6] ;add y
cmp bx,24 ;edge of screen?
ja screendj1 ;quit if so
add ax,2 ;inc old y value
mov [si],al ;reset y variable
sub ax,2 ;back to old value
mov bl,160 ;bytes per y
mul bl ;calculate y offset
shl cx,1 ;x offset
add ax,cx ;add to y offset
mov si,ax ;si pts to topleft corner
mov [bp+12],si ;save on stack
mov ax,dx ;video_buff
mov ds,ax ;move to ds
mov ax,[bp+6] ;y
mov cl,160 ;bytes per y
mul cl ;times y
add si,ax ;ds:si pts to topright
mov [bp+10],si ;copy position on stack
pop bx ;video_buff
cld ;set direction
mov cx,[bp+8] ;xx
shl cx,1 ;double for attributes
call boxd_screen ;write a char
mov ax,ds ;ds to ax
mov es,ax ;now es pts to screen too
mov di,[bp+10] ;new bottom right pos
mov si,di ;copy to si
sub si,160 ;si one y higher
mov ax,[bp+6] ;y to ax
screendl1: mov cx,[bp+8] ;xx to cx
push di ;save target ptr
push si ;save source ptr
shl cx,1 ;dbl xx for attributes
call boxd_screen ;write a char
pop si ;restore ptr
pop di ;restore ptr
sub di,160 ;ptr up one y
sub si,160 ;ditto
dec ax ;dec y counter
jnz screendl1 ;loop till finished
mov ax,[bp+20] ;segment of box
mov ds,ax ;move to ds
mov si,[bp+18] ;offset of box
mov di,[bp+12] ;es:di pts to topleft
mov dx,[bp+8] ;xx
shl dx,1 ;double for attributes
mov cx,dx ;use as counter
call boxd_screen ;write a char
mov ax,ds ;ds pts to box
mov es,ax ;now es does too
mov di,[bp+18] ;offset to start of box
mov si,di ;copy to si
add si,dx ;offset to second y
mov ax,[bp+6] ;y
mov cx,[bp+8] ;xx
mul cl ;size of box
mov cx,ax ;move to cx as counter
rep movsw ;shift all upwards
jmp short screendn1 ;jump to end
screendm1: pop bx ;balance stack if error
screendn1: sti ;reenable interrupts
pop ds ;restore ds and quit
pop bp ;restore bp
ret 16
screendown endp
;-------------------------------------------------------------------------------
;procedure screenleft(box:pointer; var x,y :byte;; xx,y :byte;);
;-------------------------------------------------------------------------------
;
screenleft proc far
push bp ;preserve register bp
mov bp,sp ;set stack frame
push ds ;save turbo's ds
mov dx,video_buff ;grab video_buff
push dx ;save it
les di,dword ptr[bp+14] ;es:di pts to x
mov al,snow_check ;grab snow_check
mov [bp+16],al ;save on stack
sub cx,cx ;
mov cl,es:[di] ;get column position
jcxz screenlj1 ;quit if column is zero
dec cx ;count from zero
cmp cx,79 ;in range?
jna screenli1 ;jump ahead if so
jmp screenlt1 ;else quit
screenli1: cmp cx,2 ;not on left edge?
jnb screenlk1 ;jump ahead if not
screenlj1: jmp screenlt1 ;else quit routine
screenlk1: dec cx ;old x minus 2
mov es:[di],cl ;change the setting
inc cx ;restore old x pos
mov ax,[bp+20] ;segment of box
mov es,ax ;load in es
mov di,[bp+18] ;offset of box
mov byte ptr[bp+7],0 ;zero out high byte
mov ax,[bp+6] ;y to ax
dec ax ;dec for test
cmp ax,24 ;in range?
jna screenll1 ;jump ahead if so
jmp screenlt1 ;else quit routine
screenll1: inc ax ;readjust
mov byte ptr[bp+9],0 ;zero out high byte
mov bx,[bp+8] ;xx to bx
dec bx ;dec for test
cmp bx,79 ;in range?
jna screenlm1 ;jump ahead if so
jmp screenlt1 ;else quit
screenlm1: inc bx ;readjust
mul bl ;xx times y
shl ax,1 ;double for attributes
add ax,di ;offset to end of box
mov [bp+14],ax ;end of box ptr to stack
mov di,ax ;pt es:di to end of box
lds si,dword ptr[bp+10] ;ds:si pts to y
sub ax,ax ;
mov al,[si] ;get y value
dec ax ;count from zero
cmp ax,24 ;in range?
jna screenln1 ;jump ahead if so
jmp screenlt1 ;else quit
screenln1: mov bl,160 ;bytes per y
mul bl ;calculate y offset
shl cx,1 ;x offset
add ax,cx ;add to y offset
mov si,ax ;si pts to topleft corner
mov [bp+12],si ;save on stack
mov ax,dx ;video_buff
mov ds,ax ;move to ds
mov ax,[bp+8] ;xx
shl ax,1 ;double for attributes
add si,ax ;ds:si pts to topright
mov [bp+10],si ;copy position on stack
pop bx ;video_buff
cld ;set direction
mov si,[bp+12] ;point to topleft corner
sub si,4 ;minus two columns
mov cx,[bp+6] ;y
mov dx,si ;dx holds start x
screenlo1: mov si,dx ;set start x
call boxl_screen ;write a char
call boxl_screen ;write another
add dx,160 ;forward one y
loop screenlo1 ;do next y
mov ax,ds ;ds to ax
mov es,ax ;now es pts to screen too
mov si,[bp+12] ;top left position
mov di,si ;copy to di
sub di,4 ;will shift right by 2
mov dx,[bp+6] ;y
mov ax,[bp+8] ;xx
screenlp1: mov cx,ax ;xx to cx
push di ;save target start
push si ;save source start
screenlq1: call boxl_screen ;write a char
loop screenlq1 ;go do next
pop si ;restore source start
pop di ;restore target start
add di,160 ;forward dest ptr
add si,160 ;forward source ptr
dec dx ;dec y counter
jnz screenlp1 ;loop till image shifted
mov ax,[bp+20] ;segment of box
mov ds,ax ;move to ds
mov si,[bp+18] ;offset of box
mov di,[bp+10] ;es:di pts to old topleft
sub di,4 ;leftwards by 2 cols
mov cx,[bp+6] ;y
mov dx,[bp+8] ;xx
sub dx,2 ;minus 2 for 2 columns
shl dx,1 ;double for attributes
screenlr1: add si,dx ;forward box ptr
call boxl_screen ;write a char
call boxl_screen ;write another
add di,156 ;forward target ptr
loop screenlr1 ;do next y
std ;reverse direction flag
mov ax,ds ;ds pts to box
mov es,ax ;now es does too
mov di,[bp+14] ;offset to end of box
dec di ;dec screen ptr
dec di ;again
mov si,di ;copy to si
sub si,4 ;source pos 2 chars left
mov ax,[bp+6] ;y
mov cx,[bp+8] ;xx
mul cl ;size of box
mov cx,ax ;move to cx as counter
rep movsw ;shift all downwards
mov di,[bp+18] ;offset of box
mov si,[bp+14] ;offset of x
mov cx,[bp+6] ;y
cld ;direction flag forward
screenls1: movsw ;move first word of two
movsw ;move the next
add di,dx ;forward target ptr
loop screenls1 ;go move 2 more chars
jmp short screenlu1 ;jump to end
screenlt1: pop bx ;balance stack if error
screenlu1: sti ;reenable interrupts
pop ds ;restore ds and quit
pop bp ;restore bp
ret 16
screenleft endp
;-------------------------------------------------------------------------------
;procedure screenright(box:pointer; var x,y :byte;; xx,y :byte;);
;-------------------------------------------------------------------------------
;
screenright proc far
push bp ;save bp
mov bp,sp ;set stack frame
push ds ;save turbo's ds
mov dx,video_buff ;grab video_buff
mov bl,snow_check ;grab snow_check
push bx ;save it
les di,dword ptr[bp+14] ;es:di pts to x
sub cx,cx ;
mov cl,es:[di] ;get column position
jcxz screenrti1 ;quit if column is zero
dec cx ;count from zero
mov ax,cx ;copy to ax
mov byte ptr[bp+9],0 ;zero out high byte
add ax,[bp+8] ;add xx
cmp ax,78 ;in range?
jna screenrtj1 ;jump ahead if so
screenrti1: jmp screenrtt1 ;else quit routine
screenrtj1: add cx,3 ;add 2 (+ inc) to x pos
mov es:[di],cl ;change the setting
sub cx,3 ;back to old x position
mov ax,[bp+20] ;segment of box
mov es,ax ;load in es
mov di,[bp+18] ;offset of box
mov byte ptr[bp+7],0 ;zero out high byte
mov ax,[bp+6] ;y to ax
dec ax ;dec for test
cmp ax,24 ;in range?
jna screenrtk1 ;jump ahead if so
jmp screenrtt1 ;else quit routine
screenrtk1: inc ax ;readjust
mov bx,[bp+8] ;xx to bx
dec bx ;dec for test
cmp bx,79 ;in range?
jna screenrtl1 ;jump ahead if so
jmp screenrtt1 ;else quit
screenrtl1: inc bx ;readjust
mul bl ;xx times y
shl ax,1 ;double for attributes
add ax,di ;offset to end of box
mov [bp+14],ax ;end of box ptr to stack
mov di,ax ;pt es:di to end of box
lds si,dword ptr[bp+10] ;ds:si pts to y
sub ax,ax ;
mov al,[si] ;get y value
dec ax ;count from zero
cmp ax,24 ;in range?
jna screenrtm1 ;jump ahead if so
jmp screenrtt1 ;else quit
screenrtm1: mov bl,160 ;bytes per y
mul bl ;calculate y offset
shl cx,1 ;x offset
add ax,cx ;add to y offset
mov si,ax ;si pts to topleft corner
mov [bp+12],si ;save on stack
mov ax,dx ;video_buff
mov ds,ax ;move to ds
mov ax,[bp+8] ;xx
shl ax,1 ;double for attributes
add si,ax ;ds:si pts to topright
mov [bp+10],si ;copy position on stack
pop bx ;restore procedure ptr
cld ;set direction
mov cx,[bp+6] ;y
mov dx,si ;dx holds start x
screenrtn1: mov si,dx ;set start x
call boxr_screen ;write a char
call boxr_screen ;write another
add dx,160 ;forward one y
loop screenrtn1 ;do next y
mov ax,ds ;ds to ax
mov es,ax ;now es pts to screen too
mov si,[bp+10] ;top right position + 2
sub si,2 ;minus 2
mov di,si ;copy to di
add di,4 ;will shift right by 2
std ;reverse direction flag
cmp ax,0b800h ;graphics card?
jb screenrto1 ;jump if monochrome
inc di ;forward ptr to start
inc si ;other ptr
screenrto1: mov dx,[bp+6] ;y
mov ax,[bp+8] ;xx
screenrtp1: mov cx,ax ;xx to cx
push di ;save target start
push si ;save source start
screenrtq1: call boxr_screen ;write a char
loop screenrtq1 ;go do next
pop si ;restore source start
pop di ;restore target start
add di,160 ;forward dest ptr
add si,160 ;forward source ptr
dec dx ;dec y counter
jnz screenrtp1 ;loop till image shifted
cld ;reset direction flag
mov ax,[bp+20] ;segment of box
mov ds,ax ;move to ds
mov si,[bp+18] ;offset of box
mov di,[bp+12] ;es:di pts to old topleft
mov cx,[bp+6] ;y
mov dx,[bp+8] ;xx
sub dx,2 ;minus 2 for 2 columns
shl dx,1 ;double for attributes
screenrtr1: call boxr_screen ;write a char
call boxr_screen ;write another
add di,156 ;forward target ptr
add si,dx ;forward source ptr
loop screenrtr1 ;do next y
mov ax,[bp+20] ;segment of box
mov es,ax ;move to es
mov di,[bp+18] ;offset of box
mov ax,[bp+16] ;segment of x
mov ds,ax ;move to ds
mov si,[bp+14] ;offset of x
add di,4 ;di to new start of box
mov cx,[bp+6] ;y
screenrts1: add di,dx ;forward target ptr
movsw ;move one char of two
movsw ;move the next
loop screenrts1 ;go move 2 more chars
mov di,[bp+18] ;offset to start of box
mov si,di ;copy to si
add si,4 ;si 2 chars to the right
mov ax,[bp+6] ;y
mov cx,[bp+8] ;xx
mul cl ;size of box
mov cx,ax ;move to cx as counter
rep movsw ;shift all downwards
jmp short screenrtu1 ;jump to end
screenrtt1: pop bx ;balance stack if error
screenrtu1: sti ;reenable interrupts
pop ds ;restore ds and quit
pop bp ;restore bp
ret 16
screenright endp
;-------------------------------------------------------------------------------
;procedure screenup(box :pointer; var x,y :byte;; xx,y :byte;);
;-------------------------------------------------------------------------------
;
screenup proc far
push bp ;save bp
mov bp,sp ;set stack frame
push ds ;save turbo's ds
mov dx,video_buff ;grab video_buff
push dx ;save it
les di,dword ptr[bp+14] ;point es:di to x
mov al,snow_check ;grab snow_check
mov [bp+16],al ;save on stack
sub cx,cx ;
mov cl,es:[di] ;get column position
jcxz scrupf1 ;quit if column is zero
dec cx ;count from zero
cmp cx,79 ;in range?
jna scrupg1 ;jump ahead if so
scrupf1: jmp scrupm1 ;else quit
scrupg1: les di,dword ptr[bp+18] ;point es:di to byte array
mov byte ptr[bp+7],0 ;zero out high byte
mov ax,[bp+6] ;y to ax
dec ax ;dec for test
cmp ax,24 ;in range?
jna scruph1 ;jump ahead if so
jmp scrupm1 ;else quit routine
scruph1: inc ax ;readjust
mov byte ptr[bp+9],0 ;zero out high byte
mov bx,[bp+8] ;xx to bx
dec bx ;dec for test
cmp bx,79 ;in range?
jna scrupi1 ;jump ahead if so
jmp scrupm1 ;else quit
scrupi1: inc bx ;readjust
mul bl ;xx times y
shl ax,1 ;double for attributes
add ax,di ;offset to end of box
mov [bp+14],ax ;end of box ptr to stack
mov di,ax ;pt es:di to end of box
lds si,dword ptr[bp+10] ;point ds:si to y
sub ax,ax ;
mov al,[si] ;get y value
cmp ax,1 ;top y already?
je scrupj1 ;quit if so
dec ax ;count from zero
cmp ax,24 ;in range?
jna scrupk1 ;jump ahead if so
scrupj1: jmp scrupm1 ;else quit
scrupk1: mov bx,ax ;copy in bx
add bx,[bp+6] ;add y
cmp bx,25 ;in range?
ja scrupj1 ;quit if so
mov [si],al ;reset y variable
mov bl,160 ;bytes per y
mul bl ;calculate y offset
shl cx,1 ;x offset
add ax,cx ;add to y offset
mov si,ax ;si pts to topleft corner
mov [bp+12],si ;save on stack
mov ax,dx ;video_buff
mov ds,ax ;move to ds
mov ax,[bp+6] ;y
mov cl,160 ;bytes per y
mul cl ;times y
add si,ax ;ds:si pts to topright
mov [bp+10],si ;copy position on stack
pop bx ;video_buff
cld ;set direction
mov si,[bp+12] ;topright position
sub si,160 ;y higher
mov cx,[bp+8] ;xx
shl cx,1 ;double for movsb
call boxu_screen ;write a char
mov ax,ds ;ds to ax
mov es,ax ;now es pts to screen too
mov di,[bp+12] ;top left position
mov si,di ;copy to si
sub di,160 ;di one y higher
mov ax,[bp+6] ;y to ax
scrupl1: mov cx,[bp+8] ;xx to cx
push di ;save target ptr
push si ;save source ptr
shl cx,1 ;double xx for movsb
call boxu_screen ;write a char
pop si ;restore ptr
pop di ;restore ptr
add di,160 ;ptr down one y
add si,160 ;ditto
dec ax ;dec y counter
jnz scrupl1 ;loop till finished
mov ax,[bp+20] ;segment of box
mov ds,ax ;move to ds
mov si,[bp+14] ;offset of end of box
mov di,[bp+10] ;es:di pts to bottomleft
sub di,160 ;one y higher
mov dx,[bp+8] ;xx
shl dx,1 ;double for attributes
sub si,dx ;ds:si pts to last y
mov cx,dx ;use as counter
call boxu_screen ;write a char
std ;reverse direction flag
mov ax,ds ;ds pts to box
mov es,ax ;now es does too
mov di,[bp+14] ;offset to end of box
sub di,2 ;last char of box
mov si,di ;copy to si
sub si,dx ;offset to second y
mov ax,[bp+6] ;y
dec ax ;minus one y
mov cx,[bp+8] ;xx
mul cl ;size of box minus 1 y
mov cx,ax ;move to cx as counter
rep movsw ;shift all upwards
mov di,[bp+18] ;offset of box
mov si,[bp+14] ;end of box
mov cx,[bp+8] ;xx
cld ;direction flag forward
rep movsw ;move new data
jmp short scrupn1 ;jump to end
scrupm1: pop bx ;balance stack if error
scrupn1: sti ;reenable interrupts
pop ds ;restore ds
pop bp ;restore bp
ret
screenup endp
;-------------------------------------------------------------------------------
;procedure fillscreen(ch :char; x,y,xx,y,colour :byte;);
;-------------------------------------------------------------------------------
;
fillscreen proc far
push bp ;save bp
mov bp,sp ;set stack frame
cld ;set direction flag
mov ax,video_buff ;fetch video_buff
mov es,ax ;es pts to screen
mov si,bx ;procedure addr to si
sub ax,ax ;
mov al,[bp+12] ;get y
dec ax ;count from 0
mov dl,160 ;bytes in a y
mul dl ;times y
sub dx,dx ;
mov dl,[bp+14] ;get column
dec dx ;count from 0
shl dx,1 ;double for attributes
add ax,dx ;add to y offset
mov di,ax ;es:di pts to first char
sub bx,bx ;
mov bl,[bp+10] ;xx in bx
or bx,bx ;test for zero
jz fillscrl6 ;quit if zero
sub dx,dx ;
mov dl,[bp+8] ;y in dx
or dx,dx ;test for zero
jz fillscrl6 ;quit if zero
mov al,[bp+16] ;char in al
mov ah,[bp+6] ;attribute in ah
fillscrl1: mov cx,bx ;xx to cx as counter
push di ;save starting point
push dx ;save y counter
fillscrl2: cmp snow_check,0 ;protect against snow?
je fillscrl5 ;jump ahead if not
mov dx,3dah ;status byte address
mov si,ax ;save ax contents
fillscrl3: in al,dx ;get status byte
test al,1 ;test bit
jnz fillscrl3 ;loop till 0
cli ;disable interrupts
fillscrl4: in al,dx ;get status byte
test al,1 ;test bit
jz fillscrl4 ;loop till 1
mov ax,si ;restore ax contents
fillscrl5: stosw ;write char and attribute
loop fillscrl2 ;go do next
pop dx ;restore y counter
pop di ;restore starting point
add di,160 ;forward ptr one y
dec dx ;dec y counter
jnz fillscrl1 ;go do next y
fillscrl6: sti ;reenable interrupts
pop bp ;restore bp
ret 12
fillscreen endp
;-------------------------------------------------------------------------------
;procedure drawbox(char_x ,char_y :char ; x,y,xx,y,colour :byte);
;-------------------------------------------------------------------------------
;
drawbox proc far
push bp ;save bp
mov TPFError,1 ;1 = y out of range
mov bp,sp ;set up stack frame
mov al,[bp+18] ;horz double or single?
mov dh,205 ;assume double
cmp al,68 ;is it a double line ?
je drawboxe1 ;jump ahead if so
cmp al,100 ;is it a double line?
je drawboxe1 ;jump ahead if so
mov dh,196 ;else single line
drawboxe1: mov al,[bp+16] ;vert double or single?
mov dl,186 ;assume double line
cmp al,68 ;double line?
je drawboxg1 ;jump ahead if so
cmp al,100 ;double line?
je drawboxg1 ;jump ahead if so
mov dl,179 ;else single line
cmp dh,196 ;horizontal single?
jne drawboxf1 ;jump ahead if not
mov ax,0dabfh ;top sngl vert, sngl horz
mov bx,0c0d9h ;bot sngl vert, sngl horz
jmp short drawboxi1 ;registers set
drawboxf1: mov ax,0d5b8h ;top sngl vert, dbl horz
mov bx,0d4beh ;bot sngl vert, dbl horz
jmp short drawboxi1 ;registers set
drawboxg1: cmp dh,196 ;horizontal single?
jne drawboxh1 ;jump ahead if not
mov ax,0d6b7h ;top dbl vert, sngl horz
mov bx,0d3bdh ;bot dbl vert, sngl horz
jmp short drawboxi1 ;registers set
drawboxh1: mov ax,0c9bbh ;top dbl vert, dbl horz
mov bx,0c8bch ;bot dbl vert, dbl horz
drawboxi1: mov [bp+18],ax ;save top corners
mov [bp+16],bx ;save bottom corners
mov ax,video_buff ;get ptr to video_buff
mov es,ax ;move to es
sub ax,ax ;
mov al,[bp+12] ;y to ax
dec ax ;count from 0
cmp ax,24 ;in range?
jbe drawboxj1 ;jump ahead if so
jmp drawboxo1 ;else quit routine
drawboxj1: inc TPFError ;2 = column out of range
mov cl,160 ;bytes in a y
mul cl ;times y
sub cx,cx ;
mov cl,[bp+14] ;column to cx
dec cx ;count from 0
cmp cx,79 ;in range?
jna drawboxk1 ;jump ahead if ok
jmp drawboxo1 ;else quit
drawboxk1: inc TPFError ;3 = xx out of range
shl cx,1 ;double for attributes
add ax,cx ;buffer offset
mov di,ax ;es:di pts to offset
sub bx,bx ;
mov bl,[bp+10] ;xx to bx
dec bx ;count from 0
dec bx ;ready for test
cmp bx,78 ;out of range?
ja drawboxo1 ;quit if so
inc TPFError ;4 = y out of range
inc bx ;readjust after test
shl bx,1 ;double for attributes
mov ah,[bp+6] ;attribute to ah
mov al,[bp+19] ;topleft corner to al
call drawb_screen ;write the character
add di,bx ;add offset to scrn ptr
mov al,[bp+18] ;topright corner to al
call drawb_screen ;write the character
sub di,bx ;sub offset from scrn ptr
sub cx,cx ;
mov cl,[bp+8] ;get box y
dec cx ;minus 2
dec cx ; for corners
cmp cx,23 ;test length
ja drawboxo1 ;quit if out of range
mov TPFError,0 ;else no error
push di ;save initial position
add di,160 ;forward screen ptr
jcxz drawboxm1 ;jump if no chr to write
mov al,dl ;vertical char to al
drawboxl1: call drawb_screen ;write the character
add di,bx ;add offset to scrn ptr
call drawb_screen ;write the character
sub di,bx ;sub offset from scrn ptr
add di,160 ;forward screen ptr
loop drawboxl1 ;on to next vert chars
drawboxm1: mov al,[bp+17] ;bottomleft corner to al
call drawb_screen ;write the character
mov al,[bp+16] ;bottomright corner to al
add di,bx ;add offset to scrn ptr
call drawb_screen ;write the character
sub di,bx ;sub offset from scrn ptr
mov bx,di ;save bottom left pos
pop di ;restore top left pos
mov al,dh ;horizontal char to al
sub cx,cx ;
mov cl,[bp+10] ;get xx
dec cx ;minus 2
dec cx ; for corners
jcxz drawboxo1 ;quit if no chrs to print
inc di ;forward scrn ptr
inc di ; to 1st position on top
drawboxn1: call drawb_screen ;write the character
inc di ;forward base ptr
inc di ;...again
inc bx ;forward scrn ptr
inc bx ; for bottom line
xchg di,bx ;get ready to write
call drawb_screen ;write the character
xchg di,bx ;restore scrn ptr
loop drawboxn1 ;go do next char
drawboxo1: sti ;reenable interrupts
pop bp ;restore bp and quit
ret 14
drawbox endp
;-------------------------------------------------------------------------------
;procedure copyclear(box :pointer; x,y,xx,y,colour :byte;);
;-------------------------------------------------------------------------------
;
copyclear proc far
push bp ;save bp
mov bp,sp ;set stack frame
push ds ;save ds
mov bl,snow_check ;grab snow_check
mov ax,video_buff ;fetch video address
mov ds,ax ;ds points to buffer
les di,dword ptr[bp+16] ;es:di pts to byte array
sub ax,ax ;
mov al,[bp+12] ;y in ax
dec ax ;count y from 0
mov dl,160 ;160 bytes per y
mul dl ;ax times 160
sub dx,dx ;
mov dl,[bp+14] ;x in dx
dec dx ;count cols from 0
shl dx,1 ;double for attributes
add ax,dx ;offset of topleft corner
mov dh,[bp+10] ;xx in dh
mov dl,[bp+8] ;y in dl
mov ch,[bp+6] ;fill attribute
mov cl,32 ;space char for fill
mov bp,ax ;scrn ptr copy in bp
mov ah,bl ;move snow_check
mov bx,cx ;copy in bx
sub cx,cx ;clear loop counter
cld ;set direction flag
copyclear1: mov si,bp ;set ds:si scrn ptr
mov cl,dh ;count box xx
push dx ;save xx,y ctr
copyclear2: cmp ah,0 ;protect against snow?
je copyclear7 ;jump ahead if not
mov dx,3dah ;status byte port addr
copyclear3: in al,dx ;get status byte
test al,1 ;test bit
jnz copyclear3 ;loop till 0
cli ;disable interrupts
copyclear4: in al,dx ;get status byte
test al,1 ;test bit
jz copyclear4 ;loop till 1
movsw ;transfer word to buffer
sub si,2 ;pull back screen ptr
copyclear5: in al,dx ;get status byte
test al,1 ;test bit
jnz copyclear5 ;loop till 0
copyclear6: in al,dx ;get status byte
test al,1 ;test bit
jz copyclear6 ;loop till 1
mov [si],bx ;clear cell on screen
add si,2 ;move scrn ptr back
jmp short copyclear8 ;jump ahead
copyclear7: movsw ;monochrome: transf char
mov [si-2],bx ;clear screen cell
copyclear8: loop copyclear2 ;go do next
pop dx ;restore xx,y ctrs
add bp,160 ;forward ptr to next y
dec dl ;dec y counter
jnz copyclear1 ;loop if another line
copyclear9: sti ;reenable interrupts
pop ds ;restore ds
pop bp ;restore bp
ret 14
copyclear endp
;-------------------------------------------------------------------------------
;procedure restorescreen(box :pointer; x,y,xx,y :byte;);
;-------------------------------------------------------------------------------
;
restorescreen proc far
push bp ;save bp
mov bp,sp ;set stack frame
mov bl,snow_check ;grab snow_check
push ds ;save ds
cld ;set direction flag
mov ax,video_buff ;fetch video address
mov es,ax ;es points to screen
lds si,dword ptr[bp+14] ;ds:si pts to byte array
mov [bp+14],bl ;save snow_check on stack
sub ax,ax ;
mov al,[bp+10] ;y in ax
dec ax ;count y from 0
mov dl,160 ;160 bytes per y
mul dl ;ax times 160
sub dx,dx ;
mov dl,[bp+12] ;x in dx
dec dx ;count cols from 0
shl dx,1 ;double for attributes
add ax,dx ;offset of topleft corner
mov bx,ax ;move scrn ptr to bx
mov dh,[bp+8] ;xx in bx
mov dl,[bp+6] ;y in dx
sub cx,cx ;clear cx
restorescrl1: mov di,bx ;set es:di scrn ptr
mov cl,dh ;xx counter
push dx ;save xx,y ctrs
restorescrl2: cmp byte ptr[bp+14],0 ;protect against snow?
je restorescrl5 ;jump ahead if not
mov dx,3dah ;status byte address
restorescrl3: in al,dx ;get status byte
test al,1 ;test bit
jnz restorescrl3 ;loop till 0
cli ;disable interrupts
restorescrl4: in al,dx ;get status byte
test al,1 ;test bit
jz restorescrl4 ;loop till 1
restorescrl5: movsw ;transfer char to scrn
loop restorescrl2 ;go do next in y
pop dx ;restore xx,y ctrs
add bx,160 ;forward ptr to next y
dec dl ;dec y counter
jnz restorescrl1 ;loop if another line
restorescrl6: sti ;reenable interrupts
pop ds ;restore ds
pop bp ;restore bp
ret 12
restorescreen endp
;-------------------------------------------------------------------------------
;procedure savescreen(box :pointer; x,y,xx,y :byte;);
;-------------------------------------------------------------------------------
;
savescreen proc far
push bp ;save bp
mov bp,sp ;set stack frame
push ds ;ds changed
mov bl,snow_check ;getch snow_check
mov ax,video_buff ;fetch video address
mov ds,ax ;ds points to buffer
les di,dword ptr[bp+14] ;es:di pts to box
sub ax,ax ;
mov al,[bp+10] ;y in ax
dec ax ;count y from 0
mov dl,160 ;160 bytes per y
mul dl ;ax times 160
sub dx,dx ;
mov dl,[bp+12] ;x in dx
dec dx ;count cols from 0
shl dx,1 ;double for attributes
add ax,dx ;offset of topleft corner
mov dh,[bp+8] ;xx to dh
mov dl,[bp+6] ;y to dl
sub cx,cx ;clear cx
cld ;set direction flag
savescrl1: mov si,ax ;set ds:si scrn ptr
mov cl,dh ;xx counter
push dx ;save xx, y ctrs
push ax ;save line start ptr
savescrl2: or bl,bl ;protect against snow?
je savescrl5 ;jump ahead if not
mov dx,3dah ;status byte address
savescrl3: in al,dx ;get status byte
test al,1 ;test bit
jnz savescrl3 ;loop till 0
cli ;disable interrupts
savescrl4: in al,dx ;get status byte
test al,1 ;test bit
jz savescrl4 ;loop till 1
savescrl5: movsw ;move word to buffer
loop savescrl2 ;go do next in y
pop ax ;restore line start ptr
pop dx ;restore xx,y ctrs
add ax,160 ;forward ptr to next y
dec dl ;dec y counter
jnz savescrl1 ;loop if another line
savescrl6: sti ;reenable interrupts
pop ds ;restore ds
pop bp ;restore bp
ret 12
savescreen endp
;-------------------------------------------------------------------------------
;procedure scrollx(where :char; x,y,xx,y,cols,colour :byte;);
;-------------------------------------------------------------------------------
;
scrollx proc far
push bp ;save bp
mov bp,sp ;set stack frame
push ds ;save turbo's ds
mov ax,video_buff ;fetch video_buff
mov bl,snow_check ;get snow_check before change ds
mov es,ax ;move to es
mov ds,ax ;copy in ds
sub ax,ax ;
mov al,[bp+14] ;top left y to ax
mov [bp+14],bl ;save snow_check
dec ax ;count from 0
cmp ax,24 ;in range?
jna scrollxl2 ;jump ahead if so
scrollxl1: jmp scrollxl8 ;else quit routine
scrollxl2: mov cl,160 ;bytes per y
mul cl ;times y count
sub cx,cx ;
mov cl,[bp+16] ;top left x to cx
dec cx ;count from 0
cmp cx,79 ;in range?
ja scrollxl1 ;quit if not
shl cx,1 ;double for attributes
add ax,cx ;add to y offset
sub dx,dx ;
mov dl,[bp+10] ;y to dx
or dx,dx ;test for zero length
jz scrollxl1 ;quit if zero
mov cl,[bp+18] ;get direction flag
cmp cl,'l' ;test for 'l'
je scrollxl3 ;jump ahead if 'l'
cmp cl,'l' ;test for 'l'
je scrollxl3 ;jump ahead if 'l'
sub cx,cx ;
mov cl,[bp+12] ;xx to cx
dec cx ;adjust
shl cx,1 ;double for attributes
add ax,cx ;add to x,y position
mov di,ax ;es:di pts to top right
sub cx,cx ;
mov cl,[bp+8] ;get cols to scroll
shl cx,1 ;double for attributes
sub ax,cx ;sub from top right pos
mov si,ax ;ds:si pts to source
std ;set direction for 'r'
jmp short scrollxl4 ;jump ahead
scrollxl3: sub cx,cx ;
mov cl,[bp+8] ;cols to cx
shl cx,1 ;double for attributes
mov di,ax ;es:di pts leftmost char
add ax,cx ;offset to lst scrl char
mov si,ax ;ds:si pts scrl char
cld ;set direction for 'l'
scrollxl4: sub cx,cx ;
mov cl,[bp+12] ;box xx to dx
or cx,cx ;test for zero xx
jz scrollxl8 ;quit routine if zero
sub ax,ax ;
mov al,[bp+8] ;number cols to scroll
or ax,ax ;test for zero cols
jnz scrollxl5 ;jump ahead if not zero
xchg ax,cx ;else cols = xx
jmp short scrollxl6 ;jump ahead
scrollxl5: sub cx,ax ;xx minus cols
cmp cx,0 ;more cols than xx?
jge scrollxl6 ;jump ahead if not
sub ax,ax ;
mov al,[bp+12] ;else cols = xx
mov cx,0 ;scroll = 0
scrollxl6: push ax ;save number cols
push cx ;save xx counter
push si ;save source ptr
push di ;save destination ptr
push dx ;save y counter
push ax ;save number cols
cmp byte ptr[bp+14],0 ;protect against snow?
je scrollxl7 ;jump ahead if not
mov dx,3d8h ;cga mode select register
mov al,25h ;shut off screen
out dx,al ;do it
scrollxl7: pop ax ;restore number cols
pop dx ;restore y counter
rep movsw ;move a y
mov cx,ax ;number cols scrolled
mov al,32 ;clear with spc char
mov ah,[bp+6] ;attribute for clear
rep stosw ;clear opened area
pop di ;restore destination ptr
add di,160 ;forward to next line
pop si ;restore source ptr
add si,160 ;forward to next line
pop cx ;restore xx counter
pop ax ;restore num cols
dec dx ;dec the y counter
jnz scrollxl6 ;loop until finished
cmp byte ptr[bp+14],0 ;protected against snow?
je scrollxl8 ;jump if not
mov dx,3d8h ;cga mode select register
mov al,41 ;80x25, blink enabled
out dx,al ;reenable video
scrollxl8: pop ds ;restore ds
pop bp ;restore bp
ret 14
scrollx endp
;-------------------------------------------------------------------------------
;procedure scrolly(where :char; x,y,xx,yy,lines,colour :byte;);
;-------------------------------------------------------------------------------
;
scrolly proc far
push bp ;save bp
mov bp,sp ;set stack frame
mov ah,7 ;assume downward scroll
mov al,[bp+18] ;get direction code
cmp al,'d' ;downward scroll?
je scrollyl1 ;jump ahead if so
cmp al,'d' ;downward scroll?
je scrollyl1 ;jump ahead if so
mov ah,6 ;else code to scroll up
scrollyl1: mov cl,[bp+16] ;top left x in cl
dec cl ;count from 0
mov ch,[bp+14] ;top left y in ch
dec ch ;count from 0
mov dl,[bp+12] ;xx in dl
dec dl ;adjust
add dl,cl ;bottom right x in dl
mov dh,[bp+10] ;y in dh
dec dh ;adjust
add dh,ch ;bottom right y in dh
mov al,[bp+8] ;number lines in al
mov bh,[bp+6] ;fill attribute
int 10h ;make the scroll
pop bp ;restore bp and quit
ret 14
scrolly endp
;-------------------------------------------------------------------------------
; local procedures used by other procedures
;-------------------------------------------------------------------------------
boxd_screen proc
push dx ;save dx
push ax ;save ax
mov dx,3dah ;status byte address
mov bx,es ;get target segment
mov ax,ds ;get source segment
cmp ax,bx ;is source larger?
jna boxdscra1 ;jump if not
mov bx,ax ;else use source
boxdscra1: cmp byte ptr[bp+16],0 ;protect against snow?
je boxdscrd1 ;jump ahead if not
boxdscrb1: in al,dx ;get status byte
test al,1 ;test bit
jnz boxdscrb1 ;loop till 0
cli ;disable interrupts
boxdscrc1: in al,dx ;get status byte
test al,1 ;test bit
jz boxdscrc1 ;loop till 1
boxdscrd1: movsb ;move a character
loop boxdscra1 ;go do next
pop ax ;restore ax
pop dx ;restore dx
ret ;
boxd_screen endp
;-------------------------------------------------------------------------------
boxl_screen proc
push dx ;save dx
push ax ;save ax too
mov dx,es ;get target segment
mov ax,ds ;get source segment
cmp ax,dx ;is source larger?
jna boxlscra1 ;jump if not
mov dx,ax ;else use source
boxlscra1: cmp byte ptr[bp+16],0 ;protect against snow?
je boxlscrf1 ;jump ahead if not
mov dx,3dah ;status byte address
boxlscrb1: in al,dx ;get status byte
test al,1 ;test bit
jnz boxlscrb1 ;loop till 0
cli ;disable interrupts
boxlscrc1: in al,dx ;get status byte
test al,1 ;test bit
jz boxlscrc1 ;loop till 1
movsb ;write a char
boxlscrd1: in al,dx ;get status byte
test al,1 ;test bit
jnz boxlscrd1 ;loop till 0
boxlscre1: in al,dx ;get status byte
test al,1 ;test bit
jz boxlscre1 ;loop till 1
movsb ;write a char
jmp short boxlscrg1 ;jump ahead and quit
boxlscrf1: movsw ;move the character
boxlscrg1: pop ax ;restore ax
pop dx ;restore dx
ret ;
boxl_screen endp
;-------------------------------------------------------------------------------
boxr_screen proc
push dx ;save dx
push bx ;save bx
push ax ;save ax
mov dx,es ;get target segment
mov ax,ds ;get source segment
cmp ax,dx ;is source larger?
jna boxriscra1 ;jump if not
mov dx,ax ;else use source
boxriscra1: cmp bl,0 ;protect against snow?
je boxriscrf1 ;jump ahead if not
mov dx,3dah ;status byte address
boxriscrb1: in al,dx ;get status byte
test al,1 ;test bit
jnz boxriscrb1 ;loop till 0
boxriscrc1: in al,dx ;get status byte
test al,1 ;test bit
jz boxriscrc1 ;loop till 1
movsb ;move a character
boxriscrd1: in al,dx ;get status byte
test al,1 ;test bit
jnz boxriscrd1 ;loop till 0
boxriscre1: in al,dx ;get status byte
test al,1 ;test bit
jz boxriscre1 ;loop till 1
movsb ;move a character
jmp short boxriscrg1 ;jump ahead and quit
boxriscrf1: movsw ;move the character
boxriscrg1: pop ax ;restore ax
pop bx ;restore bx
pop dx ;restore dx
ret ;
boxr_screen endp
;-------------------------------------------------------------------------------
boxu_screen proc
push dx ;save dx
push ax ;save ax
mov dx,3dah ;status byte address
mov bx,es ;get target segment
mov ax,ds ;get source segment
cmp ax,bx ;is source larger?
jna boxuscra1 ;jump if not
mov bx,ax ;else use source
boxuscra1: cmp byte ptr[bp+16],0 ;protect against snow?
je boxuscrd1 ;jump ahead if not
boxuscrb1: in al,dx ;get status byte
test al,1 ;test bit
jnz boxuscrb1 ;loop till 0
cli ;disable interrupts
boxuscrc1: in al,dx ;get status byte
test al,1 ;test bit
jz boxuscrc1 ;loop till 1
boxuscrd1: movsb ;move a character
loop boxuscra1 ;go do next
pop ax ;restore ax
pop dx ;restore dx
ret ;
boxu_screen endp
;-------------------------------------------------------------------------------
drawb_screen proc ;procedures writes char,
push dx ;fix snow
push bx ;save dx and bx
cld ;set direction flag
cmp snow_check,0 ;protect against snow?
je dboxscrc1 ;jump ahead if not
mov dx,3dah ;status byte address
mov bx,ax ;store ax contents
dboxscra1: in al,dx ;get status byte
test al,1 ;test bit
jnz dboxscra1 ;loop till 0
cli ;disable interrupts
dboxscrb1: in al,dx ;get status byte
test al,1 ;test bit
jz dboxscrb1 ;loop till 1
mov ax,bx ;restore ax contents
dboxscrc1: stosw ;write the character
dec di ;pull ptr back
dec di ;again
pop bx ;restore bx
pop dx ;restore dx and return
ret
drawb_screen endp
code ends
end