" S1 .. = 0 t = 0 orig: hlt " overwritten with interrupt return addr jmp pibreak " dispatch to interrupt processing . = orig+7 " real time (60Hz) clock -1 " -1 will cause "clock overflow" on next tick " Overflow is checked by "clsf" instr " in PI service (pibreak) routine, " reset to -1 after tick handling " results in an interrupt every "jiffy" . = orig+020 " syscall (CAL) and user "interrupt" processing 1f " addr for "CAL I": store return here on "CAL" iof " here on CAL: interrupts off dac u.ac " save user AC lac 020 " save user return addr dac 1f " save as if "CAL I" lac 1f-1 dac 020 " restore location 20 lac u.ac " restore user AC jmp 1f+1 " join "CAL I" processing 1f " literal to restore location 20 1: 0 " "CAL I" PC stored here iof " interrupts off dac u.ac " save user AC in user area lacq dac u.mq " save user MQ in user area lac 8 dac u.rg " save user auto-index location 8 in uarea lac 9 dac u.rg+1 " save auto-index location 9 in user area jms copy; 10; u.rg+2; 6 " save auto-index locations 10-15 (using 8/9!) lac 1b " load user PC dac u.rg+8 " save in user area -1 " load -1 dac .savblk " set "save" flag (cleared by disk I/O?) dac .insys " set "in system" flag lac uquant " load user quantum (tick) count jms betwen; d0; maxquant " check if between 0 & maxquant (30 jiffies) jms swap " no: quantum expired: swap process out ion " interrupts on -1 tad u.rg+8 " get address of system call jms laci " load system call instruction jms betwen; o20001; swn " range check (expects CAL I!) jmp badcal " bad system call tad swp " add "jmp syscall_table_base" dac .+1 " save as next instruction jmp .. i " dispatch system call . = orig+0100 jmp coldentry " here to start kernel jms halt okexit: dzm u.ac " 'OK' system call exit: clear user AC sysexit: " common system call exit code ion " enable interrupts lac .savblk " load "save" flag sza " is zero (cleared by disk I/O)? jmp 1f " no: no disk I/O done? jms copy; sysdata; dskbuf; 64 " copy system data to disk buffer cla jms dskio; 07000 " save to disk? 1: dzm .insys " clear "in system call" flag jms chkint " pending user interrupt? skp " no, return to user jmp .save " yes: dump core jms copy; u.rg+2; 10; 6 " restore auto-index locations 10-15 (use 8/9) lac u.rg+1 " restore auto-index location 9 dac 9 lac u.rg " restore auto-index location 8 dac 8 lac u.mq " restore MQ register lmq lac u.ac " restore AC register jmp u.rg+8 i " return to user " scheduler / swapper / idle loop swap: 0 ion 1: jms lookfor; 3 " out/ready jmp 1f jms lookfor; 1 " in/ready skp jmp 1b " loop until a process becomes ready dzm maxquant " in/ready (self?): come back next tick! jmp 3f 1: " here with out/ready process dac 9f+t " save process pointer (swapped out) in t0 jms lookfor; 2 " in/notready " find a swapped in process to swap out? jmp 1f jms lookfor; 1 " in/ready jmp 1f jmp 2f 1: lac swap dac u.swapret " return to caller when swapped back iof lac o200000 " change status to swapped out tad u.ulistp i dac u.ulistp i ion jms dskswap; 07000 " swap process out lac u.dspbuf sna " process using display?? jmp 2f " no law dspbuf " reset to default display buffer jms movdsp 2: iof " disable interrupts lac o600000 " change status (1->7?????) tad 9f+t i dac 9f+t i ion " enable interrupts jms dskswap; 06000 " read process in? lac u.swapret " set our return addr dac swap " to saved return addr lac o20 " reset maxquant to 16 ticks (149.333ms) dac maxquant lac u.dspbuf sza " using display? "** 01-s1.pdf page 4 jms movdsp " yes. switch to user display bufferx 3: dzm uquant " reset process tick count iof jmp swap i " return t = t+1 swp: " system call dispatch table jmp . " base instruction .save; .getuid; .open; .read; .write; .creat; .seek; .tell .close; .link; .unlink; .setuid; .rename; .exit; .time; .intrp .chdir; .chmod; .chown; badcal; .sysloc; badcal; .capt; .rele .status; badcal; .smes; .rmes; .fork swn: .-swp-1 i " last system call number: "CAL I n" " AC/ new value for intflg (non-zero to ignore interrupt char) " sys intrp .intrp: lac u.ac dac u.intflg jmp okexit " syscall to retrieve system addresses (data & routines!!) " AC/ index (1..17) " sys sysloc " AC/ address (or -1 on bad index) .sysloc: lac u.ac and o17777 jms betwen; d1; locn jms error tad locsw dac .+1 lac .. dac u.ac jmp sysexit locsw: " table of system addresses for sysloc lac . iget; inode; userdata; sysdata; copy; copyz; betwen; dskrd dskwr; dskbuf; dpdata; namei; pbsflgs; alloc; free; dspdata crdata locn: .-locsw-1 " check if "interrupt" for current process " checks .int1 and .int2 (contain i-number of interrupt source) " compared against process stdin " " call: " .insys/ 0 " jms chkint " " chkint: 0 lac .insys sza " in system? jmp chkint i " yes: return lac .int1 " get inumber of interrupt1 source? sna " zero? jmp 1f " yes: skip stdin check sad u.ofiles+2 " non-zero: compare to stdin inumber jmp 2f " same 1: lac .int2 " get inum of interrupt 2 source? sna " zero? jmp chkint i " yes: return sad u.ofiles+2 " non-zero: compare to stdin inumber skp " match! jmp chkint i " no match: return dzm .int2 " clear int2 source jmp 1f 2: dzm .int1 " clear int1 source 1: "** 01-s1.pdf page 5 lac u.intflg " get user intflg sza " zero? jmp chkint i " no: ignore -1 dac .insys " set "in system" flag ion " enable interrupts isz chkint " give skip return jmp chkint i