Search code examples
assemblyx8616-bitvga

Write graphics pixels in 16-bit assembly


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?


Solution

  • 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