home *** CD-ROM | disk | FTP | other *** search
- ; WINDOWER.ASM This is a window management system, intended to be linked
- ; with programs written in Microsoft high-level languages.
- ; It can be used to draw and restore windows in a variety of
- ; styles and colours. Windows can be zoomed onto the screen
- ; and may have shadows to the left or right if required.
- ;
- ; Author: Christy Gemmell
- ; For: Assembly-Language ToolBox for QuickBASIC
- ; Version: 5.00
- ; Date: 17/6/1991
- ;
- ; Compatible with QuickBASIC 4.x, Extended QuickBASIC and BASIC 7
- ; Assembled with MicroSoft Macro Assembler, MASM version 5.1
- ;
- ; Exploding and imploding windows implemented 17/6/91
- ;
- ;┌────────────────────────────────────────────────────────────────────────┐
- ;│ Global symbols and procedures. │
- ;└────────────────────────────────────────────────────────────────────────┘
- ;
- .model medium
-
- extrn Delay:proc
- extrn Explode:proc
- extrn ScreenAddress:proc
- extrn ScreenCopy:proc
- extrn ScreenWrite:proc
- extrn VideoType:proc
- extrn WriteByte:proc
-
- public PopUp, ShutUp
-
- .code
-
- ;┌────────────────────────────────────────────────────────────────────────┐
- ;│ Data Division. │
- ;└────────────────────────────────────────────────────────────────────────┘
- ;
- Signature db ' WINDOW MANAGER By Christy Gemmell '
-
- Ulc label word ; Upper left co-ordinate
- TlRow db ? ; Top left screen row
- TlCol db ? ; Top left screen column
- Lrc label word ; Lower right co-ordinate
- BrCol db ? ; Right column of window
- BrRow db ? ; Bottom row of window
- Area label word
- Breadth db ? ; Window width (inc shadow)
- Height db ? ; Window Height (inc shadow)
- ToDo label word
- Cols2do db ? ; Columns to restore
- Rows2do db ? ; Rows to restore
- Rows db ? ; Screen length in rows
- Columns db ? ; Screen width in columns
- Increment dw ? ; Interval between rows
- BuffPtr dw ? ; Pointer to current buffer
- BuffTop dw ? ; Offset of first buffer row
- BuffEnd dw ? ; Offset of last buffer row
- WinTop dw ? ; Offset of first screen row
- WinEnd dw ? ; Offset of last screen row
-
- TopLeft label byte
- db ' ┌╔╒╓╤╦┬╥' ; TL Corner characters
- TopRight label byte
- db ' ┐╗╕╖╤╦┬╥' ; TR Corner characters
- BotLeft label byte
- db ' └╚╘╙╘╚└╙' ; BL Corner characters
- BotRight label byte
- db ' ┘╝╛╜╛╝┘╜' ; BR Corner characters
- Vertical label byte
- db ' │║│║│║│║' ; Vertical characters
- Horizontal label byte
- db ' ─══─══──' ; Horizontal characters
-
- Buffer label byte ; Start of screen buffer
- db 4000h dup(0)
- BufferTop dw 0 ; End of screen Buffer
-
- ;┌────────────────────────────────────────────────────────────────────────┐
- ;│ POPUP | Save a screen rectangle and replace it with a window. │
- ;└────────────────────────────────────────────────────────────────────────┘
- ;
- PopUp proc far
- push bp ; Save Base pointer
- mov bp,sp ; Establish stack frame
- push ds ; Preserve segment
- push es ; registers and
- push di ; index
- push si ; pointers
- call VideoType ; Get video parameters
- push cs ; Align Code and
- pop ds ; Data segments
- mov Rows,bl ; Store screen height
- mov Columns,ah ; Store screen width
- mov al,ah ; Transfer number of
- xor ah,ah ; columns to AX
- shl ax,1 ; and convert
- mov Increment,ax ; to bytes
- mov al,[bp+20] ; Get top-left row
- dec al ; Make it base zero
- cmp al,0 ; Check for
- jae Pop_01 ; legal
- xor al,al ; values
- Pop_01:
- mov TlRow,al ; Save top-left row
- mov al,[bp+18] ; Get top-left column
- dec al ; Make it base zero
- cmp al,0 ; Check for
- ja Pop_02 ; legal
- mov al,1 ; values
- Pop_02:
- mov TlCol,al ; Store top-left column
- mov al,[bp+16] ; Get window height
- cmp al,2 ; Check for
- ja Pop_03 ; legal
- mov al,3 ; values
- Pop_03:
- mov [bp+16],al ; Store window height
- mov al,[bp+14] ; Get window width
- cmp al,2 ; Check for
- ja Pop_04 ; legal
- mov al,3 ; values
- Pop_04:
- mov [bp+14],al ; Store window width
- mov al,TlRow ; Get start row
- mov ah,[bp+16] ; Get number of rows
- add al,ah ; Add 'em together
- cmp al,Rows ; Out of bounds?
- jb Pop_05 ; No, carry on
- jmp Pop_38 ; Else abort
- Pop_05:
- dec al ; Store bottom
- mov BrRow,al ; row number
- mov al,TlCol ; Get start column
- mov ah,[bp+14] ; Get number of columns
- add al,ah ; Add 'em together
- cmp al,Columns ; Out of bounds?
- jb Pop_06 ; No, carry on
- jmp Pop_38 ; Else abort
- Pop_06:
- dec al ; Store rightmost
- mov BrCol,al ; column number
- mov al,[bp+10] ; Get required border type
- cmp al,0 ; Check
- jb Pop_07 ; for
- cmp al,8 ; legal
- ja Pop_07 ; values
- jmp short Pop_08
- Pop_07:
- mov byte ptr [bp+10],1 ; Set default (single line)
- Pop_08:
- mov ax,[bp+8] ; See if shadow is required
- cmp al,0 ; Check
- jb Pop_09 ; for
- cmp al,4 ; legal
- ja Pop_09 ; values
- jmp short Pop_10
- Pop_09:
- mov byte ptr [bp+8],0 ; Set default (no shadow)
- Pop_10:
- cmp word ptr [bp+6],0 ; Check for
- jge Pop_11 ; legal
- mov word ptr [bp+6],20 ; values
- Pop_11:
- mov ax,1 ; Initialise
- push ax ; millisecond
- call Delay ; delay routine
- xor ax,ax ; Get number of rows
- mov al,[bp+16] ; into AX
- xor bx,bx ; Get number of columns
- mov bl,[bp+14] ; into BX
- cmp byte ptr [bp+8],0 ; Shadow required?
- jz Pop_12 ; No, skip next bit
- inc al ; Add a row
- inc bl ; and a column
- Pop_12:
- mov Height,al ; Store adjusted height
- mov Breadth,bl ; Store adjusted width
- mul bl ; Find area
- shl ax,1 ; in bytes
- mov cx,ax ; Transfer to CX
- mov si,offset Buffer ; Start of screen stack
- Pop_13:
- cmp word ptr [si],0 ; Is anything there?
- jz Pop_14 ; No, must be free space
- mov si,[si] ; Point to next block
- jmp Pop_13 ; and try again
- Pop_14:
- mov ax,si ; Point AX to entry
- add ax,6 ; Allow for pointers
- add ax,cx ; and area to be saved
- mov dx,offset BufferTop ; Point DX to end of stack
- cmp ax,dx ; Enough space left?
- jb Pop_15 ; Yes, Carry on
- jmp Pop_38 ; Otherwise abort
- Pop_15:
- mov [si],ax ; Set pointer to next block
- mov ax,Ulc ; Get row-column co-ordinates
- call ScreenAddress ; Convert to memory address
- mov WinTop,di ; Save it for later
- test byte ptr [bp+8],1 ; Left shadow?
- jz Pop_16 ; No, skip next bit
- dec di ; One column
- dec di ; to the left
- Pop_16:
- inc si ; Bump buffer
- inc si ; pointer
- mov [si],di ; Store it in buffer
- inc si ; Bump buffer
- inc si ; pointer
- mov ax,Area ; Get panel Area
- mov [si],ax ; Store them in the buffer
- inc si ; Bump pointer to
- inc si ; screen storage block
- xor cx,cx ; Get number of rows
- mov cl,ah ; in CX
- xchg di,si ; Swap pointers
- push ds ; Point DS to
- push es ; video segment
- pop ds ; and ES to
- pop es ; local data
- Pop_17:
- push cx ; Save row count
- push si ; Save screen pointer
- mov cl,cs:Breadth ; Set column count
- Pop_18:
- call ScreenCopy ; Copy word from screen
- loop Pop_18 ; For length of row
- pop si ; Bump pointer
- add si,cs:Increment ; to next row
- pop cx ; Recover row count
- loop Pop_17 ; For each row
- push es ; Realign Code and
- pop ds ; Data segments
- xor ah,ah ; Get all parameters in AX
- mov al,TlRow ; Get upper-left row
- inc al ; Must use BASIC numbering
- push ax ; Pass the argument
- mov al,TlCol ; Get upper-left column
- inc al ; Must use BASIC numbering
- push ax ; Pass the argument
- mov al,BrRow ; Get lower-right row
- inc al ; Must use BASIC numbering
- push ax ; Pass the argument
- mov al,BrCol ; Get lower-right column
- inc al ; Must use BASIC numbering
- push ax ; Pass the argument
- push [bp+12] ; Pass display attribute
- push [bp+6] ; Pass speed value
- call Explode ; Display the window
- mov ax,Ulc ; Get row/column co-ordinate
- call ScreenAddress ; Convert to memory address
- cmp byte ptr [bp+10],0 ; Border required?
- ja Pop_19 ; Yes, draw it
- jmp Pop_23 ; Else check for shadow
- Pop_19:
- xor bx,bx ; Border type
- mov bl,[bp+10] ; to BX
- mov ah,[bp+12] ; Attribute to AH
- push di ; Save screen offset
- mov al,TopLeft[bx] ; Border character to AL
- call ScreenWrite ; Send it to the screen
- mov al,Horizontal[bx] ; Border character to AL
- xor cx,cx ; Window width
- mov cl,[bp+14] ; to CX
- dec cl ; Subtract
- dec cl ; corners
- Pop_20:
- call ScreenWrite ; Send it to the screen
- loop Pop_20
- mov al,TopRight[bx] ; Border character to AL
- call ScreenWrite ; Send it to the screen
- pop di ; Recover offset
- add di,Increment ; Bump to next row
- mov al,Vertical[bx] ; Border character to AL
- mov cl,[bp+16] ; Window height to CX
- dec cl ; Subtract top and
- dec cl ; bottom rows
- Pop_21:
- push cx ; Save counter
- push di ; Save screen pointer
- call ScreenWrite ; Left border
- mov cl,[bp+14] ; Get window width
- dec cl ; Point
- dec cl ; to
- shl cx,1 ; rightmost
- add di,cx ; column
- call ScreenWrite ; Right border
- pop di ; Recover screen pointer
- add di,Increment ; Bump to next row
- pop cx ; Recover row count
- loop Pop_21 ; For each row
- mov al,BotLeft[bx] ; Border character to AL
- call ScreenWrite ; Send it to the screen
- mov al,Horizontal[bx] ; Border character to AL
- mov cl,[bp+14] ; Get window width
- dec cl ; Subtract
- dec cl ; corners
- Pop_22:
- call ScreenWrite ; Send it to the screen
- loop Pop_22
- mov al,BotRight[bx] ; Border character to AL
- call ScreenWrite ; Send it to the screen
- Pop_23:
- cmp byte ptr [bp+8],0 ; Shadow required?
- ja Pop_24 ; Yes, handle it
- jmp Pop_37 ; Else wrap everything up
- Pop_24:
- mov di,WinTop ; Back to top-left corner
- add di,Increment ; start at next row down
- xor cx,cx ; Get window width
- mov cl,[bp+14] ; into CX
- shl cx,1 ; Include attribute bytes
- cmp byte ptr [bp+8],2 ; Solid shadow?
- ja Pop_30 ; No, make it transparant
- cmp byte ptr [bp+8],1 ; Left shadow?
- jne Pop_25 ; No, must be right
- dec di ; Left one
- dec di ; column
- jmp short Pop_26 ; Get to work
- Pop_25:
- add di,cx ; Offset past right-hand edge
- Pop_26:
- mov ax,720h ; Space on black background
- push cx ; Save width for now
- mov cl,[bp+16] ; Rows to shadow
- Pop_27:
- call ScreenWrite ; Send it to the screen
- add di,Increment ; Bump to
- dec di ; next
- dec di ; row
- loop Pop_27 ; For height of window
- pop cx ; Recover window width
- sub di,Increment ; Back up one row
- cmp byte ptr [bp+8],1 ; Left shadow?
- je Pop_28 ; No, must be right
- sub di,cx ; Jump back to start of row
- inc di ; Begin one column
- inc di ; in from left
- Pop_28:
- shr cx,1 ; Convert width to columns
- Pop_29:
- call ScreenWrite ; Put black shadow
- loop Pop_29 ; under the bottom row
- jmp short Pop_37 ; Branch to the exit
- Pop_30:
- cmp byte ptr [bp+8],3 ; Left shadow?
- jne Pop_31 ; No, must be right
- dec di ; Left one
- dec di ; column
- jmp short Pop_32 ; Get to work
- Pop_31:
- add di,cx ; Offset past right-hand edge
- Pop_32:
- inc di ; Bump to attribute byte
- mov al,8 ; Dark grey background
- push cx ; Save width for now
- mov cl,[bp+16] ; Rows to shadow
- Pop_33:
- call WriteByte ; Set display attribute
- add di,Increment ; Bump to
- dec di ; next row
- loop Pop_33 ; For height of window
- pop cx ; Recover window width
- sub di,Increment ; Back up
- inc di ; one row
- cmp byte ptr [bp+8],3 ; Left shadow?
- jne Pop_34 ; No, must be right
- dec di ; Back up one column
- jmp short Pop_35 ; Start on bottom row
- Pop_34:
- sub di,cx ; Jump back to the
- inc di ; beginning of the row
- Pop_35:
- shr cx,1 ; Convert width to columns
- Pop_36:
- call WriteByte ; Set display attribute
- inc di ; Bump past character byte
- loop Pop_36 ; For width of window
- Pop_37:
- xor ax,ax ; Report no error
- Pop_38:
- pop si ; Clean up the stack
- pop di
- pop es
- pop ds
- pop bp
- ret 16 ; Return to caller
- PopUp endp
-
- ;┌────────────────────────────────────────────────────────────────────────┐
- ;│ Close the last window opened by restoring the screen under it. │
- ;└────────────────────────────────────────────────────────────────────────┘
- ;
- ; If a delay is specified, this routine produces the effect of imploding
- ; the storage buffer contents onto the screen, making the window appear
- ; to vanish into a point source.
- ;
- ShutUp proc far
- push bp ; Save base pointer
- mov bp,sp ; Establish stack frame
- push ds ; Save segment
- push es ; registers and
- push di ; index
- push si ; pointers
- push cs ; Align code and
- pop ds ; data segments
- cld ; Clear direction forward
- call VideoType ; Get video parameters
- mov al,ah ; Transfer number of
- xor ah,ah ; columns to AX
- shl ax,1 ; and convert
- mov Increment,ax ; to bytes
- mov si,offset Buffer ; DS:SI==> screen buffer
- xor ax,ax ; Initialise
- push ax ; back pointer
- Shut_01:
- cmp word ptr [si],0 ; Is anything there?
- jz Shut_02 ; No, we're at the end
- pop ax ; Retrieve pointer
- push si ; Save present pointer
- mov si,[si] ; Point to next block
- jmp Shut_01 ; Keep searching
- Shut_02:
- pop si ; Retrieve last pointer
- cmp si,0 ; Was there anything?
- jnz Shut_03 ; Yes, proceed
- mov ax,1 ; Else set Errorlevel
- jmp Shut_14 ; and abort
- Shut_03:
- mov BuffPtr,si ; Save buffer pointer
- inc si ; Bump to
- inc si ; next entry
- mov di,[si] ; ES:DI==> screen location
- mov WinTop,di ; Save screen offset
- inc si ; Bump to
- inc si ; next entry
- mov ax,[si] ; Get panel dimensions
- mov Area,ax ; Store them
- mov ToDo,ax ; for later
- inc si ; Bump to screen
- inc si ; storage block
- mov BuffTop,si ; Save buffer pointer
- xor bx,bx ; AX has window width
- xchg bl,ah ; BX has window height
- dec bl ; less one row
- shl bx,1 ; Convert to bytes
- mul bx ; Calculate offset
- add ax,si ; of the last row
- mov BuffEnd,ax ; Save this as well
- mov ax,Increment ; Multiply screen width
- mov bl,Height ; by window height
- dec bl ; less one row
- mul bx ; Result is relative offset
- add ax,di ; Now convert it to the
- mov WinEnd,ax ; absolute screen offset
- xor ax,ax ; Get video segment
- call ScreenAddress ; and CRT status port
- cmp word ptr [bp+6],0 ; Check for
- jge Shut_04 ; legal delay
- mov word ptr [bp+6],20 ; values
- Shut_04:
- xor cx,cx ; Clear counter
- mov si,BuffTop ; DS:SI==> first buffer row
- mov di,WinTop ; ES:DI==> first screen row
- mov cl,Cols2do ; Number of words to copy
- Shut_05:
- call ScreenCopy ; Send word to the screen
- loop Shut_05 ; For length of row
- dec Rows2do ; All rows done?
- jnz Shut_06 ; No, carry on
- jmp Shut_13 ; Otherwise depart
- Shut_06:
- mov si,BuffEnd ; DS:SI==> last buffer row
- mov di,WinEnd ; ES:DI==> last screen row
- mov cl,Cols2do ; Number of words to copy
- Shut_07:
- call ScreenCopy ; Send word to the screen
- loop Shut_07 ; For length of row
- dec Rows2do ; All rows done?
- jnz Shut_08 ; No, carry on
- jmp Shut_13 ; Otherwise depart
- Shut_08:
- xor ax,ax ; Clear AX
- mov si,BuffTop ; Reset
- mov al,Breadth ; pointer
- shl al,1 ; to first
- add si,ax ; buffer
- mov BuffTop,si ; row
- mov di,WinTop ; Do the same
- add di,Increment ; for the first
- mov WinTop,di ; screen row
- mov ax,BuffEnd ; Reset
- mov cl,Breadth ; pointer
- shl cl,1 ; to last
- sub ax,cx ; buffer
- mov BuffEnd,ax ; row
- mov ax,WinEnd ; Do the same
- sub ax,Increment ; for the last
- mov WinEnd,ax ; screen row
- Shut_09:
- cmp si,BuffEnd ; End of buffer?
- ja Shut_10 ; Yes, see if we've finished
- call ScreenCopy ; Send word to the screen
- xor ax,ax ; Clear AX again
- mov al,Breadth ; Keep
- dec al ; doing
- shl al,1 ; it
- add si,ax ; all
- add di,Increment ; down
- dec di ; the
- dec di ; left
- jmp short Shut_09 ; side
- Shut_10:
- dec Cols2do ; All columns done?
- jz Shut_13 ; If so, depart
- mov al,Cols2do ; How far to the
- shl al,1 ; end of the row?
- mov si,BuffTop ; Point SI to
- add si,ax ; buffer data
- mov di,WinTop ; Point DI to
- add di,ax ; screen offset
- Shut_11:
- call ScreenCopy ; Send word to the screen
- cmp si,BuffEnd ; End of buffer?
- ja Shut_12 ; Yes, see if we're finished
- xor ax,ax ; Clear AX again
- mov al,Breadth ; Keep
- dec al ; doing
- shl al,1 ; it
- add si,ax ; all
- add di,Increment ; down
- dec di ; the
- dec di ; right
- jmp short Shut_11 ; side
- Shut_12:
- dec Cols2do ; All columns done?
- jz Shut_13 ; If so, depart
- add BuffTop,2 ; Each subsequent
- add BuffEnd,2 ; row starts
- add WinTop,2 ; another word
- add WinEnd,2 ; further in
- push [bp+6] ; Pass speed value
- call Delay ; Pause awhile
- jmp Shut_04 ; Then do it all again
- Shut_13:
- mov di,BuffPtr ; Recover buffer pointer
- mov cx,[di] ; Pointer to next block
- sub cx,di ; Calculate length of block
- inc cx
- push ds ; Point ES to Data Segment
- pop es
- xor ax,ax ; Clear AX
- rep stosb ; Zero restored block
- Shut_14:
- pop si ; Clean up the stack
- pop di
- pop es
- pop ds
- pop bp
- ret 2 ; Return to caller
- ShutUp endp
-
- end
-
- ;┌────────────────────────────────────────────────────────────────────────┐
- ;│ (c) 1988,1991 By Christy Gemmell and Singular SoftWare. │
- ;└────────────────────────────────────────────────────────────────────────┘
-