Compare commits

..
3 Commits
Author SHA1 Message Date
t3hn3rd 0548e89608 fix: missing index.md from doc folder
continuous-integration/drone/push Build is passing
2026-03-08 20:39:23 +00:00
t3hn3rd 4bd8741050 fix: use pip3 and python3 -m mkdocs for Drone compatibility
continuous-integration/drone/push Build is failing
The Drone runner environment does not have `pip` or `mkdocs` on PATH
even when installed via the Docker image. Use `pip3` explicitly and
invoke mkdocs as `python3 -m mkdocs` to ensure reliable execution.
Also add --break-system-packages to the fallback install.
2026-03-08 20:24:39 +00:00
t3hn3rd 08919309fc feature: add mkdocs-material documentation site with CI deployment
continuous-integration/drone/push Build is failing
Generate comprehensive documentation for all 173 source units and
integrate mkdocs-material into the build toolchain. Documentation
covers kernel core, x86 architecture, drivers, applications, and
all subsystems with a tabbed navigation structure.

- Add mkdocs.yml with material theme, mermaid support, and tabbed nav
- Add doc/index.md landing page
- Generate doc/src/ markdown for every Pascal unit in src/
- Reorganize planning docs into doc/planning/
- Add compat, lvglh, and toolchain doc sections
- Update Dockerfile to install python3 and mkdocs-material (pinned <2)
- Replace pasdoc-based compile_docs.sh with mkdocs build --strict
- Add compile_docs.sh to the main build pipeline in compile.sh
- Add deploy-docs step in .drone.yml with host volume mount to nginx
- Add site/.gitkeep for build output directory
2026-03-08 20:10:56 +00:00
19 changed files with 481 additions and 3134 deletions

No files matched your search

-587
View File
File diff suppressed because it is too large. Load diff
Generated
-1
View File
@@ -1 +0,0 @@
mnt {device}/sys /sys
-1
View File
@@ -296,5 +296,4 @@ nav:
- Process Management: planning/processmanagement.md
- TCP: planning/tcp.md
- Tracer: planning/tracer.md
- VFS: planning/vfs.md
- WASM: planning/wasm.md
+3 -3
View File
@@ -138,7 +138,7 @@ begin
{ Open for writing }
debug.tracer.push_trace('edit.SaveFile.openRW');
fHandle := driver.storage.vfs.OpenFile(FilePath, omReadWrite, @fError);
fHandle := driver.storage.vfs.OpenFile(FilePath, omReadWrite, wmRewrite, @fError);
if fHandle <> 0 then begin
debug.tracer.push_trace('edit.SaveFile.writeFile');
driver.storage.vfs.WriteFile(fHandle, 0, puint8(buf), totalLen);
@@ -149,7 +149,7 @@ begin
end else begin
{ Try write-only for new file }
debug.tracer.push_trace('edit.SaveFile.openWO');
fHandle := driver.storage.vfs.OpenFile(FilePath, omCreate, @fError);
fHandle := driver.storage.vfs.OpenFile(FilePath, omWriteOnly, wmNew, @fError);
if fHandle <> 0 then begin
debug.tracer.push_trace('edit.SaveFile.writeFileNew');
driver.storage.vfs.WriteFile(fHandle, 0, puint8(buf), totalLen);
@@ -181,7 +181,7 @@ begin
if FilePath = nil then exit;
debug.tracer.push_trace('edit.LoadFile.openFile');
fHandle := driver.storage.vfs.OpenFile(FilePath, omRead, @fError);
fHandle := driver.storage.vfs.OpenFile(FilePath, omReadOnly, wmRewrite, @fError);
debug.tracer.push_trace('edit.LoadFile.openFile.done');
if (fHandle = 0) or (fError <> eNone) then begin
io.syslog.writestringln('New file.');
+5 -40
View File
@@ -77,15 +77,12 @@ type
{ Flat name buffer — heap-alloc'd in do_refresh to avoid stack bloat }
TNameBuf = array[0..ENTRY_MAX - 1] of pchar;
PNameBuf = ^TNameBuf;
TSizeBuf = array[0..ENTRY_MAX - 1] of uint32;
PSizeBuf = ^TSizeBuf;
{ Per-call context passed to the forEach collect callback }
PFPCollectCtx = ^TFPCollectCtx;
TFPCollectCtx = record
dir_names : PNameBuf;
file_names : PNameBuf;
file_sizes : PSizeBuf;
dir_count : uint32;
file_count : uint32;
filter : pchar;
@@ -353,28 +350,6 @@ begin
end;
end;
{ Insertion sort on name array, swapping a parallel size array in lockstep }
procedure sortNamesWithSizes(var names: array of pchar; var sizes: array of uint32; n: uint32);
var
i, j : uint32;
tmpN : pchar;
tmpS : uint32;
begin
if n < 2 then exit;
for i := 1 to n - 1 do begin
tmpN := names[i];
tmpS := sizes[i];
j := i;
while (j > 0) and strLess(tmpN, names[j - 1]) do begin
names[j] := names[j - 1];
sizes[j] := sizes[j - 1];
j := j - 1;
end;
names[j] := tmpN;
sizes[j] := tmpS;
end;
end;
{ ============================================================
fp_collect_cb
core.ds.hashmap.forEach callback: classifies each VFS entry as dir or file
@@ -389,7 +364,7 @@ begin
obj := PVFSObject(data);
if (ctx = nil) or (obj = nil) then exit;
case obj^.ObjectType of
otVDIRECTORY, otDRIVE, otDIRECTORY, otMOUNT, otSYMLINK:
otVDIRECTORY, otDRIVE, otDIRECTORY, otMOUNT:
if ctx^.dir_count < ENTRY_MAX then begin
ctx^.dir_names^[ctx^.dir_count] := key;
ctx^.dir_count := ctx^.dir_count + 1;
@@ -398,7 +373,6 @@ begin
if matchesFilter(key, ctx^.filter) then
if ctx^.file_count < ENTRY_MAX then begin
ctx^.file_names^[ctx^.file_count] := key;
ctx^.file_sizes^[ctx^.file_count] := obj^.FileSize;
ctx^.file_count := ctx^.file_count + 1;
end;
end;
@@ -416,14 +390,12 @@ var
ctx : TFPCollectCtx;
dir_names : PNameBuf; { heap-alloc'd to avoid blowing the core.version stack }
file_names : PNameBuf;
file_sizes : PSizeBuf;
dir_count : uint32;
file_count : uint32;
i : uint32;
row, name_lbl, size_lbl : Plv_obj;
sep : pchar;
copy : pchar;
szStr : pchar;
s1, s2, s3 : pchar;
begin
debug.tracer.push_trace('filepicker.do_refresh');
@@ -436,10 +408,8 @@ begin
io.syslog.logln('FPCIK', 'do_refresh: kalloc name bufs');
dir_names := PNameBuf(kalloc(sizeof(TNameBuf)));
file_names := PNameBuf(kalloc(sizeof(TNameBuf)));
file_sizes := PSizeBuf(kalloc(sizeof(TSizeBuf)));
memset(uint32(dir_names), 0, sizeof(TNameBuf));
memset(uint32(file_names), 0, sizeof(TNameBuf));
memset(uint32(file_sizes), 0, sizeof(TSizeBuf));
{ Sync path bar }
if p^.path_bar <> nil then
@@ -459,7 +429,6 @@ begin
lv_label_set_text(p^.status_label, 'Could not read directory');
kfree(void(dir_names));
kfree(void(file_names));
kfree(void(file_sizes));
debug.tracer.pop_trace;
exit;
end;
@@ -468,7 +437,6 @@ begin
driver.storage.vfs.FreeDirectoryListing(Map);
kfree(void(dir_names));
kfree(void(file_names));
kfree(void(file_sizes));
debug.tracer.pop_trace;
exit;
end;
@@ -476,7 +444,6 @@ begin
ctx.dir_names := dir_names;
ctx.file_names := file_names;
ctx.file_sizes := file_sizes;
ctx.dir_count := 0;
ctx.file_count := 0;
ctx.filter := p^.filter;
@@ -488,7 +455,7 @@ begin
{ --- Sort both collections alphabetically --- }
if dir_count > 0 then sortNames(dir_names^, dir_count);
if file_count > 0 then sortNamesWithSizes(file_names^, file_sizes^, file_count);
if file_count > 0 then sortNames(file_names^, file_count);
{ --- Build directory rows --- }
if dir_count > 0 then
@@ -557,11 +524,10 @@ begin
lv_obj_set_style_text_color(name_lbl, lv_color_make(210, 215, 230), 0);
lv_obj_set_style_text_font(name_lbl, @lv_font_montserrat_14, 0);
{ File size column: use metadata from directory listing }
{ File size column: skipped here to avoid blocking disk I/O
inside the LVGL timer callback context. }
size_lbl := lv_label_create(row);
szStr := fmtFileSize(file_sizes^[i]);
lv_label_set_text(size_lbl, szStr);
kfree(void(szStr));
lv_label_set_text(size_lbl, '--');
lv_obj_set_width(size_lbl, 70);
lv_obj_set_style_text_color(size_lbl, lv_color_make(100, 110, 130), 0);
lv_obj_set_style_text_font(size_lbl, @lv_font_montserrat_14, 0);
@@ -577,7 +543,6 @@ begin
kfree(void(dir_names));
kfree(void(file_names));
kfree(void(file_sizes));
{ Update status label: "X dirs, Y files" }
if p^.status_label <> nil then begin
+3 -3
View File
@@ -65,7 +65,7 @@ begin
{ ---- READ ---- }
if op[0] = '<' then begin
fHandle := driver.storage.vfs.OpenFile(absPath, omRead, @fError);
fHandle := driver.storage.vfs.OpenFile(absPath, omReadOnly, wmRewrite, @fError);
if (fHandle = 0) or (fError <> eNone) then begin
io.syslog.writestringln('Error: cannot open file for reading.');
kfree(void(absPath));
@@ -112,10 +112,10 @@ begin
contentLen := stringSize(content);
{ Try read-write rewrite first (existing file) }
fHandle := driver.storage.vfs.OpenFile(absPath, omReadWrite, @fError);
fHandle := driver.storage.vfs.OpenFile(absPath, omReadWrite, wmRewrite, @fError);
if (fHandle = 0) or (fError <> eNone) then begin
{ Try creating new file }
fHandle := driver.storage.vfs.OpenFile(absPath, omCreate, @fError);
fHandle := driver.storage.vfs.OpenFile(absPath, omWriteOnly, wmNew, @fError);
end;
if (fHandle = 0) or (fError <> eNone) then begin
+3 -3
View File
@@ -372,9 +372,9 @@ begin
buf := pchar(kalloc(FILE_BUF_SIZE));
memset(uint32(buf), 0, FILE_BUF_SIZE);
memcpy(uint32(txt), uint32(buf), len);
fHandle := driver.storage.vfs.OpenFile(state^.currentPath, omReadWrite, @fError);
fHandle := driver.storage.vfs.OpenFile(state^.currentPath, omReadWrite, wmRewrite, @fError);
if fHandle = 0 then
fHandle := driver.storage.vfs.OpenFile(state^.currentPath, omCreate, @fError);
fHandle := driver.storage.vfs.OpenFile(state^.currentPath, omWriteOnly, wmNew, @fError);
if fHandle = 0 then begin
kfree(void(buf));
io.syslog.logln('NOTEPAD', 'saveFile: OpenFile failed');
@@ -413,7 +413,7 @@ var
buf : pchar;
begin
debug.tracer.push_trace('notepad.loadFile');
fHandle := driver.storage.vfs.OpenFile(path, omRead, @fError);
fHandle := driver.storage.vfs.OpenFile(path, omReadOnly, wmRewrite, @fError);
if (fHandle = 0) or (fError <> eNone) then begin
io.syslog.logln('NOTEPAD', 'loadFile: could not open file');
showErrorMsgbox('Open Failed', 'Could not open file for reading.');
+3 -3
View File
@@ -343,7 +343,7 @@ begin
end;
end;
{ Resolve relative to per-terminal cwd }
Validity := driver.storage.vfs.ChangeDirectoryFrom(Path, state^.cwd, NewDir);
Validity := driver.storage.vfs.changeDirectoryFrom(Path, state^.cwd, NewDir);
case Validity of
pvDirectory: begin
kfree(void(state^.cwd));
@@ -410,7 +410,7 @@ var
begin
if STRLL_Size(state^.dir_stack) > 0 then begin
wd := STRLL_Get(state^.dir_stack, STRLL_Size(state^.dir_stack) - 1);
Validity := driver.storage.vfs.ChangeDirectoryFrom(wd, state^.cwd, NewDir);
Validity := driver.storage.vfs.changeDirectoryFrom(wd, state^.cwd, NewDir);
if Validity = pvDirectory then begin
kfree(void(state^.cwd));
state^.cwd := NewDir;
@@ -696,7 +696,7 @@ begin
end;
end else begin
{ No built-in command found — try file dispatch }
absPath := driver.storage.vfs.MakeAbsolutePathFrom(params^.Param, state^.cwd);
absPath := driver.storage.vfs.makeAbsolutePathFrom(params^.Param, state^.cwd);
if absPath <> nil then begin
if is_bg then begin
{ Background file dispatch }
+14 -13
View File
@@ -152,35 +152,36 @@ var
fh : TFileHandle;
err : TError;
fsize : uint32;
errb : uint8;
bytesRead : uint32;
processCtx : PProcessContext;
begin
debug.tracer.push_trace('wasmrunner.handler');
wasm_file_handler := 0;
{ 1. Open file once — omRead pre-loads the data and gives us the size }
err := eNone;
fh := driver.storage.vfs.OpenFile(path, omRead, @err);
if (fh = 0) or (err <> eNone) then begin
io.stdio.bufWriteStrLn(stderr_buf, 'WASM: cannot open file');
exit;
end;
fsize := driver.storage.vfs.FileSizeFromHandle(fh);
if fsize = 0 then begin
driver.storage.vfs.CloseFile(fh);
io.stdio.bufWriteStrLn(stderr_buf, 'WASM: file is empty or cannot determine size');
{ 1. Get file size }
errb := 0;
fsize := driver.storage.vfs.FileSize(path, @errb);
if (fsize = 0) or (errb <> 0) then begin
io.stdio.bufWriteStrLn(stderr_buf, 'WASM: cannot determine file size');
exit;
end;
{ 2. Allocate buffer and read file }
buf := puint8(kalloc(fsize));
if buf = nil then begin
driver.storage.vfs.CloseFile(fh);
io.stdio.bufWriteStrLn(stderr_buf, 'WASM: out of memory');
exit;
end;
err := eNone;
fh := driver.storage.vfs.OpenFile(path, omReadOnly, wmRewrite, @err);
if fh = 0 then begin
kfree(void(buf));
io.stdio.bufWriteStrLn(stderr_buf, 'WASM: cannot open file');
exit;
end;
bytesRead := driver.storage.vfs.ReadFile(fh, 0, buf, fsize);
driver.storage.vfs.CloseFile(fh);
@@ -148,10 +148,6 @@ begin
entry := PDirectory_Entry(LL_Add(dirList));
entry^.fileName := stringCopy(Files[i].Name);
entry^.entryType := fileEntry;
entry^.fileSize := Files[i].Size;
entry^.modifiedDate := 0;
entry^.modifiedTime := 0;
entry^.attributes := 0;
end;
end;
if status <> nil then status^ := 0;
@@ -41,12 +41,11 @@ type
Directory : pchar; { directory path within the volume }
FileName : pchar; { filename within that directory }
OpenMode : uint8; { TOpenMode ordinal — avoids VFS type dependency }
WriteMode : uint8; { TWriteMode ordinal }
DataBuffer : puint32; { pre-loaded data for small files, nil otherwise }
DataSize : uint32; { size of pre-loaded data in bytes }
Loaded : boolean; { true if pre-loaded into DataBuffer }
StreamOff : uint32; { current byte offset for streaming / on-demand reads }
DeviceOps : pointer; { PVFSDeviceOps — non-nil for device FDs }
DeviceData : pointer; { opaque data passed to device callbacks }
end;
PFDTable = ^TFDTable;
@@ -114,8 +113,6 @@ begin
entry^.Loaded := false;
entry^.DataSize := 0;
entry^.StreamOff := 0;
entry^.DeviceOps := nil;
entry^.DeviceData := nil;
end;
procedure fd_table_free(table : PFDTable);
@@ -133,10 +133,9 @@ begin
validity := driver.storage.vfs.PathValid(absPath);
if validity <> pvFile then exit;
{ 2. Open the file in stream mode — only reads the bytes we ask for,
avoids pre-loading the entire file just to check a few magic bytes. }
{ 2. Open the file and read the header bytes }
err := eNone;
fh := driver.storage.vfs.OpenFile(absPath, omStream, @err);
fh := driver.storage.vfs.OpenFile(absPath, omReadOnly, wmRewrite, @err);
if fh = 0 then exit;
memset(uint32(@headerBuf[0]), 0, MAX_MAGIC_LEN);
File diff suppressed because it is too large. Load diff
@@ -90,8 +90,6 @@ type
eTooManyOpenFiles, { per-process FD table full }
eInvalidHandle, { TFileHandle does not refer to an open FD }
eNotStreamMode, { SeekFile called on a non-omStream handle }
eFileNotLoaded, { ReadFile on a pre-load handle whose data is not yet loaded }
eAlreadyExists, { generic: target name already exists (symlink, file, etc.) }
{ Disk / capacity errors }
eDiskFull, { FS reports no free clusters/blocks }
@@ -150,17 +148,11 @@ type
PPDeleteFileHook = procedure(volume : PStorage_Volume; filePath : pchar; status : puint32);
PPDeleteDirHook = procedure(volume : PStorage_Volume; path : pchar; status : puint32);
PPIdentifyHook = function(volume : PStorage_Volume) : boolean;
PPRenameFileHook = procedure(volume : PStorage_Volume; filePath : pchar; newName : pchar; status : puint32);
{ Offset-based read: reads byteCount bytes starting at byte offset into the file.
Returns the number of bytes actually read.
Filesystems that do not implement this leave the field nil and VFS falls back
to the load-all readCallback behaviour. }
PPReadOffsetHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; offset : uint32; buffer : puint32; byteCount : uint32) : uint32;
{ Offset-based write: writes byteCount bytes starting at byte offset into the file.
Returns the number of bytes actually written.
Filesystems that do not implement this leave the field nil; VFS returns 0
for stream-mode writes on volume FDs. }
PPWriteOffsetHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; offset : uint32; buffer : puint32; byteCount : uint32) : uint32;
{ === Async filesystem hook core.types ===
Each mirrors the corresponding sync hook but receives a TIOCallback + callbackData.
@@ -235,8 +227,6 @@ type
identifyCallback : PPIdentifyHook;
{ Offset-based read for streaming mode — nil if not implemented }
readOffsetCallback : PPReadOffsetHook;
{ Offset-based write for streaming mode — nil if not implemented }
writeOffsetCallback : PPWriteOffsetHook;
{ Async format — nil if FS only supports synchronous create }
createAsyncCallback : PPCreateAsyncHook;
{ Async variants of the main I/O hooks — nil if FS only supports sync.
@@ -247,7 +237,6 @@ type
readDirAsyncCallback : PPReadDirAsyncHook;
deleteFileAsyncCallback : PPDeleteFileAsyncHook;
deleteDirAsyncCallback : PPDeleteDirAsyncHook;
renameFileCallback : PPRenameFileHook;
end;
{ Generic storage volume }
@@ -266,10 +255,6 @@ type
TDirectory_Entry = record
fileName : pchar;
entryType : TDirectory_Entry_Type;
fileSize : uint32;
modifiedDate : uint16; { FAT-style: bits 15-9=year-1980, 8-5=month, 4-0=day }
modifiedTime : uint16; { FAT-style: bits 15-11=hour, 10-5=min, 4-0=sec/2 }
attributes : uint8; { FS-specific attribute bits }
end;
TDrive_Error = record
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -827,10 +827,6 @@ begin
dirEntry^.entryType := TDirectory_Entry_Type.directoryEntry
else
dirEntry^.entryType := TDirectory_Entry_Type.fileEntry;
dirEntry^.fileSize := fileEntrys[i].size;
dirEntry^.modifiedDate := 0;
dirEntry^.modifiedTime := 0;
dirEntry^.attributes := fileEntrys[i].attribues;
end;
kfree(void(compString));
@@ -562,19 +562,6 @@ begin
else
dirEntry^.entryType := TDirectory_Entry_Type.fileEntry;
dirEntry^.fileSize := rec^.dataLen_LSB;
dirEntry^.attributes := rec^.fileFlags;
{ Convert ISO 9660 date (year-1900,month,day,hour,min,sec) to FAT-style }
if rec^.recDate[0] >= 80 then
dirEntry^.modifiedDate := (uint16(rec^.recDate[0] - 80) shl 9)
or (uint16(rec^.recDate[1]) shl 5)
or uint16(rec^.recDate[2])
else
dirEntry^.modifiedDate := 0;
dirEntry^.modifiedTime := (uint16(rec^.recDate[3]) shl 11)
or (uint16(rec^.recDate[4]) shl 5)
or (uint16(rec^.recDate[5]) shr 1);
offset := offset + rec^.recLen;
end;
@@ -735,7 +722,6 @@ begin
filesystem.createDirCallback := nil;
filesystem.deleteFileCallback := nil;
filesystem.deleteDirCallback := nil;
filesystem.renameFileCallback := nil;
filesystem.readAsyncCallback := nil;
filesystem.readDirAsyncCallback := nil;
+2 -2
View File
@@ -498,13 +498,13 @@ end;
function getWorkingDirectory: pchar;
begin
getWorkingDirectory := driver.storage.vfs.GetWorkingDirectory;
getWorkingDirectory := driver.storage.vfs.getWorkingDirectory;
end;
procedure setWorkingDirectory(str: pchar);
begin
if str <> nil then
driver.storage.vfs.ChangeDirectory(str);
driver.storage.vfs.changeDirectory(str);
end;
{ ---- Halt mechanism ---- }