Category : Assembly Language Source Code
Archive   : JED.ZIP
Filename : VIDBLAST.ASM

 
Output of file : VIDBLAST.ASM contained in archive : JED.ZIP
;===========================================================================
;
; V I D B L A S T - Blast character pattern into memory, & add attributes
;
;===========================================================================
;
; by Jeff Duntemann 25 November 1988
;
; VIDBLAST is written to be called from Turbo Pascal V4.0 or 5.0 using the
; EXTERNAL machine-code procedure convention.
;
; Declare the procedure itself as external using this declaration:
;
; PROCEDURE VidBlast(ScreenEnd,StoreEnd : ScrnPtr;
; ScreenX,ScreenY : Integer;
; ULX,ULY : Integer;
; Width,Height : Integer;
; Attribute : Byte;
; DeadLines : Integer);
; EXTERNAL;
;
; What we have here is a means of moving a rectangular region of a text
; screen (either the visible screen or a screen stored on the heap) from
; the screen array to a storage array. It is the text analog of a BITBLT
; (BIT BLock Transfer.) It is an essential component of any windowing or
; menuing system that expects to update the display faster than the eyes
; can follow.
;
; It works like this: ScreenEnd and StoreEnd are the two pointers pointing
; to the screen array and the storage array, respectively. If the destination
; pointer is NIL, VidBlast returns without taking any action. ScreenX and
; ScreenY are the dimensions of the screen in use. ULX and ULY are the
; coordinates of the upper left hand corner of the rectangular region to be
; written to on the destination screen. Width and Height are the dimensions
; of the region to be written to on the destination screen.
;
; During the blast itself, the attribute byte passed in the Attribute
; parameter is written to the screen along with the character information
; pointed to by the source pointer. In effect, this means we do a byte-sized
; read from the source character data, but a word-sized write to the screen.
;
;
; There is a critical difference between a screen array and a storage array.
; A screen array has an implied structure of rows and columns, dictated by
; the ScreenX and ScreenY parameters. A rectangular region within such an
; array is not one contiguous block of elements, but rather a number of
; blocks of elements separated by some quantity of storage not included in
; the block transfer. Additionally, the rectangular region begins at some
; offset from the beginning of the screen array. A storage buffer, by
; contrast, is a simple contiguous array of character/attribute pairs without
; any consideration for the row/column structure of a visible screen. We
; do it this way for the utmost speed and most efficient use of memory.
;
; Allocation of both screen and storage arrays, of course, is the
; responsibility of the calling logic. HINT: Use GetMem and FreeMem
; rather than New and Dispose.
;
;
; To reassemble/relink WORDBLT:
;
; Assemble this file with MASM or TASM: "C>MASM VIDBLAST;"
; (The semicolon is unnecessary with TASM.)
;
;========================
;
; STACK PROTOCOL
;
; This creature puts lots of things on the stack. Study closely:
;

ONSTACK STRUC
OLDBP DW ? ;Caller's BP value saved on the stack
RETADDR DD ? ;Full 32-bit return address. (This is a FAR proc!)
DEADLNS DW ? ;Number of lines of dead space to insert between blasted lines
ATTR DW ? ;Attribute to be added to blasted pattern
WHEIGHT DW ? ;HEIGHT OF WINDOW TO BE MOVED
WWIDTH DW ? ;WIDTH OF WINDOW TO BE MOVED
ULY DW ? ;Y COORDINATE OF UPPER LEFT CORNER OF WINDOW
ULX DW ? ;X COORDINATE OF UPPER LEFT CORNER OF WINDOW
YSIZE DW ? ;GENNED MAX Y DIMENSION OF CURRENT VISIBLE SCREEN
XSIZE DW ? ;GENNED MAX X DIMENSION OF CURRENT VISIBLE SCREEN
STORE DD ? ;32-BIT POINTER TO STORE BUFFER
SCREEN DD ? ;32-BIT POINTER TO SCREEN BUFFER
ENDMRK DB ? ;DUMMY FIELD FOR SIZE CALCULATION PURPOSES
ONSTACK ENDS


CODE SEGMENT PUBLIC
ASSUME CS:CODE
PUBLIC VIDBLAST

VIDBLAST PROC FAR
PUSH BP ;SAVE CALLER'S BP VALUE
MOV BP,SP ;SP BECOMES NEW VALUE OF BP
PUSH DS ;SAVE CALLER'S DS VALUE

;-------------------------------------------------------------------------
; The increment between window lines must be calculated and stored in DX.
; This includes adding additional instances of the increment for "dead
; space" to avoid lines between forms, things like that.
;-------------------------------------------------------------------------

MOV DX,[BP].XSIZE
SUB DX,[BP].WWIDTH ;INCREMENT IS SCREEN WIDTH MINUS
; WINDOW WIDTH
SHL DX,1 ;INCREMENT IS IN WORDS. MUST
; CONVERT TO BYTES FOR USE; HERE
; WE MULTIPLY IT BY TWO BY
; SHIFTING LEFT ONE BIT
MOV CX,[BP].DeadLns ;Put deadspace line count in CX
CMP CX,0 ;Is there any dead space needed?
JE Inset ;If not, go calculate the inset

MOV BX,[BP].XSIZE ;Mov screen width into BX
SHL BX,1 ;Multiply by two for attributes
AddDed: ADD DX,BX ;Add a screen width to increment
LOOP AddDed ;Dec CX & loop backn if CX <> 0


;-------------------------------------------------------------------------
; HERE WE CALCULATE THE INSET FROM THE START OF THE VISIBLE
; SCREEN BUFFER TO THE FIRST BYTE OF THE WINDOW TO BE BLITTED
;-------------------------------------------------------------------------

Inset: PUSH DX ;Save increment; MUL trashes DX
MOV CX,[BP].XSIZE ;SCREEN MAX X DIMENSION IN CX
MOV BX,[BP].ULX ;UL CORNER X DIMENSION IN BX
MOV AX,[BP].ULY ;UL CORNER Y DIMENSION IN AX
SUB BX,1 ;CORRECT FOR ORIGIN AT 1 NOT 0
SUB AX,1 ;CORRECT FOR ORIGIN AT 1 NOT 0
MUL CX ;MULTIPLY SCREEN WIDTH BY UL Y
ADD AX,BX ; AND ADD INDENT FROM LEFT MARGIN
MOV CX,AX
SHL CX,1


;-------------------------------------------------------------------------
; NEXT WE HAVE TO FILL THE SOURCE AND DESTINATION SEGMENT AND OFFSET
; REGISTERS, DEPENDING ON WHICH WAY DATA WILL BE FLOWING. DS:SI IS
; ALWAYS THE SOURCE ADDRESS, AND ES:DI IS ALWAYS THE DESTINATION
; ADDRESS. TOWARD DETERMINES WHETHER DATA WILL BE FLOWING TOWARD THE
; SCREEN BUFFER OR TOWARD THE STORAGE BUFFER. MUCH OF THIS CODE IS
; CHECKING TO SEE IF EITHER POINTER WAS SET TO NIL, I.E. BOTH WORDS
; SET TO ZERO. IF EITHER POINTER WAS PASSED AS NIL, WORDBLT RETURNS
; WITHOUT TAKING FURTHER ACTION.
;-------------------------------------------------------------------------

LES DI,[BP].SCREEN ;SCREEN IS DESTINATION: ES:DI
LDS SI,[BP].STORE ;STORAGE BUFFER IS SOURCE: DS:SI

MOV AX,ES ;CAN'T DO A CMP ON A SEGMENT REG.
CMP AX,0 ;A NIL POINTER IS A SEGMENT AND
JNE AddIn ; OFFSET BOTH SET TO 0
CMP DI,0 ;RETURN WITHOUT ACTING IF BOTH
JE GOHOME ; ARE SET TO 0

AddIn: ADD DI,CX ;SCREEN END MUST ADD INSET VALUE
; TO OFFSET PORTION OF POINTER
POP DX ;Restore saved increment to DX

;-------------------------------------------------------------------------
; THE POINTERS ARE NOW READY FOR WORK. NOW WE SET UP FOR THE LOOPS.
; THE DIRECTION FLAG MUST BE SET FOR AUTOINCREMENT DURING LOOPS.

;-------------------------------------------------------------------------

MOV AX,[BP].WHEIGHT ;HEIGHT IS COUNT OF LINE MOVES
MOV BX,[BP].Attr ;Move attribute byte into BX
XCHG BH,BL ;Put attribute info into high byte

;-------------------------------------------------------------------------
; DOLINE IS THE LABEL FOR THE OUTER LOOP. THIS LOOP PERFORMS HEIGHT
; STOSW OPS WHICH EACH MOVE WIDTH WORDS FROM SOURCE TO DESTINATION
;-------------------------------------------------------------------------

DOLINE: MOV CX,[BP].WWIDTH ;COUNT VALUE FOR INNER LOOP IS WIDTH

DoChar: MOV BL,[SI] ;Bring source byte into BL
MOV ES:[DI],BX ;Move WORD QUANTITY to ES:DI
INC SI ;Bump SI to next byte
INC DI ;Bump DI *by two* to next word
INC DI
LOOP DoChar ;Repeat inner loop until CX is zero

ADD DI,DX ;ADD DESTINATION INCREMENT TO DI
DEC AX ;AX IS HEIGHT; I.E. OUTER LOOP COUNTER
JNZ DOLINE ;AND LOOP UNTIL AX IS ZERO

;-------------------------------------------------------------------------
; WHEN THE OUTER LOOP IS FINISHED, THE WORK IS DONE. RESTORE REGISTERS
; AND GO HOME.
;-------------------------------------------------------------------------

GOHOME: POP DS ;RESTORE CALLER'S DS
MOV SP,BP ;RESTORE PRIOR STACK POINTER & BP
POP BP ; IN CONVENTIONAL RETURN
RET ENDMRK-RETADDR-4

VIDBLAST ENDP
CODE ENDS
END


  3 Responses to “Category : Assembly Language Source Code
Archive   : JED.ZIP
Filename : VIDBLAST.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/