Compare commits

..
Author SHA1 Message Date
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
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
30 changed files with 3854 additions and 145 deletions
+2 -1
View File
@@ -16,4 +16,5 @@ dockerout.txt
AGENTS.md
lessons_learnt.md
*.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_vergen.sh" "Versions failed to compile"
"compile_lvgl.sh" "Failed to compile LVGL!"
"compile_wasuro.sh" "Failed to pull Wasuro!"
"compile_sources.sh" "Failed to compile FPC Sources!"
"compile_link.sh" "Failed linking!"
"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"
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 "Compiling Stub..."
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
uses
idt, isrmanager, processmanager, proctypes, util, tracer;
idt, isrmanager, processmanager, proctypes, util, syslog, tracer;
{ Initialise: overwrite IDT gate 32 with our custom ISR. }
procedure init;
{ No idle ESP variable needed — idle is now a formal process (PID 0)
with its SavedESP managed like any other process. }
implementation
{ -----------------------------------------------------------------------
File diff suppressed because it is too large Load Diff
+64 -10
View File
@@ -1157,6 +1157,13 @@ var
pvVol : PStorage_Volume;
pvStatus : puint32;
pvDirList: PLinkedListBase;
pvSplitRel : PLinkedListBase;
pvSegCount : uint32;
pvIdx : uint32;
pvLeafName : pchar;
pvParentDir : pchar;
pvTmpConcat : pchar;
pvEntry : PDirectory_Entry;
begin
tracer.push_trace('vfs.PathValid.enter');
@@ -1175,22 +1182,69 @@ begin
RelPath[0] := '/';
end;
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 RelPath is just '/' we're at volume root — always valid }
if StringEquals(RelPath, '/') then begin
PathValid := pvDirectory;
end else begin
{ Ask the filesystem if this directory actually exists }
pvStatus := puint32(kalloc(4));
pvStatus^ := 0;
pvDirList := pvVol^.filesystem^.readDirCallback(pvVol, RelPath, pvStatus);
if pvStatus^ = 0 then
PathValid := pvDirectory
else
{ Split RelPath into parent directory and leaf name,
then list the parent and look for the leaf entry. }
pvSplitRel := STRLL_FromString(RelPath, '/');
pvSegCount := STRLL_Size(pvSplitRel);
if pvSegCount = 0 then begin
PathValid := pvInvalid;
if pvDirList <> nil then LL_Free(pvDirList);
kfree(puint32(pvStatus));
end else begin
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 else
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
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)
@@ -1670,6 +1670,7 @@ function lvgl_get_display: Plv_display;
procedure lvgl_set_mouse_cursor(cursor: Plv_obj);
function lvgl_get_ticks: uint32;
function lvgl_get_kb_group: Plv_group;
procedure lvgl_update_resolution(screen_w, screen_h: uint32);
{ Color helper (Pascal wrapper for inline C function) }
function lv_color_make(r, g, b: uint8): lv_color_t;
@@ -1909,6 +1910,14 @@ begin
tick_accumulator := tick_accumulator + 1;
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
============================================================ }
@@ -1962,9 +1971,45 @@ begin
{ Hook 1024Hz timer for accurate LVGL 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');
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;
var
elapsed: uint32;
File diff suppressed because it is too large Load Diff
+59 -1
View File
@@ -22,7 +22,7 @@ unit video;
interface
uses
lmemorymanager, tracer, color, videotypes, hashmap, util, texture;
lmemorymanager, tracer, color, videotypes, hashmap, util, texture, gpu;
procedure init();
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 FillRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32);
procedure Flush();
procedure reinit(fb_addr, width, height, pitch : uint32; bpp : uint8);
function register(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean;
function enable(DriverIdentifier : pchar) : boolean;
@@ -47,6 +48,9 @@ Procedure basicFDrawTexture(Buffer : PVideoBuffer; X : uint32; Y : uint32; Textu
implementation
uses
VESA8, VESA16, VESA24, VESA32;
Procedure dummyFDrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32);
begin
tracer.push_trace('video.dummyFDrawPixel.enter');
@@ -191,6 +195,14 @@ var
VideoInterface : TVideoInterface;
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();
var
RGB : TRGB32;
@@ -226,6 +238,9 @@ begin
//Initialize our 'DriverMap', a hashmap of loadable display drivers.
DriverMap:= hashmap.new;
{ Register for GPU mode-change notifications so reinit fires automatically }
gpu.registerModeChangeCallback(@videoModeChanged);
tracer.push_trace('video.init.exit');
end;
@@ -327,4 +342,47 @@ begin
frontBufferLocation:= VideoInterface.FrontBuffer.Location;
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.
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;
TTARGAHeader = packed record
Magic: uint8;
IDLength: uint8;
ColorMapType: uint8;
ImageType: uint8;
ColorMapOrigin: uint16;
@@ -24,7 +24,6 @@ type
Height: uint16;
PixelDepth: uint8;
ImageDescriptor: uint8;
Data : PTARGAColor;
end;
PTARGAHeader = ^TTARGAHeader;
@@ -35,29 +34,40 @@ implementation
Function Parse(buffer : puint8; len : uint32) : PTexture;
var
header : PTARGAHeader;
i, j : uint32;
data : PTARGAColor;
tex : PTexture;
src : PTARGAColor;
tex : PTexture;
x, y : uint32;
dstRow : uint32;
topDown: boolean;
begin
if (len < sizeof(TTARGAHeader)) then exit;
Parse := nil;
if len < sizeof(TTARGAHeader) then exit;
header := PTARGAHeader(buffer);
if (header^.Magic <> $0) or (header^.ImageType <> 2) or (header^.PixelDepth <> 32) then exit;
//Create a new texture
tex:= texture.newTexture(header^.Width, header^.Height);
tex^.Width:= header^.Width;
tex^.Height:= header^.Height;
//Copy the data
data := PTARGAColor(header^.Data);
for i := 0 to header^.Height - 1 do begin
for j := 0 to header^.Width - 1 do begin
tex^.Pixels[i * header^.Width + j].r := data^.r;
tex^.Pixels[i * header^.Width + j].g := data^.g;
tex^.Pixels[i * header^.Width + j].b := data^.b;
tex^.Pixels[i * header^.Width + j].a := data^.a;
if (header^.ImageType <> 2) or (header^.PixelDepth <> 32) then exit;
{ Pixel data starts after the 18-byte header + any ID field. }
src := PTARGAColor(buffer + sizeof(TTARGAHeader) + header^.IDLength);
{ Bit 5 of ImageDescriptor: 1 = top-to-bottom, 0 = bottom-to-top. }
topDown := (header^.ImageDescriptor AND $20) <> 0;
tex := texture.newTexture(header^.Width, header^.Height);
for y := 0 to header^.Height - 1 do begin
{ Flip vertically when origin is bottom-left (the TGA default). }
if topDown then
dstRow := y
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;
+74 -44
View File
File diff suppressed because it is too large Load Diff
+83
View File
@@ -0,0 +1,83 @@
{
Prog->setres - Set display resolution via GPU driver framework.
Usage: SETRES <width> <height>
Example: SETRES 1024 768
Uses the GPU driver framework to switch display modes. Tries BGA first,
then falls back to VBE/VESA.
@author(Kieron Morris <[email protected]>)
}
unit setres;
interface
uses
stdio, gpu, util, strings, tracer, syslog;
procedure init();
implementation
procedure run(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
var
w, h : uint32;
wStr, hStr : pchar;
info : TGPUModeInfo;
begin
tracer.push_trace('setres.run');
if paramCount(params) < 2 then begin
stdio.bufWriteStrLn(stderr_buf, 'Usage: SETRES <width> <height>');
stdio.bufWriteStrLn(stderr_buf, 'Example: SETRES 1024 768');
tracer.pop_trace;
exit;
end;
wStr := getParam(0, params);
hStr := getParam(1, params);
w := stringToInt(wStr);
h := stringToInt(hStr);
if (w = 0) or (h = 0) then begin
stdio.bufWriteStrLn(stderr_buf, 'Error: Invalid resolution values.');
tracer.pop_trace;
exit;
end;
stdio.bufWriteStr(stdout_buf, 'Setting resolution to ');
stdio.bufWriteInt(stdout_buf, w);
stdio.bufWriteStr(stdout_buf, 'x');
stdio.bufWriteInt(stdout_buf, h);
stdio.bufWriteStrLn(stdout_buf, 'x32...');
{ Step 1: Set display mode via GPU framework (tries BGA first, then VBE) }
if not gpu.setMode(w, h, 32, info) then begin
stdio.bufWriteStrLn(stderr_buf, 'Error: Mode switch failed. Mode may not be supported.');
tracer.pop_trace;
exit;
end;
stdio.bufWriteStr(stdout_buf, 'Mode set via ');
stdio.bufWriteStrLn(stdout_buf, gpu.activeDriverName());
stdio.bufWriteStr(stdout_buf, 'Resolution set to ');
stdio.bufWriteInt(stdout_buf, w);
stdio.bufWriteStr(stdout_buf, 'x');
stdio.bufWriteInt(stdout_buf, h);
stdio.bufWriteStrLn(stdout_buf, 'x32 successfully.');
tracer.pop_trace;
end;
procedure init();
begin
tracer.push_trace('setres.init');
stdio.registerCommand('SETRES', @Run, 'Set display resolution. Usage: SETRES <width> <height>');
tracer.pop_trace;
end;
end.

Some files were not shown because too many files have changed in this diff Show More