DEFINITION MODULE IKS; (*# save, call(c_conv => off) *) (****************************************************************) (* *) (* This is a stripped-down version of the module *) (* called InnerKernel, with support for interrupt *) (* tasks removed. *) (* *) (* By removing the interrupt support, we achieve a *) (* large reduction in code complexity. Note that *) (* interrupt handlers can still be written and used, *) (* but since the kernel does not know about them *) (* they have to be implemented as procedures rather *) (* than as tasks. *) (* *) (* For the sake of additional readibility, we assume *) (* that we are using the TopSpeed Extra Large memory *) (* model: multiple code segments, multiple data *) (* segments, and separate stack segments. (That is, *) (* all intermodule pointers are long.) This allows us *) (* to delete some of the conditional compilation. *) (* *) (* Note the extensive use of compiler pragmas to specify *) (* which registers parameters are passed in. *) (* *) (* Programmer: P. Moylan *) (* Last edited: 1 April 2004 *) (* Status: OK *) (* *) (****************************************************************) FROM Types IMPORT (* type *) FarPointer; TYPE (**) TaskSelector = FarPointer; FloatSaveSelector = CARDINAL; (************************************************************************) (*# call(reg_saved => (bx,cx,dx,si,di,ds,es,st1,st2)) *) PROCEDURE EnterKernel (): CARDINAL; (* Saves the processor flags word, including the current "interrupt *) (* enable" status, and returns with interrupts disabled. *) (* NOTE: this procedure and the following one should be used as a *) (* matched pair. *) (*# call(reg_param => (ax), reg_saved => (ax,bx,cx,dx,si,di,ds,es,st1,st2)) *) PROCEDURE LeaveKernel (PSW: CARDINAL); (* Restores the processor flags word, including the "interrupt *) (* enable" status. NOTE: this procedure and the one above should *) (* be used as a matched pair. *) (*# call(reg_return => (bx,es), reg_saved => (dx,si,di,ds,st1,st2)) *) (*# call(reg_param => (ax,bx,cx,dx)) *) PROCEDURE TaskInit (StackBase: ADDRESS; StackSize: CARDINAL; EnableInterrupts: BOOLEAN; TaskExit, StartAddress: PROC): TaskSelector; (* Initialises the stack for a new task. Parameter StackBase *) (* points to a block of memory which can be used to hold the stack *) (* (note that this is a pointer to the start of the memory block, *) (* not to the bottom of the stack); and StackSize is the size of *) (* this block. The next parameter specifies whether processor *) (* interrupts should be enabled when the task is started. *) (* StartAddress and TaskExit are the start address of the task code *) (* and the start address of the code to execute when the task *) (* terminates. The value returned is a selector for the new task. *) (*# call(reg_saved => (ax,cx,dx,si,di,ds,st1,st2)) *) PROCEDURE InitMainTask (): TaskSelector; (* Like TaskInit, but for the special case of the original task *) (* which is running at program startup. The function of this *) (* procedure is simply to ensure that the main stack layout is *) (* consistent with what we do for all other tasks. *) (*# call(reg_saved => (ax,bx,cx,dx,si,di,ds,es,st1,st2)) *) (*# call(reg_param => (si, ds, ax, bx)) *) PROCEDURE Transfer (VAR (*OUT*) source: TaskSelector; destination: TaskSelector); (* Performs a task switch to the destination task, at the same time *) (* saving a selector for the outgoing task in variable "source". *) (* This allows a subsequent call to Transfer to resume the *) (* original task. By the time this procedure has returned to the *) (* caller, then, we are again executing the calling task. *) (*# call(reg_param => (ax,bx), reg_return => (bx)) *) PROCEDURE MakeFloatSaveSelector (selector: TaskSelector): FloatSaveSelector; (* Creates the special form of selector which must subsequently be *) (* used in calls to save and restore the floating point state. *) (* The parameter supplied must be the value of the task selector *) (* as created by TaskInit. *) PROCEDURE NPXsave (selector: FloatSaveSelector); (* Saves the state of the Numeric Processor Extension coprocessor. *) PROCEDURE NPXrestore (selector: FloatSaveSelector); (* The operation complementary to NewNPXsave. Restores the *) (* previously saved state of the floating point coprocessor. *) (*# restore *) PROCEDURE PrepareForShutdown; (* This procedure is needed just before executing the "exit from *) (* program" operation, and is provided to get around a problem *) (* with some memory models in TopSpeed version 3. (With other *) (* compilers, this can afford to be a dummy procedure.) *) (* A (deliberate) side-effect of calling this procedure is that *) (* the stack is corrupted, so do NOT call it except as the final *) (* step of termination processing. *) END IKS.