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.
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.
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:
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.