abort trap - sjsoftware/centurion-cpu6 GitHub Wiki

Abort Trap

The abort trap handles exceptions in the microcode execution. There is a large overlap with the interrupt handling code.

There are 6 identified abort conditions

Condition Description
0 Illegal Instruction
1 Privileged Instruction/HLT at interrupt level < 15
2 Bad memory write
3 Bad memory read
4 Parity error
5 Multibyte/bignum overflow

The abort trap will execute the interrupt handler for interrupt level 15. If the interrupt level is already 15, then the CPU6 will enter the Halt state. The Halt state can be recovered by use of the dip switches.

The 'R' dip switch will continue execution from the instruction following the instruction that caused the Halt state. Resume.

The I dip switch will continue execution from the instruction indexed by S at the interrupt level indicated by S1 and S2 switches (0 to 3). Interrupt.

Bugs

The microinstruction at address 780 sets the low byte of the work address register to zero. This is possibly meant to cancel an interrupt acknowledge. Or fixing a bug which was incorrectly cancelling interrupt acknowledge

When in Halt state timer interrupts do not appear to be processed.

It is possibly a bug that the address of the next instruction when using the I switch is retrieved from S and not P.

Microcode

I think at some point this goes into interrupt handling code

105       CRY0 r00 r02 RAM  NOT.D                 P P P      0f0 f0 (0f)                                       LOAD.RIR READ.CONST  (105) r02 <- f0; RIR <- r02   ;* A level 15
          CRY0 r02 r00 Q    D.AND.A               D D D      2f0 f0 (0f)                                                READ.MSR    (106) Q <- r02 & MSR          ;* interrupt level
          CRY0 r02 r07 PASS A.XOR.Q               P P P      000 00 (ff)          LOAD.FLR          DIR+                READ.SWP    (2f0) r02 ^ Q                 ;* level 15...
      RLO CRY0 r00 r00 PASS A+Q         COND Z    P P D      0cd cd (32)                            WRITE.RF            READ.SWP    (2f1) RF (low) <- RR; BRT (zero) 2ff    ;* branch if level 15 - write AL level 0
          CRY0 r02 r15 RAM  A                     D D D      780 80 (7f)                                                READ.SWP    (2fd) r15 <- r02
          CRY0 r00 r15 PASS ZERO                  D D D      715 15 (ea)          LOAD.FLR          LOAD.ALO            READ.SWP    (780) ALO <- ZERO                    ;* Maybe a bug and meant to be M13 enable, should be IACK+ from context maybe

;* Interrupt code starts here
715       CRY0 r15 r00 RAM  NOT.D.AND.A           D D D      6bc bc (43)                                                READ.CCR    (715) r00 <- CCR & r15
          CRY0 r06 r14 RSH  A                     D D D PUSH 059 59 (a6)                                                READ.SWP    (6bc) r14 <- r06 >> 1; BSR 059  ;* r14 <- r06 >> 4
          CRY0 r15 r01 RAM  NOT.A                 D D D      6ca ca (35)                                                READ.SWP    (6bd) r01 <- ~r15
          CRY0 r14 r01 RAM  A.AND.B               D D D      65a 5a (a5)                                                READ.SWP    (6ca) r01 &= r14 
          CRY0 r00 r01 PASS A.OR.B                P P P      785 85 (7a) JSR DMA                               LOAD.RR  READ.SWP    (65a) RR <- r01 | r00
          CRY0 r00 r09 RSH  NOT.D                 P P P      01c 1c (e3)                                       LOAD.RIR READ.CONST  (65b) RIR <- 1c; r09 <- 0e;
    I RLO CRY0 r09 r00 PASS A                     D D D PUSH 48e 8e (71)                            WRITE.RF   LOAD.RIR READ.SWP    (65c) RF <- RR; RR <- r09; BSR 48e                 ;* Write CL, P <- PC
          CRY0 r00 r00 RAM  D           COND Z    P P D      0c5 c5 (3a)                                                READ.MSR    (65d) r00 <- MSR; BRT (zero) 657        ;* interrupt request?
          CRY0 r00 r00 PASS D                     D D D      6d5 d5 (2a)                                       LOAD.ILR READ.INR    (655) ILR <- INR ; BRT 6d5              ;* yes???
	
657       CRY0 r02 r00 PASS A                     D D D      6d5 d5 (2a)                                       LOAD.ILR READ.SWP    (657) ILR <- r02                        ;* level 15
          CRY0 r00 r14 PASS A+Q                   D D D PUSH 68e 8e (71)                            IACK-               READ.SWP    (6d5) BSR 68e                           ;* Acknowledge
          CRY0 r09 r09 RAM  A+B                   D D D      6dc dc (23)                            RUN+       LOAD.RIR READ.SWP    (6d6) r09 += r09; RIR <- r09            ;* Run, what register is this?? 0c?
          CRY0 r00 r00 PASS A                     P P P      785 85 (7a) JSR DMA                               LOAD.RR  READ.SWP    (6dc) RR <- r00
    I     CRY0 r00 r00 PASS A+Q                   D D D      6ed ed (12)                            WRITE.RF   LOAD.MAR READ.SWP    (6dd) RF <- RR
    I RLO CRY0 r00 r00 RAM  NOT.D                 P P P      0f0 f0 (0f)                                                READ.CONST  (6ed) r00 <- f0
          CRY0 r00 r01 RAM  D                     P P P      785 85 (7a) JSR DMA                               LOAD.RR  READ.RF     (6ee) r01 <- RF; RR<- r01
          CRY0 r00 r06 RAM  NOT.A.AND.B           P P P      102 02 (fd)                                       LOAD.CCR READ.SWP    (6ef) CCR <- RR; r06 &= ~r00
          CRY0 r01 r00 PASS A                     D D D      73f 3f (c0)                                       LOAD.MAP READ.SWP    (6f0) MAP <- r01
          CRY0 r01 r01 LSH  A+B                   D D D      654 54 (ab)                                                READ.SWP    (73f) r01 = (r01 + r01) << 1
          CRY0 r01 r01 LSH  A+B                   D D D      6e5 e5 (1a)                                                READ.SWP    (654) r01 = (r01 + r01) << 1
          CRY0 r00 r01 RAM  A.AND.B               D D D      6e9 e9 (16)                                                READ.SWP    (6e5) r01 &= r00
          CRY0 r01 r06 RAM  A.OR.B                D D D      100 00 (ff)                                                READ.SWP    (6e9) r06 |= r01

;* interrupt level 15
2ff       CRY0 r00 r13 PASS A+Q                   D D D      2fe fe (01)                            ABORT+              READ.SWP    (2ff)                        ;* abort

          CRY0 r00 r09 RAM  NOT.D                 D D D      71e 1e (e1)                                       LOAD.RIR READ.CONST  (2fe) RIR <- 1e
71e       CRY0 r00 r08 PASS A+Q                   D D D PUSH 48e 8e (71)                            RUN-                READ.SWP    (71e) P <- PC; RUN-          ;* HLT comes in here, does the timer get checked?  
71f       CRY0 r00 r00 RAM  NOT.D                 P P P      008 08 (f7)                                                READ.CONST  (71f) r00 <- 8               ;* switch setting
          CRY0 r00 r01 RAM  NOT.D                 P P D      00a 0a (f5)                                                READ.CONST  (720) r01 <- a               ;* switch setting
          CRY0 r00 r00 PASS A+Q                   P P P      785 85 (7a) JSR DMA                                        READ.SWP    (72a) 
          CRY0 r00 r00 PASS D.AND.A               D D D      73d 3d (c2)          LOAD.FLR                              READ.MSR    (72b)                        ;* not DMA int..
          CRY0 r00 r00 PASS A+Q         COND !INT P P D      074 74 (8b)                                                READ.SWP    (73d) BRT (!int) 73c         ;* loop until interrupt
          CRY0 r00 r00 PASS A+Q                   D D D      714 14 (eb)                                                READ.SWP    (734)
          CRY0 r00 r15 RAM  NOT.D                 P P P      0f0 f0 (0f)          LOAD.FLR          IACK+               READ.CONST  (714) r15 <- f0; BRT 715     ;* interrupt, branch to interrupt handler which will break us out of the loop

;* no interrupt, zero flag is DMA int pending
73c       CRY0 r01 r02 RAM  D.AND.A     COND Z    P P D      0c5 c5 (3a)          LOAD.FLR                              READ.INR    (73c)  ;* MSR & 8 ;* ~INR & a => dip switches R and I
          CRY0 r00 r00 PASS A+Q                   D D D      791 91 (6e)                                                READ.SWP    (735)  ;* DMA
          CRY0 r00 r02 RAM  D                     D D D POP  7d4 d4 (2b)                                                READ.CONST  (791)  ;* interrupt level = 2 (this code is shared with the interrupt code)
          CRY0 r00 r00 PASS A+Q                   D D D      782 82 (7d)                                                READ.SWP    (7d4)
          CRY0 r00 r15 RAM  NOT.D                 P P D      0f0 f0 (0f)                                                READ.CONST  (782)  ;* BRT 780 - process interrupt at level 2

737       CRY0 r03 r03 RAM  A.EQV.B     COND Z    P P D      0c9 c9 (36)                                                READ.SWP    (737)  ;* no DMA
          CRY0 r04 r04 RAM  A.EQV.B               D D D PUSH 1e1 e1 (1e)                                                READ.SWP    (739)  ;* switches grounded
          CRY0 r01 r00 PASS D.AND.A               D D D      6fb fb (04)          LOAD.FLR                              READ.INR    (73a)  ;* check switches
          CRY0 r03 r03 RAM  A.EQV.B     COND Z    P P D      0c5 c5 (3a)                                                READ.SWP    (6fb)  
          CRY0 r00 r00 PASS A+Q                   D D D      73a 3a (c5)                                                READ.SWP    (6f5)  BRT 73a ;* on, 73a - wait for off

73b       CRY0 r00 r00 PASS A+Q                   D D D      71f 1f (e0)                                                READ.SWP    (73b) BRT 71f

6f7       CRY0 r04 r04 RAM  A.EQV.B               D D D PUSH 1e1 e1 (1e)                   LOAD.SWP                     READ.CCR    (6f7) SWP <- CCR; r04 <- ff
          CRY0 r02 r00 PASS A.AND.B               D D D      688 88 (77)          LOAD.FLR                              READ.SWP    (6f8)
          CRY0 r00 r02 RAM  D           COND Z    P P D      0c9 c9 (36)                                                READ.MSR    (688)
          CRY0 r00 r09 PASS A+Q                   D D D PUSH 68e 8e (71)                            RUN+                READ.SWP    (689)
          CRY0 r00 r12 PASS A+Q                   D D D      6f6 f6 (09)                            ABORT-     LOAD.MAR READ.SWP    (68a)
          CRY0 r02 r00 PASS A                     D D D      609 09 (f6)                   BUS.RD              LOAD.ILR READ.SWP    (6f6)
          CRY0 r00 r09 RAM  ZERO                  P P P      633 33 (cc) JSR BADR LOAD.FLR                     LOAD.RIR READ.SWP    (609)
          CRY1 r09 r08 RAMA A+0                   D D D PUSH 103 03 (fc)          BUS.WAIT INC.MAR             LOAD.RR  READ.SWP    (60a)
          CRY0 r00 r00 PASS A+Q                   D D D      100 00 (ff)                                                READ.SWP    (60b)  ;* just in case we jump back to here, we need to go back a little bit.

68b       CRY0 r01 r00 RAMA D                     P P P      000 00 (ff)                                       LOAD.RIR READ.SWP    (68b)
          CRY0 r00 r00 RAM  NOT.D.AND.A           P P D      039 39 (c6)                                       LOAD.ILR READ.CONST  (68c) BRT 689


; delay loop, used by DLY as well
1e1       CRY0 r03 r03 RAM  A-1                   P P P      785 85 (7a) JSR DMA  LOAD.FLR                              READ.SWP    (1e1)
          CRY  r04 r04 RAM  A-1                   P P D      000 00 (ff)          LOAD.FLR                              READ.SWP    (1e2)
          CRY0 r00 r00 PASS A+Q         COND Z    P P D      0c1 c1 (3e)                                                READ.SWP    (1e0) BRT (!zero) 1e1
1e3       CRY0 r00 r00 PASS A+Q                   S S S POP  000 00 (ff)                                                READ.SWP    (1e3)


68e I RLO CRY0 r00 r00 PASS A+Q                   D D D      60f 0f (f0)                                                READ.SWP    (68e)
    I     CRY0 r00 r00 PASS D                     D D D      625 25 (da)                                       LOAD.RR  READ.RF     (60f)
          CRY0 r00 r00 PASS D                     D D D      68d 8d (72)                            LOAD.ALO   LOAD.RR  READ.RF     (625)
          CRY0 r00 r00 PASS A+Q                   S S S POP  000 00 (ff)                   LOAD.AHI                     READ.SWP    (68d) WAR <- P
⚠️ **GitHub.com Fallback** ⚠️