home *** CD-ROM | disk | FTP | other *** search
- ; _______________________________________________________________
- ; | |
- ; | 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
-