 **************************************************************************
;
; Filename : TASK.ASM
; -------------------
;
; (c) 1991 by Thomas Lehmann
;
;
; Jackophone V5.00
;
;
; Routinen zur Task Verwaltung
;
;
; Services:	task_sleep	Task setzt für X-Male aus (Accu)
;	task_delay	Task schläft für X-10mS (Accu)
;	task_wait	Task wartet auf ein Ereignis
;	nxt_task	nächste Task wird aktiviert
;
;**************************************************************************

MODUL_START	set	*	; Größe des Moduls berechnen



; =========================================================================
;
; Funktion	: Task`s initialisieren (definieren)
;
; Eingang	: --------
;
; Ausgang	: --------
;
; Register	: Accu, X, Y
;
; (c) by Thomas Lehmann Januar 1991
;
; =========================================================================

task_def
	block
	tsx		; akt. Stackpointer retten
	stx hlp_reg

	; Task definieren
	; ---------------
	ldy #$00	; Ptr. auf Task Adresse
	stz task_nr	; Tasknr.
	lda #STK_INIT	; Stackende der 1. Task

loop	clc		; Stackptr. für Task ermitteln
	adc task_tab,y	; Stackgröße der Task
	tax		; Stackptr. für Task stellen
	txs

	; Taskadr. initialisieren
	; -----------------------
	iny		; Ptr. auf Taskadr. stellen
	ldx task_tab+1,y	; Taskadr. auf den Stack
	phx
	ldx task_tab,y
	phx

	tsx		; Stackpointer für Task holen (Adr. über RTS)
	phy		; Ptr. auf Tasktabelle retten
	ldy task_nr	; Tasknr. laden
	inc task_nr	; nächste Task einstellen
	stx task_sp,y	; Stackptr. für Task einstellen
	phx		; X-Reg. retten
	phy		; Tasknummer nach Y-Reg.
	plx
	stz task_event,x	; Task wartet auf kein Ereignis
	plx		; X-Reg. zurück
	cpy #ANZ_TASK-1	; alle Task`s definiert ?
	bcs end		; ja, Ende

loop_1	ply		; Ptr. auf Tasktabelle zurück
	iny		; Ptr. auf nächsten Eintrag
	iny
	bra loop	; und nächste Task definieren


	; Task-Definition beenden
	; -----------------------
end	stz task_nr	; 1. Task einstellen
	ldx hlp_reg
	txs		; Stackpointer richten
	rts
	bend



	; ------------------------------
	; Aufbau der Task-Tabelle:
	; Stack-Size, Startadr. der Task
	; ------------------------------
task_tab	byte	STK_TAST
	rta	tast_task	; Tastaturabfrage

	byte	STK_MAIN
	rta	main_task	; Hauptschleife

	byte	STK_UPD
	rta	update_task	; Schalten von Ereignissen, Ports ...

	byte	STK_EXTCMD
	rta	extcmd_task	; Auswertung der Cmd.`s von serieller




; =========================================================================
;
; Funktion	: Task setzt für x-Male aus
;
; Eingang	: Anzahl der "Aussetzter" im Accu
;
; Ausgang	: ----------
;
; Register	: ----------
;
; (c) by Thomas Lehmann Januar 1991
;
; =========================================================================

task_sleep	phy
	ldy task_nr	; akt. Task ermitteln
	sta task_sl_cnt,y	; Anzahl der Aussetzter für Task eintragen
	ply
	bra nxt_task	; und nächste Task aktivieren



; =========================================================================
;
; Funktion	: Task schläft X-10mS
;
; Eingang	: Anzahl der 10mS Aussetzer im Accu
;
; Ausgang	: ----------
;
; Register	: Accu
;
; (c) by Thomas Lehmann Januar 1991
;
; =========================================================================

task_delay	phy
	ldy task_nr		; aktive Task holen
	sta struct_tim+TASK_TIM_O,y	; Timer starten

delay_lp	lda #10			; Anzahl der Aussetzter
	jsr task_sleep		; Task schlafen legen
	lda struct_tim+TASK_TIM_O,y	; Timerwert laden
	bne delay_lp		; nicht abgelaufen, weiter warten

	ply
	rts


; =========================================================================
;
; Funktion	: Task wartet auf Ereignis
;
; Eingang	: low/high Adresse für das Ereignis in X/Y-Reg.
;	  Ereignis im Accu
;
; Ausgang	: ----------
;
; Register	: ----------
;
; (c) by Thomas Lehmann Juni 1991
;
; =========================================================================

task_wait	phx
	ldx task_nr	; akt. Task ermitteln
	sta task_event,x	; Ereignis für Task eintragen
	txa
	asl		; Offset auf Event Adresse
	tax
	sty task_ev_adr+1,x ; high Byte der Adresse eintragen
	ply		; low Byte der Adresse (X-Reg.) laden
	sty task_ev_adr,x	; und eintragen

	bra nxt_task	; nächste Task aktivieren


; =========================================================================
;
; Funktion	: nächste Task aktivieren
;
; Eingang	: Funktion muß mit JSR aufgerufen werden (Reaktivierung)
;
; Ausgang	: ----------
;
; Register	: ----------
;
; (c) by Thomas Lehmann Januar 1991
;
; =========================================================================

nxt_task	phy		; Y-Reg. retten
	ldy task_nr	; aktuelle Task laden

	; Zustand der Register retten
	; ---------------------------
	sta task_reg_a,y	; Accu merken
	stx task_reg_x,y	; X-Reg. merken
	plx		; Y-Reg. vom Stack
	stx task_reg_y,y	; Y-Reg. merken
	tsx		; Stackpointer holen
	stx task_sp,y	; Stackptr. merken


	; nächste Task ermitteln
	; ----------------------
get_nxt_tsk	inc task_nr	; nächste Task einstellen
	ldx task_nr	; aktuelle Task laden
	cpx #ANZ_TASK	; sind alle Task gelaufen ?
	bcc nxt_task_1	; nein

	stz task_nr	; wieder 1. Task einstellen
	ldx #00


	; Register wiederherstellen
	; -------------------------
nxt_task_1	lda task_sl_cnt,x	; darf Task geweckt werden ?
	beq nxt_task_2	; ja

	dec task_sl_cnt,x	; Anzahl der Aussetzter nachführen
	bra get_nxt_tsk	; nächste Task ermitteln


	; Ereignis für Task checken
	; -------------------------
nxt_task_2	lda task_event,x	; wartet Task auf ein Ereignis ?
	beq nxt_task_3	; nein, Task aktivieren

	phx
	txa
	asl		; Offset auf Event Adresse
	tax
	lda (task_ev_adr,x) ; Zustand der Ereignisadr. laden
	plx
	bit task_event,x	; ist Ereignis eingetreten ?
	beq get_nxt_tsk	; nein, weiter warten

	stz task_event,x	; Task wartet nicht mehr auf ein Ereignis


	; nächste Task aktivieren
	; -----------------------
nxt_task_3	phx		; Tasknummer nach Y-Reg.
	ply
	ldx task_sp,y	; Stackptr. holen
	txs		; Stackpointer setzten
	lda task_reg_y,y	; Y-Reg. holen
	pha
	lda task_reg_a,y	; Accu holen
	ldx task_reg_x,y	; X-Reg. holen
	ply		; Y-Register holen
	rts		; Rücksprungadr. auf dem Stack








; --------------------------------------------------------------------------

HLP	set	*
_TASK	equ	HLP-MODUL_START		; Größe des Moduls

