From fb3c5327b776cf7f8052502e1ea61b8ac401f7b7 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Fri, 3 Apr 2015 18:49:44 -0700 Subject: [PATCH] H316: Merge updates from Bob Supnik and Bob Armstrong (Instruction decoding) --- H316/h316_cpu.c | 118 +++++++++++++++++++++++++-------------------- H316/h316_defs.h | 87 ++++++++++++++++----------------- H316/h316_dp.c | 4 +- H316/h316_fhd.c | 6 +-- H316/h316_lp.c | 4 +- H316/h316_mt.c | 2 +- H316/h316_stddev.c | 4 +- H316/h316_sys.c | 56 ++++++++++++++++----- 8 files changed, 165 insertions(+), 116 deletions(-) diff --git a/H316/h316_cpu.c b/H316/h316_cpu.c index 92e77eac..16f53628 100644 --- a/H316/h316_cpu.c +++ b/H316/h316_cpu.c @@ -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"), @@ -276,9 +276,9 @@ int32 sc = 0; /* shift count */ int32 ss[4]; /* sense switches */ int32 dev_int = 0; /* dev ready */ int32 dev_enb = 0; /* dev enable */ -uint32 ext_ints = 0; // [RLA] 16 if extended interrupts enabled -uint16 dev_ext_int = 0; // [RLA] extended interrupt request bitmap -uint16 dev_ext_enb = 0; // [RLA] extended interrupt enable bitmap +uint32 ext_ints = 0; // [RLA] 16 if extended interrupts enabled +uint16 dev_ext_int = 0; // [RLA] extended interrupt request bitmap +uint16 dev_ext_enb = 0; // [RLA] extended interrupt enable bitmap int32 ind_max = 8; /* iadr nest limit */ int32 stop_inst = 1; /* stop on ill inst */ int32 stop_dev = 2; /* stop on ill dev */ @@ -405,10 +405,10 @@ t_stat sim_instr (void) { int32 AR, BR, MB, Y, t1, t2, t3, skip, dev; uint32 ut; -t_bool iack; // [RLA] TRUE if an interrupt was taken this cycle +t_bool iack; // [RLA] TRUE if an interrupt was taken this cycle t_stat reason; t_stat Ea (int32 inst, int32 *addr); -t_stat Write (int32 addr, int32 val); // [RLA] Write() can now cause a break +t_stat Write (int32 addr, int32 val); // [RLA] Write() can now cause a break int32 Add16 (int32 val1, int32 val2); int32 Add31 (int32 val1, int32 val2); int32 Operate (int32 MB, int32 AR); @@ -508,14 +508,17 @@ 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; - } -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; - } + 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; + } /* Instruction fetch */ @@ -542,7 +545,7 @@ if (hst_lnt) { /* instr hist? */ hst[hst_p].ar = AR; hst[hst_p].br = BR; hst[hst_p].xr = XR; - hst[hst_p].iack = iack; // [RLA] record if interrupt taken + hst[hst_p].iack = iack; // [RLA] record if interrupt taken } /* Memory reference instructions */ @@ -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 */ @@ -730,7 +739,7 @@ switch (I_GETOP (MB)) { /* case on <1:6> */ if ((dev == 020) || (dev == 024)) t2 = sim_ota_2024(ioOTA, I_GETFNC (MB), AR, dev); else - t2 = iotab[dev] (ioOTA, I_GETFNC (MB), AR, dev); + t2 = iotab[dev] (ioOTA, I_GETFNC (MB), AR, dev); reason = t2 >> IOT_V_REASON; if (t2 & IOT_SKIP) /* skip? */ PC = NEWA (PC, PC + 1); @@ -1092,16 +1101,16 @@ 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'))) - return STOP_IBKPT; - else - return SCPE_OK; + // [RLA] Implement "break on memory write" ... + if (sim_brk_summ && sim_brk_test (addr, SWMASK ('W'))) + return STOP_IBKPT; + else + return SCPE_OK; } /* Add */ @@ -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)) { @@ -1685,21 +1697,23 @@ for (i = 0; (dptr = sim_devices[i]); i++) { /* loop thru devices */ for (j = 0; j < dibp->num; j++) { /* repeat for slots */ if (iotab[dno + j]) { /* conflict? */ sim_printf ("%s device number conflict, devno = %02o\n", - sim_dname (dptr), dno + j); + sim_dname (dptr), dno + j); return TRUE; } iotab[dno + j] = dibp->io; /* set I/O routine */ } /* end for */ - // [RLA] set up the channel map - if (dibp->chan != 0) - 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; - // [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)) { + // [RLA] set up the channel map + if (dibp->chan != 0) + 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; + // [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)); return TRUE; - } + } } /* end for */ for (i = 0; i < DEV_MAX; i++) { /* fill in blanks */ if (iotab[i] == NULL) diff --git a/H316/h316_defs.h b/H316/h316_defs.h index af051de1..dc7a8ba6 100644 --- a/H316/h316_defs.h +++ b/H316/h316_defs.h @@ -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"), @@ -33,7 +33,7 @@ */ #ifndef H316_DEFS_H_ -#define H316_DEFS_H_ 0 +#define H316_DEFS_H_ 0 #include "sim_defs.h" /* simulator defns */ @@ -111,14 +111,14 @@ /* Device information block */ struct h316_dib { - uint32 dev; /* device number */ - uint32 num; /* number of slots */ - uint32 chan; /* dma/dmc channel */ - uint32 chan2; /* alternate DMA/DMD channel */ - uint32 inum; /* interrupt number */ - uint32 inum2; /* alternate interrupt */ - int32 (*io) (int32 inst, int32 fnc, int32 dat, int32 dev); - uint32 u3; /* "user" parameter #1 */ + uint32 dev; /* device number */ + uint32 num; /* number of slots */ + uint32 chan; /* dma/dmc channel */ + uint32 chan2; /* alternate DMA/DMD channel */ + uint32 inum; /* interrupt number */ + uint32 inum2; /* alternate interrupt */ + int32 (*io) (int32 inst, int32 fnc, int32 dat, int32 dev); + uint32 u3; /* "user" parameter #1 */ }; typedef struct h316_dib DIB; @@ -147,35 +147,35 @@ typedef struct h316_dib DIB; /* I/O device codes */ -#define PTR 001 /* paper tape reader */ -#define PTP 002 /* paper tape punch */ -#define LPT 003 /* line printer */ -#define TTY 004 /* console */ -#define CDR 005 /* card reader */ -#define MT 010 /* mag tape data */ -#define CLK_KEYS 020 /* clock/keys (CPU) */ -#define FHD 022 /* fixed head disk */ -#define DMA 024 /* DMA control */ -#define DP 025 /* moving head disk */ +#define PTR 001 /* paper tape reader */ +#define PTP 002 /* paper tape punch */ +#define LPT 003 /* line printer */ +#define TTY 004 /* console */ +#define CDR 005 /* card reader */ +#define MT 010 /* mag tape data */ +#define CLK_KEYS 020 /* clock/keys (CPU) */ +#define FHD 022 /* fixed head disk */ +#define DMA 024 /* DMA control */ +#define DP 025 /* moving head disk */ #define DEV_MAX 64 /* Interrupt flags, definitions correspond to SMK bits */ -#define INT_V_CLK 0 /* clock */ -#define INT_V_MPE 1 /* parity error */ -#define INT_V_LPT 2 /* line printer */ -#define INT_V_CDR 4 /* card reader */ -#define INT_V_TTY 5 /* teletype */ -#define INT_V_PTP 6 /* paper tape punch */ -#define INT_V_PTR 7 /* paper tape reader */ -#define INT_V_FHD 8 /* fixed head disk */ -#define INT_V_DP 12 /* moving head disk */ -#define INT_V_MT 15 /* mag tape */ -#define INT_V_START 16 /* start button */ -#define INT_V_NODEF 17 /* int not deferred */ -#define INT_V_ON 18 /* int on */ -#define INT_V_EXTD 16 /* first extended interrupt */ -#define INT_V_NONE 0xffffffff /* no interrupt used */ +#define INT_V_CLK 0 /* clock */ +#define INT_V_MPE 1 /* parity error */ +#define INT_V_LPT 2 /* line printer */ +#define INT_V_CDR 4 /* card reader */ +#define INT_V_TTY 5 /* teletype */ +#define INT_V_PTP 6 /* paper tape punch */ +#define INT_V_PTR 7 /* paper tape reader */ +#define INT_V_FHD 8 /* fixed head disk */ +#define INT_V_DP 12 /* moving head disk */ +#define INT_V_MT 15 /* mag tape */ +#define INT_V_START 16 /* start button */ +#define INT_V_NODEF 17 /* int not deferred */ +#define INT_V_ON 18 /* int on */ +#define INT_V_EXTD 16 /* first extended interrupt */ +#define INT_V_NONE 0xffffffff /* no interrupt used */ /* I/O macros */ @@ -204,20 +204,21 @@ typedef struct h316_dib DIB; // [RLA] These macros now all affect the standard interrupts. We'll leave // [RLA] them alone for backward compatibility with the existing code. -#define SET_INT(x) dev_int = dev_int | (x) +#define SET_INT(x) dev_int = dev_int | (x) #define CLR_INT(x) dev_int = dev_int & ~(x) -#define TST_INT(x) ((dev_int & (x)) != 0) +#define TST_INT(x) ((dev_int & (x)) != 0) #define CLR_ENB(x) dev_enb = dev_enb & ~(x) -#define TST_INTREQ(x) ((dev_int & dev_enb & (x)) != 0) +#define TST_INTREQ(x) ((dev_int & dev_enb & (x)) != 0) // [RLA] These macros are functionally identical, but affect extended interrupts. -#define SET_EXT_INT(x) dev_ext_int = dev_ext_int | (x) -#define CLR_EXT_INT(x) dev_ext_int = dev_ext_int & ~(x) -#define TST_EXT_INT(x) ((dev_ext_int & (x)) != 0) -#define CLR_EXT_ENB(x) dev_ext_enb = dev_ext_enb & ~(x) -#define TST_EXT_INTREQ(x) ((dev_ext_int & dev_ext_enb & (x)) != 0) +#define SET_EXT_INT(x) dev_ext_int = dev_ext_int | (x) +#define CLR_EXT_INT(x) dev_ext_int = dev_ext_int & ~(x) +#define TST_EXT_INT(x) ((dev_ext_int & (x)) != 0) +#define CLR_EXT_ENB(x) dev_ext_enb = dev_ext_enb & ~(x) +#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); diff --git a/H316/h316_dp.c b/H316/h316_dp.c index 5bb93f83..ac0145c7 100644 --- a/H316/h316_dp.c +++ b/H316/h316_dp.c @@ -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 diff --git a/H316/h316_fhd.c b/H316/h316_fhd.c index 57937d83..e711adab 100644 --- a/H316/h316_fhd.c +++ b/H316/h316_fhd.c @@ -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 @@ -375,7 +375,7 @@ uint32 tk = CW1_GETTK (fhd_cw1); /* track */ uint32 ca = CW2_GETCA (fhd_cw2); /* char addr */ uint32 wa = ca >> 1; /* word addr */ uint32 ba = (((sf * FH_NUMTK) + tk) * FH_NUMWD) + wa; /* buffer offset */ -uint16 *fbuf = (uint16 *) uptr->filebuf; /* buffer base */ +uint16 *fbuf = (uint16 *) uptr->filebuf; /* buffer base */ uint32 wd; if (fhd_bad_wa (wa)) /* addr bad? */ diff --git a/H316/h316_lp.c b/H316/h316_lp.c index 815f5d15..6f97d85c 100644 --- a/H316/h316_lp.c +++ b/H316/h316_lp.c @@ -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) diff --git a/H316/h316_mt.c b/H316/h316_mt.c index ef7c2610..320a6ab9 100644 --- a/H316/h316_mt.c +++ b/H316/h316_mt.c @@ -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 diff --git a/H316/h316_stddev.c b/H316/h316_stddev.c index 1abd9130..0e69c782 100644 --- a/H316/h316_stddev.c +++ b/H316/h316_stddev.c @@ -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) diff --git a/H316/h316_sys.c b/H316/h316_sys.c index 02ebe61e..1d640732 100644 --- a/H316/h316_sys.c +++ b/H316/h316_sys.c @@ -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*", @@ -167,6 +169,17 @@ static const char *opcode[] = { NULL, NULL, /* decode only */ 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, @@ -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); - if (r != SCPE_OK) - return SCPE_ARG; - val[0] = val[0] | d; + 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 */