Initial LVGL modifications

Basic LVGL wrapper with an example desktop & windowing system.
This commit is contained in:
2026-02-27 16:30:31 +00:00
parent ceb03a9d7e
commit 989e36ffe2
17 changed files with 3380 additions and 95 deletions
+4
View File
@@ -11,3 +11,7 @@
/*.img
src/include/asuro.pas
localenv.json
/lvgl/
dockerout.txt
AGENTS.md
*.log
+1 -1
View File
@@ -5,7 +5,7 @@ VOLUME ["/code"]
ENV DEBIAN_FRONTEND=noninteractive
RUN dpkg --add-architecture i386
RUN apt-get update && apt-get install -y \
curl dos2unix wget git make nasm binutils:i386 xorriso grub-pc-bin && \
curl dos2unix wget git make nasm binutils xorriso grub-pc-bin gcc gcc-multilib && \
apt-get clean my room
SHELL ["/bin/bash", "-c"]
+2 -1
View File
@@ -7,7 +7,7 @@ echo "Asuro Compilation"
echo " "
#Compile Stub.asm
rm lib/*
rm -f lib/*
runOrFail() {
local binary=$1
@@ -23,6 +23,7 @@ runOrFail() {
declare -a run_steps=(
"compile_stub.sh" "Failed to compile stub!"
"compile_vergen.sh" "Versions failed to compile"
"compile_lvgl.sh" "Failed to compile LVGL!"
"compile_sources.sh" "Failed to compile FPC Sources!"
"compile_link.sh" "Failed linking!"
"compile_isogen.sh" "Failed to create ISO!"
+6 -1
View File
@@ -14,4 +14,9 @@ done;
objstring=lib/stub.o" "$objstring
echo "Object Files: "$objstring
echo " "
ld -m elf_i386 -s --gc-sections -Tlinker.script -o bin/kernel.bin $objstring
# Find libgcc for i386 (needed by LVGL compiled with gcc)
LIBGCC=$(gcc -m32 -print-libgcc-file-name)
echo "libgcc: ${LIBGCC}"
ld -m elf_i386 -s --gc-sections -Tlinker.script -o bin/kernel.bin $objstring --start-group lib/liblvgl.a ${LIBGCC} --end-group
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/env bash
# compile_lvgl.sh — Download LVGL v9.2 source and compile into lib/liblvgl.a
# Clone & compile in /tmp (fast container-local fs).
# Copy source + objects to /lvgl (host mount) for debugging.
set -e
LVGL_VERSION="v9.2.2"
LVGL_REPO="https://github.com/lvgl/lvgl.git"
LVGL_DIR="/tmp/lvgl"
OBJ_DIR="/tmp/lvgl_obj"
CONF_DIR="$(pwd)"
OUT_DIR="$(pwd)/lib"
CC="gcc"
CFLAGS="-m32 -march=i686 -ffreestanding \
-fno-builtin -fno-stack-protector -fno-pic -fno-pie \
-O2 -Wall -Wno-unused-function -Wno-unused-variable \
-I${CONF_DIR} \
-I${LVGL_DIR} \
-I${LVGL_DIR}/.. \
-DLV_CONF_INCLUDE_SIMPLE"
echo " "
echo "======================="
echo " "
echo "Compiling LVGL..."
echo " "
# Clone LVGL into /tmp (container-local)
rm -rf "$LVGL_DIR"
echo "Downloading LVGL ${LVGL_VERSION}..."
git clone --depth 1 --branch "${LVGL_VERSION}" "${LVGL_REPO}" "${LVGL_DIR}" 2>&1
echo "Download complete."
# Gather all LVGL .c source files (core library only, no demos/examples)
SOURCES=$(find "${LVGL_DIR}/src" -name '*.c' -not -path '*/test/*')
TOTAL=$(echo "$SOURCES" | wc -l)
echo "Found ${TOTAL} LVGL source files."
# Compile each .c file to .o (container-local)
rm -rf "$OBJ_DIR"
mkdir -p "$OBJ_DIR"
COUNT=0
ERRORS=0
for src in $SOURCES; do
COUNT=$((COUNT + 1))
rel="${src#${LVGL_DIR}/src/}"
obj_path="${OBJ_DIR}/${rel%.c}.o"
mkdir -p "$(dirname "$obj_path")"
if ! $CC $CFLAGS -c "$src" -o "$obj_path" 2>&1; then
echo "FAILED: $rel"
ERRORS=$((ERRORS + 1))
fi
if [ $((COUNT % 50)) -eq 0 ]; then
echo " Compiled ${COUNT}/${TOTAL}..."
fi
done
echo "Compiled ${COUNT} files (${ERRORS} errors)."
if [ "$ERRORS" -ne 0 ]; then
echo "LVGL compilation FAILED with ${ERRORS} errors."
exit 1
fi
# Archive into static library
OBJECTS=$(find "$OBJ_DIR" -name '*.o')
ar rcs "${OUT_DIR}/liblvgl.a" $OBJECTS
echo "Created ${OUT_DIR}/liblvgl.a"
# Copy source + objects to /lvgl host mount for debugging
echo "Copying LVGL source and objects to host mount..."
rm -rf /lvgl/* /lvgl/.[!.]* /lvgl/..?* 2>/dev/null || true
cp -a "$LVGL_DIR/src" /lvgl/src
cp -a "$OBJ_DIR" /lvgl/obj
echo "Done."
echo " "
echo "LVGL compilation complete."
echo " "
+2 -1
View File
@@ -2,4 +2,5 @@ services:
builder:
build: .
volumes:
- .:/code
- .:/code
- ./lvgl:/lvgl
+374
View File
File diff suppressed because it is too large Load Diff
+62 -3
View File
@@ -51,6 +51,11 @@ type
procedure init();
procedure DrawCursor;
function getMouseX: sint32;
function getMouseY: sint32;
function getMouseLMB: boolean;
function getMouseRMB: boolean;
function getMouseScroll: sint32; { returns accumulated scroll delta since last call }
implementation
@@ -59,7 +64,7 @@ var
FirstDraw : boolean = true;
BackPixels : Array[0..1] of Array[0..7] of uint64;
Cycle : uint32 = 0;
Mouse_Byte : Array[0..2] of uint8;
Mouse_Byte : Array[0..3] of uint8;
Packet : uint32;
Registered : Boolean = false;
NeedsRedraw : Boolean = false;
@@ -67,6 +72,35 @@ var
LMouseDownPos : TMousePos;
LMouseDown : Boolean;
RMouseDown : Boolean;
HasScrollWheel : Boolean = false;
ScrollAccum : sint32 = 0;
PacketSize : uint32 = 3;
function getMouseX: sint32;
begin
getMouseX := Current.x;
end;
function getMouseY: sint32;
begin
getMouseY := Current.y;
end;
function getMouseLMB: boolean;
begin
getMouseLMB := LMouseDown;
end;
function getMouseRMB: boolean;
begin
getMouseRMB := RMouseDown;
end;
function getMouseScroll: sint32;
begin
getMouseScroll := ScrollAccum;
ScrollAccum := 0;
end;
procedure DrawCursor;
var
@@ -151,7 +185,7 @@ begin
Mouse_Byte[Cycle]:= b;
Inc(Cycle);
end;
if Cycle = 3 then begin
if Cycle = PacketSize then begin
//Process
f:= Mouse_Byte[0];
Packet.x_sign:= (f AND %00010000) = %00010000;
@@ -173,6 +207,10 @@ begin
if Current.x > (Console.getConsoleProperties^.Width-8) then Current.x:= (Console.getConsoleProperties^.Width-8);
if Current.y > (Console.getConsoleProperties^.Height-8) then Current.y:= (Console.getConsoleProperties^.Height-8);
end;
{ Process scroll wheel (4th byte, signed) }
if HasScrollWheel then begin
ScrollAccum := ScrollAccum + sint8(Mouse_Byte[3]);
end;
Cycle:= 0;
if Packet.LMB_Down then begin
if not LMouseDown then begin
@@ -217,7 +255,8 @@ end;
function load(ptr : void) : boolean;
var
status : uint8;
status : uint8;
devid_byte : uint8;
begin
push_trace('mouse.load');
mouse_wait(1);
@@ -232,6 +271,26 @@ begin
outb($60, status);
mouse_write($F6);
mouse_read();
{ Enable IntelliMouse scroll wheel: set sample rate 200, 100, 80 }
mouse_write($F3); mouse_read(); mouse_write(200); mouse_read();
mouse_write($F3); mouse_read(); mouse_write(100); mouse_read();
mouse_write($F3); mouse_read(); mouse_write(80); mouse_read();
{ Query device ID — ID 3 = IntelliMouse (scroll wheel) }
mouse_write($F2);
mouse_read(); { ACK }
devid_byte := mouse_read(); { Device ID }
if devid_byte = 3 then begin
HasScrollWheel := true;
PacketSize := 4;
console.outputln('PS/2 MOUSE', 'Scroll wheel enabled (IntelliMouse).');
end else begin
HasScrollWheel := false;
PacketSize := 3;
console.outputln('PS/2 MOUSE', 'Standard mouse (no scroll wheel).');
end;
mouse_write($F4);
mouse_read();
isrmanager.registerISR(44, @Main);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+12
View File
@@ -40,6 +40,8 @@ function frontBufferBpp : uint8;
function backBufferWidth : uint32;
function backBufferHeight : uint32;
function backBufferBpp : uint8;
function backBufferLocation : uint32;
function frontBufferLocation : uint32;
Procedure basicFDrawTexture(Buffer : PVideoBuffer; X : uint32; Y : uint32; Texture : PTexture);
@@ -315,4 +317,14 @@ begin
backBufferBpp:= VideoInterface.BackBuffer.BitsPerPixel;
end;
function backBufferLocation : uint32;
begin
backBufferLocation:= VideoInterface.BackBuffer.Location;
end;
function frontBufferLocation : uint32;
begin
frontBufferLocation:= VideoInterface.FrontBuffer.Location;
end;
end.
File diff suppressed because it is too large Load Diff
+26 -1
View File
@@ -300,8 +300,33 @@ begin
end;
function intToString(i : uint32) : pchar;
var
buf : array[0..11] of char;
len : uint32;
tmp : uint32;
result : pchar;
j : uint32;
begin
intToString:= ' ';
if i = 0 then begin
result := stringNew(1);
result[0] := '0';
result[1] := #0;
intToString := result;
exit;
end;
len := 0;
tmp := i;
while tmp > 0 do begin
buf[len] := char(byte('0') + (tmp mod 10));
tmp := tmp div 10;
inc(len);
end;
result := stringNew(len);
for j := 0 to len - 1 do begin
result[j] := buf[len - 1 - j];
end;
result[len] := #0;
intToString := result;
end;
function boolToString(b : boolean; ext : boolean) : pchar;
+107
View File
@@ -266,6 +266,8 @@ procedure fpc_shortstr_assign(len: longint; sstr, dstr: Pointer); compilerproc;
any int64/uint64 arithmetic occurs (e.g. sint32 * uint32 promotion).
Must live in the system unit so the compiler can resolve it. }
function fpc_mul_int64(f1, f2: int64): int64; compilerproc;
function fpc_div_int64(n, d: int64): int64; compilerproc;
function fpc_mod_int64(n, d: int64): int64; compilerproc;
{ Memory allocation compilerprocs delegate to kernel heap (lmemorymanager) }
function fpc_getmem(size: PtrUInt): Pointer; compilerproc;
@@ -454,6 +456,111 @@ begin
fpc_mul_int64 := res;
end;
{ ---------- 64-bit division / modulo ---------- }
{ Helper: unsigned 64÷64→64 using shift-subtract (binary long division).
Called by both signed div and mod after sign handling. }
procedure udiv64(dividendLo, dividendHi, divisorLo, divisorHi: uint32;
var quotLo, quotHi, remLo, remHi: uint32);
var
bit: longint;
begin
quotLo := 0; quotHi := 0;
remLo := 0; remHi := 0;
for bit := 63 downto 0 do begin
{ rem := rem shl 1 }
remHi := (remHi shl 1) or (remLo shr 31);
remLo := remLo shl 1;
{ bring down next bit of dividend }
if bit >= 32 then begin
remLo := remLo or ((dividendHi shr (bit - 32)) and 1);
end else begin
remLo := remLo or ((dividendLo shr bit) and 1);
end;
{ if rem >= divisor then rem -= divisor; set quotient bit }
if (remHi > divisorHi) or
((remHi = divisorHi) and (remLo >= divisorLo)) then begin
{ rem -= divisor (64-bit subtract) }
if remLo < divisorLo then begin
remHi := remHi - divisorHi - 1;
remLo := remLo - divisorLo;
end else begin
remHi := remHi - divisorHi;
remLo := remLo - divisorLo;
end;
{ set quotient bit }
if bit >= 32 then
quotHi := quotHi or (uint32(1) shl (bit - 32))
else
quotLo := quotLo or (uint32(1) shl bit);
end;
end;
end;
function fpc_div_int64(n, d: int64): int64; [public, alias: 'FPC_DIV_INT64']; compilerproc;
var
negate: boolean;
nLo, nHi, dLo, dHi: uint32;
qLo, qHi, rLo, rHi: uint32;
begin
if d = 0 then begin
HandleErrorInternal(200); { divide by zero }
fpc_div_int64 := 0;
exit;
end;
negate := false;
{ Make both operands positive, track sign }
if n < 0 then begin
n := -n;
negate := not negate;
end;
if d < 0 then begin
d := -d;
negate := not negate;
end;
nLo := uint32(n); nHi := uint32(n shr 32);
dLo := uint32(d); dHi := uint32(d shr 32);
udiv64(nLo, nHi, dLo, dHi, qLo, qHi, rLo, rHi);
fpc_div_int64 := int64(qLo) or (int64(qHi) shl 32);
if negate then
fpc_div_int64 := -fpc_div_int64;
end;
function fpc_mod_int64(n, d: int64): int64; [public, alias: 'FPC_MOD_INT64']; compilerproc;
var
nNeg: boolean;
nLo, nHi, dLo, dHi: uint32;
qLo, qHi, rLo, rHi: uint32;
begin
if d = 0 then begin
HandleErrorInternal(200); { divide by zero }
fpc_mod_int64 := 0;
exit;
end;
nNeg := n < 0;
if n < 0 then n := -n;
if d < 0 then d := -d;
nLo := uint32(n); nHi := uint32(n shr 32);
dLo := uint32(d); dHi := uint32(d shr 32);
udiv64(nLo, nHi, dLo, dHi, qLo, qHi, rLo, rHi);
fpc_mod_int64 := int64(rLo) or (int64(rHi) shl 32);
if nNeg then
fpc_mod_int64 := -fpc_mod_int64;
end;
{ ---------- Memory allocation compilerprocs ---------- }
function kernel_kalloc(size: uint32): Pointer; external name 'kernel_kalloc';
+21 -84
View File
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -58,10 +58,13 @@ align 0x1000
_PageDirectory equ BootPageDirectory
global _PageDirectory
BootPageDirectory:
dd 0x00000083
dd 0x00000083 ; Identity map first 4MB (for boot transition)
times (KERNEL_PAGE_NUMBER - 1) dd 0
dd 0x00000083
times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0
dd 0x00000083 ; 0xC0000000 -> phys 0x00000000 (0-4MB)
dd 0x00400083 ; 0xC0400000 -> phys 0x00400000 (4-8MB)
dd 0x00800083 ; 0xC0800000 -> phys 0x00800000 (8-12MB)
dd 0x00C00083 ; 0xC0C00000 -> phys 0x00C00000 (12-16MB)
times (1024 - KERNEL_PAGE_NUMBER - 4) dd 0
section .text
;