// mos in Rz // new data structure for process queue // update 8 Feb 2025 Q, qq // Q process queue, qq points to currentp in Q nump // number of active process currentp // current process newp() return malloc(16) newStack() return malloc(64) newFrame() return malloc(64) // function prototype new(v) appendL(L,a) enqueue(p) // put p in process queue nump = nump + 1 e = new(p) appendL(Q,e) // add it to the end of queue e[1] = Q[0] // make list circular dequeue() // dequeue the current process nump = nump - 1 p = currentp p[3] = 0 // mark it not-active createp(ads) p = newp() // new PCB p[0] = ads // p.PC p[1] = newStack()+16 // p.SP, offset for initial popm p[2] = newFrame() // p.FP p[3] = 1 // p.state, ready enqueue(p) return p nextQ() qq = qq[1] // next return qq[0] // get p nextp() // next process from process queue p = nextQ() while( p[3] == 0 ) // not ready p = nextQ() return p terminate() // terminate the current process asm("di #0") dequeue() asm("int #0") // task switch // task switch // use r1 but it will be restore // store state PC,SP,FP in PCB #noframe int0() asm("di #0") asm("trap sp #15") // save currentp context asm("push sp rads") // save link register asm("push sp retval") // save retval register asm("ld r1 currentp") // save current process asm("st r31 @0 r1") // p.PC = RetAds asm("st sp @1 r1") // p.SP = sp asm("st fp @2 r1") // p.FP = fp if(nump == 0) asm("trap r0 #0") // no process, stop simulation currentp = nextp() // update currentp asm("ld r1 currentp") // restore next process asm("ld r31 @0 r1") // restore p.PC asm("ld sp @1 r1") // restore p.SP asm("ld fp @2 r1") // restore p.FP asm("pop sp retval") // restore retval asm("pop sp rads") // restore link asm("trap sp #16") // restore context boot() currentp = newp() // zeroth process not in Q asm("int #0") // run task in Q // ---- manage list ----- freelist new(v) // get a cell if( freelist == 0 ) a = malloc(2) else a = freelist freelist = a[1] // next a[0] = v a[1] = 0 return a free(a) // free a cell a[1] = freelist freelist = a // single link list with header // header[0] points to head of list // header[1] points to end of list appendL(L,a) // append list L with cell a if( L[0] == 0 ) // empty list L[0] = a else b = L[1] // L.end b[1] = a // link end to a L[1] = a // update L.end deleteL(L) // delete head from L a = L[0] // L.head b = L[1] // L.end if( a == b ) // singleton L[0] = 0 // empty L[1] = 0 else L[0] = a[1] // update L.head to next p = a[0] free(a) return p // function prototype clock1() clock2() main() asm("di #0") nump = 0 freelist = 0 Q = malloc(2) // make a list header p = createp(&clock1) p = createp(&clock2) qq = Q[0] // point to Q head settimer0(200) boot() // ------------- applications ---------- cnt1, cnt2 clock1() cnt1 = 0 while(1) cnt1 = cnt1 + 1 print(cnt1) doze() clock2() cnt2 = 100 while(1) cnt2 = cnt2 + 1 print(cnt2) doze() // ------------------------------------------