1
0
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:
AZBevier 2021-03-14 20:27:17 -07:00
parent 2fc381dfe1
commit fdf8fffb4c
8 changed files with 287 additions and 452 deletions

View File

@ -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",

View File

@ -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 */

View File

@ -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:

View File

@ -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;
}

View File

@ -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)

View File

@ -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 */

View File

@ -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)
{

View File

@ -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)
{