H316: Merge updates from Bob Supnik and Bob Armstrong (Instruction decoding)

This commit is contained in:
Mark Pizzolato 2015-04-03 18:49:44 -07:00
parent 2f350955ec
commit fb3c5327b7
8 changed files with 165 additions and 116 deletions

View file

@ -1,6 +1,6 @@
/* h316_cpu.c: Honeywell 316/516 CPU simulator
Copyright (c) 1999-2011, Robert M. Supnik
Copyright (c) 1999-2015, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -508,13 +508,16 @@ if (chan_req) { /* channel request? */
/* Interrupts */
//[RLA] Todo - add WDT interrupts ????
iack = FALSE;
if ((dev_int & (INT_PEND|INT_NMI|dev_enb)) > INT_PEND) { // [RLA] check for standard interrupt
MB = cpu_interrupt(M_INT); iack = TRUE;
MB = cpu_interrupt(M_INT);
iack = TRUE;
}
else if ( ((dev_ext_int & dev_ext_enb) != 0) // [RLA] check for extended interrupt
&& ((dev_int & INT_PEND) == INT_PEND) ) {
MB = cpu_ext_interrupt(); iack = TRUE;
else if (((dev_ext_int & dev_ext_enb) != 0) // [RLA] check for extended interrupt
&& ((dev_int & INT_PEND) == INT_PEND)) {
MB = cpu_ext_interrupt ();
iack = TRUE;
}
/* Instruction fetch */
@ -578,9 +581,11 @@ switch (I_GETOP (MB)) { /* case on <1:6> */
case 004: case 024: case 044: case 064: /* STA */
if ((reason = Ea (MB, &Y))) /* eff addr */
break;
if ((reason = Write(Y, AR))) break; /* [RLA] store A */
if ((reason = Write(Y, AR)))
break; /* [RLA] store A */
if (dp) { /* double prec? */
if ((reason = Write(Y | 1, BR))) break; /* [RLA] store B */
if ((reason = Write(Y | 1, BR)))
break; /* [RLA] store B */
sc = 0;
}
break;
@ -621,7 +626,8 @@ switch (I_GETOP (MB)) { /* case on <1:6> */
if ((reason = Ea (MB, &Y))) /* eff addr */
break;
MB = NEWA (Read (Y), PC); /* merge old PC */
if ((reason = Write(Y, MB))) break; // [RLA]
if ((reason = Write(Y, MB)))
break; // [RLA]
PCQ_ENTRY;
PC = NEWA (PC, Y + 1); /* set new PC */
break;
@ -640,7 +646,8 @@ switch (I_GETOP (MB)) { /* case on <1:6> */
if ((reason = Ea (MB, &Y))) /* eff addr */
break;
MB = (Read (Y) + 1) & DMASK; /* incr, rewrite */
if ((reason = Write(Y, MB))) break; // [RLA]
if ((reason = Write(Y, MB)))
break; // [RLA]
if (MB == 0) /* skip if zero */
PC = NEWA (PC, PC + 1);
break;
@ -649,14 +656,16 @@ switch (I_GETOP (MB)) { /* case on <1:6> */
if ((reason = Ea (MB, &Y))) /* eff addr */
break;
MB = Read (Y);
if ((reason = Write(Y, AR))) break; /* [RLA] A to mem */
if ((reason = Write(Y, AR)))
break; /* [RLA] A to mem */
AR = MB; /* mem to A */
break;
case 015: case 055: /* STX */
if ((reason = Ea (MB & ~IDX, &Y))) /* eff addr */
break;
if ((reason = Write(Y, XR))) break; /* [RLA] store XR */
if ((reason = Write(Y, XR)))
break; /* [RLA] store XR */
break;
case 035: case 075: /* LDX */
@ -1092,10 +1101,10 @@ return SCPE_OK;
t_stat Write (int32 addr, int32 val)
{
// [RLA] Write() now checks for address breaks ...
if (((addr == 0) || (addr >= 020)) && MEM_ADDR_OK (addr))
// [RLA] Write() now checks for address breaks ...
if (((addr == 0) || (addr >= 020)) && MEM_ADDR_OK (addr))
M[addr] = val;
if (addr == M_XR) /* write XR loc? */
if (addr == M_XR) /* write XR loc? */
XR = val;
// [RLA] Implement "break on memory write" ...
if (sim_brk_summ && sim_brk_test (addr, SWMASK ('W')))
@ -1127,11 +1136,14 @@ return r;
}
// [RLA] Standard (fixed vector) interrupt action ...
int32 cpu_interrupt (int32 vec) {
pme = ext; /* save extend */
if (cpu_unit.flags & UNIT_EXT) ext = 1; /* ext opt? extend on */
dev_int = dev_int & ~INT_ON; /* intr off */
return 0120000 | vec; /* inst = JST* vector */
int32 cpu_interrupt (int32 vec)
{
pme = ext; /* save extend */
if (cpu_unit.flags & UNIT_EXT)
ext = 1; /* ext opt? extend on */
dev_int = dev_int & ~INT_ON; /* intr off */
return 0120000 | vec; /* inst = JST* vector */
}
// [RLA] Extended (priority) interrupt action ...
@ -1191,11 +1203,6 @@ int32 sim_ota_2024 (int32 inst, int32 fnc, int32 dat, int32 dev)
// flags (single or double precision HSA, extended addressing mode,
// the carry flag, etc).
//
// The original simh implementation handled the regular SMK and OTK
// as special cases in the CLK device. Why the CLK device??? Because
// it also uses device code 20! Shame - these have nothing to do with
// the clock!
//
// This routine implements these special OTKs as part of the CPU.
// That allows us to implement the extra interrupt masks needed by the
// IMP, and it also allows the CLK device to be disabled without losing
@ -1204,15 +1211,20 @@ int32 sim_ota_2024 (int32 inst, int32 fnc, int32 dat, int32 dev)
// needs it to be disabled.
// Although OTA 24 is reserved nothing we currently simulate uses it!
if (dev == 024) return IOBADFNC (dat);
if (dev == 024)
return IOBADFNC (dat);
// Device code 20...
switch (fnc) {
case 000: // SMK 020 - set standard interrupt mask
dev_enb = dat; break;
dev_enb = dat;
break;
case 001: // SMK 120 - set extended interrupt mask #1
if (ext_ints < 16) return IOBADFNC(dat);
dev_ext_enb = dat; break;
if (ext_ints < 16)
return IOBADFNC(dat);
dev_ext_enb = dat;
break;
case 002: // SMK 220 - set extended interrupt mask #2
case 003: // SMK 320 - set extended interrupt mask #3
return IOBADFNC(dat);
@ -1647,8 +1659,8 @@ return SCPE_OK;
}
/* Set up I/O dispatch and channel maps */
// [RLA] Check for DMC conflicts (on both DMC channels!) ...
t_bool set_chanmap (DEVICE *dptr, DIB *dibp, uint32 dno, uint32 chan)
{
if ((chan < DMC_V_DMC1) && (chan >= dma_nch)) {
@ -1692,9 +1704,11 @@ for (i = 0; (dptr = sim_devices[i]); i++) { /* loop thru devices */
} /* end for */
// [RLA] set up the channel map
if (dibp->chan != 0)
if (set_chanmap(dptr, dibp, dno, dibp->chan-1)) return TRUE;
if (set_chanmap(dptr, dibp, dno, dibp->chan-1))
return TRUE;
if (dibp->chan2 != 0)
if (set_chanmap(dptr, dibp, dno, dibp->chan2-1)) return TRUE;
if (set_chanmap(dptr, dibp, dno, dibp->chan2-1))
return TRUE;
// [RLA] If the device uses extended interrupts, check that they're enabled.
if ((dibp->inum != INT_V_NONE) && (dibp->inum >= INT_V_EXTD) && (ext_ints == 0)) {
sim_printf ("%s uses extended interrupts but that option is disabled\n", sim_dname (dptr));

View file

@ -1,6 +1,6 @@
/* h316_defs.h: Honeywell 316/516 simulator definitions
Copyright (c) 1999-2011, Robert M. Supnik
Copyright (c) 1999-2015, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -218,6 +218,7 @@ typedef struct h316_dib DIB;
#define TST_EXT_INTREQ(x) ((dev_ext_int & dev_ext_enb & (x)) != 0)
/* Prototypes */
t_stat io_set_iobus (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat io_set_dma (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat io_set_dmc (UNIT *uptr, int32 val, char *cptr, void *desc);

View file

@ -1,6 +1,6 @@
/* h316_dp.c: Honeywell 4623, 4651, 4720 disk simulator
Copyright (c) 2003-2012, Robert M. Supnik
Copyright (c) 2003-2015, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -27,7 +27,7 @@
4651 disk subsystem
4720 disk subsystem
3-Jul-13 RLA compatibility changes for extended interrupts
03-Jul-13 RLA compatibility changes for extended interrupts
19-Mar-12 RMS Fixed declaration of chan_req (Mark Pizzolato)
04-Sep-05 RMS Fixed missing return (Peter Schorn)
15-Jul-05 RMS Fixed bug in attach routine

View file

@ -1,6 +1,6 @@
/* h316_fhd.c: H316/516 fixed head simulator
Copyright (c) 2003-2013, Robert M. Supnik
Copyright (c) 2003-2015, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -26,7 +26,7 @@
fhd 516-4400 fixed head disk
03-Sep-13 RMS Added explicit void * cast
3-Jul-13 RLA compatibility changes for extended interrupts
03-Jul-13 RLA compatibility changes for extended interrupts
19-Mar-12 RMS Fixed declaration of chan_req (Mark Pizzolato)
15-May-06 RMS Fixed bug in autosize attach (David Gesswein)
04-Jan-04 RMS Changed sim_fsize calling sequence

View file

@ -1,6 +1,6 @@
/* h316_lp.c: Honeywell 316/516 line printer
Copyright (c) 1999-2008, Robert M. Supnik
Copyright (c) 1999-2015, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -25,7 +25,7 @@
lpt line printer
3-Jul-13 RLA compatibility changes for extended interrupts
03-Jul-13 RLA compatibility changes for extended interrupts
09-Jun-07 RMS Fixed lost last print line (Theo Engel)
19-Jan-06 RMS Added UNIT_TEXT flag
03-Apr-06 RMS Fixed bug in blanks backscanning (Theo Engel)

View file

@ -25,7 +25,7 @@
mt 516-4100 seven track magnetic tape
3-Jul-13 RLA compatibility changes for extended interrupts
03-Jul-13 RLA compatibility changes for extended interrupts
19-Mar-12 RMS Fixed declaration of chan_req (Mark Pizzolato)
09-Jun-07 RMS Fixed bug in write without stop (Theo Engel)
16-Feb-06 RMS Added tape capacity checking

View file

@ -1,6 +1,6 @@
/* h316_stddev.c: Honeywell 316/516 standard devices
Copyright (c) 1999-2013, Robert M. Supnik
Copyright (c) 1999-2015, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -30,7 +30,7 @@
10-Sep-13 RMS Fixed several bugs in the TTY logic
Added SET file type commands to PTR/PTP
3-Jul-13 RLA compatibility changes for extended interrupts
03-Jul-13 RLA compatibility changes for extended interrupts
23-May-13 RLA Move the SMK/OTK to h316_cpu (where it belongs!)
Allow the CLK device to be disabled
09-Jun-07 RMS Fixed bug in clock increment (Theo Engel)

View file

@ -1,6 +1,6 @@
/* h316_sys.c: Honeywell 316/516 simulator interface
Copyright (c) 1999-2008, Robert M Supnik
Copyright (c) 1999-2015, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,8 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
15-Sep-13 RMS Added device name support for IO instructions
Fixed handling of OTK
21-May-13 RLA Add IMP/TIP devices
01-Dec-04 RMS Fixed fprint_opr calling sequence
24-Oct-03 RMS Added DMA/DMC support
@ -144,7 +146,7 @@ static const char *opcode[] = {
"CAR", "CAL", "ICL",
"AOA", "ACA", "ICR", "ICA",
"NOP", "SKP", "SSR", "SSS",
"JMP", "JMP*",
"OTK", "JMP", "JMP*",
"LDA", "LDA*", "ANA", "ANA*",
"STA", "STA*", "ERA", "ERA*",
"ADD", "ADD*", "SUB", "SUB*",
@ -168,6 +170,17 @@ static const char *opcode[] = {
NULL
};
static const char *ioname[DEV_MAX] = {
NULL, "PTR", "PTP", "LPT", "TTY", "CDR", NULL, NULL,
"MT", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"CLK", NULL, "FHD", NULL, "DMA", "DP", NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static const int32 opc_val[] = {
0000000+I_NPN, 0000005+I_NPN, 0000007+I_NPN,
0000011+I_NPN, 0000013+I_NPN, 0000021+I_NPN,
@ -179,7 +192,7 @@ static const int32 opc_val[] = {
0141044+I_NPN, 0141050+I_NPN, 0141140+I_NPN,
0141206+I_NPN, 0141216+I_NPN, 0141240+I_NPN, 0141340+I_NPN,
0101000+I_NPN, 0100000+I_NPN, 0100036+I_NPN, 0101036+I_NPN,
0002000+I_MRF, 0102000+I_MRF,
0171020+I_NPN, 0002000+I_MRF, 0102000+I_MRF,
0004000+I_MRF, 0104000+I_MRF, 0006000+I_MRF, 0106000+I_MRF,
0010000+I_MRF, 0110000+I_MRF, 0012000+I_MRF, 0112000+I_MRF,
0014000+I_MRF, 0114000+I_MRF, 0016000+I_MRF, 0116000+I_MRF,
@ -251,7 +264,7 @@ return;
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
UNIT *uptr, int32 sw)
{
int32 cflag, i, j, inst, disp;
int32 cflag, i, j, inst, fnc, disp;
cflag = (uptr == NULL) || (uptr == &cpu_unit);
inst = val[0];
@ -295,8 +308,11 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
break;
case I_V_IOT: /* I/O */
disp = inst & 01777; /* pulse+dev */
fprintf (of, "%s %o", opcode[i], disp);
fnc = I_GETFNC (inst); /* get func */
disp = inst & DEVMASK; /* get dev */
if (ioname[disp] != NULL)
fprintf (of, "%s %o,%s", opcode[i], fnc, ioname[disp]);
else fprintf (of, "%s %o,%o", opcode[i], fnc, disp);
break;
case I_V_SHF: /* shift */
@ -364,11 +380,29 @@ switch (j) { /* case on class */
break;
case I_V_IOT: /* IOT */
cptr = get_glyph (cptr, gbuf, 0); /* get pulse+dev */
d = get_uint (gbuf, 8, 01777, &r);
cptr = get_glyph (cptr, gbuf, ','); /* get field */
if (*cptr == 0) { /* single field? */
d = get_uint (gbuf, 8, 01777, &r); /* pulse+dev */
if (r != SCPE_OK)
return SCPE_ARG;
val[0] = val[0] | d;
}
else { /* multiple fields */
d = get_uint (gbuf, 8, 017, &r); /* get pulse */
if (r != SCPE_OK)
return SCPE_ARG;
cptr = get_glyph (cptr, gbuf, 0); /* get dev name */
for (k = 0; k < DEV_MAX; k++) { /* sch for name */
if ((ioname[k] != NULL) && (strcmp (gbuf, ioname[k]) == 0))
break; /* match? */
}
if (k >= DEV_MAX) { /* no match */
k = get_uint (gbuf, 8, DEV_MAX - 1, &r);/* integer */
if (r != SCPE_OK)
return SCPE_ARG;
}
val[0] = val[0] | (d << I_V_FNC) | k;
}
break;
case I_V_SHF: /* shift */