;****************************************************************************
;* Copyright 1991 MBARI                                                     *
;****************************************************************************
;* $Header: dispatch.s,v 4.4 2001/06/19 12:13:23 oasisa Exp $		    *
;* Summary  : Assembly language dispatcher for 80C196 Multitasking Library  *
;* Filename : dispatch.s						    *
;* Author   : Robert Herlien						    *
;* Project  : OASIS Mooring Controller                                      *
;* $Revision: 4.4 $							    *
;* Created  : 06/05/91                                                      *
;*									    *
;* MBARI provides this documentation and code "as is", with no warranty,    *
;* express or implied, of its quality or consistency. It is provided without*
;* support and without obligation on the part of the Monterey Bay Aquarium  *
;* Research Institute to assist in its use, correction, modification, or    *
;* enhancement. This information should not be published or distributed to  *
;* third parties without specific written permission from MBARI.            *
;*									    *
;****************************************************************************
;
$TITLE("Dispatcher")
;
DISPATCH	MODULE

$INCLUDE(..\C196\INCLUDE\8096.INC)
$INCLUDE(OASIS.INC)

;*****************************************************************************
;		PUBLIC and EXTERNAL Declarations
;
		CSEG
PUBLIC	do_dispatch		;Dispatcher entry point

EXTRN	ready_delayed_tasks:ENTRY ;C Routine to ready delayed tasks

		RSEG
PUBLIC 	port			
PUBLIC	sermode

port:		dsw	1		;Default serial port
sermode:	dsw	1		;Serial port mode
	;Port and sermode are special variables:  they get saved/restored
	;during task swap, so they're always valid


		OSEG

EXTRN	ready_list:null			;Ready list
EXTRN	delay_list:null			;Delay list
EXTRN	?FRAME01:word			;C Frame pointer


		DSEG


;*****************************************************************************
; Task Descriptor offsets.  MUST agree with definitions in taskLib.h
;
TD_SP		equ	14		;Place to save SP in task desc

		CSEG

;*****************************************************************************
; DO_DISPATCH - Task Dispatcher
;	    	Save old task context, restore new task context
;		Does not manipulate ready list.  Assumes that was already
;		  done, and it just dispatches head of ready list.
;
; void do_dispatch( TaskDesc *td )

do_dispatch:
	ld	plmreg, 2[SP]			;Get ptr to TD to save
	cmp	plmreg, R0			;NULL task?
	be	disp1				;If NULL, skip reg save code
	push	port				;Save task default serial port
	push	sermode				;Save task serial mode
	push	?FRAME01			;Save task frame pointer
	st	SP, TD_SP[plmreg]		;Save task SP

disp1:
	lcall	ready_delayed_tasks		;Check for delayed tasks done
	cmp	ready_list, R0			;Any ready tasks?
	bne	disp2				;If yes, dispatch 1st one
	ei
	cmp	delay_list, R0			;Sanity check.  Any del tasks?
	bne	disp1				;If no, something's wrong
	rst					;  start over
disp2:
	ld	SP, TD_SP[ready_list]		;Restore new task's SP
	pop	?FRAME01			;Restore new task's frame ptr
	pop	sermode				;Restore task serial mode
	pop	port				;Restore task dflt serial port

	ret					;Return to new task context

		END
