home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_09_03
/
9n03035a
< prev
next >
Wrap
Text File
|
1990-12-07
|
6KB
|
170 lines
title multask.s
name mtask
*********************************************************************
*
* NAME :
*
* DESCRIPTION : multasking routines for the motorola 68xx series
* of microcomputers
*
* init_task(task#, task_address) /* called from system mode */
* continue_task(task#) /* called from system mode */
* suspend() /* called from task mode */
*
* The task_mode flag to keep track of which mode is in effect
* allows the use of subroutines hat are called by both system
* and task code. If those subroutines call suspend(). then in
* the case of a system mode caller syspend() must return con-
* trol immediately.
*
*********************************************************************/
* COMMON DEFINITIONS */
stksize equ 255
tasks equ 4
xref SF ;Stack Frame
SECTION DATA,?,DATA
sys_stk dw 0
sys_sf dw 0
task_num dw 0
task_mode db 0
tstk dw 0 ; temporary stack storage
task_tab ds tasks*2 ; tasks words
fram_tab ds tasks*2 ; frame words
SECTION STACK,?,DATA
xdef _task_stks, task_stks
_task_stks
task_stks ds stksize*(tasks+1)
pad2 dw 0 ; end boundry for data
xdef _sp?
_sp?: DS 2
pad3 dw 0 ; end boundry for stacks
SECTION PROGRAM_CODE,?,CODE
xdef init_task?
xdef continue_task?
xdef suspend?
*********************************************************************
*
* NAME : init_task(task_number, task_address)
*
* DESCRIPTION: initializes the task specified by the task address
* saves the stack pointer into sys_stack
* saves the task number into task_num
* calculates the beginning of the task's stack
* loads the stack pointer with the results of the preceeding
* calculation
* sets task_mode to one to indicate that we are in task mode
* push address of callsus to new stack in case the task returns
* this prepares the return address of a hung task that re-
* peatedly gives up control by calling suspend
* this routine drops through to suspend.
* so in effect this routine sets up a task with a stack then
* prepares the stack for the next call as if it were running
* then suspends itself.
*
init_task?:
sts sys_stk ; Save the system stack
std task_num ; save parameter task number for later
ldd SF ; get stack frame pointer and save into
std sys_sf ; system variable
ldd task_num
ldaa #stksize ; make calculation of task_num times
mul ; stack size then add to beginning
addd #(task_stks+stksize) ; of stack pool
std tstk ; put d into temporary stack storage
lds tstk ; get new stack from temp. stack storage
subd #3 ; adjust frame pointer for next routine
std SF ; load new stack frame pointer
inc task_mode ; put us into task mode
ldd #callsus ; get address of suspend and
pshb ; load it into the new stack
psha ;
pshx ; save stack into new stack
* fall through to next routine (suspend)
*********************************************************************
*
* NAME : suspend()
*
* DESCRIPTION: suspend the current task by saving the current stack
* stack pointer into the task table and then getting the
* system stack and transfer control to the system, setting
* task mode to 0 and start executing the next task in the
* master while loop in main.
*
suspend?: ; see if we are in task mode if s?o
tst task_mode ; go to suspend task
bne sustsk ; else return
rts
sustsk:
ldd task_num ; get the task number and multiply by two
lsld ; for indexing purposes into the task table
ldx #task_tab
abx
sts x ; store the stack into the proper table entry
ldx #fram_tab ; get address of frame table and store SF
abx ; into indexed address of frame table array
ldd SF
std x
lds sys_stk ; restore the system stack
ldd sys_sf ; restore stack frame pointer
std SF
clr task_mode ; go into system mode
rts ; and return
*********************************************************************
*
* NAME : continue(task_number)
*
* DESCRIPTION: continues the task specified by the task number
* get the task number in the task table
* loads the stack pointer at the table index
* set task mode to one indication we are task mode
* and returns
*
*
continue_task?:
sts sys_stk ; store the stack
std task_num ; save into variable task_num
ldd SF
std sys_sf
ldd task_num
lsld ; multiply task number by 2
ldx #task_tab ; get address of tasktable into index
abx ; add (task num * 2) + table address
lds x ; load new stack into sp
ldx #fram_tab ; get the task's frame pointer and update
abx ; the frame pointer
ldd x
std SF
inc task_mode ; set task mode to task
rts ; return ( to new task)
*********************************************************************
*
* NAME : callsus
*
* DESCRIPTION: this routine is in case the task returns all the way
* back to the main routine.
*
callsus:
bsr suspend?
bra callsus
end