home *** CD-ROM | disk | FTP | other *** search
- ;===========================================================================
- ;
- ; S C R N B L T - Graphics Screen Block Transfer for Turbo Pascal
- ;
- ;===========================================================================
- ;
- ; by Larry Stone 21-Jul-84
- ;
- ; SCRNBLT is written to be called from Turbo Pascal V2.0 using the
- ; EXTERNAL procedure convention. It will copy the contents of the
- ; video graphics display buffer (either low or high resolution) to
- ; a designated memory location on a virtual "pad" of set dimensions.
- ;
- ; To use SCRNBLT, the following lines must be included in your Turbo
- ; Pascal program. The type "padtype" demonstrates how a PAD data type
- ; may be declared. When the PAD type is declared, the dimensions of
- ; the array must be as shown here. It should also be specified ABSOLUTE
- ; with the initial offset 0, so that all of a 64K segment is available
- ; to it.
- ;
- ; PROCEDURE SCRNBLT( MOVDIR, PADX, PADY : INTEGER; VAR PAD : PADARRAY );
- ; EXTERN 'SCRNBLT';
- ;
- ; TYPE
- ; padtype = ARRAY [0..159, 0..399] OF BYTE;
- ; VAR
- ; pad : padtype ABSOLUTE $BA00 : $0000; (* sample declaration *)
- ;
- ; SCRNBLT(0, x, y, pad); (* sample call; saves screen on pad(x,y) *)
- ;
- ; The parameters PADX and PAXY are specified as absolute coordinates
- ; on the pad, exactly as screen coordinates would be specified. The
- ; X-coordinates correspond to the bits on the pad, not the bytes.
- ;
- ; The first parameter, "MOVDIR", determines the direction of the transfer.
- ; If 0 is specified, the contents of the screen are transferred to the
- ; designated area of the pad; if a nonzero number is specified,
- ; the designated area of the pad is transferred to the screen buffer.
- ;
- ; SCRNBLT transfers the contents of the screen as a rectangular block,
- ; 80 bytes wide by 200 bytes high, to a rectangular area of the pad
- ; at the designated x,y coordinates. The pad area is not organized
- ; exactly like the display buffer; odd and even lines are interleaved
- ; in a more straightforward fashion to allow the offset of an x,y location
- ; in the pad to be calculated as (y * padwidth) + x.
- ;
- ; To use SCRNBLT with a Turbo Program:
- ;-------------------------------------
- ; 1. Assemble this file with MASM. "A> MASM SCRNBLT;"
- ; 2. Link it into a .EXE file. "A> LINK SCRNBLT;"
- ; 3. Use EXE2BIN to make a .COM file. "A> EXE2BIN SCRNBLT.EXE SCRNBLT.COM"
- ; 4. Declare as shown in your Turbo Pascal program.
- ; 5. Ignore any minor diagnostic messages that may be generated when
- ; this file is assembled and linked. EXE2BIN is supplied with the
- ; supplemental programs for PC-DOS; see the DOS manual.
- ;
-
- ;
- ; EQUATES TO DEFINE GRAPHICS CONSTANTS
- ;
- PADWD EQU 160 ; WIDTH OF VIRTUAL PAD, BYTES
- SCRNWD EQU 80 ; WIDTH OF REAL SCREEN
- SCRNWD2 EQU 40 ; HALF OF SCREEN WIDTH
- HALFSC EQU 100 ; LINES FOR HALF OF SCREEN
- EVENSC EQU 0B800H ; ADDRESS OF EVEN HALF OF SCREEN
- ODDSC EQU 02000H ; OFFSET OF ODD HALF OF SCREEN
-
- CODE SEGMENT PUBLIC
- ASSUME CS:CODE
- PUBLIC SCRNBLT
- ;
- ; EQUATES FOR ARGUMENTS TO SCRNBLT
- ;
- PADOFS EQU 4[BP] ; OFFSET OF PAD ORIGIN
- PADSEG EQU 6[BP] ; SEGMENT OF PAD
- PADY EQU 8[BP] ; Y-COORD IN PAD
- PADX EQU 10[BP] ; X-COORD IN PAD
- MOVDIR EQU 12[BP] ; MOVE DIRECTION (0 = TO SCREEN)
-
- SCRNBLT PROC NEAR
- PUSH BP
- MOV BP,SP ; CALLING CONVENTION
- PUSH DS ; SAVE DS
- ;
- ; COMPUTE THE ADDRESS OF THE ORIGIN OF THE PAD AREA DESIGNATED BY
- ; PADX, PADY. LOC = PAD_OFFSET + (PADY * PADWD) + (PADX / 8)
- ;
- MOV AX,PADY ; PREPARE PADY * PADX
- MOV BX,PADWD
- MUL BX ; AX = PADY * PADX (DX TRASHED)
- MOV BX,PADX ; ADD IN X COMPONENT:
- MOV CL,3 ; (PREPARE TO SHIFT BY 3)
- SHR BX,CL ; DIV BY 8 SO WE MOVE BY BYTE
- ADD AX,BX ; ADD IT IN.
- ADD AX,PADOFS
- CMP WORD PTR MOVDIR,0 ; IS MOVDIR 0?
- JE BACKWRD ; IF SO, DO BACKWARDS MOVE.
- ;----------------------------------------------------
- ; MOVE "FORWARD" : FROM PAD TO REAL SCREEN
- ;----------------------------------------------------
- ; MOVE THE EVEN LINES OF THE SCREEN. THE LOOP IS CONTROLLED BY
- ; THE HALFSC VALUE IN DX; A REP MOVSW IS USED TO MOVE THE SCREEN
- ; LINES A WORD AT A TIME (PROBABLY NO MORE EFFICIENT ON AN 8088..)
- ;
- CLD ; BE SURE DIR. FLAG IS 0
- MOV BX,PADSEG ; SOURCE IS PAD, SO SET DS TO
- MOV DS,BX ; PAD SEGMENT
- MOV SI,AX ; AND DI TO OFFSET IN PAD
- MOV BX,EVENSC ; DEST IS SCREEN, SET ES TO SCREEN
- MOV ES,BX ; SEGMENT.
- MOV DI,0 ; AND INDEX OF 0
- ;
- ; LOOP TO COPY EVEN LINES
- ;
- MOV CX,HALFSC ; PREPARE LOOP COUNTER
- EVEN: MOV DX,CX ; RECORD LOOP COUNTER
- MOV CX,SCRNWD2 ; SET UP COUNTER
- REP MOVSW ; DO THE MOVE
- ADD SI,PADWD+PADWD-SCRNWD ; MOVE SI TO NEXT SCREEN LINE
- MOV CX,DX
- LOOP EVEN
- ;
- ; NOW SET UP FOR ODD LINES AND COPY THOSE
- ;
- MOV DI,ODDSC ; SET DI TO ODD SCREEN OFFSET
- MOV SI,AX
- ADD SI,PADWD ; SET SI TO FIRST ODD LINE
- ;
- ; COPY ODD LINES
- ;
- MOV CX,HALFSC ; LOAD COUNTER
- ODD: MOV DX,CX ; SAVE COUNTER
- MOV CX,SCRNWD2 ; SET UP LINE COUNTER
- REP MOVSW
- ADD SI,PADWD+PADWD-SCRNWD ; MOVE SI TO NEXT SCREEN LINE
- MOV CX,DX ; GET LOOP COUNTER
- LOOP ODD
- JMP BYE ; LEAVE
- ;----------------------------------------------------
- ; MOVE "BACKWARD" : FROM REAL SCREEN TO PAD
- ;----------------------------------------------------
- ; THIS IS ALMOST EXACTLY LIKE THE CODE ABOVE THAT MOVES
- ; FROM THE VIRTUAL SCREEN TO THE DISPLAY BUFFER
- ;
- BACKWRD:
- CLD ; BE SURE DIR. FLAG IS 0
- MOV BX,PADSEG ; DEST IS PAD, SO SET ES TO
- MOV ES,BX ; PAD SEGMENT
- MOV DI,AX ; SET UP SOURCE INDEX
- MOV BX,EVENSC ; SET DS TO SCREEN SEGMENT
- MOV DS,BX ; FOR EVEN LINES OF SCREEN
- MOV SI,0 ; AND SOURCE INDEX
- ;
- ; LOOP TO COPY EVEN LINES
- ;
- MOV CX,HALFSC ; PREPARE LOOP COUNTER
- BEVEN: MOV DX,CX ; RECORD LOOP COUNTER
- MOV CX,SCRNWD2 ; SET UP COUNTER
- REP MOVSW ; DO THE MOVE
- ADD DI,PADWD+PADWD-SCRNWD ; MOVE SI TO NEXT SCREEN LINE
- MOV CX,DX
- LOOP BEVEN
- ;
- ; NOW SET UP FOR ODD LINES AND COPY THOSE
- ;
- MOV SI,ODDSC ; SET DI TO ODD SCREEN OFFSET
- MOV DI,AX
- ADD DI,PADWD ; SET SI TO FIRST ODD LINE
- ;
- ; COPY ODD LINES
- ;
- MOV CX,HALFSC ; LOAD COUNTER
- BODD: MOV DX,CX ; SAVE COUNTER
- MOV CX,SCRNWD2 ; SET UP LINE COUNTER
- REP MOVSW
- ADD DI,PADWD+PADWD-SCRNWD ; MOVE SI TO NEXT SCREEN LINE
- MOV CX,DX ; GET LOOP COUNTER
- LOOP BODD
- ;
- ; DONE.. CLEAN UP THE STACK AND LEAVE
- ;
- BYE: POP DS ; RESTORE DS
- MOV SP,BP
- POP BP ; CONVENTIONAL RETURN
- RET 10 ; TRASH 10 BYTES FOR PARMS
-
- SCRNBLT ENDP
- CODE ENDS
- END