Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3c164e8af |
No files matched your search
@@ -16,4 +16,3 @@ dockerout.txt
|
||||
AGENTS.md
|
||||
*.log
|
||||
/doc/*.md
|
||||
wasuro
|
||||
@@ -24,7 +24,6 @@ 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
-8
@@ -4,11 +4,4 @@ echo "======================="
|
||||
echo " "
|
||||
echo "Compiling FPC Sources..."
|
||||
echo " "
|
||||
|
||||
# Build -Fu flags for all directories under src/ and wasuro/
|
||||
FU_PATHS=""
|
||||
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 -v0ew -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/* -Fusrc/driver/net/* -Fusrc/driver/bus/* -Fusrc/driver/bus/usb/* -Fusrc/driver/hid/* src/kernel.pas
|
||||
@@ -1,43 +0,0 @@
|
||||
#!/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 /code/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="/code/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 /code
|
||||
|
||||
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 " "
|
||||
+2
-108
@@ -13,120 +13,14 @@
|
||||
// limitations under the License.
|
||||
|
||||
{
|
||||
ContextSwitcher - Custom IRQ0 handler for preemptive context switching.
|
||||
|
||||
Replaces the default ISR_32 with a naked assembly stub that saves the
|
||||
interrupted context (PUSHAD + segment regs), calls a Pascal helper to
|
||||
dispatch timer hooks, send EOI, and run the scheduler, then restores
|
||||
the next process context (or idles) via the returned ESP.
|
||||
ContextSwitcher - Switch Process Contexts when preempted.
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit contextswitcher;
|
||||
|
||||
{$ASMMODE intel}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
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
|
||||
|
||||
{ -----------------------------------------------------------------------
|
||||
do_context_switch_work
|
||||
Pascal helper called from the assembly ISR. Receives the current ESP
|
||||
(pointing to the GS..EFLAGS save area), dispatches timer hooks, sends
|
||||
EOI, runs the scheduler and returns the ESP for the next context.
|
||||
Uses register calling convention: saved_esp in EAX, result in EAX.
|
||||
----------------------------------------------------------------------- }
|
||||
function do_context_switch_work(saved_esp : uint32) : uint32;
|
||||
var
|
||||
next : PProcessContext;
|
||||
begin
|
||||
{ 1. Save ESP into the current process }
|
||||
processmanager.CurrentProcess^.SavedESP := saved_esp;
|
||||
|
||||
{ 2. Dispatch all hooks registered on interrupt 32 (timer hooks).
|
||||
This fires TMR_0_ISR.Main which in turn fires BDA tick,
|
||||
graphics refresh, USB hotplug, etc. }
|
||||
isrmanager.dispatchHooks(32);
|
||||
|
||||
{ 3. Send End-Of-Interrupt to the master PIC }
|
||||
outb($20, $20);
|
||||
|
||||
{ 4. Pick the next process to run (always returns non-nil; idle as fallback) }
|
||||
next := processmanager.scheduler_pick_next;
|
||||
processmanager.CurrentProcess := next;
|
||||
|
||||
{ 5. Return the selected process ESP }
|
||||
do_context_switch_work := next^.SavedESP;
|
||||
end;
|
||||
|
||||
{ -----------------------------------------------------------------------
|
||||
context_switch_isr
|
||||
Naked assembly ISR that replaces ISR_32 (IRQ0 / PIT timer).
|
||||
|
||||
Stack on entry (pushed by CPU):
|
||||
[ESP+8] EFLAGS
|
||||
[ESP+4] CS
|
||||
[ESP+0] EIP
|
||||
|
||||
We push general-purpose and segment registers, call the Pascal helper,
|
||||
switch ESP to the returned value, pop registers and IRETD.
|
||||
----------------------------------------------------------------------- }
|
||||
procedure context_switch_isr; assembler; nostackframe;
|
||||
asm
|
||||
{ Save all general-purpose registers (EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI) }
|
||||
pushad
|
||||
|
||||
{ Save segment registers }
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
|
||||
{ Load kernel data segments }
|
||||
mov ax, $10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
{ Call Pascal helper: EAX = current ESP (register calling convention).
|
||||
Returns new ESP in EAX. }
|
||||
mov eax, esp
|
||||
call do_context_switch_work
|
||||
mov esp, eax
|
||||
|
||||
{ Restore segment registers }
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
|
||||
{ Restore general-purpose registers }
|
||||
popad
|
||||
|
||||
{ Return from interrupt }
|
||||
iretd
|
||||
end;
|
||||
|
||||
{ -----------------------------------------------------------------------
|
||||
init
|
||||
Override IDT gate 32 with our custom ISR. Must be called AFTER
|
||||
isrmanager.init so that the default gate has been set up first.
|
||||
----------------------------------------------------------------------- }
|
||||
procedure init;
|
||||
begin
|
||||
idt.set_gate(32, uint32(@context_switch_isr), $08, ISR_RING_0);
|
||||
tracer.push_trace('contextswitcher.init');
|
||||
end;
|
||||
implementation;
|
||||
|
||||
end.
|
||||
+5
-2
@@ -22,7 +22,7 @@ unit cpu;
|
||||
interface
|
||||
|
||||
uses
|
||||
util, RTC, stdio;
|
||||
util, RTC;
|
||||
|
||||
type
|
||||
PCapabilities_Old = ^TCapabilities_Old;
|
||||
@@ -113,10 +113,12 @@ var
|
||||
CAP_OLD, CAP_NEW : uint32;
|
||||
|
||||
procedure init();
|
||||
procedure Terminal_Command_CPU(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
stdio;
|
||||
|
||||
procedure getCPUIdentifier;
|
||||
var
|
||||
id0, id1, id2 : uint32;
|
||||
@@ -323,6 +325,7 @@ end;
|
||||
|
||||
procedure init();
|
||||
begin
|
||||
stdio.registerCommand('CPU', @Terminal_Command_CPU, 'CPU Info.');
|
||||
CPUID.Capabilities0:= PCapabilities_Old(@CAP_OLD);
|
||||
CPUID.Capabilities1:= PCapabilities_New(@CAP_NEW);
|
||||
getCPUIdentifier;
|
||||
|
||||
@@ -158,9 +158,6 @@ procedure init;
|
||||
{ Unit Tests }
|
||||
procedure UnitTest;
|
||||
|
||||
{ Terminal command }
|
||||
procedure terminal_command_usb(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
implementation
|
||||
|
||||
{ ========================= Globals ========================= }
|
||||
@@ -1103,6 +1100,7 @@ begin
|
||||
CompletionHookCount := 0;
|
||||
for i := 0 to MAX_COMPLETION_HOOKS - 1 do
|
||||
CompletionHooks[i] := nil;
|
||||
stdio.registerCommand('USB', @terminal_command_usb, 'USB subsystem information.');
|
||||
syslog.logln('USB Core', 'INIT END.');
|
||||
pop_trace;
|
||||
end;
|
||||
|
||||
@@ -256,7 +256,6 @@ type
|
||||
OnReceive : TTCPReceiveCallback;
|
||||
OnEvent : TTCPEventCallback;
|
||||
UserData : void;
|
||||
OwnerPID : uint32; { PID of owning process, 0 if none }
|
||||
end;
|
||||
|
||||
TTCB = record
|
||||
|
||||
@@ -25,7 +25,7 @@ uses
|
||||
tracer, lmemorymanager,
|
||||
util, lists,
|
||||
net, nettypes, netutils,
|
||||
eth2, ipv4, stdio;
|
||||
eth2, ipv4;
|
||||
|
||||
type
|
||||
PARPCacheRecord = ^TARPCacheRecord;
|
||||
@@ -41,12 +41,11 @@ procedure sendGratuitous;
|
||||
procedure sendRequest(ip : puint8);
|
||||
procedure send(hType : uint16; pType : uint16; op : uint16; p_context : PPacketContext);
|
||||
function resolveIP(ip : puint8) : puint8;
|
||||
procedure terminal_command_arp(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
strings;
|
||||
stdio, strings;
|
||||
|
||||
var
|
||||
Registered : Boolean = false;
|
||||
@@ -310,6 +309,7 @@ begin
|
||||
writeToLogLn(' L3/ARP: register');
|
||||
Cache:= LL_New(sizeof(TARPCacheRecord));
|
||||
eth2.registerTypePromisc($0806, @recv);
|
||||
stdio.registerCommand('ARP', @terminal_command_arp, 'Get ARP Table.');
|
||||
Registered:= true;
|
||||
end;
|
||||
pop_trace;
|
||||
|
||||
@@ -26,18 +26,17 @@ uses
|
||||
util, strings,
|
||||
net, nettypes, netutils,
|
||||
lists,
|
||||
eth2, stdio;
|
||||
eth2;
|
||||
|
||||
procedure send(p_data : void; p_len : uint16; p_context : PPacketContext);
|
||||
procedure registerProtocol(Protocol_ID : uint8; recv_callback : TRecvCallback);
|
||||
function getIPv4Config : PIPv4Configuration;
|
||||
procedure register;
|
||||
procedure terminal_command_ifconfig(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
arp;
|
||||
arp, stdio;
|
||||
|
||||
var
|
||||
Registered : Boolean = false;
|
||||
@@ -212,6 +211,7 @@ begin
|
||||
end;
|
||||
Config.UP:= false;
|
||||
eth2.registerType($0800, @recv);
|
||||
stdio.registerCommand('IFCONFIG', @terminal_command_ifconfig, 'Configure Network Settings.');
|
||||
Registered:= true;
|
||||
end;
|
||||
pop_trace;
|
||||
|
||||
+86
-10
File diff suppressed because it is too large.
Load diff
@@ -22,7 +22,7 @@ unit tcp;
|
||||
interface
|
||||
|
||||
uses
|
||||
tracer, stdio,
|
||||
tracer,
|
||||
nettypes, netutils,
|
||||
ipv4;
|
||||
|
||||
@@ -33,17 +33,13 @@ function accept(listener : PTCPSocket) : PTCPSocket;
|
||||
function send(socket : PTCPSocket; p_data : void; p_len : uint16) : TTCPError;
|
||||
function close(socket : PTCPSocket) : TTCPError;
|
||||
function abort_connection(socket : PTCPSocket) : TTCPError;
|
||||
procedure terminal_command_tcpconnect(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
procedure terminal_command_tcplisten(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
procedure terminal_command_tcphttp(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
lmemorymanager, util, syslog, rand, lists,
|
||||
net, TMR_0_ISR, bios_data_area,
|
||||
strings, arp,
|
||||
processmanager, proctypes;
|
||||
stdio, strings, arp;
|
||||
|
||||
const
|
||||
TCP_PROTOCOL_ID = $06;
|
||||
@@ -229,7 +225,6 @@ begin
|
||||
sock^.OnReceive := onRecv;
|
||||
sock^.OnEvent := onEvt;
|
||||
sock^.UserData := userData;
|
||||
sock^.OwnerPID := 0;
|
||||
tcb^.Socket := sock;
|
||||
CreateSocket := sock;
|
||||
end;
|
||||
@@ -256,29 +251,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure socket_cleanup(handle : void);
|
||||
var
|
||||
sock : PTCPSocket;
|
||||
begin
|
||||
sock := PTCPSocket(handle);
|
||||
if sock = nil then exit;
|
||||
sock^.OwnerPID := 0; { Prevent DestroySocket from trying to unbind again }
|
||||
abort_connection(sock);
|
||||
end;
|
||||
|
||||
procedure DestroySocket(sock : PTCPSocket);
|
||||
var
|
||||
owner : PProcessContext;
|
||||
begin
|
||||
push_trace('tcp.DestroySocket');
|
||||
if sock <> nil then begin
|
||||
{ Remove resource binding from owning process }
|
||||
if sock^.OwnerPID <> 0 then begin
|
||||
owner := processmanager.findByID(sock^.OwnerPID);
|
||||
sock^.OwnerPID := 0;
|
||||
if owner <> nil then
|
||||
processmanager.unbindResourceNoCleanup(owner, void(sock));
|
||||
end;
|
||||
if sock^.TCB <> nil then begin
|
||||
sock^.TCB^.Socket := nil;
|
||||
DestroyTCB(sock^.TCB);
|
||||
@@ -1393,12 +1369,6 @@ begin
|
||||
|
||||
sock := CreateSocket(tcb, context^.OnReceive, context^.OnEvent, context^.UserData);
|
||||
|
||||
{ Auto-bind socket to calling process for cleanup on process death }
|
||||
if processmanager.CurrentProcess <> nil then begin
|
||||
sock^.OwnerPID := processmanager.CurrentProcess^.ProcessID;
|
||||
processmanager.bindResource(processmanager.CurrentProcess, rkSocket, void(sock), @socket_cleanup);
|
||||
end;
|
||||
|
||||
AddTCB(tcb);
|
||||
|
||||
{ Send SYN (includes MSS option via SendSegment) }
|
||||
@@ -1432,13 +1402,6 @@ begin
|
||||
if tcb^.BacklogMax = 0 then tcb^.BacklogMax := 5; { default backlog }
|
||||
|
||||
sock := CreateSocket(tcb, context^.OnReceive, context^.OnEvent, context^.UserData);
|
||||
|
||||
{ Auto-bind socket to calling process for cleanup on process death }
|
||||
if processmanager.CurrentProcess <> nil then begin
|
||||
sock^.OwnerPID := processmanager.CurrentProcess^.ProcessID;
|
||||
processmanager.bindResource(processmanager.CurrentProcess, rkSocket, void(sock), @socket_cleanup);
|
||||
end;
|
||||
|
||||
AddTCB(tcb);
|
||||
|
||||
listen := sock;
|
||||
@@ -1903,6 +1866,9 @@ begin
|
||||
Connections := DL_New(sizeof(uint32));
|
||||
ipv4.registerProtocol(TCP_PROTOCOL_ID, @ProcessPacket);
|
||||
TMR_0_ISR.hook(uint32(@TimerTick));
|
||||
stdio.registerCommand('TCPCONNECT', @terminal_command_tcpconnect, 'Connect to a TCP host and send Hello World.');
|
||||
stdio.registerCommand('TCPLISTEN', @terminal_command_tcplisten, 'Listen on a TCP port and log received data.');
|
||||
stdio.registerCommand('TCPHTTP', @terminal_command_tcphttp, 'Send HTTP GET to a host IP (port 80 default).');
|
||||
Registered := true;
|
||||
syslog.logln('TCP', 'TCP registered.');
|
||||
end;
|
||||
|
||||
@@ -112,7 +112,6 @@ function get_device_list() : PLinkedListBase;
|
||||
procedure register_filesystem(filesystem : PFilesystem);
|
||||
|
||||
procedure register_volume(device : PStorage_Device; volume : PStorage_Volume);
|
||||
procedure disk_command(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
//function writeNewFile(fileName : pchar; extension : pchar; buffer : puint32; size : uint32) : uint32;
|
||||
//function readFile(fileName : pchar; extension : pchar; buffer : puint32; byteCount : puint32) : puint32;
|
||||
|
||||
@@ -232,6 +231,7 @@ begin
|
||||
setworkingdirectory('.');
|
||||
storageDevices:= ll_new(sizeof(TStorage_Device));
|
||||
fileSystems:= ll_New(sizeof(TFilesystem));
|
||||
stdio.registerCommand('DISK', @disk_command, 'Disk utility');
|
||||
|
||||
pop_trace();
|
||||
end;
|
||||
|
||||
@@ -104,10 +104,6 @@ function GetDirectories(Handle : uint32; Path : pchar) : PHashMap;
|
||||
function PathValid(Path : pchar) : TIsPathValid;
|
||||
function changeDirectory(Path : pchar) : TIsPathValid;
|
||||
function getWorkingDirectory : pchar;
|
||||
function makeAbsolutePathFrom(Path : pchar; BaseDir : pchar) : pchar;
|
||||
function resolvePathFrom(Path : pchar; BaseDir : pchar) : TIsPathValid;
|
||||
function GetDirectoryListingFrom(Path : pchar; BaseDir : pchar) : PHashMap;
|
||||
function changeDirectoryFrom(Path : pchar; BaseDir : pchar; var NewDir : pchar) : TIsPathValid;
|
||||
|
||||
//VFS Functions
|
||||
function newVirtualDirectory(Path : pchar) : TError;
|
||||
@@ -612,67 +608,6 @@ begin
|
||||
tracer.push_trace('vfs.getWorkingDirectory.exit');
|
||||
end;
|
||||
|
||||
function makeAbsolutePathFrom(Path : pchar; BaseDir : pchar) : pchar;
|
||||
var
|
||||
AbsPath : pchar;
|
||||
TempPath : pchar;
|
||||
begin
|
||||
if Path[0] = '/' then
|
||||
AbsPath := stringCopy(Path)
|
||||
else begin
|
||||
if BaseDir[StringSize(BaseDir)-1] <> '/' then
|
||||
TempPath := StringConcat(BaseDir, '/')
|
||||
else
|
||||
TempPath := stringCopy(BaseDir);
|
||||
AbsPath := StringConcat(TempPath, Path);
|
||||
kfree(void(TempPath));
|
||||
end;
|
||||
makeAbsolutePathFrom := AbsPath;
|
||||
end;
|
||||
|
||||
function resolvePathFrom(Path : pchar; BaseDir : pchar) : TIsPathValid;
|
||||
var
|
||||
TempPath : pchar;
|
||||
AbsPath : pchar;
|
||||
begin
|
||||
TempPath := makeAbsolutePathFrom(Path, BaseDir);
|
||||
AbsPath := evaluatePath(TempPath);
|
||||
kfree(void(TempPath));
|
||||
resolvePathFrom := PathValid(AbsPath);
|
||||
kfree(void(AbsPath));
|
||||
end;
|
||||
|
||||
function GetDirectoryListingFrom(Path : pchar; BaseDir : pchar) : PHashMap;
|
||||
var
|
||||
TempPath : pchar;
|
||||
AbsPath : pchar;
|
||||
begin
|
||||
TempPath := makeAbsolutePathFrom(Path, BaseDir);
|
||||
AbsPath := evaluatePath(TempPath);
|
||||
kfree(void(TempPath));
|
||||
GetDirectoryListingFrom := GetDirectoryListing(AbsPath);
|
||||
kfree(void(AbsPath));
|
||||
end;
|
||||
|
||||
function changeDirectoryFrom(Path : pchar; BaseDir : pchar; var NewDir : pchar) : TIsPathValid;
|
||||
var
|
||||
TempPath : pchar;
|
||||
AbsPath : pchar;
|
||||
Validity : TIsPathValid;
|
||||
begin
|
||||
TempPath := makeAbsolutePathFrom(Path, BaseDir);
|
||||
AbsPath := evaluatePath(TempPath);
|
||||
kfree(void(TempPath));
|
||||
Validity := PathValid(AbsPath);
|
||||
if Validity = pvDirectory then
|
||||
NewDir := AbsPath
|
||||
else begin
|
||||
NewDir := nil;
|
||||
kfree(void(AbsPath));
|
||||
end;
|
||||
changeDirectoryFrom := Validity;
|
||||
end;
|
||||
|
||||
{ Terminal Commands }
|
||||
|
||||
procedure VFS_COMMAND_PUSHD(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
@@ -811,8 +746,11 @@ begin
|
||||
//outputln('VFS', makeRelative('/test/mydisk/mything', '/test/mydisk'));
|
||||
//while true do begin end;
|
||||
|
||||
{ LS, CD, PUSHD, POPD are now handled as per-terminal builtins
|
||||
in vterminal.pas so each terminal has its own working directory. }
|
||||
{ Register Terminal Commands }
|
||||
stdio.registerCommand('LS', @VFS_COMMAND_LS, 'List directory contents.');
|
||||
stdio.registerCommand('CD', @VFS_COMMAND_CD, 'Set working directory.');
|
||||
stdio.registerCommand('PUSHD', @VFS_COMMAND_PUSHD, 'Push the working directory.');
|
||||
stdio.registerCommand('POPD', @VFS_COMMAND_POPD, 'Pop the working directory.');
|
||||
|
||||
//ht:= PHashMap(Root^.Reference);
|
||||
//hashmap.add(ht, 'VDirectory', void(newDummyObject(otVDIRECTORY)));
|
||||
|
||||
@@ -21,7 +21,6 @@ uses
|
||||
uidebug,
|
||||
lvgl,
|
||||
video,
|
||||
windows,
|
||||
syslog;
|
||||
|
||||
const
|
||||
@@ -36,7 +35,6 @@ begin
|
||||
TickCounter := TickCounter + 1;
|
||||
if TickCounter >= TICKS_PER_FRAME then begin
|
||||
TickCounter := 0;
|
||||
windows.reapOrphanedWindows;
|
||||
desktop.update;
|
||||
uidebug.update;
|
||||
lvgl_handler;
|
||||
|
||||
@@ -467,7 +467,6 @@ const
|
||||
LV_KEY_PREV = 11;
|
||||
LV_KEY_HOME = 2;
|
||||
LV_KEY_END = 3;
|
||||
LV_KEY_CTRLC = 128; { Ctrl+C — terminal interrupt }
|
||||
|
||||
{ Arc mode }
|
||||
LV_ARC_MODE_NORMAL = 0;
|
||||
@@ -1862,16 +1861,6 @@ begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ Ctrl+C — inject custom key code so focused terminal can handle it }
|
||||
if key_info.is_down_code and key_info.CTRL_DOWN and (key_info.key_code = ord('c')) then begin
|
||||
next_head := (kb_head + 1) mod KB_BUF_SIZE;
|
||||
if next_head <> kb_tail then begin
|
||||
kb_buf[kb_head] := LV_KEY_CTRLC;
|
||||
kb_head := next_head;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ Map Asuro key codes to LVGL key codes }
|
||||
case key_info.key_code of
|
||||
$1B: k := LV_KEY_ESC;
|
||||
|
||||
@@ -11,7 +11,7 @@ unit windows;
|
||||
interface
|
||||
|
||||
uses
|
||||
lvgl, mouse, serial, tracer, processmanager, proctypes;
|
||||
lvgl, mouse, serial, tracer;
|
||||
|
||||
const
|
||||
MAX_WINDOWS = 16;
|
||||
@@ -55,7 +55,6 @@ type
|
||||
on_close : TWinCloseCallback;
|
||||
on_resize : TWinResizeCallback;
|
||||
cursor_obj : Plv_obj; { cursor to keep on top }
|
||||
owner_pid : uint32; { owning process PID; 0 = unowned }
|
||||
end;
|
||||
|
||||
{ Create a new window. Returns window ID (0 = failure). }
|
||||
@@ -82,15 +81,6 @@ function getWindowCount: uint32;
|
||||
{ Set a callback to be notified when a window is resized. }
|
||||
procedure setWindowResizeCallback(win_id: uint32; cb: TWinResizeCallback);
|
||||
|
||||
{ Assign an owning process to a window.
|
||||
When reapOrphanedWindows detects the process has died, the window
|
||||
is automatically closed via its on_close callback. }
|
||||
procedure setWindowOwner(win_id: uint32; pid: uint32);
|
||||
|
||||
{ Check all windows for dead owner processes and close them.
|
||||
Called once per frame from graphicsrefresh. }
|
||||
procedure reapOrphanedWindows;
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
@@ -651,7 +641,6 @@ begin
|
||||
wins[id].on_close := closeCB;
|
||||
wins[id].on_resize := nil;
|
||||
wins[id].cursor_obj := cursor;
|
||||
wins[id].owner_pid := 0;
|
||||
|
||||
{ Bring to front }
|
||||
bringToFront(id);
|
||||
@@ -709,7 +698,6 @@ begin
|
||||
wins[win_id].on_close := nil;
|
||||
wins[win_id].on_resize := nil;
|
||||
wins[win_id].cursor_obj := nil;
|
||||
wins[win_id].owner_pid := 0;
|
||||
|
||||
tracer.pop_trace;
|
||||
end;
|
||||
@@ -758,36 +746,4 @@ begin
|
||||
wins[win_id].on_resize := cb;
|
||||
end;
|
||||
|
||||
{ ============================================================
|
||||
Public: set window owner PID
|
||||
============================================================ }
|
||||
procedure setWindowOwner(win_id: uint32; pid: uint32);
|
||||
begin
|
||||
if (win_id < 1) or (win_id > MAX_WINDOWS) then exit;
|
||||
if wins[win_id].state = wsNone then exit;
|
||||
wins[win_id].owner_pid := pid;
|
||||
end;
|
||||
|
||||
{ ============================================================
|
||||
Public: reap windows whose owning process has died
|
||||
============================================================ }
|
||||
procedure reapOrphanedWindows;
|
||||
var
|
||||
i : uint32;
|
||||
ctx : PProcessContext;
|
||||
begin
|
||||
for i := 1 to MAX_WINDOWS do begin
|
||||
if wins[i].state = wsNone then continue;
|
||||
if wins[i].owner_pid = 0 then continue;
|
||||
ctx := processmanager.findByID(wins[i].owner_pid);
|
||||
if (ctx = nil) or (ctx^.State = psFinished) or (ctx^.State = psError) then begin
|
||||
{ Owner is dead — trigger close callback or destroy directly }
|
||||
if wins[i].on_close <> nil then
|
||||
wins[i].on_close(i)
|
||||
else
|
||||
destroyWindow(i);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -72,8 +72,6 @@ procedure register_driver(Driver_Name : PChar; DeviceID : PDeviceIdentifier; Loa
|
||||
procedure register_driver_ex(Driver_Name : PChar; DeviceID : PDeviceIdentifier; Load_Callback : TDriverLoadCallback; force_load : boolean);
|
||||
procedure register_device(Device_Name : PChar; DeviceID : PDeviceIdentifier; ptr : void);
|
||||
|
||||
procedure terminal_command_dev(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
|
||||
var
|
||||
Root : PDriverRegistration = nil;
|
||||
Dev : PDeviceRegistration = nil;
|
||||
@@ -330,6 +328,10 @@ end;
|
||||
procedure init;
|
||||
begin
|
||||
push_trace('driver_management.init');
|
||||
stdio.registerCommand('DEV', @terminal_command_dev, 'Driver Management Interface.');
|
||||
//stdio.registerCommand('DRIVERSEX', @terminal_command_driversex, 'List all available drivers.');
|
||||
//stdio.registerCommand('DRIVERS', @terminal_command_drivers, 'List loaded drivers.');
|
||||
//stdio.registerCommand('DEVICES', @terminal_command_devices, 'List devices.');
|
||||
pop_trace;
|
||||
end;
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
{
|
||||
ProcTypes - Type definitions for the preemptive process management system.
|
||||
|
||||
Defines process states, system messages, context records, and resource
|
||||
bindings used by processmanager.pas and contextswitcher.pas.
|
||||
|
||||
@author(Kieron Morris <kjm@kieronmorris.me>)
|
||||
}
|
||||
unit proctypes;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
stdio;
|
||||
|
||||
const
|
||||
{ 8 KB per-process kernel stack }
|
||||
PROCESS_STACK_SIZE = 8192;
|
||||
|
||||
{ Base quantum multiplier: quantum = Priority * BASE_QUANTUM ticks }
|
||||
BASE_QUANTUM = 8;
|
||||
|
||||
type
|
||||
{ Forward declaration }
|
||||
PProcessContext = ^TProcessContext;
|
||||
|
||||
{ Process states }
|
||||
TProcessState = (
|
||||
psCreated, { Allocated, stack prepared, not yet scheduled }
|
||||
psRunning, { Currently executing on the main thread }
|
||||
psReady, { Runnable but not the current process }
|
||||
psSuspended, { Paused - will not be scheduled }
|
||||
psAwaiting, { Blocked on I/O or event - will not be scheduled }
|
||||
psFinished, { Terminal state - safe to reap }
|
||||
psError { Unrecoverable error - safe to reap }
|
||||
);
|
||||
|
||||
{ System messages delivered to processes }
|
||||
TProcessSysMsg = (
|
||||
smNone, { No message }
|
||||
smTerminate, { Graceful shutdown requested }
|
||||
smKill, { Immediate forced shutdown }
|
||||
smSuspend, { Pause execution }
|
||||
smResume, { Resume from suspended }
|
||||
smInput, { New data available on stdin }
|
||||
smChildExited, { A child process has exited }
|
||||
smCustom { User-defined message (payload in MsgData) }
|
||||
);
|
||||
|
||||
{ Process entry point - a procedure that IS the process.
|
||||
When this procedure returns, the process is finished. }
|
||||
TProcessEntryPoint = procedure(ctx : PProcessContext);
|
||||
|
||||
{ Resource binding types }
|
||||
TResourceKind = (
|
||||
rkSocket, { TCP/UDP socket }
|
||||
rkTimer, { A timer hook }
|
||||
rkFileHandle, { VFS file descriptor }
|
||||
rkCustom { Arbitrary pointer }
|
||||
);
|
||||
|
||||
{ Resource cleanup callback }
|
||||
TResourceCleanup = procedure(handle : void);
|
||||
|
||||
PResourceBinding = ^TResourceBinding;
|
||||
TResourceBinding = record
|
||||
Kind : TResourceKind;
|
||||
Handle : void;
|
||||
Cleanup : TResourceCleanup;
|
||||
end;
|
||||
|
||||
{ Process context - the core data structure for each process }
|
||||
TProcessContext = record
|
||||
{ Identity }
|
||||
ProcessID : uint32;
|
||||
Name : array[0..31] of char;
|
||||
ParentID : uint32;
|
||||
|
||||
{ State }
|
||||
State : TProcessState;
|
||||
ExitCode : uint32;
|
||||
|
||||
{ StdIO - per-process I/O buffers }
|
||||
StdIn : POutBuf;
|
||||
StdOut : POutBuf;
|
||||
StdErr : POutBuf;
|
||||
|
||||
{ Entry point }
|
||||
EntryPoint : TProcessEntryPoint;
|
||||
|
||||
{ Context switch state }
|
||||
SavedESP : uint32;
|
||||
StackBase : void;
|
||||
StackTop : uint32;
|
||||
|
||||
{ Scheduling }
|
||||
Priority : uint8;
|
||||
Quantum : uint16;
|
||||
TicksUsed : uint16;
|
||||
|
||||
{ System messages }
|
||||
PendingMsg : TProcessSysMsg;
|
||||
MsgData : void;
|
||||
|
||||
{ Resource bindings (PDList of TResourceBinding) }
|
||||
Resources : void;
|
||||
|
||||
{ User-defined state }
|
||||
Local : void;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
+16
-201
File diff suppressed because it is too large.
Load diff
Loaded 20 of 29 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user