home *** CD-ROM | disk | FTP | other *** search
- ;--------------------------------------------------------------------
- ; Program FAST_PRINT.ASM
- ;====================================================================
- ; PROGRAM: FAST_PRINT
- ;
- ; This program is a high speed screen printing routine for
- ; use with TurboPascal. It overcomes the problem of the
- ; painfully slow printing facilities commonly supported by
- ; MS-DOS. This routine is capable of filling the screen
- ; twenty times in one second.
- ;
- ; The routine requires that TurboPascal pass a string and
- ; an integer. The string is printed with the Attribute
- ; type specified by the integer. The calling format is:
- ;
- ; Procedure FastPrint(s:StringType, Attribute:Interger);
- ; External;
- ; FastPrint(strng,Attribute);
- ;
- ; AUTHOR : Jeff Firestone
- ; April 27, 1984
- ;--------------------------------------------------------------------
-
- MPOP MACRO DEST ;Move the stack addr. into DEST
- POP AX
- MOV DEST, AX
- ENDM
-
- MPUSH MACRO SOURCE ;Push the SOURCE onto the Stack
- MOV AX, SOURCE
- PUSH AX
- ENDM
-
-
- BIOSseg EQU 0040h ;Segment Address of BIOS
- MonoSeg EQU 0B000h ;Segment Address of Monocrome Card
- ColorSeg EQU 0B800h ;Segment Address of Color Card
-
- bEquipFlag EQU 0010h ;Address of Equipment flag in BIOS
- bCrtCols EQU 004Ah ;Address of number of columns on screen
- bCrtLen EQU 004Ch ;Address of length of regen in bytes
- bCursorPos EQU 0050h ;Address of Cursor Pos in BIOS
- bPageNumber EQU 0062h ;Address of Video Page number in BIOS
- bAddr_6845 EQU 0063h ;Base address for active display card
-
-
- CODE SEGMENT PARA PUBLIC 'CODE'
- ASSUME CS:CODE
- PUBLIC FASTPRINT
-
- FASTPRINT PROC NEAR
-
- CALL BEGIN
-
- BasePage DW ? ;Storage for BP reg
- RETURN DW ? ;Storage for return address
- Attribute DB ? ;Storage for Attribute byte
-
- CrtCols DB ? ;Address of number of columns on screen
- CrtLen DW ? ;Address of length of regen in bytes
- Addr_6845 DW ? ;Base address for active display card
- CrtBoundary DW ? ;Bottom of current CRT page
-
-
- BEGIN PROC NEAR
- pop ax ;Get the segment for our data
- sub ax, 3 ;Adjust it
- mov si, ax ;Move to SI temporarily
- mov BasePage[si], bp ;Save old BP for exit
- mov bp, ax ;BP now points to our data
- cld ;Set direction forward
-
- MPOP RETURN[bp] ;Save the RETURN Addr.
- pop ax ;Get the attribute into AX
- mov Attribute[bp], al ;Save Attribute byte
- pop si ;Get the string address in SI
- pop ax ;A dummy pop to clear the stack
- call strdisp
-
- MPUSH RETURN[bp] ;Replace the Return Addr.
- mov bp, BasePage[bp] ;Restore the BasePage
- RET
- begin endp
-
-
- strdisp proc near
- mov ax, BIOSseg ;Segment 0040h
- mov es, ax ; loaded into ES
-
- mov bx, 00 ;Zero BX
- mov al, ES:bCrtCols[bx]
- mov CrtCols[bp], al ;Init CrtCols
- mov ax, ES:bCrtLen[bx]
- mov CrtLen[bp], ax ;Init CrtLen
- mov ax, ES:bAddr_6845
- mov Addr_6845[bp], ax ;Init Addr_6845
-
- mov ax, ES:bCursorPos[bx] ;Get Cursor POS in AX
- mov cl, ES:bPageNumber[bx] ;Get Screen Page Number
- xor ch, ch ;Zero screen page # garbage
-
- mov dx, MonoSeg ;Get Mono Screen Segment
- mov di, ES:bEquipFlag[bx] ;Equipment setting to DI
- and di, 30h ;Mask the flag
- cmp di, 30h ;Is it B&W Card
- jz B_W ;Yep, seg OK
- mov dx, ColorSeg ;Nope, use Color Seg
- B_W: mov es, dx ;Assign the video seg to ES
-
- jcxz PageZero ;Skip if Screen # is zero
-
- PageLoop:
- add bx, CrtLen[bp] ;Adjust for Screen Page #
- loop PageLoop
-
- PageZero:
- mov di, bx ;Save Screen Addr for later
- mov cx, bx ;Get Screen Addr
- add cx, CrtLen[bp] ;Add a page length
- mov CrtBoundary[bp], cx ;Set up CrtBoundary
-
- mov bl, al ;Move COL to BL
- xor bh, bh ;COL = BX
- mov al, ah ;Move ROW to AL
- xor ah, ah ;ROW = AX
- mul CrtCols[bp] ;# of bytes per row
- add ax, bx ;Add ROW & COL
- sal ax, 1 ;Times 2 for attribute bytes
- add di, ax ;Add Screen Addr to Scrn POS
-
- mov cl, byte ptr DS:[si] ;Get string length
- xor ch, ch ;Zero MSD
- inc si ;Point at first char
- mov ah, Attribute[bp] ;Put Video Attribute in AL
-
- ScreenPrint:
- mov al, byte ptr DS:[si] ;Get string character
- cmp al, 13 ;Is it a CR?
- jz short NextLine ;Nope, goto next line
- mov ES:[di], ax ;Place on screen
- inc si ;Point @ next char
- inc di ;Point @ next screen pos
- inc di
- loop short ScreenPrint
-
-
- ReplacePOS:
- mov ax, BIOSseg
- mov es, ax
- mov ax, di ;Get screen pos
- mov cl, ES:bPageNumber[bx] ;Get Screen Page Number
- xor ch, ch ;Zero MSD
- jcxz ZeroPage ;Dont bother if page zero
- DecLoop:
- sub ax, CrtLen[bp] ;Adjust for Screen Page #
- loop DecLoop
-
- ZeroPage:
- sar ax, 1 ;Divide by 2 for attribute byte
- mov bx, ax ;Save for later
- div CrtCols[bp] ;Divide by # of columns
- xor ah, ah ;Zero remainder
- mov dh, al ;Place ROWs into DH
- mul CrtCols[bp] ;Translate back into screenpos
- sub bx, ax ;Get remaining Columns
- mov dl, bl ;Place COLs into DL
-
- mov si, bCursorPos ;Get Cursor Pos in BIOS
- mov es:[si], dx ;Update it
-
- ret
-
- NextLine:
- mov ax, di ;Get screen pos
- sar ax, 1 ;Divide by 2 for attribute byte
- div CrtCols[bp] ;Divide by # of columns
- xor ah, ah ;Zero remainder
- mul CrtCols[bp] ;Get beginning of line
- mov bl, CrtCols[bp] ;Get line length
- xor bh, bh ;Zero high BH
- add ax, bx ;Move to next line
- sal ax, 1 ;Adjust for Attribute bytes
- mov di, ax ;Screen pos back to DI
- cmp di, CrtBoundary[bp] ;Is the Curp Pointer to far?
- jl Next1 ;Nope, no need to scrole
- call ScroleScreen ;Scrole the screen
- Next1: inc si ;Move to next string char
- mov ah, Attribute[bp] ;Put Video Attribute in AL
- dec cx ;Dec count
- jnz ScreenPrint ;Print next char if any
- jmp ReplacePos ;Put in Cursor Pos
-
-
- ScroleScreen:
- push si ;Save the string pointer
- push cx ;Save the count register
- mov di, CrtBoundary[bp] ;DI = CrtBoundary
- mov cx, CrtLen[bp] ;CX = CrtLen
- sub di, cx ;DI = Top of current page
- mov si, di ;SI = Top of current page
- mov al, CrtCols[bp] ;Get CrtCols
- xor ah, ah ;Clear MSD
- sal ax, 1 ;AX = CrtCols * 2
- add si, ax ;SI = Second line is source
- sar ax, 1 ;AX = CrtCols
- sub cx, ax ;CX = # of chars to scrole
- push ds ;Save DS
- mov ax, es ;Get ES
- mov ds, ax ;Put is DS
- rep movsw ;Scrole the screen
- pop ds ;Restore DS
- push di ;Save bottom line addr
- mov cx, ax ;Save CrtCols number of zeros
- mov ax, 00 ;Store zeros
- rep stosw ;Clear bottom line
- pop di ;Screen pointer set to new line
- pop cx ;Recall the count register
- pop si ;Recall the string pointer
- ret
-
- strdisp endp
-
- fastprint endp
- code ends
- end