By using this site, you agree to the Privacy Policy and Terms of Use.
Accept
World of SoftwareWorld of SoftwareWorld of Software
  • News
  • Software
  • Mobile
  • Computing
  • Gaming
  • Videos
  • More
    • Gadget
    • Web Stories
    • Trending
    • Press Release
Search
  • Privacy
  • Terms
  • Advertise
  • Contact
Copyright © All Rights Reserved. World of Software.
Reading: Redefining ‘A’ in VGA Mode 03h | HackerNoon
Share
Sign In
Notification Show More
Font ResizerAa
World of SoftwareWorld of Software
Font ResizerAa
  • Software
  • Mobile
  • Computing
  • Gadget
  • Gaming
  • Videos
Search
  • News
  • Software
  • Mobile
  • Computing
  • Gaming
  • Videos
  • More
    • Gadget
    • Web Stories
    • Trending
    • Press Release
Have an existing account? Sign In
Follow US
  • Privacy
  • Terms
  • Advertise
  • Contact
Copyright © All Rights Reserved. World of Software.
World of Software > Computing > Redefining ‘A’ in VGA Mode 03h | HackerNoon
Computing

Redefining ‘A’ in VGA Mode 03h | HackerNoon

News Room
Last updated: 2026/01/10 at 10:41 PM
News Room Published 10 January 2026
Share
Redefining ‘A’ in VGA Mode 03h | HackerNoon
SHARE

In the 8086-era DOS environment, text display typically relied on the BIOS and the graphics adapter’s built-in character generator rather than any sophisticated font rendering system. The fonts were firmly tied to specific text modes implemented by adapters such as CGA, EGA, or VGA. One of the most common modes was text mode 03h, which presented an 80×25 text grid.

In one of our previous deep dives, we explored the infamous VGA-Mode 13h and how to integrate hardware timers to produce simple beeps with the PC-Speaker. This time, we’ll change the appearance of an ASCII character ( in this case ‘A’ ) by redefining its pixel data. In our next part you will also understand where this is actually heading for.

ASCII and the DOS Character Set

ASCII (American Standard Code for Information Interchange) is originally a 7-bit code that defines characters (letters, digits, punctuation) in the range 0–127. In DOS, the standard extended ASCII set (often called Code Page 437) added an additional 128 characters (128–255), including box-drawing characters, symbols, and other glyphs used frequently in the DOS world.

Text Mode 03h (80×25)

One of the typical display modes used in 8086 DOS for text output is Mode 03h. In Mode 03h, the screen is divided into 80 columns and 25 rows of text characters. Each position on the screen is one text cell which holds one character plus attributes (like foreground and background colors, blinking, etc.).

  • With the earliest CGA (Color Graphics Adapter), each text cell was typically an 8×8 pixel matrix (though some adapters might effectively use 8×14 or 9×14 for EGA, and 9×16 for VGA).

  • For standard VGA in 80×25 text mode, each character cell is often 9 pixels wide and 16 pixels tall (though the actual glyph itself might only occupy 8 pixels in width, with the 9th column used for spacing or other features).

    This program is called FRAPT - I highly recommend it

If you consider the typical VGA text mode of 9×16 character cells in 80×25, the total screen resolution in terms of raw pixels is 720×400 (80 columns × 9 pixels wide, 25 rows × 16 pixels tall). In Mode 03h, each character is stored in video RAM (at ES:DI B800h:0000h) with a Byte for the character Index (00h – FFh) and another byte for defining foreground color and background color (0-F for the Background and 0-F for the Foreground).

VGA Color Palette

How to?

There are times you might want to go beyond the default text-mode look. Maybe you want to display your own symbols, or get creative with ASCII graphics. In DOS and other low-level environments, you have an awesome ability to poke the BIOS or VGA memory directly to define what each character’s pixels look like. We will use the BIOS’ interrupt 10h with AL = 11h to load our custom font. Let’s break it down step by step:

Step By Step

First let’s clone our startup environment again so that you can follow along:

git clone [email protected]:MilesTails01/i8086_boilercode.git

After downloading you need to unpack DOSBOX.zip and TOOLS.zip

cd bin
tar -xf TOOLS.zip
tar -xf DOSBOX.zip

build.bat   // Compile, Link and Start the source
debug.bat   // Starts AFDEBUG and loads the compiled exe
start.bat   // Start the program without rebuilding it

Remove anything that is not needed. Keep the code simple and start with the minimum

;   #################################
;   #           ASCII.ASM           #
;   #################################

;   #################################
;   #           STACK               #
;   #################################
STACK SEGMENT PARA STACK
    db 256 dup(0)
STACK ENDS

;   #################################
;   #           DATA                #
;   #################################
DATA SEGMENT PARA 'DATA'
DATA ENDS

;   #################################
;   #           CODE                #
;   #################################
CODE SEGMENT PARA 'CODE'

    ASSUME cs:CODE, ds:DATA, ss:STACK
    mov ax, DATA
    mov ds, ax
    mov ax, STACK
    mov ss, ax
    mov sp, 256

CODE ENDS

Step 1

Let’s define our character pixel data first. 0 will become the background color and 1 will become the foreground color. Keep in mind in normal 80×25 Mode the dimension for a character are 9×16. We will define 14 rows each row containing 8bit cause (keep in mind to make the 9th bit 0 cause db is limited to 1 byte). This character will be striped block if you wonder what it will look like later.

CHAR_DATA   db  010101010b
            db  010101010b
            db  010101010b
            db  010101010b
            db  010101010b
            db  010101010b
            db  010101010b
            db  010101010b
            db  010101010b
            db  010101010b
            db  010101010b
            db  010101010b
            db  010101010b
            db  010101010b

Step 2

Let’s define a print function to fill the whole screen with the character A

PRINT PROC NEAR
    mov ax, 0B800h      ; VGA text mode memory segment
    mov es, ax
    mov di, 0           ; Start at the top-left of the screen
    mov cx, 2000        ; 80x25 screen = 2000 characters
    mov al, 'A'         ; ASCII code for 'A'
    mov ah, 19h         ; Attribute byte (blue on white)
    rep stosw           ; Fill screen with 'A'
    ret
PRINT ENDP

Step 3

Now the important part: We will use interrupt 10h (Bios Interrupt) with AH set to 11h. I wrote the definition of the parameter for AX, BX, CX, DX and BP in the comments.

REPLACE_ASCII PROC NEAR
    ;   mov ax, 03h         ; Set video mode to text mode (80x25, color)
    ;   int 10h             ; 9x16 font size
    ;
    ;   mov ax, 1112h       ; Force 8x8 font size for character cells
    ;   xor bl, bl          ; RAM block
    ;   int 10h

    ; Change text mode character (int 10h)
    ; AH    = 11h   
    ; BH    = Number of bytes per character
    ; CX    = Number of characters to change
    ; DX    = Starting character to change
    ; ES:BP = Offset of character data

    push ds
    pop es              ; make sure es = ds
    lea bp, CHAR_DATA   ; Pointer to custom font data
    mov ax, 1100h       ; Load user-defined font
    mov bh, 0Eh         ; Number of bytes per character
    xor bl,bl           ; RAM block
    mov cx, 01h         ; Number of characters to replace = 1 for now
    mov dx, 41h         ; Starting character to change (41h="A" in ASCII)
    int 10h             ; Call BIOS to load the font

    ret
REPLACE_ASCII ENDP

Step 4

Optional: If you like you can print the current ASCII table in the middle of the screen 😉

ASCIIPRINT PROC NEAR
    mov ax, 0B800h      ; VGA text mode memory segment
    mov es, ax
    xor di, di          ; Reset offset

    mov cx, 5           ; Total number of characters (0-255)
    mov ah, 4Fh         ; Attribute byte (red on white)
    mov dl, 10          ; Padding on the left (adjust as needed)
    mov dh, 60          ; Total width of the centered line (adjust as needed)
    mov di, 1620        ; Row (10 x 80 + padding) * 2, starting with left padding


PrintLoop:
    stosw               ; Store the character (AL) and attribute (AH)
    inc al              ; Move to the next ASCII character
    dec dh              ; Decrement width counter
    jnz PrintLoop       ; Continue until row width is filled
    add di, 40          ; Move to the next row with padding ((80 - 60) * 2)
    mov dh, 60          ; Reset row width
    loop PrintLoop      ; Repeat for all 256 characters

    ret
ASCIIPRINT ENDP

Result

Every character of A got replaced with the new striped block. This Glyph will come in very handy in a later article.

Replaced the Character 'A' with a new symbol

Screenshot from AdlibEditor - https://fenixfox-studios.com/content/adlib_editor/

Complete Code

;   #################################
;   #           ASCII.ASM           #
;   #################################

;   #################################
;   #           STACK               #
;   #################################
STACK SEGMENT PARA STACK
    db 256 dup(0)
STACK ENDS

;   #################################
;   #           DATA                #
;   #################################
DATA SEGMENT PARA 'DATA'
    CHAR_DATA   db  010101010b
                db  010101010b
                db  010101010b
                db  010101010b
                db  010101010b
                db  010101010b
                db  010101010b
                db  010101010b
                db  010101010b
                db  010101010b
                db  010101010b
                db  010101010b
                db  010101010b
                db  010101010b
DATA ENDS

;   #################################
;   #           CODE                #
;   #################################
CODE SEGMENT PARA 'CODE'

    ASSUME cs:CODE, ds:DATA, ss:STACK
    mov ax, DATA
    mov ds, ax
    mov ax, STACK
    mov ss, ax
    mov sp, 256

;   #################################
;   #           MAIN                #
;   #################################

    call REPLACE_ASCII
    call PRINT
    call ASCIIPRINT

    ret

;   =============================
;   |   FUNCTIONS               |
;   =============================

PUBLIC REPLACE_ASCII

REPLACE_ASCII PROC NEAR
    ;   mov ax, 03h         ; Set video mode to text mode (80x25, color)
    ;   int 10h             ; 9x16 font size
    ;
    ;   mov ax, 1112h       ; Force 8x8 font size for character cells
    ;   xor bl, bl          ; RAM block
    ;   int 10h

    ; Change text mode character (int 10h)
    ; AH    = 11h   
    ; BH    = Number of bytes per character
    ; CX    = Number of characters to change
    ; DX    = Starting character to change
    ; ES:BP = Offset of character data

    push ds
    pop es              ; make sure es = ds
    lea bp, CHAR_DATA   ; Pointer to custom font data
    mov ax, 1100h       ; Load user-defined font
    mov bh, 0Eh         ; Number of bytes per character
    xor bl,bl           ; RAM block
    mov cx, 01h         ; Number of characters to replace = 1 for now
    mov dx, 41h         ; Starting character to change (41h="A" in ASCII)
    int 10h             ; Call BIOS to load the font

    ret
REPLACE_ASCII ENDP

PRINT PROC NEAR
    mov ax, 0B800h      ; VGA text mode memory segment
    mov es, ax
    mov di, 0           ; Start at the top-left of the screen
    mov cx, 2000        ; 80x25 screen = 2000 characters
    mov al, 'A'         ; ASCII code for 'A'
    mov ah, 19h         ; Attribute byte (blue on white)
    rep stosw           ; Fill screen with 'A'
    ret
PRINT ENDP

ASCIIPRINT PROC NEAR
    mov ax, 0B800h      ; VGA text mode memory segment
    mov es, ax
    xor di, di          ; Reset offset

    mov cx, 5           ; Total number of characters (0-255)
    mov ah, 4Fh         ; Attribute byte (red on white)
    mov dl, 10          ; Padding on the left (adjust as needed)
    mov dh, 60          ; Total width of the centered line (adjust as needed)
    mov di, 1620        ; Row (10 x 80 + padding) * 2, starting with left padding


PrintLoop:
    stosw               ; Store the character (AL) and attribute (AH)
    inc al              ; Move to the next ASCII character
    dec dh              ; Decrement width counter
    jnz PrintLoop       ; Continue until row width is filled
    add di, 40          ; Move to the next row with padding ((80 - 60) * 2)
    mov dh, 60          ; Reset row width
    loop PrintLoop      ; Repeat for all 256 characters

    ret
ASCIIPRINT ENDP

CODE ENDS
END

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Twitter Email Print
Share
What do you think?
Love0
Sad0
Happy0
Sleepy0
Angry0
Dead0
Wink0
Previous Article Free BBC iPlayer rival adds 100s of tops shows in historic streaming deal Free BBC iPlayer rival adds 100s of tops shows in historic streaming deal
Next Article Here’s the one thing that Motorola needs to succeed in 2026 Here’s the one thing that Motorola needs to succeed in 2026
Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Stay Connected

248.1k Like
69.1k Follow
134k Pin
54.3k Follow

Latest News

Linux Lands Safeguard For RISC-V Against Another Microarchitectural Attack Vector
Linux Lands Safeguard For RISC-V Against Another Microarchitectural Attack Vector
Computing
Roborock cuts 0 off its best floor cleaner in a limited-time exclusive F25 Ultra deal – 9to5Mac
Roborock cuts $300 off its best floor cleaner in a limited-time exclusive F25 Ultra deal – 9to5Mac
News
With Hackers Targeting Windows 10 Users, You Should Upgrade With This Outstanding Deal
With Hackers Targeting Windows 10 Users, You Should Upgrade With This Outstanding Deal
News
Oppo unveils Find X8 with enhanced features for night portrait · TechNode
Oppo unveils Find X8 with enhanced features for night portrait · TechNode
Computing

You Might also Like

Linux Lands Safeguard For RISC-V Against Another Microarchitectural Attack Vector
Computing

Linux Lands Safeguard For RISC-V Against Another Microarchitectural Attack Vector

2 Min Read
Oppo unveils Find X8 with enhanced features for night portrait · TechNode
Computing

Oppo unveils Find X8 with enhanced features for night portrait · TechNode

4 Min Read
The TechBeat: I Saw a Phishing Site That Traps Security Bots (1/11/2026) | HackerNoon
Computing

The TechBeat: I Saw a Phishing Site That Traps Security Bots (1/11/2026) | HackerNoon

7 Min Read
GYESME: A New Design-Led Downstream Of GNOME Being Explored
Computing

GYESME: A New Design-Led Downstream Of GNOME Being Explored

3 Min Read
//

World of Software is your one-stop website for the latest tech news and updates, follow us now to get the news that matters to you.

Quick Link

  • Privacy Policy
  • Terms of use
  • Advertise
  • Contact

Topics

  • Computing
  • Software
  • Press Release
  • Trending

Sign Up for Our Newsletter

Subscribe to our newsletter to get our newest articles instantly!

World of SoftwareWorld of Software
Follow US
Copyright © All Rights Reserved. World of Software.
Welcome Back!

Sign in to your account

Lost your password?