2929
3030/* Debug */
3131#define DBG_CPU 0001
32+ #define DBG_INT 0002
3233
3334#define WMASK 07777 /* Full word. */
3435#define HMASK 04000 /* H bit; half word select. */
@@ -57,9 +58,9 @@ static uint16 XL[12];
5758static int paused ;
5859static int IBZ ;
5960static int OVF ;
61+ static int INTREQ ;
62+ static int ENI = 0 ;
6063static int PINFF ;
61- static int interrupt ;
62- static int interrupt_enable = 0 ;
6364
6465static t_stat stop_reason ;
6566
@@ -95,11 +96,16 @@ REG cpu_reg[] = {
9596 { ORDATAD (LSW , LSW , 12 , "Left Switches" ) },
9697 { ORDATAD (RSW , RSW , 12 , "Right Switches" ) },
9798 { ORDATAD (SSW , SSW , 6 , "Sense Switches" ) },
99+
98100 { FLDATAD (paused , paused , 1 , "Paused" ) },
99- { FLDATAD (IBZ , IBZ , 1 , "Interblock zone" ) },
100- { FLDATAD (OVF , OVF , 1 , "Overflow" ) },
101- { BRDATAD (SAM , SAM , 8 , 7 , 16 , "Sampled analog inputs" ) },
102- { BRDATAD (XL , XL , 8 , 1 , 12 , "External levels" ) },
101+ { FLDATAD (IBZ , IBZ , 1 , "Interblock zone" ) },
102+ { FLDATAD (OVF , OVF , 1 , "Overflow" ) },
103+ { FLDATAD (INTREQ , INTREQ , 1 , "Interrupt" ) },
104+ { FLDATAD (ENI , ENI , 1 , "Interrupt Enable" ) },
105+ { FLDATAD (PIN , PINFF , 1 , "Pause Interrupt" ) },
106+
107+ { BRDATAD (SAM , SAM , 8 , 7 , 16 , "Sampled analog inputs" ) },
108+ { BRDATAD (XL , XL , 8 , 1 , 12 , "External levels" ) },
103109 { NULL }
104110};
105111
@@ -111,6 +117,7 @@ static MTAB cpu_mod[] = {
111117
112118static DEBTAB cpu_deb [] = {
113119 { "CPU" , DBG_CPU },
120+ { "INTERRUPT" , DBG_INT },
114121 { NULL , 0 }
115122};
116123
@@ -218,7 +225,8 @@ cpu_misc(void)
218225 A = Z >> 1 ;
219226 break ;
220227 case 00010 : //ENI
221- interrupt_enable = 1 ;
228+ sim_debug (DBG_INT , & cpu_dev , "ENI, Interrupt enabled.\n" );
229+ ENI = 1 ;
222230 break ;
223231 case 00011 : //CLR
224232 A = L = Z = 0 ;
@@ -232,6 +240,7 @@ cpu_misc(void)
232240 A = R & RMASK ;
233241 break ;
234242 case 00016 : //NOP
243+ sim_debug (DBG_CPU , & cpu_dev , "NOP\n" );
235244 break ;
236245 case 00017 : //COM
237246 A = (~A ) & WMASK ;
@@ -336,6 +345,8 @@ int cpu_skip(void)
336345 break ;
337346 case 046 : //PIN
338347 flag = PINFF ;
348+ PINFF = 0 ;
349+ sim_debug (DBG_INT , & cpu_dev , "PIN -> %d.\n" , flag );
339350 break ;
340351 case 050 : //AZE
341352 flag = (A == 0 ) || (A == WMASK );
@@ -374,7 +385,10 @@ static void cpu_opr(void)
374385 ; //Pause.
375386 break ;
376387 case 015 : //KBD
388+ sim_debug (DBG_CPU , & cpu_dev , "KBD%s\n" , C & IMASK ? " i" : "" );
377389 A = kbd_key (C & IMASK );
390+ sim_debug (DBG_CPU , & cpu_dev , " key = %02o\n" , A );
391+ sim_debug (DBG_CPU , & cpu_dev , " paused = %d\n" , paused );
378392 break ;
379393 case 016 : //RSW
380394 A = RSW ;
@@ -721,12 +735,32 @@ cpu_insn(void)
721735 }
722736
723737 /* Check for interrupts. */
724- if ((C & 06000 ) != 06000 && C != 00010 && interrupt && interrupt_enable ) {
725- interrupt = interrupt_enable = 0 ;
738+ if (INTREQ && ENI ) {
739+ sim_debug (DBG_INT , & cpu_dev ,
740+ "Interrupt requested and enabled; paused = %d.\n" ,
741+ paused );
742+ if ((C & 06000 ) == 06000 || C == 00010 )
743+ sim_debug (DBG_INT , & cpu_dev , "Can't interrupt after JMP or ENI.\n" );
744+ }
745+ if ((C & 06000 ) != 06000 && C != 00010 && INTREQ && ENI ) {
746+ sim_debug (DBG_INT , & cpu_dev , "Interrupt taken.\n" );
747+ if (paused ) {
748+ PINFF = 1 ;
749+ sim_debug (DBG_INT , & cpu_dev , "Was paused, set PINFF.\n" );
750+ }
751+ paused = 0 ;
726752 memaddr (021 );
727753 memrd ();
728754 C = B ;
729- cpu_jmp ();
755+ INTREQ = ENI = 0 ;
756+ if ((C & 06000 ) == 06000 ) {
757+ sim_debug (DBG_INT , & cpu_dev , "JMP in 21.\n" );
758+ cpu_jmp ();
759+ } else if ((C & 07700 ) == 00500 ) {
760+ sim_debug (DBG_INT , & cpu_dev , "OPR in 21.\n" );
761+ cpu_opr ();
762+ } else if ((B & 07777 ) == 00016 )
763+ sim_debug (DBG_INT , & cpu_dev , "NOP in 21.\n" );
730764 }
731765}
732766
@@ -739,6 +773,8 @@ t_stat sim_instr(void)
739773
740774 stop_reason = 0 ;
741775 paused = 0 ;
776+ PINFF = 0 ;
777+ ENI = 0 ;
742778
743779 for (;;) {
744780 AIO_CHECK_EVENT ;
@@ -750,13 +786,18 @@ t_stat sim_instr(void)
750786 if (sim_brk_summ && sim_brk_test (P , SWMASK ('E' )))
751787 return STOP_IBKPT ;
752788
753- #if 0
789+ #if 1
754790 if (paused )
755791 sim_debug (DBG_CPU , & cpu_dev , "Paused\n" );
756792#endif
757- if (paused )
793+ if (paused ) {
758794 sim_interval -- ;
759- else
795+ if (INTREQ && ENI && !PINFF ) {
796+ sim_debug (DBG_INT , & cpu_dev , "Interrupt during pause\n" );
797+ paused = 0 ;
798+ PINFF = 1 ;
799+ }
800+ } else
760801 cpu_insn ();
761802
762803 if (sim_step != 0 ) {
0 commit comments