5

So at the moment i am copying a screenbuffer (screenbuffer db 64000 DUP(0)) to the video memory (which starts at 0a0000h) to clear the screen. But i was wondering if it is better to just setup the video mode again like this:

mov ax, 13h
int 10h

which seems to clear the screen as well.

Or is there an even better way to clear the screen?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
T Snake
  • 89
  • 1
  • 8
  • 2
    Have you just considered using _REP [STOSD](http://www.felixcloutier.com/x86/STOS:STOSB:STOSW:STOSD:STOSQ.html)_ to do it? – Michael Petch Dec 25 '16 at 02:14
  • 2
    Mind you, the BIOS calls were rather slow. So your way of copying screenbuffer (if you did that by some fast way like `rep movsd`) is actually quite good. The `rep stosd` is even faster, but if you are drawing something on the screen every frame, then use `rep stosd` on your screenbuffer, then draw there, then copy it to screen. `int 10h` solutions are inferior when compared to direct VRAM access (even if you do something penalized like accessing VRAM in unfortunate pattern). And if you draw enough things to cover whole screenbuffer, you don't need to clear it (for ex. DOOM1/2 didn't clear). – Ped7g Dec 25 '16 at 09:55

2 Answers2

4

There is INT 10H function to clear the screen: AH=06h, AL=00h

You can set the color in BH.

This is INT 10H Scroll up window function which clears the screen if AL=0

The function applies to a rectangular area which is set in other registers, e.g. DH = Lower row number, DL = Right column number.

The standard way to clear the screen is to set CX to 0000H, DL to 0040:[004a]-1 (usually 79), DH to 0040:[0084] (usually 24), BH to 07H (white-on black video attribute), and AL to 00H (to clear the entire screen).

Fedor Losev
  • 3,244
  • 15
  • 13
  • This seems to work only if DL is set to a minimum of 39 and DH to a minimum of 24. I guess this has to to with the width and height of the screen, but i don't understand why 39 and 24. – T Snake Dec 24 '16 at 23:47
  • 1
    Function takes also character window rectangle where it applies, I've expanded the answer. – Fedor Losev Dec 25 '16 at 00:05
4

You could use STOSD with a REP prefix to clear video memory for video mode 13 (320x200x256 colors). REP STOSD will repeat STOSD by the count stored in ECX . STOSD will write each DWORD in EAX to ES:[EDI] incrementing EDI by 4 each time.

REP: Repeats a string instruction the number of times specified in the count register.

STOSD: stores a doubleword from the EAX register into the destination operand.

Sample code could look something like:

cld                    ; Set forward direction for STOSD
mov ax, 0x0013
int 0x10               ; Set video mode 0x13 (320x200x256 colors)

push es                ; Save ES if you want to restore it after
mov ax, 0xa000
mov es, ax             ; Beginning of VGA memory in segment 0xA000
mov eax, 0x76767676    ; Set the color to clear with 0x76 (green?) 0x00=black
xor edi, edi           ; Destination address set to 0
mov ecx, (320*200)/4   ; We are doing 4 bytes at a time so count = (320*200)/4 DWORDS
rep stosd              ; Clear video memory
pop es                 ; Restore ES

This code assumes you are on a 32-bit processor, but doesn't assume you are running in unreal mode.

If you are using a 16-bit processor (8086/80186/80286) you would have to use the 16-bit registers, and use REP STOSW . CX would be set to (320*200)/2 instead of (320*200)/4. The 16-bit processors don't allow for 32-bit operands so don't support STOSD.

You could easily convert this code to be an assembly language function.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198