Hacker News new | ask | show | jobs
by rep_lodsb 618 days ago
non-JS URL: https://content.deadbeef.io/pages/a_cpp_developer_learns_ass...

Sadly it doesn't work on my system: the display is drawn at the start (sometimes partially), and then only ever updates when switching between virtual consoles.

Tried adding O_SYNC to the open flags for the framebuffer, and it didn't help. It's writing to the device 60 times per second, just won't show for some reason.

1 comments

Interesting, I’ve only tried it on two machines - my (fairly old) laptop with integrated graphics and my desktop with an RTX4060. I’ve also tried it on the desktop on Windows in a Linux VM running Ubuntu 24.04. It runs way smoother on the laptop.

Thanks for trying it :)

BTW, is there a problem with the JavaScript on my website?

Now I've at least got it working on an old laptop with 1366x768 resolution :)

Well, not immediately. At first there was an entirely different problem: everything on the screen was garbled!

However it was easy to figure out why and fix it: depending on the hardware and resolution, lines in the framebuffer can have extra padding beyond what's needed for the visible pixels. That information is available in another info structure:

              ; Get size of line in framebuffer
              mov eax, 16                   ; sys_ioctl
              mov edi, [drw_fbfd]
              mov esi, 0x4602               ; FBIOGET_FSCREENINFO
              mov rdx, rsp
              syscall
              mov eax, [rsp+0x30]           ; bytes per line
              shr eax, 2                    ; convert to pixels
              mov [drw_fb_pitch], eax
There are only a few places in draw.asm that then need to be changed to multiply by this new variable instead of drw_fb_w.
Hi, thanks for the update. I’ll make this change when I get a chance. Thanks
I've now also figured out a solution to my first problem, though still not much of an idea of what really causes it. In drw_flush, after writing out the screen buffer, do this:

              push 0                        ; put X,Y offsets on stack
              sub rsp, 16                   ; 4 more dwords (don't care)
              mov eax, 16                   ; sys_ioctl
              mov edi, [drw_fbfd]
              mov esi, 0x4606               ; FBIOPAN_DISPLAY
              mov rdx, rsp                  ; ptr to structure on stack
              syscall
              add rsp, 24                   ; drop it
              ret
From what little documentation there is, this IOCTL takes a fb_var_screeninfo structure, but only pays attention to the x/y offset fields (so allocating 24 bytes for it should be enough). With the offsets set to zero, it now works perfectly on my machine.
Thanks, I've made a new branch called display_fixes. Let me know if it works
I might try it out on other machines or without running X at the same time. Maybe some conflict with the framebuffer console + X?

>BTW, is there a problem with the JavaScript on my website?

I just block all JavaScript by default, and strongly believe that websites should remain usable that way.

In case you're still reading this, I tried a more mature program using the framebuffer (fbi image viewer), and it had exactly the same problem! I now suspect it has something to do with the Intel graphics driver (i915), either a bug or more likely some undocumented interaction with the console.

It's really too bad how the Linux kernel provides these APIs, but barely any documentation, and the only way you're supposed to interact with them is through some specially "blessed" abstraction layer running in userspace (X11/Wayland/SDL, pulseaudio, etc.) which inevitably demands linking in C libraries.