home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / TURBOPAS / NOSNOW2.ZIP / NOSNOW2.PAS
Encoding:
Pascal/Delphi Source File  |  1986-02-02  |  14.1 KB  |  337 lines

  1. program nosnow;
  2.  
  3. {======================================================================}
  4. {                                                                      }
  5. { 2 procedures to write 1 byte to the display; avoid "snow"            }
  6. { 1 procedure to build an entire screen, 500 bytes at a time; avoid    }
  7. {    "snow".                                                           }
  8. {                                                                      }
  9. { NOTE: These procedures are released to the public domain on the      }
  10. { condition that nobody tells on me. There are a lot of skiers here    }
  11. { in Salt Lake City who would get very mad at somebody who was trying  }
  12. { to eliminate snow!                                                   }
  13. {                                                                      }
  14. {======================================================================}
  15.  
  16. { By Michael Quinlan   7/1/85  }
  17.  
  18. {======================================================================}
  19. {                                                                      }
  20. { NoSnow1 is not as fast as NoSnow2, but it has these advantages:      }
  21. {                                                                      }
  22. {   1. Should work on almost any PC compatible,                        }
  23. {   2. Should work with almost any display adaptor and monitor.        }
  24. {   3. Absolutely no "snow".                                           }
  25. {                                                                      }
  26. { It works by calling the BIOS to position the cursor, then calling    }
  27. { the BIOS again to write the character.                               }
  28. {                                                                      }
  29. {======================================================================}
  30.  
  31. {$C-}   { do not interput control codes }
  32. {$V-}   { do NOT check that actual and formal parameters agree }
  33.  
  34. procedure NoSnow1(r, c : integer; ch : char; a : byte);
  35.  
  36. { r = row (1..25)
  37.   c = column (1..80)
  38.   ch = character to write
  39.   a = attribute of character }
  40.  
  41.   begin
  42.     Inline(
  43.       $8a/$76/<r/      { mov dh,r[bp]   ;get row }
  44.       $fe/$ce/         { dec dh         ;convert row to [0..24] }
  45.       $8a/$56/<c/      { mov dl,c[bp]   ;get col }
  46.       $fe/$ca/         { dec dl         ;convert col to [0..79] }
  47.       $b7/$00/         { mov bh,0       ;page }
  48.       $b4/$02/         { mov ah,2       ;set cursor position }
  49.       $cd/$10/         { int $10        ;have BIOS do the dirty work }
  50.       $b7/$00/         { mov bh,0       ;page }
  51.       $b9/>1/          { mov cx,1       ;number of copies }
  52.       $8a/$46/<ch/     { mov al,ch[bp]  ;character }
  53.       $8a/$5e/<a/      { mov bl,a[bp]   ;attribute }
  54.       $b4/$09/         { mov ah,9       ;write attr/char }
  55.       $cd/$10)         { int $10        ;have BIOS do the dirty work }
  56.   end;
  57.  
  58. {======================================================================}
  59. {                                                                      }
  60. { NoSnow2 writes a single character as fast as possible to the         }
  61. { display buffer. It seems that there is still some "snow" on the      }
  62. { left edge of the screen (it usually isn't very noticable). The code  }
  63. { only works with the color graphics adaptor in 25x80 text mode. It    }
  64. { would be simple (but useless) to change the code to work with other  }
  65. { adaptors.                                                            }
  66. {                                                                      }
  67. { NoSnow2 only works on an IBM PC or highly compatible.                }
  68. {                                                                      }
  69. {======================================================================}
  70.  
  71. procedure NoSnow2(r, c : integer; ch : char; a : byte);
  72.  
  73. { r = row (1..25)
  74.   c = column (1..80)
  75.   ch = character to write
  76.   a = attribute of character }
  77.  
  78.   begin
  79.     Inline(
  80.      $8a/$46/<r/       { mov al,r[bp]   ;get row }
  81.      $fe/$c8/          { dec al         ;convert to [0..24] }
  82.      $bb/>80/          { mov bx,80      ;# columns per row }
  83.      $f7/$e3/          { mul bx         ;calc offset into display buffer }
  84.      $03/$46/<c/       { add ax,c[bp]   ;add in column }
  85.      $48/              { dec ax         ;adjust for column in [0..79] }
  86.      $03/$c0/          { add ax,ax      ;mult by to to get buffer offset }
  87.      $8b/$f8/          { mov di,ax      ;save offset for later }
  88.      $b8/$b800/        { mov ax,$b800   ;color display base }
  89.      $1e/              { push ds        ;save seg reg }
  90.      $8e/$d8/          { mov ds,ax }
  91.      $8a/$5e/<ch/      { mov bl,ch[bp]  ;character }
  92.      $8a/$7e/<a/       { mov bh,a[bp]   ;attribute }
  93.      $ba/$03da/        { mov dx,$3da    ;color status port }
  94.      $fa/              { cli            ;don't allow interrupts }
  95. {L1:}
  96.      $ec/              { in al,dx       ;wait for partial horiz. retrace }
  97.      $a8/$01/          { test al,1 }
  98.      $75/$fb/          { jnz L1 }
  99. {L2:}
  100.      $ec/              { in al,dx       ;wait for horiz retrace }
  101.      $a8/$01/          { test al,1 }
  102.      $74/$fb/          { jz L2 }
  103. { horizontal retrace in progress. we must move very quickly here... }
  104.      $89/$1d/          { mov [di],bx    ;put char, attr in AX }
  105.      $fb/              { sti            ;now allow interrupts }
  106.      $1f);             { pop ds         ;restore seg reg }
  107.  end;
  108.  
  109. {======================================================================}
  110. {                                                                      }
  111. { Procedure ColorFlash writes an entire screen to the display buffer.  }
  112. { It waits for the vertical retrace, then moves 500 bytes (250         }
  113. { characters and attributes) at a time. It is amazingly fast and is    }
  114. { completely free of flicker and snow.                                 }
  115. {                                                                      }
  116. { ColorFlash only works on an IBM PC or highly compatible, with the    }
  117. { color graphics adaptor. As with NoSnow2, it would be easy to change  }
  118. { the code to work with other adaptors (but why? other adaptors don't  }
  119. { have the hardware bug that causes "snow" in the first place...).     }
  120. {                                                                      }
  121. { This code may leave interrupts disabled for too long. Some high      }
  122. { speed communications applications, for example, may lose characters  }
  123. { while we are waiting for the vertical retrace.                       }
  124. {                                                                      }
  125. {======================================================================}
  126.  
  127. type FlashBufferType = array [1..25] of
  128.                          array [1..80] of
  129.                            record
  130.                              c : char;
  131.                              a : byte
  132.                            end;
  133.  
  134. procedure ColorFlash(var d : FlashBufferType);
  135.   begin
  136.     inline(
  137.       $1E/                        { PUSH DS         ;save reg used }
  138.       $B8/$B800/                  { MOV AX,0B800h   ;dest. segment }
  139.       $8E/$C0/                    { MOV ES,AX }
  140.       $BF/$00/$00/                { MOV DI,0        ;dest. offset }
  141.       $8B/$76/$04/                { MOV SI,4[BP]    ;source offset }
  142.       $8E/$5e/$06/                { MOV DS,6[BP]    ;source segment }
  143.       $BA/$03DA/                  { MOV DX,03DAh    ;status register }
  144.       $FC/                        { CLD             ;go forwards }
  145.       $BB/$08/$00/                { MOV BX,8        ;8*250 = 2000 words }
  146. {LOOP:}
  147.       $B9/$FA/$00/                { MOV CX,250      ;250 words/500 bytes }
  148.       $FA/                        { CLI             ;don't allow interrupts }
  149. {WAIT1:  ;wait for any partially complete vertical retrace to finish }
  150.       $EC/                        { IN AL,DX }
  151.       $A8/$08/                    { TEST AL,08h }
  152.       $75/$FB/                    { JNZ WAIT1 }
  153. {WAIT2:  ;wait for the next vertical retrace to begin }
  154.       $EC/                        { IN AL,DX }
  155.       $A8/$08/                    { TEST AL,08h }
  156.       $74/$FB/                    { JZ WAIT2 }
  157. { vertical retrace in progress; copy part of the buffer }
  158.       $F3/$A5/                    { REP MOVSW       ;move 250 word chunk }
  159.       $FB/                        { STI             ;allow interrupts }
  160.       $4B/                        { DEC BX          ;more left to move? }
  161.       $75/$EC/                    { JNZ LOOP        ;yes -- loop back }
  162.       $1F)                        { POP DS          ;no -- done }
  163.   end;
  164.  
  165. {======================================================================}
  166. { Procedure ColorFlash2 writes an entire screen as fast as possible to }
  167. { the to the display buffer.  There is some "snow" but the screen is   }
  168. { writen very quickly.                                                 }
  169. {                                                                      }
  170. { The code only works with the color graphics adaptor in 25x80 text    }
  171. { mode. It would be simple (but useless) to change the code to work    }
  172. { with other adaptors.                                                 }
  173. {                                                                      }
  174. { ColorFlash2 only works on an IBM PC or highly compatible.            }
  175. {                                                                      }
  176. { ColorFlash2 is the same code as ColorFlash except that vertical      }
  177. { retrace check has been remove.                                       }
  178. {======================================================================}
  179.  
  180. procedure ColorFlash2(var d : FlashBufferType);
  181.   begin
  182.     inline(
  183.       $1E/                        { PUSH DS         ;save reg used }
  184.       $B8/$B800/                  { MOV AX,0B800h   ;dest. segment }
  185.       $8E/$C0/                    { MOV ES,AX }
  186.       $BF/$00/$00/                { MOV DI,0        ;dest. offset }
  187.       $8B/$76/$04/                { MOV SI,4[BP]    ;source offset }
  188.       $8E/$5e/$06/                { MOV DS,6[BP]    ;source segment }
  189.       $BA/$03DA/                  { MOV DX,03DAh    ;status register }
  190.  
  191.       $FC/                        { CLD             ;go forwards }
  192.  
  193.       $B9/$D0/$07/                { MOV CX,2000     ;2000 words/4000 bytes }
  194.       $FA/                        { CLI             ;don't allow interrupts }
  195.       $F3/$A5/                    { REP MOVSW       ;move 2000 word chunk }
  196.       $FB/                        { STI             ;allow interrupts }
  197.  
  198.       $1F)                        { POP DS          ;no -- done }
  199.   end;
  200.  
  201. {======================================================================}
  202. {                                                                      }
  203. { simple code to show off the above routines.                          }
  204. {                                                                      }
  205. {======================================================================}
  206.  
  207. var i, j    : integer;
  208.     symbol  : char;
  209.     b       : FlashBufferType;
  210.     b1,b2,b3,b4,b5,b6,b7,b8,b9,b10 : FlashBufferType;
  211.  
  212. begin
  213.  
  214. { prepare for "ColorFlash" routine }
  215.   for i := 1 to 25 do
  216.     for j := 1 to 80 do
  217.       with b[i, j] do begin
  218.         a := $1e;       { attribute byte }
  219.         c := '?'        { actual symbol to display }
  220.       end;
  221.  
  222.   for i := 1 to 25 do
  223.     for j := 1 to 80 do
  224.       begin;
  225.         b1[i, j].a:=$07;  { attribute byte }
  226.         b1[i, j].c:= '1'; { actual symbol to display }
  227.  
  228.         b2[i, j].a:=$07;  { attribute byte }
  229.         b2[i, j].c:= '2'; { actual symbol to display }
  230.  
  231.         b3[i, j].a:=$07;  { attribute byte }
  232.         b3[i, j].c:= '3'; { actual symbol to display }
  233.  
  234.         b4[i, j].a:=$07;  { attribute byte }
  235.         b4[i, j].c:= '4'; { actual symbol to display }
  236.  
  237.         b5[i, j].a:=$07;  { attribute byte }
  238.         b5[i, j].c:= '5'; { actual symbol to display }
  239.  
  240.         b6[i, j].a:=$07;  { attribute byte }
  241.         b6[i, j].c:= '6'; { actual symbol to display }
  242.  
  243.         b7[i, j].a:=$07;  { attribute byte }
  244.         b7[i, j].c:= '7'; { actual symbol to display }
  245.  
  246.         b8[i, j].a:=$07;  { attribute byte }
  247.         b8[i, j].c:= '8'; { actual symbol to display }
  248.  
  249.         b9[i, j].a:=$07;  { attribute byte }
  250.         b9[i, j].c:= '9'; { actual symbol to display }
  251.  
  252.         b10[i, j].a:=$07;  { attribute byte }
  253.         b10[i, j].c:= '0'; { actual symbol to display }
  254.       end;
  255.  
  256.   ClrScr;
  257.   GotoXY(1,25);
  258.   write('Ready to Begin, Press Enter...');
  259.   ReadLn;
  260.  
  261.   ClrScr;
  262.   for i := 1 to 25 do
  263.     for j := 1 to 79 do begin
  264.       GotoXY(j, i);
  265.       write('z')
  266.     end;
  267.   GotoXY(1,25);
  268.   Write('Turbo Pascal Write Done, Press Enter...');
  269.   ReadLn;
  270.  
  271.   ClrScr;
  272.   for i := 1 to 25 do
  273.     for j := 1 to 80 do
  274.       NoSnow1(i, j, 'x', $1e);
  275.   GotoXY(1,25);
  276.   write('NoSnow1 Done, Press Enter...');
  277.   ReadLn;
  278.  
  279.   ClrScr;
  280.   for i := 1 to 25 do
  281.     for j := 1 to 80 do
  282.       NoSnow2(i, j, 'a', $1e);
  283.   GotoXY(1,25);
  284.   write('NoSnow2 Done, Press Enter...');
  285.   ReadLn;
  286.  
  287.   ClrScr;
  288.   ColorFlash(b);
  289.   GoToXY(1,25);
  290.   write('ColorFlash Done, Press Enter...');
  291.   ReadLn;
  292.  
  293.   ClrScr;
  294.   ColorFlash2(b2);
  295.   GoToXY(1,25);
  296.   write('ColorFlash 2 Done, Press Enter...');
  297.   ReadLn(con,symbol);
  298.  
  299.   ClrScr;
  300.   repeat
  301.     gotoXY(1,1);
  302.     writeln('In order to give you a better feel for the differents in speed ');
  303.     writeln('between ColorFlash and ColorFlash2 the following example will');
  304.     writeln('rewrite the screen 10 times once with 0, once with 1, ',
  305.              'and so on through 9.');
  306.     write('enter 1 for ColorFlash or 2 for ColorFlash 2 or Q to quit ');
  307.     readln(con,symbol);
  308.  
  309.     if symbol='1' then
  310.       begin;
  311.         ColorFlash(b1);
  312.         ColorFlash(b2);
  313.         ColorFlash(b3);
  314.         ColorFlash(b4);
  315.         ColorFlash(b5);
  316.         ColorFlash(b6);
  317.         ColorFlash(b7);
  318.         ColorFlash(b8);
  319.         ColorFlash(b9);
  320.         ColorFlash(b10);
  321.       end;
  322.     if symbol='2' then
  323.       begin;
  324.         ColorFlash2(b1);
  325.         ColorFlash2(b2);
  326.         ColorFlash2(b3);
  327.         ColorFlash2(b4);
  328.         ColorFlash2(b5);
  329.         ColorFlash2(b6);
  330.         ColorFlash2(b7);
  331.         ColorFlash2(b8);
  332.         ColorFlash2(b9);
  333.         ColorFlash2(b10);
  334.       end;
  335.   until symbol in ['Q','q'];
  336. end.
  337.