diff --git a/Examples/Standard/Interrupt/KernelTrap.asm.txt b/Examples/Standard/Interrupt/KernelTrap.asm.txt
new file mode 100644
index 0000000..fc46f21
--- /dev/null
+++ b/Examples/Standard/Interrupt/KernelTrap.asm.txt
@@ -0,0 +1,279 @@
+; KernelTrap: Implement some trap operations for user defined kernel
+; Implement process breaks using timer interrupt
+; Sigma16: https://jtod.github.io/home/Sigma16  John O'Donnell, 2024
+
+;**********************************************************************
+; Kernel
+;**********************************************************************
+
+;----------------------------------------------------------------------
+; Initialize kernel
+;----------------------------------------------------------------------
+
+; Prepare interrupt vector
+     lea    R1,intVector[R0]      ; address of vector
+     putctl R1,vect               ; initialize vector register
+; Enable timer interrupt
+;     lea    R1,timerBit[R0]       ; flag for timer interrupt
+;     putctl R1,mask               ; set interrupt mask
+
+; Initialize PCB
+     load   R3,InitProcStatus[R0] ; initial status for user process
+     lea    R1,PCBA[R0]           ; pointer to Process A PCB
+     lea    R2,ProcessA[R0]       ; initial pc
+     store  R2,PCBpc[R1]          ; save initial pc in PCB
+     store  R3,PCBstatus[R1]      ; save initial process status
+
+; Select Process A as first process to run
+     lea     R1,PCBA[R0]          ; pointer to PCB for Process A
+     store   R1,CurrentPCBptr[R0] ; will run Process A
+
+;----------------------------------------------------------------------
+; Give time slice to current process
+;----------------------------------------------------------------------
+
+GiveTimeSlice
+; Resume process
+     load    R1,CurrentPCBptr[R0] ;
+     load    R2,PCBpc[R1]         ;
+     putctl  R2,ipc               ;
+     load    R2,PCBir[R1]
+     putctl  R2,iir
+     load    R2,PCBadr[R1]
+     putctl  R2,iadr
+     load    R2,PCBstatus[R1]     ;
+     putctl  R2,istat             ;
+     restore R1,R15,8[R1]         ; restore process registers
+     resume                       ; transfer to running process
+
+;----------------------------------------------------------------------
+; User kernel trap
+;----------------------------------------------------------------------
+
+HandleUserTrap
+
+; Save the state of the interrupted process
+     store  R1,PrimarySaveR1[R0]  ; save R1 so handler can use it
+     load   R1,CurrentPCBptr[R0]  ; get address of current PCB
+     save   R2,R15,9[R1]          ; save R2-R15 in current PCB
+     load   R2,PrimarySaveR1[R0]  ; get back the value of R1
+     store  R2,PCBR1[R1]          ; and save it in the PCB
+     getctl R2,ipc                ;
+     store  R2,PCBpc[R1]          ;
+     getctl R2,iir
+     store  R2,PCBir[R1]
+     getctl R2,iadr
+     store  R2,PCBadr[R1]
+
+; Obtain trap operands
+; get the trap code and use it to index the user trap vector
+;     load    R2,PCBpc[R1]         ; the trap instruction  save ir???
+     load    R2,PCBir[R1]         ; the trap instruction
+     extract R3,3,0,R2,11         ; R4 := ir.d
+     lea     R4,PCBR0[R1]         ; register file array in PCB
+     add     R5,R4,R3             ; PCB index of R[ir.d]
+     load    R6,0[R5]             ; R5 := R[ir.d]
+     shiftr  R7,R6,8              ; R7 = left half of the trap code
+     shiftl  R8,R7,1              ; jump table entries are 2 words
+     jump    UserTrapVector[R8]   ; go to trap handler for code
+
+;----------------------------------------------------------------------
+; Halt
+;----------------------------------------------------------------------
+
+KernelDone
+     trap   R0,R0,R0             ; halt the machine
+
+;----------------------------------------------------------------------
+; Interrupt vector
+;----------------------------------------------------------------------
+
+intVector
+     jump   HandleTimerInterrupt[R0]
+     jump   HandleSegFault[R0]
+     jump   HandleStackFault[R0]
+     jump   HandleUserTrap[R0]
+     jump   HandleOverflow[R0]
+     jump   HandleZdiv[R0]
+
+UserTrapVector
+     jump   HandleTrap00ff
+     jump   HandleTrap01ff
+     jump   HandleTrap02ff
+     jump   HandleTrap03ff
+     jump   HandleTrap04ff
+     jump   HandleTrap05ff
+
+HandleTrap00ff
+     add    R0,R0,R0
+     jump   GiveTimeSlice[R0]
+
+HandleTrap01ff
+     add    R0,R0,R0
+     jump   GiveTimeSlice[R0]
+
+HandleTrap02ff
+     add    R0,R0,R0
+     jump   GiveTimeSlice[R0]
+
+HandleTrap03ff
+     add    R0,R0,R0
+     jump   GiveTimeSlice[R0]
+
+HandleTrap04ff
+     add    R0,R0,R0
+     jump   GiveTimeSlice[R0]
+
+HandleTrap05ff
+     add    R0,R0,R0
+     jump   GiveTimeSlice[R0]
+
+; The following exceptions are not expected, and if they occur they
+; will terminate the program
+
+HandleTimerInterrupt
+HandleSegFault
+HandleStackFault
+HandleOverflow
+HandleZdiv
+     trap    R0,R0,R0
+
+;----------------------------------------------------------------------
+; Process Control Block (PCB) format
+;----------------------------------------------------------------------
+
+PCBsize        equ  32 ; allow space for additional fields
+PCBid          equ   0
+PCBrunning     equ   1
+PCBterminated  equ   2
+PCBpc          equ   3
+PCBir          equ   4
+PCBadr         equ   5
+PCBstatus      equ   6
+PCBR0          equ   7 ; used only for indexing Reg[i]
+PCBR1          equ   8
+PCBR2_15       equ   9 ; 14 words
+
+;----------------------------------------------------------------------
+; Kernel software parameters
+;----------------------------------------------------------------------
+
+; Kernel trap codes
+ReqTerm         equ    $00ff
+
+;----------------------------------------------------------------------
+; Machine hardware parameters
+;----------------------------------------------------------------------
+
+; Status register control bit indices
+userStateBit    equ    $0001   ; bit index 0
+intEnable       equ    $0002   ; bit index 1
+
+; Interrupt control bit indices
+timerBit        equ    $0001   ; bit index 0
+segFaultBit     equ    $0002   ; bit index 1
+stackOverBit    equ    $0004   ; bit index 2
+stackUnderBit   equ    $0008   ; bit index 3
+userTrapBit     equ    $0010   ; bit index 4
+overflowBit     equ    $0020   ; bit index 5
+zDivBit         equ    $0040   ; bit index 6
+
+;----------------------------------------------------------------------
+; Kernel data
+;----------------------------------------------------------------------
+
+; Kernel constants
+InitProcStatus data  $0002  ; user state, interrupts enabled
+
+; Kernel variables
+SliceCount     data    0  ; # time slices granted so far
+SliceLimit     data   50  ; limit on # of time slices
+interval       data  100  ; timer interval
+PrimarySaveR1  data    0  ; temporary save R1 after interrupt
+CurrentPCBptr  data    0  ; ptr to PCB for running process
+
+; Reserve space for process control blocks
+PCBA           reserve  PCBsize
+
+;**********************************************************************
+; Process A
+;**********************************************************************
+
+ProcessA
+     lea   R5,$03ff[R0]  ; user trap code 3
+     lea   R10,24[R0]
+     lea   R8,25[R0]
+     trap  R5,R10,R8
+     add   R0,R0,R0
+     
+     lea   R2,$01ff[R0]  ; user trap code 1
+     lea   R3,80[R0]
+     lea   R4,90[R0]
+     trap  R2,R3,R4
+     add   R0,R0,R0
+
+     trap  R0,R0,R0
+
+; Data for Process A
+limitA   data  16000          ; number of iterations for Process A
+Acount   data      0
+
+
+
+; deprecated
+;----------------------------------------------------------------------
+; Handle timer interrupt
+;----------------------------------------------------------------------
+
+;HandleTimerInterrupt
+
+; Save the state of the interrupted process
+     store  R1,PrimarySaveR1[R0]  ; save R1 so handler can use it
+     load   R1,CurrentPCBptr[R0]  ; get address of current PCB
+     save   R2,R15,9[R1]          ; save R2-R15 in current PCB
+     load   R2,PrimarySaveR1[R0]  ; get back the value of R1
+     store  R2,PCBR1[R1]          ; and save it in the PCB
+     getctl R2,ipc                ;
+     store  R2,PCBpc[R1]          ;
+     getctl R2,iir
+     store  R2,PCBir[R1]
+     getctl R2,iadr
+     store  R2,PCBadr[R1]
+
+; At this point, the full state of the user process is saved in its
+; PCB, and the kernel can use all the registers
+
+; Choose process to run (just Process A in this example)
+; chosen
+     lea    R3,PCBA[R0]           ; else choose process A
+     store R3,CurrentPCBptr[R0]   ; R3 contains address of chosen PCB
+     jump  GiveTimeSlice[R0]      ; run the chosen process
+
+; GiveTimeSlice redundant
+; Stop if limit of time slices has been reached
+     load    R1,SliceCount[R0]    ; R1 := SliceCount
+     lea     R2,1[R0]             ; R2 := 1
+     add     R1,R1,R2             ; SliceCount := SliceCount + 1
+     store   R1,SliceCount[R0]    ; save SliceCount
+     load    R3,SliceLimit[R0]    ; R3 := SliceLimit
+     cmp     R1,R3                ; if SliceCount > SliceLimit
+     jumpgt  KernelDone[R0]       ; then goto KernelDone
+
+; end of HandleUserTrap
+; This code is moot, handler will go to GiveTimeSlice
+; Resume process with new time slice (perhaps be more fair?)
+     load    R1,CurrentPCBptr[R0] ;
+     load    R2,PCBpc[R1]         ;
+     putctl  R2,ipc               ;
+     load    R3,PCBstatus[R1]     ;
+     putctl  R3,istat             ;
+;     load    R4,interval[R0]      ; timer interval
+;     timeron R4                   ;
+     restore R1,R15,8[R1]         ; restore process registers
+     resume                       ; transfer to running process
+
+     store   R0,SliceCount[R0]    ; initialize SliceCount := 0
+
+;     load    R4,interval[R0]      ; timer interval
+;     timeron R4                   ;
+;     timeroff
diff --git a/Examples/Standard/Interrupt/MutexNeeded.asm.txt b/Examples/Standard/Interrupt/MutexNeeded.asm.txt
new file mode 100644
index 0000000..df3e52e
--- /dev/null
+++ b/Examples/Standard/Interrupt/MutexNeeded.asm.txt
@@ -0,0 +1,286 @@
+; NeedMutex: Run two concurrent processes that need mutex but lack it
+; Implement process breaks using timer interrupt
+; Sigma16: https://jtod.github.io/home/Sigma16  John O'Donnell, 2024
+
+;**********************************************************************
+; Kernel
+;**********************************************************************
+
+;----------------------------------------------------------------------
+; Initialize kernel
+;----------------------------------------------------------------------
+
+; Prepare interrupt vector
+     lea    R1,intVector[R0]      ; address of vector
+     putctl R1,vect               ; initialize vector register
+; Enable timer interrupt
+     lea    R1,timerBit[R0]       ; flag for timer interrupt
+     putctl R1,mask               ; set interrupt mask
+
+; Initialize PCBs
+     load   R3,InitProcStatus[R0] ; initial status for user process
+
+     lea    R1,PCBA[R0]           ; pointer to Process A PCB
+     lea    R2,ProcessA[R0]       ; initial pc
+     store  R2,PCBpc[R1]          ; save initial pc in PCB
+     store  R3,PCBstatus[R1]      ; save initial process status
+
+     lea    R1,PCBB[R0]           ; pointer to Process A PCB
+     lea    R2,ProcessB[R0]       ; initial pc
+     store  R2,PCBpc[R1]          ; save initial pc in PCB
+     store  R3,PCBstatus[R1]      ; save initial process status
+
+     store   R0,SliceCount[R0]    ; initialize SliceCount := 0
+
+; Select Process A as first process to run
+     lea     R1,PCBA[R0]          ; pointer to PCB for Process A
+     store   R1,CurrentPCBptr[R0] ; will run Process A
+
+
+;----------------------------------------------------------------------
+; Give time slice to current process
+;----------------------------------------------------------------------
+
+GiveTimeSlice
+
+; Stop if limit of time slices has been reached
+     load    R1,SliceCount[R0]    ; R1 := SliceCount
+     lea     R2,1[R0]             ; R2 := 1
+     add     R1,R1,R2             ; SliceCount := SliceCount + 1
+     store   R1,SliceCount[R0]    ; save SliceCount
+     load    R3,SliceLimit[R0]    ; R3 := SliceLimit
+     cmp     R1,R3                ; if SliceCount > SliceLimit
+     jumpgt  KernelDone[R0]       ; then goto KernelDone
+
+; Start timer and resume process
+     load    R1,CurrentPCBptr[R0] ;
+     load    R2,PCBpc[R1]         ;
+     putctl  R2,ipc               ;
+     load    R3,PCBstatus[R1]     ;
+     putctl  R3,istat             ;
+     load    R4,interval[R0]      ; timer interval
+     timeron R4                   ;
+     restore R1,R15,5[R1]         ; restore process registers
+     resume                       ; transfer to running process
+
+;----------------------------------------------------------------------
+; Handle timer interrupt
+;----------------------------------------------------------------------
+
+HandleTimerInterrupt
+
+; Save the state of the interrupted process
+     store  R1,PrimarySaveR1[R0]  ; save R1 so handler can use it
+     load   R1,CurrentPCBptr[R0]  ; get address of current PCB
+     save   R2,R15,6[R1]          ; save R2-R15 in current PCB
+     load   R2,PrimarySaveR1[R0]  ; get back the value of R1
+     store  R2,PCBR1[R1]          ; and save it in the PCB
+     getctl R2,ipc                ;
+     store  R2,PCBpc[R1]          ;
+
+; At this point, the full state of the user process is saved in its
+; PCB, and the kernel can use all the registers
+
+; Choose process to run
+     load   R1,CurrentPCBptr[R0]  ;
+     lea    R2,PCBA[R0]           ; R2 := pointer to Process A PCB
+     cmp    R1,R2                 ; if CurrentPCB is Process A
+     jumpeq chooseB[R0]           ; then goto choose Process B
+chooseA
+     lea    R3,PCBA[R0]           ; else choose process A
+     jump   chosen[R0]
+chooseB
+     lea   R3,PCBB[R0]            ; choose process B
+
+chosen
+     store R3,CurrentPCBptr[R0]   ; R3 contains address of chosen PCB
+     jump  GiveTimeSlice[R0]      ; run the chosen process
+
+;----------------------------------------------------------------------
+; Halt
+;----------------------------------------------------------------------
+
+KernelDone
+     trap   R0,R0,R0             ; halt the machine
+
+;----------------------------------------------------------------------
+; Interrupt vector
+;----------------------------------------------------------------------
+
+intVector
+     jump   HandleTimerInterrupt[R0]
+     jump   handleSegFault[R0]
+     jump   handleStackFault[R0]
+     jump   handleUserTrap[R0]
+     jump   handleOverflow[R0]
+     jump   handleZdiv[R0]
+
+; The following exceptions are not expected, and if they occur they
+; will terminate the program
+
+handleSegFault
+handleStackFault
+handleUserTrap
+handleOverflow
+handleZdiv
+     trap    R0,R0,R0
+
+
+;----------------------------------------------------------------------
+; Process Control Block (PCB) format
+;----------------------------------------------------------------------
+
+PCBsize        equ  32
+PCBid          equ   0
+PCBrunning     equ   1
+PCBterminated  equ   2
+PCBpc          equ   3
+PCBstatus      equ   4
+PCBR1          equ   5
+PCBR2_15       equ   6
+
+;----------------------------------------------------------------------
+; Kernel software parameters
+;----------------------------------------------------------------------
+
+; Kernel trap codes
+ReqTerm         equ    $00ff
+
+;----------------------------------------------------------------------
+; Machine hardware parameters
+;----------------------------------------------------------------------
+
+; Status register control bit indices
+userStateBit    equ    $0001   ; bit index 0
+intEnable       equ    $0002   ; bit index 1
+
+; Interrupt control bit indices
+timerBit        equ    $0001   ; bit index 0
+segFaultBit     equ    $0002   ; bit index 1
+stackOverBit    equ    $0004   ; bit index 2
+stackUnderBit   equ    $0008   ; bit index 3
+userTrapBit     equ    $0010   ; bit index 4
+overflowBit     equ    $0020   ; bit index 5
+zDivBit         equ    $0040   ; bit index 6
+
+;----------------------------------------------------------------------
+; Kernel data
+;----------------------------------------------------------------------
+
+; Kernel constants
+InitProcStatus data  $0002  ; user state, interrupts enabled
+
+; Kernel variables
+SliceCount     data    0  ; # time slices granted so far
+SliceLimit     data   50  ; limit on # of time slices
+interval       data  100  ; timer interval
+PrimarySaveR1  data    0  ; temporary save R1 after interrupt
+CurrentPCBptr  data    0  ; ptr to PCB for running process
+
+; Reserve space for process control blocks
+PCBA           reserve  PCBsize
+PCBB           reserve  PCBsize
+
+;**********************************************************************
+; Process A
+;**********************************************************************
+
+ProcessA
+; initialize
+       add    R1,R0,R0        ; R1 := counterA = 0
+       load   R2,limitA       ; maximum number of iterations
+       lea    R3,1[R0]        ; R3 := 1, counter increment
+
+; loop for limitA iterations
+loopA  cmp    R1,R2           ; if counterA > limitA
+       jumpgt doneA           ; then goto doneA
+
+       load   R4,Shared[R0]
+       lea    R5,1[R0]
+       add    R4,R4,R5
+       store  R4,Shared[R0]
+
+       load   R4,Acount[R0]
+       lea    R5,1[R0]
+       add    R4,R4,R5
+       store  R4,Acount[R0]
+
+       add    R1,R1,R3        ; counterA := counterA + 1
+       jump   loopA           ; goto LoopA
+
+doneA  lea    R1,ReqTerm[R0]  ; trap code for terminate process
+       trap R0,R0,R0 ; TEMP
+       trap   R1,R0,R0        ; request kernel to terminate
+
+; Data for Process A
+limitA   data  16000          ; number of iterations for Process A
+Acount   data      0
+
+;**********************************************************************
+; Process B
+;**********************************************************************
+
+ProcessB
+; initialize
+       add    R1,R0,R0        ; R1 := counterB = 0
+       load   R2,limitB       ; maximum number of iterations
+       lea    R3,1[R0]        ; R3 := 1, counter increment
+
+; loop for limitB iterations
+loopB  cmp    R1,R2           ; if counterB > limitB
+       jumpgt doneB           ; then goto doneB
+
+       load   R4,Shared[R0]
+       lea    R5,1[R0]
+       add    R4,R4,R5
+       store  R4,Shared[R0]
+
+       load   R4,Bcount[R0]
+       lea    R5,1[R0]
+       add    R4,R4,R5
+       store  R4,Bcount[R0]
+
+       add    R1,R1,R3        ; counterB := counterB + 1
+       jump   loopB           ; goto LoopB
+
+doneB  lea    R1,ReqTerm[R0]  ; trap code for terminate process
+       trap   R1,R0,R0        ; request kernel to terminate
+
+; Data for Process B
+limitB   data   16000         ; number of iterations for Process B
+Bcount   data       0
+
+;**********************************************************************
+; Shared data used by both Process A and Process B
+;**********************************************************************
+
+Shared   data      0
+
+
+;----------------------------------------------------------------------
+; deprecated
+
+;handleTimer
+;     store  R1,save1[R0]      ; save state
+;     store  R2,save2[R0]      ; save state
+;     store  R3,save3[R0]      ; save state
+;     lea    R1,2[R0]          ; trap code for write
+;     lea    R2,timerMsg[R0]   ; message: divide by 0
+;     lea    R3,5[R0]          ; length of message
+;     trap   R1,R2,R3          ; print the message
+;     load   R1,save1[R0]      ; restore state
+;     load   R2,save2[R0]      ; restore state
+;     load   R3,save3[R0]      ; restore state
+;     resume                   ; return from interrupt
+; mutex data  0
+
+; limit     data   5000   ; stop eventually even if not interrupted
+; save1           data   0
+; save2           data   0
+; save3           data   0
+; save4           data   0
+; timerMsg        data    98  ; b
+;                data   105  ; i
+;                data   110  ; n
+;                data   103  ; g
+;                data    10  ; newline
diff --git a/VERSION.txt b/VERSION.txt
index fc428f7..ad744ca 100644
--- a/VERSION.txt
+++ b/VERSION.txt
@@ -1 +1 @@
-Version 3.8.0, August 2024
+Version 3.8.0, September 2024
diff --git a/docs/UserGuide/Sigma16UserGuide.org b/docs/UserGuide/Sigma16UserGuide.org
index 5540480..fcb1593 100644
--- a/docs/UserGuide/Sigma16UserGuide.org
+++ b/docs/UserGuide/Sigma16UserGuide.org
@@ -5723,36 +5723,6 @@ existing programs.
 
 * Typesetting
 
-** Links
-
-- Link to a section: see [[*Core architecture tutorials]]
-- Link to a destination in double angle brackets: the execute
-  instruction is discussed in [[strange execute anchor]]
-
-xx - Link to a subsection: see x[x[** A strange program]]
-
-** Included org files
-
-This is a test to see if an org file can be included, and will show up
-in the index.
-
-#   #+INCLUDE: Test.org
-
-** References and bibliography
-
-#+index: Basic
-#+index: Hydra
-- The Basic programming language [cite:@Basic-1964]
-- Historical overview [cite:@Dyson-2012-Turings-Cathedral]
-- Hydra is a functional hardware description language that provides
-  implicit concurrency among digital components
-  [cite:@ODonnell-2002-PDSECA-Hydra]
-- Hydra is well suited for teaching digital circuits
-  [cite:@1995-OD-Hydra-FPLE]
-
-** Index items
-#+INDEX: index
-  
 ** Code listings
 
 #+INDEX: code listing
@@ -5796,6 +5766,40 @@ loop  add    R3,R1,R2      ; R3 := a+b
       store  R5,x[R0]      ; x := a+b+c
 #+END_CodeListing
 
+** Links
+
+- Link to a section: see [[*Core architecture tutorials]]
+- Link to a destination in double angle brackets: the execute
+  instruction is discussed in [[strange execute anchor]]
+
+xx - Link to a subsection: see x[x[** A strange program]]
+
+** Included org files
+
+This is a test to see if an org file can be included, and will show up
+in the index.
+
+#   #+INCLUDE: Test.org
+
+** References and bibliography
+
+#+index: Basic
+#+index: Hydra
+- The Basic programming language [cite:@Basic-1964]
+- Historical overview [cite:@Dyson-2012-Turings-Cathedral]
+- Hydra is a functional hardware description language that provides
+  implicit concurrency among digital components
+  [cite:@ODonnell-2002-PDSECA-Hydra]
+- Hydra is well suited for teaching digital circuits
+  [cite:@1995-OD-Hydra-FPLE]
+
+** Index items
+#+INDEX: index
+  
+** favicon
+
+https://www.ionos.com/tools/favicon-generator
+
 * License
 #+INCLUDE: ../../LICENSE.txt
 
diff --git a/docs/VersionMacro.org b/docs/VersionMacro.org
index b78a6e2..4600034 100644
--- a/docs/VersionMacro.org
+++ b/docs/VersionMacro.org
@@ -1 +1 @@
-#+MACRO: S16version Version 3.8.0, August 2024
+#+MACRO: S16version Version 3.8.0, September 2024
diff --git a/src/Sigma16.html b/src/Sigma16.html
index e1e3834..d92a513 100644
--- a/src/Sigma16.html
+++ b/src/Sigma16.html
@@ -43,6 +43,9 @@
     <script type="module" src="src/base/emulator.mjs"> </script>
     <script type="module" src="./src/gui/gui.mjs"> </script>
     <link rel="stylesheet" href="src/gui/gui.css" type="text/css">
+    <link rel="icon" 
+      type="image/png" 
+      href="./src/graphics/favicon.ico">
   </head>
   <body>
     <div class="FullFrame">
@@ -312,19 +315,23 @@ <h2>Module Set</h2>
 		      <div class="RegisterValue" id='datElt'></div>
 		      <div class="RegisterName">status</div>
 		      <div class="RegisterValue" id="statusElt"></div>
+		      <div class="RegisterName">mask</div>
+		      <div class="RegisterValue" id="maskElt"></div>
 		    </div>
 		  </div>
 		  <div class="ProcStateSection" id="InterruptRegisters">
 		    <div class="Registers">
 		      <div class="NewRegSecName">Interrupt</div>
-		      <div class="RegisterName">mask</div>
-		      <div class="RegisterValue" id="maskElt"></div>
 		      <div class="RegisterName">req</div>
 		      <div class="RegisterValue" id="reqElt"></div>
 		      <div class="RegisterName">istat</div>
 		      <div class="RegisterValue" id='rstatElt'></div>
 		      <div class="RegisterName">ipc</div>
 		      <div class="RegisterValue" id='rpcElt'></div>
+		      <div class="RegisterName">iir</div>
+		      <div class="RegisterValue" id='iirElt'></div>
+		      <div class="RegisterName">iadr</div>
+		      <div class="RegisterValue" id='iadrElt'></div>
 		      <div class="RegisterName">vect</div>
 		      <div class="RegisterValue" id="vectElt"></div>
 		    </div>
diff --git a/src/base/architecture.mjs b/src/base/architecture.mjs
index 0dbe224..2682c22 100644
--- a/src/base/architecture.mjs
+++ b/src/base/architecture.mjs
@@ -210,11 +210,13 @@ ctlReg.set ("mask",     {ctlRegIndex:1});
 ctlReg.set ("req",      {ctlRegIndex:2});
 ctlReg.set ("istat",    {ctlRegIndex:3});
 ctlReg.set ("ipc",      {ctlRegIndex:4});
-ctlReg.set ("vect",     {ctlRegIndex:5});
-ctlReg.set ("psegBeg",  {ctlRegIndex:6});
-ctlReg.set ("psegEnd",  {ctlRegIndex:7});
-ctlReg.set ("dsegBeg",  {ctlRegIndex:8});
-ctlReg.set ("dsegEnd",  {ctlRegIndex:9});
+ctlReg.set ("iir",      {ctlRegIndex:5});
+ctlReg.set ("iadr",     {ctlRegIndex:6});
+ctlReg.set ("vect",     {ctlRegIndex:7});
+ctlReg.set ("psegBeg",  {ctlRegIndex:8});
+ctlReg.set ("psegEnd",  {ctlRegIndex:9});
+ctlReg.set ("dsegBeg",  {ctlRegIndex:10});
+ctlReg.set ("dsegEnd",  {ctlRegIndex:11});
 
 //----------------------------------------------------------------------
 // Condition code
diff --git a/src/base/emulator.mjs b/src/base/emulator.mjs
index 896a096..8c7b1b3 100644
--- a/src/base/emulator.mjs
+++ b/src/base/emulator.mjs
@@ -499,10 +499,13 @@ export function initializeMachineState (es) {
     // bit 2        trap 3
     // bit 3        
     
-    es.rstat    = new genregister (es, 'rstat',  'rstatElt',  arith.wordToHex4);
-    es.rpc      = new genregister (es, 'rpc',    'rpcElt',    arith.wordToHex4);
-    es.vect     = new genregister (es, 'vect',   'vectElt',   arith.wordToHex4);
+    es.rstat = new genregister (es, 'rstat', 'rstatElt',  arith.wordToHex4);
+    es.rpc   = new genregister (es, 'rpc',   'rpcElt',    arith.wordToHex4);
 
+    es.iir  = new genregister (es, 'iir', 'iirElt',   arith.wordToHex4);
+    es.iadr = new genregister (es, 'iadr', 'iadrElt',   arith.wordToHex4);
+    es.vect  = new genregister (es, 'vect',  'vectElt',   arith.wordToHex4);
+    
 // Segment control registers
     es.bpseg = new genregister (es, 'bpseg',  'bpsegElt',  arith.wordToHex4);
     es.epseg = new genregister (es, 'epseg',  'epsegElt',  arith.wordToHex4);
@@ -514,7 +517,9 @@ export function initializeMachineState (es) {
 	[es.pc, es.ir, es.adr, es.dat,
          // not accessible to getctl/putctl instructions
 	 // the following can be used for getctl/getctl, indexing from 0
-	 es.statusreg, es.mask, es.req, es.rstat, es.rpc, es.vect,
+	 es.statusreg, es.mask, es.req, es.rstat, es.rpc,
+         es.iir, es.iadr,
+         es.vect,
          es.bpseg, es.epseg, es.bdseg, es.edseg
 	]
 
@@ -736,6 +741,8 @@ export function executeInstruction (es) {
 	com.mode.devlog (`\n*** Interrupt ${i} ***`)
 	es.rpc.put(es.pc.get())            // save the pc
 	es.rstat.put(es.statusreg.get())   // save the status register
+        es.iir.put(es.ir.get())            // save the ir register
+        es.iadr.put(es.adr.get())          // save the adr register
 	arch.clearBitInRegLE (es.req,i)    // clear the taken interrupt
 	es.pc.put (limitAddress (es, es.vect.get() + 2*i))  // goto handler
         // Disable interrupts and enter system state
@@ -923,6 +930,14 @@ const cab_dca = (f) => (es) => {
     es.regfile[es.ir_a].put(tertiary)
 }
 
+// Traps with 000 <= code < 00ff are "magic" operations that are
+// handled directly by the emulator.  Their purpose is to make
+// programming easier for beginners.  In effect, they have a code
+// between 00 and fe.  Traps with 00ff <= code <= ffff are genuine
+// trap interrupts, and they trigger the full interrupt mechanism.
+// Their behavior is defined by the programmer.  Their purpose is to
+// enable you to write an interrupt driven operating system kernel.
+
 const op_trap = (es) => {
 //  console.log (`%c*** op_trap es.thread_host=${es.thread_host}`, 'color: red')
     switch (es.thread_host) {
@@ -930,7 +945,10 @@ const op_trap = (es) => {
         com.mode.devlog (`handle trap in main thread`)
         let code = es.regfile[es.ir_d].get();
         com.mode.devlog (`trap code=${code}`);
-        if (code===0) { // Halt
+        if (code>255) { // user trap handler
+            handleUserTrap (es)
+        }
+        else if (code===0) { // Halt
 	    console.log ("%cTrap: halt", 'color: red');
 	    com.mode.devlog ("Trap: halt");
             ab.writeSCB (es, ab.SCB_status, ab.SCB_halted)
@@ -962,6 +980,35 @@ const op_trap = (es) => {
     }
 }
 
+// Similar but not identical to executeInstruction check for interrupt
+function handleUserTrap (es) {
+    console.log (`handleUserTrap`)
+    const code = es.regfile[es.ir_d].get();
+    const aval = es.regfile[es.ir_a].get();
+    const bval = es.regfile[es.ir_b].get();
+    console.log (`d=${es.ir_d} code=${arith.wordToHex4(code)}`)
+    console.log (`a=${es.ir_d} aval=${arith.wordToHex4(aval)}`)
+    console.log (`b=${es.ir_d} bval=${arith.wordToHex4(bval)}`)
+
+    com.mode.devlog (`User trap: interrupt`)
+//	let i = 0; // find interrupt that is taken
+    //	while (i<16 && arch.getBitInWordLE(mr,i) === 0) { i++ }
+    const i = 3 ; // code for User Trap interrupt
+    com.mode.devlog (`\n*** Interrupt ${i} ***`)
+    es.rpc.put(es.pc.get())            // save the pc
+    es.rstat.put(es.statusreg.get())   // save the status register
+    es.iir.put(es.ir.get())            // save the ir register
+    es.iadr.put(es.adr.get())          // save the adr register
+    arch.clearBitInRegLE (es.req,i)    // clear the taken interrupt
+    es.pc.put (limitAddress (es, es.vect.get() + 2*i))  // goto handler
+    // Disable interrupts and enter system state
+    es.statusreg.put (es.statusreg.get()
+		      & arch.maskToClearBitLE(arch.intEnableBit)
+		      & arch.maskToClearBitLE(arch.userStateBit))
+    //    timerStop (es)  
+    return
+}
+
 // trapRead performs in input from the contents of the input buffer: a
 // = address of the buffer, and b = size of buffer.  If the number of
 // characters entered by the user into the input buffer exceeds b,
@@ -1441,6 +1488,8 @@ function exp2_resume (es) {
     console.log ('exp2_resume')
     es.statusreg.put (es.rstat.get())
     es.pc.put (limitAddress (es, es.rpc.get()))
+    es.ir.put (es.iir.get())
+    es.adr.put (es.iadr.get())
 }
 
 function exp2_timeron (es) {
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/android-icon-192x192.png b/src/graphics/ea9a02f5f31583077aa151216da13418/android-icon-192x192.png
new file mode 100644
index 0000000..4f6120d
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/android-icon-192x192.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-114x114.png b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-114x114.png
new file mode 100644
index 0000000..902d7a6
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-114x114.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-120x120.png b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-120x120.png
new file mode 100644
index 0000000..9e413a9
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-120x120.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-144x144.png b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-144x144.png
new file mode 100644
index 0000000..2647eab
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-144x144.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-152x152.png b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-152x152.png
new file mode 100644
index 0000000..860a206
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-152x152.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-180x180.png b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-180x180.png
new file mode 100644
index 0000000..aa7115b
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-180x180.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-57x57.png b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-57x57.png
new file mode 100644
index 0000000..c8ad7c3
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-57x57.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-60x60.png b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-60x60.png
new file mode 100644
index 0000000..8c775e9
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-60x60.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-72x72.png b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-72x72.png
new file mode 100644
index 0000000..3731cec
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-72x72.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-76x76.png b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-76x76.png
new file mode 100644
index 0000000..1244478
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/apple-icon-76x76.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/browserconfig.xml b/src/graphics/ea9a02f5f31583077aa151216da13418/browserconfig.xml
new file mode 100644
index 0000000..c554148
--- /dev/null
+++ b/src/graphics/ea9a02f5f31583077aa151216da13418/browserconfig.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
\ No newline at end of file
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-16x16.png b/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-16x16.png
new file mode 100644
index 0000000..02fdf1e
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-16x16.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-256x256.png b/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-256x256.png
new file mode 100644
index 0000000..ee2c14b
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-256x256.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-32x32.png b/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-32x32.png
new file mode 100644
index 0000000..cd0d8fc
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-32x32.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-96x96.png b/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-96x96.png
new file mode 100644
index 0000000..d5cb4d9
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/favicon-96x96.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/favicon.ico b/src/graphics/ea9a02f5f31583077aa151216da13418/favicon.ico
new file mode 100644
index 0000000..df84ad6
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/favicon.ico differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/instructions.txt b/src/graphics/ea9a02f5f31583077aa151216da13418/instructions.txt
new file mode 100644
index 0000000..5c7c8c5
--- /dev/null
+++ b/src/graphics/ea9a02f5f31583077aa151216da13418/instructions.txt
@@ -0,0 +1,22 @@
+1) Upload images
+Upload your images into your domain's root directory
+
+2) Add HTML code
+Insert the following HTML code between the <head> </head> tags:
+<link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
+<link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
+<link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
+<link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
+<link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
+<link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
+<link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
+<link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
+<link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
+<link rel="icon" type="image/png" sizes="192x192"  href="/android-icon-192x192.png">
+<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
+<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png">
+<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
+<link rel="manifest" href="/manifest.json">
+<meta name="msapplication-TileColor" content="#ffffff">
+<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
+<meta name="theme-color" content="#ffffff">
\ No newline at end of file
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/manifest.json b/src/graphics/ea9a02f5f31583077aa151216da13418/manifest.json
new file mode 100644
index 0000000..013d4a6
--- /dev/null
+++ b/src/graphics/ea9a02f5f31583077aa151216da13418/manifest.json
@@ -0,0 +1,41 @@
+{
+ "name": "App",
+ "icons": [
+  {
+   "src": "\/android-icon-36x36.png",
+   "sizes": "36x36",
+   "type": "image\/png",
+   "density": "0.75"
+  },
+  {
+   "src": "\/android-icon-48x48.png",
+   "sizes": "48x48",
+   "type": "image\/png",
+   "density": "1.0"
+  },
+  {
+   "src": "\/android-icon-72x72.png",
+   "sizes": "72x72",
+   "type": "image\/png",
+   "density": "1.5"
+  },
+  {
+   "src": "\/android-icon-96x96.png",
+   "sizes": "96x96",
+   "type": "image\/png",
+   "density": "2.0"
+  },
+  {
+   "src": "\/android-icon-144x144.png",
+   "sizes": "144x144",
+   "type": "image\/png",
+   "density": "3.0"
+  },
+  {
+   "src": "\/android-icon-192x192.png",
+   "sizes": "192x192",
+   "type": "image\/png",
+   "density": "4.0"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-144x144.png b/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-144x144.png
new file mode 100644
index 0000000..2647eab
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-144x144.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-150x150.png b/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-150x150.png
new file mode 100644
index 0000000..9989a21
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-150x150.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-310x310.png b/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-310x310.png
new file mode 100644
index 0000000..115a3f3
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-310x310.png differ
diff --git a/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-70x70.png b/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-70x70.png
new file mode 100644
index 0000000..c85e183
Binary files /dev/null and b/src/graphics/ea9a02f5f31583077aa151216da13418/ms-icon-70x70.png differ
diff --git a/src/graphics/favicon.ico b/src/graphics/favicon.ico
new file mode 100644
index 0000000..df84ad6
Binary files /dev/null and b/src/graphics/favicon.ico differ