mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-13 15:27:04 +00:00
SEL32: Updates for SEL Diags and UTX support.
This commit is contained in:
parent
506e103afd
commit
f4dc60bd69
@ -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));
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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 */
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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; i<dptr->numunits && 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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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; i<dptr->numunits && 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; i<ssize; i++) {
|
||||
if (chan_read_byte(chsa, &ch)) { /* get a byte from memory */
|
||||
/* if error on reading 1st byte, we are done writing */
|
||||
if (i == 0) {
|
||||
uptr->u3 &= ~(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 */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user