Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e922f086c2 | ||
|
|
605ec9d817 | ||
|
|
1ae867d929 | ||
|
|
40a1c05728 | ||
|
|
2bfbb44cfb | ||
|
|
8ab2d0d04f | ||
|
|
b51881ced7 | ||
|
|
0d6f1e006c | ||
|
|
c70c0b52c3 | ||
|
|
452cc0c8c8 | ||
|
|
3d334b8e8b | ||
|
|
b9643a7b56 | ||
|
|
6902a406b0 | ||
|
|
36ec7bfdb6 | ||
|
|
6c3c0e63d5 | ||
|
|
df71c59aea | ||
|
|
97244a2b95 | ||
|
|
ecca496978 | ||
|
|
e52b4a9763 | ||
|
|
f78eaa3811 |
No files matched your search
@@ -17,3 +17,4 @@ AGENTS.md
|
||||
lessons_learnt.md
|
||||
*.log
|
||||
/doc/*.md
|
||||
wasuro
|
||||
@@ -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
@@ -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
|
||||
@@ -5,3 +5,4 @@ echo " "
|
||||
echo "Compiling Stub..."
|
||||
echo " "
|
||||
nasm -f elf src/stub/stub.asm -o lib/stub.o
|
||||
nasm -f elf src/stub/splash_tga.asm -o lib/splash_tga.o
|
||||
@@ -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 " "
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
@@ -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
@@ -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 }
|
||||
{ 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;
|
||||
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, RelPath, pvStatus);
|
||||
if pvStatus^ = 0 then
|
||||
PathValid := pvDirectory
|
||||
else
|
||||
pvDirList := pvVol^.filesystem^.readDirCallback(pvVol, pvParentDir, pvStatus);
|
||||
PathValid := pvInvalid;
|
||||
if pvDirList <> nil then LL_Free(pvDirList);
|
||||
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
@@ -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;
|
||||
|
||||
+161
-1
File diff suppressed because it is too large.
Load diff
@@ -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
File diff suppressed because it is too large.
Load diff
+201
-16
File diff suppressed because it is too large.
Load diff
+28
-18
@@ -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;
|
||||
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;
|
||||
if (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;
|
||||
{ Pixel data starts after the 18-byte header + any ID field. }
|
||||
src := PTARGAColor(buffer + sizeof(TTARGAHeader) + header^.IDLength);
|
||||
|
||||
//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;
|
||||
{ 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;
|
||||
|
||||
|
||||
+73
-43
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
Reference in new issue
Block a user