home *** CD-ROM | disk | FTP | other *** search
- ; File......: SAVEATT.ASM
- ; Author....: Ted Means
- ; Date......: $Date: 15 Aug 1991 23:07:58 $
- ; Revision..: $Revision: 1.1 $
- ; Log file..: $Logfile: E:/nanfor/src/saveatt.asv $
- ;
- ; This is an original work by Ted Means and is placed in the
- ; public domain.
- ;
- ; Modification history:
- ; ---------------------
- ;
- ; $Log: E:/nanfor/src/saveatt.asv $
- ;
- ; Rev 1.1 15 Aug 1991 23:07:58 GLENN
- ; Forest Belt proofread/edited/cleaned up doc
- ;
- ; Rev 1.0 12 Jun 1991 01:30:20 GLENN
- ; Initial revision.
- ;
-
-
- ; $DOC$
- ; $FUNCNAME$
- ; FT_SAVEATT()
- ; $CATEGORY$
- ; Video
- ; $ONELINER$
- ; Save the attribute bytes of a specified screen region.
- ; $SYNTAX$
- ; FT_SAVEATT( <nTop>, <nLeft>, <nBottom>, <nRight> ) -> cAttributes
- ; $ARGUMENTS$
- ; <nTop>, <nLeft>, <nBottom>, and <nRight> define the screen region.
- ; $RETURNS$
- ; A character string containing the screen attribute bytes for the
- ; specified region. If the memory to store the return value could
- ; not be allocated, the function returns NIL.
- ; $DESCRIPTION$
- ; This function is similar to Clipper's SaveScreen(), except that it only
- ; saves the attribute bytes. This is useful if you want to change the
- ; screen color without affecting the text.
- ;
- ; *** INTERNALS ALERT ***
- ;
- ; This function calls the Clipper internal __gtMaxCol to obtain the
- ; maximum column value for the current video mode. If you're too gutless
- ; to use internals, then this function isn't for you.
- ; $EXAMPLES$
- ; // Save attributes of row 4
- ; cBuffer := FT_SAVEATT( 4, 0, 4, maxcol())
- ;
- ; // Save attributes from middle of screen
- ; cBuffer := FT_SAVEATT(10,20,14,59)
- ; $SEEALSO$
- ; FT_RESTATT()
- ; $END$
- ;
-
- IDEAL
-
- Public FT_SAVEATT
-
- Extrn __ParNI:Far
- Extrn __gtMaxCol:Far ; INTERNAL!! INTERNAL!!
- Extrn __XAlloc:Far
- Extrn __XFree:Far
- Extrn __RetCLen:Far
-
- Upper EQU Word Ptr BP - 2
- Left EQU Word Ptr BP - 4
- Lower EQU Word Ptr BP - 6
- Right EQU Word Ptr BP - 8
- BufSize EQU Word Ptr BP - 10
- BufSeg EQU Word Ptr BP - 12
- BufOfs EQU Word Ptr BP - 14
- BufPtr EQU DWord Ptr BP - 14
- MaxCol EQU Word Ptr BP - 16
-
- Segment _NanFor Word "CODE"
- Assume CS:_NanFor
-
- Proc FT_SAVEATT Far
-
- Push BP ; Save BP
- Mov BP,SP ; Set up stack reference
- Sub SP,16 ; Allocate space for locals
-
- Call __gtMaxCol ; Get current value of maxcol()
- Inc AX ; Set to number of columns
- Mov [MaxCol],AX ; Store it in local
-
- Mov AX,1 ; Specify param #1
- Push AX ; Put on stack
- Call __ParNI ; Get value
- Mov [Upper],AX ; Store in local
-
- Mov AX,2 ; Specify param #2
- Push AX ; Put on stack
- Call __ParNI ; Get value
- Mov [Left],AX ; Store in local
-
- Mov AX,3 ; Specify param #3
- Push AX ; Put on stack
- Call __ParNI ; Get value
- Mov [Lower],AX ; Store in local
-
- Mov AX,4 ; Specify param #4
- Push AX ; Put on stack
- Call __ParNI ; Get value
- Mov [Right],AX ; Store in local
- Add SP,8
-
- Mov AX,[Right] ; Load right column
- Sub AX,[Left] ; Subtract left
- Inc AX ; Get column count
- Mov DX,[Lower] ; Load lower row
- Sub DX,[Upper] ; Subtract upper
- Inc DX ; Get row count
- Mul DX ; Calculate buffer size
- Mov [BufSize],AX ; Store in local
- Push AX ; Put on stack
- Call __XAlloc ; Allocate buffer
- Add SP,2 ; Realign stack
- Mov [BufSeg],DX ; Load segment into local
- Mov [BufOfs],AX ; Load offset into local
- Or DX,AX ; Check for null pointer
- JZ Exit ; If so, allocation failed
-
- SetPtr: Push DS ; Save appropriate registers and
- Push SI ; make sure direction flag clear
- Push DI
- CLD
-
- LES DI,[BufPtr] ; Load pointer to buffer
- Xor AX,AX ; Clear AX
- Mov DS,AX ; Point DS to low memory
- Mov AX,0B800h ; Initialize video base
- Cmp [Word Ptr 463h],3B4h ; Monochrome?
- JNE SetVid ; No, continue
- Mov AX,0B000h ; Set video base to mono
-
- SetVid: Mov DS,AX ; Set video base
- Xor SI,SI ; Start at offset 0
- Mov CX,[Lower] ; Get lower row
- Sub CX,[Upper] ; Subtract upper row
- Inc CX ; Get number of rows
-
- Rows: Mov AX,CX ; Get row number
- Sub AX,[Lower] ; Subtract last row
- Dec AX ; Get negation of row
- Neg AX ; Convert to abs()
- Mul [MaxCol] ; Multiply by column count
- SHL AX,1 ; Multiply by two
- Mov BX,[Left] ; Get left column
- SHL BX,1 ; Multiply by two
- Inc BX ; Point to attribute byte
- Add BX,AX ; Add rows * columns
- Push CX ; Save row indicator
- Mov CX,[Right] ; Load right column
- Sub CX,[Left] ; Subtract left column
- Inc CX ; Get number of columns
- Cols: Mov AL,[Byte Ptr BX + SI] ; Load attribute byte
- Stosb ; Store in allocated string
- Add BX,2 ; Point to next attribute byte
- Loop Cols ; Get next byte
- Pop CX ; Restore row indicator
- Loop Rows ; Do next row
-
- Done: Pop DI ; Restore registers
- Pop SI
- Pop DS
- Push [BufSize] ; Put buffer size on stack
- Push [BufSeg] ; Put buffer segment on stack
- Push [BufOfs] ; Put buffer offset on stack
- Call __RetCLen ; Return string to Clipper app
- Call __XFree ; Free memory held by buffer
- Exit: Mov SP,BP
- Pop BP
- Ret
- Endp FT_SAVEATT
- Ends _NanFor
- End
-