home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / FASTWR_2.ZIP / FASTWRIT.PAS next >
Encoding:
Pascal/Delphi Source File  |  1986-11-06  |  11.6 KB  |  179 lines

  1. {            FASTWRITE routine and example.
  2.                 Code by Marshall Brain.
  3.     This program contains a routine called FASTWRITE, that can
  4. be used on the IBM PC, XT, and compatibles to update the screen
  5. much faster than can be done with write statements. It handles
  6. graphics and monochrome screens.
  7.     As can be seen, four variables are passed to Fastwrite. They
  8. are: the cursor's column location to begin printing (0..79), the
  9. cursor's row location (0..24), the screen attribute (contols
  10. color, underlining, and intensity), and the string to be printed.
  11. A typical call to fastwrite would be as follows:
  12.  
  13.      tempstring:='Fastwrite is fast as lightning';
  14.      fastwrite(15,10,$07,tempstring);
  15.  
  16. This would print tempstring at location (15,10), with characters
  17. that are white on black (if you are not familiar with attribute
  18. bytes, look them up in the Technical Reference manual, or get a
  19. book such as "Inside the IBM PC" by Peter Norton).
  20.     These four parameters are crucial to Fastwrite's speed. In
  21. order to write to the screen as quickly as it does, Fastwrite
  22. ignores all of the normal channels used for screen updating such
  23. as DOS and BIOS calls. Instead, it dumps the string to be
  24. displayed directly into the display's memory buffer. The
  25. advantage of speed is gained, but in the process you lose the
  26. use of the gotoxy statement, the color statements, and
  27. windowing. If you like, you can mix Fastwrite and regular write
  28. statements and continue to make use of some of these features. Or
  29. you can, as I have, create new routines to handle windows,
  30. gotoxy, etc.
  31.     An article on this routine was submitted to the TUG
  32. newsletter in October - it contains code listings, etc, but
  33. it has not been printed and I have not been told when it will
  34. be printed. If there is any demand, I can upload the source code
  35. for FASTWRITE.
  36.      Good luck using this routine.  MB.  }
  37.  
  38. (*  Modified FastWrite - Doug Senalik - 11/6/86              *)
  39. (*  I have modified FastWrite to:                            *)
  40. (*  1: use Turbo-style screen coordinates [1..80, 1..25]     *)
  41. (*     rather than BIOS style [0..79, 0..24]                 *)
  42. (*     IF you want or need the old FastWrite type coord-     *)
  43. (*     inates, just comment out all lines marked with        *)
  44. (*     a {**} (there are four of them), and change the line  *)
  45. (*     marked with a {##} from   /$E2/$C1   to   /$E2/$C5    *)
  46. (*  2: Use BIOS for writing when direct screen writes not    *)
  47. (*     possible (e.g. for graphic modes, some PC clones, or  *)
  48. (*     when running other software at the same time that     *)
  49. (*     doesn't like you to do that).                         *)
  50. (*  3: Changed the original FastWrite code a little bit, to  *)
  51. (*     pass variable locations as bytes instead of words,    *)
  52. (*     get port address of CRTC controller from BIOS data    *)
  53. (*     area rather than hard-coding it in (not that that     *)
  54. (*     matters), and put in a STI instruction after the CLI  *)
  55. (*     to turn interrupts back on (a nasty omission in the   *)
  56. (*     original version, this left interrupts OFF until      *)
  57. (*     something else turned them back on.  This would       *)
  58. (*     eventually happen, but the system clock could get a   *)
  59. (*     few milliseconds or seconds (or more??) behind.       *)
  60. (*  4: The include file VID-TYPE.PAS is needed.  That file   *)
  61. (*     contains a function to determine if it is safe or     *)
  62. (*     possible to write directly to video memory.           *)
  63.  
  64.  
  65. type FastString = string[80];
  66.  
  67. procedure FastWrite (Col, Row, Attrib: byte; Str: FastString);
  68.  
  69. begin
  70.   if VideoDisplayType in [1,2] then  {we can do direct memory writes}
  71.     begin
  72.       inline(
  73.    $1E                   {      Push DS                 ;Save value of Turbo's data segment}
  74.   /$8A/$46/<ROW          {      Mov  AL,[BP+<Row]       ;Screen row position wanted}
  75.   /$FE/$C8           {**}{      Dec  AL                 ;Dec so corresponds to Turbo coord #'s}
  76.   /$B3/$50               {      Mov  BL,$50             ;80 char's per row on screen}
  77.   /$F6/$E3               {      Mul  BL                 ;AX = Row * 80}
  78.   /$29/$DB               {      Sub  BX,BX              ;BX = 0}
  79.   /$8A/$5E/<COL          {      Mov  BL,[BP+<Col]       ;Screen column position wanted}
  80.   /$FE/$CB           {**}{      Dec  BL                 ;Dec so corresponds to Turbo coord #'s}
  81.   /$01/$D8               {      Add  AX,BX              ;AX = Row * 80 + Col}
  82.   /$01/$C0               {      Add  AX,AX              ;AX = (Row * 80 + Col) * 2}
  83.   /$89/$C7               {      Mov  DI,AX              ;DI now = addr. in video area to write to}
  84.   /$31/$F6               {      Xor  SI,SI              ;SI = 0}
  85.   /$8A/$7E/<ATTRIB       {      Mov  BH,[BP+<Attrib]    ;Attribute of characters}
  86.   /$8A/$4E/<STR          {      Mov  CL,[BP+<Str[0]]    ;CL = length of string}
  87.   /$30/$ED               {      Xor  CH,CH              ;CX = length of string}
  88.   /$20/$C9               {      And  CL,CL              ;Test for zero-length string}
  89.   /$74/$3A               {      Jz   L6                 ;Jump to end if null string}
  90.   /$29/$C0               {      Sub  AX,AX              ;AX = 0}
  91.   /$8E/$D8               {      Mov  DS,AX              ;DS = 0}
  92.   /$8A/$26/$49/$04       {      Mov  AH,[$0449]         ;0040:0049 is current video mode}
  93.   /$8B/$16/$63/$04       {      Mov  DX,[$0463]         ;Addr of display card, from BIOS data area}
  94.   /$83/$C2/$06           {      Add  DX,6               ;Point at status port}
  95.   /$80/$EC/$07           {      Sub  AH,7               ;See if mode 7, which is monochrome adapter}
  96.   /$74/$1C               {      Jz   L4                 ;Jump if mode 7 to monochrome routine}
  97.                          {      ;Color display routine starts here}
  98.   /$B4/$B8               {      Mov  AH,$B8             ;AL was already 0, so AX=$B800}
  99.   /$8E/$D8               {      Mov  DS,AX              ;DS = video ram segment (at $B800)}
  100.   /$46                   {L1:   Inc  SI                 ;Increment source pointer by 1 byte}
  101.   /$8A/$5A/<STR          {      Mov  BL,[BP+SI+<Str[0]] ;Get next character (Attrib. is in BH)}
  102.   /$EC                   {L2:   In   AL,DX              ;Wait for horiz retrace to end}
  103.   /$A8/$01               {      Test AL,1               }
  104.   /$75/$FB               {      Jnz  L2                 }
  105.   /$FA                   {      Cli                     ;No more interrupts}
  106.   /$EC                   {L3:   In   AL,DX              ;Wait for horizontal retrace}
  107.   /$A8/$01               {      Test AL,1               }
  108.   /$74/$FB               {      Jz   L3                 }
  109.   /$89/$1D               {      Mov  [DI],BX            ;Put character & attribute in display memory}
  110.   /$FB                   {      Sti                     ;Interrupts back on}
  111.   /$47                   {      Inc  DI                 ;Increment destination addr. by one word}
  112.   /$47                   {      Inc  DI                 }
  113.   /$E2/$EA               {      Loop L1                 ;Loop for next character}
  114.   /$EB/$0E               {      Jmp Short L6            ;Finished, so jump to end}
  115.                          {      ;Monochrome display routine starts here}
  116.   /$B4/$B0               {L4:   Mov  AH,$B0             ;AL was already 0, so AX=$B000}
  117.   /$8E/$D8               {      Mov  DS,AX              ;DS = video ram segment (at $B000)}
  118.   /$46                   {L5:   Inc  SI                 ;Increment source pointer by 1 byte}
  119.   /$8A/$5A/<STR          {      Mov  BL,[BP+SI+<Str[0]] ;Get next character (Attrib. is in BH)}
  120.   /$89/$1D               {      Mov  [DI],BX            ;Put character & attribute in display memory}
  121.   /$47                   {      Inc  DI                 ;Increment destination addr. by one word}
  122.   /$47                   {      Inc  DI                 }
  123.   /$E2/$F6               {      Loop L5                 ;Loop for next character}
  124.   /$1F);                 {L6:   Pop  DS                 ;Restore Turbo's data segment}
  125.     end
  126.  
  127.   else  {must use BIOS}
  128.  
  129.     begin
  130.       inline(
  131.    $B4/$03               {      Mov  AH,3               ;Get current cursor pos. to save it}
  132.   /$30/$FF               {      Xor  BH,BH              ;Display page 0}
  133.   /$CD/$10               {      Int  $10                }
  134.   /$52                   {      Push DX                 ;Save cursor pos. on stack}
  135.   /$8A/$4E/<STR          {      Mov  CL,[BP+<Str[0]]    ;CL = string length}
  136.   /$30/$ED               {      Xor  CH,CH              ;CH = 0, to set CX to string length}
  137.   /$31/$F6               {      Xor  SI,SI              ;SI = 0}
  138.   /$20/$C9               {      And  CL,CL              ;If null string, jump to end, do nothing}
  139.   /$74/$3F               {      Jz   L10                }
  140.   /$51                   {L7:   Push CX                 ;Save chars left to write on stack}
  141.   /$46                   {      Inc  SI                 ;Incr pointer to char in string}
  142.   /$8A/$76/<ROW          {      Mov  DH,[BP+<Row]       ;Screen row}
  143.   /$8A/$56/<COL          {      Mov  DL,[BP+<Col]       ;Screen column}
  144.   /$FE/$CE           {**}{      Dec  DH                 ;To correspond to Turbo coord #'s}
  145.   /$FE/$CA           {**}{      Dec  DL                 ;To correspond to Turbo coord #'s}
  146.   /$FE/$46/<COL          {      Inc  Byte Ptr [BP+<Col] ;Incr. column position}
  147.   /$30/$FF               {      Xor  BH,BH              ;Display page 0 (BH=0)}
  148.   /$B4/$02               {      Mov  AH,2               ;Set cursor position}
  149.   /$CD/$10               {      Int  $10                }
  150.   /$B9/$01/$00           {      Mov  CX,1               ;CX = count of characters to write, will be >= 1}
  151.   /$30/$FF               {      Xor  BH,BH              ;Display page 0}
  152.   /$8A/$5E/<ATTRIB       {      Mov  BL,[BP+<Attrib]    ;Get attribute}
  153.   /$8A/$42/<STR          {      Mov  AL,[BP+SI+<Str[0]] ;Get next character to write}
  154.   /$B4/$09               {      Mov  AH,9               ;Func 9 of int 10 = write char & attrib at cursor pos.}
  155.   /$3A/$82/>STR+$0001    {L8:   Cmp  AL,[BP+SI+<Str[1]] ;See if next char is exactly the same}
  156.   /$75/$12               {      Jnz  L9                 ;If not, write this character}
  157.   /$5A                   {      Pop  DX                 ;Pop char's left in string}
  158.   /$81/$FA/$01/$00       {      Cmp  DX,1               ;See if this is the last one}
  159.   /$52                   {      Push DX                 ;Put back}
  160.   /$74/$0A               {      Jz   L9                 ;If last char, also go ahead and write the char}
  161.   /$5A                   {      Pop  DX                 ;Next char is same as this one, so...}
  162.   /$4A                   {      Dec  DX                 ;Decrement char's left counter}
  163.   /$52                   {      Push DX                 }
  164.   /$46                   {      Inc  SI                 ;Incr. position}
  165.   /$41                   {      Inc  CX                 ;Incr # of chars we want BIOS to write}
  166.   /$FE/$46/<COL          {      Inc  Byte Ptr [BP+<Col] ;Incr column to write at}
  167.   /$EB/$E8               {      Jmp  L8                 ;Loop to see if next char is also identical}
  168.   /$CD/$10               {L9:   Int  $10                ;Write CX copies of char and attrib}
  169.   /$59                   {      Pop  CX                 ;Get # of chars left}
  170.   /$E2/$C1           {##}{      Loop L7                 ;Loop if more to do}
  171.   /$5A                   {L10:  Pop  DX                 ;Get back original cursor position}
  172.   /$30/$FF               {      Xor  BH,BH              ;Display page 0}
  173.   /$B4/$02               {      Mov  AH,2               ;Set cursor position function}
  174.   /$CD/$10);             {      Int  $10                }
  175.     end;  {BIOS writing}
  176. end;  {FastWrite}
  177.  
  178.  
  179. {End of file}