extension of s21 with interrupt and support instructions
int xop 23 int r1
(r1 as int number), software int
reti xop 24 return from int
savr xop 25 savr r1 r2 (r1 as
sp)
resr xop 26 resr r1 r2 (r1 as
sp)
where savr/resr
save/restore registers r0..r15
to stack (M[sp])
interrupt vectore stored at 1000
Here is some example how to write interrupted routines.
Let make one process, do the counting of a global variable "cnt".
The main program is actually an empty loop but it also terminates the
program when the count reach 10. The process is an interrupt service
routine (ISR). When an interrupt occurs, ISR is called and executed
to the instruction "reti" then it will return to main.
:main
mv r1 #isr
st r1 1000 ;; set up int vector
mv r1 #0
st r1 cnt ;; cnt = 0
:loop
;; this is almost empty loop
ld r1 cnt
eq r2 r1 #10
jf r2 loop
trap stop
:isr
;; must not use r1
ld r3 cnt
add r3 r3 #1
st r3 cnt
reti
If the interrupt occurs every n instructions, then the program will take
10*n*(time in irs) instructions before it terminates.
Compare the above program to this plain count to 10 program.
:main
mv r1 #0
st r1 cnt
:loop
ld r1 cnt
add r1 r1 #1
st r1 cnt
eq r2 r1 #10
jf r2 loop
trap stop
This program will take 10*(time in loop) instructions to complete.
Now suppose we break the counting routine into two and make it so that 2
interrupts are required to complete one counting. We have to change the
interrupt vector dynamically in order to schedule the next instruction
when the interrupt occurs. Meanwhile we have to save all registers to make
the ISR re-entrant.
:main
mv r1 #isr1
st r1 1000 ;; set int vec
mv r1 #0
st r1 cnt ;; cnt = 0
:loop
;; this is almost empty loop
ld r1 cnt
eq r2 r1 #10
jf r2 loop
trap stop
;; the counting routine is split into two
:isr1
ld r3 cnt
add r3 r3 #1
savr sp
mv r3 #isr2
st r3 1000 ;; change interrupt
vector
reti
:isr2
resr sp
st r3 cnt
mv r3 #isr1
st r3 1000 ;; change int vec
reti
:process1
....
... <- int1
:L1
....
... <- int3
:process2
...
...
... <- int2
:L2
...
:tswitch (an isr)
save next PC (of the current process)
savr
(of the current process)
get next process
resr
(of the next process)
restore PC (of the next process)
reti
(return directly to PC of next process)
savt r1 xop 27 save return-address to r1
rest r1 xop 28 restore ret-ads from r1
:tswitch
savt r3 ;; save current process PC to r3
savr sp
mv sp #nextPCB ;; pointer to data of next process
resr sp
rest r3 ;; restore next process PC to
return-address
reti