Created
December 21, 2025 11:28
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ; ============================== | |
| ; | |
| ; 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