Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Screen appears to "loop around" when resolution goes above 1024x768 on Alpine Linux #1088

Open
HunterBoy344 opened this issue Jul 21, 2024 · 7 comments
Labels

Comments

@HunterBoy344
Copy link

HunterBoy344 commented Jul 21, 2024

Browser: Chromium version 126.0.6478.182
VM memory: 256MB
VM video memory: 128MB

Screenshot 1 (before resolution change, login screen, 1024x768):
image

Screenshot 2 (after resolution change, desktop, 1280x960):
image

The start button is supposed to be on the far left, and the sliver of my mouse you can see is where the right edge of the screen is supposed to be. Everything appears to be offset, and moving my mouse off the left edge of the screen causes it to loop over to the right.

I can avoid this issue by not raising the video memory of the VM above 8MB, preventing it from resizing above 1024x768. However, I want a higher resolution than that, and I also want more video memory, so this is a bit of a problem. This bug doesn't seem to happen when I use my disk image on QEMU, nor does it happen when changing resolutions in the official Windows 2000 VM on V86.

Disk image is here. It's 3GB and it contains a copy of Alpine Linux with linux-virt and the Xfce desktop environment. Default password is alp1neNSO.

@copy copy added the bug label Jul 22, 2024
@ProgrammerIn-wonderland
Copy link
Contributor

How do other kernels treat the display? Like linux-lts in the place of Linux virt?

@chschnell
Copy link
Contributor

chschnell commented Sep 4, 2024

I've taken a log of V86's VGA debug messages when booting this image.

The switch from 1024x768 -> 1280x960 begins at timestamp 11:40:35, I've inserted 3 lines breaks in the log. I think this stands out:

11:40:36.158 11:40:36+158 [VGA ] 1CF / dispi write 0x6: 0x500
11:40:36.158 11:40:36+158 [VGA ] Unimplemented dispi write index: 0x6
11:40:36.158 11:40:36+158 [VGA ] SVGA: enabled=false, 1280x960x32
11:40:36.158 11:40:36+158 [VGA ] 1CF / dispi write 0x7: 0x6666
11:40:36.158 11:40:36+158 [VGA ] Unimplemented dispi write index: 0x7
11:40:36.158 11:40:36+158 [VGA ] SVGA: enabled=false, 1280x960x32
11:40:36.158 11:40:36+158 [VGA ] 1CF / dispi write 0x8: 0x0
11:40:36.158 11:40:36+158 [VGA ] Unimplemented dispi write index: 0x8
11:40:36.158 11:40:36+158 [VGA ] SVGA: enabled=false, 1280x960x32
11:40:36.158 11:40:36+158 [VGA ] 1CF / dispi write 0x9: 0x0
11:40:36.158 11:40:36+158 [VGA ] SVGA offset: 0x0 y=0x0
11:40:36.158 11:40:36+158 [VGA ] complete redraw

For context, 0x1CF is Bochs' VBE port as documented in the OSDev Wiki. The log states that three functions (0x6 - 0x8) are not implemented in V86, their meaning:

  • 0x1CF:0x6 - VBE_DISPI_INDEX_VIRT_WIDTH
  • 0x1CF:0x7 - VBE_DISPI_INDEX_VIRT_HEIGHT
  • 0x1CF:0x8 - VBE_DISPI_INDEX_X_OFFSET

Note that the Y-offset 0x1CF:0x9 (VBE_DISPI_INDEX_Y_OFFSET) is already implemented in V86.

Even though an attempt to write "0" to 0x1CF:0x08 fails at this particular log entry, later down we find this:

11:40:36.167 11:40:36+167 [VGA ] 1CF / dispi write 0x8: 0x400
11:40:36.167 11:40:36+167 [VGA ] Unimplemented dispi write index: 0x8

So later an attempt is made to write 0x400 (dec. 1024) into 0x1CF:0x08 which looks promising.

My guess would be that including support for 0x1CF:0x08 (VBE_DISPI_INDEX_X_OFFSET) could fix this. Not sure about virtual width and height (0x6 and 0x7) though.

EDIT: That indeed fixed it:
alpine-1280x960

chschnell added a commit to chschnell/v86-graphical-text that referenced this issue Sep 4, 2024
Adds support for horizontal offset in Bochs VESA BIOS Extension.

Should fix issue copy#1088.
@SuperMaxusa
Copy link
Contributor

I tested changing resolution on Windows 2000 (with VBE NT driver) and it doesn't use virtual width/height:

[VGA ] planar mode: 0x10
[VGA ] 3CC read 
[VGA ] 1CF / dispi write 0x4: 0x0 <- VBE_DISPI_INDEX_ENABLE
[VGA ] SVGA: enabled=false, 1024x768x32 
[VGA ] 1CF / dispi write 0x3: 0x20 <- VBE_DISPI_INDEX_BPP
[VGA ] SVGA: enabled=false, 1024x768x32 
[VGA ] 1CF / dispi write 0x1: 0x640 <- VBE_DISPI_INDEX_XRES
[VGA ] SVGA: enabled=false, 1600x768x32 
[VGA ] 1CF / dispi write 0x2: 0x384 <- VBE_DISPI_INDEX_YRES
[VGA ] SVGA: enabled=false, 1600x900x32 
[VGA ] 1CF / dispi write 0x5: 0x0 <- VBE_DISPI_INDEX_BANK
[VGA ] SVGA bank offset: 0x0 
[VGA ] SVGA: enabled=false, 1600x900x32 
[VGA ] 1CF / dispi write 0x4: 0x41 <- VBE_DISPI_INDEX_ENABLE
[VGA ] SVGA: enabled=true, 1600x900x32 
[VGA ] 3D4 / crtc index: 17 

@chschnell
Copy link
Contributor

I tested changing resolution on Windows 2000 (with VBE NT driver) and it doesn't use virtual width/height:

As always, thanks a lot!

Seeing that I cannot find any bug reports from the past it looks to me that virtual width and height are not being used in the wild (that's assuming that it would completely trash the screen), though I do not believe that myself.

Maybe others, who've been around here longer than I, can chip in.

@SuperMaxusa
Copy link
Contributor

SuperMaxusa commented Sep 4, 2024

You're welcome, thank you too!

it looks to me that virtual width and height are not being used in the wild

Probably (in Linux vesafb) this virtual display is changed itself as main display when you need to switch between VESA videomodes. Modern Linux distros enables framebuffer on boot. I guess if Alpine Linux were booted with vgacon and gdm (login screen) was set to 1600x900, the screen wouldn't loop.

How do other kernels treat the display? Like linux-lts in the place of Linux virt?

IIRC Alpine Linux Standard and Virtual use same module for framebuffer.

@chschnell
Copy link
Contributor

During boot, my 32-bit Debian 12 image does what seems to be the norm (I googled around a bit today but couldn't find much substantial): It sets the virtual width to the same value as the real width, and the virtual height to fill all of the available video RAM.

The real screen size is 1024x768x4 (32bpp), with 8M video RAM the virtual size is 1024x2048x4 and with 16M it's 1024x4096x4 (I spare you the logs).

vga.js already supports virtual width and height (see members screen_width/screen_height vs. virtual_width/virtual_height), I have yet to look into that but shouldn't it be possible to reuse these mechanics in order to add full support for the Bochs-specific registers VBE_DISPI_INDEX_VIRT_WIDTH and VBE_DISPI_INDEX_VIRT_HEIGHT?

By "Bochs-specific" I mean to say that port 0x1CF exists only in Bochs VGA Bios, this is not the common VESA interface, the application (or OS) needs to know specifically about Bochs when making use of it (like Debian or Alpine obviously do).

From what I know, virtual screens are in general used for panning, scrolling and double-buffering, so unless it turns out that nobody uses the Bochs-specific registers to do that, I think proper support for it should be added. Bochs is 30 years old, and according to the API history, virtual width and height were added in 2002, so it's been around for a while.

@SuperMaxusa
Copy link
Contributor

By "Bochs-specific" I mean to say that port 0x1CF exists only in Bochs VGA Bios, this is not the common VESA interface, the application (or OS) needs to know specifically about Bochs when making use of it (like Debian or Alpine obviously do).

SerenityOS sources said that Bochs VGA doesn't support MMIO registers, so you need communicate via default IO-ports (QEMU stdvga has it: https://www.qemu.org/docs/master/specs/standard-vga.html#mmio-area-spec).

copy pushed a commit that referenced this issue Sep 8, 2024
Adds support for horizontal offset in Bochs VESA BIOS Extension.

Should fix issue #1088.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants