equi

A self-descriptive stack-based PC platform
git clone git://git.luxferre.top/equi.git
Log | Files | Refs | README | LICENSE

commit 132dcedc9e14ce02705eca7b746b5e40df3800f8
parent 30d901e29d4015b0d2889c88808f9c31675658f9
Author: Luxferre <lux@ferre>
Date:   Sun, 14 Aug 2022 09:18:54 +0300

Implemented task privileges

Diffstat:
Mequi.c | 26++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/equi.c b/equi.c @@ -98,11 +98,12 @@ struct CLTEntry { /* one entry in the compilation lookup table */ struct EquiCtx { /* one Equi program context */ ushort id; /* task ID */ uchar active; /* 0 - inactive/quit, 1 - active */ + uchar privileged; /* whether or not the task is allowed to write to the entire command buffer */ uchar CM; /* compilation mode flag */ uchar IM; /* interpretation mode flag */ - uchar lsp; /* literal stack pointer */ ushort msp; /* main stack pointer */ ushort rsp; /* return stack pointer */ + ushort lsp; /* literal stack pointer */ ushort cltp; /* compilation lookup table pointer */ ushort cbp; /* compilation buffer pointer */ ushort gpd_start; /* GPD area start for this task */ @@ -344,16 +345,16 @@ ushort tobig(ushort val) { /* Task-based memory address jump checker */ uchar taskMemJumpAllowed(addr) { - /* task 0 is allowed to jump anywhere in the command buffer, others only in their own zone */ - if(curtask->id) - return (addr >= curtask->cmd_start) && (addr < curtask->cmd_start + curtask->cmd_size); - else + /* a privileged task is allowed to jump anywhere in the command buffer, others only in their own zone */ + if(curtask->privileged) return addr >= ram.cmd_start; + else + return (addr >= curtask->cmd_start) && (addr < curtask->cmd_start + curtask->cmd_size); } /* Task-based memory address write checker */ uchar taskMemWriteAllowed(addr) { - /* task 0 is allowed to write anywhere in the command buffer, others only in their own zone */ + /* a privileged task is allowed to write anywhere in the command buffer, others only in their own zone */ return (addr >= curtask->gpd_start && addr < (curtask->gpd_start + GPD_AREA_SIZE)) || taskMemJumpAllowed(addr); } @@ -426,8 +427,11 @@ struct EquiCtx* equi_find_next_task() { } /* Task loader method */ -struct EquiCtx* equi_load_task(ushort len, ushort progStart) { +struct EquiCtx* equi_load_task(uchar priv, ushort len, ushort progStart) { ushort tid = equi_find_free_task_slot(); + /* don't allow to load privileged tasks from non-privileged ones */ + if(curtask && !curtask->privileged) + priv = 0; struct EquiCtx *taskptr = &ram.tasks[tid]; /* refer to the next available entry */ taskptr->msp = taskptr->rsp = taskptr->lsp = taskptr->cltp = 0; /* init stacks and CLT */ taskptr->pc = progStart - 1U; /* init program counter for preincrement logic */ @@ -436,6 +440,7 @@ struct EquiCtx* equi_load_task(ushort len, ushort progStart) { taskptr->id = tid; /* assign task ID */ taskptr->gpd_start = (ushort) (taskptr->gpd - flatram); /* assign GPD area start */ taskptr->CM = 0; /* unset compilation mode flag */ + taskptr->privileged = priv; /* set privileged flag */ return taskptr; } @@ -658,9 +663,10 @@ void equi_main_loop() { case INS_PERSIST_WRITE: /* ( blk len maddr -- status) */ pushMain(persistOp(pfd, popMain(), popMain(), popMain(), 1)); break; - case INS_TASKLOAD: /* ( addr len -- ) */ - newtaskptr = equi_load_task(popMain(), popMain()); + case INS_TASKLOAD: /* ( addr len priv -- taskid ) */ + newtaskptr = equi_load_task(popMain(), popMain(), popMain()); newtaskptr->active = 1; + pushMain(newtaskptr->id); break; default: /* all characters not processed before are invalid instructions */ trapout(INVALID_INSTRUCTION); @@ -743,7 +749,7 @@ int main(int argc, char* argv[]) { cputc(LF); /* echo LF */ } ram.cmdbuf[++ram.ibp] = INS_QUIT; /* end program with INS_QUIT */ - curtask = equi_load_task(ram.ibp+1, (ushort)ram.cmd_start); /* load the code as task 0 */ + curtask = equi_load_task(1, ram.ibp+1, (ushort)ram.cmd_start); /* load the code as task 0 - always privileged */ ram.taskid = curtask->id; /* actualize the current task id */ curtask->active = 1; /*activate the current task */ equi_main_loop(); /* and run the interpreter loop */