4

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?

LJ Germain
  • 467
  • 1
  • 6
  • 14
Moe
  • 432
  • 1
  • 6
  • 21
  • Umm, video mode 03h is a text mode, with 80 columns and 25 rows. You say you want mode 13h (and you do), but your code says 03h. – Cody Gray - on strike Jul 08 '16 at 14:15
  • I think for 16b VGA it can be safely assumed this is x86, but tag and complete info would definitely help. – Ped7g Jul 08 '16 at 14:50
  • @CodyGray i used `13h` then tried several modes, and when i copied the code to here i forgot to change the mode to the mode i mentioned in the question..i will edit the question and change it – Moe Jul 08 '16 at 14:59
  • @JoseManuelAbarcaRodríguez i tried different colors but it never prints anything – Moe Jul 08 '16 at 15:00
  • @TobySpeight its x86 yes but i forgot to mention that in the question, sorry – Moe Jul 08 '16 at 15:01
  • @Ped7g i forgot to mention that in the question – Moe Jul 08 '16 at 15:01
  • 2
    Are you sure that is your complete complete code? Tell us something about the compiler you are using. – Jose Manuel Abarca Rodríguez Jul 08 '16 at 15:03
  • @JoseManuelAbarcaRodríguez for sure its not the complete code, its a kernel so i cant post a hundreds of lines to ask about just a little bit of code, i'm using nasm and test my kernel on bochs – Moe Jul 08 '16 at 15:06
  • So can you somehow confirm the mode is changed? See the LCD info box? The resolution/vertical/horizontal freq. will be probably quite different from native mode. And 13h mode has about 60Hz refresh rate. If the mode is set, you can try to draw pixels directly into VRAM. (under DOS it is mapped to `a000:0000` for 13h mode, but I'm not sure how does this relate to your own operating system, if you have to map VGA memory first, or the BIOS will do that for you). – Ped7g Jul 08 '16 at 15:06
  • 2
    Delete most of your hundreds of lines and leave only the necessary code to display a pixel until you see it on screen. – Jose Manuel Abarca Rodríguez Jul 08 '16 at 15:11
  • 1
    Have you verified that these lines of code are actually being reached, e.g. by single-stepping using the Bochs internal debugger? (Just ruling out causes here.) – atomicinf Jul 08 '16 at 15:14
  • @JoseManuelAbarcaRodríguez cool idea, it will help me to figure out where is the wrong..thanks – Moe Jul 08 '16 at 15:15
  • @atomicinf no, but i will try doing this now – Moe Jul 08 '16 at 15:16
  • code looks fine to me, the problem i have had is that the screen 'disappears' too fast to see whats going on. i had to program in a "wait" function so that the screen will stay in graphics mode, before i switch back to textmode and before the program exits. good luck – don bright Feb 20 '23 at 04:20

2 Answers2

4

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
Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • 1
    While writing directly into VRAM is definitely the way to go for a production operating system, the OP's one is educational. I say, let her stick with int10h for the time being. – Seva Alekseyev Jul 08 '16 at 15:28
  • 1
    @SevaAlekseyev: One of the main problems I have with educational operating systems is that they tend to only teach people how do things wrong (in ways that would be inappropriate for a real OS). It makes me wonder if someone who has learnt "wrong" is better off, or worse off, than someone who hasn't learnt anything. – Brendan Jul 08 '16 at 16:07
  • i got errors in this lines `mov es:[di],ax` & `mov es:[di+2],ax` & `mov es:[di+4],al` .. it says "invalid combination of opcode and operands" – Moe Jul 08 '16 at 16:08
  • 3
    @Kordy: Different assemblers want different syntax (even if they're in the same family - e.g. "intel syntax"). For NASM and YASM, try `mov [es:di],ax`, etc (with the segment inside the brackets). – Brendan Jul 08 '16 at 16:11
  • @Kordy sorry, you didn't specify which assembler you are using, and even if you would, as I didn't try compile it myself, I would maybe do the same mistake (it's mixed up syntax of TASM and NASM) anyway. @SevaAlekseyev well, I personally don't see any serious value in using BIOS's draw pixel calls (not even educational), when you work with particular gfx mode. You already has to work with `int 10h` to set up the mode, so direct VRAM drawing is actually teaching you something new. Also I think there's some joy in doing your own graphics effects... :) Learning ASM on x86 can hardly get better. – Ped7g Jul 08 '16 at 16:18
  • @Ped7g i set the bits into 16 then sets the registers and the stack then tried the code but bochs waits so long and don't boot from the floppy drive – Moe Jul 08 '16 at 16:24
  • @Kordy You have to able to tell where it gets stuck. So either figure out some way to debug it (with stepping by instruction), or use something what works already to separate stages of execution, ie. so you can tell the OS did boot, did set up memory/interrupts/etc (I don't know what is needed in 16b x86), did run set gfx mode, etc... I think this part of [documentation](http://bochs.sourceforge.net/cgi-bin/topper.pl?name=New+Bochs+Documentation&url=http://bochs.sourceforge.net/doc/docbook/user/index.html) may help? – Ped7g Jul 08 '16 at 17:26
  • @Kordy I tried my source in dosbox, compiled as DOS .com, and it works (I added the `es:` fix and added gfx mode set up + exit code, otherwise no problem found) (I did use NASM 2.11.05 in Kubuntu 15.04 linux). So you should probably focus on the boot process and set up of your kernel/environment. Maybe your original code drawing the pixel was not even reached? Unfortunately I never did my own boot sector + kernel, so I have no idea about possible problems there. – Ped7g Jul 09 '16 at 15:01
  • @Kordy and finally, after short study of bootloaders, I edited my answer. If you still can't make it works, post your bootloader source, and how you build+run it, and what it does. And whether you were able to make some example bootloader to work. – Ped7g Jul 09 '16 at 15:31
  • This is the first chunk of assembly I've managed to copy-paste into a text file, build with nasm under dosbox and run to get some colours on my screen. Thank you! – Seb Oct 07 '16 at 20:35
3

The following code displays, a pixel, in red. Color, nr, 4 namely. You must compile it with NASM, then it works.

mov ax,13h        
int 10h             
mov ax,0A000h        
mov es,ax             
mov ax,32010          
mov di,ax             
mov dl,4             
mov [es:di],dx        
int 10h
ChrisM
  • 1,576
  • 6
  • 18
  • 29