I want to make an OS (64 bit). I made a compiler in it, input, output, I just need to have a 24 bit graphics mode to make a GUI. I tried to display all of the colors but I just get this mess:
the code which ran it: (just in a test 16 bit environment)
[org 0x7c00]
mov ax,4f02h
mov bx,103h
int 10h
mov ax, 0a000h
mov es, ax
mov al, 0
mov edi, 0
mov eax, 0
sl:
stosw
inc edi
inc eax
jmp sl
times 510-($-$$) db 0
dw 0AA55h
And I need to make it interrupt free because of the cli instruction when switching to 64 bit mode. I hope that I can make it to be compatible with any resolution but I need to output a pixel for now. I hope someone knows how to do it, because I didn't find anything is this topic.
I tried to switch the mov bx, 103h to other things, but it just made it worse. And I can't even run it in 64 bit mode because of the mov es, ax.
First I strongly recommend to read this:
The idea behind pixel rendering is to compute address where pixel lies in VRAM and copy the color or index at that address (using segment where the VRAM is located usually
A000h
for video andB800h
for text modes).However normally we can access only single segment of VRAM so wee need also to select which one it is (page) so:
now you switch in page (if not already) and copy the pixel color (
1/2/4
bytes) at that address for example by usingstosb/w/d
. Now I am not sure if pixel can be at 2 pages at once (the code bellow does not handle that) so if true you should handle that too (however as x resolution for standard video modes is always multiple of 4 I do not think its possible).Looks like you really a rookie so here is small simple (ugly and slooooow) example (MS-DOS com executable using VESA BIOS in NASM) of rendering pixels in 800x600x32bit mode 115h... just inspect the function
pixel
, it expects 800x600x32bit video mode andax,bx
as x,y andecx
as 32bit color:Firs main source file:
and the helper
vesa.lib
:note that I did not code in asm in ages and have no mod to tweak this in DOS-BOX too much so its ugly and non optimized.
This renders blue diagonal line using function
pixel
which means the layout of color is:there are many pusha/popa and I am using slow computation using
mul
to improve performance you should have array where you store the starting address and page of each scan line precomputed once (after changing video mode) and then just access it usingy
. Also the actualpage
variable could be moved directly intovesapag
function but I was not in the mood to edit 2 files as I am really rusty in MS-DOS and asm now and DOS BOX is conflicting key shortcuts with my editors not to mention VC editors stopped working for god knows what reason (took me a lot more time to workaround that than code the example itself)...Also if you want to use 32/64 bit code you will have to use some kind of extender to have access to VESA BIOS (or any BIOS) functions or their replacement. Have never done such thing but people used DOS4GW for this back in the day...
Also in 32/64 bit mode you can use LFB (linear frame buffer) and forget about page switching completely (improving speed a lot more).
If you want to have this working for any resolution then you should change the hardcoded
800
to real resolution you use. It can be obtained from VESA BIOS (along with starting segment) just disect this:It obtains all available VESA video modes along with information about them and once you chose one from the list it renders a control image so you see the difference between 8/15/16/32 bit modes...