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