FrankRay78 / PatienceOS

A baremetal C# kernel.
https://frankray.net/blog/category/software-development/os-development/patienceos/
MIT License
21 stars 4 forks source link

Switch between VGA text modes (Real mode, INT10) #11

Closed FrankRay78 closed 2 months ago

FrankRay78 commented 3 months ago

See PC common text modes on VGA text mode

This issue covers the ability to change the VGA text mode (aka 'mode setting) through a BIOS interrupt 10 call.

The processor state is required to be in 'real mode', otherwise interrupts are disabled.


Please upvote :+1: this issue if you are interested in it.

FrankRay78 commented 3 months ago

VGA mode setting

(BIOS, real mode, INT10)

INT 10h is shorthand for BIOS interrupt call 10hex, the 17th interrupt vector in an x86-based computer system. The BIOS typically sets up a real mode interrupt handler at this vector that provides video services. Set video mode | AH=00h | AL = video mode modes 1, modes 2

https://en.wikipedia.org/wiki/INT_10H

Mode 13h is the standard 256-color mode on VGA graphics hardware introduced in 1987 Mode 13h provides programmers with a linear 320x200 block of video memory

https://en.wikipedia.org/wiki/Mode_13h

Can someone please send me a working code for setting up VGA mode 13?

    mov ax,0x0013
    int 0x10

It assumes that the OS is designed properly and therefore sets a video mode in real mode during boot It assumes that the computer was booted using BIOS (and not UEFI)

And also

[The first two problems] can be mitigated a little by using "int 0x10, ax = 0x1A00" to check that a video card that emulates VGA at the video ROM level exists.

https://forum.osdev.org/viewtopic.php?p=280800#p280800


I used this code in my very old project to change from 80x25 to 80x50,

; set 80x50 text mode
   mov   ax,1112h   
            ; AH=11h TEXT-MODE CHARACTER GENERATOR FUNCTIONS
            ; AL=12h load ROM 8x8 double-dot pattern (PS,EGA,VGA)
   xor   bl,bl      ; block to load
   int   10h

https://forum.osdev.org/viewtopic.php?p=334528#p334528

(nb. Frank's comment - I'm not sure the above code snippet is actually changing the video text mode. I would expect AH=00h to be included somewhere, along with AL specifying which text mode to switch to)


I've been using text mode 3, 80x25, via int 10, ax=0003. I'd like to get more characters on a page than that

Here's how I do it

;set VGA 400 lines
        mov ax,1202h
        mov bl,30h
        int 10h
;set VGA 80x25 colour
        mov ax,3
        int 10h
;set 8x8 font
        mov ax,1112h
        sub bl,bl
        int 10h

https://board.flatassembler.net/topic.php?t=14300

FrankRay78 commented 3 months ago

An extensive listing of all the various INT10, video function calls:

image

https://www.ctyme.com/intr/int-10.htm

FrankRay78 commented 3 months ago

Assembly method to print a string to the console using Int 10: https://github.com/cfenollosa/os-tutorial/blob/ce8e050d246594fda7f0067d7f4c9abeaa2b269c/15-video-ports/boot/print.asm

print:
    pusha

; keep this in mind:
; while (string[i] != 0) { print string[i]; i++ }

; the comparison for string end (null byte)
start:
    mov al, [bx] ; 'bx' is the base address for the string
    cmp al, 0 
    je done

    ; the part where we print with the BIOS help
    mov ah, 0x0e
    int 0x10 ; 'al' already contains the char

    ; increment pointer and do next loop
    add bx, 1
    jmp start

done:
    popa
    ret
FrankRay78 commented 2 months ago

TLDR: The PatienceOS kernel is booting in 32-bit protected mode, by default. Interrupts are disabled.

The following code, when added into loader.asm has no effect:

        mov ah, 0x00    ; Video function: Set Video Mode
        mov al, 0x00    ; Video mode: 00h (T40x25)
        int 0x10        ; Call BIOS video interrupt

After hours of trying to work out why, I noticed the following comment on the OS Dev: Bare Bones tutorial:

_start:
    /*
    The bootloader has loaded us into 32-bit protected mode on a x86
    machine. Interrupts are disabled. */

I believe this explains why I can't seem to make a call via int 10 within _start:


Next steps: Pursue mode setting by direct writes to the VGA registers via IO Ports, see issue #15.

FrankRay78 commented 2 months ago

The following works nicely, I've tested it:

mov ax, 0x0003 ; VGA text mode, 720x400 pixels, 9x16 font, 80x25 characters
int 0x10
mov ax, 0x1112 ; replace 9x16 font with 9x8 font, so now it's 80x50 characters
mov bl, 0x00
int 0x10