Write graphics pixels in 16-bit assembly

Moe picture Moe · Jul 8, 2016 · Viewed 10.4k times · Source

I'm trying to develop my own very basic operating system for educational purposes. While coding the kernel, I tried to set color to some pixels on screen to make it look better, but I failed.

I used INT 10h with AH = 0CH with video mode 13h (320x200 graphics, 256 colors, 1 page) and tried several other modes like 01h and 03h but they don't work.

This is my complete code:

;set video mode
mov ah, 00h
mov al, 13h

int 10h

;write pixels on screen
mov ah, 0ch
mov bh, 0
mov dx, 5
mov cx, 5
mov al, 0100b

int 10h

What's wrong with my code?

Answer

Ped7g picture Ped7g · Jul 8, 2016

edit: Your code works in DOS (tested in dosbox on my linux machine).

So it was either not reached (problem with your boot process and code ahead of this piece), or your set-up of kernel/environment prevents int 10h BIOS interrupt to work (don't you destroy IVT by accident?). Or maybe your bootloader is already over 510B size, so the boot sector does not look as you expect?

According to this wiki about Bootloaders it looks like when you put into first sector on disk your own code (or this example), and mark it with 0xAA55 at end of sector, it should work (and it will probably crash after pressing key at the end).

You may also want to try their example of bootloader (writing hello world).


To test direct write into VRAM you can use a code like this (works in dosbox on my linux machine, so if your OS sets up similar 16b environment and allows BIOS interrupts):

palette.asm:

; to compile DOS COM file: nasm -o palette.com palette.asm
; to run it with dosbox: dosbox palette.com -exit
    BITS    16
    ORG     100h
start:
    mov ax,13h
    int 10h
  ; draw palette in 32x8 squares, each square 5x5 pixels big (so 160x40px)
    push 0a000h
    pop es
    xor di,di
    xor ax,ax  ; color
    mov cx,8   ; big rows (each having 32 5x5 squares)
bigRowLoop:
    mov bx,5 ; pixel height of single row
rowLoop:
    mov dx,32 ; squares per row
    push ax
    push di
squareLoop:
    ; draw 5 pixels with "ah:al" color, ++color, di += 5
    mov [es:di],ax
    mov [es:di+2],ax
    mov [es:di+4],al
    add ax,0101h
    add di,5
    dec dx
    jnz squareLoop
    pop di
    pop ax     ; restore color for first square
    add di,320 ; move di to start of next line
    dec bx     ; do next single pixel line
    jnz rowLoop
    ; one row of color squares is drawn, now next 32 colors
    add ax,02020h ; color += 32
    dec cx
    jnz bigRowLoop
  ; wait for any key and exit
    xor ah,ah
    int 16h
    ret