-3

I am using Bochs and trying to develop a simple operating system, using Assembly and C.

I have chosen to use 1024x768 at 24bpp, but I cannot write to the majority of the screen as 0xa0000 to 0xaffff does not have enough space (only 64 KB).

I am trying to write pixels to the screen, but as I have said hardly anything gets written. I have simply done a test to see if I could write to the screen, which has failed:

image

How do I use/enable a framebuffer so that I can write to all of the screen?

Edit: sorry for being unclear, I am making a 64-bit operating system, but I want to be able to write to the entire screen. Video mode:

    mov ax,4f02h
    mov bx,118h
    int 10h
  • 6
    What specific video mode have you set? There will be documentation that tells you how to access the video memory. If you're in 16 bit mode, then it will presumably be paged; you get to map 64 KB at a time into the A0000-AFFFF window and there will be a BIOS call or hardware register to select which 64K you want. As you concluded yourself, you can't get a fully linear framebuffer in 16-bit mode. If you are in 32 bit mode, then video memory will be accessible at some completely different physical address, which the documentation should tell you how to locate. – Nate Eldredge Nov 23 '22 at 03:00
  • Here's an answer of mine: [How can I fix my VBE implementation for my OS?](https://stackoverflow.com/a/73102809/5382650) that had a similar issue. Also, have a look at the corresponding repo: https://github.com/Subwaey/KaiOS – Craig Estey Nov 23 '22 at 03:06
  • If you're using VESA / VBE, check the [spec](https://web.archive.org/web/20081211174813/http://docs.ruudkoot.nl/vbe20.txt) to read about the BIOS calls that will tell you all sorts of things, including the physical address of the linear framebuffer for use in 32-bit mode. – Nate Eldredge Nov 23 '22 at 03:06
  • The link I gave has such BIOS calls. I just reran the qemu simulation. Screen buffer at 0xFD000000 – Craig Estey Nov 23 '22 at 03:16
  • 2
    @NateEldredge: Technically you can be in [16-bit unreal mode](https://wiki.osdev.org/Unreal_Mode) (ds base=0, limit=-1 after switching back to real mode from protected). Then you can use 32-bit registers in addressing modes to access the full 4GiB of address-space. But you're in 16-bit real mode so BIOS `int 0x??` calls can still work for stuff like keyboard input, if for some reason they want to do that instead of UEFI. – Peter Cordes Nov 23 '22 at 06:04
  • 64-bit mode has a flat memory model with 64-bit pointers. All memory is linear, assuming you map contiguous virtual addresses to the physical address range of the framebuffer or whatever else you want to access. – Peter Cordes Nov 28 '22 at 17:26
  • @PeterCordes: How would one implement this "flat memory model" in 64-bit C in order to access video memory linearly? – Assembly Dev Nov 29 '22 at 00:39
  • You'd just direct-map all physical memory into contiguous virtual memory, aka a 1:1 mapping. So virtual address = physical, or physical+offset like in a high-half kernel. e.g. like Linux does: https://www.kernel.org/doc/Documentation/x86/x86_64/mm.txt . Virtual memory is automatically flat in 64-bit mode, non-zero segment bases are impossible for DS/CS/ES/SS. – Peter Cordes Nov 29 '22 at 00:47

1 Answers1

0

When the documentation says something like "The frame buffer is at 0xa0000 - 0xaffff they're referring to physical addressing, which isn't how the 8086 CPU is able to address memory. It uses a segment-offset system, which means that you need to use your segment registers ds or es to point to the upper four hex digits. It's a bit confusing, but what ends up happening is that the value in DS or ES is effectively multiplied by 16 and the value in SI or DI is added to that value, which is used to figure out the address to write to. This all happens automatically.

This example uses VGA mode 13H (320x200, 8bpp) but you'll get the idea.

mov ax,13h
int 10h     ;enter 256 color VGA mode

mov ax,0A000h
mov es,ax  ;you can't MOV a constant directly into ES so you need to use another register first.

mov di,0    ;when combined together, [es:di] aliases address 0xA0000
mov al,0Fh  ;white
stosb       ;mov [es:di],al

Hopefully that helps, I've never used a 386 CPU so all I know is the 16-bit version.

puppydrum64
  • 1,598
  • 2
  • 15
  • "I could have just written `mov [di],al` since it defaults to using **ES** anyway" That comment is incorrect! `mov [di], al` defaults to using **DS**, but you could have replaced `mov [es:di], al` by `stosb` that does use ES exclusively. – Sep Roland Nov 26 '22 at 01:46
  • `mov al,13h` `int 10h ;enter 256 color VGA mode` Better write `mov ax, 13h` so you set the required function number in AH. – Sep Roland Nov 26 '22 at 01:51
  • `mov al,0FFh ;white` Right after mode set, color register 255 contains *black*. In order to plot *white* use `mov al, 15`. – Sep Roland Nov 26 '22 at 01:54
  • My bad, it's been a while since I've done anything in DOS. – puppydrum64 Nov 28 '22 at 14:45
  • Might I point out that this appears to be referencing _bank switching_, not a linear frame buffer as I asked for. The solution that I am looking for should be using 64-bit C, but setting the linear frame buffer video mode in Assembly, before switching to long mode. – Assembly Dev Nov 29 '22 at 00:41