Compare commits

...
Author SHA1 Message Date
admin e922f086c2 Merge pull request 'WASM Execution Pipeline, File Dispatch & Supporting Infrastructure' (#52) from feature/wasm into develop
continuous-integration/drone/push Build is passing
Reviewed-on: #52
Reviewed-by: Aaron Hance <[email protected]>
2026-03-07 22:29:29 +00:00
admin 605ec9d817 Merge pull request 'Standalone SHA-1 hashing implementation' (#51) from feature/sha1 into develop
continuous-integration/drone/push Build is passing
Reviewed-on: #51
Reviewed-by: Aaron Hance <[email protected]>
2026-03-07 22:12:38 +00:00
t3hn3rd 1ae867d929 fix: adapt subsystems to new VFS volume API and fix desktop program registry
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
- ramdrive: rewrite from registerDrive callbacks to TFilesystem/TStorage_Volume
  hooks (rd_Read, rd_ReadDir, rd_ReadOffset, rd_Identify) and mount via
  vfs.mountVolume('/disk/ram', ...). Remove open-slot tracking; VFS now
  manages file handles through the FD table.

- vfs: fix PathValid for otDRIVE nodes — split relative path into parent
  directory + leaf name, list the parent via readDirCallback, and check
  each entry's type so individual files are correctly identified as pvFile
  instead of always returning pvDirectory or pvInvalid.

- desktop: replace static array[0..MAX_PROGRAMS-1] program registry with
  a dynamic PLinkedListBase. Lazy-init on first registerProgram call.
  Remove prog_count := 0 from init so programs registered before
  desktop.init (e.g. notepad, diskutil) are no longer wiped.

- filedispatch, wasmrunner: add storagetypes to uses, remove stale Lock
  parameter from vfs.OpenFile calls.

- progmanager: clean up duplicate uses clauses and remove invalid
  kernel.bsod registration.
2026-03-07 22:12:18 +00:00
t3hn3rd 40a1c05728 Fix: missing imports in wasmio.pas 2026-03-07 21:26:26 +00:00
t3hn3rd 2bfbb44cfb feature: WASM execution pipeline, file dispatch, RAM drive, and VFS handle table
- Add file-type dispatch registry (filedispatch.pas) matching files by
  magic header bytes and routing to registered handlers
- Add WASM integration layer: wasmshim, wasmio, wasmrunner, wasmcleanup
  providing full WASI Preview1 bridging (fd_write/read, proc_exit,
  clock, random, args passthrough, environ stubs)
- Add RAM drive (ramdrive.pas) providing in-memory VFS at /disk/ram
  with a built-in hello world WASM binary
- (Placeholder) Implement VFS handle table for proper
  open/read/write/close/filesize routing through registered drives
  and devices
- Integrate file dispatch into vterminal for unknown commands, supporting
  both foreground and background execution of dispatched files
- Expand progmanager init with PS, KILL, TERMINATE, DEV, DISK, MEMRAW,
  BSOD, IFCONFIG, ARP, and TCP commands; wire up ramdrive, filedispatch,
  and wasmrunner initialization
- Replace serial.sendString with syslog.logln in desktop launcher
2026-03-07 21:26:25 +00:00
t3hn3rd 8ab2d0d04f fix: drone pipeline not working
- compile_wasuro.sh was copying files to the /code directory which
  is not where drone builds from, fixed to use $(pwd) and relative
  directories based on the root.
2026-03-07 21:24:13 +00:00
t3hn3rd b51881ced7 feat: integrate Wasuro WASM runtime into Asuro build chain
- Add compile_wasuro.sh to sparse-clone Wasuro src/wasm from gitea
  (develop branch) with caching to skip redundant pulls
- Update compile.sh to include wasuro build step in pipeline
- Update compile_sources.sh to dynamically discover -Fu paths via
  find across src/ and wasuro/ directories
- Extend system.pas with FPC 3.2.2 compilerprocs required by Wasuro:
  - 64-bit signed/unsigned div and mod (fpc_div_int64, fpc_mod_int64,
    fpc_div_qword, fpc_mod_qword) with correct i386 parameter mapping
  - 64-bit multiply (fpc_mul_int64) via three 32-bit MUL instructions
  - Float-to-integer intrinsics (Trunc, Round) using x87 FPU
  - Memory allocation compilerprocs (fpc_getmem, fpc_freemem)
    delegating to kernel kalloc/kfree
  - Exception handling stubs (reraise, raiseexception, catches, doneexception)
  - setjmp/longjmp for exception address stack
  - Fix sInt64 type alias (was longint/32-bit, now int64/64-bit)
  - Add serial debug helpers (COM1 $3F8) for bare-metal tracing
- Wire up Wasuro in kernel.pas: init WASM VM, set I/O callback to
  syslog, and run all 1103 Wasuro tests (0 failures)
- Update .gitignore to exclude wasuro/ cache directory
2026-03-07 21:24:12 +00:00
t3hn3rd 0d6f1e006c feature: preemptive process management - implementation progress
Implement a preemptive multitasking system for the Asuro kernel.

Context Switching & Scheduling:
- Custom IRQ0 ISR (contextswitcher.pas) with PUSHAD/POPAD ESP-swap
- Round-robin scheduler with priority-based quantum
- Process table using DList of PProcessContext pointers
- Idle process (PID 0) replaces kernel HLT loop

Process Lifecycle:
- create/kill/terminate/sendMessage API (processmanager.pas)
- Process states: Created, Running, Ready, Suspended, Awaiting,
  Finished, Error
- Parent-child tracking (ParentID, smChildExited notification on reap)
- proc_yield, proc_sleep_ms, proc_await, proc_suspend, proc_exit

Resource Binding & Cleanup:
- Per-process resource list
  (bindResource/unbindResource/unbindAllResources)
- TCP sockets auto-bound to owning process (OwnerPID on TTCPSocket)
- socket_cleanup + auto-unbind in DestroySocket

VTerminal Refactor:
- Multi-instance design (heap-allocated TVTermState per terminal)
- Foreground process with incremental stdout/stderr drain via LVGL timer
- Ctrl+C kills foreground process (killForeground)
- Per-terminal CWD, dir stack, FS builtins (CD/LS/PUSHD/POPD)
- Background job support (& suffix, JOBS/FG commands)
- Command history (Up/Down arrow)

Command Consolidation:
- 14 commands extracted from 9 units into centralized progmanager.pas
- Command procedures exported in host unit interfaces
- E1000/TRACER/stdio builtins kept in-place (conditional/circular)

New Units:
- src/include/proctypes.pas — process type definitions
- src/processmanager.pas — core process manager
- src/prog/ping.pas — standalone ICMP ping process
- src/prog/testcmd.pas — test command (proc_sleep_ms demo)
- src/testprocs.pas — process subsystem smoke tests

Misc:
- ICMP callbacks gain userData parameter for concurrency-safe ping
- CLI/STI guards on kalloc/kfree (lmemorymanager.pas)
- LV_KEY_CTRLC constant + Ctrl+C interception in LVGL keyboard hook
- Window owner PID tracking (windows.pas)
- ISR_32 gate override support (isrmanager.pas)
2026-03-07 21:21:45 +00:00
t3hn3rd c70c0b52c3 Rebase: Fixed accidentally removed unit tests.
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-07 21:05:12 +00:00
t3hn3rd 452cc0c8c8 Rebased on develop & remove test code from Kernel main.
continuous-integration/drone/push Build is passing
2026-03-07 20:59:42 +00:00
t3hn3rd 3d334b8e8b feature: SHA-1 Hashing
- Add SHA-1 hashing implementation with Init/Update/Final API and inline test in kernel,
  following the same interface as MD5 & the fpc rtl.
2026-03-07 20:58:51 +00:00
t3hn3rd b9643a7b56 feature: SHA-1 Hashing
- Add SHA-1 hashing implementation with Init/Update/Final API and inline test in kernel,
  following the same interface as MD5 & the fpc rtl.
2026-03-07 20:58:22 +00:00
Aaron 6902a406b0 Merge pull request 'GPU Stack, V8086 Monitor & BGA Driver' (#50) from feature/gpu-stack-v8086-bga into develop
continuous-integration/drone/push Build is passing
Reviewed-on: #50
Reviewed-by: Aaron Hance <[email protected]>
2026-03-07 20:56:19 +00:00
t3hn3rd 36ec7bfdb6 refactor: move program registration from kernel to progmanager
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
- Remove diskcmd, diskutil, notepad, partcmd, volcmd init calls and
  uses from kernel.pas — these are programs, not kernel subsystems.
- Move their initialization into progmanager.init() alongside the
  other baked-in programs (md5sum, base64_prog, dhclient, etc.).
- Remove diskcmd, diskutil, notepad from kernel's uses clause.
- Add a splash.update() call for the auto-mount volumes step.
- Suppress FPC warnings in compile_sources.sh (-v0e instead of -v0ew).
2026-03-07 20:39:43 +00:00
t3hn3rd 6c3c0e63d5 fix: Rebase borked kernel.pas - added missing deps 2026-03-07 20:31:38 +00:00
t3hn3rd df71c59aea feature: add boot splash screen with embedded TGA logo
- New splash unit (src/prog/splash.pas) displays a centered logo,
  progress bar and status label during kernel boot.  Manually drives
  LVGL rendering + video.Flush since gfxd isn't running yet.
- Embed img/asuro.tga into the kernel via NASM incbin stub
  (src/stub/splash_tga.asm), assembled in compile_stub.sh.
- Build an lv_image_dsc_t at runtime from the decoded TGA pixel data
  and display it at 50% scale using lv_image_set_scale(128).
- Move LVGL init earlier in kernel.pas (right after video enable) so
  the splash screen is available before VFS/drivers/network init.
- Sprinkle splash.update() calls throughout kmain to show boot
  progress (VFS → drivers → buses → network → tests → desktop).
- Fix targa.pas parser: rename Magic→IDLength, remove erroneous Data
  pointer field, compute pixel offset correctly (buffer+18+IDLength),
  advance source pointer per pixel, handle bottom-to-top origin flip.
- Unit tests moved before desktop.init; splash.teardown called at 100%
  just before handing off to the desktop environment.
2026-03-07 20:20:00 +00:00
t3hn3rd 97244a2b95 Rebase: Changes made to conform with rebase on develop 2026-03-07 20:17:24 +00:00
t3hn3rd ecca496978 fix: show live GPU/resolution info in System Information
- desktop: Resolution/Graphics fields now read from video frontbuffer
  and gpu.activeDriverName instead of static multiboot/hardcoded values
- gpu: markAvailable sets ActiveName when no driver is active yet, so
  the initial VBE boot driver is reported before any setMode call
- kernel: whitespace cleanup
2026-03-07 20:16:26 +00:00
t3hn3rd e52b4a9763 feature: GPU driver framework with BGA, V86 monitor, and runtime resolution switching
- GPU Framework (gpu.pas): Priority-ordered GPU driver registry with
  mode-change callback system. Drivers register with a priority (lower =
  tried first). After successful setMode, fires registered callbacks in
  order (video → LVGL → desktop) for fully decoupled resolution updates.

- BGA Driver (bga.pas): Bochs Graphics Adapter via drivermanagement PCI
  auto-detection (class=$03 subclass=$00 wildcard). Programs display via
  I/O ports $01CE/$01CF, reads framebuffer from PCI BARs with VMware SVGA
  fallback. Supports arbitrary resolutions (1920x1080, 2560x1440, etc).

- SETRES Command (setres.pas): Runtime resolution switching — just calls
  gpu.setMode; video reinit, LVGL buffer realloc, and desktop relayout
  all fire automatically via GPU mode-change callbacks.

- VESA/VBE: Registered as GPU fallback driver (priority 50), uses V86
  INT 10h for VBE mode switching.

- TSS: Fix SS0 from $08 (code segment) to $10 (data segment); add
  set_esp0/get_esp0 helpers for V86 ring-0 stack management.

- VMM: Add map_page_user() for identity-mapping first 4MB with User bit
  (required for V86 IVT/BDA/video ROM access).

- Desktop: relayout procedure + GPU callback registration for automatic
  dock/watermark repositioning on resolution change.

- V86 Monitor (v86.pas): Full Virtual 8086 mode monitor for executing
  real-mode BIOS interrupts from protected mode. Naked GPF handler with
  instruction emulation (INT, IRET, CLI, STI, PUSHF/POPF, IN/OUT, HLT,
  0x66 prefix for 32-bit variants). Thunk-based entry via IRET into VM86.

- Kernel init order: gpu.init → video.init → vesa.init → bga.init;
  drivermanagement.init moved earlier (before video) so PCI scan detects
  BGA before first use.
2026-03-07 20:16:25 +00:00
admin f78eaa3811 Merge pull request 'Storage system overhaul: VFS, FAT32, ISO9660, AHCI/IDE refactor, GUI apps & boot drive mounting' (#49) from feature/storage-system into develop
continuous-integration/drone/push Build is passing
Reviewed-on: #49
Reviewed-by: admin <[email protected]>
2026-03-07 19:53:14 +00:00
31 changed files with 4064 additions and 145 deletions

No files matched your search

+2 -1
View File
@@ -16,4 +16,5 @@ dockerout.txt
AGENTS.md AGENTS.md
lessons_learnt.md lessons_learnt.md
*.log *.log
/doc/*.md /doc/*.md
wasuro
+1
View File
@@ -24,6 +24,7 @@ declare -a run_steps=(
"compile_stub.sh" "Failed to compile stub!" "compile_stub.sh" "Failed to compile stub!"
"compile_vergen.sh" "Versions failed to compile" "compile_vergen.sh" "Versions failed to compile"
"compile_lvgl.sh" "Failed to compile LVGL!" "compile_lvgl.sh" "Failed to compile LVGL!"
"compile_wasuro.sh" "Failed to pull Wasuro!"
"compile_sources.sh" "Failed to compile FPC Sources!" "compile_sources.sh" "Failed to compile FPC Sources!"
"compile_link.sh" "Failed linking!" "compile_link.sh" "Failed linking!"
"compile_isogen.sh" "Failed to create ISO!" "compile_isogen.sh" "Failed to create ISO!"
+1 -1
View File
@@ -10,4 +10,4 @@ for dir in $(find src wasuro -type d 2>/dev/null); do
FU_PATHS="$FU_PATHS -Fu$dir" FU_PATHS="$FU_PATHS -Fu$dir"
done done
fpc -Aelf -gw -g -gl -n -v0ew -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ $FU_PATHS src/kernel.pas fpc -Aelf -gw -g -gl -n -v0e -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ $FU_PATHS src/kernel.pas
+2 -1
View File
@@ -4,4 +4,5 @@ echo "======================="
echo " " echo " "
echo "Compiling Stub..." echo "Compiling Stub..."
echo " " echo " "
nasm -f elf src/stub/stub.asm -o lib/stub.o nasm -f elf src/stub/stub.asm -o lib/stub.o
nasm -f elf src/stub/splash_tga.asm -o lib/splash_tga.o
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
# compile_wasuro.sh — Pull Wasuro WASM runtime source into wasuro/
# Clones the repo (sparse, src/wasm only) and copies the Pascal sources
# into $PWD/wasuro so the FPC build can reference them via -Fu.
set -e
WASURO_REPO="https://gitea.spexeah.com/Spexeah/Wasuro.git"
WASURO_BRANCH="develop"
WASURO_TMP="/tmp/wasuro"
WASURO_OUT="$(pwd)/wasuro"
echo " "
echo "======================="
echo " "
echo "Pulling Wasuro WASM runtime..."
echo " "
# Skip if wasuro/ already has .pas files (cached from previous build)
if [ -n "$(find "${WASURO_OUT}" -name '*.pas' 2>/dev/null | head -1)" ]; then
echo "Wasuro sources already present in ${WASURO_OUT}, skipping pull."
echo " "
exit 0
fi
# Clone sparse checkout (only src/wasm)
rm -rf "$WASURO_TMP"
git clone --depth 1 --branch "${WASURO_BRANCH}" --filter=blob:none --sparse \
"${WASURO_REPO}" "${WASURO_TMP}" 2>&1
cd "$WASURO_TMP"
git sparse-checkout set src/wasm 2>&1
cd -
echo "Copying src/wasm to ${WASURO_OUT}..."
rm -rf "$WASURO_OUT"
mkdir -p "$WASURO_OUT"
cp -a "${WASURO_TMP}/src/wasm/"* "$WASURO_OUT"/
rm -rf "$WASURO_TMP"
TOTAL=$(find "$WASURO_OUT" -name '*.pas' | wc -l)
echo "Copied ${TOTAL} Pascal source files."
echo " "
echo "Wasuro pull complete."
echo " "
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

+4 -1
View File
@@ -29,11 +29,14 @@ unit contextswitcher;
interface interface
uses uses
idt, isrmanager, processmanager, proctypes, util, tracer; idt, isrmanager, processmanager, proctypes, util, syslog, tracer;
{ Initialise: overwrite IDT gate 32 with our custom ISR. } { Initialise: overwrite IDT gate 32 with our custom ISR. }
procedure init; procedure init;
{ No idle ESP variable needed — idle is now a formal process (PID 0)
with its SavedESP managed like any other process. }
implementation implementation
{ ----------------------------------------------------------------------- { -----------------------------------------------------------------------
File diff suppressed because it is too large. Load diff
+64 -10
View File
@@ -1157,6 +1157,13 @@ var
pvVol : PStorage_Volume; pvVol : PStorage_Volume;
pvStatus : puint32; pvStatus : puint32;
pvDirList: PLinkedListBase; pvDirList: PLinkedListBase;
pvSplitRel : PLinkedListBase;
pvSegCount : uint32;
pvIdx : uint32;
pvLeafName : pchar;
pvParentDir : pchar;
pvTmpConcat : pchar;
pvEntry : PDirectory_Entry;
begin begin
tracer.push_trace('vfs.PathValid.enter'); tracer.push_trace('vfs.PathValid.enter');
@@ -1175,22 +1182,69 @@ begin
RelPath[0] := '/'; RelPath[0] := '/';
end; end;
pvVol := PStorage_Volume(Obj^.Reference); pvVol := PStorage_Volume(Obj^.Reference);
{ Actually verify the path exists on the volume } { Verify the path exists on the volume }
if (pvVol^.filesystem <> nil) and (pvVol^.filesystem^.readDirCallback <> nil) then begin if (pvVol^.filesystem <> nil) and (pvVol^.filesystem^.readDirCallback <> nil) then begin
{ If RelPath is just '/' we're at volume root — always valid } { If RelPath is just '/' we're at volume root — always valid }
if StringEquals(RelPath, '/') then begin if StringEquals(RelPath, '/') then begin
PathValid := pvDirectory; PathValid := pvDirectory;
end else begin end else begin
{ Ask the filesystem if this directory actually exists } { Split RelPath into parent directory and leaf name,
pvStatus := puint32(kalloc(4)); then list the parent and look for the leaf entry. }
pvStatus^ := 0; pvSplitRel := STRLL_FromString(RelPath, '/');
pvDirList := pvVol^.filesystem^.readDirCallback(pvVol, RelPath, pvStatus); pvSegCount := STRLL_Size(pvSplitRel);
if pvStatus^ = 0 then if pvSegCount = 0 then begin
PathValid := pvDirectory
else
PathValid := pvInvalid; PathValid := pvInvalid;
if pvDirList <> nil then LL_Free(pvDirList); end else begin
kfree(puint32(pvStatus)); pvLeafName := STRLL_Get(pvSplitRel, pvSegCount - 1);
{ Build parent directory path from all segments except the last }
if pvSegCount <= 1 then begin
pvParentDir := stringNew(1);
pvParentDir[0] := '/';
end else begin
pvParentDir := stringNew(0);
for pvIdx := 0 to pvSegCount - 2 do begin
if stringSize(pvParentDir) > 0 then begin
pvTmpConcat := stringConcat(pvParentDir, '/');
kfree(void(pvParentDir));
pvParentDir := pvTmpConcat;
end;
pvTmpConcat := stringConcat(pvParentDir, STRLL_Get(pvSplitRel, pvIdx));
kfree(void(pvParentDir));
pvParentDir := pvTmpConcat;
end;
end;
{ List parent directory }
pvStatus := puint32(kalloc(4));
pvStatus^ := 0;
pvDirList := pvVol^.filesystem^.readDirCallback(pvVol, pvParentDir, pvStatus);
PathValid := pvInvalid;
if (pvDirList <> nil) and (pvStatus^ = 0) and (LL_Size(pvDirList) > 0) then begin
for pvIdx := 0 to LL_Size(pvDirList) - 1 do begin
pvEntry := PDirectory_Entry(LL_Get(pvDirList, pvIdx));
if (pvEntry <> nil) and (pvEntry^.fileName <> nil) then begin
if stringEquals(pvEntry^.fileName, pvLeafName) then begin
case pvEntry^.entryType of
fileEntry: PathValid := pvFile;
directoryEntry: PathValid := pvDirectory;
mountEntry: PathValid := pvDirectory;
end;
break;
end;
end;
end;
{ Free entry file names and list }
for pvIdx := 0 to LL_Size(pvDirList) - 1 do begin
pvEntry := PDirectory_Entry(LL_Get(pvDirList, pvIdx));
if (pvEntry <> nil) and (pvEntry^.fileName <> nil) then
kfree(void(pvEntry^.fileName));
end;
LL_Free(pvDirList);
end else if pvDirList <> nil then
LL_Free(pvDirList);
kfree(puint32(pvStatus));
kfree(void(pvParentDir));
end;
STRLL_Free(pvSplitRel);
end; end;
end else end else
PathValid := pvInvalid; PathValid := pvInvalid;
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
+46 -1
View File
@@ -13,7 +13,7 @@ interface
uses uses
video, videotypes, color, serial, tracer, lmemorymanager, video, videotypes, color, serial, tracer, lmemorymanager,
mouse, keyboard, TMR_0_ISR, util; mouse, keyboard, TMR_0_ISR, util, syslog, gpu;
{ ============================================================ { ============================================================
Opaque LVGL pointer types (internal C structs) Opaque LVGL pointer types (internal C structs)
@@ -1670,6 +1670,7 @@ function lvgl_get_display: Plv_display;
procedure lvgl_set_mouse_cursor(cursor: Plv_obj); procedure lvgl_set_mouse_cursor(cursor: Plv_obj);
function lvgl_get_ticks: uint32; function lvgl_get_ticks: uint32;
function lvgl_get_kb_group: Plv_group; function lvgl_get_kb_group: Plv_group;
procedure lvgl_update_resolution(screen_w, screen_h: uint32);
{ Color helper (Pascal wrapper for inline C function) } { Color helper (Pascal wrapper for inline C function) }
function lv_color_make(r, g, b: uint8): lv_color_t; function lv_color_make(r, g, b: uint8): lv_color_t;
@@ -1909,6 +1910,14 @@ begin
tick_accumulator := tick_accumulator + 1; tick_accumulator := tick_accumulator + 1;
end; end;
{ ============================================================
GPU mode-change callback — updates LVGL display resolution
============================================================ }
procedure lvglModeChanged(const info : TGPUModeInfo);
begin
lvgl_update_resolution(info.Width, info.Height);
end;
{ ============================================================ { ============================================================
High-level init High-level init
============================================================ } ============================================================ }
@@ -1962,9 +1971,45 @@ begin
{ Hook 1024Hz timer for accurate LVGL tick } { Hook 1024Hz timer for accurate LVGL tick }
TMR_0_ISR.hook(uint32(@lvgl_timer_tick)); TMR_0_ISR.hook(uint32(@lvgl_timer_tick));
{ Register for GPU mode-change notifications so LVGL resolution updates automatically }
gpu.registerModeChangeCallback(@lvglModeChanged);
tracer.push_trace('lvgl.init.exit'); tracer.push_trace('lvgl.init.exit');
end; end;
procedure lvgl_update_resolution(screen_w, screen_h: uint32);
var
new_buf : pointer;
new_size : uint32;
begin
tracer.push_trace('lvgl.update_resolution.enter');
{ Allocate new render buffer for the new width }
new_size := screen_w * LV_BUF_LINES * SizeOf(lv_color_t);
new_buf := pointer(kalloc(new_size));
if new_buf <> nil then begin
{ Free old render buffer }
if lv_buf1 <> nil then
kfree(lv_buf1);
lv_buf1 := new_buf;
lv_buf1_size := new_size;
{ Update LVGL display resolution and buffers }
lv_display_set_resolution(disp, sint32(screen_w), sint32(screen_h));
lv_display_set_buffers(disp, lv_buf1, nil,
lv_buf1_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
syslog.logln('LVGL', 'Resolution updated successfully.');
end else begin
syslog.logln('LVGL', 'Failed to allocate new render buffer.');
end;
tracer.push_trace('lvgl.update_resolution.exit');
end;
function lvgl_handler: uint32; function lvgl_handler: uint32;
var var
elapsed: uint32; elapsed: uint32;
File diff suppressed because it is too large. Load diff
+59 -1
View File
@@ -22,7 +22,7 @@ unit video;
interface interface
uses uses
lmemorymanager, tracer, color, videotypes, hashmap, util, texture; lmemorymanager, tracer, color, videotypes, hashmap, util, texture, gpu;
procedure init(); procedure init();
procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32); procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32);
@@ -30,6 +30,7 @@ procedure DrawLine(x1,y1,x2,y2 : uint32; thickness : uint32; Color : TRGB32);
procedure DrawRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32); procedure DrawRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32);
procedure FillRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32); procedure FillRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32);
procedure Flush(); procedure Flush();
procedure reinit(fb_addr, width, height, pitch : uint32; bpp : uint8);
function register(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean; function register(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean;
function enable(DriverIdentifier : pchar) : boolean; function enable(DriverIdentifier : pchar) : boolean;
@@ -47,6 +48,9 @@ Procedure basicFDrawTexture(Buffer : PVideoBuffer; X : uint32; Y : uint32; Textu
implementation implementation
uses
VESA8, VESA16, VESA24, VESA32;
Procedure dummyFDrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32); Procedure dummyFDrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32);
begin begin
tracer.push_trace('video.dummyFDrawPixel.enter'); tracer.push_trace('video.dummyFDrawPixel.enter');
@@ -191,6 +195,14 @@ var
VideoInterface : TVideoInterface; VideoInterface : TVideoInterface;
DriverMap : PHashMap; DriverMap : PHashMap;
{ ============================================================
GPU mode-change callback — reinits front/back buffers
============================================================ }
procedure videoModeChanged(const info : TGPUModeInfo);
begin
reinit(info.Framebuffer, info.Width, info.Height, info.Pitch, info.BPP);
end;
procedure init(); procedure init();
var var
RGB : TRGB32; RGB : TRGB32;
@@ -226,6 +238,9 @@ begin
//Initialize our 'DriverMap', a hashmap of loadable display drivers. //Initialize our 'DriverMap', a hashmap of loadable display drivers.
DriverMap:= hashmap.new; DriverMap:= hashmap.new;
{ Register for GPU mode-change notifications so reinit fires automatically }
gpu.registerModeChangeCallback(@videoModeChanged);
tracer.push_trace('video.init.exit'); tracer.push_trace('video.init.exit');
end; end;
@@ -327,4 +342,47 @@ begin
frontBufferLocation:= VideoInterface.FrontBuffer.Location; frontBufferLocation:= VideoInterface.FrontBuffer.Location;
end; end;
procedure reinit(fb_addr, width, height, pitch : uint32; bpp : uint8);
begin
tracer.push_trace('video.reinit.enter');
{ Free old back buffer if allocated }
if VideoInterface.BackBuffer.Initialized then begin
kfree(void(VideoInterface.BackBuffer.Location));
VideoInterface.BackBuffer.Initialized := false;
VideoInterface.BackBuffer.Location := 0;
VideoInterface.BackBuffer.Width := 0;
VideoInterface.BackBuffer.Height := 0;
end;
{ Reset front buffer so it can be re-initialized }
VideoInterface.FrontBuffer.Initialized := false;
VideoInterface.FrontBuffer.Location := 0;
VideoInterface.FrontBuffer.Width := 0;
VideoInterface.FrontBuffer.Height := 0;
{ Point default buffer back to front (in case doublebuffer re-enable fails) }
VideoInterface.DefaultBuffer := @VideoInterface.FrontBuffer;
{ Set front buffer directly from GPU mode info }
VideoInterface.FrontBuffer.Location := fb_addr;
VideoInterface.FrontBuffer.Width := width;
VideoInterface.FrontBuffer.Height := height;
VideoInterface.FrontBuffer.BitsPerPixel := bpp;
if fb_addr <> 0 then
VideoInterface.FrontBuffer.Initialized := true;
{ Set up BPP-specific draw routines }
case bpp of
08: VESA8.init(@VideoInterface.DrawRoutines);
16: VESA16.init(@VideoInterface.DrawRoutines);
24: VESA24.init(@VideoInterface.DrawRoutines);
32: VESA32.init(@VideoInterface.DrawRoutines);
end;
{ Re-enable double buffer (allocates new back buffer matching front) }
enable('BASIC_DOUBLE_BUFFER');
tracer.push_trace('video.reinit.exit');
end;
end. end.
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+203 -18
View File
File diff suppressed because it is too large. Load diff
+31 -21
View File
@@ -12,7 +12,7 @@ type
PTARGAColor = ^TTARGAColor; PTARGAColor = ^TTARGAColor;
TTARGAHeader = packed record TTARGAHeader = packed record
Magic: uint8; IDLength: uint8;
ColorMapType: uint8; ColorMapType: uint8;
ImageType: uint8; ImageType: uint8;
ColorMapOrigin: uint16; ColorMapOrigin: uint16;
@@ -24,7 +24,6 @@ type
Height: uint16; Height: uint16;
PixelDepth: uint8; PixelDepth: uint8;
ImageDescriptor: uint8; ImageDescriptor: uint8;
Data : PTARGAColor;
end; end;
PTARGAHeader = ^TTARGAHeader; PTARGAHeader = ^TTARGAHeader;
@@ -35,29 +34,40 @@ implementation
Function Parse(buffer : puint8; len : uint32) : PTexture; Function Parse(buffer : puint8; len : uint32) : PTexture;
var var
header : PTARGAHeader; header : PTARGAHeader;
i, j : uint32; src : PTARGAColor;
data : PTARGAColor; tex : PTexture;
tex : PTexture; x, y : uint32;
dstRow : uint32;
topDown: boolean;
begin begin
if (len < sizeof(TTARGAHeader)) then exit; Parse := nil;
if len < sizeof(TTARGAHeader) then exit;
header := PTARGAHeader(buffer); header := PTARGAHeader(buffer);
if (header^.Magic <> $0) or (header^.ImageType <> 2) or (header^.PixelDepth <> 32) then exit; if (header^.ImageType <> 2) or (header^.PixelDepth <> 32) then exit;
//Create a new texture { Pixel data starts after the 18-byte header + any ID field. }
tex:= texture.newTexture(header^.Width, header^.Height); src := PTARGAColor(buffer + sizeof(TTARGAHeader) + header^.IDLength);
tex^.Width:= header^.Width;
tex^.Height:= header^.Height; { Bit 5 of ImageDescriptor: 1 = top-to-bottom, 0 = bottom-to-top. }
topDown := (header^.ImageDescriptor AND $20) <> 0;
//Copy the data
data := PTARGAColor(header^.Data); tex := texture.newTexture(header^.Width, header^.Height);
for i := 0 to header^.Height - 1 do begin
for j := 0 to header^.Width - 1 do begin for y := 0 to header^.Height - 1 do begin
tex^.Pixels[i * header^.Width + j].r := data^.r; { Flip vertically when origin is bottom-left (the TGA default). }
tex^.Pixels[i * header^.Width + j].g := data^.g; if topDown then
tex^.Pixels[i * header^.Width + j].b := data^.b; dstRow := y
tex^.Pixels[i * header^.Width + j].a := data^.a; else
dstRow := (header^.Height - 1) - y;
for x := 0 to header^.Width - 1 do begin
tex^.Pixels[dstRow * header^.Width + x].b := src^.b;
tex^.Pixels[dstRow * header^.Width + x].g := src^.g;
tex^.Pixels[dstRow * header^.Width + x].r := src^.r;
tex^.Pixels[dstRow * header^.Width + x].a := src^.a;
Inc(src);
end; end;
end; end;
+74 -44
View File
File diff suppressed because it is too large. Load diff
Loaded 20 of 31 files, more files were not shown because too many files have changed in this diff. Show more