home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
TURBOPAS
/
TP-UTIL.ARK
/
SCRNBLT.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-01-06
|
7KB
|
190 lines
;===========================================================================
;
; 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