Skip to content

Instantly share code, notes, and snippets.

@IvanTheProtogen
Created December 21, 2025 11:28
Show Gist options
  • Select an option

  • Save IvanTheProtogen/3288861acf499aca63013a3cfb3fff95 to your computer and use it in GitHub Desktop.

Select an option

Save IvanTheProtogen/3288861acf499aca63013a3cfb3fff95 to your computer and use it in GitHub Desktop.
Demonstration of a DOS program which fills half of the screen with light blue color in video mode 13h.
; ==============================
;
; DEMONSTRATION OF A DOS PROGRAM
; WHICH FILLS HALF OF THE SCREEN
; WITH LIGHT BLUE COLOR IN VIDEO
; MODE 13H
;
; ==============================
org 0x100 ; Necessary for .COM files
; Before we'll do the filling, we must set the necessary video mode first
; And more crucially, we must save the previous video mode first
mov ah,0x0F ; get video mode function
int 0x10 ; BIOS interrupt
; Now, AL should have the current video mode
mov bl,al ; We are using BX to store the previous video mode, since using the memory instead of the register is often slower, and we don't use BX in our code much
; Now set our desired video mode
; Set video mode 13h
mov ax,0x0013 ; AH (0x00) = set video mode function; AL (0x13) = 320x200 256-color VGA
int 0x10 ; BIOS interrupt
; Let's make sure the video mode is set, as some systems may not support Mode 13h
; Get video mode 13h
mov ah,0x0F ; get video mode function
int 0x10 ; BIOS interrupt
; Then, compare to the desired video mode, exit if not equal
xor al,0x13 ; We use XOR because mathematically, if the inputs are equal, the output should be zero
jnz exit ; If the output isn't zero, we assume the video mode isn't set to what we desired, so we jump straight to the exit
; When we get past this point, we assume it's safe to do the filling now
; Here, we assume the location for the video buffer for Mode 13h is A000:0000, which is documented and guaranteed reliable by the VGA manufacturers and DOS engineers
; We are using Direct Memory Address method, since we guarantee it is the fastest, yet still reliable
mov ax,0xA000 ; Memory address >A000<:0000 ([>ES<:DI])
mov es,ax ; x86 cannot do 'mov es,0xA000', so this is what only works best
xor di,di ; Memory address A000:>0000< ([ES:>DI<)
mov dx,200 ; Counter for 'dec dx; jnz fill' -- Repeat 200 times for Y axis
mov ax,0x0909 ; Pattern to repeat (2 bytes) -- On default VGA palette, 0x09 is light blue
fill:
; For every Y axis (1-200), we put 160 pixels up the X axis
mov cx,80 ; Amount of patterns to put -- Repeat 80 times for X axies -- 80 because the pattern is 2 bytes wide, so CX=160/2=80 -- At every loop, because 'rep stosw' resets CX to 0
; In some cases 'cld' (Clear direction flag) is required, but the code here works without it
rep stosw ; Repeat WORD function on [ES:DI] -- The main part of filling here
add di,160 ; Increment [ES:>DI<] by 160, because each pixel on VGA is accessed via y*320+x
dec dx ; Decrement the counter for every loop iteration
jnz fill ; Repeat the filling process until the counter is zero
; When we get past this point, we must wait for user input first
; Wait until keypress
mov ah,0x00 ; wait until keypress function
int 0x16 ; BIOS interrupt
; And now we gracefully shut down the program
exit:
; Before exiting, we must set the previous video mode
; Set video mode 3h
mov ah,0x00 ; set video mode function
mov al,bl ; Previous video mode we've saved into BX before
int 0x10 ; BIOS interrupt
; Exit program
mov ax,0x4C00 ; AH (0x4C) = exit program function; AL (0x00) = exit program return code
int 0x21 ; DOS interrupt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment