diff --git a/SEL32/sel32_chan.c b/SEL32/sel32_chan.c index ce198b2..c2beacd 100644 --- a/SEL32/sel32_chan.c +++ b/SEL32/sel32_chan.c @@ -394,6 +394,8 @@ loop: sim_debug(DEBUG_CMD, &cpu_dev, "load_ccw read ccw chan %02x caw %06x IOCD wd 1 %08x\n", chan, chp->chan_caw, word); + sim_debug(DEBUG_CMD, &cpu_dev, "load_ccw read data @ IOCD wd 1 %08x data wd 1 %08x\n", + word, M[(word & 0xffffff)>>2]); /* TIC can't follow TIC or be first in command chain */ if (((word >> 24) & 0xf) == CMD_TIC) { @@ -451,11 +453,18 @@ loop: return 1; /* if none, error */ #ifdef DO_DYNAMIC_DEBUG - if ((chp->chan_dev == 0x1000) && ((chp->ccw_cmd & 0xff) == 0x80)) { +// if ((chp->chan_dev == 0x1000) && ((chp->ccw_cmd & 0xff) == 0x80)) { +// if ((chp->chan_dev == 0x0800) && ((chp->ccw_cmd & 0xff) == 0x04) && +// (chp->ccw_count == 0x0e)) { + if ((chp->chan_dev == 0x0800) && ((chp->ccw_cmd & 0xff) == 0xff)) + cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ); + if ((chp->chan_dev == 0x0800) && ((chp->ccw_cmd & 0xff) == 0x00) && + (chp->ccw_count == 0x24)) { uint32 addr = chp->ccw_addr; /* set the data address */ /* start debugging */ - cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP); - sim_debug(DEBUG_CMD, &cpu_dev, "cmd 80 MT wds @ addr %08x %08x %08x %08x %08x\n", + cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ); +// sim_debug(DEBUG_CMD, &cpu_dev, "cmd 80 MT wds @ addr %08x %08x %08x %08x %08x\n", + sim_debug(DEBUG_CMD, &cpu_dev, "cmd 04 DP wds @ addr %08x %08x %08x %08x %08x\n", addr, M[addr>>2], M[(addr+4)>>2], M[(addr+8)>>2], M[(addr+12)>>2]); } #endif @@ -463,7 +472,7 @@ loop: #ifdef DO_DYNAMIC_DEBUG if ((chp->chan_dev == 0x7efc) && ((chp->ccw_cmd & 0xff) == 0x03) && (chp->ccw_count == 0)) /* start debugging */ - cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP); + cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ); #endif #endif /* Check if this is INCH command */ @@ -515,6 +524,11 @@ loop: chp->chan_status &= STATUS_DEND; /* inch has only channel end status */ sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw INCH %08x saved chan %04x\n", chp->chan_inch_addr, chan); +#ifdef DO_DYNAMIC_DEBUG + if (chp->chan_inch_addr == 0x8580) + /* start debugging */ + cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ); +#endif } #endif @@ -1136,7 +1150,8 @@ t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */ return SCPE_OK; /* just busy CC4 */ } /* the channel is not busy, so return OK */ - *status = 0; /* CCs = 0, accepted */ +//REBOOT *status = 0; /* CCs = 0, accepted */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ sim_debug(DEBUG_CMD, &cpu_dev, "$$$ STOPIO good return chsa %04x chan %04x cmd %02x flags %04x status %04x\n", chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status); @@ -1153,6 +1168,10 @@ t_stat rschnlxio(uint16 lchsa, uint32 *status) { /* reset channel XIO */ int lev, i; uint32 chan = get_chan(lchsa); +#ifdef DO_DYNAMIC_DEBUG +/* start debugging */ +cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ); +#endif /* get the device entry for the logical channel in SPAD */ spadent = SPAD[chan]; /* get spad device entry for logical channel */ chan = spadent & 0x7f00; /* get real channel */ @@ -1256,17 +1275,53 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ sim_debug(DEBUG_CMD, &cpu_dev, "$$$ HIO %04x %04x %02x %04x\n", chsa, chan, chp->ccw_cmd, chp->ccw_flags); +#ifdef OLDWAY + /* see if we have a haltio device entry */ + if (dibp->halt_io != NULL) { /* NULL if no haltio function */ + /* call the device controller to get halt_io status */ + uint32 tempa = dibp->halt_io(uptr); /* get status from device */ + if (tempa != 0) { /* see if sub channel status is ready */ + /* The device must be busy or something, but it is not ready. Return busy */ + sim_debug(DEBUG_CMD, &cpu_dev, "haltxio halt_io call return busy chan %04x cstat %08x\n", + chan, tempa); + chp->chan_status = 0; /* no status anymore */ + *status = CC3BIT|CC4BIT; /* sub channel busy, so CC3|CC4 */ + return SCPE_OK; /* just busy or something, CC3|CC4 */ + } else { + /* we have completed the i/o with error */ + /* the channel is not busy, so return OK */ + *status = 0; /* CCs = 0, accepted */ + sim_debug(DEBUG_CMD, &cpu_dev, + "$$$ HALTIO good return chsa %04x chan %04x cmd %02x flags %04x status %04x\n", + chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status); +// return SCPE_OK; /* No CC's all OK */ + } + } +#endif + /* check for a Command or data chain operation in progresss */ if (chp->ccw_cmd != 0 || (chp->ccw_flags & (FLAG_DC|FLAG_CC)) != 0) { sim_debug(DEBUG_CMD, &cpu_dev, "haltxio busy return CC4 chsa %04x chan %04x\n", chsa, chan); /* reset the DC or CC bits to force completion after current IOCD */ +#ifndef OLDWAY chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ dev_status[chsa] |= STATUS_ECHO; /* show we stopped the cmd */ *status = 0; /* not busy, no CC */ +#else + dev_status[chsa] = 0; /* clear device status */ + chp->chan_status = 0; /* clear the channel status */ + chp->chan_byte = BUFF_EMPTY; /* no data yet */ + chp->ccw_addr = 0; /* clear buffer address */ + chp->chan_caw = 0x0; /* clear IOCD address */ + chp->ccw_count = 0; /* channel byte count 0 bytes*/ + chp->ccw_flags = 0; /* clear flags */ + chp->ccw_cmd = 0; /* read command */ +#endif goto hioret; /* just busy CC4 */ } /* the channel is not busy, so return OK */ - *status = CC2BIT; /* INCH status stored, so CC2 TRY */ +//BOOT *status = CC2BIT; /* INCH status stored, so CC2 TRY */ + *status = CC1BIT; /* request accepted, no status, so CC1 TRY THIS */ hioret: sim_debug(DEBUG_CMD, &cpu_dev, "$$$ HIO END chsa %04x chan %04x cmd %02x flags %04x status %04x\n", chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status); @@ -1300,20 +1355,66 @@ t_stat grabxio(uint16 lchsa, uint32 *status) { /* grab controller XIO n/u /* reset controller XIO */ t_stat rsctlxio(uint16 lchsa, uint32 *status) { /* reset controller XIO */ - int chan = get_chan(lchsa); + DIB *dibp; + UNIT *uptr; uint32 spadent; uint16 chsa; -// CHANP *chp; + CHANP *chp; + int lev, i; + uint32 chan = get_chan(lchsa); /* get the device entry for the logical channel in SPAD */ spadent = SPAD[chan]; /* get spad device entry for logical channel */ - chan = (spadent & 0x7f00) >> 8; /* get real channel */ - chsa = (chan << 8) | (lchsa & 0xff); /* merge sa to real channel */ -// chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + chan = spadent & 0x7f00; /* get real channel */ + chsa = chan; /* use just channel */ + dibp = dev_unit[chsa]; /* get the device information pointer */ + chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */ - *status = 0; /* not busy, no CC */ - sim_debug(DEBUG_CMD, &cpu_dev, "rsctlxio chsa %04x chan %04x\n", chsa, chan); - return 0; + sim_debug(DEBUG_CMD, &cpu_dev, "rsctlxio 1 chan %04x SPAD %08x\n", chsa, spadent); + if (dibp == 0 || uptr == 0) { /* if no dib or unit ptr, CC3 on return */ + *status = CC3BIT; /* not found, so CC3 */ + return SCPE_OK; /* not found, CC3 */ + } + sim_debug(DEBUG_CMD, &cpu_dev, "rsctlxio 2 chan %04x, spad %08x\r\n", chsa, spadent); + if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { /* is unit attached? */ + *status = CC3BIT; /* not attached, so error CC3 */ + return SCPE_OK; /* not found, CC3 */ + } + /* reset the FIFO pointers */ + dibp->chan_fifo_in = 0; + dibp->chan_fifo_out = 0; + dev_status[chan] = 0; /* clear the channel status location */ + chp->chan_inch_addr = 0; /* remove inch status buffer address */ + lev = find_int_lev(chan); /* get our int level */ + INTS[lev] &= ~INTS_ACT; /* clear level active */ + INTS[lev] &= ~INTS_REQ; /* clear level request */ + SPAD[lev+0x80] &= ~SINT_ACT; /* clear spad too */ + + /* now go through all the sa for the channel and stop any IOCLs */ + for (i=0; i<256; i++) { + chsa = chan | i; /* merge sa to real channel */ + dibp = dev_unit[chsa]; /* get the device information pointer */ + if (dibp == 0) + { + continue; /* not used */ + } + chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + if (chp == 0) { + continue; /* not used */ + } + dev_status[chsa] = 0; /* clear device status */ + chp->chan_status = 0; /* clear the channel status */ + chp->chan_byte = BUFF_EMPTY; /* no data yet */ + chp->ccw_addr = 0; /* clear buffer address */ + chp->chan_caw = 0x0; /* clear IOCD address */ + chp->ccw_count = 0; /* channel byte count 0 bytes*/ + chp->ccw_flags = 0; /* clear flags */ + chp->ccw_cmd = 0; /* read command */ + } + sim_debug(DEBUG_CMD, &cpu_dev, "rsctlxio return CC1 chan %04x lev %04x\n", chan, lev); + *status = CC1BIT; /* request accepted, no status, so CC1 TRY THIS */ + return SCPE_OK; /* All OK */ } /* boot from the device (ch/sa) the caller specified */ @@ -1573,7 +1674,7 @@ t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc) { if (dibp == NULL) return SCPE_IERR; - newdev = get_uint(cptr, 16, 0xfff, &r); + newdev = get_uint(cptr, 16, 0xffff, &r); if (r != SCPE_OK) return r; @@ -1590,7 +1691,7 @@ t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc) { if (dptr->flags & DEV_UADDR) { dev_unit[devaddr] = NULL; } else { - devaddr &= dibp->mask | 0x700; + devaddr &= (dibp->mask | 0x7f00); for (i = 0; i < dibp->numunits; i++) dev_unit[devaddr + i] = NULL; } @@ -1600,7 +1701,7 @@ t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc) { if (dev_unit[newdev] != NULL) r = SCPE_ARG; } else { - newdev &= dibp->mask | 0x700; + newdev &= (dibp->mask | 0x7f00); for (i = 0; i < dibp->numunits; i++) { if (dev_unit[newdev + i] != NULL) r = SCPE_ARG; @@ -1614,14 +1715,14 @@ t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc) { /* Update device entry */ if (dptr->flags & DEV_UADDR) { dev_unit[devaddr] = dibp; - uptr->u3 &= ~UNIT_ADDR(0x7ff); + uptr->u3 &= ~UNIT_ADDR(0x7fff); uptr->u3 |= UNIT_ADDR(devaddr); fprintf(stderr, "Set dev %04x\r\n", GET_UADDR(uptr->u3)); } else { for (i = 0; i < dibp->numunits; i++) { dev_unit[devaddr + i] = dibp; uptr = &((dibp->units)[i]); - uptr->u3 &= ~UNIT_ADDR(0x7ff); + uptr->u3 &= ~UNIT_ADDR(0x7fff); uptr->u3 |= UNIT_ADDR(devaddr + i); fprintf(stderr, "Set dev %04x\r\n", GET_UADDR(uptr->u3)); } diff --git a/SEL32/sel32_clk.c b/SEL32/sel32_clk.c index 57f4cd9..f70b2e7 100644 --- a/SEL32/sel32_clk.c +++ b/SEL32/sel32_clk.c @@ -97,7 +97,8 @@ DEVICE rtc_dev = { 1, 8, 8, 1, 8, 8, NULL, NULL, &rtc_reset, /* examine, deposit, reset */ NULL, NULL, NULL, /* boot, attach, detach */ - NULL, 0, 0, NULL, /* dib, dev flags, debug flags, debug */ +// NULL, 0, 0, NULL, /* dib, dev flags, debug flags, debug */ + NULL, DEV_DEBUG, 0, dev_debug, /* dib, dev flags, debug flags, debug */ NULL, NULL, &rtc_help, /* ?, ?, help */ NULL, NULL, &rtc_desc, /* ?, ?, description */ }; @@ -111,8 +112,9 @@ DEVICE rtc_dev = { t_stat rtc_srv (UNIT *uptr) { if (rtc_pie) { /* set pulse intr */ -// time_t result = time(NULL); + time_t result = time(NULL); // fprintf(stderr, "Clock int time %08x\r\n", (uint32)result); + sim_debug(DEBUG_CMD, &rtc_dev, "RT Clock int time %08x\n", (uint32)result); INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */ irq_pend = 1; /* make sure we scan for int */ } @@ -239,7 +241,8 @@ DEVICE itm_dev = { 1, 8, 8, 1, 8, 8, NULL, NULL, &itm_reset, /* examine, deposit, reset */ NULL, NULL, NULL, /* boot, attach, detach */ - NULL, 0, 0, NULL, /* dib, ?, ?, debug */ +// NULL, 0, 0, NULL, /* dib, ?, ?, debug */ + NULL, DEV_DEBUG, 0, dev_debug, /* dib, dev flags, debug flags, debug */ NULL, NULL, &itm_help, /* ?, ?, help */ NULL, NULL, &itm_desc, /* ?, ?, description */ }; @@ -256,7 +259,8 @@ t_stat itm_srv (UNIT *uptr) { if (itm_pie) { /* interrupt enabled? */ time_t result = time(NULL); - fprintf(stderr, "Clock int time %08x\r\n", (uint32)result); +// fprintf(stderr, "Clock int time %08x\r\n", (uint32)result); + sim_debug(DEBUG_CMD, &itm_dev, "Interval Timer expired interrupt time %08x\n", (uint32)result); INTS[itm_lvl] |= INTS_REQ; /* request the interrupt on zero value */ irq_pend = 1; /* make sure we scan for int */ if (itm_cmd == 0x3d) { @@ -284,20 +288,24 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level) itm_cmd = cmd; /* save last cmd */ switch (cmd) { case 0x20: /* stop timer */ -// fprintf(stderr, "clk kill value %08x (%08d)\r\n", cnt, cnt); +// fprintf(stderr, "clk kill value %08x (%08d)\r\n", cnt, cnt); + sim_debug(DEBUG_CMD, &itm_dev, "clk kill value %08x (%08d)\n", cnt, cnt); sim_cancel (&itm_unit); /* cancel itc */ itm_cnt = 0; /* no count reset value */ return 0; /* does not matter, no value returned */ case 0x39: /* load timer with new value and start*/ +// sim_debug(DEBUG_CMD, &itm_dev, "clk 0x39 init value %08x (%08d)\n", cnt, cnt); if (cnt <= 0) cnt = 26042; /* 0x65ba TRY 1,000,000/38.4 */ -// fprintf(stderr, "clk 0x39 init value %08x (%08d)\r\n", cnt, cnt); +// fprintf(stderr, "clk 0x39 init value %08x (%08d)\r\n", cnt, cnt); + sim_debug(DEBUG_CMD, &itm_dev, "clk 0x39 init value %08x (%08d)\n", cnt, cnt); /* start timer with value from user */ sim_activate_after_abs_d (&itm_unit, ((double)cnt * itm_tick_size_x_100) / 100.0); itm_cnt = 0; /* no count reset value */ return 0; /* does not matter, no value returned */ case 0x3d: /* load timer with new value and start*/ -// fprintf(stderr, "clk 0x3d init value %08x (%08d)\r\n", cnt, cnt); +// fprintf(stderr, "clk 0x3d init value %08x (%08d)\r\n", cnt, cnt); + sim_debug(DEBUG_CMD, &itm_dev, "clk 0x3d init value %08x (%08d)\n", cnt, cnt); /* start timer with value from user, reload on zero time */ sim_activate_after_abs_d (&itm_unit, ((double)cnt * itm_tick_size_x_100) / 100.0); itm_cnt = cnt; /* count reset value */ @@ -305,14 +313,17 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level) case 0x60: /* read and stop timer */ /* get timer value and stop timer */ temp = (uint32)(100.0 * sim_activate_time_usecs (&itm_unit) / itm_tick_size_x_100); -// fprintf(stderr, "clk 0x60 temp value %08x (%08d)\r\n", temp, temp); +// fprintf(stderr, "clk 0x60 temp value %08x (%08d)\r\n", temp, temp); + sim_debug(DEBUG_CMD, &itm_dev, "clk 0x60 temp value %08x (%08d)\n", temp, temp); sim_cancel (&itm_unit); return temp; /* return current count value */ case 0x79: /* read the current timer value */ /* get timer value, load new value and start timer */ temp = (uint32)(100.0 * sim_activate_time_usecs (&itm_unit) / itm_tick_size_x_100); -// fprintf(stderr, "clk 0x79 temp value %08x (%08d)\r\n", temp, temp); -// fprintf(stderr, "clk 0x79 init value %08x (%08d)\r\n", cnt, cnt); +// fprintf(stderr, "clk 0x79 temp value %08x (%08d)\r\n", temp, temp); +// fprintf(stderr, "clk 0x79 init value %08x (%08d)\r\n", cnt, cnt); + sim_debug(DEBUG_CMD, &itm_dev, "clk 0x79 temp value %08x (%08d)\n", temp, temp); + sim_debug(DEBUG_CMD, &itm_dev, "clk 0x79 init value %08x (%08d)\n", cnt, cnt); /* start timer to fire after cnt ticks */ sim_activate_after_abs_d (&itm_unit, ((double)cnt * itm_tick_size_x_100) / 100.0); itm_cnt = 0; /* no count reset value */ @@ -320,7 +331,8 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level) case 0x40: /* read the current timer value */ /* return current count value */ temp = (uint32)(100.0 * sim_activate_time_usecs (&itm_unit) / itm_tick_size_x_100); -// fprintf(stderr, "clk 0x40 temp value %08x (%08d)\r\n", temp, temp); +// fprintf(stderr, "clk 0x40 temp value %08x (%08d)\r\n", temp, temp); + sim_debug(DEBUG_CMD, &itm_dev, "clk 0x40 temp value %08x (%08d)\n", temp, temp); return temp; break; } diff --git a/SEL32/sel32_con.c b/SEL32/sel32_con.c index 3dd7136..fc4ca43 100644 --- a/SEL32/sel32_con.c +++ b/SEL32/sel32_con.c @@ -51,6 +51,7 @@ extern void set_devwake(uint16 addr, uint8 flags); /* Held in u3 is the device command and status */ #define CON_INCH 0x00 /* Initialize channel command */ +#define CON_INCH2 0xf0 /* Initialize channel command for processing */ #define CON_WR 0x01 /* Write console */ #define CON_RD 0x02 /* Read console */ #define CON_NOP 0x03 /* No op command */ @@ -101,10 +102,11 @@ con_data[NUM_UNITS_CON]; uint32 atbuf=0; /* attention buffer */ /* forward definitions */ -uint8 con_startcmd(UNIT *, uint16, uint8); +uint8 con_startcmd(UNIT *, uint16, uint8); void con_ini(UNIT *, t_bool); t_stat con_srvi(UNIT *); t_stat con_srvo(UNIT *); +uint8 con_haltio(UNIT *); t_stat con_poll(UNIT *); t_stat con_reset(DEVICE *); @@ -125,7 +127,7 @@ UNIT con_unit[] = { DIB con_dib = { NULL, /* uint8 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */ con_startcmd, /* uint8 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start a command */ - NULL, /* uint8 (*halt_io)(UNIT *uptr) */ /* Stop I/O */ + con_haltio, /* uint8 (*halt_io)(UNIT *uptr) */ /* Stop I/O */ NULL, /* uint8 (*test_io)(UNIT *uptr) */ /* Test I/O */ NULL, /* uint8 (*post_io)(UNIT *uptr) */ /* Post I/O */ con_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ @@ -167,13 +169,13 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { if ((uptr->u3 & CON_MSK) != 0) /* is unit busy */ return SNS_BSY; /* yes, return busy */ - sim_debug(DEBUG_CMD, &con_dev, "con_startcmd chan %04x cmd %02x enter\n", chan, cmd); + sim_debug(DEBUG_CMD, &con_dev, "con_startcmd chan %02x cmd %02x enter\n", chan, cmd); /* process the commands */ switch (cmd & 0xFF) { case CON_INCH: /* 0x00 */ /* INCH command */ sim_debug(DEBUG_CMD, &con_dev, "con_startcmd %04x: Cmd INCH\n", chan); uptr->u3 &= LMASK; /* leave only chsa */ - uptr->u3 |= CON_MSK; /* save INCH command as 0xff */ + uptr->u3 |= CON_INCH2; /* save INCH command as 0xf0 */ uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */ sim_activate(uptr, 10); /* start us off */ return 0; /* no status change */ @@ -220,6 +222,16 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { return 0; /* no status change */ break; +#ifdef JUNK + case 0x0c: /* 0x0C */ /* Unknown command */ + uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */ + uptr->u3 &= LMASK; /* leave only chsa */ + uptr->u3 |= (cmd & CON_MSK); /* save command */ + sim_activate(uptr, 10); /* start us off */ + return 0; /* no status change */ + break; +#endif + case CON_CON: /* 0x1f */ /* Connect, return Data Set ready */ sim_debug(DEBUG_CMD, &con_dev, "con_startcmd %04x: Cmd %02x CON\n", chan, cmd); uptr->u5 |= (SNS_DSR|SNS_DCD); /* Data set ready, Data Carrier detected */ @@ -232,8 +244,12 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { return SNS_CHNEND|SNS_DEVEND; /* good return */ break; +#ifdef JUNK + case 0x0c: /* 0x0C */ /* Unknown command */ +#endif case CON_SNS: /* 0x04 */ /* Sense */ - sim_debug(DEBUG_CMD, &con_dev, "con_startcmd %04x: Cmd Sense %02x\n", chan, uptr->u5); + sim_debug(DEBUG_CMD, &con_dev, + "con_startcmd %04x: Cmd Sense %02x\n", chan, uptr->u5); /* value 4 is Data Set Ready */ /* value 5 is Data carrier detected n/u */ ch = uptr->u5; /* status */ @@ -243,7 +259,9 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { default: /* invalid command */ uptr->u5 |= SNS_CMDREJ; /* command rejected */ - sim_debug(DEBUG_CMD, &con_dev, "con_startcmd %04x: Invalid command Sense %02x\n", chan, uptr->u5); + sim_debug(DEBUG_CMD, &con_dev, + "con_startcmd %04x: Invalid command %02x Sense %02x\n", + chan, cmd, uptr->u5); return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* unit check */ break; } @@ -261,9 +279,15 @@ t_stat con_srvo(UNIT *uptr) { uint8 ch; sim_debug(DEBUG_CMD, &con_dev, "con_srvo enter chsa %04x cmd = %02x\n", chsa, cmd); - if ((cmd == CON_NOP) || (cmd == CON_MSK)) { /* NOP has to do nothing */ + if (cmd == 0x0C) { /* unknown has to do nothing */ + sim_debug(DEBUG_CMD, &con_dev, "con_srvo Unknown (0x0C) chsa %04x cmd = %02x\n", chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + return SCPE_OK; + } + + if ((cmd == CON_NOP) || (cmd == CON_INCH2)) { /* NOP has to do nothing */ uptr->u3 &= LMASK; /* nothing left, command complete */ - if (cmd == CON_MSK) { /* Channel end only for INCH */ + if (cmd == CON_INCH2) { /* Channel end only for INCH */ sim_debug(DEBUG_CMD, &con_dev, "con_srvo INCH chsa %04x cmd = %02x\n", chsa, cmd); chan_end(chsa, SNS_CHNEND); /* done */ } else { @@ -281,8 +305,9 @@ t_stat con_srvo(UNIT *uptr) { } else { /* HACK HACK HACK */ /* simh stops outputing chars to debug file if it is passed a null????? */ -// if (ch == 0) /* do not pass a null char */ -// ch = '@'; /* stop simh abort .... */ + if (ch == 0) /* do not pass a null char */ +//WAS ch = '@'; /* stop simh abort .... */ + ch = ' '; /* stop simh abort .... */ sim_debug(DEBUG_CMD, &con_dev, "con_srvo write %01x: putch 0x%02x\n", unit, ch); sim_putchar(ch); /* output next char to device */ sim_activate(uptr, 20); /* start us off */ @@ -299,11 +324,19 @@ t_stat con_srvi(UNIT *uptr) { uint8 ch; t_stat r; - sim_debug(DEBUG_DATA, &con_dev, "con_srvi enter chsa %04x cmd = %02x\n", chsa, cmd); + sim_debug(DEBUG_EXP, &con_dev, "con_srvi enter chsa %04x cmd = %02x\n", chsa, cmd); - if ((cmd == CON_NOP) || (cmd == CON_MSK)) { /* NOP has do nothing */ +#ifdef JUNK + if (cmd == 0x0C) { /* unknown has to do nothing */ + sim_debug(DEBUG_CMD, &con_dev, "con_srvi Unknown (0x0C) chsa %04x cmd = %02x\n", chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + return SCPE_OK; + } +#endif + + if ((cmd == CON_NOP) || (cmd == CON_INCH2)) { /* NOP is do nothing */ uptr->u3 &= LMASK; /* nothing left, command complete */ - if (cmd == CON_MSK) { /* Channel end only for INCH */ + if (cmd == CON_INCH2) { /* Channel end only for INCH */ sim_debug(DEBUG_CMD, &con_dev, "con_srvi INCH chsa %04x cmd = %02x\n", chsa, cmd); chan_end(chsa, SNS_CHNEND); /* done */ // chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ @@ -321,7 +354,7 @@ t_stat con_srvi(UNIT *uptr) { case CON_ECHO: /* 0x0a */ /* read from device w/ECHO */ if (uptr->u3 & CON_INPUT) { /* input waiting? */ ch = con_data[unit].ibuff[uptr->u4++]; /* get char from read buffer */ - sim_debug(DEBUG_CMD, &con_dev, "con_srvi %04x: read %02x\n", unit, ch); + sim_debug(DEBUG_CMD, &con_dev, "con_srvi unit %02x: read %02x\n", unit, ch); if (chan_write_byte(chsa, &ch)) { /* write byte to memory */ con_data[unit].incnt = 0; /* buffer empty */ cmd = 0; /* no cmd either */ @@ -417,5 +450,25 @@ t_stat con_reset(DEVICE *dptr) { return SCPE_OK; } +/* Handle haltio transfers for console */ +uint8 con_haltio(UNIT *uptr) { + uint16 chsa = GET_UADDR(uptr->u3); + int unit = (uptr - con_unit); /* unit 0 is read, unit 1 is write */ + int cmd = uptr->u3 & CON_MSK; + uint8 ch; + t_stat r; + + sim_debug(DEBUG_EXP, &con_dev, "con_haltio enter chsa %04x cmd = %02x\n", chsa, cmd); + + /* terminate any command */ + if ((uptr->u3 & CON_MSK) != 0) { /* is unit busy */ + uptr->u3 &= LMASK; /* nothing left, command complete */ + uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */ + sim_debug(DEBUG_CMD, &con_dev, "con_srvi HIO chsa %04x cmd = %02x\n", chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + tmxr_set_console_units (&con_unit[0], &con_unit[1]); /* reset console I/O */ + } + return SCPE_OK; +} #endif diff --git a/SEL32/sel32_cpu.c b/SEL32/sel32_cpu.c index 20111d0..36628e1 100644 --- a/SEL32/sel32_cpu.c +++ b/SEL32/sel32_cpu.c @@ -190,7 +190,7 @@ uint32 dummy=0; uint32 pfault; /* page # of fault from read/write */ uint32 BPIX=0; /* # pages loaded for O/S */ uint32 CPIXPL=0; /* highest page loaded for User */ -uint32 CPIXBA=0; /* 24 bit logical address of the User */ +uint32 CPIX=0; /* CPIX user MPL offset */ uint32 HIWM=0; /* max maps loaded so far */ uint32 TLB[2048]; /* Translated addresses for each map entry */ /* bits 0-4 are bits 0-4 from map entry */ @@ -205,6 +205,7 @@ uint32 TLB[2048]; /* Translated addresses for each map /* bits 8-18 has map reg contents for this page (Map << 13) */ /* bit 19-31 is zero for page offset of zero */ +uint32 dummy2=0; uint32 modes; /* Operating modes, bits 0, 5, 6, 7 of PSD1 */ uint8 wait4int = 0; /* waiting for interrupt if set */ @@ -322,7 +323,7 @@ REG cpu_reg[] = { {HRDATAD(HIWM, HIWM, 32, "Max Maps Loaded"), REG_FIT}, {HRDATAD(BPIX, BPIX, 32, "# Maps Loaded for O/S"), REG_FIT}, {HRDATAD(CPIXPL, CPIXPL, 32, "Maximum Map # Loaded for User"), REG_FIT}, - {HRDATAD(CPIXBA, CPIXBA, 32, "24 bit starting address for User"), REG_FIT}, + {HRDATAD(CPIX, CPIX, 32, "Current CPIX user MPL offset"), REG_FIT}, {HRDATAD(CPUSTATUS, CPUSTATUS, 32, "CPU Status Word"), REG_FIT}, {HRDATAD(TRAPSTATUS, TRAPSTATUS, 32, "TRAP Status Word"), REG_FIT}, {HRDATAD(CC, CC, 32, "Condition Codes"), REG_FIT}, @@ -647,7 +648,7 @@ int base_mode[] = { /* Bits 5-15 contain the 11 most-significant bits of the physical address */ /* MSD 0 page limit is used to verify access to O/S pages */ /* CPIXPL page limit is used to verify access to user pages and page faults */ -/* CPIXBA base address is used for user address translation */ +/* CPIX CPIX of user MPL offset */ /* Access to pages outside the limit registers results in a map fault */ #define MAX32 32 /* 32/77 map limit */ @@ -658,7 +659,7 @@ int base_mode[] = { #define RMW(x) (M[(x)>>2]) /* read memory addressed word */ #define WMW(x,y) (M[(x)>>2]=y) /* write memory addressed word */ /* write halfword to memory address */ -#define WMH(x,y) ((x)&2?(M[(x)>>2]=(M[(x)>>]&LMASK)|((y)&RMASK)):(M[(x)>>2]=(M[(x)>>2]&RMASK)|((y)<<16))) +#define WMH(x,y) ((x)&2?(M[(x)>>2]=(M[(x)>>2]&LMASK)|((y)&RMASK)):(M[(x)>>2]=(M[(x)>>2]&RMASK)|((y)<<16))) /* write halfword map register to MAP cache address */ #define WMR(x,y) ((x)&2?(MAPC[(x)>>2]=(MAPC[(x)>>2]&LMASK)|((y)&RMASK)):(MAPC[(x)>>2]=(MAPC[(x)>>2]&RMASK)|((y)<<16))) #define RMR(x) ((x)&2?(MAPC[(x)>>2]&RMASK):(MAPC[(x)>>2]>>16)&RMASK) /* read map register halfword */ @@ -691,23 +692,31 @@ t_stat load_maps(uint32 thepsd[2], uint32 diag) /* master process list is in 0x83 of spad for 7x */ mpl = SPAD[0x83] >> 2; /* get mpl from spad address */ /* check if valid real address */ - if ((mpl & 0x003fffff) >= MEMSIZE) /* see if address is within our memory */ + if ((mpl & 0x003fffff) >= MEMSIZE) { /* see if address is within our memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "MEMORY0 %08x MPL %08x MPL[0] %08x bad\n", + MEMSIZE*4, mpl, M[(mpl)>>2]); return NPMEM; /* no, none present memory error */ + } cpixmsdl = M[mpl + cpix]; /* get msdl from mpl for given cpix */ /* if bit zero of mpl entry is set, use bpix first to load maps */ if (cpixmsdl & BIT0) { /* load bpix maps first */ bpixmsdl = M[mpl + bpix]; /* get bpix msdl word address */ + /* TODO test for valid bpixmsdl addr here */ sdc = (bpixmsdl >> 24) & 0x3f; /* get 6 bit segment description count */ msdl = (bpixmsdl >> 2) & 0x3fffff; /* get 24 bit real address of msdl */ + /* TODO test for valid msdl addr here */ for (i = 0; i < sdc; i++) { /* loop through the msd's */ spc = (M[msdl + i] >> 24) & 0xff; /* get segment page count from msdl */ midl = (M[msdl + i] >> 2) & 0x3fffff; /* get 24 bit real word address of midl */ for (j = 0; j < spc; j++, num++) { /* loop throught the midl's */ - if (num >= MAXMAP) + if (num >= MAXMAP) { + TRAPSTATUS |= 0x8000; /* set bit 16 of trap status */ return MAPFLT; /* map loading overflow, map fault error */ + } /* load 16 bit map descriptors */ map = (M[midl + (j / 2)]); /* get 2 16 bit map entries */ if (j & 1) @@ -732,15 +741,19 @@ t_stat load_maps(uint32 thepsd[2], uint32 diag) } /* now load cpix maps */ cpixmsdl = M[mpl + cpix]; /* get cpix msdl word address */ + /* TODO test for valid cpixmsdl addr here */ sdc = (cpixmsdl >> 24) & 0x3f; /* get 6 bit segment description count */ msdl = (cpixmsdl >> 2) & 0x3fffff; /* get 24 bit real address of msdl */ + /* TODO test for valid msdl addr here */ for (i = 0; i < sdc; i++) { spc = (M[msdl + i] >> 24) & 0xff; /* get segment page count from msdl */ midl = (M[msdl + i] >> 2) & 0x3fffff; /* get 24 bit real word address of midl */ for (j = 0; j < spc; j++, num++) { /* loop through the midl's */ - if (num >= MAXMAP) + if (num >= MAXMAP) { + TRAPSTATUS |= 0x8000; /* set bit 16 of trap status */ return MAPFLT; /* map loading overflow, map fault error */ + } /* load 16 bit map descriptors */ map = (M[midl + (j / 2)]); /* get 2 16 bit map entries */ if (j & 1) @@ -762,8 +775,10 @@ t_stat load_maps(uint32 thepsd[2], uint32 diag) } } /* if none loaded, map fault */ - if (num == 0) + if (num == 0) { + TRAPSTATUS |= 0x8000; /* set bit 16 of trap status */ return MAPFLT; /* map fault error */ + } if (num & 1) { /* clear rest of maps */ /* left hw of map is good, zero right */ map = (MAPC[num/2] & LMASK); /* clean rt hw */ @@ -790,37 +805,63 @@ t_stat load_maps(uint32 thepsd[2], uint32 diag) /* we are mapped, so calculate real address from map information */ cpix = thepsd[1] & 0x3ff8; /* get cpix 11 bit offset from psd wd 2 */ num = 0; /* no maps loaded yet */ - BPIX = 0; /* assume no os maps loaded */ /* master process list is in 0xf3 of spad for concept */ mpl = SPAD[0xf3]; /* get mpl from spad address */ - sim_debug(DEBUG_EXP, &cpu_dev, - "MEMORY %08x MPL %08x MPL[0] %08x MPL[1] %08x MPL[%04x] %08x %08x\n", - MEMSIZE*4, mpl, M[(mpl)>>2], M[(mpl+4)>>2], cpix, M[(cpix+mpl)>>2], M[(cpix+mpl+4)>>2]); + /* check if valid real address */ if ((mpl & MASK24) >= MEMSIZE*4) { /* see if address is within our memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "MEMORY1 %08x MPL %08x MPL[0] %08x bad\n", + MEMSIZE*4, mpl, M[(mpl)>>2]); +#ifdef DO_DYNAMIC_DEBUG + /* start debugging at test 46 of cn.mmm diag */ + cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ); +#endif + TRAPSTATUS |= 0x0200; /* set bit 22 of trap status */ + /* clear all maps */ + for (i=0; i>2], M[(mpl+4)>>2], cpix, M[(cpix+mpl)>>2], M[(cpix+mpl+4)>>2]); + + /* mpl is valid, get msdls for O/S and User */ osmsdl = RMW(mpl+4); /* get msdl pointer from wd 1 of OS MPL entry */ - if ((osmsdl & MASK24)>= (MEMSIZE*4)) /* see if address is within our memory */ - return NPMEM; /* no, non present memory error */ - msdl = RMW(mpl+cpix+4); /* get mpl entry wd 1 for given cpix */ - if ((msdl & MASK24) >= (MEMSIZE*4)) /* see if address is within our memory */ + if ((osmsdl & MASK24)>= (MEMSIZE*4)) { /* see if address is within our memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "MEMORY2 %08x OS MPL[0] %08x MPL[1] %08x bad\n", + MEMSIZE*4, M[(mpl)>>2], M[(mpl+4)>>2]); + TRAPSTATUS |= 0x0200; /* set bit 22 of trap status */ + /* clear all maps */ + for (i=0; i= (MEMSIZE*4)) { /* see if address is within our memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "MEMORY2a %08x OS MPL[0] %08x MPL[1] %08x bad\n", + MEMSIZE*4, M[(mpl)>>2], M[(mpl+4)>>2]); +// return MAPFLT; /* no, none present memory error */ + TRAPSTATUS |= 0x0200; /* set bit 22 of trap status */ + /* clear all maps */ + for (i=0; i= MAXMAP) { sim_debug(DEBUG_EXP, &cpu_dev, "loadmap 4 map fault\n"); + TRAPSTATUS |= 0x8000; /* set bit 16 of trap status */ + /* clear all maps */ + for (i=0; i= MODEL_V6) && (map & 0x8000)) { + map &= 0xe7ff; /* clear access/modify bits in map */ + WMH(osmsdl+(j<<1),map); /* write map content */ + } /* translate the map number to a real address */ - /* put this address in the LTB for later translation */ + /* put this address in the TLB for later translation */ /* copy the map status bits too and set hit bit */ /* set the hit bit in the TLB */ TLB[num] = ((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000) | 0x04000000; @@ -862,101 +947,171 @@ t_stat load_maps(uint32 thepsd[2], uint32 diag) } BPIX = num; /* save the # maps loaded in O/S */ } + skipos: - CPIXPL = 0; /* no user pages yet */ - CPIXBA = 0; /* no user pages yet */ /* sysgen in mpx does not have a valid cpix MPL entry, only a bpix entry */ /* that entry uses 64 map entries to map between target/host systems */ /* When cpix in instruction is zero, just load the O/S specified by MSD 0 */ -#ifdef FIXMPX - if ((cpix == 0) && (num == 0)) /* see if any maps loaded */ -/// return MAPFLT; /* map fault error */ - goto skipcpix; /* only load maps specified by msd 0 */ -#else - if ((cpix == 0) && (num == 0)) { /* see if any maps loaded */ + spc = midl & MASK16; /* get segment page count from user msdl */ + if (((cpix == 0) || spc == 0) && (num == 0)) { /* see if any maps loaded or to load */ sim_debug(DEBUG_EXP, &cpu_dev, "loadmap 3 map fault\n"); - return MAPFLT; /* map fault error */ + TRAPSTATUS |= 0x8000; /* set bit 16 of trap status */ + /* clear all maps */ + for (i=0; i= (MEMSIZE*4)) { /* see if address is within our memory */ +#ifdef DO_DYNAMIC_DEBUG + /* start debugging at test 46 of cn.mmm diag */ + cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ); +#endif + sim_debug(DEBUG_EXP, &cpu_dev, + "MEMORY3a %08x USER MPL[%04x] %08x %08x bad\n", + MEMSIZE*4, cpix, M[(cpix+mpl)>>2], M[(cpix+mpl+4)>>2]); + /* clear all maps */ + for (i=0; i= MAXMAP) { sim_debug(DEBUG_EXP, &cpu_dev, "loadmap 0 map fault\n"); + TRAPSTATUS |= 0x8000; /* set bit 16 of trap status */ + /* clear all user maps */ + for (i=BPIX; i= MODEL_V6) && (map & 0x8000)) { + map &= 0xe7ff; /* clear access/modify bits in map */ + WMH(msdl+(j<<1),map); /* write map content */ + } /* translate the map number to a real address */ - /* put this address in the LTB for later translation */ + /* put this address in the TLB for later translation */ /* copy the map status bits too */ -// TLB[num] = ((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000) | 0x04000000; if (CPU_MODEL < MODEL_V6) if (diag) TLB[num] = (((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000)) | 0x04000000; -// TLB[num] = ((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000); else TLB[num] = (((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000)); -// TLB[num] = (((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000)) | 0x04000000; else TLB[num] = ((map & 0x7ff) << 13) | ((map << 16) & 0xe0000000) | 0x04000000; WMR((num*2),map); /* store the map reg contents into cache */ if ((num < 0x20) || (num > (MAXMAP - 0x10))) - sim_debug(DEBUG_EXP, &cpu_dev, "UserN map #%4x, %04x, map2 %08x, TLB %08x, MAPC %08x\n", - num, map, ((map << 16) & 0xf8000000), TLB[num], MAPC[num/2]); + sim_debug(DEBUG_EXP, &cpu_dev, + "UserN map #%4x, %04x, map2 %08x, TLB %08x, MAPC %08x\n", + num, map, ((map << 16) & 0xf8000000), TLB[num], MAPC[num/2]); } if (num & 1) { /* last map was in left hw, zero right halfword */ WMR((num*2),0); /* zero the map reg contents in cache */ TLB[num++] = 0; /* zero the TLB entry too */ } -//WAS skipcpix: - if (num == 0) { /* see if any maps loaded */ - sim_debug(DEBUG_EXP, &cpu_dev, "loadmap 1 map fault\n"); + if (num == 0) { /* see if any maps loaded */ + sim_debug(DEBUG_EXP, &cpu_dev, "loadmap 1a map fault\n"); + TRAPSTATUS |= 0x8000; /* set bit 16 of trap status */ + /* clear all maps */ + for (i=0; i= MAXMAP) { sim_debug(DEBUG_EXP, &cpu_dev, "loadmap 2 map fault\n"); + TRAPSTATUS |= 0x8000; /* set bit 16 of trap status */ + /* clear all user maps */ + for (i=BPIX; i= MODEL_V6) && (map & 0x8000)) { + map &= 0xe7ff; /* clear access/modify bits in map */ +//TRY WMH(msdl+(j<<1),map); /* write map content */ + } +//HUH TLB[num] = ((map & 0x7ff) << 13) | ((map << 16) & 0xe0000000) | 0x04000000; TLB[num] = 0; /* clear the TLB entry */ +//WAS2 WMR((num*2),map); /* store the map reg contents into cache */ //WAS WMR((num*2),0); /* zero the map reg contents in cache */ if ((num < 0x20) || (num > (MAXMAP - 0x10))) - sim_debug(DEBUG_EXP, &cpu_dev, "UserV map #%4x, %04x, map2 %08x, TLB %08x, MAPC %08x\n", - num, map, ((map << 16) & 0xf8000000), TLB[num], MAPC[num/2]); + sim_debug(DEBUG_EXP, &cpu_dev, + "UserV map #%4x, %04x, map2 %08x, TLB %08x, MAPC %08x\n", + num, map, ((map << 16) & 0xf8000000), TLB[num], MAPC[num/2]); } -// if (num & 1) { -// /* last map was in left hw, zero right halfword */ -/// WMR((num*2),0); /* zero the map reg contents in cache */ -// TLB[num++] = 0; /* zero the TLB entry too */ -// } } skipcpix: - if (num == 0) /* see if any maps loaded */ + if (num == 0) { /* see if any maps loaded */ + TRAPSTATUS |= 0x8000; /* set bit 16 of trap status */ + /* clear all maps */ + for (i=0; i= (MEMSIZE*4)) /* see if address is within our memory */ - return NPMEM; /* no, none present memory error */ - *realaddr = word; /* return the real address */ - return ALLOK; /* all OK, return instruction */ + if (word >= (MEMSIZE*4)) { /* see if address is within our memory */ + return NPMEM; /* no, none present memory error */ + } + *realaddr = word; /* return the real address */ + return ALLOK; /* all OK, return instruction */ } /* we are mapped, so calculate real address from map information */ /* 32/7x machine, 8KW maps */ - index = word >> 15; /* get 4 or 5 bit value */ - map = MAPC[index/2]; /* get two hw map entries */ + index = word >> 15; /* get 4 or 5 bit value */ + map = MAPC[index/2]; /* get two hw map entries */ if (index & 1) /* entry is in rt hw, clear left hw */ - map &= RMASK; /* map is in rt hw */ + map &= RMASK; /* map is in rt hw */ else /* entry is in left hw, move to rt hw */ - map >>= 16; /* map is in left hw */ + map >>= 16; /* map is in left hw */ /* see if map is valid */ if (map & 0x4000) { /* required map is valid, get 9 bit address and merge with 15 bit page offset */ word = ((map & 0x1ff) << 15) | (word & 0x7fff); #ifndef DIAGS_SAYS_ANY_ADDRESS_OK_IF_MAPPED /* check if valid real address */ - if (word >= (MEMSIZE*4)) /* see if address is within our memory */ - return NPMEM; /* no, none present memory error */ + if (word >= (MEMSIZE*4)) /* see if address is within our memory */ + return NPMEM; /* no, none present memory error */ #endif - if ((modes & PRIVBIT) == 0) { /* see if we are in unprivileged mode */ - if (map & 0x2000) /* check if protect bit is set in map entry */ - *prot = 1; /* return memory write protection status */ + if ((modes & PRIVBIT) == 0) { /* see if we are in unprivileged mode */ + if (map & 0x2000) /* check if protect bit is set in map entry */ + *prot = 1; /* return memory write protection status */ } - *realaddr = word; /* return the real address */ - return ALLOK; /* all OK, return instruction */ + *realaddr = word; /* return the real address */ + return ALLOK; /* all OK, return instruction */ } /* map is invalid, so return map fault error */ - return MAPFLT; /* map fault error */ + return MAPFLT; /* map fault error */ } + + /* Everyone else has 2KW maps */ + /* do common processing */ + if (modes & (BASEBIT | EXTDBIT)) + word = addr & 0xffffff; /* get 24 bit address */ else + word = addr & 0x7ffff; /* get 19 bit address */ + if ((modes & MAPMODE) == 0) { + /* we are in unmapped mode, check if valid real address */ + if (word >= (MEMSIZE*4)) /* see if address is within our memory */ + return NPMEM; /* no, none present memory error */ + *realaddr = word; /* return the real address */ + return ALLOK; /* all OK, return instruction */ + } + /* diag wants the mpl entries checked to make sure valid */ + /* master process list is in 0xf3 of spad for concept */ + mpl = SPAD[0xf3] & MASK24; /* get mpl from spad address */ + /* check if valid real address */ + if ((mpl & MASK24) >= MEMSIZE*4) { /* see if address is within our memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "RealAddr MapFault MPL %06x\n", mpl, M[(mpl+4)>>2]); + return NPMEM; /* no, non present memory error */ + } + /* now check the mpl pointer for being valid */ + if ((M[(mpl+4)>>2] & MASK24) >= (MEMSIZE*4)) { /* check OS midl */ + sim_debug(DEBUG_EXP, &cpu_dev, + "RealAddr Fault MPL Bad %06x MPL[1] %06x\r\n", mpl, M[(mpl+4)>>2]); + if (CPU_MODEL == MODEL_67) { + // 32/67 wants MAPFLT for test 37/1 in CN.MMM + return MAPFLT; /* no, map fault error */ + } else { + // 32/27 & 32/87 wants MACHINECHK 37/1 in CN.MMM + return MACHINECHK_TRAP; /* diags want machine check error */ + } + } + + /* we are mapped, so calculate real address from map information */ + /* get 11 bit page number from address bits 8-18 */ + /* diag want the address to be 19 or 24 bit, use masked address */ + index = (word >> 13) & 0x7ff; /* get 11 bit page value */ + offset = word & 0x1fff; /* get 13 bit page offset */ + + /* make sure map index is valid */ + if (index >= (BPIX + CPIXPL)) { + sim_debug(DEBUG_EXP, &cpu_dev, + "RealAddr %06x word %06x loadmap gets mapfault index %04x B(%x)+C(%x) %04x\n", + word, addr, index, BPIX, CPIXPL, BPIX+CPIXPL); + return MAPFLT; /* no, map fault error */ + } + + /* continue processing non virtual machines here */ +/// if ((CPU_MODEL < MODEL_V6) && (CPU_MODEL != MODEL_67)) { if ((CPU_MODEL < MODEL_V6) && (CPU_MODEL != MODEL_67) && (CPU_MODEL != MODEL_97)) { -// if (CPU_MODEL < MODEL_V6) { - /* 32/27, 32/87, 32/97 2KW maps */ -// /* 32/27, 32/67, 32/87, 32/97 2KW maps */ - /* Concept 32 machine, 2KW maps */ - if (modes & (BASEBIT | EXTDBIT)) - word = addr & 0xffffff; /* get 24 bit address */ - else - word = addr & 0x7ffff; /* get 19 bit address */ - if ((modes & MAPMODE) == 0) { - /* we are in unmapped mode, check if valid real address */ - if (word >= (MEMSIZE*4)) /* see if address is within our memory */ - return NPMEM; /* no, none present memory error */ - *realaddr = word; /* return the real address */ - return ALLOK; /* all OK, return instruction */ - } - /* diag wants the mpl entry checked to make sure valid */ - mpl = SPAD[0xf3]; /* get mpl from spad address */ - if ((M[(mpl+4)>>2] & MASK24) >= (MEMSIZE*4)) { /* check OS midl */ - sim_debug(DEBUG_EXP, &cpu_dev, - "RealAddr MachCheck MPL %x MPL[1] %x\r\n", mpl, M[(mpl+4)>>2]); - return MACHINECHK_TRAP; /* no, diags want machine check error */ -// return NPMEM; /* no, none present memory error */ - } - /* we are mapped, so calculate real address from map information */ - /* get 11 bit page number from address bits 8-18 */ - index = (word >> 13) & 0x7ff; /* get 11 bit value */ - offset = word & 0x1fff; /* get 13 bit page offset */ - map = MAPC[index/2]; /* get two hw map entries */ + map = MAPC[index/2]; /* get two hw map entries */ if (index & 1) /* entry is in rt hw, clear left hw */ - map &= RMASK; /* map is in rt hw */ + map &= RMASK; /* map is in rt hw */ else /* entry is in left hw, move to rt hw */ - map >>= 16; /* map is in left hw */ + map >>= 16; /* map is in left hw */ + /* see if map is valid */ - if ((map & 0x8000) == 0) { /* see if valid map */ - sim_debug(DEBUG_EXP, &cpu_dev, "RealAddr loadmap 0a map fault index %04x B+C %04x map %04x\n", - index, BPIX+CPIXPL, map); - return MAPFLT; /* no, map fault error */ + if ((map & 0x8000) == 0) { /* see if valid map */ + sim_debug(DEBUG_EXP, &cpu_dev, "RealAddr loadmap 0a map fault index %04x B+C %04x map %04x TLB %08x\n", + index, BPIX+CPIXPL, map, TLB[index]); + return MAPFLT; /* no, map fault error */ } - raddr = TLB[index]; /* get the base address & bits */ - if (raddr == 0) { /* see if valid address */ - sim_debug(DEBUG_EXP, &cpu_dev, "RealAddr loadmap 0b map fault index %04x B+C %04x TLB %08x\n", - index, BPIX+CPIXPL, raddr); - return MAPFLT; /* no, map fault error */ + raddr = TLB[index]; /* get the base address & bits */ + if (raddr == 0) { /* see if valid address */ + sim_debug(DEBUG_EXP, &cpu_dev, "RealAddr loadmap 0b map fault index %04x B+C %04x map %04x TLB %08x\n", + index, BPIX+CPIXPL, map, raddr); + return MAPFLT; /* no, map fault error */ } #ifndef DIAGS_SAYS_ANY_ADDRESS_OK_IF_MAPPED + //test 34/1 fails + // needed for 32/27 & 32/87 /* check if valid real address */ - if ((raddr & 0xffffff) >= (MEMSIZE*4)) /* see if address is within our memory */ - return NPMEM; /* no, none present memory error */ + if ((raddr & 0xffffff) >= (MEMSIZE*4)) { /* see if address is within our memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "RealAddr loadmap 0c non present memory fault addr %08x raddr %08x index %04x\n", + addr, raddr, index); + return NPMEM; /* no, none present memory error */ + } #endif word = (raddr & 0xffe000) | (word & 0x1fff); /* combine map and offset */ - *realaddr = word; /* return the real address */ -// if (PSD2 & 0x80000000) -// fprintf(stderr, "RealAddr page %x realaddr = %x raddr %x\n", index, word, raddr); - if (modes & BIT0) /* all OK if privledged */ - return ALLOK; /* all OK, return instruction */ + *realaddr = word; /* return the real address */ + if (modes & BIT0) /* all OK if privledged */ + return ALLOK; /* all OK, return instruction */ /* get protection status of map */ - index = (word >> 11) & 0x3; /* see which 1/4 page we are in */ - if ((BIT1 >> index) & raddr) { /* is 1/4 page write protected */ - *prot = 1; /* return memory write protection status */ + index = (word >> 11) & 0x3; /* see which 1/4 page we are in */ + if ((BIT1 >> index) & raddr) { /* is 1/4 page write protected */ + *prot = 1; /* return memory write protection status */ } - return ALLOK; /* all OK, return instruction */ + return ALLOK; /* all OK, return instruction */ } else { - /* handle 32/67, V6 & V9 here */ + /* handle 32/67, 32/97 and V6 & V9 here */ /* Concept 32 machine, 2KW maps */ - if (modes & (BASEBIT | EXTDBIT)) - word = addr & 0xffffff; /* get 24 bit address */ - else - word = addr & 0x7ffff; /* get 19 bit address */ - if ((modes & MAPMODE) == 0) { - /* check if valid real address */ - if (word >= (MEMSIZE*4)) /* see if address is within our memory */ - return NPMEM; /* no, none present memory error */ - *realaddr = word; /* return the real address */ - return ALLOK; /* all OK, return instruction */ - } - - /* diag wants the mpl entries checked to make sure valid */ - /* master process list is in 0xf3 of spad for concept */ - mpl = SPAD[0xf3] & MASK24; /* get mpl from spad address */ - /* check if valid real address */ - if ((mpl & MASK24) >= MEMSIZE*4) { /* see if address is within our memory */ - return NPMEM; /* no, non present memory error */ - } - if ((M[(mpl+4)>>2] & MASK24) >= (MEMSIZE*4)) { /* check OS midl */ - sim_debug(DEBUG_EXP, &cpu_dev, - "RealAddr MachCheck MPL %x MPL[1] %x\r\n", mpl, M[(mpl+4)>>2]); - return MACHINECHK_TRAP; /* diags want machine check error */ - } - - /* we are mapped, so calculate real address from map information */ - /* get 11 bit page number from address bits 8-18 */ - index = (addr >> 13) & 0x7ff; /* get 11 bit page value */ - offset = addr & 0x1fff; /* get 13 bit page offset */ - - if (index >= (BPIX + CPIXPL)) { - sim_debug(DEBUG_EXP, &cpu_dev, "RealAddr loadmap 1 map fault index %04x B+C %04x\n", index, BPIX+CPIXPL); - return MAPFLT; /* no, map fault error */ - } - - if ((TLB[index] & 0x04000000) == 0) { /* is HIT bit on */ + /* the index is less than B+C, so setup to get a map */ + if ((TLB[index] & 0x04000000) == 0) { /* is HIT bit on */ uint32 nix, msdl; -//NU uint32 midl; sim_debug(DEBUG_EXP, &cpu_dev, "MEMORY %08x MPL %08x MPL[0] %08x MPL[1] %08x MPL[%04x] %08x %08x\n", - MEMSIZE*4, mpl, M[(mpl)>>2], M[(mpl+4)>>2], CPIXBA, M[(CPIXBA+mpl)>>2], M[(CPIXBA+mpl+4)>>2]); - msdl = RMW(mpl+CPIXBA+4); /* get mpl entry wd 1 for given cpix */ - if ((msdl & MASK24) >= (MEMSIZE*4)) /* see if address is within our memory */ - return NPMEM; /* no, non present memory error */ -//NU midl = RMW(mpl+CPIXBA); /* get midl entry for given cpix */ + MEMSIZE*4, mpl, M[(mpl)>>2], M[(mpl+4)>>2], CPIX, M[(CPIX+mpl)>>2], M[(CPIX+mpl+4)>>2]); + msdl = RMW(mpl+CPIX+4); /* get mpl entry wd 1 for given cpix */ + if ((msdl & MASK24) >= (MEMSIZE*4)) { /* see if address is within our memory */ + return NPMEM; /* no, non present memory error */ + } #ifdef DO_DYNAMIC_DEBUG - /* start debugging */ - cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ); + /* start debugging at test 15/0 of vm.mmm diag */ + if (RMW(mpl+CPIX) == 0x800007ee) + cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ); #endif + /* HIT bit is off, we must load the map entries from memory */ /* turn on the map hit flag and set maps real base addr */ - nix = index & 0x7ff; /* map # */ + nix = index & 0x7ff; /* map # */ word = (TLB[nix] & 0xffe000) | offset; /* combine map and offset */ - map = RMH(msdl+((nix-BPIX)<<1)); /* map content */ - sim_debug(DEBUG_EXP, &cpu_dev, "Addr %08x RealAddr %08x Map0 HIT %08x, TLB[%3x] %08x MAPC[%03x] %08x\n", + map = RMH(msdl+((nix-BPIX)<<1)); /* map content from memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "Addr %08x RealAddr %08x Map0 HIT %08x, TLB[%3x] %08x MAPC[%03x] %08x\n", addr, word, map, nix, TLB[nix], nix/2, MAPC[nix/2]); + if ((CPU_MODEL >= MODEL_V6) && (map & 0x8000)) { + map &= 0xe7ff; /* clear access/modify bits in map */ + WMH(msdl+((nix-BPIX)<<1),map); /* write map content */ + } TLB[nix] = ((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000) | 0x04000000; word = (TLB[nix] & 0xffe000) | offset; /* combine map and offset */ - WMR((nix*2),map); /* store the map reg contents into cache */ - sim_debug(DEBUG_EXP, &cpu_dev, "Addr %08x RealAddr %08x Map1 HIT %08x, TLB[%3x] %08x MAPC[%03x] %08x\n", + if ((CPU_MODEL >= MODEL_V6) && (map & 0x8000)) { +//DIAG map |= 0x800; /* set the accessed bit in the map entry */ + } + WMR((nix*2),map); /* store the map reg contents into MAPC cache */ + sim_debug(DEBUG_EXP, &cpu_dev, + "Addr1 %08x RealAddr %08x Map1 HIT %08x, TLB[%3x] %08x MAPC[%03x] %08x\n", addr, word, map, nix, TLB[nix], nix/2, MAPC[nix/2]); +#ifndef JUST_ONE /* now do the other map reg in the same word */ - if ((nix-BPIX) & 1) /* is bpix odd count */ - nix -= 1; /* we are at rt hw, so backup hw */ +//diag if ((nix > 0) && (((nix-BPIX) & 1) == 1)) /* is bpix odd count */ + if ((nix & 1) == 1) /* is map odd */ + nix -= 1; /* we are at rt hw, so backup hw */ else - nix += 1; /* we are at lf hw, so do next hw */ + nix += 1; /* we are at lf hw, so do next hw */ + /* nix has correct index */ - if ((TLB[nix] & 0x04000000) == 0) { /* is HIT bit already on */ + if ((nix == (nix & 0x7ff)) && ((TLB[nix] & 0x04000000) == 0)) { /* is HIT bit already on */ /* hit not on, so load the map */ - if (nix < (BPIX+CPIXPL)) { /* need to be a mapped reg */ - map = RMH(msdl+((nix-BPIX)<<1)); /* do other map content */ - WMR((nix*2),map); /* store the map reg contents into cache */ + if (nix < (BPIX+CPIXPL)) { /* needs to be a mapped reg */ + map = RMH(msdl+((nix-BPIX)<<1)); /* do other map content */ + if ((CPU_MODEL >= MODEL_V6) && (map & 0x8000)) { + map &= 0xe7ff; /* clear access/modify bits in map */ + WMH(msdl+((nix-BPIX)<<1),map); /* write map content */ + } + + if ((CPU_MODEL >= MODEL_V6) && (map & 0x8000)) { +//DIAG map |= 0x800; /* set the accessed bit in the map entry */ + } + WMR((nix*2),map); /* store the map reg contents into cache */ TLB[nix] = ((map&0x7ff) << 13) | ((map<<16) & 0xf8000000) | 0x04000000; - word = (TLB[nix] & 0xffe000); /* combine map and offset */ + word = (TLB[nix] & 0xffe000); /* combine map and offset */ sim_debug(DEBUG_EXP, &cpu_dev, - "RealAddr %08x Map2 HIT %08x, TLB[%03x] %08x MAPC[%03x] %08x\n", - word, map, nix, TLB[nix], nix/2, MAPC[nix/2]); + "Addr2 %08x RealAddr %08x Map2 HIT %08x, TLB[%3x] %08x MAPC[%03x] %08x\n", + addr, word, map, nix, TLB[nix], nix/2, MAPC[nix/2]); } } - } - raddr = TLB[index]; /* get the base address & bits */ -#ifndef IGNOR - if ((raddr & BIT0) == 0) { /* see if valid address */ - sim_debug(DEBUG_EXP, &cpu_dev, - "RealAddr loadmap 2 map fault addr %08x raddr %08x index %04x\n", addr, raddr, index); - return MAPFLT; /* no, map fault error */ - } #endif + } else { + /* HIT bit is on in TLB */ + /* diags wants a NPMEM error if physical addr is exceeded */ + index &= 0x7ff; /* map # */ + raddr = TLB[index]; /* get the base address & bits */ + /* check if valid real address */ + if ((raddr & 0xffffff) >= (MEMSIZE*4)) { /* see if address is within our memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "RealAddr loadmap 2b non present memory fault addr %08x raddr %08x index %04x\n", + addr, raddr, index); + return NPMEM; /* no, none present memory error */ + } + map = RMR((index*2)); /* read the map reg contents */ + /* handle user maps */ +//DIAG if ((CPU_MODEL >= MODEL_V6) && (map & 0x8000)) { + if ((CPU_MODEL >= MODEL_V6) && (map & 0x8000) && (index >= BPIX)) { + map |= 0x800; /* set the accessed bit in the map entry */ + WMR((index*2),map); /* store the map reg contents into cache */ + TLB[index] |= 0x08000000; /* set the accessed bit in TLB */ + sim_debug(DEBUG_EXP, &cpu_dev, + "RealAddrZ loadmap addr %08x raddr %08x TLB[%04x] %08x map %04x\n", + addr, raddr, index, TLB[index], map); + } + else + sim_debug(DEBUG_EXP, &cpu_dev, + "RealAddr loadmap 2Z map addr %08x raddr %08x TLB[%04x] %08x map %04x\n", + addr, raddr, index, TLB[index], map); + } + raddr = TLB[index]; /* get the base address & bits */ + if ((raddr & BIT0) == 0) { /* see if valid address */ + sim_debug(DEBUG_EXP, &cpu_dev, + "RealAddr loadmap 2a map fault addr %08x raddr %08x index %04x\n", addr, raddr, index); + return MAPFLT; /* no, map fault error */ + } #ifdef DIAGS_SAYS_ANY_ADDRESS_OK_IF_MAPPED /* check if valid real address */ - if ((raddr & 0xffffff) >= (MEMSIZE*4)) { /* see if address is within our memory */ - return NPMEM; /* no, none present memory error */ -// fprintf(stderr, "\r\nRealAddr Bad address %08x, TLB %08x MAPC[%03x] %08x\n", -// raddr, TLB[index], index/2, MAPC[index/2]); -// fflush(stderr); -// sim_debug(DEBUG_EXP, &cpu_dev, "RealAddr Bad address %08x, TLB %08x MAPC[%03x] %08x\n", -// raddr, TLB[index], index/2, MAPC[index/2]); + if ((raddr & 0xffffff) >= (MEMSIZE*4)) { /* see if address is within our memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "RealAddr loadmap 2b non present memory fault addr %08x raddr %08x index %04x\n", addr, raddr, index); + return NPMEM; /* no, none present memory error */ } #endif - word = (raddr & 0xffe000) | offset; /* combine map and offset */ - *realaddr = word; /* return the real address */ -// sim_debug(DEBUG_EXP, &cpu_dev, "RealAddr address %08x, TLB %08x MAPC[%03x] %08x qp %02x\n", -// word, TLB[index], index/2, MAPC[index/2], (word>>11)&3); + word = (raddr & 0xffe000) | offset; /* combine map and offset */ + *realaddr = word; /* return the real address */ + sim_debug(DEBUG_EXP, &cpu_dev, "RealAddr address %08x, TLB %08x MAPC[%03x] %08x wprot %02x\n", + word, TLB[index], index/2, MAPC[index/2], (word>>11)&3); /* handle V6 & V9 different than 32/67 */ if (CPU_MODEL >= MODEL_V6) { @@ -1209,16 +1404,16 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot) /* access bits in bits 24-26 and bit 31 set indicating status returned */ *prot = (((modes & BIT0) | (raddr & 0x60000000)) >> 24) | 1; } else { - /* handle 32/67 */ - if (modes & BIT0) /* all OK if privledged */ - return ALLOK; /* all OK, return instruction */ + /* handle 32/67 & 32/97 */ + if (modes & BIT0) /* all OK if privledged */ + return ALLOK; /* all OK, return instruction */ /* get protection status of map */ - index = (word >> 11) & 0x3; /* see which 1/4 page we are in */ - if ((BIT1 >> index) & raddr) { /* is 1/4 page write protected */ - *prot = 1; /* return memory write protection status */ + index = (word >> 11) & 0x3; /* see which 1/4 page we are in */ + if ((BIT1 >> index) & raddr) { /* is 1/4 page write protected */ + *prot = 1; /* return memory write protection status */ } } - return ALLOK; /* all OK, return instruction */ + return ALLOK; /* all OK, return instruction */ } } @@ -1231,25 +1426,31 @@ t_stat read_instruction(uint32 thepsd[2], uint32 *instr) { /* 32/7x machine with 8KW maps */ /* instruction must be in first 512KB of address space */ - addr = thepsd[0] & 0x7fffc; /* get 19 bit logical word address */ + addr = thepsd[0] & 0x7fffc; /* get 19 bit logical word address */ } else { /* 32/27, 32/67, 32/87, 32/97 2KW maps */ /* Concept 32 machine, 2KW maps */ - if (thepsd[0] & BASEBIT) { /* bit 6 is base mode? */ - addr = thepsd[0] & 0xfffffc; /* get 24 bit address */ + if (thepsd[0] & BASEBIT) { /* bit 6 is base mode? */ + addr = thepsd[0] & 0xfffffc; /* get 24 bit address */ } else - addr = thepsd[0] & 0x7fffc; /* get 19 bit address */ + addr = thepsd[0] & 0x7fffc; /* get 19 bit address */ } - status = Mem_read(addr, instr); /* get the instruction at the specified address */ - if (status == DMDPG) { /* demand page request */ - *instr |= 0x80000000; /* set instruction fetch paging error */ - pfault = *instr; /* save page number */ + status = Mem_read(addr, instr); /* get the instruction at the specified address */ + if (status == DMDPG) { /* demand page request */ + *instr |= 0x80000000; /* set instruction fetch paging error */ + pfault = *instr; /* save page number */ } - sim_debug(DEBUG_DETAIL, &cpu_dev, "read_instr status = %02x\n", status); - return status; /* return ALLOK or ERROR */ + if (status != ALLOK) { + sim_debug(DEBUG_EXP, &cpu_dev, "read_instr error status %02x @ %08x\n", status, addr); + if (status == NPMEM) /* instruction nonpresent memory error */ + TRAPSTATUS |= 0x100000; /* set bit 11 of trap status */ +// TRAPME = NPMEM; /* Try non-present mem Trap */ + } else + sim_debug(DEBUG_DETAIL, &cpu_dev, "read_instr status %02x @ %08x\n", status, addr); + return status; /* return ALLOK or ERROR */ } /* @@ -1259,14 +1460,15 @@ t_stat read_instruction(uint32 thepsd[2], uint32 *instr) */ t_stat Mem_read(uint32 addr, uint32 *data) { - uint32 status, realaddr, prot, raddr, page; + uint32 status, realaddr, prot, raddr, page, map; status = RealAddr(addr, &realaddr, &prot); /* convert address to real physical address */ sim_debug(DEBUG_DETAIL, &cpu_dev, "Mem_read status = %02x\n", status); if (status == ALLOK) { *data = M[realaddr >> 2]; /* valid address, get physical address contents */ // if (((CPU_MODEL >= MODEL_V6) || (CPU_MODEL == MODEL_67)) && (modes & MAPMODE)) { - if (((CPU_MODEL >= MODEL_V6) || (CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_67)) && (modes & MAPMODE)) { + if (((CPU_MODEL >= MODEL_V6) || (CPU_MODEL == MODEL_97) || + (CPU_MODEL == MODEL_67)) && (modes & MAPMODE)) { page = (addr >> 13) & 0x7ff; /* get 11 bit value */ if (CPU_MODEL >= MODEL_V6) { /* for v6 & v9, check if we have read access */ @@ -1276,22 +1478,38 @@ t_stat Mem_read(uint32 addr, uint32 *data) return MPVIOL; /* return memory protection violation */ } raddr = TLB[page]; /* get the base address & bits */ + map = RMR((page*2)); /* read the map reg contents */ if ((raddr & BIT0) == 0) { /* see if page is valid */ /* not valid, but mapped, so do a demand page request */ *data = page; /* return the page # */ pfault = page; /* save page number */ + sim_debug(DEBUG_EXP, &cpu_dev, + "Mem_read Daddr %08x page %04x demand page bits set TLB %08x map %04x\n", + addr, page, TLB[page], map); return DMDPG; /* demand page request */ } - if ((raddr & 0x04000000) == 0) /* HIT on */ -//HUH TLB[page] |= 0x08000000; /* set accessed bit */ - TLB[page] |= 0x08000000; /* no, set accessed bit */ - sim_debug(DEBUG_EXP, &cpu_dev, "Mem_read addr %08x page %04x access bit set TLB %08x\n", addr, page, TLB[page]); + if ((raddr & 0x04000000) == 0) { /* HIT on */ +/*diag*/ TLB[page] |= 0x08000000; /* no, set accessed */ +//ZZ map |= 0x0800; /* set the accessed bit in the map entry */ +//ZZ WMR((page*2),map); /* store the map reg contents back into cache */ + sim_debug(DEBUG_EXP, &cpu_dev, + "Mem_read HIT on addr %08x page %04x access bit set TLB %08x map %04x\n", + addr, page, TLB[page], map); + } + sim_debug(DEBUG_EXP, &cpu_dev, + "Mem_read Yaddr %08x page %04x access bit set TLB %08x map %04x\n", + addr, page, TLB[page], map); } /* everybody else has read access */ } sim_debug(DEBUG_DETAIL, &cpu_dev, "Mem_read addr %.8x realaddr %.8x data %.8x prot %d\n", addr, realaddr, *data, prot); + } else { + if (status == NPMEM) /* operand nonpresent memory error */ + TRAPSTATUS |= 0x200000; /* set bit 10 of trap status */ + sim_debug(DEBUG_EXP, &cpu_dev, "Mem_read error %02x @ %08x\n", status, addr); } + return status; /* return ALLOK or ERROR status */ } @@ -1302,7 +1520,7 @@ t_stat Mem_read(uint32 addr, uint32 *data) */ t_stat Mem_write(uint32 addr, uint32 *data) { - uint32 status, realaddr, prot, raddr, page; + uint32 status, realaddr, prot, raddr, page, map; status = RealAddr(addr, &realaddr, &prot); /* convert address to real physical address */ if (prot) { @@ -1313,13 +1531,15 @@ t_stat Mem_write(uint32 addr, uint32 *data) } if (status == ALLOK) { // if (((CPU_MODEL >= MODEL_V6) || (CPU_MODEL == MODEL_67)) && (modes & MAPMODE)) { - if (((CPU_MODEL >= MODEL_V6) || (CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_67)) && (modes & MAPMODE)) { + if (((CPU_MODEL >= MODEL_V6) || (CPU_MODEL == MODEL_97) || + (CPU_MODEL == MODEL_67)) && (modes & MAPMODE)) { page = (addr >> 13) & 0x7ff; /* get 11 bit value */ if (CPU_MODEL >= MODEL_V6) { /* for v6 & v9, check if we have write access */ if (((prot & 0xe0) != 0x40) && ((prot & 0xe0) != 0x80) && ((prot & 0xe0) != 0xc0)){ /* user has no write access, do protection violation */ sim_debug(DEBUG_EXP, &cpu_dev, "Mem_write V6 & V7 protect error @ %08x prot %02x\n", addr, prot); + TRAPSTATUS |= 0x080000; /* set bit 12 of trap status for memory prot */ return MPVIOL; /* return memory protection violation */ } raddr = TLB[page]; /* get the base address & bits */ @@ -1327,15 +1547,27 @@ t_stat Mem_write(uint32 addr, uint32 *data) /* not valid, but mapped, so do a demand page request */ *data = page; /* return the page # */ pfault = page; /* save page number */ + sim_debug(DEBUG_EXP, &cpu_dev, + "Mem_write Daddr %08x page %04x demand page bits set TLB %08x map %04x\n", + addr, page, TLB[page], map); return DMDPG; /* demand page request */ } - if ((raddr & 0x04000000) == 0) /* HIT on */ -//HUH TLB[page] |= 0x18000000; /* set modify/accessed bit */ - TLB[page] |= 0x18000000; /* no, set modify/accessed bit */ - sim_debug(DEBUG_EXP, &cpu_dev, "Mem_write addr %08x page %04x modify/access bits set TLB %08x\n", addr, page, TLB[page]); + map = RMR((page*2)); /* read the map reg contents */ + if ((raddr & 0x04000000) == 0) { /* is HIT on */ + TLB[page] |= 0x18000000; /* no, set modify/accessed */ +//ZZ map |= 0x1000; /* set the modified bit in the map entry */ +//ZZ WMR((page*2),map); /* store the map reg contents back into cache */ + sim_debug(DEBUG_EXP, &cpu_dev, + "Mem_write HIT on addr %08x page %04x modify/access bit set TLB %08x map %04x\n", + addr, page, TLB[page], map); + } + sim_debug(DEBUG_EXP, &cpu_dev, + "Mem_write Xaddr %08x page %04x modify/access bits set TLB %08x map %04x\n", + addr, page, TLB[page], map); } else { if (prot) { /* check for write protected memory */ - sim_debug(DEBUG_EXP, &cpu_dev, "Mem_write 32/67 protect error @ %08x prot %02x\n", addr, prot); + sim_debug(DEBUG_EXP, &cpu_dev, "Mem_write 32/67 protect error @ %08x prot %02x page %04x\n", addr, prot, page); + TRAPSTATUS |= 0x080000; /* set bit 12 of trap status for memory prot */ return MPVIOL; /* return memory protection violation */ } } @@ -1343,10 +1575,14 @@ t_stat Mem_write(uint32 addr, uint32 *data) } else { if (prot) { /* check for write protected memory */ sim_debug(DEBUG_EXP, &cpu_dev, "Mem_write protect error @ %08x prot %02x\n", addr, prot); + TRAPSTATUS |= 0x080000; /* set bit 12 of trap status for memory prot */ return MPVIOL; /* return memory protection violation */ } } M[realaddr >> 2] = *data; /* valid address, put physical address contents */ + } else { + sim_debug(DEBUG_EXP, &cpu_dev, "Mem_write error %02x @ %08x\n", status, addr); + TRAPSTATUS |= 0x0200; /* set bit 22 of trap status */ } return status; /* return ALLOK or ERROR */ } @@ -1578,14 +1814,19 @@ skipi: #endif sim_debug(DEBUG_EXP, &cpu_dev, "read_instr TRAPME %04x PSD %08x %08x\n", TRAPME, PSD1, PSD2); - i_flags = HLF; /* assume a hw instruction */ -// if ((CPU_MODEL <= MODEL_27) || (CPU_MODEL == MODEL_87) || -// (CPU_MODEL == MODEL_97)) -// goto newpsd; /* got process trap */ -// else - if ((CPU_MODEL == MODEL_27)) - if ((TRAPME == MAPFLT) || (TRAPME == NPMEM)) - i_flags |= BT; /* do not update pc if MF or NPM */ +//DIAG if ((CPU_MODEL == MODEL_27) || (CPU_MODEL == MODEL_67)) +// if ((CPU_MODEL == MODEL_67) || + if ((CPU_MODEL <= MODEL_27) || (CPU_MODEL == MODEL_67) || + (CPU_MODEL == MODEL_87) || (CPU_MODEL == MODEL_97)) + if ((TRAPME == MAPFLT) || (TRAPME == NPMEM)) { + i_flags |= HLF; /* assume half word instr */ +/*DIAG*/ PSD1 &= ~1; /* force off last right */ +// fix for 32/67 test 32/3 in MMM diag + if ((CPU_MODEL == MODEL_27) || (CPU_MODEL == MODEL_67)) + i_flags |= BT; /* do not update pc if MF or NPM */ + else + i_flags &= ~BT; /* do not update pc if MF or NPM */ + } goto newpsd; /* got process trap */ } @@ -1703,11 +1944,19 @@ exec: addr = IR & 0x7ffff; /* get 19 bit address from instruction */ if (PC >= 0x80000) { TRAPME = MAPFAULT_TRAP; /* Map Fault Trap */ - if ((CPU_MODEL <= MODEL_27)) { - i_flags &= ~(BT|HLF); /* update pc if MAPFAULT */ - i_flags |= BT; /* do not update pc if MAPFAULT */ - } else + // DIAG add 97 for correct PSD address CN.MMM test 32, subtest 1 fails + if ((CPU_MODEL <= MODEL_27) || (CPU_MODEL == MODEL_67) || + (CPU_MODEL == MODEL_87) || (CPU_MODEL == MODEL_97)) { + // DIAG fix for 32/87 test 33/2, clear psd bit 31 + if ((CPU_MODEL == MODEL_87)) +/*DIAG*/ PSD1 &= ~1; /* force off last right */ + // DIAG fix 32/27 32/67 for diag MMM test 33/2 + if ((CPU_MODEL <= MODEL_27) || (CPU_MODEL == MODEL_67)) + i_flags |= BT; /* do not update pc if MAPFAULT on 27 */ + else + i_flags &= ~BT; /* do not update pc if MF or NPM */ i_flags |= HLF; /* assume half word instr */ + } if ((CPU_MODEL <= MODEL_27)) /* 77, 27 rolls to zero, not 80000 */ PSD1 &= 0xff07ffff; /* remove overflow bits */ @@ -1766,6 +2015,7 @@ exec: t = IR; /* get current IR */ while ((t & IND) != 0) { /* process indirection */ if ((TRAPME = Mem_read(addr, &temp))) { /* get the word from memory */ + sim_debug(DEBUG_EXP, &cpu_dev, "case WRD Mem_read status %02x @ %08x\n", TRAPME, addr); goto newpsd; /* memory read error or map fault */ } bc = temp & 0xC0000000; /* save new bits 0, 1 from indirect location */ @@ -1790,6 +2040,7 @@ exec: break; case INV: /* Invalid instruction */ if ((TRAPME = Mem_read(addr, &temp))) { /* get the word from memory */ + sim_debug(DEBUG_EXP, &cpu_dev, "case INV Mem_read status %02x @ %08x\n", TRAPME, addr); goto newpsd; /* memory read error or map fault */ } TRAPME = UNDEFINSTR_TRAP; /* Undefined Instruction Trap */ @@ -1801,6 +2052,13 @@ exec: /* Read memory operand */ if (i_flags & RM) { if ((TRAPME = Mem_read(addr, &temp))) { /* get the word from memory */ + sim_debug(DEBUG_EXP, &cpu_dev, "case RM Mem_read status %02x @ %08x\n", TRAPME, addr); + // DIAG add 97 for correct PSD address CN.MMM test 32, subtest 1 fails + if ((TRAPME == MAPFLT) || (TRAPME == NPMEM)) +/*DIAG*/ PSD1 &= ~1; /* force off last right */ +// if ((CPU_MODEL <= MODEL_27) || (CPU_MODEL == MODEL_67) || +// (CPU_MODEL == MODEL_97)) { +// i_flags |= BT; /* do not update pc if MAPFAULT */ goto newpsd; /* memory read error or map fault */ } source = (t_uint64)temp; /* make into 64 bit value */ @@ -1825,6 +2083,7 @@ exec: goto newpsd; /* go execute the trap now */ } if ((TRAPME = Mem_read(addr+4, &temp))) { /* get the 2nd word from memory */ + sim_debug(DEBUG_EXP, &cpu_dev, "case RM wd 2 Mem_read status %02x @ %08x\n", TRAPME, addr+4); goto newpsd; /* memory read error or map fault */ } source = (source << 32) | (t_uint64)temp; /* merge in the low order 32 bits */ @@ -1842,6 +2101,7 @@ exec: /* Read memory operand without doing sign extend for EOMX/ANMX/ORMX/ARMX */ if (i_flags & RNX) { if ((TRAPME = Mem_read(addr, &temp))) { /* get the word from memory */ + sim_debug(DEBUG_EXP, &cpu_dev, "case RNX 2 Mem_read status %02x @ %08x\n", TRAPME, addr); goto newpsd; /* memory read error or map fault */ } source = (t_uint64)temp; /* make into 64 bit value */ @@ -1861,6 +2121,7 @@ exec: goto newpsd; /* go execute the trap now */ } if ((TRAPME = Mem_read(addr+4, &temp))) { /* get the 2nd word from memory */ + sim_debug(DEBUG_EXP, &cpu_dev, "case RNX wd 2 Mem_read status %02x @ %08x\n", TRAPME, addr+4); goto newpsd; /* memory read error or map fault */ } source = (source << 32) | (t_uint64)temp; /* merge in the low order 32 bits */ @@ -1930,6 +2191,7 @@ exec: case 0x0: /* HALT */ if ((modes & PRIVBIT) == 0) { /* must be privileged to halt */ TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + TRAPSTATUS |= 0x1000; /* set bit 19 of trap status */ goto newpsd; /* Privlege violation trap */ } if (CPUSTATUS & 0x00000100) { /* Priv mode halt must be enabled */ @@ -1952,6 +2214,11 @@ exec: for (ix=0; ix<8; ix+=2) { fprintf(stdout, "GPR[%d] %.8x GPR[%d] %.8x\r\n", ix, GPR[ix], ix+1, GPR[ix+1]); } + if (modes & BASEBIT) { /* see if based */ + for (ix=0; ix<8; ix+=2) { + fprintf(stdout, "BR[%d] %.8x BR[%d] %.8x\r\n", ix, BR[ix], ix+1, BR[ix+1]); + } + } fprintf(stdout, "[][][][][][][][][][] HALT [][][][][][][][][][]\r\n"); /*TEST DIAG*/ reason = STOP_HALT; /* do halt for now */ ///*TEST DIAG*/ return STOP_HALT; /* exit to simh for halt */ @@ -1959,6 +2226,7 @@ exec: case 0x1: /* WAIT */ if ((modes & PRIVBIT) == 0) { /* must be privileged to wait */ TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + TRAPSTATUS |= 0x1000; /* set bit 19 of trap status */ goto newpsd; /* Privlege violation trap */ } /* if interrupts are blocked, system check trap */ @@ -2025,6 +2293,7 @@ exec: case 0x6: /* BEI */ if ((modes & PRIVBIT) == 0) { /* must be privileged to BEI */ TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + TRAPSTATUS |= 0x1000; /* set bit 19 of trap status */ goto newpsd; /* Privlege violation trap */ } CPUSTATUS |= 0x80; /* into status word bit 24 too */ @@ -2036,6 +2305,7 @@ exec: case 0x7: /* UEI */ if ((modes & PRIVBIT) == 0) { /* must be privileged to UEI */ TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + TRAPSTATUS |= 0x1000; /* set bit 19 of trap status */ goto newpsd; /* Privlege violation trap */ } if (CPUSTATUS & 0x80) /* see if old mode is blocked */ @@ -2805,6 +3075,7 @@ tbr: /* handle basemode TBR too * case 0x7: /* LMAP */ /* Load map reg - Diags only */ if ((modes & PRIVBIT) == 0) { /* must be privileged */ TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + TRAPSTATUS |= 0x1000; /* set bit 19 of trap status */ goto newpsd; /* handle trap */ } /* cpu must be unmapped */ @@ -2876,6 +3147,7 @@ tbr: /* handle basemode TBR too * case 0x9: /* SETCPU */ if ((modes & PRIVBIT) == 0) { /* must be privileged */ TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + TRAPSTATUS |= 0x1000; /* set bit 19 of trap status */ goto newpsd; /* handle trap */ } CPUSTATUS &= 0xfffff0bf; /* zero bits that can change */ @@ -2885,6 +3157,7 @@ tbr: /* handle basemode TBR too * case 0xA: /* TMAPR */ /* Transfer map to Reg - Diags only */ if ((modes & PRIVBIT) == 0) { /* must be privileged */ TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + TRAPSTATUS |= 0x1000; /* set bit 19 of trap status */ goto newpsd; /* handle trap */ } #ifndef DIAG_CAN_BE_MAPPED_OR_UNMAPPED @@ -2969,6 +3242,7 @@ tbr: /* handle basemode TBR too * case 0xE: /* TRSC */ /* transfer reg to SPAD */ if ((modes & PRIVBIT) == 0) { /* must be privileged */ TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + TRAPSTATUS |= 0x1000; /* set bit 19 of trap status */ goto newpsd; /* handle trap */ } t = (GPR[reg] >> 16) & 0xff; /* get SPAD address from Rd (6-8) */ @@ -2979,6 +3253,7 @@ tbr: /* handle basemode TBR too * case 0xF: /* TSCR */ /* Transfer scratchpad to register */ if ((modes & PRIVBIT) == 0) { /* must be privileged */ TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + TRAPSTATUS |= 0x1000; /* set bit 19 of trap status */ goto newpsd; /* handle trap */ } t = (GPR[sreg] >> 16) & 0xff; /* get SPAD address from Rs (9-11) */ @@ -3865,11 +4140,14 @@ doovr3: case 0x80>>2: /* 0x80 SD|ADR - SD|ADR */ /* LEAR */ /* convert address to real physical address */ TRAPME = RealAddr(addr, &temp, &t); +#ifndef TRY_THIS_FOR_DIAG + // diag allows any addr if mapped if (TRAPME != ALLOK) { sim_debug(DEBUG_EXP, &cpu_dev, "At LEAR with TRAPME %04x addr %08x\n", TRAPME, addr); goto newpsd; /* memory read error or map fault */ } +#endif /* OS code says F bit is not transferred, so just ignore it */ /* DIAGS needs it, so put it back */ if (FC & 4) /* see if F bit was set */ @@ -5007,6 +5285,7 @@ doovr2: case 0x5: /* LPSDCM FA80 */ if ((modes & PRIVBIT) == 0) { /* must be privileged */ TRAPME = PRIVVIOL_TRAP; /* set the trap to take */ + TRAPSTATUS |= 0x1000; /* set bit 19 of trap status */ goto newpsd; /* Privlege violation trap */ } CPUSTATUS |= 0x40; /* enable software traps */ @@ -5018,6 +5297,7 @@ doovr2: goto newpsd; /* go execute the trap now */ } if ((TRAPME = Mem_read(addr, &temp))) { /* get PSD1 from memory */ + TRAPSTATUS |= 0x2000; /* set bit 18 of trap status */ goto newpsd; /* memory read error or map fault */ } #ifdef DO_DYNAMIC_DEBUG @@ -5034,16 +5314,57 @@ doovr2: if (opr & 0x0200) { /* Was it LPSDCM? */ if ((TRAPME = Mem_read(addr+4, &temp2))) { /* get PSD2 from memory */ + TRAPSTATUS |= 0x2000; /* set bit 18 of trap status */ goto newpsd; /* memory read error or map fault */ } PSD2 = temp2; /* PSD2 access good, so save it */ } else { if ((TRAPME = Mem_read(addr+4, &temp2))) { /* get PSD2 from memory */ + TRAPSTATUS |= 0x2000; /* set bit 18 of trap status */ goto newpsd; /* memory read error or map fault */ } /* lpsd can not change cpix, so keep it */ PSD2 = ((PSD2 & 0x3fff) | (temp2 & 0xffffc000)); /* use current cpix */ } +#ifdef TEST_IN_LOAD_MAPS + /* now see if mpl & mpl[0] & mpl[cpix] are in real memory */ + if ((opr & 0x0200) && (CPU_MODEL >= MODEL_27)) { /* Was it LPSDCM? */ + uint32 msdl, mpl, cpix, map; + + mpl = SPAD[0xf3]; /* get mpl from spad address */ + if ((mpl & MASK24) >= MEMSIZE*4) { /* see if address is within our memory */ + sim_debug(DEBUG_EXP, &cpu_dev, + "MEMORYx %08x MPL %08x bad\n", MEMSIZE*4, mpl); + TRAPME = NPMEM; /* no, non present memory error */ + TRAPSTATUS |= 0x0200; /* set bit 22 of trap status */ +#ifdef DO_DYNAMIC_DEBUG + /* start debugging */ + cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ); +#endif + goto newpsd; /* non present memory error */ + } + sim_debug(DEBUG_EXP, &cpu_dev, + "MEMORYy %08x MPL %08x MPL[0] %08x %08x MPL[%04x] %08x %08x RET %05x\n", + MEMSIZE*4, mpl, M[(mpl)>>2], M[(mpl+4)>>2], + cpix, M[(cpix+mpl)>>2], M[(cpix+mpl+4)>>2], PSD2&RETMBIT); + /* now test msd[0] and new msd[cpix] addresses */ + cpix = PSD2 & 0x3ff8; /* get cpix 11 bit offset from psd wd 2 */ + msdl = RMW(mpl+4); /* get O/S msdl pointer from wd 1 of OS MPL entry */ + if ((msdl & MASK24) >= MEMSIZE*4) { /* see if address is within our memory */ + TRAPME = NPMEM; /* no, non present memory error */ + TRAPSTATUS |= 0x0200; /* set bit 22 of trap status */ + goto newpsd; /* non present memory error */ + } + msdl = RMW(mpl+cpix+4); /* get user msdl pointer from wd 1 of MPL entry */ + if ((msdl & MASK24) >= MEMSIZE*4) { /* see if address is within our memory */ + TRAPME = NPMEM; /* no, non present memory error */ + TRAPSTATUS |= 0x0200; /* set bit 22 of trap status */ + goto newpsd; /* non present memory error */ + } + /* we are good to load the maps */ + } +#endif + PSD1 = temp; /* PSD1 good, so set it */ /* set the mode bits and CCs from the new PSD */ CC = PSD1 & 0x78000000; /* extract bits 1-4 from PSD1 */ @@ -5087,6 +5408,9 @@ doovr2: sim_debug(DEBUG_EXP, &cpu_dev, "B4 LPSDCM temp %06x TPSD %08x %08x PSD %08x %08x\n", temp, TPSD[0], TPSD[1], PSD1, PSD2); + sim_debug(DEBUG_EXP, &cpu_dev, + "B4 LPSDCM BPIX %04x CPIX %04x CPIXPL %04x\n", + BPIX, CPIX, CPIXPL); sim_debug(DEBUG_EXP, &cpu_dev, "B4 LPSDCM MAPC[14-19] %08x %08x %08x %08x %08x %08x\n", MAPC[14], MAPC[15], MAPC[16], MAPC[17], MAPC[18], MAPC[19]); @@ -5094,14 +5418,19 @@ doovr2: // MAPC[0], MAPC[1], MAPC[2], MAPC[3], MAPC[4], MAPC[5]); /* this mod fixes MPX 1.X 1st swapr load */ // if ((BPIX == 0) && (CPIXPL == 0)) /* any O/S or user maps yet? */ +#ifndef FIX_MPX if (CPIXPL == 0) /* any user maps yet? */ PSD2 &= ~RETMBIT; /* no, turn off retain bit in PSD2 */ - if ((PSD2 & RETMBIT) == 0) { /* don't load maps if retain bit set */ +#endif + if ((PSD2 & RETMBIT) == 0) { /* don't load maps if retain bit set */ /* we need to load the new maps */ TRAPME = load_maps(PSD, 0); /* load maps for new PSD */ sim_debug(DEBUG_EXP, &cpu_dev, - "AF LPSDCM TPSD %08x %08x PSD %08x %08x\n", - TPSD[0], TPSD[1], PSD1, PSD2); + "AF LPSDCM TPSD %08x %08x PSD %08x %08x TRAPME %02x\n", + TPSD[0], TPSD[1], PSD1, PSD2, TRAPME); + sim_debug(DEBUG_EXP, &cpu_dev, + "AF LPSDCM BPIX %04x CPIX %04x CPIXPL %04x\n", + BPIX, CPIX, CPIXPL); sim_debug(DEBUG_EXP, &cpu_dev, // "AF LPSDCM MAPC[0-6] %08x %08x %08x %08x %08x %08x\n", // MAPC[0], MAPC[1], MAPC[2], MAPC[3], MAPC[4], MAPC[5]); @@ -5116,8 +5445,8 @@ doovr2: TRAPME, PSD1, PSD2, CPUSTATUS); #ifdef DO_DYNAMIC_DEBUG /* start debugging */ -// if ((PSD1&0xffffff) == 0x6d44) - if ((PSD1&0xffffff) == 0x5c34) + if ((PSD1&0xffffff) == 0x6d44) +// if ((PSD1&0xffffff) == 0x5c34) cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ); #endif } @@ -5143,6 +5472,7 @@ doovr2: SPAD[0xf5] = ix; /* restore the current PSD2 to SPAD */ SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */ irq_pend = reg; /* restore intr status */ + TRAPSTATUS |= 0x2000; /* set bit 18 of trap status */ goto newpsd; /* go process error */ } skipinstr = 1; /* do not allow intr on next instruction */ @@ -5226,8 +5556,8 @@ doovr2: /* SPAD entries for interrupts begin at 0x80 */ t = SPAD[prior+0x80]; /* get spad entry for interrupt */ if (t == 0 || t == 0xffffffff) /* if not set up, not class F */ - goto syscheck; /* system check */ -// break; /* ignore */ +//RESTART goto syscheck; /* system check */ + break; /* ignore */ if ((t & 0x0f000000) == 0x0f000000) /* if class F ignore instruction */ break; /* ignore for F class */ /* active state is left alone */ @@ -5444,7 +5774,11 @@ mcheck: case 0x03: /* Test I/O TIO */ chsa = temp2 & 0x7FFF; /* get logical device address */ if ((TRAPME = testxio(chsa, &status))) { -// fprintf(stderr, "XIO TIO ret PSD1 %x chan %x chsa %x status %x\n", PSD1, chan, (chan<<8)|suba, status); +// fprintf(stderr, "XIO TIO ret PSD1 %x chan %x chsa %x status %x\n", +// PSD1, chan, (chan<<8)|suba, status); + sim_debug(DEBUG_EXP, &cpu_dev, + "XIO TIO ret PSD1 %x chan %x chsa %x status %x\n", + PSD1, chan, (chan<<8)|suba, status); goto newpsd; /* error returned, trap cpu */ } PSD1 = ((PSD1 & 0x87fffffe) | (status & 0x78000000)); /* insert status */ @@ -5497,7 +5831,7 @@ mcheck: case 0x08: /* Reset controller RSCTL */ chsa = temp2 & 0x7FFF; /* get logical device address */ - if ((TRAPME = stopxio(chsa, &status))) + if ((TRAPME = rsctlxio(chsa, &status))) goto newpsd; /* error returned, trap cpu */ PSD1 = ((PSD1 & 0x87fffffe) | (status & 0x78000000)); /* insert status */ sim_debug(DEBUG_EXP, &cpu_dev, "XIO RSCTL ret chan %04x chsa %04x status %08x\n", @@ -5817,11 +6151,15 @@ newpsd: PSD1 = (PSD1 + 2) | (((PSD1 & 2) >> 1) & 1); } else { PSD1 = (PSD1 + 4) | (((PSD1 & 2) >> 1) & 1); + //DIAG fix for test 34/10 in MMM diag, reset bit 31 +// if ((CPU_MODEL == MODEL_87) && (i_flags & ADR)) + if ((CPU_MODEL == MODEL_87) || (CPU_MODEL == MODEL_97)) + PSD1 &= ~1; /* force off last right */ } } else { EXM_EXR = 0; /* reset PC increment for EXR */ -/*DIAG*/ if ((drop_nop) && ((CPU_MODEL == MODEL_67) || (CPU_MODEL >= MODEL_V6))) -/*DIAG*/ PSD1 &= ~1; /* force off last right */ + if ((drop_nop) && ((CPU_MODEL == MODEL_67) || (CPU_MODEL >= MODEL_V6))) + PSD1 &= ~1; /* force off last right */ drop_nop = 0; sim_debug(DEBUG_EXP, &cpu_dev, "##GOT BT TRAPME %04x LOAD MAPS PSD1 %08x PSD2 %08x addr %08x\n", @@ -5931,6 +6269,7 @@ newpsd: "PAGE TRAP %04x TSTATUS %08x LOAD MAPS PSD1 %08x PSD2 %08x CPUSTATUS %08x pfault %08x\n", TRAPME, TRAPSTATUS, PSD1, PSD2, CPUSTATUS, pfault); } + TRAPSTATUS = CPU_MODEL; /* clear all trap status except cpu type */ break; /* Go execute the trap */ } break; @@ -6071,8 +6410,18 @@ t_stat cpu_reset(DEVICE * dptr) /* examine a 32bit memory location and return a byte */ t_stat cpu_ex(t_value *vptr, t_addr baddr, UNIT *uptr, int32 sw) { + uint32 status, realaddr, prot; uint32 addr = (baddr & 0xfffffc) >> 2; /* make 24 bit byte address into word address */ + if (sw & SWMASK('V')) { + status = RealAddr(addr, &realaddr, &prot); /* convert address to real physical address */ + sim_debug(DEBUG_CMD, &cpu_dev, "cpu_ex Mem_read status = %02x\n", status); + if (status == ALLOK) { + *vptr = (M[realaddr] >> (8 * (3 - (baddr & 0x3)))); /* return memory contents */ + return SCPE_OK; /* we are all ok */ + } + return SCPE_NXM; /* no, none existant memory error */ + } /* MSIZE is in 32 bit words */ if (addr >= MEMSIZE) /* see if address is within our memory */ return SCPE_NXM; /* no, none existant memory error */ diff --git a/SEL32/sel32_defs.h b/SEL32/sel32_defs.h index 9c356a6..02536d0 100644 --- a/SEL32/sel32_defs.h +++ b/SEL32/sel32_defs.h @@ -109,14 +109,16 @@ #define NUM_UNITS_CON 2 /* 2 console input & output */ #define NUM_DEVS_MT 1 /* 1 mag tape controllers */ #define NUM_UNITS_MT 4 /* 4 of 8 devices */ -#define NUM_DEVS_DISK 1 /* 1 DP02 disk drive controller */ -#define NUM_UNITS_DISK 4 /* 4 disk drive devices */ +#ifdef FOR_UTX #define NUM_DEVS_HSDP 1 /* 1 HSPD disk drive controller */ #define NUM_UNITS_HSDP 2 /* 2 disk drive devices */ +#else +#define NUM_DEVS_DISK 1 /* 1 DP02 disk drive controller */ +#define NUM_UNITS_DISK 2 /* 2 disk drive devices */ +//#define NUM_UNITS_DISK 4 /* 4 disk drive devices */ +#endif #define NUM_DEVS_SCFI 1 /* 1 scfi (SCSI) disk drive units */ #define NUM_UNITS_SCFI 1 /* 1 of 4 disk drive devices */ -//#define NUM_DEVS_SCFI 2 /* 2 scfi (SCSI) disk drive units */ -//#define NUM_UNITS_SCFI 2 /* 2 of 4 disk drive devices */ #define NUM_DEVS_RTOM 1 /* 1 IOP RTOM channel */ #define NUM_UNITS_RTOM 1 /* 1 IOP RTOM device (clock & interval timer) */ #define NUM_DEVS_LPR 1 /* 1 IOP Line printer */ diff --git a/SEL32/sel32_disk.c b/SEL32/sel32_disk.c index af9e255..419e4d0 100644 --- a/SEL32/sel32_disk.c +++ b/SEL32/sel32_disk.c @@ -94,6 +94,7 @@ bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option #define DSK_BUSY 0x8000 /* Flag to send a CUE */ /* commands */ #define DSK_INCH 0x00 /* Initialize channel */ +#define DSK_INCH2 0xf0 /* Initialize channel for processing */ #define DSK_WD 0x01 /* Write data */ #define DSK_RD 0x02 /* Read data */ #define DSK_NOP 0x03 /* No operation */ @@ -223,8 +224,13 @@ disk_type[] = /* Class F Disc Devices */ {"FL001", 1334, 0, 2, 64, 26, 3, 3, 26, 0x40}, /* 1 M */ {"MH040", 20000, 625, 5, 192, 20, 2, 1, 400, 0x40}, /* 40 M */ +#ifdef FOR_UTX + {"9342", 40000, 1250, 5, 256, 16, 2, 1, 800, 0x40}, /*823 80 M */ + {"9344", 76000, 2375, 19, 256, 16, 4, 1, 800, 0x40}, /*823 300 M */ +#else {"MH080", 40000, 1250, 5, 192, 20, 2, 1, 800, 0x40}, /* 80 M */ {"MH300", 76000, 2375, 19, 192, 20, 4, 1, 800, 0x40}, /* 300 M */ +#endif {"FH005", 5120, 184, 4, 192, 20, 1, 1, 64, 0x80}, /* 5 M */ {"CD032", 8000, 250, 1, 192, 20, 2, 1, 800, 0x60}, /* 32 M */ {"CD032", 8000, 250, 1, 192, 20, 2, 1, 800, 0x60}, /* 32 M */ @@ -484,7 +490,7 @@ uint8 disk_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) uptr->SNS &= 0xff000000; /* clear status bytes, but leave mode data */ return SNS_CHNEND|SNS_DEVEND; } - if (cmd == 0x0) /* INCH cmd gives unit check here */ + if (cmd == 0x00) /* INCH cmd gives unit check here */ return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; uptr->SNS |= (SNS_INTVENT|SNS_CMDREJ); /* set new error status */ @@ -523,7 +529,7 @@ uint8 disk_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) up++; /* next unit for this device */ } sim_debug(DEBUG_CMD, dptr, "disk_startcmd done inch cmd addr %04x\n", addr); - uptr->CMD |= DSK_CMDMSK; /* use 0xff for inch, just need int */ + uptr->CMD |= DSK_INCH2; /* use 0xf0 for inch, just need int */ sim_activate(uptr, 20); /* start things off */ return 0; } @@ -579,8 +585,8 @@ t_stat disk_srv(UNIT * uptr) int tsize = disk_type[type].spt * disk_type[type].ssiz * 4; /* get track size in bytes */ int ssize = disk_type[type].ssiz * 4; /* disk sector size in bytes */ int tstart; - uint8 buf2[768]; - uint8 buf[768]; + uint8 buf2[1024]; + uint8 buf[1024]; sim_debug(DEBUG_DETAIL, &dda_dev, "disk_srv entry unit %02x cmd %02x chsa %04x chan %04x count %04x\n", @@ -595,13 +601,13 @@ t_stat disk_srv(UNIT * uptr) sim_debug(DEBUG_CMD, dptr, "disk_srv cmd=%02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count); switch (cmd) { - case 0: /* No command, stop disk */ + case 0: /* No command, stop disk */ break; - case DSK_CMDMSK: /* use 0xff for inch, just need int */ + case DSK_INCH2: /* use 0xff for inch, just need int */ uptr->CMD &= ~(0xffff); /* remove old cmd */ - sim_debug(DEBUG_CMD, dptr, "disk_srv cmd=%02x chsa %04x count %04x completed\n", - cmd, chsa, chp->ccw_count); + sim_debug(DEBUG_CMD, dptr, "disk_srv cmd INCH chsa %04x count %04x completed\n", + chsa, chp->ccw_count); #ifdef FIX4MPX chan_end(chsa, SNS_CHNEND); /* return just channel end OK */ #else @@ -731,7 +737,8 @@ rezero: uptr->CMD |= DSK_STAR; /* show we have seek STAR in STAR */ /* calc the sector address of data */ /* calculate file position in bytes of requested sector */ - tstart = (cyl * disk_type[type].nhds * tsize) + (trk * tsize) + (buf[3] * 0x300); + // FIXME for variable sector size + tstart = (cyl * disk_type[type].nhds * tsize) + (trk * tsize) + (buf[3] * ssize); data->tpos = trk; /* save the track/head number */ data->spos = buf[3]; /* save the sector number */ sim_debug(DEBUG_DETAIL, dptr, "dsk_srv seek start %04x trk %02x sec %02x\n", @@ -741,7 +748,7 @@ rezero: } /* Check if already on correct cylinder */ - if (trk != data->cyl) { + if (cyl != data->cyl) { /* Do seek */ uptr->CMD |= DSK_SEEKING; /* show we are seeking */ sim_debug(DEBUG_DETAIL, dptr, "dsk_srv seek unit=%02x trk %02x cyl %02x\n", @@ -948,7 +955,7 @@ void disk_ini(UNIT *uptr, t_bool f) DEVICE *dptr = find_dev_from_unit(uptr); int i = GET_TYPE(uptr->flags); - uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */ + uptr->CMD &= ~0x7fff; /* clear out the flags but leave ch/sa */ /* capacity is total allocation units time sectors per allocation unit */ /* total sectors on disk */ uptr->capac = disk_type[i].taus * disk_type[i].spau; diff --git a/SEL32/sel32_hsdp.c b/SEL32/sel32_hsdp.c index 60436ee..2864d75 100644 --- a/SEL32/sel32_hsdp.c +++ b/SEL32/sel32_hsdp.c @@ -48,7 +48,7 @@ extern uint32 SPAD[]; /* cpu SPAD memory */ WD 0 - Data address WD 1 - Flags - 0 -36 byte count -Data - 224 word INCH buffer address +Data - 224 word INCH buffer address (SST) WD 1 Drive 0 Attribute register WD 2 Drive 1 Attribute register WD 3 Drive 2 Attribute register @@ -58,27 +58,120 @@ WD 6 Drive 5 Attribute register WD 7 Drive 6 Attribute register WD 8 Drive 7 Attribute register -Memory attribute register layout -bits 0-7 - Flags - bits 0&1 - 00=Reserved, 01=MHD, 10=FHD, 11=MHD with FHD option - bit 2 - 1=Cartridge module drive - bit 3 - 0=Reserved - bit 4 - 1=Drive not present - bit 5 - 1=Dual Port - bit 6 - 0=Reserved - bit 7 - 0=Reserved -bits 8-15 - sector count (sectors per track)(F16=16, F20=20) -bits 16-23 - MHD Head count (number of heads on MHD) -bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option of - mini-module) +Drive attribute register bit assignments (DATR) +Byte 0 bits 0-7 - Flags + Drive type + bits 0&1 - 00=Undefined + - 01=MHD + - 10=Undefined + - 11=Undefined + Optimized seeks + bit 2&3 - 00=Optimize seeks and post IOCL status out of order + - 01=Optimize seeks and post IOCL status in order + - 10=Do not optimize seeks + - 11=Do not optimize seeks + bit 4 - 0=Drive is present + - 1=Drive not present + bit 5 - 0=Not Dual Port + - 1=Dual Port + Sector Size + bit 6&7 - 00=768 bytes + 01=1024 bytes + 10=2048 bytes + 11=Unassigned +Byte 1 bits 8-15 - Sectors per track +Byte 2 bits 16-23 - Number of head +Byte 3 bits 24-31 - Reserved (zero) */ +/* +Drive status bit assignments (DSR) +Byte 0 bits 0-7 + bit 00 - Seek End + 01 - Unit selected + 02 - Sector pulse counter bit 0 + 03 - Sector pulse counter bit 1 + 04 - Sector pulse counter bit 2 + 05 - Sector pulse counter bit 3 + 06 - Sector pulse counter bit 4 + 07 - Sector pulse counter bit 5 +Byte 1 bits 7-15 + bit 08 - Disc drive fault + 09 - Seek error + 10 - On cylinder + 11 - Unit Ready + 12 - Write protected + 13 - Drive busy + 14 - Reserved (zero) + 15 - Reserved (zero) +*/ -/* 224 word INCH Buffer layout */ -/* 128 word subchannel status storage (SST) */ -/* 66 words of program status queue (PSQ) */ -/* 26 words of scratchpad */ -/* 4 words of label buffer registers */ +/* Subchannel Target Register (STAR) */ +/* byte 0 - Cylinder MS byte */ +/* byte 1 - Cylinder LS byte */ +/* byte 2 - Track count */ +/* byte 3 - Sector count */ + +/* Mode Register (MODE) */ +/* Bits 0-7 - bit assignments */ + +/* Bits 0-3 are for data recovery operations which can be */ +/* tried by the software */ +/* 0 - Servo offset 0/1=disable/enable */ +/* 1 - Servo offset polarity 0/1=positive/negative */ +/* 2 - Data strobe offset 0/1=disable/enable */ +/* 3 - Data strobe offset polarity 0/1=positive/negative */ +/* Bit 4 enables sector ECC data to be read or written for */ +/* diagnostic commands */ +/* 4 - Read/write ECC data 0/1=disable/enable */ +/* Bit 5 controls the transfer of an ID during express bus */ +/* read commands */ +/* 5 - Express bus ID 0/1=enable/disable */ +/* Bit 6 enables auto-retry in accordance with the firmware */ +/* auto-retry algorithms */ +/* 6 - Auto retry 0/1=enable/disable */ +/* Bit 7 disables the subchannel from interacting with the */ +/* disc drive and is for diagnostic testing only */ +/* 7 - Diagnostic mode 0/1=disable/enable */ + +/* Sense Buffer Register (SBR) */ +/* The SBR contains subchannel error status information */ +/* Byte 0 + * bit 00 Command rejected (CR) + * 01 Intervention requested (IR) + * 02 Unit select error (USEL) + * 03 Equipment check (EQCK) + * 04 Reserved (zero) + * 05 Reserved (zero) + * 06 Disc format error (DFER) + * 07 Defective track encountered (DETR) + * Byte 1 + * bit 08 Reserved (zero) + * 09 At alternate track (AATT) + * 10 Write protect error (WPER) + * 11 Write lock error (WRL) + * 12 Mode check (MOCK) + * 13 Invalid address (INAD) + * 14 Release fault (RELF) + * 15 Chaining error (CHER) + * Byte 2 + * bit 16 Revolution lost (REVL) + * 17 Disc addressing or seek error + * 18 Reserved (zero) + * 19 Reserved (zero) + * 20 ECC error in data (ECCD) + * 21 Reserved (zero) + * 22 Reserved (zero) + * 23 Uncorrectable ECC error (UECC) + * Byte 3 + * Not used + * */ + +/* 224 word Subchannel Storage Buffer (SST) */ +/* 128 words reserved */ +/* 66 words (33 DW) of program status queue (PSQ) */ +/* 8 words of retry counters (1/channel) */ +/* 22 words reserved */ #define CMD u3 /* u3 */ @@ -91,32 +184,38 @@ bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option #define DSK_SEEKING 0x1000 /* Disk is currently seeking */ #define DSK_READING 0x2000 /* Disk is reading data */ #define DSK_WRITING 0x4000 /* Disk is writing data */ -#define DSK_BUSY 0x8000 /* Flag to send a CUE */ +#define DSK_BUSY 0x8000 /* Disk is busy */ /* commands */ #define DSK_INCH 0x00 /* Initialize channel */ #define DSK_WD 0x01 /* Write data */ #define DSK_RD 0x02 /* Read data */ #define DSK_NOP 0x03 /* No operation */ #define DSK_SNS 0x04 /* Sense */ -#define DSK_SCK 0x07 /* Seek cylinder, track, sector */ +#define DSK_SKC 0x07 /* Seek cylinder, track, sector */ #define DSK_TIC 0x08 /* Transfer in channel */ -#define DSK_FNSK 0x0B /* Format for no skip */ -#define DSK_LPL 0x13 /* Lock protected label */ +#define DSK_FMT 0x0B /* Format track */ +#define DSK_RE 0x12 /* Read express bus with ECC */ +//#define DSK_LPL 0x13 /* Lock protected label */ #define DSK_LMR 0x1F /* Load mode register */ +#define DSK_RENO 0x22 /* Read express bus with no ECC */ #define DSK_RES 0x23 /* Reserve */ #define DSK_WSL 0x31 /* Write sector label */ #define DSK_RSL 0x32 /* Read sector label */ #define DSK_REL 0x33 /* Release */ #define DSK_XEZ 0x37 /* Rezero */ +#define DSK_WTF 0x41 /* Write track format */ +#define DSK_RVL 0x42 /* Read vendor label */ #define DSK_POR 0x43 /* Priority Override */ #define DSK_IHA 0x47 /* Increment head address */ -#define DSK_SRM 0x4F /* Set reserve track mode */ +//#define DSK_SRM 0x4F /* Set reserve track mode */ #define DSK_WTL 0x51 /* Write track label */ #define DSK_RTL 0x52 /* Read track label */ -#define DSK_XRM 0x5F /* Reset reserve track mode */ -#define DSK_RAP 0xA2 /* Read angular positions */ -#define DSK_TESS 0xAB /* Test STAR (subchannel target address register) */ -#define DSK_ICH 0xFF /* Initialize Controller */ +//#define DSK_XRM 0x5F /* Reset reserve track mode */ +#define DSK_RAP 0xA2 /* Read angular position */ +//#define DSK_TESS 0xAB /* Test STAR (subchannel target address register) */ +#define DSK_REC 0xB2 /* Read ECC */ +#define DSK_FINC 0xC0 /* Fake while in srv Initialize channel */ +#define DSK_INC 0xFF /* Initialize Controller */ #define STAR u4 /* u4 - sector target address register (STAR) */ @@ -208,26 +307,31 @@ struct hsdp_t uint8 spau; /* # sectors per allocation unit */ uint8 spb; /* # sectors per block (256 WDS)*/ uint32 cyl; /* Number of cylinders */ + uint32 geom; /* disk star geometry cyl(16) hsd(8) sec(8) */ uint8 type; /* Device type code */ } + hsdp_type[] = { /* Class F Disc Devices */ /*XX CYL SIZE */ - {"MH040", 20000, 625, 5, 256, 16, 2, 1, 400, 0x40}, /*0 411 40 M */ - {"MH080", 40000, 1250, 5, 256, 16, 2, 1, 800, 0x40}, /*1 823 80 M */ - {"MH160", 80000, 1250, 10, 256, 16, 4, 1, 1600, 0x40}, /*2 823 160 M */ - {"MH300", 76000, 2375, 19, 256, 16, 4, 1, 800, 0x40}, /*3 823 300 M */ - {"MH340", 76000, 2375, 24, 256, 16, 4, 1, 800, 0x40}, /*4 711 340 M */ - {"FH005", 5120, 184, 4, 256, 16, 1, 1, 64, 0x80}, /*5 64 5 M */ - {"CD032", 8000, 250, 1, 256, 16, 2, 1, 800, 0x60}, /*6 823 32 M */ - {"CD032", 8000, 250, 1, 256, 16, 2, 1, 800, 0x60}, /*7 823 32 M */ - {"CD064", 8000, 250, 1, 256, 16, 2, 1, 800, 0x60}, /*8 823 64 M */ - {"CD064", 24000, 750, 3, 256, 16, 2, 1, 800, 0x60}, /*9 823 64 M */ - {"CD096", 8000, 250, 1, 256, 16, 2, 1, 800, 0x60}, /*10 823 96 M */ - {"CD096", 40000, 1250, 5, 256, 16, 2, 1, 800, 0x60}, /*11 823 96 M */ - {"MH600", 80000, 2500, 40, 256, 16, 8, 1, 800, 0x40}, /*12 843 600 M */ - {"FM600", 80000, 2500, 40, 256, 16, 8, 1, 800, 0x40}, /*13 843 600 M */ - {"FM600", 1600, 50, 40, 256, 16, 1, 1, 2, 0x80}, /*14 10 600 M */ + {"MH040", 20000, 625, 5, 256, 16, 2, 1, 400, 0, 0x40}, /*0 411 40 M */ + {"MH080", 40000, 1250, 5, 256, 16, 2, 1, 800, 0, 0x40}, /*1 823 80 M 9342 */ + {"MH160", 80000, 1250, 10, 256, 16, 4, 1, 1600, 0, 0x40}, /*2 823 160 M 8148 */ +// {"MH300", 76000, 2375, 19, 256, 16, 4, 1, 800, 0, 0x40}, /*3 823 300 M 9346 */ +// {"MH300", 80000, 2500, 10, 256, 35, 4, 1, 800, 0, 0x40}, /*3 823 300 M 8887 */ +// {"MH300", 80000, 2500, 10, 256, 34, 4, 1, 820, 0, 0x40}, /*3 823 300 M 8887 */ + {"MH300", 80000, 2500, 10, 256, 34, 4, 1, 844, 0, 0x40}, /*3 823 300 M 8887 */ + {"MH340", 76000, 2375, 24, 256, 16, 4, 1, 800, 0, 0x40}, /*4 711 340 M 8858 */ + {"FH005", 5120, 184, 4, 256, 16, 1, 1, 64, 0, 0x80}, /*5 64 5 M */ + {"CD032", 8000, 250, 1, 256, 16, 2, 1, 800, 0, 0x60}, /*6 823 32 M */ + {"CD032", 8000, 250, 1, 256, 16, 2, 1, 800, 0, 0x60}, /*7 823 32 M */ + {"CD064", 8000, 250, 1, 256, 16, 2, 1, 800, 0, 0x60}, /*8 823 64 M */ + {"CD064", 24000, 750, 3, 256, 16, 2, 1, 800, 0, 0x60}, /*9 823 64 M */ + {"CD096", 8000, 250, 1, 256, 16, 2, 1, 800, 0, 0x60}, /*10 823 96 M */ + {"CD096", 40000, 1250, 5, 256, 16, 2, 1, 800, 0, 0x60}, /*11 823 96 M */ + {"MH600", 80000, 2500, 40, 256, 16, 8, 1, 800, 0, 0x40}, /*12 843 600 M */ + {"FM600", 80000, 2500, 40, 256, 16, 8, 1, 800, 0, 0x40}, /*13 843 600 M */ + {"FM600", 1600, 50, 40, 256, 16, 1, 1, 2, 0, 0x80}, /*14 10 600 M */ {NULL, 0} }; @@ -332,14 +436,14 @@ MTAB hsdp_mod[] = { UNIT dpa_unit[] = { /* SET_TYPE(3) DM300 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC00)}, /* 0 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC02)}, /* 1 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC04)}, /* 2 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC06)}, /* 3 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC08)}, /* 4 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0A)}, /* 5 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0C)}, /* 6 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0E)}, /* 7 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x800)}, /* 0 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x802)}, /* 1 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x804)}, /* 2 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x806)}, /* 3 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x808)}, /* 4 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x80A)}, /* 5 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x80C)}, /* 6 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x80E)}, /* 7 */ }; DIB dpa_dib = { @@ -352,8 +456,8 @@ DIB dpa_dib = { dpa_unit, /* Pointer to units structure */ dpa_chp, /* Pointer to chan_prg structure */ NUM_UNITS_HSDP, /* number of units defined */ - 0x0F, /* 16 devices - device mask */ - 0x0C00, /* parent channel address */ + 0x0E, /* 16 devices - device mask */ + 0x0800, /* parent channel address */ 0, /* fifo input index */ 0, /* fifo output index */ 0, /* interrupt status fifo for channel */ @@ -373,14 +477,14 @@ CHANP dpb_chp[NUM_UNITS_HSDP] = {0}; UNIT dpb_unit[] = { /* SET_TYPE(3) DM300 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x800)}, /* 0 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x802)}, /* 1 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x804)}, /* 2 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x806)}, /* 3 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x808)}, /* 4 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x80A)}, /* 5 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x80C)}, /* 6 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0x80E)}, /* 7 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC00)}, /* 0 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC02)}, /* 1 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC04)}, /* 2 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC06)}, /* 3 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC08)}, /* 4 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0A)}, /* 5 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0C)}, /* 6 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(3), 0), 0, UNIT_ADDR(0xC0E)}, /* 7 */ }; @@ -394,8 +498,8 @@ DIB dpb_dib = { dpb_unit, /* Pointer to units structure */ dpb_chp, /* Pointer to chan_prg structure */ NUM_UNITS_HSDP, /* number of units defined */ - 0x0F, /* 8 devices - device mask */ - 0x0800, /* parent channel address */ + 0x0E, /* 8 devices - device mask */ + 0x0C00, /* parent channel address */ 0, /* fifo input index */ 0, /* fifo output index */ 0, /* interrupt status fifo for channel */ @@ -413,14 +517,16 @@ DEVICE dpb_dev = { /* start a disk operation */ uint8 hsdp_preio(UNIT *uptr, uint16 chan) { - DEVICE *dptr = find_dev_from_unit(uptr); - int unit = (uptr - dptr->units); + DEVICE *dptr = find_dev_from_unit(uptr); + uint16 addr = GET_UADDR(uptr->CMD); + int unit = (uptr - dptr->units); - if ((uptr->CMD & 0xff00) != 0) { /* just return if busy */ +//TRY if ((uptr->CMD & 0xff00) != 0) { /* just return if busy */ + if (uptr->CMD & DSK_BUSY) { /* just return if busy */ return SNS_BSY; } - sim_debug(DEBUG_CMD, dptr, "hsdp_preio unit=%02x OK\n", unit); + sim_debug(DEBUG_CMD, dptr, "hsdp_preio unit=%02x chsa=%04x OK\n", unit, addr); return 0; /* good to go */ } @@ -431,18 +537,22 @@ uint8 hsdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) int unit = (uptr - dptr->units); uint8 ch; - sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd unit %02x cmd %02x CMD %08x\n", unit, cmd, uptr->CMD); + sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd addr %04x unit %02x cmd %02x CMD %08x\n", + addr, unit, cmd, uptr->CMD); if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd unit %02x not attached\n", unit); uptr->SNS |= SNS_INTVENT; /* unit intervention required */ if (cmd != DSK_SNS) /* we are completed with unit check status */ return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; } if ((uptr->CMD & DSK_CMDMSK) != 0) { + sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd unit %02x busy\n", unit); uptr->CMD |= DSK_BUSY; /* Flag we we are busy */ return SNS_BSY; } if ((uptr->CMD & 0xff00) != 0) { /* if any status info, we are busy */ + sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd unit %02x busy2\n", unit); return SNS_BSY; } sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd CMD continue unit=%02x cmd %02x\n", unit, cmd); @@ -499,6 +609,7 @@ uint8 hsdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) chan_write_byte(addr, &ch) ; /* bytes 12 & 13 contain drive related status */ ch = 0; /* zero for now */ + /* TODO set drive status bits here */ chan_write_byte(addr, &ch) ; chan_write_byte(addr, &ch) ; @@ -531,25 +642,32 @@ uint8 hsdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) mema = (uint32)uptr->STAR; /* get memory address of buffer */ uptr->STAR = M[mema>>2]; /* get status buffer address for XIO return status */ sim_debug(DEBUG_CMD, dptr, - "hsdp_startcmd starting inch cmd addr %04x STAR %08x mema %08x units %02x\n", + "hsdp_startcmd starting inch cmd addr %04x stat buf addr %08x mema %08x units %02x\n", addr, uptr->STAR, mema, dptr->numunits); /* the next 8 words have drive data for each unit */ /* WARNING 8 drives must be defined for this controller */ /* so we will not have a map fault */ for (i=0; inumunits && i<8; i++) { /* process all drives */ + int type = GET_TYPE(up->flags); /* get disk type */ up->ATTR = M[(mema>>2)+i+1]; /* save each unit's drive data */ + /* see if sec/trk and num hds are set, if not set them */ + if ((up->ATTR & 0x00ff0000) == 0) + up->ATTR = (up->ATTR & 0xff00ffff) | ((hsdp_type[type].spt & 0xff) << 16); + if ((up->ATTR & 0x0000ff00) == 0) + up->ATTR = (up->ATTR & 0xffff00ff) | ((hsdp_type[type].nhds & 0xff) << 8); sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd ATTR data %08x unit %02x flags %02x sec %02x MHD %02x FHD %02x\n", up->ATTR, i, (up->ATTR >> 24)&0xff, (up->ATTR >> 16)&0xff, (up->ATTR >> 8)&0xff, (up->ATTR&0xff)); up++; /* next unit for this device */ } sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd done inch cmd addr %04x\n", addr); - uptr->CMD |= DSK_CMDMSK; /* use 0xff for inch, just need int */ +// uptr->CMD |= DSK_CMDMSK; /* use 0xff for inch, just need int */ + uptr->CMD |= DSK_FINC; /* use 0xc0 for inch, just need int */ sim_activate(uptr, 20); /* start things off */ return 0; } - case DSK_SCK: /* Seek command 0x07 */ + case DSK_SKC: /* Seek command 0x07 */ case DSK_XEZ: /* Rezero & Read IPL record 0x1f */ uptr->CMD &= ~(DSK_STAR); /* show we do not have seek STAR in STAR */ case DSK_WD: /* Write command 0x01 */ @@ -571,6 +689,11 @@ uint8 hsdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) uptr->CMD |= cmd; /* save cmd */ sim_activate(uptr, 20); /* start things off */ break; + + case DSK_RTL: /* RTL 0x52 */ + uptr->CMD |= cmd; /* save cmd */ + sim_activate(uptr, 20); /* start things off */ + return 0; } sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd done with hsdp_startcmd %02x addr %04x SNS %08x\n", @@ -603,7 +726,7 @@ t_stat hsdp_srv(UNIT * uptr) uint8 buf2[1024]; uint8 buf[1024]; - sim_debug(DEBUG_DETAIL, &dda_dev, + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv entry unit %02x cmd %02x chsa %04x chan %04x count %04x\n", unit, cmd, chsa, chsa>>8, chp->ccw_count); @@ -619,14 +742,16 @@ t_stat hsdp_srv(UNIT * uptr) case 0: /* No command, stop disk */ break; - case DSK_CMDMSK: /* use 0xff for inch, just need int */ +// case DSK_CMDMSK: /* use 0xff for inch, just need int */ + case DSK_FINC: /* use 0xc0 for inch, just need int */ uptr->CMD &= ~(0xffff); /* remove old cmd */ sim_debug(DEBUG_CMD, dptr, "hsdp_srv cmd=%02x chsa %04x count %04x completed\n", cmd, chsa, chp->ccw_count); #ifdef FIX4MPX chan_end(chsa, SNS_CHNEND); /* return just channel end OK */ #else - chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ +//TRY chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + chan_end(chsa, SNS_CHNEND); /* return OK for UTX */ #endif break; @@ -638,35 +763,97 @@ t_stat hsdp_srv(UNIT * uptr) break; case DSK_SNS: /* 0x4 */ - ch = uptr->SNS & 0xff; - sim_debug(DEBUG_DETAIL, dptr, "dsk_srv sense unit=%02x 1 %02x\n", unit, ch); - chan_write_byte(chsa, &ch) ; + sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd CMD sense\n"); + + /* bytes 0,1 - Cyl entry from STAR reg in STAR */ +// ch = (uptr->STAR >> 24) & 0xff; + ch = (data->cyl >> 8) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv sense STAR b0 unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); +// ch = (uptr->STAR >> 16) & 0xff; + ch = (data->cyl) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv sense STAR b1 unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* byte 2 - Track entry from STAR reg in STAR */ +// ch = (uptr->STAR >> 8) & 0xff; + ch = (data->tpos) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv sense STAR b2 unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* byte 3 - Sector entry from STAR reg in STAR */ +// ch = (uptr->STAR) & 0xff; + ch = (data->spos) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv sense STAR b3 unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* bytes 4 - mode reg, byte 0 of SNS */ + ch = (uptr->SNS >> 24) & 0xff; /* return the sense data for device */ + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv sense unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* bytes 5-7 - status bytes, bytes 1-3 of SNS */ + ch = (uptr->SNS >> 16) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv sense unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); ch = (uptr->SNS >> 8) & 0xff; - sim_debug(DEBUG_DETAIL, dptr, "dsk_srv sense unit=%02x 2 %02x\n", unit, ch); - chan_write_byte(chsa, &ch) ; - ch = 0; - sim_debug(DEBUG_DETAIL, dptr, "dsk_srv sense unit=%02x 3 %02x\n", unit, ch); - chan_write_byte(chsa, &ch) ; - ch = unit; - sim_debug(DEBUG_DETAIL, dptr, "dsk_srv sense unit=%02x 4 %02x\n", unit, ch); - chan_write_byte(chsa, &ch) ; - ch = 4; - uptr->CMD &= ~(0xff00); + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv sense unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->SNS) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv sense unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* bytes 8-11 - drive attribute register (DATR) entries from uptr->ATTR via + * INCH cmd */ + ch = (uptr->ATTR >> 24) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv datr unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->ATTR >> 16) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv datr unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->ATTR >> 8 ) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv datr unit=%02x 3 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + ch = (uptr->ATTR >> 0) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv datr unit=%02x 4 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + /* bytes 12 & 13 are optional, so check if read done */ + /* TODO add drive status bits here */ + if ((test_write_byte_end(chsa)) == 0) { + /* bytes 12 & 13 contain drive related status */ + ch = 0; /* zero for now */ + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv dsr unit=%02x 1 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv dsr unit=%02x 2 %02x\n", + unit, ch); + chan_write_byte(chsa, &ch); + } + uptr->SNS &= 0xff000000; /* clear status bytes, but leave mode data */ +//TRY uptr->CMD &= ~(0xff00); /* clear busy status */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); break; - case DSK_SCK: /* Seek cylinder, track, sector 0x07 */ + case DSK_SKC: /* Seek cylinder, track, sector 0x07 */ /* If we are waiting on seek to finish, check if there yet. */ if (uptr->CMD & DSK_SEEKING) { /* see if on cylinder yet */ if ((uptr->STAR >> 16) == data->cyl) { /* we are on cylinder, seek is done */ - sim_debug(DEBUG_CMD, dptr, "dsk_srv seek on cylinder unit=%02x %02x %04x\n", + sim_debug(DEBUG_CMD, dptr, "hsdp_srv seek on cylinder unit=%02x %02x %04x\n", unit, uptr->STAR >> 16, data->cyl); uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ set_devattn(chsa, SNS_DEVEND); /* start the operation */ - sim_debug(DEBUG_DETAIL, dptr, "dsk_srv seek end unit=%02x %02x %04x\n", + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv seek end unit=%02x %02x %04x\n", unit, uptr->STAR >> 16, data->cyl); sim_activate(uptr, 20); break; @@ -674,7 +861,7 @@ t_stat hsdp_srv(UNIT * uptr) /* Compute delay based of difference. */ /* Set next state = index */ i = (uptr->STAR >> 16) - data->cyl; - sim_debug(DEBUG_CMD, dptr, "dsk_srv seek unit=%02x %02x %04x\n", unit, + sim_debug(DEBUG_CMD, dptr, "hsdp_srv seek unit=%02x %02x %04x\n", unit, uptr->STAR >> 16, i); if (i > 0 ) { if (i > 50) { @@ -705,7 +892,7 @@ t_stat hsdp_srv(UNIT * uptr) if ((int32)data->cyl < 0) /* test for less than zero */ data->cyl = 0; /* make zero */ } - sim_debug(DEBUG_DETAIL, dptr, "dsk_srv seek next unit=%02x %02x %04x\n", + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv seek next unit=%02x %02x %04x\n", unit, uptr->STAR >> 16, data->cyl); sim_activate(uptr, 2); break; @@ -713,36 +900,51 @@ t_stat hsdp_srv(UNIT * uptr) } /* not seeking, so start a new seek */ - /* Read in 4 character seek code */ + /* set buf data to current STAR values */ + buf[0] = (data->cyl >> 8) & 0xff; + buf[1] = (data->cyl) & 0xff; + buf[2] = (data->tpos) & 0xff; + buf[3] = (data->spos) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv STAR unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + /* Read in up to 4 character seek code */ for (i = 0; i < 4; i++) { if (chan_read_byte(chsa, &buf[i])) { - /* we have error, bail out */ - uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ - uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; - chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); - break; + if (i == 0) { + /* we have error, bail out */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + /* just read the next byte */ } } + /* done reading, see how many we read */ + if (i == 1) { + /* UTX wants to set seek STAR to zero */ + buf[0] = buf[1] = buf[2] = buf[3] = 0; + } + /* else the cyl, trk, and sect are ready to update */ rezero: - sim_debug(DEBUG_DETAIL, dptr, "dsk_srv seek unit=%02x star %02x %02x %02x %02x\n", + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv seek unit=%02x star %02x %02x %02x %02x\n", unit, buf[0], buf[1], buf[2], buf[3]); /* save STAR (target sector) data in STAR */ uptr->STAR = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]); - cyl = uptr->STAR >> 16; /* get the cylinder */ + cyl = (uptr->STAR >> 16) & 0xffff; /* get the cylinder */ trk = buf[2]; /* get the track */ sim_debug(DEBUG_DETAIL, dptr, - "dsk_srv SEEK cyl %04x trk %02x sec %02x unit=%02x\n", cyl&0xffff, trk, buf[3], unit); + "hsdp_srv SEEK cyl %04x trk %02x sec %02x unit=%02x\n", cyl&0xffff, trk, buf[3], unit); - /* FIXME do something with FHD here */ /* Check if seek valid */ if (cyl > hsdp_type[type].cyl || trk >= hsdp_type[type].nhds || buf[3] > hsdp_type[type].spt) { sim_debug(DEBUG_CMD, dptr, - "dsk_srv seek ERROR cyl %04x trk %02x sec %02x unit=%02x\n", - cyl, trk, buf[3], unit); + "hsdp_srv seek ERROR cyl %04x trk %02x sec %02x unit=%02x\n", + cyl, trk, buf[3], unit); uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ - uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; /* set error status */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; /* set error status */ /* we have an error, tell user */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* end command */ @@ -752,27 +954,29 @@ rezero: uptr->CMD |= DSK_STAR; /* show we have seek STAR in STAR */ /* calc the sector address of data */ /* calculate file position in bytes of requested sector */ + // FIXME for variable sector size tstart = (cyl * hsdp_type[type].nhds * tsize) + (trk * tsize) + (buf[3] * 1024); data->tpos = trk; /* save the track/head number */ data->spos = buf[3]; /* save the sector number */ - sim_debug(DEBUG_DETAIL, dptr, "dsk_srv seek start %04x trk %02x sec %02x\n", - tstart, trk, buf[3]); + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv seek start %04x cyl %04x trk %02x sec %02x\n", + tstart, cyl, trk, buf[3]); if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* seek home */ - sim_debug(DEBUG_DETAIL, dptr, "dsk_srv Error on seek to %04x\n", tstart); + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv Error on seek to %08x\n", tstart); } /* Check if already on correct cylinder */ - if (trk != data->cyl) { - /* Do seek */ + if (cyl != data->cyl) { + /* No, Do seek */ uptr->CMD |= DSK_SEEKING; /* show we are seeking */ - sim_debug(DEBUG_DETAIL, dptr, "dsk_srv seek unit=%02x trk %02x cyl %02x\n", - unit, trk, data->cyl); - sim_activate(uptr, 20); + sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv seek unit=%02x cyl %04x trk %02x sec %02x\n", + unit, cyl, trk, buf[3]); + sim_activate(uptr, 20); /* start up off */ chan_end(chsa, SNS_CHNEND); } else { + /* Yes, we done */ sim_debug(DEBUG_DETAIL, dptr, - "dsk_srv calc sect addr seek start %04x trk %02x sec %02x\n", - tstart, trk, buf[3]); + "hsdp_srv calc sect addr seek start %04x cyl %04x trk %02x sec %02x\n", + tstart, cyl, trk, buf[3]); uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ sim_activate(uptr, 20); chan_end(chsa, SNS_DEVEND|SNS_CHNEND); @@ -785,7 +989,7 @@ rezero: /* Do a seek to 0 */ uptr->STAR = 0; /* set STAR to 0, 0, 0 */ uptr->CMD &= ~(0xffff); /* remove old cmd */ - uptr->CMD |= DSK_SCK; /* show as seek command */ + uptr->CMD |= DSK_SKC; /* show as seek command */ tstart = 0; /* byte offset is 0 */ /* Read in 1 dummy character for length to inhibit SLI posting */ if (chan_read_byte(chsa, &buf[0])) { @@ -850,7 +1054,7 @@ rezero: } sim_debug(DEBUG_CMD, dptr, - "DISK READ from sec end bytes end %04x from diskfile cyl %04x hds %02x sec %02x\n", + "DISK READ at sector end, read %04x bytes from disk @ cyl %04x hds %02x sec %02x\n", ssize, data->cyl, data->tpos, data->spos); data->spos++; /* set sector to read next one */ @@ -862,7 +1066,11 @@ rezero: data->cyl++; /* cylinder position */ if (data->cyl >= (int)(hsdp_type[type].cyl)) { /* EOM reached, abort */ + sim_debug(DEBUG_DATAIO, dptr, + "DISK Read reached EOM for read from disk @ cyl %04x hds %02x sec %02x\n", + data->cyl, data->tpos, data->spos); uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ + data->cyl = 0; /* reset cylinder position */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; } @@ -871,7 +1079,7 @@ rezero: /* see if we are done reading data */ if (test_write_byte_end(chsa)) { sim_debug(DEBUG_DATAIO, dptr, - "DISK Read complete Read bytes from diskfile cyl %04x hds %02x sec %02x\n", + "DISK Read complete for read from disk @ cyl %04x hds %02x sec %02x\n", data->cyl, data->tpos, data->spos); uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); @@ -951,6 +1159,56 @@ wrdone: } break; + case DSK_RTL: /* RTL 0x52 */ + /* Read track zero to get disk geometry */ + /* write 30 bytes, b0-b1=cyl, b1=trk, b2=sec */ + /* zero the Track Label Buffer */ + for (i = 0; i < 30; i++) + buf[i] = 0; + i = 286895; /* umap sector address */ + sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd RTL STAR %08x Umap pointer %08x\n", + hsdp_type[type].geom, i); + /* set buf data to current STAR values */ + buf[0] = (hsdp_type[type].cyl >> 8) & 0xff; + buf[1] = (hsdp_type[type].cyl) & 0xff; + buf[2] = hsdp_type[type].nhds & 0xff; + buf[3] = hsdp_type[type].spt & 0xff; + sim_debug(DEBUG_DETAIL, dptr, + "hsdp_srv RTL unit=%02x star %02x %02x %02x %02x\n", + unit, buf[0], buf[1], buf[2], buf[3]); + + /* the umap pointer is placed by prep program */ + /* simulate pointer here */ + i = 286895; /* umap sector address */ + buf[16] = (i >> 24) & 0xff; + buf[17] = (i >> 16) & 0xff; + buf[18] = (i >> 8) & 0xff; + buf[19] = (i) & 0xff; + /* the tech doc shows the cyl/trk/sec data is in the first 4 bytes */ + /* of the track label, BUT it is really in the configuration data */ + /* area are too. That is where UTX looks. Byte 27 is sectors/track */ + /* and byte 28 is number of heads. Byte 25 is copy of byte 27. */ + buf[25] = hsdp_type[type].spt & 0xff; + buf[27] = hsdp_type[type].spt & 0xff; + buf[28] = hsdp_type[type].nhds & 0xff; + + /* now write track label data */ + for (i = 0; i < 30; i++) { + if (chan_write_byte(chsa, &buf[i])) { + /* we have write error, bail out */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + } + + /* command done */ + uptr->CMD &= ~(0xffff); /* remove old cmd */ + sim_debug(DEBUG_CMD, dptr, "hsdp_srv cmd RTL done chsa %04x count %04x completed\n", + chsa, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + default: sim_debug(DEBUG_DETAIL, dptr, "invalid command %02x unit %02x\n", cmd, unit); uptr->SNS |= SNS_CMDREJ; @@ -974,7 +1232,7 @@ void hsdp_ini(UNIT *uptr, t_bool f) /* total sectors on disk */ uptr->capac = hsdp_type[i].taus * hsdp_type[i].spau; - sim_debug(DEBUG_EXP, &dda_dev, "DPA init device %s on unit DPA%.1x cap %x\n", + sim_debug(DEBUG_EXP, dptr, "DPA init device %s on unit DPA%.1x cap %x\n", dptr->name, GET_UADDR(uptr->CMD), uptr->capac); } @@ -1029,6 +1287,10 @@ t_stat hsdp_attach(UNIT *uptr, CONST char *file) return SCPE_FMT; /* error */ } + /* set the max configuration geometry */ + hsdp_type[type].geom = (hsdp_type[type].cyl << 16) | + (hsdp_type[type].nhds << 8) | (hsdp_type[type].spt); + data->cyl = 0; /* current cylinder position */ data->tpos = 0; /* current track position */ data->spos = 0; /* current sector position */ @@ -1052,7 +1314,7 @@ t_stat hsdp_detach(UNIT * uptr) { t_stat hsdp_boot(int32 unit_num, DEVICE * dptr) { UNIT *uptr = &dptr->units[unit_num]; /* find disk unit number */ - sim_debug(DEBUG_CMD, &dda_dev, "Disk Boot dev/unit %x\n", GET_UADDR(uptr->CMD)); + sim_debug(DEBUG_CMD, dptr, "Disk Boot dev/unit %x\n", GET_UADDR(uptr->CMD)); SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */ SPAD[0xf8] = 0xF000; /* show as F class device */ if ((uptr->flags & UNIT_ATT) == 0) @@ -1073,8 +1335,8 @@ t_stat hsdp_set_type(UNIT * uptr, int32 val, CONST char *cptr, void *desc) return SCPE_ALATT; for (i = 0; hsdp_type[i].name != 0; i++) { if (strcmp(hsdp_type[i].name, cptr) == 0) { - uptr->flags &= ~UNIT_TYPE; - uptr->flags |= SET_TYPE(i); + uptr->flags &= ~UNIT_TYPE; /* clear old type */ + uptr->flags |= SET_TYPE(i); /* set new type */ uptr->capac = hsdp_type[i].taus * hsdp_type[i].spau; return SCPE_OK; } diff --git a/SEL32/sel32_iop.c b/SEL32/sel32_iop.c index fc53ca7..2442e8b 100644 --- a/SEL32/sel32_iop.c +++ b/SEL32/sel32_iop.c @@ -1,4 +1,4 @@ -/* sel32_iop.c: SEL-32 Class F IOP processor channel. +/* sel32_iop.c: SEL-32 Model 8000/8001/8002 IOP processor controller Copyright (c) 2018-2019, James C. Bevier @@ -55,6 +55,7 @@ const char *iop_desc(DEVICE *dptr); /* Held in u3 is the device command and status */ #define IOP_INCH 0x00 /* Initialize channel command */ +#define IOP_INCH2 0xf0 /* Initialize channel command after start */ #define IOP_NOP 0x03 /* NOP command */ #define IOP_MSK 0xff /* Command mask */ @@ -156,7 +157,7 @@ uint8 iop_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */ uptr->u3 &= LMASK; /* leave only chsa */ sim_debug(DEBUG_CMD, &iop_dev, "iop_startcmd %04x: Cmd INCH\n", chan); - uptr->u3 |= IOP_MSK; /* save INCH command as 0xff */ + uptr->u3 |= IOP_INCH2; /* save INCH command as 0xf0 */ sim_activate(uptr, 20); /* TRY 07-13-19 */ return 0; /* no status change */ break; @@ -191,12 +192,13 @@ t_stat iop_srv(UNIT *uptr) int cmd = uptr->u3 & IOP_MSK; /* test for NOP or INCH cmds */ - if ((cmd == IOP_NOP) || (cmd == IOP_MSK)) { /* NOP has do nothing */ - uptr->u3 &= LMASK; /* nothing left, command complete */ + if ((cmd == IOP_NOP) || (cmd == IOP_INCH2)) { /* NOP has do nothing */ + uptr->u3 &= LMASK; /* nothing left, command complete */ sim_debug(DEBUG_CMD, &iop_dev, "iop_srv INCH/NOP chan %d: chnend|devend\n", chsa); - chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ } else if (cmd) { + uptr->u3 &= LMASK; /* nothing left, command complete */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* done */ } return SCPE_OK; @@ -231,7 +233,7 @@ t_stat iop_reset(DEVICE *dptr) /* sho help iop */ t_stat iop_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr) { - fprintf(st, "SEL 32 IOP Channel Controller at 0x7E00\r\n"); + fprintf(st, "SEL-32 IOP Model 8000 Channel Controller at 0x7E00\r\n"); fprintf(st, "The IOP fields all interrupts and status posting\r\n"); fprintf(st, "for each of the controllers on the system.\r\n"); fprintf(st, "Nothing can be configured for this Channel.\r\n"); @@ -242,7 +244,7 @@ t_stat iop_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr const char *iop_desc(DEVICE *dptr) { - return("SEL-32 IOP Channel Controller @ 0x7E00"); + return("SEL-32 IOP Model 8000 Channel Controller @ 0x7E00"); } #endif diff --git a/SEL32/sel32_scfi.c b/SEL32/sel32_scfi.c index f6ccb2f..044370a 100644 --- a/SEL32/sel32_scfi.c +++ b/SEL32/sel32_scfi.c @@ -93,6 +93,7 @@ bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option #define DSK_BUSY 0x8000 /* Flag to send a CUE */ /* commands */ #define DSK_INCH 0x00 /* Initialize channel */ +#define DSK_INCH2 0xf0 /* Initialize channel for processing */ #define DSK_WD 0x01 /* Write data */ #define DSK_RD 0x02 /* Read data */ #define DSK_NOP 0x03 /* No operation */ @@ -391,8 +392,8 @@ uint8 scfi_preio(UNIT *uptr, uint16 chan) DEVICE *dptr = find_dev_from_unit(uptr); int unit = (uptr - dptr->units); - sim_debug(DEBUG_CMD, dptr, "scfi_preio u3 %08x unit=%02x\n", uptr->u3, unit); - if ((uptr->u3 & 0xff00) != 0) { /* just return if busy */ + sim_debug(DEBUG_CMD, dptr, "scfi_preio CMD %08x unit=%02x\n", uptr->CMD, unit); + if ((uptr->CMD & 0xff00) != 0) { /* just return if busy */ return SNS_BSY; } sim_debug(DEBUG_CMD, dptr, "scfi_preio unit=%02x\n", unit); @@ -400,23 +401,23 @@ uint8 scfi_preio(UNIT *uptr, uint16 chan) } uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { - uint16 addr = GET_UADDR(uptr->u3); + uint16 addr = GET_UADDR(uptr->CMD); DEVICE *dptr = find_dev_from_unit(uptr); int unit = (uptr - dptr->units); uint8 ch; - sim_debug(DEBUG_CMD, dptr, "scfi_startcmd unit %02x cmd %04x u3 %08x\n", unit, cmd, uptr->u3); + sim_debug(DEBUG_CMD, dptr, "scfi_startcmd unit %02x cmd %04x CMD %08x\n", unit, cmd, uptr->CMD); if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ - uptr->u5 |= SNS_INTVENT; /* unit intervention required */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ if (cmd != DSK_SNS) /* we are completed with unit check status */ return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; } - if ((uptr->u3 & DSK_CMDMSK) != 0) { - uptr->u3 |= DSK_BUSY; /* Flag we we are busy */ + if ((uptr->CMD & DSK_CMDMSK) != 0) { + uptr->CMD |= DSK_BUSY; /* Flag we we are busy */ return SNS_BSY; } - if ((uptr->u3 & 0xff00) != 0) { /* if any status info, we are busy */ + if ((uptr->CMD & 0xff00) != 0) { /* if any status info, we are busy */ return SNS_BSY; } sim_debug(DEBUG_CMD, dptr, "scfi_startcmd CMD 2 unit=%02x cmd %02x\n", unit, cmd); @@ -424,56 +425,56 @@ uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { if ((uptr->flags & UNIT_ATT) == 0) { /* see if unit is attached */ if (cmd == DSK_SNS) { /* not attached, is cmd Sense 0x04 */ sim_debug(DEBUG_CMD, dptr, "scfi_startcmd CMD sense\n"); - /* bytes 0,1 - Cyl entry from STAR reg in u4 */ - ch = (uptr->u4 >> 24) & 0xff; + /* bytes 0,1 - Cyl entry from STAR reg in CMD */ + ch = (uptr->CMD >> 24) & 0xff; sim_debug(DEBUG_DETAIL, dptr, "scfi_startcmd sense STAR b0 unit=%02x 1 %02x\n", unit, ch); chan_write_byte(addr, &ch) ; - ch = (uptr->u4 >> 16) & 0xff; + ch = (uptr->CMD >> 16) & 0xff; sim_debug(DEBUG_DETAIL, dptr, "scfi_startcmd sense STAR b1 unit=%02x 1 %02x\n", unit, ch); chan_write_byte(addr, &ch) ; - /* byte 2 - Track entry from STAR reg in u4 */ - ch = (uptr->u4 >> 8) & 0xff; + /* byte 2 - Track entry from STAR reg in CMD */ + ch = (uptr->CMD >> 8) & 0xff; sim_debug(DEBUG_DETAIL, dptr, "scfi_startcmd sense STAR b2 unit=%02x 1 %02x\n", unit, ch); chan_write_byte(addr, &ch) ; - /* byte 3 - Sector entry from STAR reg in u4 */ - ch = (uptr->u4) & 0xff; + /* byte 3 - Sector entry from STAR reg in CMD */ + ch = (uptr->CMD) & 0xff; sim_debug(DEBUG_DETAIL, dptr, "scfi_startcmd sense STAR b3 unit=%02x 1 %02x\n", unit, ch); chan_write_byte(addr, &ch) ; - /* bytes 4 - mode reg, byte 0 of u5 */ - ch = (uptr->u5 >> 24) & 0xff; /* return the sense data for device */ + /* bytes 4 - mode reg, byte 0 of SNS */ + ch = (uptr->SNS >> 24) & 0xff; /* return the sense data for device */ sim_debug(DEBUG_DETAIL, dptr, "scfi_startcmd sense unit=%02x 1 %02x\n", unit, ch); chan_write_byte(addr, &ch) ; - /* bytes 5-7 - status bytes, bytes 1-3 of u5 */ - ch = (uptr->u5 >> 16) & 0xff; + /* bytes 5-7 - status bytes, bytes 1-3 of SNS */ + ch = (uptr->SNS >> 16) & 0xff; sim_debug(DEBUG_DETAIL, dptr, "scfi_startcmd sense unit=%02x 2 %02x\n", unit, ch); chan_write_byte(addr, &ch) ; - ch = (uptr->u5 >> 8) & 0xff; + ch = (uptr->SNS >> 8) & 0xff; sim_debug(DEBUG_DETAIL, dptr, "scfi_startcmd sense unit=%02x 3 %02x\n", unit, ch); chan_write_byte(addr, &ch) ; - ch = (uptr->u5) & 0xff; + ch = (uptr->SNS) & 0xff; sim_debug(DEBUG_DETAIL, dptr, "scfi_startcmd sense unit=%02x 4 %02x\n", unit, ch); chan_write_byte(addr, &ch) ; - /* bytes 8-11 - drive attribute register (DATR) entries from uptr->u6 via INCH cmd */ - ch = (uptr->u6 >> 24) & 0xff; + /* bytes 8-11 - drive attribute register (DATR) entries from uptr->ATTR via INCH cmd */ + ch = (uptr->ATTR >> 24) & 0xff; chan_write_byte(addr, &ch) ; - ch = (uptr->u6 >> 16) & 0xff; + ch = (uptr->ATTR >> 16) & 0xff; chan_write_byte(addr, &ch) ; - ch = (uptr->u6 >> 8 ) & 0xff; + ch = (uptr->ATTR >> 8 ) & 0xff; chan_write_byte(addr, &ch) ; - ch = (uptr->u6 >> 0) & 0xff; + ch = (uptr->ATTR >> 0) & 0xff; chan_write_byte(addr, &ch) ; /* bytes 12 & 13 contain drive related status */ ch = 0; /* zero for now */ chan_write_byte(addr, &ch) ; chan_write_byte(addr, &ch) ; - uptr->u5 &= 0xff000000; /* clear status bytes, but leave mode data */ + uptr->SNS &= 0xff000000; /* clear status bytes, but leave mode data */ return SNS_CHNEND|SNS_DEVEND; } - if (cmd == 0x0) /* INCH cmd gives unit check */ + if (cmd == 0x00) /* INCH cmd gives unit check */ return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; - uptr->u5 |= (SNS_INTVENT|SNS_CMDREJ); /* set new error status */ + uptr->SNS |= (SNS_INTVENT|SNS_CMDREJ); /* set new error status */ return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* we done */ } @@ -486,33 +487,33 @@ uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { uint32 i; UNIT *up = dptr->units; /* first unit for this device */ sim_debug(DEBUG_CMD, dptr, - "scfi_startcmd starting inch cmd addr %04x u4 %08x\n", addr, uptr->u4); - /* u4 has IOCD word 1 contents. For the disk processor it contains */ + "scfi_startcmd starting inch cmd addr %04x CMD %08x\n", addr, uptr->CMD); + /* CMD has IOCD word 1 contents. For the disk processor it contains */ /* a pointer to the INCH buffer followed by 8 drive attribute words that */ /* contains the flags, sector count, MHD head count, and FHD count */ /* us9 has the byte count from IOCD wd2 and should be 0x24 (36) */ - /* the INCH buffer address must be returned in u4 and us9 left non-zero */ + /* the INCH buffer address must be returned in CMD and us9 left non-zero */ /* just return OK and channel software will use up8 as status buffer */ - mema = (uint32)uptr->u4; /* get memory address of buffer */ - uptr->u4 = M[mema>>2]; /* get status buffer address for XIO return status */ + mema = (uint32)uptr->CMD; /* get memory address of buffer */ + uptr->CMD = M[mema>>2]; /* get status buffer address for XIO return status */ sim_debug(DEBUG_CMD, dptr, - "scfi_startcmd starting inch cmd addr %04x u4 %08x mema %08x units %02x\n", - addr, uptr->u4, mema, dptr->numunits); + "scfi_startcmd starting inch cmd addr %04x CMD %08x mema %08x units %02x\n", + addr, uptr->CMD, mema, dptr->numunits); /* the next 8 words have drive data for each unit */ /* WARNING 8 drives must be defined for this controller */ /* so we will not have a map fault */ for (i=0; inumunits && i<8; i++) { /* process all drives */ - up->u6 = M[(mema>>2)+i+1]; /* save each unit's drive data */ + up->ATTR = M[(mema>>2)+i+1]; /* save each unit's drive data */ sim_debug(DEBUG_CMD, dptr, "scfi_startcmd ATTR data %08x unit %02x flags %02x sec %02x MHD %02x FHD %02x\n", up->ATTR, i, (up->ATTR >> 24)&0xff, (up->ATTR >> 16)&0xff, (up->ATTR >> 8)&0xff, (up->ATTR&0xff)); up++; /* next unit for this device */ } - sim_debug(DEBUG_CMD, dptr, "scfi_startcmd done inch cmd addr %04x\n", addr); + sim_debug(DEBUG_CMD, dptr, "scfi_startcmd done INCH cmd addr %04x\n", addr); // return SNS_CHNEND|SNS_DEVEND; // break; - uptr->u3 |= DSK_CMDMSK; /* use 0xff for inch, just need int */ + uptr->CMD |= DSK_INCH2; /* use 0xf0 for inch, just need int */ sim_activate(uptr, 20); /* start things off */ return (0); break; @@ -520,12 +521,12 @@ uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { case DSK_SCK: /* Seek command 0x07 */ case DSK_XEZ: /* Rezero & Read IPL record 0x1f */ - uptr->u3 &= ~(DSK_STAR); /* show we do not have seek STAR in u4 */ + uptr->CMD &= ~(DSK_STAR); /* show we do not have seek STAR in CMD */ case DSK_WD: /* Write command 0x01 */ case DSK_RD: /* Read command 0x02 */ case DSK_LMR: /* read mode register */ - uptr->u3 |= cmd; /* save cmd */ + uptr->CMD |= cmd; /* save cmd */ sim_debug(DEBUG_CMD, dptr, "scfi_startcmd done with disk seek r/w cmd %02x addr %04x\n", cmd, addr); sim_activate(uptr, 20); /* start things off */ @@ -534,21 +535,21 @@ uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { case DSK_NOP: /* NOP 0x03 */ // return SNS_CHNEND|SNS_DEVEND; /* return OK */ - uptr->u3 |= cmd; /* save cmd */ + uptr->CMD |= cmd; /* save cmd */ sim_activate(uptr, 20); /* start things off */ return 0; break; case DSK_SNS: /* Sense 0x04 */ - uptr->u3 |= cmd; /* save cmd */ + uptr->CMD |= cmd; /* save cmd */ sim_activate(uptr, 20); /* start things off */ return 0; break; } sim_debug(DEBUG_CMD, dptr, - "scfi_startcmd done with scfi_startcmd %02x addr %04x u5 %08x\n", - cmd, addr, uptr->u5); - if (uptr->u5 & 0xff) + "scfi_startcmd done with scfi_startcmd %02x addr %04x SNS %08x\n", + cmd, addr, uptr->SNS); + if (uptr->SNS & 0xff) return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; sim_activate(uptr, 20); /* start things off */ return SNS_CHNEND|SNS_DEVEND; @@ -557,12 +558,12 @@ uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { /* Handle processing of disk requests. */ t_stat scfi_srv(UNIT *uptr) { - uint16 chsa = GET_UADDR(uptr->u3); + uint16 chsa = GET_UADDR(uptr->CMD); DEVICE *dptr = find_dev_from_unit(uptr); DIB *dibp = (DIB *)dptr->ctxt; /* get pointer to Dev Info Blk for this device */ CHANP *chp = (CHANP *)dibp->chan_prg; /* get pointer to channel program */ struct ddata_t *data = (struct ddata_t *)(uptr->up7); - int cmd = uptr->u3 & DSK_CMDMSK; + int cmd = uptr->CMD & DSK_CMDMSK; int type = GET_TYPE(uptr->flags); int32 trk, cyl; int unit = (uptr - dptr->units); @@ -573,8 +574,8 @@ t_stat scfi_srv(UNIT *uptr) // int tsize = scfi_type[type].spt * scfi_type[type].ssiz*4; /* get track size in bytes */ uint16 ssize = scfi_type[type].ssiz*4; /* Size of one sector in bytes */ int32 tstart = 0; /* Location of start of cyl/track/sect in data */ - uint8 buf2[768]; - uint8 buf[768]; + uint8 buf2[1024]; + uint8 buf[1024]; sim_debug(DEBUG_DETAIL, &sda_dev, "scfi_srv entry unit %02x cmd %02x chsa %04x chan %04x count %04x\n", unit, cmd, chsa, chsa>>8, chp->ccw_count); @@ -583,7 +584,7 @@ t_stat scfi_srv(UNIT *uptr) // return SCPE_OK; // } if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ - uptr->u5 |= SNS_INTVENT; /* unit intervention required */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ if (cmd != DSK_SNS) /* we are completed with unit check status */ return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; } @@ -593,25 +594,25 @@ t_stat scfi_srv(UNIT *uptr) case 0: /* No command, stop disk */ break; - case DSK_CMDMSK: /* use 0xff for inch, just need int */ - uptr->u3 &= ~(0xffff); /* remove old cmd */ + case DSK_INCH2: /* use 0xff for inch, just need int */ + uptr->CMD &= ~(0xffff); /* remove old cmd */ sim_debug(DEBUG_CMD, dptr, "scfi_srv cmd INCH chsa %04x count %04x completed\n", chsa, chp->ccw_count); chan_end(chsa, SNS_CHNEND); /* return just channel end */ break; case DSK_NOP: /* NOP 0x03 */ - uptr->u3 &= ~(0xffff); /* remove old cmd */ + uptr->CMD &= ~(0xffff); /* remove old cmd */ sim_debug(DEBUG_CMD, dptr, "scfi_srv cmd NOP chsa %04x count %04x completed\n", chsa, chp->ccw_count); chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ break; case DSK_SNS: /* 0x4 */ - ch = uptr->u5 & 0xff; + ch = uptr->SNS & 0xff; sim_debug(DEBUG_DETAIL, dptr, "scfi_srv sense unit=%02x 1 %02x\n", unit, ch); chan_write_byte(chsa, &ch) ; - ch = (uptr->u5 >> 8) & 0xff; + ch = (uptr->SNS >> 8) & 0xff; sim_debug(DEBUG_DETAIL, dptr, "scfi_srv sense unit=%02x 2 %02x\n", unit, ch); chan_write_byte(chsa, &ch) ; ch = 0; @@ -622,31 +623,31 @@ t_stat scfi_srv(UNIT *uptr) chan_write_byte(chsa, &ch) ; ch = 4; sim_debug(DEBUG_CMD, dptr, "DISK SENSE %02x chars complete %08x, unit %02x\n", - ch, uptr->u5, unit); - uptr->u3 &= ~(0xff00); + ch, uptr->SNS, unit); + uptr->CMD &= ~(0xff00); chan_end(chsa, SNS_CHNEND|SNS_DEVEND); break; case DSK_SCK: /* Seek cylinder, track, sector 0x07 */ /* If we are waiting on seek to finish, check if there yet. */ - if (uptr->u3 & DSK_SEEKING) { + if (uptr->CMD & DSK_SEEKING) { /* see if on cylinder yet */ - if ((uptr->u4 >> 16) == data->cyl) { + if ((uptr->CMD >> 16) == data->cyl) { /* we are on cylinder, seek is done */ sim_debug(DEBUG_CMD, dptr, "scfi_srv seek on cylinder unit=%02x %04x %04x\n", - unit, uptr->u4 >> 16, data->cyl); - uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */ + unit, uptr->CMD >> 16, data->cyl); + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ set_devattn(chsa, SNS_DEVEND); /* start the operation */ sim_debug(DEBUG_DETAIL, dptr, "scfi_srv seek end unit=%02x %04x %04x\n", - unit, uptr->u4 >> 16, data->cyl); + unit, uptr->CMD >> 16, data->cyl); sim_activate(uptr, 20); break; } else { /* Compute delay based of difference. */ /* Set next state = index */ - i = (uptr->u4 >> 16) - data->cyl; - sim_debug(DEBUG_CMD, dptr, "scfi_srv seek unit=%02x %04x %04x\n", unit, uptr->u4 >> 16, i); + i = (uptr->CMD >> 16) - data->cyl; + sim_debug(DEBUG_CMD, dptr, "scfi_srv seek unit=%02x %04x %04x\n", unit, uptr->CMD >> 16, i); if (i > 0 ) { if (i > 50) { data->cyl += 50; /* seek 50 cyl */ @@ -677,7 +678,7 @@ t_stat scfi_srv(UNIT *uptr) data->cyl = 0; /* make zero */ } sim_debug(DEBUG_DETAIL, dptr, "scfi_srv seek next unit=%02x %04x %04x\n", - unit, uptr->u4 >> 16, data->cyl); + unit, uptr->CMD >> 16, data->cyl); sim_activate(uptr, 2); break; } @@ -688,8 +689,8 @@ t_stat scfi_srv(UNIT *uptr) for (i = 0; i < 4; i++) { if (chan_read_byte(chsa, &buf[i])) { /* we have error, bail out */ - uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */ - uptr->u5 |= SNS_CMDREJ|SNS_EQUCHK; + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; } @@ -697,19 +698,20 @@ t_stat scfi_srv(UNIT *uptr) rezero: sim_debug(DEBUG_DETAIL, dptr, "scfi_srv seek unit=%02x star %02x %02x %02x %02x\n", unit, buf[0], buf[1], buf[2], buf[3]); - /* save STAR (target sector) data in u4 */ - uptr->u4 = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]); - cyl = uptr->u4 >> 16; /* get the cylinder */ + /* save STAR (target sector) data in CMD */ + uptr->CMD = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]); + cyl = uptr->CMD >> 16; /* get the cylinder */ trk = buf[2]; /* get the track */ sim_debug(DEBUG_DETAIL, dptr, "scfi_srv SEEK %08x cyl %04x trk %02x sec %02x unit=%02x\n", - uptr->u4, cyl&0xffff, trk, buf[3], unit); + uptr->CMD, cyl&0xffff, trk, buf[3], unit); sim_debug(DEBUG_DETAIL, dptr, "scfi_srv Disk %s cyl %04x hds %02x sec/trk %02x unit=%02x\n", scfi_type[type].name, scfi_type[type].cyl, scfi_type[type].nhds, scfi_type[type].spt, unit); - uptr->u3 |= DSK_STAR; /* show we have seek STAR in u4 */ + uptr->CMD |= DSK_STAR; /* show we have seek STAR in CMD */ /* calc the sector address of data */ /* calculate file position in bytes of requested sector */ - tstart = uptr->u4 * (scfi_type[type].spb * scfi_type[type].ssiz * 4); /* file offset in bytes */ + /* file offset in bytes */ + tstart = uptr->CMD * (scfi_type[type].spb * scfi_type[type].ssiz * 4); data->tpos = trk; /* save the track/head number */ data->spos = buf[3]; /* save the sector number */ sim_debug(DEBUG_DETAIL, dptr, "scfi_srv seek start %08x trk %04x sec %02x\n", tstart, trk, buf[3]); @@ -717,18 +719,18 @@ rezero: sim_debug(DEBUG_DETAIL, dptr, "scfi_srv Error on seek to %08x\n", tstart); } - /* Check if already on correct cylinder */ - if (trk != data->cyl) { - /* Do seek */ - uptr->u3 |= DSK_SEEKING; /* show we are seeking */ - sim_debug(DEBUG_DETAIL, dptr, "scfi_srv seek unit=%02x trk %04x cyl %04x\n", - unit, trk, data->cyl); + /* Check if already on correct cylinder */ + if (cyl != data->cyl) { + /* No, Do seek */ + uptr->CMD |= DSK_SEEKING; /* show we are seeking */ + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv seek unit=%02x cyl %04x trk %04x sec %04x\n", + unit, cyl, trk, buf[3]); sim_activate(uptr, 20); chan_end(chsa, SNS_CHNEND); } else { - sim_debug(DEBUG_DETAIL, dptr, "scfi_srv calc sect addr seek start %08x trk %04x sec %02x\n", - tstart, trk, buf[3]); - uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */ + sim_debug(DEBUG_DETAIL, dptr, "scfi_srv calc sect addr seek start %08x cyl %04x trk %04x sec %02x\n", + tstart, cyl, trk, buf[3]); + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ sim_activate(uptr, 20); chan_end(chsa, SNS_DEVEND|SNS_CHNEND); } @@ -738,16 +740,16 @@ rezero: sim_debug(DEBUG_CMD, dptr, "RD REZERO IPL unit=%02x seek 0\n", unit); /* Do a seek to 0 */ - uptr->u4 = 0; /* set STAR to 0, 0, 0 */ - uptr->u3 &= ~(0xffff); /* remove old cmd */ - uptr->u3 |= DSK_SCK; /* show as seek command */ + uptr->CMD = 0; /* set STAR to 0, 0, 0 */ + uptr->CMD &= ~(0xffff); /* remove old cmd */ + uptr->CMD |= DSK_SCK; /* show as seek command */ tstart = 0; /* byte offset is 0 */ dlen = 0; /* no data written yet */ /* Read in 1 dummy character for length to inhibit SLI posting */ if (chan_read_byte(chsa, &buf[0])) { /* we have error, bail out */ - uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */ - uptr->u5 |= SNS_CMDREJ|SNS_EQUCHK; + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; } @@ -761,33 +763,33 @@ rezero: /* Read in 1 character of mode data */ if (chan_read_byte(chsa, &buf[0])) { /* we have error, bail out */ - uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */ - uptr->u5 |= SNS_CMDREJ|SNS_EQUCHK; + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; } - uptr->u3 &= ~(0xffff); /* remove old cmd */ - uptr->u5 &= 0x00ffffff; /* clear old mode data */ - uptr->u5 |= (buf[0] << 24); /* save mode value */ + uptr->CMD &= ~(0xffff); /* remove old cmd */ + uptr->SNS &= 0x00ffffff; /* clear old mode data */ + uptr->SNS |= (buf[0] << 24); /* save mode value */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); break; case DSK_RD: /* Read Data */ /* tstart has start of sector address in bytes */ - if ((uptr->u3 & DSK_READING) == 0) { /* see if we are reading data */ - uptr->u3 |= DSK_READING; /* read from disk starting */ + if ((uptr->CMD & DSK_READING) == 0) { /* see if we are reading data */ + uptr->CMD |= DSK_READING; /* read from disk starting */ dlen = 0; /* no data read yet */ - sim_debug(DEBUG_CMD, dptr, "DISK READ starting unit=%02x u3 %08x count %04x\n", - unit, uptr->u3, chp->ccw_count); + sim_debug(DEBUG_CMD, dptr, "DISK READ starting unit=%02x CMD %08x count %04x\n", + unit, uptr->CMD, chp->ccw_count); } - if (uptr->u3 & DSK_READING) { /* see if we are reading data */ + if (uptr->CMD & DSK_READING) { /* see if we are reading data */ /* read in a sector of data from disk */ if ((len=sim_fread(buf, 1, ssize, uptr->fileref)) != ssize) { sim_debug(DEBUG_CMD, dptr, "Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n", len, ssize, data->cyl, data->tpos, data->spos); - uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; } @@ -800,7 +802,7 @@ rezero: sim_debug(DEBUG_DATAIO, dptr, "DISK Read %04x bytes from diskfile cyl %04x hds %02x sec %02x tstart %08x\n", dlen+i, data->cyl, data->tpos, data->spos, tstart); - uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); goto rddone; } @@ -816,7 +818,7 @@ rezero: sim_debug(DEBUG_DATAIO, dptr, "DISK Read complete Read %04x bytes from diskfile cyl %04x hds %02x sec %02x tstart %08x\n", dlen, data->cyl, data->tpos, data->spos, tstart); - uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); } rddone: @@ -827,20 +829,20 @@ rddone: case DSK_WD: /* Write Data */ /* tstart has start of sector address in bytes */ - if ((uptr->u3 & DSK_WRITING) == 0) { /* see if we are writing data */ - uptr->u3 |= DSK_WRITING; /* write to disk starting */ + if ((uptr->CMD & DSK_WRITING) == 0) { /* see if we are writing data */ + uptr->CMD |= DSK_WRITING; /* write to disk starting */ dlen = 0; /* no data written yet */ - sim_debug(DEBUG_CMD, dptr, "DISK WRITE starting unit=%02x u3 %08x bytes %04x\n", - unit, uptr->u3, dlen); + sim_debug(DEBUG_CMD, dptr, "DISK WRITE starting unit=%02x CMD %08x bytes %04x\n", + unit, uptr->CMD, dlen); } - if (uptr->u3 & DSK_WRITING) { /* see if we are writing data */ + if (uptr->CMD & DSK_WRITING) { /* see if we are writing data */ /* process the next sector of data */ len = 0; /* used here as a flag for short read */ for (i=0; iu3 &= ~(0xffff); /* remove old status bits & cmd */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ sim_debug(DEBUG_DATAIO, dptr, "DISK Wrote %04x bytes to diskfile cyl %04x hds %02x sec %02x tstart %08x\n", ssize, data->cyl, data->tpos, data->spos, tstart); @@ -858,7 +860,7 @@ rddone: sim_debug(DEBUG_CMD, dptr, "Error %08x on write %04x to diskfile cyl %04x hds %02x sec %02x\n", i, ssize, data->cyl, data->tpos, data->spos); - uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; } @@ -866,7 +868,7 @@ rddone: sim_debug(DEBUG_DATAIO, dptr, "DISK WroteB %04x bytes to diskfile cyl %04x hds %02x sec %02x tstart %08x\n", ssize, data->cyl, data->tpos, data->spos, tstart); - uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */ break; } @@ -882,8 +884,8 @@ wrdone: default: sim_debug(DEBUG_DETAIL, dptr, "invalid command %02x unit %02x\n", cmd, unit); - uptr->u5 |= SNS_CMDREJ; - uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; } @@ -898,13 +900,13 @@ void scfi_ini(UNIT *uptr, t_bool f) DEVICE *dptr = find_dev_from_unit(uptr); int i = GET_TYPE(uptr->flags); - uptr->u3 &= ~0xffff; /* clear out the flags but leave ch/sa */ + uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */ /* capacity is total allocation units times sectors per allocation unit */ /* total sectors on disk */ uptr->capac = scfi_type[i].taus * scfi_type[i].spau; sim_debug(DEBUG_EXP, &sda_dev, "SDA init device %s on unit SDA%.1x cap %x\n", - dptr->name, GET_UADDR(uptr->u3), uptr->u3); + dptr->name, GET_UADDR(uptr->CMD), uptr->CMD); } t_stat scfi_reset(DEVICE * dptr) @@ -916,7 +918,7 @@ t_stat scfi_reset(DEVICE * dptr) /* create the disk file for the specified device */ int scfi_format(UNIT *uptr) { // struct ddata_t *data = (struct ddata_t *)uptr->up7; - uint16 addr = GET_UADDR(uptr->u3); + uint16 addr = GET_UADDR(uptr->CMD); int type = GET_TYPE(uptr->flags); DEVICE *dptr = find_dev_from_unit(uptr); uint16 tsize = scfi_type[type].spt * scfi_type[type].ssiz*4; /* get track size in bytes */ @@ -973,7 +975,7 @@ int scfi_format(UNIT *uptr) { /* attach the selected file to the disk */ t_stat scfi_attach(UNIT *uptr, CONST char *file) { - uint16 addr = GET_UADDR(uptr->u3); + uint16 addr = GET_UADDR(uptr->CMD); int type = GET_TYPE(uptr->flags); DEVICE *dptr = find_dev_from_unit(uptr); t_stat r; @@ -1006,7 +1008,8 @@ t_stat scfi_attach(UNIT *uptr, CONST char *file) { uptr->capac *= ssize; /* disk capacity in bytes */ sim_debug(DEBUG_CMD, dptr, "Disk taus %d spau %d ssiz %d cap %d\n", - scfi_type[type].taus, scfi_type[type].spau, scfi_type[type].ssiz * 4, uptr->capac); /* disk capacity */ + scfi_type[type].taus, scfi_type[type].spau, scfi_type[type].ssiz * 4, + uptr->capac); /* disk capacity */ if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ detach_unit(uptr); /* if no space, error */ @@ -1036,6 +1039,7 @@ fmt: return SCPE_FMT; /* error */ } + data->cyl = 0; /* current cylinder position */ data->tpos = 0; /* current track position */ data->spos = 0; /* current sector position */ @@ -1057,7 +1061,7 @@ t_stat scfi_detach(UNIT *uptr) { free(data); /* free disk data structure */ } uptr->up7 = 0; /* no pointer to disk data */ - uptr->u3 &= ~0xffff; /* no cmd and flags */ + uptr->CMD &= ~0xffff; /* no cmd and flags */ return detach_unit(uptr); /* tell simh we are done with disk */ } @@ -1065,12 +1069,12 @@ t_stat scfi_detach(UNIT *uptr) { t_stat scfi_boot(int32 unit_num, DEVICE *dptr) { UNIT *uptr = &dptr->units[unit_num]; /* find disk unit number */ - sim_debug(DEBUG_CMD, &sda_dev, "SCFI Disk Boot dev/unit %04x\n", GET_UADDR(uptr->u3)); - SPAD[0xf4] = GET_UADDR(uptr->u3); /* put boot device chan/sa into spad */ + sim_debug(DEBUG_CMD, &sda_dev, "SCFI Disk Boot dev/unit %04x\n", GET_UADDR(uptr->CMD)); + SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */ SPAD[0xf8] = 0xF000; /* show as F class device */ if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* attached? */ - return chan_boot(GET_UADDR(uptr->u3), dptr); /* boot the ch/sa */ + return chan_boot(GET_UADDR(uptr->CMD), dptr); /* boot the ch/sa */ } /* Disk option setting commands */