DEFINITION MODULE InnerKernel; (****************************************************************) (* *) (* THIS IS A SPECIAL VERSION OF INNERKER.DEF, WHICH *) (* FORCES PARAMETERS TO BE PASSED ON THE STACK. *) (* *) (****************************************************************) (*# module(implementation=>off,init_code=>off) *) (*# call(reg_param=>()) *) (****************************************************************) (* *) (* This is the nonportable part of the PMOS kernel. *) (* It contains procedures whose implementation depends *) (* not only on the processor, but also on compiler *) (* conventions (which registers are saved, etc.). *) (* *) (* This file is the definition module for the "portable" *) (* version based on Wirth-style coroutine operations. *) (* The only real difference between this file and the *) (* standard PMOS version of InnerKer.DEF is that the *) (* compiler pragmas are stripped out of this version. *) (* *) (* Programmer: P. Moylan *) (* Last edited: 16 March 1995 *) (* Status: Working *) (* *) (****************************************************************) FROM Types IMPORT (* type *) FarPointer; TYPE TaskSelector = FarPointer; FloatSaveSelector = CARDINAL; (************************************************************************) 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. *) 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. *) 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. *) 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. *) 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. *) (* Special case: if this procedure is called by an interrupt task, *) (* the call is interpreted as a requiring a task switch from the *) (* interrupted task - i.e. the source parameter must specify the *) (* interrupted task - to the destination task. In this case the *) (* actual switch to the destination task does not happen until the *) (* interrupt task makes its next call to IOTransfer. The reason *) (* for this interpretation is that task switching to and from *) (* interrupt tasks is managed internally by this module; the *) (* occurrence of an interrupt is not something that can be *) (* controlled by the caller. *) PROCEDURE IOTransfer; (* May be called only from an interrupt task. Performs a task *) (* switch from the current interrupt task to the task which it *) (* interrupted. Unlike Transfer, no parameters are required *) (* because (a) the selector for the destination task is already *) (* known to this module, having been saved at the time of the *) (* interrupt; and (b) selectors for interrupt tasks are maintained *) (* directly by this module rather than by the caller. *) PROCEDURE StartInterruptTask (TS: TaskSelector; InterruptNumber: CARDINAL); (* Starts an interrupt task by running its initialisation section *) (* - i.e. everything up to the first IOTransfer - and arranging *) (* that from then on it will be activated by the given interrupt. *) PROCEDURE DisconnectFromInterrupt (TS: TaskSelector); (* Restores the interrupt vector to which TS was connected to its *) (* state before TS was established as an interrupt task. (N.B. The *) (* result could be chaotic if there was no previous call to *) (* StartInterruptTask.) *) 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. *) END InnerKernel.