mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-13 15:27:04 +00:00
SEL32: Redo SIO, TIO, HIO support code.
SEL32: Change Ethernet simh timing. SEL32: Do more code cleanup. SEL32: Add preio entries for IOP & MFP devices.
This commit is contained in:
parent
2fc381dfe1
commit
fdf8fffb4c
@ -1,4 +1,3 @@
|
||||
/* sel32_chan.c: SEL 32 Channel functions.
|
||||
|
||||
Copyright (c) 2018-2021, James C. Bevier
|
||||
Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers
|
||||
@ -86,9 +85,6 @@ extern uint32 CPUSTATUS; /* CPU status word */
|
||||
extern uint32 INTS[]; /* Interrupt status flags */
|
||||
extern uint32 TPSD[]; /* Temp save of PSD from memory 0&4 */
|
||||
extern uint8 waitqcnt; /* # of instructions to xeq b4 int */
|
||||
#ifdef REMOVE_03072021
|
||||
extern uint8 waitrdyq; /* # of instructions to xeq b4 rdy */
|
||||
#endif
|
||||
extern uint32 inbusy;
|
||||
extern uint32 outbusy;
|
||||
|
||||
@ -123,6 +119,7 @@ t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat show_dev_addr(FILE *st, UNIT *uptr, int32 v, CONST void *desc);
|
||||
DEVICE *get_dev(UNIT *uptr);
|
||||
void store_csw(CHANP *chp);
|
||||
void push_csw(CHANP *chp);
|
||||
int16 post_csw(CHANP *chp, uint32 rstat);
|
||||
|
||||
/* FIFO support */
|
||||
@ -140,6 +137,32 @@ int16 post_csw(CHANP *chp, uint32 rstat);
|
||||
|
||||
/* initialize FIFO to empty in boot channel code */
|
||||
|
||||
/* add an entry to the start of the FIFO */
|
||||
int32 FIFO_Push(uint16 chsa, uint32 entry)
|
||||
{
|
||||
int32 num; /* number of entries */
|
||||
DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */
|
||||
if (dibp == NULL) {
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"FIFO_Push ERR NULL dib ptr for chsa %04x\n", chsa);
|
||||
return -1; /* FIFO address error */
|
||||
}
|
||||
|
||||
if (dibp->chan_fifo_in == ((dibp->chan_fifo_out-1+FIFO_SIZE) % FIFO_SIZE)) {
|
||||
num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE;
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"FIFO_Push ERR FIFO full for chsa %04x count %02x\n", chsa, num);
|
||||
return -1; /* FIFO Full */
|
||||
}
|
||||
dibp->chan_fifo_out += (FIFO_SIZE - 1); /* get index to previous first entry */
|
||||
dibp->chan_fifo_out %= FIFO_SIZE; /* modulo FIFO size */
|
||||
dibp->chan_fifo[dibp->chan_fifo_out] = entry; /* add new entry to be new first */
|
||||
num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE;
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"FIFO_Push to FIFO for chsa %04x count %02x\n", chsa, num);
|
||||
return SCPE_OK; /* all OK */
|
||||
}
|
||||
|
||||
/* add an entry to the FIFO */
|
||||
int32 FIFO_Put(uint16 chsa, uint32 entry)
|
||||
{
|
||||
@ -213,11 +236,6 @@ int32 RDYQ_Put(uint32 entry)
|
||||
RDYQIN += 1; /* next entry */
|
||||
RDYQIN %= RDYQ_SIZE; /* modulo RDYQ size */
|
||||
irq_pend = 1; /* do a scan */
|
||||
#ifdef REMOVE_03072021
|
||||
//XXwaitrdyq = 10; /* UTX21A installs with this, but diags hang */
|
||||
//XXwaitrdyq = 2;
|
||||
waitrdyq = 1; /* wait at least 1 instruction */
|
||||
#endif
|
||||
return SCPE_OK; /* all OK */
|
||||
}
|
||||
|
||||
@ -368,7 +386,6 @@ uint32 find_int_lev(uint16 chsa)
|
||||
uint32 find_int_icb(uint16 chsa)
|
||||
{
|
||||
uint32 inta, icba;
|
||||
uint32 spadent = SPAD[get_chan(chsa)]; /* get spad device entry for logical channel */
|
||||
|
||||
inta = find_int_lev(chsa); /* find the int level */
|
||||
if (inta == 0) {
|
||||
@ -471,7 +488,8 @@ int readfull(CHANP *chp, uint32 maddr, uint32 *word)
|
||||
return 1; /* show we have error */
|
||||
}
|
||||
*word = RMW(maddr); /* get 1 word */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev, "READFULL read %08x from addr %08x\n", *word, maddr);
|
||||
sim_debug(DEBUG_XIO, &cpu_dev, "READFULL chsa %04x read %08x from addr %08x\n",
|
||||
chp->chan_dev, *word, maddr);
|
||||
return 0; /* return OK */
|
||||
}
|
||||
|
||||
@ -733,9 +751,7 @@ loop:
|
||||
"load_ccw bad status chan %04x status %04x cmd %02x\n",
|
||||
chan, chp->chan_status, chp->ccw_cmd);
|
||||
RDYQ_Put(chp->chan_dev); /* queue us up */
|
||||
#ifndef CHANGE_03072021
|
||||
chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */
|
||||
#endif
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"load_ccw continue wait chsa %04x status %08x\n",
|
||||
chp->chan_dev, chp->chan_status);
|
||||
@ -766,7 +782,6 @@ loop:
|
||||
/* write to device */
|
||||
int chan_read_byte(uint16 chsa, uint8 *data)
|
||||
{
|
||||
int chan = get_chan(chsa); /* get the channel number */
|
||||
CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */
|
||||
int byte;
|
||||
|
||||
@ -888,7 +903,7 @@ int chan_write_byte(uint16 chsa, uint8 *data)
|
||||
chp->ccw_addr--; /* backward */
|
||||
else
|
||||
chp->ccw_addr++; /* forward */
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_write_byte SKIP ret addr %08x cnt %04x\n",
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte SKIP ret addr %08x cnt %04x\n",
|
||||
chp->ccw_addr, chp->ccw_count);
|
||||
return 0;
|
||||
}
|
||||
@ -1022,13 +1037,12 @@ void chan_end(uint16 chsa, uint16 flags) {
|
||||
"chan_end set RDYQ %04x No CC BUFF_NEXT chp %p chan_byte %04x\n",
|
||||
chsa, chp, chp->chan_byte);
|
||||
RDYQ_Put(chsa); /* queue us up */
|
||||
#ifndef CHANGE_03072021
|
||||
chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */
|
||||
#endif
|
||||
}
|
||||
/* just return */
|
||||
goto goout;
|
||||
} else {
|
||||
/* we have channel end and no CC flag, continue channel prog */
|
||||
UNIT *uptr = chp->unitptr; /* get the unit ptr */
|
||||
DEVICE *dptr = get_dev(uptr);
|
||||
uint16 chsa = GET_UADDR(uptr->u3);
|
||||
@ -1081,7 +1095,7 @@ void chan_end(uint16 chsa, uint16 flags) {
|
||||
chp->ccw_flags = 0; /* clear flags */
|
||||
|
||||
/* set status words in memory to first IOCD information */
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"$$ CHEND start IOCL processing from IOCLQ num %02x chsa %04x iocla %06x\n",
|
||||
IOCLQ_Num(qp), chsa, iocla);
|
||||
|
||||
@ -1089,27 +1103,21 @@ void chan_end(uint16 chsa, uint16 flags) {
|
||||
/* Queue us to continue IOCL from cpu level & make busy */
|
||||
chp->chan_byte = BUFF_NEXT; /* have main pick us up */
|
||||
chp->chan_info = INFO_SIOCD; /* show first IOCD in channel prog */
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"chan_end BUFF_NEXT chsa %04x from IOCLQ cnt %02x chp %p chan_byte %04x\n",
|
||||
chsa, IOCLQ_Num(qp), chp, chp->chan_byte);
|
||||
RDYQ_Put(chsa); /* queue us up */
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
"$$$ CHEND SIO queued chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n",
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"$$$ CHEND SIOQ queued chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n",
|
||||
chsa, iocla, RMW(iocla), RMW(iocla+4));
|
||||
|
||||
#ifdef CHANGE_03072021
|
||||
if (waitqcnt == 0) /* test for UTX delay */
|
||||
waitqcnt = 25; /* tell cpu to wait 20 instructions before int */
|
||||
//XX waitqcnt = 15; /* tell cpu to wait 20 instructions before int */
|
||||
#else
|
||||
/* this is the first IOCD for the SIO */
|
||||
chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
goout:
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"chan_end done chsa %04x chp %p status %08x chan_byte %02x\n",
|
||||
chsa, chp, chp->chan_status, chp->chan_byte);
|
||||
/* following statement required for boot to work */
|
||||
@ -1178,7 +1186,7 @@ void store_csw(CHANP *chp)
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"store_csw FIFO Overflow ERROR on chsa %04x\n", chsa);
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"store_csw FIFO #%1x write chsa %04x sw1 %08x sw2 %08x incha %08x cmd %02x\n",
|
||||
FIFO_Num(chsa), chsa, stwd1, stwd2, chp->chan_inch_addr, chp->ccw_cmd);
|
||||
/* added 011321 */
|
||||
@ -1186,6 +1194,31 @@ void store_csw(CHANP *chp)
|
||||
irq_pend = 1; /* wakeup controller */
|
||||
}
|
||||
|
||||
/* store the device status into the first entry of the status FIFO for the channel */
|
||||
void push_csw(CHANP *chp)
|
||||
{
|
||||
uint32 stwd1, stwd2; /* words 1&2 of stored status */
|
||||
uint32 chsa = chp->chan_dev; /* get ch/sa information */
|
||||
|
||||
/* put sub address in byte 0 */
|
||||
stwd1 = ((chsa & 0xff) << 24) | chp->chan_caw; /* subaddress and IOCD address to SW 1 */
|
||||
|
||||
/* save 16 bit channel status and residual byte count in SW 2 */
|
||||
stwd2 = ((uint32)chp->chan_status << 16) | ((uint32)chp->ccw_count);
|
||||
|
||||
/* Push in reverse order to allign status correctly */
|
||||
if ((FIFO_Push(chsa, stwd2) == -1) || (FIFO_Push(chsa, stwd1) == -1)) {
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"push_csw FIFO Overflow ERROR on chsa %04x\n", chsa);
|
||||
}
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"push_csw FIFO #%1x write chsa %04x sw1 %08x sw2 %08x incha %08x cmd %02x\n",
|
||||
FIFO_Num(chsa), chsa, stwd1, stwd2, chp->chan_inch_addr, chp->ccw_cmd);
|
||||
/* added 011321 */
|
||||
INTS[chp->chan_int] |= INTS_REQ; /* request an interrupt for channel */
|
||||
irq_pend = 1; /* wakeup controller */
|
||||
}
|
||||
|
||||
/* check an XIO operation */
|
||||
/* logical chan channel number 0-7f */
|
||||
/* suba unit address within channel 0-ff */
|
||||
@ -1233,12 +1266,12 @@ nothere:
|
||||
*status = CC1BIT; /* CCs = 1, not busy */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"checkxio rchsa %04x device/unit not enabled, CC1 returned\n",
|
||||
lchsa, rchsa);
|
||||
rchsa);
|
||||
} else {
|
||||
*status = CC3BIT; /* not attached, so error CC3 */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"checkxio rchsa %04x device/unit not enabled, CC3 returned\n",
|
||||
lchsa, rchsa);
|
||||
rchsa);
|
||||
}
|
||||
return SCPE_OK; /* Not found CC3/CC1 */
|
||||
}
|
||||
@ -1292,6 +1325,7 @@ t_stat startxio(uint16 lchsa, uint32 *status) {
|
||||
uint16 chsa;
|
||||
uint32 tempa, inta, spadent, chan, incha;
|
||||
uint32 word1, word2, cmd;
|
||||
#define DEBUG_DISK
|
||||
#ifdef DEBUG_DISK
|
||||
uint32 itva;
|
||||
#endif
|
||||
@ -1326,12 +1360,12 @@ t_stat startxio(uint16 lchsa, uint32 *status) {
|
||||
itva, chan_icb, iocla, incha, RMW(iocla), RMW(iocla+4));
|
||||
#endif
|
||||
/* check if we have a valid unit */
|
||||
dibp = dib_chan[chan]; /* get DIB pointer for channel */
|
||||
if (dibp == 0) goto missing;
|
||||
|
||||
chp = find_chanp_ptr(chsa); /* find the chanp pointer */
|
||||
if (chp == 0) goto missing;
|
||||
|
||||
dibp = dib_unit[chsa]; /* get the DIB pointer */
|
||||
if (dibp == 0) goto missing;
|
||||
|
||||
uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */
|
||||
|
||||
if (uptr == 0) { /* if no dib or unit ptr, CC3 on return */
|
||||
@ -1359,7 +1393,7 @@ missing:
|
||||
return SCPE_OK; /* not found, CC3 */
|
||||
}
|
||||
|
||||
#ifdef FOR_DEBUG
|
||||
#ifndef FOR_DEBUG
|
||||
if ((INTS[inta]&INTS_ACT) || (SPAD[inta+0x80]&SINT_ACT)) { /* look for level active */
|
||||
/* just output a warning */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
@ -1368,6 +1402,41 @@ missing:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_TIO_CODE_03112021
|
||||
/* channel not busy and ready to go, check for any status ready */
|
||||
/* see if any status ready to post */
|
||||
if (FIFO_Num(chsa&0x7f00)) {
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"SIOT chsa %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n",
|
||||
chsa, FIFO_Num(chsa), inta, chp->chan_inch_addr, chp, chan_icb, chp->chan_byte);
|
||||
if (post_csw(chp, 0)) {
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"SIOT chsa %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n",
|
||||
chsa, FIFO_Num(chsa), inta, chp->chan_inch_addr, RMW(chan_icb+20), chp->chan_byte);
|
||||
/* change status from BUFF_POST to BUFF_DONE */
|
||||
/* if not BUFF_POST we have a PPCI or channel busy interrupt */
|
||||
/* so leave the channel status alone */
|
||||
if (chp->chan_byte == BUFF_POST) {
|
||||
chp->chan_byte = BUFF_DONE; /* show done & not busy */
|
||||
}
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"SIOT END status stored incha %06x chan_icba+20 %08x chsa %04x sw1 %08x sw2 %08x\n",
|
||||
incha, RMW(chan_icb+20), chsa, RMW(incha), RMW(incha+4));
|
||||
INTS[inta] &= ~INTS_REQ; /* clear any level request if no status */
|
||||
*status = CC2BIT; /* status stored from SIO, so CC2 */
|
||||
return SCPE_OK; /* No CC's all OK */
|
||||
} else {
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"SIOT chsa %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n",
|
||||
chsa, FIFO_Num(chsa), inta, chp->chan_inch_addr, chan_icb, chp->chan_byte);
|
||||
/* now store the status dw address into word 5 of the ICB for the channel */
|
||||
WMW(chan_icb+20, 0); /* post sw addr 0 in ICB+5w & reset CCs */
|
||||
*status = 0; /* no status stored from SIO, so no CC */
|
||||
return SCPE_OK; /* No CC's all OK */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef TRY_03132021
|
||||
/* check for a Command or data chain operation in progresss */
|
||||
if ((chp->chan_byte & BUFF_BUSY) && (chp->chan_byte != BUFF_POST)) {
|
||||
uint16 tstat = chp->chan_status; /* save status */
|
||||
@ -1377,6 +1446,7 @@ missing:
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"startxio busy return CC3&CC4 chsa %04x chp %p cmd %02x flags %04x byte %02x\n",
|
||||
chsa, chp, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte);
|
||||
#ifndef DISABLE_03112021_03132021
|
||||
/* ethernet controller wants an interrupt for busy status */
|
||||
if ((dptr != NULL) &&
|
||||
(DEV_TYPE(dptr) == DEV_ETHER)) { /* see if this is ethernet */
|
||||
@ -1384,7 +1454,8 @@ missing:
|
||||
/* handle an Ethernet controller busy by sending interrupt/status */
|
||||
chp->chan_status = STATUS_BUSY|STATUS_CEND|STATUS_DEND; /* set busy status */
|
||||
chp->ccw_count = 0; /* zero count */
|
||||
store_csw(chp); /* store the status */
|
||||
//0312 store_csw(chp); /* store the status */
|
||||
push_csw(chp); /* store the status */
|
||||
chp->chan_status = tstat; /* restore status */
|
||||
chp->ccw_count = tcnt; /* restore count */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
@ -1392,7 +1463,20 @@ missing:
|
||||
chp, chsa, chp->ccw_flags, tstat, tcnt);
|
||||
return SCPE_OK; /* just busy CC3&CC4 */
|
||||
}
|
||||
#endif
|
||||
#ifndef ADD_03112021
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"startxio busy2 return CC3&CC4 chsa %04x chp %p cmd %02x flags %04x byte %02x\n",
|
||||
chsa, chp, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte);
|
||||
/* everyone else just gets a busy return */
|
||||
*status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"startxio done2 BUSY chp %p chsa %04x ccw_flags %04x stat %04x cnt %04x\n",
|
||||
chp, chsa, chp->ccw_flags, tstat, tcnt);
|
||||
return SCPE_OK; /* just busy CC3&CC4 */
|
||||
#endif
|
||||
}
|
||||
#endif /*TRY_03132021*/
|
||||
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"startxio int spad %08x icb %06x inta %02x chan %04x\n",
|
||||
@ -1504,18 +1588,10 @@ missing:
|
||||
"$$$ SIO queued chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n",
|
||||
chsa, iocla, RMW(iocla), RMW(iocla+4));
|
||||
|
||||
#ifdef CHANGE_03072021
|
||||
/* a value < 25 gets error ioi: sio at 801 failed, cc2 in UTX 21B */
|
||||
if (waitqcnt == 0) /* test for UTX delay */
|
||||
// waitqcnt = 20; /* tell cpu to wait 20 instructions before int */
|
||||
// waitqcnt = 35; /* tell cpu to wait 20 instructions before int */
|
||||
//XX waitqcnt = 15; /* tell cpu to wait 20 instructions before int */
|
||||
waitqcnt = 25; /* tell cpu to wait 20 instructions before int */
|
||||
#else
|
||||
// chp->chan_qwait = QWAIT10; /* run 25 instructions before starting iocl */
|
||||
chp->chan_qwait = QWAIT25; /* run 25 instructions before starting iocl */
|
||||
// chp->chan_qwait = QWAIT20; /* run 25 instructions before starting iocl */
|
||||
// chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */
|
||||
#endif
|
||||
|
||||
*status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev, "$$$ SIO done chsa %04x status %08x iocla %08x CC's %08x\n",
|
||||
@ -1545,12 +1621,6 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */
|
||||
dibp = dib_chan[rchan]; /* get the DIB pointer */
|
||||
chp = find_chanp_ptr(rchan << 8); /* find the device chanp pointer */
|
||||
|
||||
#ifdef CHANGE_03072021
|
||||
if (waitqcnt != 0) { /* test for UTX delay */
|
||||
waitqcnt = 0; /* tell cpu ok to int */
|
||||
irq_pend = 1; /* flag to test for int condition */
|
||||
}
|
||||
#endif
|
||||
if (dibp == 0 || chp == 0) { /* if no dib or channel ptr, CC3 return */
|
||||
*status = CC3BIT; /* not found, so CC3 */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
@ -1575,8 +1645,8 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */
|
||||
itva = SPAD[0xf1] + (inta<<2); /* int vector address */
|
||||
chan_icb = RMW(itva); /* Interrupt context block addr */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"TIO int spad %08x icb %06x inta %04x rchan %04x\n",
|
||||
SPAD[inta+0x80], chan_icb, inta, rchan);
|
||||
"TIO int spad %08x icb %06x inta %04x rchsa %04x\n",
|
||||
SPAD[inta+0x80], chan_icb, inta, rchsa);
|
||||
|
||||
incha = chp->chan_inch_addr; /* get inch address */
|
||||
|
||||
@ -1596,8 +1666,8 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */
|
||||
chp->chan_byte = BUFF_DONE; /* show done & not busy */
|
||||
}
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"TIO END status stored incha %06x rchsa %04x sw1 %08x sw2 %08x\n",
|
||||
incha, rchsa, RMW(incha), RMW(incha+4));
|
||||
"TIO END status stored incha %06x chan_icba+20 %08x rchsa %04x sw1 %08x sw2 %08x\n",
|
||||
incha, RMW(chan_icb+20), rchsa, RMW(incha), RMW(incha+4));
|
||||
INTS[inta] &= ~INTS_REQ; /* clear any level request if no status */
|
||||
*status = CC2BIT; /* status stored from SIO, so CC2 */
|
||||
return SCPE_OK; /* No CC's all OK */
|
||||
@ -1885,8 +1955,8 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
|
||||
/* call the device controller to get halt_io status */
|
||||
tempa = dibp->halt_io(uptr); /* get status from device */
|
||||
|
||||
/* test for SCPE_IOERR */
|
||||
if (tempa != 0) { /* sub channel has status ready */
|
||||
/* test for SCPE_IOERR (=2) SCPE_OK (=0)*/
|
||||
if (tempa != SCPE_OK) { /* sub channel has status ready */
|
||||
/* The device I/O has been terminated and status stored. */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"HIO halt_io call return ERROR FIFO #%1x rchsa %04x retstat %08x cstat %08x\n",
|
||||
@ -1894,36 +1964,12 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
|
||||
|
||||
/* chan_end is called in hio device service routine */
|
||||
/* the device is no longer busy, post status */
|
||||
/* remove PPCI status. Unit check should not be set */
|
||||
if (tempa == 1) { /* see if console HIO */
|
||||
chp->ccw_count = 0; /* zero the count */
|
||||
/* post status for UTX */
|
||||
if (post_csw(chp, ((STATUS_PCI) << 16))) {
|
||||
INTS[inta] &= ~INTS_REQ; /* clear any level request */
|
||||
*status = CC2BIT; /* status stored */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"$$$ HIO END2 rchsa %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
rchsa, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
/* change status from BUFF_POST to BUFF_DONE */
|
||||
if (chp->chan_byte == BUFF_POST) {
|
||||
chp->chan_byte = BUFF_DONE; /* show done & not busy */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"HIO BUFF_DONE1a chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
}
|
||||
return SCPE_OK; /* CC2 & all OK */
|
||||
}
|
||||
}
|
||||
#ifndef OLD_WAY_MAY_GOOD
|
||||
else {
|
||||
chp->ccw_count = 0; /* zero the count */
|
||||
/* The diags want the interrupt for the disk */
|
||||
*status = CC1BIT; /* request accepted, no status, so CC1 */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"$$$ HIO END2 ECHO rchsa %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
rchsa, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
return SCPE_OK; /* CC1 & all OK */
|
||||
}
|
||||
#endif
|
||||
/* The diags want the interrupt for the disk */
|
||||
*status = CC1BIT; /* request accepted, no status, so CC1 */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"$$$ HIO END2X ECHO rchsa %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
rchsa, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
return SCPE_OK; /* CC1 & all OK */
|
||||
}
|
||||
/* see if waiting to start */
|
||||
if (chp->chan_byte == BUFF_NEXT) {
|
||||
@ -1946,44 +1992,11 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
|
||||
"HIO BUFF_EMPTY chsa %04x cmd %02x ccw_flags %04x chan_byte %02x\n",
|
||||
rchsa, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte);
|
||||
}
|
||||
#ifdef OLD_WAY
|
||||
/* see if waiting to start */
|
||||
if (chp->chan_byte == BUFF_NEXT) {
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"HIO BUFF_DONE2a chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
chp->chan_byte = BUFF_DONE; /* allow to be dropped from RDYQ */
|
||||
*status = CC1BIT; /* request accepted, no status, so CC1 */
|
||||
return SCPE_OK; /* all OK */
|
||||
}
|
||||
/* see if done */
|
||||
if (chp->chan_byte == BUFF_POST) {
|
||||
/* post status for UTX */
|
||||
if (post_csw(chp, ((STATUS_PCI) << 16))) {
|
||||
INTS[inta] &= ~INTS_REQ; /* clear any level request */
|
||||
*status = CC2BIT; /* status stored */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"$$$ HIO END2b rchsa %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
rchsa, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
/* change status from BUFF_POST to BUFF_DONE */
|
||||
if (chp->chan_byte == BUFF_POST) {
|
||||
chp->chan_byte = BUFF_DONE; /* show done & not busy */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"HIO BUFF_DONE1b chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
}
|
||||
return SCPE_OK; /* CC2 & all OK */
|
||||
}
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"HIO BUFF_DONE2c chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
/* allow status to be posted */
|
||||
*status = CC1BIT; /* request accepted, no status, so CC1 */
|
||||
return SCPE_OK; /* all OK */
|
||||
}
|
||||
#endif
|
||||
/* the device is not busy, so cmd is completed */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"HIO BUFF_DONE2d chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
/* the channel is not busy, so return OK */
|
||||
*status = CC1BIT; /* request accepted, no status, so CC1 */
|
||||
*status = CC1BIT; /* request accepted, post good status, so CC1 */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"$$$ HIO END3 rchsa %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
rchsa, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
@ -1992,7 +2005,8 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"haltxio BUFF_DONE2 chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
chp->chan_status = (STATUS_DEND|STATUS_CEND);
|
||||
store_csw(chp); /* store the status */
|
||||
// store_csw(chp); /* store the status */
|
||||
push_csw(chp); /* store the status 1st in FIFO */
|
||||
/* change chan_byte to BUFF_POST */
|
||||
chp->chan_byte = BUFF_POST; /* show done with data */
|
||||
chp->chan_status = 0; /* no status anymore */
|
||||
@ -2034,7 +2048,8 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
|
||||
chp->chan_byte = BUFF_BUSY; /* wait for post_csw to be done */
|
||||
sim_cancel(uptr); /* cancel timer service */
|
||||
chp->chan_status &= ~STATUS_BUSY; /* remove BUSY status bit */
|
||||
chan_end(rchsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */
|
||||
// chan_end(rchsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */
|
||||
chan_end(rchsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* show I/O complete */
|
||||
|
||||
/* post the channel status */
|
||||
chp->ccw_count = 0; /* zero the count */
|
||||
@ -2381,7 +2396,6 @@ uint32 scan_chan(uint32 *ilev) {
|
||||
chp = find_chanp_ptr(chan); /* find the chanp pointer for channel */
|
||||
/* this address most likely will be zero here */
|
||||
tempa = chp->chan_inch_addr; /* get inch status buffer address */
|
||||
#if 1
|
||||
/* before overwriting memory loc 0+4, save PSD for caller in TPSD[] locations */
|
||||
TPSD[0] = M[0]; /* save PSD from loc 0&4 */
|
||||
TPSD[1] = M[1];
|
||||
@ -2390,7 +2404,6 @@ uint32 scan_chan(uint32 *ilev) {
|
||||
/* set BIT 1 to show status stored */
|
||||
WMW(tempa, sw1|BIT1); /* save sa & IOCD address in status WD 1 loc */
|
||||
WMW(tempa+4, sw2); /* save status and residual cnt in status WD 2 loc */
|
||||
#endif
|
||||
chp->chan_byte = BUFF_DONE; /* we are done */
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"LOADING %06x %04x FIFO #%1x read inch %06x sw1 %08x sw2 %08x\n",
|
||||
@ -2400,14 +2413,6 @@ uint32 scan_chan(uint32 *ilev) {
|
||||
return 0; /* not ready, return */
|
||||
}
|
||||
|
||||
#ifdef TEMP_REMOVE_03072021
|
||||
/* see if we are able to look for ints */
|
||||
if (irq_pend == 0) /* pending int? */
|
||||
return 0; /* no, done */
|
||||
if (CPUSTATUS & BIT24) /* interrupts blocked? */
|
||||
return 0; /* yes, done */
|
||||
#endif
|
||||
|
||||
/* ints not blocked, so look for highest requesting interrupt */
|
||||
for (i=0; i<112; i++) {
|
||||
if (SPAD[i+0x80] == 0) /* not initialize? */
|
||||
@ -2437,23 +2442,12 @@ uint32 scan_chan(uint32 *ilev) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEMP_REMOVE_03072021
|
||||
/* cannot make anyone active if ints are blocked */
|
||||
if ((CPUSTATUS & BIT24) || (waitqcnt)) { /* interrupts blocked? */
|
||||
if (waitqcnt) /* doing wait delay? */
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "scan_chan waitqcnt %02x\n", waitqcnt);
|
||||
if (CPUSTATUS & BIT24) /* interrupts blocked? */
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "scan_chan INTS blocked!\n");
|
||||
goto tryme; /* needed for MPX */
|
||||
}
|
||||
#else
|
||||
/* cannot make anyone active if ints are blocked */
|
||||
/* irq_pend will be set again when interrupts are unblocked */
|
||||
if (CPUSTATUS & BIT24) { /* interrupts blocked? */
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "scan_chan INTS blocked!\n");
|
||||
goto tryme; /* needed for MPX */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* now go process the highest requesting interrupt */
|
||||
for (i=0; i<112; i++) {
|
||||
@ -2517,15 +2511,15 @@ uint32 scan_chan(uint32 *ilev) {
|
||||
"scan_chan %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n",
|
||||
chsa, FIFO_Num(chan), i, chp->chan_inch_addr, chp, chan_icba, chp->chan_byte);
|
||||
if (post_csw(chp, 0)) {
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"scan_chanx %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n",
|
||||
chan, FIFO_Num(chan), i, chp->chan_inch_addr, RMW(chan_icba+20), chp->chan_byte);
|
||||
/* change status from BUFF_POST to BUFF_DONE */
|
||||
/* if not BUFF_POST we have a PPCI or channel busy interrupt */
|
||||
/* so leave the channel status alone */
|
||||
if (chp->chan_byte == BUFF_POST) {
|
||||
chp->chan_byte = BUFF_DONE; /* show done & not busy */
|
||||
}
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"scan_chanx %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n",
|
||||
chan, FIFO_Num(chan), i, chp->chan_inch_addr, RMW(chan_icba+20), chp->chan_byte);
|
||||
} else {
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"scan_chanx %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n",
|
||||
|
||||
@ -141,6 +141,7 @@ DIB con_dib = {
|
||||
DEVICE con_dev = {
|
||||
"CON", con_unit, NULL, con_mod,
|
||||
NUM_UNITS_CON, 8, 15, 1, 8, 8,
|
||||
// NULL, NULL, &con_reset, NULL, &con_attach, &con_detach,
|
||||
NULL, NULL, &con_reset, NULL, NULL, NULL,
|
||||
&con_dib, DEV_DIS|DEV_DISABLE|DEV_DEBUG, 0, dev_debug
|
||||
};
|
||||
@ -647,11 +648,13 @@ uint16 con_haltio(UNIT *uptr) {
|
||||
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */
|
||||
uptr->CMD &= LMASK; /* make non-busy */
|
||||
uptr->u4 = 0; /* no I/O yet */
|
||||
sim_cancel(uptr); /* stop timer */
|
||||
con_data[unit].incnt = 0; /* no input data */
|
||||
uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */
|
||||
sim_debug(DEBUG_CMD, &con_dev,
|
||||
"con_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd);
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */
|
||||
//BAD chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* force end */
|
||||
return 1; /* tell chan code to post status */
|
||||
}
|
||||
uptr->u4 = 0; /* no I/O yet */
|
||||
|
||||
@ -158,9 +158,6 @@ uint32 RDYQIN; /* fifo input index */
|
||||
uint32 RDYQOUT; /* fifo output index */
|
||||
uint32 RDYQ[128]; /* channel ready queue */
|
||||
uint8 waitqcnt = 0; /* # instructions before start */
|
||||
#ifdef REMOVE_03072021
|
||||
uint8 waitrdyq = 0; /* # instructions before post interrupt */
|
||||
#endif
|
||||
|
||||
struct InstHistory
|
||||
{
|
||||
@ -1945,11 +1942,6 @@ wait_loop:
|
||||
uint32 chsa; /* channel/sub adddress */
|
||||
int32 stat; /* return status 0/1 from loadccw */
|
||||
|
||||
#ifdef REMOVE_03072021
|
||||
if (waitrdyq > 0) { /* see if we are waiting to start */
|
||||
waitrdyq--;
|
||||
} else
|
||||
#endif
|
||||
/* we have entries, continue channel program */
|
||||
if (RDYQ_Get(&chsa) == SCPE_OK) { /* get chsa for program */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
@ -2075,69 +2067,53 @@ wait_loop:
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CHANGE_03072021
|
||||
/* process IOCL entries that are waiting */
|
||||
/* loop through the IOCL ready Q and decrement wait counts */
|
||||
if ((int32c = RDYQ_Num())) {
|
||||
int32 i, rqo = RDYQOUT;
|
||||
for (i=0; i<int32c; i++) {
|
||||
uint32 chsa; /* channel/sub adddress */
|
||||
uint32 chsa = 0; /* channel/sub adddress */
|
||||
CHANP *chp; /* get channel prog pointer */
|
||||
if (rqo == RDYQIN)
|
||||
break; /* done with queue */
|
||||
chsa = RDYQ[rqo]; /* get the next entry */
|
||||
if (RDYQ_Get(&chsa) == SCPE_OK) { /* get chsa for program */
|
||||
// chsa = RDYQ[rqo]; /* get the next entry */
|
||||
}
|
||||
if (chsa == 0) /* ignore unused entries */
|
||||
continue;
|
||||
chp = find_chanp_ptr(chsa); /* get channel prog pointer */
|
||||
if (chp == NULL) /* ignore unused entries */
|
||||
continue;
|
||||
if (chp->chan_byte != BUFF_NEXT) {
|
||||
/* if not BUFF_NEXT, channel has been stopped, do nothing */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"scan_chan Bad CPU RDYQ entry for chsa %04x chan_byte %02x\n",
|
||||
chsa, chp->chan_byte);
|
||||
/* not BUFF_NEXT, just zero entry */
|
||||
continue; /* ignore the entry */
|
||||
}
|
||||
/* state is BUFF_NEXT, see if wait is over */
|
||||
if (chp->chan_qwait > 0) /* still waiting? */
|
||||
chp->chan_qwait--; /* decrement count */
|
||||
rqo++; /* next queue entry */
|
||||
rqo %= RDYQ_SIZE; /* don't overrun end */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* process IOCL entries that are waiting */
|
||||
if (RDYQ_Num()) {
|
||||
uint32 chsa; /* channel/sub adddress */
|
||||
CHANP *chp; /* get channel prog pointer */
|
||||
chsa = RDYQ[RDYQOUT]; /* get the next entry */
|
||||
chp = find_chanp_ptr(chsa); /* get channel prog pointer */
|
||||
if (chp->chan_byte != BUFF_NEXT) {
|
||||
/* chan_byte is not BUFF_NEXT */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"scan_chan Bad CPU RDYQ entry for chsa %04x chan_byte %02x\n",
|
||||
chsa, chp->chan_byte);
|
||||
}
|
||||
#ifdef CHANGE_03072021
|
||||
if (chp->chan_byte == BUFF_NEXT) {
|
||||
#else
|
||||
/* checking BUFF_NEXT hangs diag n keyboard termination */
|
||||
if ((chp->chan_qwait == 0) || (chp->chan_byte != BUFF_NEXT)) {
|
||||
// if ((chp->chan_qwait == 0) && (chp->chan_byte == BUFF_NEXT)) {
|
||||
// if (chp->chan_qwait == 0) {
|
||||
#endif
|
||||
#ifdef REMOVE_03072021
|
||||
/* we have entries, continue channel program */
|
||||
if (waitrdyq > 0) {
|
||||
waitrdyq--;
|
||||
} else
|
||||
#endif
|
||||
if (RDYQ_Get(&chsa) == SCPE_OK) { /* get chsa for program */
|
||||
/* process 0 wait entry */
|
||||
if (chp->chan_qwait == 0) {
|
||||
int32 stat;
|
||||
CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"scan_chan CPU RDYQ entry for chsa %04x starting byte %02x\n",
|
||||
chsa, chp->chan_byte);
|
||||
/* if not BUFF_NEXT, channel has been stopped, just continue */
|
||||
if (chp->chan_byte == BUFF_NEXT) {
|
||||
stat = cont_chan(chsa); /* resume the channel program */
|
||||
if (stat == SCPE_OK)
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"scan_chan CPU RDYQ entry for chsa %04x processed byte %04x\n",
|
||||
chsa, chp->chan_byte);
|
||||
else
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"scan_chan CPU RDYQ entry for chsa %04x processed w/error byte %04x\n",
|
||||
chsa, chp->chan_byte);
|
||||
}
|
||||
}
|
||||
/* if not BUFF_NEXT, channel has been stopped, do nothing */
|
||||
stat = cont_chan(chsa); /* resume the channel program */
|
||||
if (stat == SCPE_OK)
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"scan_chan CPU RDYQ entry for chsa %04x processed byte %04x\n",
|
||||
chsa, chp->chan_byte);
|
||||
else
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"scan_chan CPU RDYQ entry for chsa %04x processed w/error byte %04x\n",
|
||||
chsa, chp->chan_byte);
|
||||
continue;
|
||||
} else
|
||||
RDYQ_Put(chsa); /* requeue the non-zero entry */
|
||||
rqo++; /* next queue entry */
|
||||
rqo %= RDYQ_SIZE; /* don't overrun end */
|
||||
}
|
||||
}
|
||||
|
||||
@ -5854,11 +5830,12 @@ doovr2:
|
||||
dest = (D32RMASK & dest); /* zero fill */
|
||||
if (td == 0)
|
||||
CC |= CC4BIT; /* word is zero, so CC4 */
|
||||
else
|
||||
else {
|
||||
if (td & 0x80000000)
|
||||
CC |= CC3BIT; /* it is neg wd, so CC3 */
|
||||
else
|
||||
CC |= CC2BIT; /* then td > 0, so CC2 */
|
||||
}
|
||||
break;
|
||||
case 2: /* 64 bit double */
|
||||
/* ARMD */
|
||||
@ -5873,12 +5850,13 @@ doovr2:
|
||||
ovr = 1;
|
||||
if (td == 0)
|
||||
CC |= CC4BIT; /* dw is zero, so CC4 */
|
||||
else
|
||||
else {
|
||||
if (td & DMSIGN)
|
||||
CC |= CC3BIT; /* it is neg dw, so CC3 */
|
||||
else
|
||||
CC |= CC2BIT; /* then td > 0, so CC2 */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ovr)
|
||||
CC |= CC1BIT; /* set overflow CC */
|
||||
@ -6502,10 +6480,10 @@ sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
/* SPAD address F1 has interrupt table address */
|
||||
temp = SPAD[0xf1] + (ix<<2); /* vector address in SPAD */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"$$ XIO lchan %02x sa %02x spad %08x BLK %1x INTS[%02x] %08x\n",
|
||||
lchan, suba, t, CPUSTATUS&0x80?1:0, ix, INTS[ix]);
|
||||
"$$ XIO chsa %04x spad %08x BLK %1x INTS[%02x] %08x\n",
|
||||
rchsa, t, CPUSTATUS&0x80?1:0, ix, INTS[ix]);
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"$$ XIO rchsa %04x PSD1 %08x PSD2 %08x IR %08x ICBA %06x\n",
|
||||
"$$ XIO chsa %04x PSD1 %08x PSD2 %08x IR %08x ICBA %06x\n",
|
||||
rchsa, PSD1, PSD2, IR, temp);
|
||||
if ((TRAPME = Mem_read(temp, &addr))) { /* get interrupt context block addr */
|
||||
mcheck:
|
||||
|
||||
@ -1089,7 +1089,6 @@ uint16 disk_haltio(UNIT *uptr) {
|
||||
/* status must not have an error bit set */
|
||||
/* otherwise, UTX will panic with "bad status" */
|
||||
if ((uptr->CMD & DSK_CMDMSK) != 0) { /* is unit busy */
|
||||
// sim_debug(DEBUG_CMD, dptr,
|
||||
sim_debug(DEBUG_EXP, dptr,
|
||||
"disk_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n",
|
||||
chsa, cmd, chp->ccw_count);
|
||||
@ -1098,11 +1097,9 @@ uint16 disk_haltio(UNIT *uptr) {
|
||||
uptr->CMD &= LMASK; /* make non-busy */
|
||||
uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */
|
||||
sim_cancel(uptr); /* clear the input timer */
|
||||
// sim_debug(DEBUG_CMD, dptr,
|
||||
sim_debug(DEBUG_EXP, dptr,
|
||||
"disk_haltio HIO I/O stop chsa %04x cmd = %02x CHS %08x STAR %08x\n",
|
||||
chsa, cmd, uptr->CHS, uptr->STAR);
|
||||
//1204 chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* force end */
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
102
SEL32/sel32_ec.c
102
SEL32/sel32_ec.c
@ -197,7 +197,7 @@ struct ec_device {
|
||||
ETH_MAC mac; /* Hardware MAC addresses */
|
||||
ETH_DEV etherface;
|
||||
ETH_QUE ReadQ;
|
||||
ETH_PACK rec_buff[64]; /* Buffer for recieved packet */
|
||||
ETH_PACK rec_buff[64]; /* Buffer for received packet */
|
||||
ETH_PACK snd_buff; /* Buffer for sending packet */
|
||||
int macs_n; /* Number of multi-cast addresses */
|
||||
ETH_MAC macs[67]; /* Watched Multi-cast addresses */
|
||||
@ -223,10 +223,7 @@ static CONST ETH_MAC broadcast_ethaddr = {0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
CHANP ec_chp[NUM_UNITS_ETHER] = {0};
|
||||
|
||||
/* forward definitions */
|
||||
#define FOR_TEST
|
||||
#ifdef FOR_TEST
|
||||
uint16 ec_preio(UNIT *uptr, uint16 chan);
|
||||
#endif
|
||||
uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd);
|
||||
t_stat ec_rec_srv(UNIT *uptr);
|
||||
t_stat ec_srv(UNIT *uptr);
|
||||
@ -235,9 +232,7 @@ uint16 ec_iocl(CHANP *chp, int32 tic_ok);
|
||||
void ec_packet_debug(struct ec_device *ec, const char *action, ETH_PACK *packet);
|
||||
t_stat ec_reset (DEVICE *dptr);
|
||||
void ec_ini(UNIT *, t_bool);
|
||||
#ifdef FOR_TEST
|
||||
uint16 ec_rschnlio(UNIT *uptr);
|
||||
#endif
|
||||
t_stat ec_show_mac (FILE* st, UNIT* uptr, int32 val, CONST void* desc);
|
||||
t_stat ec_set_mac (UNIT* uptr, int32 val, CONST char* cptr, void* desc);
|
||||
t_stat ec_show_mode (FILE* st, UNIT* uptr, int32 val, CONST void* desc);
|
||||
@ -276,21 +271,13 @@ UNIT ec_unit[] = {
|
||||
};
|
||||
|
||||
DIB ec_dib = {
|
||||
#ifdef FOR_TEST
|
||||
ec_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
|
||||
#else
|
||||
NULL, /* Pre start I/O */
|
||||
#endif
|
||||
ec_startcmd, /* Start a command */
|
||||
ec_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */
|
||||
ec_haltio, /* uint16 (*halt_io)(UNIT *uptr) */ /* Halt I/O */
|
||||
NULL, /* uint16 (*stop_io)(UNIT *uptr) */ /* Stop I/O */
|
||||
NULL, /* uint16 (*test_io)(UNIT *uptr) */ /* Test I/O */
|
||||
NULL, /* uint16 (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */
|
||||
#ifdef FOR_TEST
|
||||
ec_rschnlio, /* uint16 (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */
|
||||
#else
|
||||
NULL, /* uint16 (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */
|
||||
#endif
|
||||
ec_iocl, /* uint16 (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */
|
||||
ec_ini, /* void (*dev_ini)(UNIT *uptr) */ /* init function */
|
||||
ec_unit, /* UNIT *units */ /* Pointer to units structure */
|
||||
@ -400,8 +387,8 @@ loop:
|
||||
}
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"ec_iocl @%06x read ccw chan %02x IOCD wd 1 %08x wd 2 %08x SNS %08x\n",
|
||||
chp->chan_caw, chan, word1, word2, uptr->SNS);
|
||||
"ec_iocl @%06x read ccw chsa %04x IOCD wd 1 %08x wd 2 %08x SNS %08x\n",
|
||||
chp->chan_caw, chp->chan_dev, word1, word2, uptr->SNS);
|
||||
|
||||
chp->chan_caw = (chp->chan_caw & 0xfffffc) + 8; /* point to next IOCD */
|
||||
|
||||
@ -588,9 +575,7 @@ loop:
|
||||
sim_debug(DEBUG_EXP, dptr,
|
||||
"ec_iocl continue wait chsa %04x status %08x\n",
|
||||
chp->chan_dev, chp->chan_status);
|
||||
#ifndef CHANGE_03072021
|
||||
chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */
|
||||
#endif
|
||||
chp->chan_qwait = QWAIT; /* run 0 instructions before starting iocl */
|
||||
}
|
||||
} else
|
||||
|
||||
@ -613,14 +598,12 @@ loop:
|
||||
return 0; /* good return */
|
||||
}
|
||||
|
||||
#ifdef FOR_TEST
|
||||
/* start an ethernet operation */
|
||||
uint16 ec_preio(UNIT *uptr, uint16 chan) {
|
||||
DEVICE *dptr = get_dev(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
uint16 chsa = GET_UADDR(uptr->CMD);
|
||||
|
||||
#ifdef WAIT_FOR_TEST
|
||||
sim_debug(DEBUG_CMD, dptr, "ec_preio CMD %08x unit %02x chsa %04x\n",
|
||||
uptr->CMD, unit, chsa);
|
||||
if ((uptr->CMD & EC_CMDMSK) != 0) { /* just return if busy */
|
||||
@ -628,13 +611,11 @@ uint16 ec_preio(UNIT *uptr, uint16 chan) {
|
||||
"ec_preio unit %02x chsa %04x BUSY\n", unit, chsa);
|
||||
return SNS_BSY;
|
||||
}
|
||||
#endif
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr, "ec_preio CMD %08x unit %02x chsa %04x OK\n",
|
||||
uptr->CMD, unit, chsa);
|
||||
return SCPE_OK; /* good to go */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Start ethernet command */
|
||||
uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
|
||||
@ -655,7 +636,27 @@ uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
|
||||
switch (cmd) {
|
||||
case EC_WRITE: /* Write command 0x01 */
|
||||
uptr->CMD |= cmd|EC_BUSY; /* save cmd */
|
||||
sim_activate(uptr, 5000); /* start things off */
|
||||
// This works maybe 1 in 20 times to get to test 30
|
||||
//0313 sim_activate(uptr, 5000); /* start things off */
|
||||
// This smaller values runs to test 30, but gets lots of length errors */
|
||||
// sim_activate(uptr, 3000); /* start things off */
|
||||
//
|
||||
// This works most of the time & stops at test 30 with no len errors
|
||||
sim_activate(uptr, 4800); /* start things off */
|
||||
// This works some of the time, stops at test 30 with lots of len errors
|
||||
// sim_activate(uptr, 4700); /* start things off */
|
||||
// This works some of the time, stops at test 30 with lots of len errors
|
||||
//* sim_activate(uptr, 4500); /* start things off */
|
||||
// This works some of the time, stops at test 30 with lots of len errors
|
||||
// sim_activate(uptr, 4000); /* start things off */
|
||||
// This works some of the time, stops at test 19A, 20 & 30
|
||||
// sim_activate(uptr, 6000); /* start things off */
|
||||
// This works sometimes, stops at test 20
|
||||
// sim_activate(uptr, 7000); /* start things off */
|
||||
// This works sometimes, stops at test 20
|
||||
// sim_activate(uptr, 8000); /* start things off */
|
||||
// This works sometimes, stops at test 19A
|
||||
// sim_activate(uptr, 9000); /* start things off */
|
||||
return 0;
|
||||
case EC_INCH: /* INCH cmd 0x0 */
|
||||
cmd = EC_INCH2; /* set dummy INCH cmd 0xf0 */
|
||||
@ -679,7 +680,8 @@ uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
|
||||
}
|
||||
#endif
|
||||
uptr->CMD |= cmd|EC_BUSY; /* save cmd */
|
||||
sim_activate(uptr, 100); /* start things off */
|
||||
//JB sim_activate(uptr, 100); /* start things off */
|
||||
sim_activate(uptr, 50); /* start things off */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -706,8 +708,7 @@ t_stat ec_rec_srv(UNIT *uptr)
|
||||
ec_data.rec_ptr = (ec_data.rec_ptr + 1) & 0xf;
|
||||
ec_data.rx_count++;
|
||||
sim_debug(DEBUG_DETAIL, dptr,
|
||||
"ec_rec_srv received packet %08x\n",
|
||||
ec_data.rx_count);
|
||||
"ec_rec_srv received packet %08x\n", ec_data.rx_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -896,7 +897,7 @@ wr_end:
|
||||
if (ec_data.snd_buff.len > ETH_MAX_PACKET) {
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev,
|
||||
"ec_srv WRITE error user 2manybytes %0x\n", chp->ccw_count);
|
||||
/* diags wants prog check instead of unit check */
|
||||
/* diags wants prog check instead of length check test 4E */
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK);
|
||||
break;
|
||||
}
|
||||
@ -940,17 +941,18 @@ wr_end:
|
||||
case EC_READ: /* Read command 0x02 */
|
||||
/* If no data to receive wait for some more */
|
||||
if (ec_data.xtr_ptr == ec_data.rec_ptr) {
|
||||
sim_clock_coschedule(uptr, 1000); /* continue poll */
|
||||
// sim_clock_coschedule(uptr, 1000); /* continue poll */
|
||||
sim_clock_coschedule(uptr, 500); /* continue poll */
|
||||
return SCPE_OK;
|
||||
}
|
||||
pirq = 0;
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv read %d %d size=%d\n", ec_data.xtr_ptr,
|
||||
ec_data.rec_ptr, ec_data.conf[9]);
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv read %d %d size=%d\n",
|
||||
ec_data.xtr_ptr, ec_data.rec_ptr, ec_data.conf[9]);
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
/* Read must be word bounded */
|
||||
if (chp->ccw_addr & 0x3) {
|
||||
sim_debug(DEBUG_EXP, dptr,
|
||||
"ec_iocl iocd bad address caw %06x ccw %06x\n",
|
||||
"ec_srv iocd bad address caw %06x ccw %06x\n",
|
||||
chp->chan_caw, chp->ccw_addr);
|
||||
ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & 0xf;
|
||||
// chp->ccw_flags &= ~FLAG_SLI;
|
||||
@ -964,12 +966,13 @@ wr_end:
|
||||
pck = (uint8 *)(&ec_data.rec_buff[ec_data.xtr_ptr].msg[0]);
|
||||
len = (int)(ec_data.rec_buff[ec_data.xtr_ptr].len);
|
||||
if (len < ec_data.conf[9]) {
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv short read size %x %x\n",chp->ccw_count, ec_data.conf[9]);
|
||||
ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & 0xf;
|
||||
chp->ccw_count = 0;
|
||||
/* diags wants prog check instead of unit check */
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK);
|
||||
break;
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv READ error short read len %x size %x %x\n",
|
||||
len, chp->ccw_count, ec_data.conf[9]);
|
||||
ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & 0xf;
|
||||
chp->ccw_count = 0;
|
||||
/* diags wants prog check instead of unit check test 4F */
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK);
|
||||
break;
|
||||
}
|
||||
switch (GET_MODE(ec_master_uptr->flags)) {
|
||||
case 0:
|
||||
@ -1052,17 +1055,17 @@ wr_end:
|
||||
ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & 0xf;
|
||||
ec_data.rx_count++;
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev,
|
||||
"ec_srv received bytes %d of %d count=%08x\n" ,i,
|
||||
len, ec_data.rx_count);
|
||||
"ec_srv received bytes %d of %d count=%08x conf %x\n",
|
||||
i, len, ec_data.rx_count, ec_data.conf[9]);
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_LENGTH);
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
chp->ccw_flags |= FLAG_SLI;
|
||||
// chp->ccw_cmd = 0; /* This is to kill SLI indicator */
|
||||
ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & 0xf;
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev,
|
||||
"ec_srv received bytes %d count=%08x\n" ,len, ec_data.rx_count);
|
||||
"ec_srv received bytes %d count=%08x conf %x\n",
|
||||
len, ec_data.rx_count, ec_data.conf[9]);
|
||||
if (pirq)
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK);
|
||||
else
|
||||
@ -1160,8 +1163,8 @@ wr_end:
|
||||
/*JB*/ ec_data.rec_buff[ec_data.xtr_ptr].len = 0; /* clear old count */
|
||||
// if (ec_data.xtr_ptr == ec_data.rec_ptr)
|
||||
// len = 0;
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv SNS %d %d\n", ec_data.xtr_ptr,
|
||||
ec_data.rec_ptr);
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv SNS len %d xt %d rd %d\n",
|
||||
len, ec_data.xtr_ptr, ec_data.rec_ptr);
|
||||
ch = (uptr->SNS >> 24) & 0xfc;
|
||||
ch |= GET_MODE(ec_master_uptr->flags);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "ec_srv sense b0 1 %02x\n", ch);
|
||||
@ -1193,14 +1196,10 @@ wr_end:
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef ALLOW_0_CMD
|
||||
sim_debug(DEBUG_CMD, dptr, "invalid command %02x\n", cmd);
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
|
||||
#else
|
||||
sim_debug(DEBUG_CMD, dptr, "for testing, allow unknown command %02x\n", cmd);
|
||||
#endif
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, dptr,
|
||||
"ec_srv done cmd=%02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count);
|
||||
@ -1229,9 +1228,10 @@ uint16 ec_haltio(UNIT *uptr) {
|
||||
uptr->CMD &= LMASK; /* make non-busy */
|
||||
uptr->SNS = SNS_RCV_RDY; /* status is online & ready */
|
||||
if (chsa & 0x0f) /* no cancel for 0 */
|
||||
sim_cancel(uptr); /* clear the input timer */
|
||||
sim_cancel(uptr); /* clear the output timer */
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"ec_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd);
|
||||
/* No unit exception status for ethernet */
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
@ -1271,7 +1271,6 @@ void ec_ini(UNIT *uptr, t_bool f)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FOR_TEST
|
||||
/* handle rschnlio cmds for Ethernet */
|
||||
uint16 ec_rschnlio(UNIT *uptr) {
|
||||
DEVICE *dptr = get_dev(uptr);
|
||||
@ -1283,7 +1282,6 @@ uint16 ec_rschnlio(UNIT *uptr) {
|
||||
ec_ini(uptr, 0); /* reset the unit */
|
||||
return SCPE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *
|
||||
ipv4_inet_ntoa(struct in_addr ip)
|
||||
|
||||
@ -3012,9 +3012,6 @@ int hsdp_label(UNIT *uptr, int use_strep) {
|
||||
/* get sector address of vendor defect table VDT */
|
||||
/* put data = 0xf0000004 0xf4000000 */
|
||||
int32 vaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-1) * SPT(type);
|
||||
/* make logical */
|
||||
int32 logva = vaddr*(SPT(type)-1)/(SPT(type));
|
||||
|
||||
/* get sector address of utx diag map (DMAP) track 0 pointer */
|
||||
/* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */
|
||||
/* 0x9a000000 + (cyl-1), 0xf4000000 */
|
||||
@ -3024,16 +3021,9 @@ int hsdp_label(UNIT *uptr, int use_strep) {
|
||||
|
||||
/* get sector address of utx flaw map sec 1 pointer */
|
||||
/* use this address for sec 1 label pointer */
|
||||
#define NOT_NEEDED_0128
|
||||
#ifndef NOT_NEEDED_0128
|
||||
int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-4) * SPT(type);
|
||||
/* make logical */
|
||||
int32 logua = uaddr*(SPT(type)-1)/(SPT(type));
|
||||
#else
|
||||
int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type);
|
||||
/* make logical */
|
||||
int32 logua = uaddr*(SPT(type)-1)/(SPT(type));
|
||||
#endif
|
||||
|
||||
/* write 30 byte track labels for all tracks on disk */
|
||||
/* tot_tracks entries will be created starting at end of disk */
|
||||
@ -3130,29 +3120,14 @@ int hsdp_label(UNIT *uptr, int use_strep) {
|
||||
|
||||
/* write vaddr to track label for dmap */
|
||||
if ((i*SPT(type)) == daddr) { /* get track address in sectors */
|
||||
//no_logical #if 1
|
||||
#if 0
|
||||
if (use_strep) {
|
||||
/* output logical vendor defect map address of disk */
|
||||
label[12] = (logva >> 24) & 0xff; /* Vaddr pointer vdt */
|
||||
label[13] = (logva >> 16) & 0xff;
|
||||
label[14] = (logva >> 8) & 0xff;
|
||||
label[15] = (logva) & 0xff;
|
||||
printf("hsdp_label WTL logva@vaddr %08x -> %08x\r\n", logva, vaddr);
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"hsdp_label WTL logva@vaddr %08x -> %08x\n", logva, vaddr);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* output physical vendor defect map address of disk */
|
||||
label[12] = (vaddr >> 24) & 0xff; /* Vaddr pointer vdt */
|
||||
label[13] = (vaddr >> 16) & 0xff;
|
||||
label[14] = (vaddr >> 8) & 0xff;
|
||||
label[15] = (vaddr) & 0xff;
|
||||
printf("hsdp_label WTL vaddr@vaddr %08x -> %08x\r\n", vaddr, vaddr);
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"hsdp_label WTL vaddr@vaddr %08x -> %08x\n", vaddr, vaddr);
|
||||
}
|
||||
/* output physical vendor defect map address of disk */
|
||||
label[12] = (vaddr >> 24) & 0xff; /* Vaddr pointer vdt */
|
||||
label[13] = (vaddr >> 16) & 0xff;
|
||||
label[14] = (vaddr >> 8) & 0xff;
|
||||
label[15] = (vaddr) & 0xff;
|
||||
printf("hsdp_label WTL vaddr@vaddr %08x -> %08x\r\n", vaddr, vaddr);
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"hsdp_label WTL vaddr@vaddr %08x -> %08x\n", vaddr, vaddr);
|
||||
}
|
||||
|
||||
/* the tech doc shows the cyl/trk/sec data is in the first 4 bytes */
|
||||
@ -3160,13 +3135,11 @@ int hsdp_label(UNIT *uptr, int use_strep) {
|
||||
/* area too. Byte 27 is sectors/track and byte 28 is number of heads. */
|
||||
/* Byte 26 is mode. Byte 25 is copy of byte 27. */
|
||||
label[25] = SPT(type) & 0xff; /* save sectors per track */
|
||||
//no_logical if ((use_strep) && (daddr == (i*SPT(type)) || (i == 0))) {
|
||||
if ((use_strep) && (i == 0)) {
|
||||
label[25] = (SPT(type)-1) & 0xff;
|
||||
}
|
||||
uptr->LSC = label[25]; /* save logical/physical sector count from label */
|
||||
label[26] = hsdp_type[type].type & 0xfd; /* zero bits 6 in type byte */
|
||||
// label[26] = hsdp_type[type].type | 1; /* mode data is 0x41 */
|
||||
label[27] = label[25]; /* same as label[25] */
|
||||
label[28] = HDS(type) & 0xff;
|
||||
|
||||
@ -3230,34 +3203,6 @@ int hsdp_label(UNIT *uptr, int use_strep) {
|
||||
|
||||
/* if this is written, UTX will not be able to do a newfs */
|
||||
/* gets preposterous size 0 error */
|
||||
#ifdef XXXX_121720
|
||||
/* maybe not needed, but left anyway */
|
||||
/* uaddr has umap value for sector one label */
|
||||
if (CHS == 1) { /* write umap address in sec 1 */
|
||||
#if 1
|
||||
if (use_strep) {
|
||||
/* output logical umap address */
|
||||
label[12] = (logua >> 24) & 0xff; /* lumapp UMAP logical pointer */
|
||||
label[13] = (logua >> 16) & 0xff;
|
||||
label[14] = (logua >> 8) & 0xff;
|
||||
label[15] = (logua) & 0xff;
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"hsdp_format WSL uaddr star %02x %02x %02x %02x\n",
|
||||
label[12], label[13], label[14], label[15]);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* output physical umap address */
|
||||
label[12] = (uaddr >> 24) & 0xff; /* lumapp UMAP physical pointer */
|
||||
label[13] = (uaddr >> 16) & 0xff;
|
||||
label[14] = (uaddr >> 8) & 0xff;
|
||||
label[15] = (uaddr) & 0xff;
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"hsdp_format WSL uaddr star %02x %02x %02x %02x\n",
|
||||
label[12], label[13], label[14], label[15]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* 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 too. Byte 27 is sectors/track and byte 28 is number of heads. */
|
||||
@ -3303,22 +3248,10 @@ int hsdp_format(UNIT *uptr) {
|
||||
|
||||
/* last sector address of disk (cyl * hds * spt) - 1 */
|
||||
uint32 laddr = CAP(type) - 1; /* last sector of disk */
|
||||
/* make logical */
|
||||
int32 logla = laddr*(SPT(type)-1)/(SPT(type));
|
||||
|
||||
#ifndef NOT_NEEDED_0128
|
||||
/* last track address of disk (cyl * hds * spt) - spt */
|
||||
uint32 ltaddr = CAP(type)-SPT(type); /* last track of disk */
|
||||
/* make logical */
|
||||
int32 loglta = ltaddr*(SPT(type)-1)/(SPT(type));
|
||||
#endif
|
||||
|
||||
/* get sector address of vendor defect table VDT */
|
||||
/* put data = 0xf0000004 0xf4000000 */
|
||||
int32 vaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-1) * SPT(type);
|
||||
/* make logical */
|
||||
int32 logva = vaddr*(SPT(type)-1)/(SPT(type));
|
||||
|
||||
/* get sector address of utx diag map (DMAP) track 0 pointer */
|
||||
/* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */
|
||||
/* 0x9a000000 + (cyl-1), 0xf4000000 */
|
||||
@ -3327,19 +3260,7 @@ int hsdp_format(UNIT *uptr) {
|
||||
/* make logical */
|
||||
int32 logda = daddr*(SPT(type)-1)/(SPT(type));
|
||||
|
||||
#ifndef NOT_NEEDED_0128
|
||||
/* get sector address of utx flaw data (1 track long) */
|
||||
/* set trace data to zero */
|
||||
int32 faddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type);
|
||||
/* make logical */
|
||||
int32 logfa = faddr*(SPT(type)-1)/(SPT(type));
|
||||
#endif
|
||||
|
||||
#ifndef NOT_NEEDED_0128
|
||||
int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-4) * SPT(type);
|
||||
#else
|
||||
int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type);
|
||||
#endif
|
||||
|
||||
/* NULL vendor flaw map */
|
||||
uint32 vmap[2] = {0xf0000004, 0xf4000000};
|
||||
@ -3351,23 +3272,12 @@ int hsdp_format(UNIT *uptr) {
|
||||
uint32 dmap[4] = {0xf0000000 | (((cap-1)*(SPT(type)-1))/(SPT(type))),
|
||||
0x8a000000 | logda,
|
||||
0x9a000000 | (((cap-1)*(SPT(type)-1))/(SPT(type))), 0xf4000000};
|
||||
#ifndef NOT_NEEDED_0128
|
||||
/* utx flaw map */
|
||||
uint32 pfmap[4] = {0xf0000000 | (cap-1), 0x8a000000 | daddr,
|
||||
0x9a000000 | ltaddr, 0xf4000000};
|
||||
|
||||
/* utx flaw map */
|
||||
uint32 fmap[4] = {0xf0000000 | (((cap-1)*(SPT(type)-1))/(SPT(type))),
|
||||
0x8a000000 | logda,
|
||||
0x9a000000 | loglta, 0xf4000000};
|
||||
#endif
|
||||
|
||||
/* see if -i or -n specified on attach command */
|
||||
if (!(sim_switches & SWMASK('N')) && !(sim_switches & SWMASK('I'))) {
|
||||
sim_switches = 0; /* simh tests 'N' & 'Y' switches */
|
||||
/* see if user wants to initialize the disk */
|
||||
if (!get_yn("Initialize disk? [Y] ", TRUE)) {
|
||||
// printf("disk_format init question is false\r\n");
|
||||
sim_switches = oldsw;
|
||||
return 1;
|
||||
}
|
||||
@ -3434,16 +3344,6 @@ int hsdp_format(UNIT *uptr) {
|
||||
pdmap[i] = (((pdmap[i] & 0xff) << 24) | ((pdmap[i] & 0xff00) << 8) |
|
||||
((pdmap[i] & 0xff0000) >> 8) | ((pdmap[i] >> 24) & 0xff));
|
||||
}
|
||||
#ifndef NOT_NEEDED_0128
|
||||
for (i=0; i<4; i++) {
|
||||
fmap[i] = (((fmap[i] & 0xff) << 24) | ((fmap[i] & 0xff00) << 8) |
|
||||
((fmap[i] & 0xff0000) >> 8) | ((fmap[i] >> 24) & 0xff));
|
||||
}
|
||||
for (i=0; i<4; i++) {
|
||||
pfmap[i] = (((pfmap[i] & 0xff) << 24) | ((pfmap[i] & 0xff00) << 8) |
|
||||
((pfmap[i] & 0xff0000) >> 8) | ((pfmap[i] >> 24) & 0xff));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* now seek to end of disk and write the dmap data */
|
||||
/* setup dmap pointed to by track label 0 wd[3] = (cyl-4) * spt + (spt - 1) */
|
||||
@ -3499,32 +3399,6 @@ int hsdp_format(UNIT *uptr) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#ifndef NOT_NEEDED_0128
|
||||
/* write dummy UTX DMAP to faddr */
|
||||
if ((sim_fseek(uptr->fileref, faddr*ssize, SEEK_SET)) != 0) { /* seek DMAP */
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"Error on media FMAP seek to sect %06x offset %06x\n",
|
||||
faddr, faddr*ssize);
|
||||
return 1;
|
||||
}
|
||||
if (use_st_format) {
|
||||
if ((sim_fwrite((char *)&fmap, sizeof(uint32), 4, uptr->fileref)) != 4) {
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"Error writing UTX LFMAP to sect %06x offset %06x\n",
|
||||
faddr, faddr*ssize);
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if ((sim_fwrite((char *)&pfmap, sizeof(uint32), 4, uptr->fileref)) != 4) {
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"Error writing UTX FMAP to sect %06x offset %06x\n",
|
||||
faddr, faddr*ssize);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("Disk %s has %x (%d) cyl, %x (%d) hds, %x (%d) sec\r\n",
|
||||
hsdp_type[type].name, CYL(type), CYL(type), HDS(type), HDS(type),
|
||||
SPT(type), SPT(type));
|
||||
@ -3533,10 +3407,6 @@ int hsdp_format(UNIT *uptr) {
|
||||
printf("writing to dmap %x (%d) %x (%d) dmap to %x (%d) %x (%d)\r\n",
|
||||
cap-1, cap-1, (cap-1)*ssize, (cap-1)*ssize,
|
||||
daddr, daddr, daddr*ssize, daddr*ssize);
|
||||
#ifndef NOT_NEEDED_0128
|
||||
printf("writing to fmap sec %x (%d) bytes %x (%d)\r\n",
|
||||
faddr, faddr, (faddr)*ssize, (faddr)*ssize);
|
||||
#endif
|
||||
printf("writing to umap sec %x (%d) bytes %x (%d)\r\n",
|
||||
uaddr, uaddr, (uaddr)*ssize, (uaddr)*ssize);
|
||||
|
||||
@ -3633,8 +3503,6 @@ t_stat hsdp_attach(UNIT *uptr, CONST char *file)
|
||||
printf("HSDP Disk attach ftell failed s=%06d\r\n", s);
|
||||
goto fmt; /* not setup, go format */
|
||||
}
|
||||
// sim_debug(DEBUG_CMD, dptr, "HSDP Disk attach ftell value s=%06d b=%06d CAP %06d\n", s/ssize, s, CAP(type));
|
||||
// printf("HSDP Disk attach ftell value s=%06d b=%06d CAP %06d\r\n", s/ssize, s, CAP(type));
|
||||
|
||||
if (((int)s/(int)ssize) < ((int)CAP(type))) { /* full sized disk? */
|
||||
j = (CAP(type) - (s/ssize)); /* get # sectors to write */
|
||||
@ -3751,45 +3619,6 @@ ldone:
|
||||
return SCPE_FMT; /* error */
|
||||
}
|
||||
}
|
||||
#ifdef OLDWAY
|
||||
else {
|
||||
#ifndef NOT_NEEDED_0128
|
||||
int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-4) * SPT(type);
|
||||
/* make logical */
|
||||
int32 logua = uaddr*(SPT(type)-1)/(SPT(type));
|
||||
#else
|
||||
int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type);
|
||||
/* make logical */
|
||||
int32 logua = uaddr*(SPT(type)-1)/(SPT(type));
|
||||
#endif
|
||||
if (buff[25] == SPT(type)) {
|
||||
/* uaddr has physical umap value for track zero label */
|
||||
/* output physical umap address */
|
||||
buff[16] = (uaddr >> 24) & 0xff; /* lumapp DMAP pointer */
|
||||
buff[17] = (uaddr >> 16) & 0xff;
|
||||
buff[18] = (uaddr >> 8) & 0xff;
|
||||
buff[19] = (uaddr) & 0xff;
|
||||
} else {
|
||||
/* logua has logical umap value for track zero label */
|
||||
/* output logical umap address */
|
||||
buff[16] = (logua >> 24) & 0xff; /* lumapp DMAP pointer */
|
||||
buff[17] = (logua >> 16) & 0xff;
|
||||
buff[18] = (logua >> 8) & 0xff;
|
||||
buff[19] = (logua) & 0xff;
|
||||
}
|
||||
if ((sim_fseek(uptr->fileref, CAP(type)*ssize, SEEK_SET)) != 0) { /* seek end */
|
||||
detach_unit(uptr); /* detach if error */
|
||||
return SCPE_FMT; /* error */
|
||||
}
|
||||
/* output updated umap address to track 0 for UTX21a */
|
||||
if ((sim_fwrite(buff, sizeof(uint8), 30, uptr->fileref)) != 30) {
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"Error writing back track 0 label to sect %06x offset %06x\n",
|
||||
CAP(type), CAP(type)*ssize);
|
||||
return SCPE_FMT; /* error */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* see if disk has labels already, seek to sector past end of disk */
|
||||
if ((sim_fseek(uptr->fileref, CAP(type)*ssize, SEEK_SET)) != 0) { /* seek end */
|
||||
@ -3822,15 +3651,12 @@ ldone:
|
||||
}
|
||||
info = (buff[0]<<24) | (buff[1]<<16) | (buff[2]<<8) | buff[3];
|
||||
good = 0x4e554d50; /* NUMP */
|
||||
// printf("info %8x good %8x cnt %x\r\n", info, good, buff[35]);
|
||||
if (info == good) {
|
||||
/* we have a UTX umap, so fixup the data */
|
||||
if (buff[35] <= SPT(type))
|
||||
// i = (16*8) + (buff[35]*3*4) - 1; /* byte offset to where to put 0xf4 */
|
||||
i = (127) + (buff[35]*12); /* byte offset to where to put 0xf4 */
|
||||
else
|
||||
i = 127; /* only 1 track of replacement */
|
||||
// printf("Fixing umap i %x info %8x good %8x buff[%x] %02x\r\n", i, info, good, i, buff[i]);
|
||||
buff[i] = 0xf4; /* set stop for UTX search */
|
||||
if ((sim_fseek(uptr->fileref, umapaddr*ssize, SEEK_SET)) != 0) { /* seek umap */
|
||||
detach_unit(uptr); /* detach if error */
|
||||
@ -3840,7 +3666,6 @@ ldone:
|
||||
detach_unit(uptr); /* detach if error */
|
||||
return SCPE_FMT; /* error */
|
||||
}
|
||||
// printf("Fix Done i %x info %8x good %8x buff[%x] %02x\r\n", i, info, good, i, buff[i]);
|
||||
}
|
||||
|
||||
if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
#define UNIT_IOP UNIT_IDLE | UNIT_DISABLE
|
||||
|
||||
/* forward definitions */
|
||||
uint16 iop_preio(UNIT *uptr, uint16 chan);
|
||||
uint16 iop_startcmd(UNIT *uptr, uint16 chan, uint8 cmd);
|
||||
void iop_ini(UNIT *uptr, t_bool f);
|
||||
uint16 iop_rschnlio(UNIT *uptr);
|
||||
@ -99,7 +100,7 @@ UNIT iop_unit[] = {
|
||||
};
|
||||
|
||||
DIB iop_dib = {
|
||||
NULL, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */
|
||||
iop_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
|
||||
iop_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command SIO */
|
||||
NULL, /* uint16 (*halt_io)(UNIT *uptr) */ /* Halt I/O HIO */
|
||||
NULL, /* uint16 (*stop_io)(UNIT *uptr) */ /* Stop I/O HIO */
|
||||
@ -155,6 +156,25 @@ uint16 iop_rschnlio(UNIT *uptr) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* start an iop operation */
|
||||
uint16 iop_preio(UNIT *uptr, uint16 chan) {
|
||||
DEVICE *dptr = get_dev(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
uint16 chsa = GET_UADDR(uptr->u3);
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr, "iop_preio CMD %08x unit %02x chsa %04x\n",
|
||||
uptr->u3, unit, chsa);
|
||||
|
||||
if ((uptr->u3 & IOP_MSK) != 0) { /* is unit busy */
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"iop_preio unit %02x chsa %04x BUSY\n", unit, chsa);
|
||||
return SNS_BSY; /* yes, return busy */
|
||||
}
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr, "iop_preio unit %02x chsa %04x OK\n", unit, chsa);
|
||||
return SCPE_OK; /* good to go */
|
||||
}
|
||||
|
||||
/* start an I/O operation */
|
||||
uint16 iop_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
|
||||
{
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#define UNIT_MFP UNIT_IDLE | UNIT_DISABLE
|
||||
|
||||
/* forward definitions */
|
||||
uint16 mfp_preio(UNIT *uptr, uint16 chan);
|
||||
uint16 mfp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd);
|
||||
void mfp_ini(UNIT *uptr, t_bool f);
|
||||
uint16 mfp_rschnlio(UNIT *uptr);
|
||||
@ -103,7 +104,7 @@ UNIT mfp_unit[] = {
|
||||
|
||||
//DIB mfp_dib = {NULL, mfp_startcmd, NULL, NULL, NULL, mfp_ini, mfp_unit, mfp_chp, NUM_UNITS_MFP, 0xff, 0x7600,0,0,0};
|
||||
DIB mfp_dib = {
|
||||
NULL, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */
|
||||
mfp_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
|
||||
mfp_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */
|
||||
NULL, /* uint16 (*halt_io)(UNIT *uptr) */ /* Halt I/O HIO */
|
||||
NULL, /* uint16 (*stop_io)(UNIT *uptr) */ /* Stop I/O HIO */
|
||||
@ -159,6 +160,25 @@ uint16 mfp_rschnlio(UNIT *uptr) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* start an mfp operation */
|
||||
uint16 mfp_preio(UNIT *uptr, uint16 chan) {
|
||||
DEVICE *dptr = get_dev(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
uint16 chsa = GET_UADDR(uptr->u3);
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr, "mfp_preio CMD %08x unit %02x chsa %04x\n",
|
||||
uptr->u3, unit, chsa);
|
||||
|
||||
if ((uptr->u3 & MFP_MSK) != 0) { /* is unit busy */
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"mfp_preio unit %02x chsa %04x BUSY\n", unit, chsa);
|
||||
return SNS_BSY; /* yes, return busy */
|
||||
}
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr, "mfp_preio unit %02x chsa %04x OK\n", unit, chsa);
|
||||
return SCPE_OK; /* good to go */
|
||||
}
|
||||
|
||||
/* start an I/O operation */
|
||||
uint16 mfp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user