I am writing an OS on fasm assembly, R-OS, and I want to know, how to use video memory without bios. current OSs as Windows or MacOS making me create video system in kernel, and I dunt know how. Help plz.
boot.asm:
org 0x7C00
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0,7C00
cld
mov ax, 0x03
int 0x10
mov si, boot_msg
call printf
mov al, 0x04
mov bx, 0x7E00
mov cx, 0x0002
mov dh, 0x00
call disk_read
mov ax, 0x7E0
mov ds, ax
mov es, ax
mov sp, 0x7E00
jmp 0x7E0:0x0000
include 'disk.asm'
include 'printh.asm'
times 510-$ $$ db 0x00
dw 0xAA55
include 'kernel.asm'
times 65536-512-$ $$ db 0x00
kernel.asm:
org 0x7E00
mov ax, 0x4F02
mov bx, 0x101
int 0x10
mov ah, 0x0C
mov al, 0x0F
mov cx, 0x10
mov dx, 0x10
int 0x10
msg0 db 'R-OS', 0x00
raf dd 0
wax dw 0
wah db 0
wal db 0
buff db 1024 dup (?)
jmp end2048
end2048:
cli
hlt
jmp $-2
times 2048-$ $$ db 0x00
disk.asm have just kernel load func and printh.asm just printf and printh funcs
CodePudding user response:
Not every BIOS will work for an extended video mode like 101h! The BIOS.WritePixel function 0Ch normally only operates on the LEGACY video modes. Those are the video modes whose number ranges from 0 to 19.
The video mode 101h is a 640x480 256-color VESA defined video mode. Writing pixels on the screen without using BIOS will require learning a lot about VESA, linear frame buffers, bank switching, etc.
You are in the process of creating an OS. And you are at the very start of it. I think you should keep it as simple as possible in this stage, and select a legacy video mode that is easy to work with: the 320x200 256-color video mode.
An operating system is so much more than its screen, so invest most of your time in the other stuff and leave the niceties of the output screen for last. You'll thank me for it later. Many people before have lost themselves writing beautiful splashscreens and special effects, but failing to even provide an elementary input line (prompt).
This is an example of how you put a single pixel on the 320x200 256-color screen directly. The address for the pixel is calculated from
AddressInVideoBuffer = (Y * BytesPerScanline) X
mov ax, 0013h ; BIOS.SetVideoMode 320x200x8
int 10h
...
; Puts a green dot in the middle of the screen
mov cl, 2 ; Color = Green
mov bx, 100 ; Y
mov ax, 160 ; X
call PutPixel
...
; IN (ax,bx,cl) OUT () MOD (ax)
PutPixel:
push ds bx ; Preserve registers, allow AX to get clobbered
imul bx, 320 ; Y * BytesPerScanline
add bx, ax ; X
mov ax, 0xA000 ; VideoBuffer
mov ds, ax
mov [bx], cl ; Write the color from CL
pop bx ds ; Restore registers
ret
Here's another code that uses nested loops to fill a rectangular area of the screen with some color:
; IN (ax,bx,cl,si,di)
; AX is UpperLeftX, BX is UpperLeftY, CL is Color, SI is Width, DI is Height
PaintRectangle:
push ds bx di ; Preserve registers, allow AX to get clobbered
imul bx, 320 ; UpperLeftY * BytesPerScanline
add bx, ax ; UpperLeftX
mov ax, 0xA000 ; VideoBuffer
mov ds, ax
.OuterLoop:
push si ; (1)
.InnerLoop:
dec si
mov [bx si], cl ; Write the color from CL
jnz .InnerLoop
pop si ; (1)
add bx, 320 ; Move to next scanline (line below)
dec di ; Decrement Height
jnz .OuterLoop
pop di bx ds ; Restore registers
ret