Skip to content

Commit 5421f2b

Browse files
committed
interrupt
1 parent 30cace1 commit 5421f2b

3 files changed

Lines changed: 66 additions & 16 deletions

File tree

linc/linc_cpu.c

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
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];
5758
static int paused;
5859
static int IBZ;
5960
static int OVF;
61+
static int INTREQ;
62+
static int ENI = 0;
6063
static int PINFF;
61-
static int interrupt;
62-
static int interrupt_enable = 0;
6364

6465
static 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

112118
static 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) {

linc/linc_kbd.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
/* Debug */
55
#define DBG 0001
66

7+
#define A (*(uint16 *)cpu_reg[2].loc)
8+
#define paused (*(int *)cpu_reg[11].loc)
9+
710
static t_stat kbd_svc(UNIT *uptr);
811
static t_stat kbd_reset(DEVICE *dptr);
912

@@ -222,8 +225,9 @@ uint16 kbd_key(uint16 wait)
222225
sim_activate_abs(&kbd_unit, 1);
223226
kbd_pressed = 0;
224227
return kbd_code;
225-
} else {
228+
} else if (wait) {
226229
sim_debug(DBG, &kbd_dev, "KEY paused\n");
230+
paused = 1;
227231
}
228232
return 0;
229233
}
@@ -404,7 +408,11 @@ static void kbd_convert(uint32 key)
404408
}
405409
sim_debug(DBG, &kbd_dev, "Key struck %s -> %02o\n",
406410
vid_key_name(key), kbd_code);
407-
kbd_pressed = 1;
411+
if (paused)
412+
A = kbd_code;
413+
else
414+
kbd_pressed = 1;
415+
paused = 0;
408416
}
409417

410418
static int

linc/tests/classic-test.do

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ call test 701 ZTAT1 115 105
7373
call test 702 ZCLR1 116 106
7474
deposit SAM[0] 177
7575
call test 703 ZCLRT2 117 107
76-
;call test 704 ENIT1 120 110
76+
deposit INTREQ 1
77+
call test 704 ENIT1 120 110
7778
deposit RSW 0300
7879
deposit LSW 0700
7980
deposit SSW 77

0 commit comments

Comments
 (0)