        .globl  cpq,cpqt,pst,ps,n
        .globl  schdl,dispch
;
; Subroutine SCHDL:
;
; Dieses Unterprogramm wird von der sich selbst unterbrechenden Task
; TU mit JSR PC,SCHDL aufgerufen.
;
schdl:  jsr     pc,save         ; Register sichern
        jsr     pc,inslas       ; Einreihen von TU in die CPQ
        add     #2,sp           ; Stackkorrektur
;
; Einsprungstelle DISPCH:
;
; Programme, die fertig sind, enden mit JMP DISPCH. Als erstes soll
; die naechste abzuarbeitende Task TN gefunden werden.
;
dispch: mov     #cpq-2,r0
dislp:  add     #2,r0
        tstb    (r0)            ; Null-Eintrag ?
        beq     dislp           ;   ja
        cmpb    (r0),ps+15      ; TU = TN ?
        beq     dislp           ;   ja
        movb    (r0),r1
        jsr     pc,unchn        ; TN aus CPQ entfernen
        asl     r1              ; Finde PST-Eintrag
        add     #pst,r1         ;   von TN
        mov     (r1),r0         ; R0 zeigt auf Anfang des PS
        add     #8,r0           ; R0 zeigt hinter PC-Eintrag in PS
        mov     #1,2(r0)        ; Running-Zustand markieren
        mov     -(r0),-(sp)     ; PC auf Stack schreiben
        mov     -(r0),r5
        mov     -(r0),r4
        mov     -(r0),r3
        mov     -(r0),r2
        mov     -(r0),r1
        mov     -(r0),r0
        rts     pc
;
; Subroutine UNCHN:
;
; UNCHN streicht TN (R1 = ID) aus CPQT und aktualisiert CPQ.
;
unchn:  movb    r1,r2           ; R2 := ID von TN
        asl     r2              ; R2 := R2 * 2 (Wort)
        add     #cpqt+1,r2      ; R2 zeigt auf CPQT-Eintrag von TN
        movb    (r2),r3         ; Nachfolger-ID nach R3
        movb    r3,(r0)         ; CPQ aktualisieren
        tstb    r3              ; R3 = 0 (TN hat keinen Nachfolger) ?
        beq     unchend         ;   ja
        asl     r3              ; CPQT-Eintrag des Nachfolgers
        add     #cpqt,r3        ;   finden
        movb    #0,(r3)         ; kein Vorgaenger
unchend:rts     pc
;
; Subroutine SAVE:
;
; SAVE wird von SCHDL aufgerufen und sichert die Register R0 bis R5
; und PC im Bereich PS.
;
save:   mov     r0,ps
        mov     #ps+2,r0
        mov     r1,(r0)+
        mov     r2,(r0)+
        mov     r3,(r0)+
        mov     r4,(r0)+
        mov     r5,(r0)+
        mov     2(sp),(r0)+
;
; R0 zeigt jetzt auf den 8. Eintrag des PS (ID).
;
        mov     #2,2(r0)        ; Pending markieren
        rts     pc
;
; Subroutine INSLAS:
;
inslas: mov     #cpq+1,r1       ; R1 zeigt auf CPQ-Anfang
        add     2(r0),r1        ; Prioritaet addieren
        add     2(r0),r1        ; zweimal wegen Wortbreite
        movb    (r1),r2         ; R2 enthaelt entsprechenden CPQ-Eintrag
        movb    1(r0),(r1)      ; neuen letzten Task in CPQ eintragen
        asl     r2              ; R2 := R2 * 2 wegen Wortbreite
        add     #cpqt+1,r2      ; R2 zeigt jetzt auf das Warteschlangenende
        movb    1(r0),(r2)      ; neuer Nachfolger (statt 0)
        movb    1(r0),r2        ; finde Position von
        asl     r2              ;   Task TU in CPQT
        add     #cpqt,r2
        movb    (r1),(r2)+      ; Vorgaenger eintragen
        movb    #0,(r2)         ; kein Nachfolger
        rts     pc
