KA10: Added switch for DF10 vs DF10C.

Fix bug in interrupt handling in KI when EPT not at 0.
      Fix bug with handling of CCW_COMP flag on DF10 devices.
This commit is contained in:
Richard Cornwell 2022-06-21 09:43:17 -04:00
parent cc6f8ee8ee
commit 25f053e45d
9 changed files with 142 additions and 81 deletions

View file

@ -162,6 +162,7 @@ int pi_restore; /* Restore previous level */
int pi_hold; /* Hold onto interrupt */ int pi_hold; /* Hold onto interrupt */
int modify; /* Modify cycle */ int modify; /* Modify cycle */
int xct_flag; /* XCT flags */ int xct_flag; /* XCT flags */
int pi_vect; /* Last pi location used for IRQ */
#if KI | KL | KS #if KI | KL | KS
uint64 ARX; /* Extension to AR */ uint64 ARX; /* Extension to AR */
uint64 BRX; /* Extension to BR */ uint64 BRX; /* Extension to BR */
@ -184,13 +185,11 @@ int t20_page; /* Tops 20 paging selected */
int ptr_flg; /* Access to pointer value */ int ptr_flg; /* Access to pointer value */
int extend = 0; /* Process extended instruction */ int extend = 0; /* Process extended instruction */
int fe_xct = 0; /* Execute instruction at address */ int fe_xct = 0; /* Execute instruction at address */
int pi_vect; /* Last pi location used for IRQ */
#if KS_ITS #if KS_ITS
uint64 qua_time; /* Quantum clock value */ uint64 qua_time; /* Quantum clock value */
uint8 pi_act; /* Current active PI level */ uint8 pi_act; /* Current active PI level */
#endif #endif
#elif KL #elif KL
int pi_vect; /* Last pi location used for IRQ */
int ext_ac; /* Extended instruction AC */ int ext_ac; /* Extended instruction AC */
uint8 prev_ctx; /* Previous AC context */ uint8 prev_ctx; /* Previous AC context */
uint16 irq_enable; /* Apr IRQ enable bits */ uint16 irq_enable; /* Apr IRQ enable bits */
@ -404,7 +403,14 @@ t_bool build_dev_tab (void);
#define DEFMEM 256 #define DEFMEM 256
#endif #endif
UNIT cpu_unit[] = { { UDATA (&rtc_srv, UNIT_IDLE|UNIT_FIX|UNIT_BINK|UNIT_TWOSEG, DEFMEM * 1024) }, #if KI_22BIT
#define DF_FLAG UNIT_DF10C
#else
#define DF_FLAG 0
#endif
UNIT cpu_unit[] = { { UDATA (&rtc_srv,
UNIT_IDLE|UNIT_FIX|UNIT_BINK|UNIT_TWOSEG|DF_FLAG, DEFMEM * 1024) },
#if ITS #if ITS
{ UDATA (&qua_srv, UNIT_IDLE|UNIT_DIS, 0) } { UDATA (&qua_srv, UNIT_IDLE|UNIT_DIS, 0) }
#endif #endif
@ -630,6 +636,12 @@ MTAB cpu_mod[] = {
{ UNIT_M_MPX, 0, NULL, "NOMPX", NULL, NULL, NULL, { UNIT_M_MPX, 0, NULL, "NOMPX", NULL, NULL, NULL,
"Disables the MPX device"}, "Disables the MPX device"},
#endif #endif
#if KI | KL
{ UNIT_M_DF10, 0, "DF10", "DF10", NULL, NULL, NULL,
"18 bit DF10"},
{ UNIT_M_DF10, UNIT_DF10C, "DF10C", "DF10C", NULL, NULL, NULL,
"22 bit DF10C"},
#endif
#if PDP6 | KA | KI #if PDP6 | KA | KI
{ UNIT_MAOFF, UNIT_MAOFF, "MAOFF", "MAOFF", NULL, NULL, { UNIT_MAOFF, UNIT_MAOFF, "MAOFF", "MAOFF", NULL, NULL,
NULL, "Interrupts relocated to 140"}, NULL, "Interrupts relocated to 140"},
@ -656,6 +668,7 @@ DEBTAB cpu_debug[] = {
{0, 0} {0, 0}
}; };
DEVICE cpu_dev = { DEVICE cpu_dev = {
"CPU", &cpu_unit[0], cpu_reg, cpu_mod, "CPU", &cpu_unit[0], cpu_reg, cpu_mod,
1+ITS+KL, 8, 22, 1, 8, 36, 1+ITS+KL, 8, 22, 1, 8, 36,
@ -1770,7 +1783,7 @@ void check_apr_irq() {
void cty_interrupt() void cty_interrupt()
{ {
irq_flags |= CON_IRQ; irq_flags |= CON_IRQ;
sim_debug(DEBUG_IRQ, &cpu_dev, "cty interrupt %06o\n", irq_enable); sim_debug(DEBUG_IRQ, &cpu_dev, "cty interrupt %06o\n", irq_enable);
check_apr_irq(); check_apr_irq();
} }
@ -4686,11 +4699,12 @@ st_pi:
#if KL #if KL
sect = cur_sect = 0; sect = cur_sect = 0;
extend = 0; extend = 0;
pi_vect = AB;
#endif #endif
pi_vect = AB;
Mem_read_nopage(); Mem_read_nopage();
goto no_fetch; goto no_fetch;
#elif PDP6 | KA #elif PDP6 | KA
pi_vect = AB;
goto fetch; goto fetch;
#endif #endif
} }
@ -12049,16 +12063,13 @@ last:
trap_flag = 0; trap_flag = 0;
} }
#endif #endif
/* Check if I/O and BLKI/O or DATAI/O */
if ((IR & 0700) == 0700 && ((AC & 04) == 0)) { if ((IR & 0700) == 0700 && ((AC & 04) == 0)) {
pi_hold = pi_ov; pi_hold = pi_ov;
if ((!pi_hold) & f_inst_fetch) { if ((!pi_hold) && f_inst_fetch) {
pi_cycle = 0; pi_cycle = 0;
} else { } else {
#if KL | KS
AB = pi_vect | pi_ov; AB = pi_vect | pi_ov;
#else
AB = 040 | (pi_enc << 1) | maoff | pi_ov;
#endif
#if KI | KL #if KI | KL
Mem_read_nopage(); Mem_read_nopage();
#elif KS #elif KS
@ -12069,14 +12080,11 @@ last:
goto no_fetch; goto no_fetch;
} }
} else if (pi_hold && !f_pc_inh) { } else if (pi_hold && !f_pc_inh) {
/* Check if I/O, then check if IRQ was raised */
if ((IR & 0700) == 0700) { if ((IR & 0700) == 0700) {
(void)check_irq_level(); (void)check_irq_level();
} }
#if KL | KS
AB = pi_vect | pi_ov; AB = pi_vect | pi_ov;
#else
AB = 040 | (pi_enc << 1) | maoff | pi_ov;
#endif
pi_ov = 0; pi_ov = 0;
pi_hold = 0; pi_hold = 0;
#if KI | KL #if KI | KL

View file

@ -346,11 +346,9 @@ extern DEBTAB crd_debug[];
#define API_MASK 0000000007 #define API_MASK 0000000007
#define PI_ENABLE 0000000010 /* Clear DONE */ #define PI_ENABLE 0000000010 /* Clear DONE */
#define BUSY 0000000020 /* STOP */ #define BUSY 0000000020 /* STOP */
#define CCW_COMP 0000000040 /* Write Final CCW */
/* RH10 / RH20 interrupt */ /* RH10 / RH20 interrupt */
#define IADR_ATTN 0000000000040LL /* Interrupt on attention */ #define IADR_ATTN 0000000000040LL /* Interrupt on attention */
#define IARD_RAE 0000000000100LL /* Interrupt on register access error */ #define IARD_RAE 0000000000100LL /* Interrupt on register access error */
#define CCW_COMP_1 0000000040000LL /* Control word written. */
#if KI #if KI
#define DEF_SERIAL 514 /* Default DEC test machine */ #define DEF_SERIAL 514 /* Default DEC test machine */
@ -423,6 +421,10 @@ extern DEBTAB crd_debug[];
#define UNIT_V_MPX (UNIT_V_WAITS + 1) #define UNIT_V_MPX (UNIT_V_WAITS + 1)
#define UNIT_M_MPX (1 << UNIT_V_MPX) #define UNIT_M_MPX (1 << UNIT_V_MPX)
#define UNIT_MPX (UNIT_M_MPX) /* MPX Device for ITS */ #define UNIT_MPX (UNIT_M_MPX) /* MPX Device for ITS */
#define UNIT_V_DF10 (UNIT_V_MPX + 1) /* DF10 18 bit or 22 bit */
#define UNIT_M_DF10 (1 << UNIT_V_DF10)
#define UNIT_DF10C (UNIT_M_DF10)
#define UNIT_DF10 0
#define CNTRL_V_RH (UNIT_V_UF + 4) #define CNTRL_V_RH (UNIT_V_UF + 4)
#define CNTRL_M_RH 7 #define CNTRL_M_RH 7
#define GET_CNTRL_RH(x) (((x) >> CNTRL_V_RH) & CNTRL_M_RH) #define GET_CNTRL_RH(x) (((x) >> CNTRL_V_RH) & CNTRL_M_RH)
@ -525,6 +527,8 @@ extern DEVICE dz_dev;
extern DEVICE kmc_dev; extern DEVICE kmc_dev;
extern DEVICE dup_dev; extern DEVICE dup_dev;
extern DEVICE tcu_dev; extern DEVICE tcu_dev;
extern DEVICE ddc_dev;
extern DEVICE tym_dev;
#if KS #if KS
@ -620,9 +624,11 @@ struct df10 {
uint32 wcr; /* CUrrent word count */ uint32 wcr; /* CUrrent word count */
uint32 cda; /* Current transfer address */ uint32 cda; /* Current transfer address */
uint32 devnum; /* Device number */ uint32 devnum; /* Device number */
t_uint64 buf; /* Data buffer */ uint64 buf; /* Data buffer */
uint8 nxmerr; /* Bit to set for NXM */ uint8 nxmerr; /* Bit to set for NXM */
uint8 ccw_comp; /* Have we written out CCW */ uint64 amask; /* Address mask */
uint64 wmask; /* Word mask */
int cshift; /* Shift amount */
} ; } ;
/* RH10/RH20 Interface */ /* RH10/RH20 Interface */
@ -678,6 +684,7 @@ void df10_setup(struct df10 *df, uint32 addr);
int df10_fetch(struct df10 *df); int df10_fetch(struct df10 *df);
int df10_read(struct df10 *df); int df10_read(struct df10 *df);
int df10_write(struct df10 *df); int df10_write(struct df10 *df);
void df10_init(struct df10 *df, uint32 dev_num, uint8 nxmerr);
#if PDP6_DEV #if PDP6_DEV
int dct_read(int u, t_uint64 *data, int c); int dct_read(int u, t_uint64 *data, int c);
int dct_write(int u, t_uint64 *data, int c); int dct_write(int u, t_uint64 *data, int c);
@ -715,7 +722,7 @@ extern void ka10_lights_clear_aux (int);
#if !(PDP6 | KS) #if !(PDP6 | KS)
#define NUM_DEVS_LP 1 #define NUM_DEVS_LP 1
#endif #endif
#if !(KL | KS) #if !(KS)
#define NUM_DEVS_PT 1 #define NUM_DEVS_PT 1
#define NUM_DEVS_CR 1 #define NUM_DEVS_CR 1
#define NUM_DEVS_CP 1 #define NUM_DEVS_CP 1
@ -748,24 +755,25 @@ extern void ka10_lights_clear_aux (int);
#define NUM_DEVS_DUP 2 #define NUM_DEVS_DUP 2
#define NUM_DEVS_KMC 2 #define NUM_DEVS_KMC 2
#if KS_ITS #if KS_ITS
#define NUM_DEVS_IMP KS_ITS
#define NUM_DEVS_CH11 KS_ITS #define NUM_DEVS_CH11 KS_ITS
#endif #endif
#endif #endif
#if KA | KI #if KA | KI
#define NUM_DEVS_RC 1 #define NUM_DEVS_RC 1
#define NUM_DEVS_DT 1
#define NUM_DEVS_DK 1 #define NUM_DEVS_DK 1
#define NUM_DEVS_DP 2 #define NUM_DEVS_DDC 1
#endif #endif
#if KS #if KS
#define NUM_DEVS_RP 1 #define NUM_DEVS_RP 1
#elif KA | KI | KL #elif KA | KI | KL
#define NUM_DEVS_DT 1
#define NUM_DEVS_DP 2
#define NUM_DEVS_RP 4 #define NUM_DEVS_RP 4
#define NUM_DEVS_RS 1 #define NUM_DEVS_RS 1
#endif #endif
#if !(PDP6) #if !(PDP6)
#define NUM_DEVS_TU 1 #define NUM_DEVS_TU 1
#define NUM_DEVS_IMP 1
#endif #endif
#if KA #if KA
#define NUM_DEVS_PMP WAITS #define NUM_DEVS_PMP WAITS
@ -780,19 +788,20 @@ extern void ka10_lights_clear_aux (int);
#define NUM_DEVS_MTY ITS #define NUM_DEVS_MTY ITS
#define NUM_DEVS_TEN11 ITS #define NUM_DEVS_TEN11 ITS
#define NUM_DEVS_AUXCPU ITS #define NUM_DEVS_AUXCPU ITS
#define NUM_DEVS_IMP ITS
#define NUM_DEVS_CH10 ITS #define NUM_DEVS_CH10 ITS
#define NUM_DEVS_DPK ITS #define NUM_DEVS_DPK ITS
#define NUM_DEVS_AI ITS #define NUM_DEVS_AI ITS
#endif #endif
#if KL_ITS #if KL_ITS
#define NUM_DEVS_PD KL_ITS #define NUM_DEVS_PD KL_ITS
#define NUM_DEVS_IMP KL_ITS
#define NUM_DEVS_CH10 KL_ITS #define NUM_DEVS_CH10 KL_ITS
#endif #endif
#if MAGIC_SWITCH && !KA && !ITS #if MAGIC_SWITCH && !KA && !ITS
#error "Magic switch only valid on KA10 with ITS mods" #error "Magic switch only valid on KA10 with ITS mods"
#endif #endif
#if KI
#define NUM_DEVS_TYM 1
#endif
/* Global data */ /* Global data */

View file

@ -25,23 +25,25 @@
/* Set an IRQ for a DF10 device */ /* Set an IRQ for a DF10 device */
void df10_setirq(struct df10 *df) { void
df10_setirq(struct df10 *df) {
df->status |= PI_ENABLE; df->status |= PI_ENABLE;
set_interrupt(df->devnum, df->status); set_interrupt(df->devnum, df->status);
} }
/* Generate the DF10 complete word */ /* Generate the DF10 complete word */
void df10_writecw(struct df10 *df) { void
df10_writecw(struct df10 *df) {
uint64 wrd; uint64 wrd;
df->status |= 1 << df->ccw_comp;
if (df->wcr != 0) if (df->wcr != 0)
df->cda++; df->cda++;
wrd = ((uint64)(df->ccw & WMASK) << CSHIFT) | ((uint64)(df->cda) & AMASK); wrd = ((uint64)(df->ccw & df->wmask) << df->cshift) | ((uint64)(df->cda) & df->amask);
(void)Mem_write_word(df->cia|1, &wrd, 0); (void)Mem_write_word(df->cia|1, &wrd, 0);
} }
/* Finish off a DF10 transfer */ /* Finish off a DF10 transfer */
void df10_finish_op(struct df10 *df, int flags) { void
df10_finish_op(struct df10 *df, int flags) {
df->status &= ~BUSY; df->status &= ~BUSY;
df->status |= flags; df->status |= flags;
df10_writecw(df); df10_writecw(df);
@ -49,27 +51,28 @@ void df10_finish_op(struct df10 *df, int flags) {
} }
/* Setup for a DF10 transfer */ /* Setup for a DF10 transfer */
void df10_setup(struct df10 *df, uint32 addr) { void
df10_setup(struct df10 *df, uint32 addr) {
df->cia = addr & ICWA; df->cia = addr & ICWA;
df->ccw = df->cia; df->ccw = df->cia;
df->wcr = 0; df->wcr = 0;
df->status |= BUSY; df->status |= BUSY;
df->status &= ~(1 << df->ccw_comp);
} }
/* Fetch the next IO control word */ /* Fetch the next IO control word */
int df10_fetch(struct df10 *df) { int
df10_fetch(struct df10 *df) {
uint64 data; uint64 data;
if (Mem_read_word(df->ccw, &data, 0)) { if (Mem_read_word(df->ccw, &data, 0)) {
df10_finish_op(df, df->nxmerr); df10_finish_op(df, df->nxmerr);
return 0; return 0;
} }
while((data & (WMASK << CSHIFT)) == 0) { while((data & (df->wmask << df->cshift)) == 0) {
if ((data & AMASK) == 0 || (uint32)(data & AMASK) == df->ccw) { if ((data & df->amask) == 0 || (uint32)(data & df->amask) == df->ccw) {
df10_finish_op(df,0); df10_finish_op(df,0);
return 0; return 0;
} }
df->ccw = (uint32)(data & AMASK); df->ccw = (uint32)(data & df->amask);
if (Mem_read_word(df->ccw, &data, 0)) { if (Mem_read_word(df->ccw, &data, 0)) {
df10_finish_op(df, 1<<df->nxmerr); df10_finish_op(df, 1<<df->nxmerr);
return 0; return 0;
@ -77,27 +80,28 @@ int df10_fetch(struct df10 *df) {
} }
#if KA & ITS #if KA & ITS
if (cpu_unit[0].flags & UNIT_ITSPAGE) { if (cpu_unit[0].flags & UNIT_ITSPAGE) {
df->wcr = (uint32)((data >> CSHIFT) & 0077777) | 0700000; df->wcr = (uint32)((data >> df->cshift) & 0077777) | 0700000;
df->cda = (uint32)(data & RMASK); df->cda = (uint32)(data & RMASK);
df->cda |= (uint32)((data >> 15) & 00000007000000LL) ^ 07000000; df->cda |= (uint32)((data >> 15) & 00000007000000LL) ^ 07000000;
df->ccw = (uint32)((df->ccw + 1) & AMASK); df->ccw = (uint32)((df->ccw + 1) & df->amask);
return 1; return 1;
} }
#endif #endif
df->wcr = (uint32)((data >> CSHIFT) & WMASK); df->wcr = (uint32)((data >> df->cshift) & df->wmask);
df->cda = (uint32)(data & AMASK); df->cda = (uint32)(data & df->amask);
df->ccw = (uint32)((df->ccw + 1) & AMASK); df->ccw = (uint32)((df->ccw + 1) & df->amask);
return 1; return 1;
} }
/* Read next word */ /* Read next word */
int df10_read(struct df10 *df) { int
df10_read(struct df10 *df) {
uint64 data; uint64 data;
if (df->wcr == 0) { if (df->wcr == 0) {
if (!df10_fetch(df)) if (!df10_fetch(df))
return 0; return 0;
} }
df->wcr = (uint32)((df->wcr + 1) & WMASK); df->wcr = (uint32)((df->wcr + 1) & df->wmask);
if (df->cda != 0) { if (df->cda != 0) {
if (df->cda > MEMSIZE) { if (df->cda > MEMSIZE) {
df10_finish_op(df, 1<<df->nxmerr); df10_finish_op(df, 1<<df->nxmerr);
@ -108,7 +112,7 @@ int df10_read(struct df10 *df) {
df->cda = (uint32)((df->cda + 1) & RMASK) | (df->cda & 07000000); df->cda = (uint32)((df->cda + 1) & RMASK) | (df->cda & 07000000);
else else
#endif #endif
df->cda = (uint32)((df->cda + 1) & AMASK); df->cda = (uint32)((df->cda + 1) & df->amask);
if (Mem_read_word(df->cda, &data, 0)) { if (Mem_read_word(df->cda, &data, 0)) {
df10_finish_op(df, 1<<df->nxmerr); df10_finish_op(df, 1<<df->nxmerr);
return 0; return 0;
@ -124,12 +128,13 @@ int df10_read(struct df10 *df) {
} }
/* Write next word */ /* Write next word */
int df10_write(struct df10 *df) { int
df10_write(struct df10 *df) {
if (df->wcr == 0) { if (df->wcr == 0) {
if (!df10_fetch(df)) if (!df10_fetch(df))
return 0; return 0;
} }
df->wcr = (uint32)((df->wcr + 1) & WMASK); df->wcr = (uint32)((df->wcr + 1) & df->wmask);
if (df->cda != 0) { if (df->cda != 0) {
if (df->cda > MEMSIZE) { if (df->cda > MEMSIZE) {
df10_finish_op(df, 1<<df->nxmerr); df10_finish_op(df, 1<<df->nxmerr);
@ -140,7 +145,7 @@ int df10_write(struct df10 *df) {
df->cda = (uint32)((df->cda + 1) & RMASK) | (df->cda & 07000000); df->cda = (uint32)((df->cda + 1) & RMASK) | (df->cda & 07000000);
else else
#endif #endif
df->cda = (uint32)((df->cda + 1) & AMASK); df->cda = (uint32)((df->cda + 1) & df->amask);
if (Mem_write_word(df->cda, &df->buf, 0)) { if (Mem_write_word(df->cda, &df->buf, 0)) {
df10_finish_op(df, 1<<df->nxmerr); df10_finish_op(df, 1<<df->nxmerr);
return 0; return 0;
@ -151,3 +156,29 @@ int df10_write(struct df10 *df) {
} }
return 1; return 1;
} }
/* Initialize a DF10 to default values */
void
df10_init(struct df10 *df, uint32 dev_num, uint8 nxmerr)
{
df->status = 0;
df->devnum = dev_num; /* Set device number link */
df->nxmerr = nxmerr; /* Set bit in status for NXM */
#if KI_22BIT
if (cpu_unit[0].flags & UNIT_DF10C) {
df->amask = 00000017777777LL;
df->wmask = 0037777LL;
df->cshift = 22;
} else {
df->amask = RMASK;
df->wmask = RMASK;
df->cshift = 18;
}
#else
df->amask = RMASK;
df->wmask = RMASK;
df->cshift = 18;
#endif
}

View file

@ -30,6 +30,14 @@
#if (NUM_DEVS_DP > 0) #if (NUM_DEVS_DP > 0)
#if KL
#define DP_DIS DEV_DIS
#endif
#ifndef DP_DIS
#define DP_DIS 0
#endif
#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF) #define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF)
#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF #define CLR_BUF(u) u->hwmark = 0xFFFFFFFF
@ -60,6 +68,7 @@
/* CONI/CONO Flags */ /* CONI/CONO Flags */
#define CCW_COMP 0000000000040LL
#define SUF_ERR 0000000000100LL #define SUF_ERR 0000000000100LL
#define SEC_ERR 0000000000200LL #define SEC_ERR 0000000000200LL
#define ILL_CMD 0000000000400LL #define ILL_CMD 0000000000400LL
@ -287,7 +296,6 @@ REG dpa_reg[] = {
{ORDATA(DEVNUM, dp_df10[0].devnum, 9), REG_HRO}, {ORDATA(DEVNUM, dp_df10[0].devnum, 9), REG_HRO},
{ORDATA(BUF, dp_df10[0].buf, 36), REG_HRO}, {ORDATA(BUF, dp_df10[0].buf, 36), REG_HRO},
{ORDATA(NXM, dp_df10[0].nxmerr, 8), REG_HRO}, {ORDATA(NXM, dp_df10[0].nxmerr, 8), REG_HRO},
{ORDATA(COMP, dp_df10[0].ccw_comp, 8), REG_HRO},
{0} {0}
}; };
@ -295,7 +303,7 @@ DEVICE dpa_dev = {
"DPA", dp_unit, dpa_reg, dp_mod, "DPA", dp_unit, dpa_reg, dp_mod,
NUM_UNITS_DP, 8, 18, 1, 8, 36, NUM_UNITS_DP, 8, 18, 1, 8, 36,
NULL, NULL, &dp_reset, &dp_boot, &dp_attach, &dp_detach, NULL, NULL, &dp_reset, &dp_boot, &dp_attach, &dp_detach,
&dp_dib[0], DEV_DISABLE | DEV_DEBUG, 0, dev_debug, &dp_dib[0], DEV_DISABLE | DEV_DEBUG | DP_DIS, 0, dev_debug,
NULL, NULL, &dp_help, NULL, NULL, &dp_description NULL, NULL, &dp_help, NULL, NULL, &dp_description
}; };
@ -311,7 +319,6 @@ REG dpb_reg[] = {
{ORDATA(DEVNUM, dp_df10[1].devnum, 9), REG_HRO}, {ORDATA(DEVNUM, dp_df10[1].devnum, 9), REG_HRO},
{ORDATA(BUF, dp_df10[1].buf, 36), REG_HRO}, {ORDATA(BUF, dp_df10[1].buf, 36), REG_HRO},
{ORDATA(NXM, dp_df10[1].nxmerr, 8), REG_HRO}, {ORDATA(NXM, dp_df10[1].nxmerr, 8), REG_HRO},
{ORDATA(COMP, dp_df10[1].ccw_comp, 8), REG_HRO},
{0} {0}
}; };
@ -319,7 +326,7 @@ DEVICE dpb_dev = {
"DPB", &dp_unit[010], dpb_reg, dp_mod, "DPB", &dp_unit[010], dpb_reg, dp_mod,
NUM_UNITS_DP, 8, 18, 1, 8, 36, NUM_UNITS_DP, 8, 18, 1, 8, 36,
NULL, NULL, &dp_reset, &dp_boot, &dp_attach, &dp_detach, NULL, NULL, &dp_reset, &dp_boot, &dp_attach, &dp_detach,
&dp_dib[1], DEV_DISABLE | DEV_DEBUG, 0, dev_debug, &dp_dib[1], DEV_DISABLE | DEV_DEBUG | DP_DIS, 0, dev_debug,
NULL, NULL, &dp_help, NULL, NULL, &dp_description NULL, NULL, &dp_help, NULL, NULL, &dp_description
}; };
@ -335,7 +342,6 @@ REG dpc_reg[] = {
{ORDATA(DEVNUM, dp_df10[2].devnum, 9), REG_HRO}, {ORDATA(DEVNUM, dp_df10[2].devnum, 9), REG_HRO},
{ORDATA(BUF, dp_df10[2].buf, 36), REG_HRO}, {ORDATA(BUF, dp_df10[2].buf, 36), REG_HRO},
{ORDATA(NXM, dp_df10[2].nxmerr, 8), REG_HRO}, {ORDATA(NXM, dp_df10[2].nxmerr, 8), REG_HRO},
{ORDATA(COMP, dp_df10[2].ccw_comp, 8), REG_HRO},
{0} {0}
}; };
@ -343,7 +349,7 @@ DEVICE dpc_dev = {
"DPC", &dp_unit[020], dpc_reg, dp_mod, "DPC", &dp_unit[020], dpc_reg, dp_mod,
NUM_UNITS_DP, 8, 18, 1, 8, 36, NUM_UNITS_DP, 8, 18, 1, 8, 36,
NULL, NULL, &dp_reset, &dp_boot, &dp_attach, &dp_detach, NULL, NULL, &dp_reset, &dp_boot, &dp_attach, &dp_detach,
&dp_dib[2], DEV_DISABLE | DEV_DEBUG, 0, dev_debug, &dp_dib[2], DEV_DISABLE | DEV_DEBUG | DP_DIS, 0, dev_debug,
NULL, NULL, &dp_help, NULL, NULL, &dp_description NULL, NULL, &dp_help, NULL, NULL, &dp_description
}; };
@ -359,7 +365,6 @@ REG dpd_reg[] = {
{ORDATA(DEVNUM, dp_df10[3].devnum, 9), REG_HRO}, {ORDATA(DEVNUM, dp_df10[3].devnum, 9), REG_HRO},
{ORDATA(BUF, dp_df10[3].buf, 36), REG_HRO}, {ORDATA(BUF, dp_df10[3].buf, 36), REG_HRO},
{ORDATA(NXM, dp_df10[3].nxmerr, 8), REG_HRO}, {ORDATA(NXM, dp_df10[3].nxmerr, 8), REG_HRO},
{ORDATA(COMP, dp_df10[3].ccw_comp, 8), REG_HRO},
{0} {0}
}; };
@ -367,7 +372,7 @@ DEVICE dpd_dev = {
"DPD", &dp_unit[030], dpd_reg, dp_mod, "DPD", &dp_unit[030], dpd_reg, dp_mod,
NUM_UNITS_DP, 8, 18, 1, 8, 36, NUM_UNITS_DP, 8, 18, 1, 8, 36,
NULL, NULL, &dp_reset, &dp_boot, &dp_attach, &dp_detach, NULL, NULL, &dp_reset, &dp_boot, &dp_attach, &dp_detach,
&dp_dib[3], DEV_DISABLE | DEV_DEBUG, 0, dev_debug, &dp_dib[3], DEV_DISABLE | DEV_DEBUG | DP_DIS, 0, dev_debug,
NULL, NULL, &dp_help, NULL, NULL, &dp_description NULL, NULL, &dp_help, NULL, NULL, &dp_description
}; };
@ -411,7 +416,9 @@ t_stat dp_devio(uint32 dev, uint64 *data) {
case CONI: case CONI:
*data = (uint64)(df10->status | uptr->STATUS); *data = (uint64)(df10->status | uptr->STATUS);
#if KI_22BIT #if KI_22BIT
*data |= B22_FLAG; if (cpu_unit[0].flags & UNIT_DF10C) {
*data |= B22_FLAG;
}
#endif #endif
sim_debug(DEBUG_CONI, dptr, "DP %03o CONI %012llo %d PC=%o\n", dev, sim_debug(DEBUG_CONI, dptr, "DP %03o CONI %012llo %d PC=%o\n", dev,
*data, ctlr, PC); *data, ctlr, PC);
@ -433,7 +440,7 @@ t_stat dp_devio(uint32 dev, uint64 *data) {
uptr->STATUS &= ~(CLRMSK2); uptr->STATUS &= ~(CLRMSK2);
if (*data & CCW_COMP) { if (*data & CCW_COMP) {
df10_writecw(df10); df10_writecw(df10);
df10->status &= ~CCW_COMP; df10->status |= CCW_COMP;
} }
if (*data & PI_ENABLE) { if (*data & PI_ENABLE) {
uptr->UFLAGS &= ~DONE; uptr->UFLAGS &= ~DONE;
@ -904,10 +911,7 @@ dp_reset(DEVICE * dptr)
uptr++; uptr++;
} }
for (ctlr = 0; ctlr < NUM_DEVS_DP; ctlr++) { for (ctlr = 0; ctlr < NUM_DEVS_DP; ctlr++) {
dp_df10[ctlr].status = 0; df10_init(&dp_df10[ctlr], dp_dib[ctlr].dev_num, 12);
dp_df10[ctlr].devnum = dp_dib[ctlr].dev_num;
dp_df10[ctlr].nxmerr = 12;
dp_df10[ctlr].ccw_comp = 5;
} }
return SCPE_OK; return SCPE_OK;
} }

View file

@ -43,6 +43,14 @@
#if (NUM_DEVS_MT > 0) #if (NUM_DEVS_MT > 0)
#if KL
#define MT_DIS DEV_DIS
#endif
#ifndef MT_DIS
#define MT_DIS 0
#endif
#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF) #define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF)
#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF #define CLR_BUF(u) u->hwmark = 0xFFFFFFFF
@ -214,7 +222,6 @@ REG mt_reg[] = {
{ORDATA(DEVNUM, mt_df10.devnum, 9), REG_HRO}, {ORDATA(DEVNUM, mt_df10.devnum, 9), REG_HRO},
{ORDATA(BUF, mt_df10.buf, 36), REG_HRO}, {ORDATA(BUF, mt_df10.buf, 36), REG_HRO},
{ORDATA(NXM, mt_df10.nxmerr, 8), REG_HRO}, {ORDATA(NXM, mt_df10.nxmerr, 8), REG_HRO},
{ORDATA(COMP, mt_df10.ccw_comp, 8), REG_HRO},
{0} {0}
}; };
@ -222,7 +229,7 @@ DEVICE mt_dev = {
"MTA", mt_unit, mt_reg, mt_mod, "MTA", mt_unit, mt_reg, mt_mod,
8, 8, 15, 1, 8, 8, 8, 8, 15, 1, 8, 8,
NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach,
&mt_dib, DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug, &mt_dib, DEV_DISABLE | DEV_DEBUG | DEV_TAPE | MT_DIS, 0, dev_debug,
NULL, NULL, &mt_help, NULL, NULL, &mt_description NULL, NULL, &mt_help, NULL, NULL, &mt_description
}; };
@ -379,7 +386,7 @@ t_stat mt_devio(uint32 dev, uint64 *data) {
if ((dptr->flags & MTDF_TYPEB) == 0) if ((dptr->flags & MTDF_TYPEB) == 0)
res |= WT_CW_DONE|DATA_PARITY|NXM_ERR|CW_PAR_ERR; res |= WT_CW_DONE|DATA_PARITY|NXM_ERR|CW_PAR_ERR;
#if KI_22BIT #if KI_22BIT
if (dptr->flags & MTDF_TYPEB) if (dptr->flags & MTDF_TYPEB && cpu_unit[0].flags & UNIT_DF10C)
res |= B22_FLAG; res |= B22_FLAG;
#endif #endif
*data = res; *data = res;
@ -397,8 +404,10 @@ t_stat mt_devio(uint32 dev, uint64 *data) {
mt_hold_reg ^= mt_df10.buf; mt_hold_reg ^= mt_df10.buf;
} }
if (dptr->flags & MTDF_TYPEB) { if (dptr->flags & MTDF_TYPEB) {
if (*data & 04) if (*data & 04) {
df10_writecw(&mt_df10); df10_writecw(&mt_df10);
mt_status |= WT_CW_DONE;
}
if (*data & 010) if (*data & 010)
mt_status &= ~(WT_CW_DONE); mt_status &= ~(WT_CW_DONE);
} }
@ -412,9 +421,10 @@ t_stat mt_devio(uint32 dev, uint64 *data) {
case DATAO|04: case DATAO|04:
/* Set Initial CCW */ /* Set Initial CCW */
if (dptr->flags & MTDF_TYPEB) if (dptr->flags & MTDF_TYPEB) {
df10_setup(&mt_df10, (uint32) *data); df10_setup(&mt_df10, (uint32) *data);
else mt_status &= ~(WT_CW_DONE);
} else
mt_df10.buf ^= mt_hold_reg; mt_df10.buf ^= mt_hold_reg;
sim_debug(DEBUG_DATAIO, dptr, "MT DATAO %03o %012llo\n", dev, *data); sim_debug(DEBUG_DATAIO, dptr, "MT DATAO %03o %012llo\n", dev, *data);
break; break;
@ -1027,9 +1037,7 @@ mt_reset(DEVICE * dptr)
uptr->CNTRL = 0; uptr->CNTRL = 0;
sim_cancel(uptr); sim_cancel(uptr);
} }
mt_df10.devnum = mt_dib.dev_num; df10_init(&mt_df10, mt_dib.dev_num, 24);
mt_df10.nxmerr = 24;
mt_df10.ccw_comp = 25;
mt_pia = 0; mt_pia = 0;
mt_status = 0; mt_status = 0;
mt_sel_unit = 0; mt_sel_unit = 0;

View file

@ -78,6 +78,7 @@
#define NXM_ERR 0000000000400LL /* Non existant memory */ #define NXM_ERR 0000000000400LL /* Non existant memory */
#define ILL_WR 0000000000200LL /* Write to protected area */ #define ILL_WR 0000000000200LL /* Write to protected area */
#define OVRRUN 0000000000100LL /* Over run */ #define OVRRUN 0000000000100LL /* Over run */
#define CCW_COMP 0000000000040LL /* Control word written */
#define RD10_DTYPE 0 #define RD10_DTYPE 0
#define RD10_WDS 32 #define RD10_WDS 32
@ -172,7 +173,6 @@ REG rca_reg[] = {
{ORDATA(DEVNUM, rc_df10[0].devnum, 9), REG_HRO}, {ORDATA(DEVNUM, rc_df10[0].devnum, 9), REG_HRO},
{ORDATA(BUF, rc_df10[0].buf, 36), REG_HRO}, {ORDATA(BUF, rc_df10[0].buf, 36), REG_HRO},
{ORDATA(NXM, rc_df10[0].nxmerr, 8), REG_HRO}, {ORDATA(NXM, rc_df10[0].nxmerr, 8), REG_HRO},
{ORDATA(COMP, rc_df10[0].ccw_comp, 8), REG_HRO},
{0} {0}
}; };
@ -196,7 +196,6 @@ REG rcb_reg[] = {
{ORDATA(DEVNUM, rc_df10[1].devnum, 9), REG_HRO}, {ORDATA(DEVNUM, rc_df10[1].devnum, 9), REG_HRO},
{ORDATA(BUF, rc_df10[1].buf, 36), REG_HRO}, {ORDATA(BUF, rc_df10[1].buf, 36), REG_HRO},
{ORDATA(NXM, rc_df10[1].nxmerr, 8), REG_HRO}, {ORDATA(NXM, rc_df10[1].nxmerr, 8), REG_HRO},
{ORDATA(COMP, rc_df10[1].ccw_comp, 8), REG_HRO},
{0} {0}
}; };
@ -238,7 +237,9 @@ t_stat rc_devio(uint32 dev, uint64 *data) {
case CONI: case CONI:
*data = df10->status; *data = df10->status;
#if KI_22BIT #if KI_22BIT
*data |= B22_FLAG; if (cpu_unit[0].flags & UNIT_DF10C) {
*data |= B22_FLAG;
}
#endif #endif
*data |= PRTLT; *data |= PRTLT;
sim_debug(DEBUG_CONI, dptr, "HK %03o CONI %06o PC=%o\n", dev, sim_debug(DEBUG_CONI, dptr, "HK %03o CONI %06o PC=%o\n", dev,
@ -268,6 +269,7 @@ t_stat rc_devio(uint32 dev, uint64 *data) {
if ((df10->status & BUSY) != 0 && (*data & CCW_COMP) != 0) { if ((df10->status & BUSY) != 0 && (*data & CCW_COMP) != 0) {
df10_writecw(df10); df10_writecw(df10);
df10->status |= CCW_COMP;
} else } else
df10->status &= ~CCW_COMP; df10->status &= ~CCW_COMP;
sim_debug(DEBUG_CONO, dptr, "HK %03o CONO %06o PC=%o %06o\n", dev, sim_debug(DEBUG_CONO, dptr, "HK %03o CONO %06o PC=%o %06o\n", dev,
@ -308,6 +310,7 @@ t_stat rc_devio(uint32 dev, uint64 *data) {
return SCPE_OK; return SCPE_OK;
} }
df10_setup(df10, (uint32)*data); df10_setup(df10, (uint32)*data);
df10->status &= ~CCW_COMP;
tmp = (uint32)(*data >> 15) & ~07; tmp = (uint32)(*data >> 15) & ~07;
cyl = (tmp >> 10) & 0777; cyl = (tmp >> 10) & 0777;
if (((cyl & 017) > 9) || (((cyl >> 4) & 017) > 9)) { if (((cyl & 017) > 9) || (((cyl >> 4) & 017) > 9)) {
@ -488,10 +491,7 @@ rc_reset(DEVICE * dptr)
} }
for (ctlr = 0; ctlr < NUM_DEVS_RC; ctlr++) { for (ctlr = 0; ctlr < NUM_DEVS_RC; ctlr++) {
rc_ipr[ctlr] = 0; rc_ipr[ctlr] = 0;
rc_df10[ctlr].status = 0; df10_init(&rc_df10[ctlr], rc_dib[ctlr].dev_num, 8);
rc_df10[ctlr].devnum = rc_dib[ctlr].dev_num;
rc_df10[ctlr].nxmerr = 8;
rc_df10[ctlr].ccw_comp = 5;
} }
return SCPE_OK; return SCPE_OK;
} }

View file

@ -652,8 +652,10 @@ t_stat rh_devio(uint32 dev, uint64 *data) {
rhc->status &= ~(CXR_ILFC|CXR_SD_RAE); rhc->status &= ~(CXR_ILFC|CXR_SD_RAE);
if (*data & DRE_CLR) if (*data & DRE_CLR)
rhc->status &= ~(CR_DRE); rhc->status &= ~(CR_DRE);
if (*data & WRT_CW) if (*data & WRT_CW) {
rh_writecw(rhc, 0); rh_writecw(rhc, 0);
rhc->status |= (CCW_COMP_1);
}
if (*data & PI_ENABLE) if (*data & PI_ENABLE)
rhc->status &= ~PI_ENABLE; rhc->status &= ~PI_ENABLE;
if (rhc->status & PI_ENABLE) if (rhc->status & PI_ENABLE)
@ -914,7 +916,6 @@ void rh_writecw(struct rh_if *rhc, int nxm) {
#endif #endif
if (nxm) if (nxm)
rhc->status |= CXR_NXM; rhc->status |= CXR_NXM;
rhc->status |= CCW_COMP_1;
if (rhc->wcr != 0) if (rhc->wcr != 0)
rhc->cda++; rhc->cda++;
wrd1 = ((uint64)(rhc->ccw & WMASK) << CSHIFT) | ((uint64)(rhc->cda) & AMASK); wrd1 = ((uint64)(rhc->ccw & WMASK) << CSHIFT) | ((uint64)(rhc->cda) & AMASK);

View file

@ -1207,7 +1207,7 @@ if (len == 0)
#endif #endif
#if !KS #if !KS
rhc->reg = 040; rhc->reg = 040;
rhc->status |= CCW_COMP_1|PI_ENABLE; rhc->status |= PI_ENABLE;
#endif #endif
rhc->drive = uptr - dptr->units; rhc->drive = uptr - dptr->units;
PC = word & RMASK; PC = word & RMASK;

View file

@ -650,7 +650,7 @@ rs_boot(int32 unit_num, DEVICE * rptr)
word = rs_buf[0][ptr++]; word = rs_buf[0][ptr++];
rhc->reg = 040; rhc->reg = 040;
rhc->drive = uptr - dptr->units; rhc->drive = uptr - dptr->units;
rhc->status |= CCW_COMP_1|PI_ENABLE; rhc->status |= PI_ENABLE;
PC = word & RMASK; PC = word & RMASK;
return SCPE_OK; return SCPE_OK;