I'm trying to write an entire basic OS in ASM, for the hell of it. Unfortunately (and this is probably a bad omen) I can't figure out how to write text to the console through the VRAM. I've looked at examples like PizziOS code and others but they're either very hard to understand or they use the BIOS method (ah = 0eh, int 10h) and I can't manage that *for some reason*.
Can someone help me out? I know most people don't get much past the bootstrap writing in ASM (in favor of C or whatever), but it would be a great help
ASM writing out
Re:ASM writing out
I have not written anything past the boot starp in assembler so don't get your hopes up. Anyway surely it would be done teh same way we do it in C. By this i mean you would stick a pointer to the Video RAM which is 0xb8000. You then right in in bytes where the first one is the ASCII character and the second is the control byte which holds the colour so somehting like 0x09 whihc gives you blue text. You then just do this in a loop for the number of characters you want to print.
Peter
Peter
Re:ASM writing out
hi
set_mode:
push bp ;ebp for 32bit
mov bp,sp
push ax
mov ax,word [bp+4] ;32bit stack [bp+8] first argument
int 10h
pop ax;
mov sp,bp
pop bp
ret
the funtion above,uses the C calling convention, you can change it to use the ASM way of using registers to pass arguments. use values for vga mode only and do not use once in protected mode as BIOS is not available. i.e
push word 0x03 ;80*25*16 colors text mode
call set_mode
or
push word 0x13 ;320*200*256 color graphics mode
call set_mode
print_string:
;this function expects ds:si (or ds:esi) to point to the address of the string to print
;es:di (or es:edi) points to the address where the string is to be displayed.
push es
push ax
mov ax,0xb800 (use 0xb8000 for protexted mode)
mov es,ax ;es now points to the base of VRam
char_out:
mov al,[si]
cmp al,0
je finished_print
mov [es:di],byte al
inc di
mov [es:di],byte 0x07 ;normal white on black attribute for mode 0x03
inc di
inc si
jmp char_out
finished_print:
pop ax
pop es
ret
to use this print function,
eg
to print 'hello there' at (3,4) (min x=0,max x=79 ==> giving 80 colums and min y=0 and max y=24 ==> giving 25 lines/rows) in mode 0x03,you can do
string db 'hello there',0
....
....
mov ax,4 ; y value
mov bx,160
mul bx ;y*160
mov bx,4 ;x value
shl bx,1 ;x*2
add ax,bx ;
mov di,ax ; di=y*160+x*2 as required by mode 0x03, read vga docs for more info
mov si,string ;string to print
call print_string
(hope this helps, I'm typing from the top of my head and haven't tested it but it looks fine to me)
set_mode:
push bp ;ebp for 32bit
mov bp,sp
push ax
mov ax,word [bp+4] ;32bit stack [bp+8] first argument
int 10h
pop ax;
mov sp,bp
pop bp
ret
the funtion above,uses the C calling convention, you can change it to use the ASM way of using registers to pass arguments. use values for vga mode only and do not use once in protected mode as BIOS is not available. i.e
push word 0x03 ;80*25*16 colors text mode
call set_mode
or
push word 0x13 ;320*200*256 color graphics mode
call set_mode
print_string:
;this function expects ds:si (or ds:esi) to point to the address of the string to print
;es:di (or es:edi) points to the address where the string is to be displayed.
push es
push ax
mov ax,0xb800 (use 0xb8000 for protexted mode)
mov es,ax ;es now points to the base of VRam
char_out:
mov al,[si]
cmp al,0
je finished_print
mov [es:di],byte al
inc di
mov [es:di],byte 0x07 ;normal white on black attribute for mode 0x03
inc di
inc si
jmp char_out
finished_print:
pop ax
pop es
ret
to use this print function,
eg
to print 'hello there' at (3,4) (min x=0,max x=79 ==> giving 80 colums and min y=0 and max y=24 ==> giving 25 lines/rows) in mode 0x03,you can do
string db 'hello there',0
....
....
mov ax,4 ; y value
mov bx,160
mul bx ;y*160
mov bx,4 ;x value
shl bx,1 ;x*2
add ax,bx ;
mov di,ax ; di=y*160+x*2 as required by mode 0x03, read vga docs for more info
mov si,string ;string to print
call print_string
(hope this helps, I'm typing from the top of my head and haven't tested it but it looks fine to me)