; NOYAU MULTITACHE POUR 68000

; type: Round robin preemptif
; rem: initialiser le vecteur de l'IT vec l'adresse de "noyau"
; pour les systemes autres que TOS

EXEC    equ     0
SUSP    equ     1
DORM    equ     2
PRET    equ     3

CODE    equ     0
PILE    equ     4
ETAT    equ     PILE+4
PRIO    EQU     ETAT+2
NEXT    EQU     PRIO+2

        pea     0
        move    #$20,-(sp)
        trap    #1
        addq.l  #4,sp

        move.l  $70,old_70              sauve ancien vecteur IT

        move.l  process,a0              tache initiale
suivant
        move.l  NEXT(a0),a1             prochain dscripteur
        cmp.l   process,a1              premiere tache du RR?
        beq     fin_init                non, init son contexte
        bsr     inittache
        bra     suivant

fin_init
        bsr     inittache               derniere tache du RR
        move    #$2700,sr               masque tte les IT
        move.l  #noyau,$70              vecteur VBL
        move.l  process,a0
        move.l  PILE(a0),sp             restaure pile tache initiale
        move    #$2300,sr               lance le noyau

        move.l  CODE(a0),a0             a0->code de la tache
        jmp     (a0)                    demarre tache initiale

fin
        move.l  old_70,$70
        move    #7,-(sp)
        trap    #1
        addq.l  #2,sp
        move    #$666,$ff8240
        clr     $ff8246
        pea     0
        trap    #1

inittache
        move.l  PILE(a0),a1             a1->pile de la tache
        move.l  CODE(a0),-(a1)          empile @ du code
        move    #$2300,-(a1)            empile SR
        sub.l   #60,a1                  60 octets pour les registres
        move.l  a1,PILE(a0)             sauve @ du haut de la pile
        move.l  NEXT(a0),a0             a0->descripteur suivant
        rts

noyau
        subq    #1,process+4            -1 tick pour la tache en cours
        bne     rte                     continue tache
        movem.l d0-d7/a0-a6,-(sp)       sauve contexte tache interrompue
        move.l  process,a0              a0->descripteur tache en cours
        move.l  sp,PILE(a0)             sauvegarde pile
nexttache
        move.l  NEXT(a0),a0             prochain descripteur
        cmp     #EXEC,ETAT(a0)          tache en execution?
        bne     nexttache               non, inutile de lui donner la main
        move.l  a0,process              donne la main
        move.l  PRIO(a0),process+4      initialise quantuum
        move.l  PILE(a0),sp             restaure pile
        movem.l (sp)+,d0-d7/a0-a6       et contexte
rte     rte                             reprend execution

        include taches.s

        data

process
        dc.l    p0                      process initial
        dc.w    1                       quantuum restant

p0      dc.l    tache0                  ptr code
        dc.l    pile0                   ptr pile
        dc.w    EXEC                    etat
        dc.w    5                       quantuum
        dc.l    p1                      descripteur suivant

p1      dc.l    tache1
        dc.l    pile1
        dc.w    EXEC
        dc.w    10
        dc.l    p2

p2      dc.l    tache2
        dc.l    pile2
        dc.w    EXEC
        dc.w    20
        dc.l    p3

p3      dc.l    tache3
        dc.l    pile3
        dc.w    EXEC
        dc.w    30
        dc.l    p4

p4      dc.l    tache4
        dc.l    pile4
        dc.w    EXEC
        dc.w    40
        dc.l    p0


        bss

old_70  ds.l    1                       sauve vecteur VBL

        ds.l    500                     piles lifo montantes
pile0   ds.l    500
pile1   ds.l    500
pile2   ds.l    500
pile3   ds.l    500
pile4
