home *** CD-ROM | disk | FTP | other *** search
- { FASTWRITE routine and example.
- Code by Marshall Brain.
- This program contains a routine called FASTWRITE, that can
- be used on the IBM PC, XT, and compatibles to update the screen
- much faster than can be done with write statements. It handles
- graphics and monochrome screens.
- As can be seen, four variables are passed to Fastwrite. They
- are: the cursor's column location to begin printing (0..79), the
- cursor's row location (0..24), the screen attribute (contols
- color, underlining, and intensity), and the string to be printed.
- A typical call to fastwrite would be as follows:
-
- tempstring:='Fastwrite is fast as lightning';
- fastwrite(15,10,$07,tempstring);
-
- This would print tempstring at location (15,10), with characters
- that are white on black (if you are not familiar with attribute
- bytes, look them up in the Technical Reference manual, or get a
- book such as "Inside the IBM PC" by Peter Norton).
- These four parameters are crucial to Fastwrite's speed. In
- order to write to the screen as quickly as it does, Fastwrite
- ignores all of the normal channels used for screen updating such
- as DOS and BIOS calls. Instead, it dumps the string to be
- displayed directly into the display's memory buffer. The
- advantage of speed is gained, but in the process you lose the
- use of the gotoxy statement, the color statements, and
- windowing. If you like, you can mix Fastwrite and regular write
- statements and continue to make use of some of these features. Or
- you can, as I have, create new routines to handle windows,
- gotoxy, etc.
- An article on this routine was submitted to the TUG
- newsletter in October - it contains code listings, etc, but
- it has not been printed and I have not been told when it will
- be printed. If there is any demand, I can upload the source code
- for FASTWRITE.
- Good luck using this routine. MB. }
-
- (* Modified FastWrite - Doug Senalik - 11/6/86 *)
- (* I have modified FastWrite to: *)
- (* 1: use Turbo-style screen coordinates [1..80, 1..25] *)
- (* rather than BIOS style [0..79, 0..24] *)
- (* IF you want or need the old FastWrite type coord- *)
- (* inates, just comment out all lines marked with *)
- (* a {**} (there are four of them), and change the line *)
- (* marked with a {##} from /$E2/$C1 to /$E2/$C5 *)
- (* 2: Use BIOS for writing when direct screen writes not *)
- (* possible (e.g. for graphic modes, some PC clones, or *)
- (* when running other software at the same time that *)
- (* doesn't like you to do that). *)
- (* 3: Changed the original FastWrite code a little bit, to *)
- (* pass variable locations as bytes instead of words, *)
- (* get port address of CRTC controller from BIOS data *)
- (* area rather than hard-coding it in (not that that *)
- (* matters), and put in a STI instruction after the CLI *)
- (* to turn interrupts back on (a nasty omission in the *)
- (* original version, this left interrupts OFF until *)
- (* something else turned them back on. This would *)
- (* eventually happen, but the system clock could get a *)
- (* few milliseconds or seconds (or more??) behind. *)
- (* 4: The include file VID-TYPE.PAS is needed. That file *)
- (* contains a function to determine if it is safe or *)
- (* possible to write directly to video memory. *)
-
-
- type FastString = string[80];
-
- procedure FastWrite (Col, Row, Attrib: byte; Str: FastString);
-
- begin
- if VideoDisplayType in [1,2] then {we can do direct memory writes}
- begin
- inline(
- $1E { Push DS ;Save value of Turbo's data segment}
- /$8A/$46/<ROW { Mov AL,[BP+<Row] ;Screen row position wanted}
- /$FE/$C8 {**}{ Dec AL ;Dec so corresponds to Turbo coord #'s}
- /$B3/$50 { Mov BL,$50 ;80 char's per row on screen}
- /$F6/$E3 { Mul BL ;AX = Row * 80}
- /$29/$DB { Sub BX,BX ;BX = 0}
- /$8A/$5E/<COL { Mov BL,[BP+<Col] ;Screen column position wanted}
- /$FE/$CB {**}{ Dec BL ;Dec so corresponds to Turbo coord #'s}
- /$01/$D8 { Add AX,BX ;AX = Row * 80 + Col}
- /$01/$C0 { Add AX,AX ;AX = (Row * 80 + Col) * 2}
- /$89/$C7 { Mov DI,AX ;DI now = addr. in video area to write to}
- /$31/$F6 { Xor SI,SI ;SI = 0}
- /$8A/$7E/<ATTRIB { Mov BH,[BP+<Attrib] ;Attribute of characters}
- /$8A/$4E/<STR { Mov CL,[BP+<Str[0]] ;CL = length of string}
- /$30/$ED { Xor CH,CH ;CX = length of string}
- /$20/$C9 { And CL,CL ;Test for zero-length string}
- /$74/$3A { Jz L6 ;Jump to end if null string}
- /$29/$C0 { Sub AX,AX ;AX = 0}
- /$8E/$D8 { Mov DS,AX ;DS = 0}
- /$8A/$26/$49/$04 { Mov AH,[$0449] ;0040:0049 is current video mode}
- /$8B/$16/$63/$04 { Mov DX,[$0463] ;Addr of display card, from BIOS data area}
- /$83/$C2/$06 { Add DX,6 ;Point at status port}
- /$80/$EC/$07 { Sub AH,7 ;See if mode 7, which is monochrome adapter}
- /$74/$1C { Jz L4 ;Jump if mode 7 to monochrome routine}
- { ;Color display routine starts here}
- /$B4/$B8 { Mov AH,$B8 ;AL was already 0, so AX=$B800}
- /$8E/$D8 { Mov DS,AX ;DS = video ram segment (at $B800)}
- /$46 {L1: Inc SI ;Increment source pointer by 1 byte}
- /$8A/$5A/<STR { Mov BL,[BP+SI+<Str[0]] ;Get next character (Attrib. is in BH)}
- /$EC {L2: In AL,DX ;Wait for horiz retrace to end}
- /$A8/$01 { Test AL,1 }
- /$75/$FB { Jnz L2 }
- /$FA { Cli ;No more interrupts}
- /$EC {L3: In AL,DX ;Wait for horizontal retrace}
- /$A8/$01 { Test AL,1 }
- /$74/$FB { Jz L3 }
- /$89/$1D { Mov [DI],BX ;Put character & attribute in display memory}
- /$FB { Sti ;Interrupts back on}
- /$47 { Inc DI ;Increment destination addr. by one word}
- /$47 { Inc DI }
- /$E2/$EA { Loop L1 ;Loop for next character}
- /$EB/$0E { Jmp Short L6 ;Finished, so jump to end}
- { ;Monochrome display routine starts here}
- /$B4/$B0 {L4: Mov AH,$B0 ;AL was already 0, so AX=$B000}
- /$8E/$D8 { Mov DS,AX ;DS = video ram segment (at $B000)}
- /$46 {L5: Inc SI ;Increment source pointer by 1 byte}
- /$8A/$5A/<STR { Mov BL,[BP+SI+<Str[0]] ;Get next character (Attrib. is in BH)}
- /$89/$1D { Mov [DI],BX ;Put character & attribute in display memory}
- /$47 { Inc DI ;Increment destination addr. by one word}
- /$47 { Inc DI }
- /$E2/$F6 { Loop L5 ;Loop for next character}
- /$1F); {L6: Pop DS ;Restore Turbo's data segment}
- end
-
- else {must use BIOS}
-
- begin
- inline(
- $B4/$03 { Mov AH,3 ;Get current cursor pos. to save it}
- /$30/$FF { Xor BH,BH ;Display page 0}
- /$CD/$10 { Int $10 }
- /$52 { Push DX ;Save cursor pos. on stack}
- /$8A/$4E/<STR { Mov CL,[BP+<Str[0]] ;CL = string length}
- /$30/$ED { Xor CH,CH ;CH = 0, to set CX to string length}
- /$31/$F6 { Xor SI,SI ;SI = 0}
- /$20/$C9 { And CL,CL ;If null string, jump to end, do nothing}
- /$74/$3F { Jz L10 }
- /$51 {L7: Push CX ;Save chars left to write on stack}
- /$46 { Inc SI ;Incr pointer to char in string}
- /$8A/$76/<ROW { Mov DH,[BP+<Row] ;Screen row}
- /$8A/$56/<COL { Mov DL,[BP+<Col] ;Screen column}
- /$FE/$CE {**}{ Dec DH ;To correspond to Turbo coord #'s}
- /$FE/$CA {**}{ Dec DL ;To correspond to Turbo coord #'s}
- /$FE/$46/<COL { Inc Byte Ptr [BP+<Col] ;Incr. column position}
- /$30/$FF { Xor BH,BH ;Display page 0 (BH=0)}
- /$B4/$02 { Mov AH,2 ;Set cursor position}
- /$CD/$10 { Int $10 }
- /$B9/$01/$00 { Mov CX,1 ;CX = count of characters to write, will be >= 1}
- /$30/$FF { Xor BH,BH ;Display page 0}
- /$8A/$5E/<ATTRIB { Mov BL,[BP+<Attrib] ;Get attribute}
- /$8A/$42/<STR { Mov AL,[BP+SI+<Str[0]] ;Get next character to write}
- /$B4/$09 { Mov AH,9 ;Func 9 of int 10 = write char & attrib at cursor pos.}
- /$3A/$82/>STR+$0001 {L8: Cmp AL,[BP+SI+<Str[1]] ;See if next char is exactly the same}
- /$75/$12 { Jnz L9 ;If not, write this character}
- /$5A { Pop DX ;Pop char's left in string}
- /$81/$FA/$01/$00 { Cmp DX,1 ;See if this is the last one}
- /$52 { Push DX ;Put back}
- /$74/$0A { Jz L9 ;If last char, also go ahead and write the char}
- /$5A { Pop DX ;Next char is same as this one, so...}
- /$4A { Dec DX ;Decrement char's left counter}
- /$52 { Push DX }
- /$46 { Inc SI ;Incr. position}
- /$41 { Inc CX ;Incr # of chars we want BIOS to write}
- /$FE/$46/<COL { Inc Byte Ptr [BP+<Col] ;Incr column to write at}
- /$EB/$E8 { Jmp L8 ;Loop to see if next char is also identical}
- /$CD/$10 {L9: Int $10 ;Write CX copies of char and attrib}
- /$59 { Pop CX ;Get # of chars left}
- /$E2/$C1 {##}{ Loop L7 ;Loop if more to do}
- /$5A {L10: Pop DX ;Get back original cursor position}
- /$30/$FF { Xor BH,BH ;Display page 0}
- /$B4/$02 { Mov AH,2 ;Set cursor position function}
- /$CD/$10); { Int $10 }
- end; {BIOS writing}
- end; {FastWrite}
-
-
- {End of file}