home *** CD-ROM | disk | FTP | other *** search
- program nosnow;
-
- {======================================================================}
- { }
- { 2 procedures to write 1 byte to the display; avoid "snow" }
- { 1 procedure to build an entire screen, 500 bytes at a time; avoid }
- { "snow". }
- { }
- { NOTE: These procedures are released to the public domain on the }
- { condition that nobody tells on me. There are a lot of skiers here }
- { in Salt Lake City who would get very mad at somebody who was trying }
- { to eliminate snow! }
- { }
- {======================================================================}
-
- { By Michael Quinlan 7/1/85 }
-
- {======================================================================}
- { }
- { NoSnow1 is not as fast as NoSnow2, but it has these advantages: }
- { }
- { 1. Should work on almost any PC compatible, }
- { 2. Should work with almost any display adaptor and monitor. }
- { 3. Absolutely no "snow". }
- { }
- { It works by calling the BIOS to position the cursor, then calling }
- { the BIOS again to write the character. }
- { }
- {======================================================================}
-
- {$C-} { do not interput control codes }
- {$V-} { do NOT check that actual and formal parameters agree }
-
- procedure NoSnow1(r, c : integer; ch : char; a : byte);
-
- { r = row (1..25)
- c = column (1..80)
- ch = character to write
- a = attribute of character }
-
- begin
- Inline(
- $8a/$76/<r/ { mov dh,r[bp] ;get row }
- $fe/$ce/ { dec dh ;convert row to [0..24] }
- $8a/$56/<c/ { mov dl,c[bp] ;get col }
- $fe/$ca/ { dec dl ;convert col to [0..79] }
- $b7/$00/ { mov bh,0 ;page }
- $b4/$02/ { mov ah,2 ;set cursor position }
- $cd/$10/ { int $10 ;have BIOS do the dirty work }
- $b7/$00/ { mov bh,0 ;page }
- $b9/>1/ { mov cx,1 ;number of copies }
- $8a/$46/<ch/ { mov al,ch[bp] ;character }
- $8a/$5e/<a/ { mov bl,a[bp] ;attribute }
- $b4/$09/ { mov ah,9 ;write attr/char }
- $cd/$10) { int $10 ;have BIOS do the dirty work }
- end;
-
- {======================================================================}
- { }
- { NoSnow2 writes a single character as fast as possible to the }
- { display buffer. It seems that there is still some "snow" on the }
- { left edge of the screen (it usually isn't very noticable). The code }
- { only works with the color graphics adaptor in 25x80 text mode. It }
- { would be simple (but useless) to change the code to work with other }
- { adaptors. }
- { }
- { NoSnow2 only works on an IBM PC or highly compatible. }
- { }
- {======================================================================}
-
- procedure NoSnow2(r, c : integer; ch : char; a : byte);
-
- { r = row (1..25)
- c = column (1..80)
- ch = character to write
- a = attribute of character }
-
- begin
- Inline(
- $8a/$46/<r/ { mov al,r[bp] ;get row }
- $fe/$c8/ { dec al ;convert to [0..24] }
- $bb/>80/ { mov bx,80 ;# columns per row }
- $f7/$e3/ { mul bx ;calc offset into display buffer }
- $03/$46/<c/ { add ax,c[bp] ;add in column }
- $48/ { dec ax ;adjust for column in [0..79] }
- $03/$c0/ { add ax,ax ;mult by to to get buffer offset }
- $8b/$f8/ { mov di,ax ;save offset for later }
- $b8/$b800/ { mov ax,$b800 ;color display base }
- $1e/ { push ds ;save seg reg }
- $8e/$d8/ { mov ds,ax }
- $8a/$5e/<ch/ { mov bl,ch[bp] ;character }
- $8a/$7e/<a/ { mov bh,a[bp] ;attribute }
- $ba/$03da/ { mov dx,$3da ;color status port }
- $fa/ { cli ;don't allow interrupts }
- {L1:}
- $ec/ { in al,dx ;wait for partial horiz. retrace }
- $a8/$01/ { test al,1 }
- $75/$fb/ { jnz L1 }
- {L2:}
- $ec/ { in al,dx ;wait for horiz retrace }
- $a8/$01/ { test al,1 }
- $74/$fb/ { jz L2 }
- { horizontal retrace in progress. we must move very quickly here... }
- $89/$1d/ { mov [di],bx ;put char, attr in AX }
- $fb/ { sti ;now allow interrupts }
- $1f); { pop ds ;restore seg reg }
- end;
-
- {======================================================================}
- { }
- { Procedure ColorFlash writes an entire screen to the display buffer. }
- { It waits for the vertical retrace, then moves 500 bytes (250 }
- { characters and attributes) at a time. It is amazingly fast and is }
- { completely free of flicker and snow. }
- { }
- { ColorFlash only works on an IBM PC or highly compatible, with the }
- { color graphics adaptor. As with NoSnow2, it would be easy to change }
- { the code to work with other adaptors (but why? other adaptors don't }
- { have the hardware bug that causes "snow" in the first place...). }
- { }
- { This code may leave interrupts disabled for too long. Some high }
- { speed communications applications, for example, may lose characters }
- { while we are waiting for the vertical retrace. }
- { }
- {======================================================================}
-
- type FlashBufferType = array [1..25] of
- array [1..80] of
- record
- c : char;
- a : byte
- end;
-
- procedure ColorFlash(var d : FlashBufferType);
- begin
- inline(
- $1E/ { PUSH DS ;save reg used }
- $B8/$B800/ { MOV AX,0B800h ;dest. segment }
- $8E/$C0/ { MOV ES,AX }
- $BF/$00/$00/ { MOV DI,0 ;dest. offset }
- $8B/$76/$04/ { MOV SI,4[BP] ;source offset }
- $8E/$5e/$06/ { MOV DS,6[BP] ;source segment }
- $BA/$03DA/ { MOV DX,03DAh ;status register }
- $FC/ { CLD ;go forwards }
- $BB/$08/$00/ { MOV BX,8 ;8*250 = 2000 words }
- {LOOP:}
- $B9/$FA/$00/ { MOV CX,250 ;250 words/500 bytes }
- $FA/ { CLI ;don't allow interrupts }
- {WAIT1: ;wait for any partially complete vertical retrace to finish }
- $EC/ { IN AL,DX }
- $A8/$08/ { TEST AL,08h }
- $75/$FB/ { JNZ WAIT1 }
- {WAIT2: ;wait for the next vertical retrace to begin }
- $EC/ { IN AL,DX }
- $A8/$08/ { TEST AL,08h }
- $74/$FB/ { JZ WAIT2 }
- { vertical retrace in progress; copy part of the buffer }
- $F3/$A5/ { REP MOVSW ;move 250 word chunk }
- $FB/ { STI ;allow interrupts }
- $4B/ { DEC BX ;more left to move? }
- $75/$EC/ { JNZ LOOP ;yes -- loop back }
- $1F) { POP DS ;no -- done }
- end;
-
- {======================================================================}
- { Procedure ColorFlash2 writes an entire screen as fast as possible to }
- { the to the display buffer. There is some "snow" but the screen is }
- { writen very quickly. }
- { }
- { The code only works with the color graphics adaptor in 25x80 text }
- { mode. It would be simple (but useless) to change the code to work }
- { with other adaptors. }
- { }
- { ColorFlash2 only works on an IBM PC or highly compatible. }
- { }
- { ColorFlash2 is the same code as ColorFlash except that vertical }
- { retrace check has been remove. }
- {======================================================================}
-
- procedure ColorFlash2(var d : FlashBufferType);
- begin
- inline(
- $1E/ { PUSH DS ;save reg used }
- $B8/$B800/ { MOV AX,0B800h ;dest. segment }
- $8E/$C0/ { MOV ES,AX }
- $BF/$00/$00/ { MOV DI,0 ;dest. offset }
- $8B/$76/$04/ { MOV SI,4[BP] ;source offset }
- $8E/$5e/$06/ { MOV DS,6[BP] ;source segment }
- $BA/$03DA/ { MOV DX,03DAh ;status register }
-
- $FC/ { CLD ;go forwards }
-
- $B9/$D0/$07/ { MOV CX,2000 ;2000 words/4000 bytes }
- $FA/ { CLI ;don't allow interrupts }
- $F3/$A5/ { REP MOVSW ;move 2000 word chunk }
- $FB/ { STI ;allow interrupts }
-
- $1F) { POP DS ;no -- done }
- end;
-
- {======================================================================}
- { }
- { simple code to show off the above routines. }
- { }
- {======================================================================}
-
- var i, j : integer;
- symbol : char;
- b : FlashBufferType;
- b1,b2,b3,b4,b5,b6,b7,b8,b9,b10 : FlashBufferType;
-
- begin
-
- { prepare for "ColorFlash" routine }
- for i := 1 to 25 do
- for j := 1 to 80 do
- with b[i, j] do begin
- a := $1e; { attribute byte }
- c := '?' { actual symbol to display }
- end;
-
- for i := 1 to 25 do
- for j := 1 to 80 do
- begin;
- b1[i, j].a:=$07; { attribute byte }
- b1[i, j].c:= '1'; { actual symbol to display }
-
- b2[i, j].a:=$07; { attribute byte }
- b2[i, j].c:= '2'; { actual symbol to display }
-
- b3[i, j].a:=$07; { attribute byte }
- b3[i, j].c:= '3'; { actual symbol to display }
-
- b4[i, j].a:=$07; { attribute byte }
- b4[i, j].c:= '4'; { actual symbol to display }
-
- b5[i, j].a:=$07; { attribute byte }
- b5[i, j].c:= '5'; { actual symbol to display }
-
- b6[i, j].a:=$07; { attribute byte }
- b6[i, j].c:= '6'; { actual symbol to display }
-
- b7[i, j].a:=$07; { attribute byte }
- b7[i, j].c:= '7'; { actual symbol to display }
-
- b8[i, j].a:=$07; { attribute byte }
- b8[i, j].c:= '8'; { actual symbol to display }
-
- b9[i, j].a:=$07; { attribute byte }
- b9[i, j].c:= '9'; { actual symbol to display }
-
- b10[i, j].a:=$07; { attribute byte }
- b10[i, j].c:= '0'; { actual symbol to display }
- end;
-
- ClrScr;
- GotoXY(1,25);
- write('Ready to Begin, Press Enter...');
- ReadLn;
-
- ClrScr;
- for i := 1 to 25 do
- for j := 1 to 79 do begin
- GotoXY(j, i);
- write('z')
- end;
- GotoXY(1,25);
- Write('Turbo Pascal Write Done, Press Enter...');
- ReadLn;
-
- ClrScr;
- for i := 1 to 25 do
- for j := 1 to 80 do
- NoSnow1(i, j, 'x', $1e);
- GotoXY(1,25);
- write('NoSnow1 Done, Press Enter...');
- ReadLn;
-
- ClrScr;
- for i := 1 to 25 do
- for j := 1 to 80 do
- NoSnow2(i, j, 'a', $1e);
- GotoXY(1,25);
- write('NoSnow2 Done, Press Enter...');
- ReadLn;
-
- ClrScr;
- ColorFlash(b);
- GoToXY(1,25);
- write('ColorFlash Done, Press Enter...');
- ReadLn;
-
- ClrScr;
- ColorFlash2(b2);
- GoToXY(1,25);
- write('ColorFlash 2 Done, Press Enter...');
- ReadLn(con,symbol);
-
- ClrScr;
- repeat
- gotoXY(1,1);
- writeln('In order to give you a better feel for the differents in speed ');
- writeln('between ColorFlash and ColorFlash2 the following example will');
- writeln('rewrite the screen 10 times once with 0, once with 1, ',
- 'and so on through 9.');
- write('enter 1 for ColorFlash or 2 for ColorFlash 2 or Q to quit ');
- readln(con,symbol);
-
- if symbol='1' then
- begin;
- ColorFlash(b1);
- ColorFlash(b2);
- ColorFlash(b3);
- ColorFlash(b4);
- ColorFlash(b5);
- ColorFlash(b6);
- ColorFlash(b7);
- ColorFlash(b8);
- ColorFlash(b9);
- ColorFlash(b10);
- end;
- if symbol='2' then
- begin;
- ColorFlash2(b1);
- ColorFlash2(b2);
- ColorFlash2(b3);
- ColorFlash2(b4);
- ColorFlash2(b5);
- ColorFlash2(b6);
- ColorFlash2(b7);
- ColorFlash2(b8);
- ColorFlash2(b9);
- ColorFlash2(b10);
- end;
- until symbol in ['Q','q'];
- end.