1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-01-13 15:27:04 +00:00

SEL32: Continue Code cleanup and formatting.

SEL32: Finish adding preio entry to rest of devices.
SEL32: Remove attached test from SIO processing code.
SEL32: Add attached test to each device processing code.
SEL32: Correct renum.c tap tool tp handle large files.
SEL32: Fix device address assignment for sel32_com.c device.
SEL32: Fix deblk to handle more file formatting errors.
This commit is contained in:
AZBevier 2021-03-04 08:24:01 -07:00
parent 296a7b4192
commit 3ddc772ce2
17 changed files with 4863 additions and 5013 deletions

View File

@ -159,15 +159,12 @@ int32 FIFO_Put(uint16 chsa, uint32 entry)
dibp->chan_fifo_in += 1; /* next entry */
dibp->chan_fifo_in %= FIFO_SIZE; /* modulo FIFO size */
num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE;
// sim_debug(DEBUG_EXP, &cpu_dev,
// "FIFO_Put FIFO put entry %04x for chsa %04x count %02x\n", entry, chsa, num);
return SCPE_OK; /* all OK */
}
/* get the next entry from the FIFO */
int32 FIFO_Get(uint16 chsa, uint32 *old)
{
// 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,
@ -182,9 +179,6 @@ int32 FIFO_Get(uint16 chsa, uint32 *old)
*old = dibp->chan_fifo[dibp->chan_fifo_out]; /* get the next entry */
dibp->chan_fifo_out += 1; /* next entry */
dibp->chan_fifo_out %= FIFO_SIZE; /* modulo FIFO size */
// num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE;
// sim_debug(DEBUG_EXP, &cpu_dev,
// "FIFO_Get FIFO get entry %04x for chsa %04x leaving count %02x\n", *old, chsa, num);
return SCPE_OK; /* all OK */
}
@ -206,23 +200,19 @@ int32 FIFO_Num(uint16 chsa)
/* add an entry to the RDYQ */
int32 RDYQ_Put(uint32 entry)
{
// int32 num; /* number of entries */
int32 num; /* number of entries */
/* see if RDYQ FIFO is full */
if (RDYQIN == ((RDYQOUT-1+RDYQ_SIZE) % RDYQ_SIZE)) {
// num = (RDYQIN - RDYQOUT + RDYQ_SIZE) % RDYQ_SIZE; /* number of entries */
// sim_debug(DEBUG_XIO, &cpu_dev, "RDYQ_Put queue FULL count %02x\n", num);
num = (RDYQIN - RDYQOUT + RDYQ_SIZE) % RDYQ_SIZE; /* number of entries */
sim_debug(DEBUG_EXP, &cpu_dev, "RDYQ_Put queue FULL count %02x\n", num);
return -1; /* RDYQ Full */
}
RDYQ[RDYQIN] = entry; /* add new entry */
RDYQIN += 1; /* next entry */
RDYQIN %= RDYQ_SIZE; /* modulo RDYQ size */
// num = (RDYQIN - RDYQOUT + RDYQ_SIZE) % RDYQ_SIZE; /* number of entries */
// sim_debug(DEBUG_XIO, &cpu_dev, "RDYQ_Put entry %04x count %02x\n", entry, num);
irq_pend = 1; /* do a scan */
//XXwaitrdyq = 10; /* UTX21A installs with this, but diags hang */
//ZZwaitrdyq = 8;
//XXwaitrdyq = 5;
// waitrdyq = 2;
//XXwaitrdyq = 2;
waitrdyq = 1; /* wait at least 1 instruction */
return SCPE_OK; /* all OK */
}
@ -230,7 +220,6 @@ int32 RDYQ_Put(uint32 entry)
/* get the next entry from the RDYQ */
int32 RDYQ_Get(uint32 *old)
{
// int32 num; /* number of entries */
/* see if the RDYQ is empty */
if (RDYQIN == RDYQOUT) {
return -1; /* RDYQ is empty, tell caller */
@ -238,8 +227,6 @@ int32 RDYQ_Get(uint32 *old)
*old = RDYQ[RDYQOUT]; /* get the next entry */
RDYQOUT += 1; /* next entry */
RDYQOUT %= RDYQ_SIZE; /* modulo RDYQ size */
// num = (RDYQIN - RDYQOUT + RDYQ_SIZE) % RDYQ_SIZE; /* number of entries */
// sim_debug(DEBUG_XIO, &cpu_dev, "RDYQ_Get entry %04x leaving %02x\n", *old, num);
return SCPE_OK; /* all OK */
}
@ -248,8 +235,6 @@ int32 RDYQ_Num(void)
{
/* calc entries */
int32 num = (RDYQIN - RDYQOUT + RDYQ_SIZE) % RDYQ_SIZE; /* number of entries */
// sim_debug(DEBUG_XIO, &cpu_dev, "RDYQ_Num entres %04x\n", num);
// return ((RDYQIN - RDYQOUT + RDYQ_SIZE) % RDYQ_SIZE);
return num;
}
@ -271,14 +256,12 @@ int32 IOCLQ_Put(IOCLQ *qptr, uint32 entry)
qptr->ioclq_in += 1; /* next entry */
qptr->ioclq_in %= IOCLQ_SIZE; /* modulo IOCLQ size */
num = (qptr->ioclq_in - qptr->ioclq_out + IOCLQ_SIZE) % IOCLQ_SIZE;
// sim_debug(DEBUG_XIO, &cpu_dev, "IOCLQ_Put entry %06x count %02x\n", entry, num);
return SCPE_OK; /* all OK */
}
/* get the next entry from the IOCLQ */
int32 IOCLQ_Get(IOCLQ *qptr, uint32 *old)
{
// int32 num; /* number of entries */
if (qptr == NULL) {
sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Get ERROR NULL qptr\n");
return -1; /* IOCLQ address error */
@ -286,14 +269,12 @@ int32 IOCLQ_Get(IOCLQ *qptr, uint32 *old)
/* see if the IOCLQ is empty */
if (qptr->ioclq_in == qptr->ioclq_out) {
sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Get IOCLQ empty\n");
// sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Get IOCLQ empty\n");
return -1; /* IOCLQ is empty, tell caller */
}
*old = qptr->ioclq_fifo[qptr->ioclq_out]; /* get the next entry */
qptr->ioclq_out += 1; /* next entry */
qptr->ioclq_out %= IOCLQ_SIZE; /* modulo IOCLQ size */
// num = (qptr->ioclq_in - qptr->ioclq_out + IOCLQ_SIZE) % IOCLQ_SIZE;
// sim_debug(DEBUG_XIO, &cpu_dev, "IOCLQ_Get entry %06x leaving %02x entries\n", *old, num);
return SCPE_OK; /* all OK */
}
@ -307,7 +288,6 @@ int32 IOCLQ_Num(IOCLQ *qptr)
}
/* calc entries */
num = (qptr->ioclq_in - qptr->ioclq_out + IOCLQ_SIZE) % IOCLQ_SIZE;
// sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Num #entries %02x\n", num);
return num; /* one words/entry */
}
@ -321,16 +301,11 @@ t_stat set_inch(UNIT *uptr, uint32 inch_addr) {
DIB *dibp = dib_chan[chan>>8]; /* get channel dib ptr */
CHANP *pchp = 0; /* for channel prog ptr */
sim_debug(DEBUG_XIO, &cpu_dev,
"set_inch chan %04x inch addr %06x dibp %p\n", chan, inch_addr, dibp);
/* must be valid DIB pointer */
if (dibp == NULL)
return SCPE_MEM; /* return memory error */
pchp = dibp->chan_prg; /* get parent channel prog ptr */
sim_debug(DEBUG_XIO, &cpu_dev,
"set_inch chan %04x inch addr %06x pchp %p\n", chan, inch_addr, pchp);
/* must be valid channel pointer */
if (pchp == NULL)
return SCPE_MEM; /* return memory error */
@ -348,6 +323,7 @@ t_stat set_inch(UNIT *uptr, uint32 inch_addr) {
sim_debug(DEBUG_XIO, &cpu_dev,
"set_inch chan %04x inch addr %06x chp %p\n", chan, inch_addr, chp);
/* now go through all the sub addresses for the channel and set inch addr */
for (i=0; i<SUB_CHANS; i++) {
chsa = chan | i; /* merge sa to real channel */
@ -380,11 +356,6 @@ uint32 find_int_lev(uint16 chsa)
return 0; /* not found */
}
inta = ((~spadent)>>16)&0x7f; /* get interrupt level */
// sim_debug(DEBUG_IRQ, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"find_int_lev class F SPADC %08x chsa %04x lev %02x SPADI %08x INTS %08x\n",
spadent, chsa, inta, SPAD[inta+0x80], INTS[inta]);
return(inta); /* return the level*/
}
@ -414,10 +385,6 @@ uint32 find_int_icb(uint16 chsa)
"find_int_icb ERR chsa %04x icba %02x\n", chsa, icba);
return 0; /* not found */
}
// sim_debug(DEBUG_IRQ, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"find_int_icb icba %06x SPADC %08x chsa %04x lev %02x SPADI %08x INTS %08x\n",
icba, spadent, chsa, inta, SPAD[inta+0x80], INTS[inta]);
return(icba); /* return the address */
}
@ -448,8 +415,6 @@ UNIT *find_unit_ptr(uint16 chsa)
}
uptr++; /* next unit */
}
sim_debug(DEBUG_EXP, &cpu_dev,
"find_unit_ptr ERR chsa %04x no match uptr %p\n", chsa, uptr);
return NULL; /* device not found on system */
}
@ -463,20 +428,17 @@ CHANP *find_chanp_ptr(uint16 chsa)
dibp = dib_unit[chsa]; /* get DIB pointer from unit address */
if (dibp == 0) { /* if zero, not defined on system */
sim_debug(DEBUG_EXP, &cpu_dev,
"find_chanp_ptr ERR chsa %04x dibp %p\n", chsa, dibp);
sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x dibp %p\n", chsa, dibp);
return NULL; /* tell caller */
}
if ((chp = (CHANP *)dibp->chan_prg) == NULL) { /* must have channel information for each device */
sim_debug(DEBUG_EXP, &cpu_dev,
"find_chanp_ptr ERR chsa %04x chp %p\n", chsa, chp);
sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x chp %p\n", chsa, chp);
return NULL; /* tell caller */
}
uptr = dibp->units; /* get the pointer to the units on this channel */
if (uptr == 0) { /* if zero, no devices defined on system */
sim_debug(DEBUG_EXP, &cpu_dev,
"find_chanp_ptr ERR chsa %04x uptr %p\n", chsa, uptr);
sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x uptr %p\n", chsa, uptr);
return NULL; /* tell caller */
}
@ -487,8 +449,7 @@ CHANP *find_chanp_ptr(uint16 chsa)
uptr++; /* next UNIT */
chp++; /* next CHANP */
}
sim_debug(DEBUG_EXP, &cpu_dev,
"find_chanp_ptr ERR chsa %04x no match uptr %p\n", chsa, uptr);
sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x no match uptr %p\n", chsa, uptr);
return NULL; /* device not found on system */
}
@ -507,14 +468,6 @@ int readfull(CHANP *chp, uint32 maddr, uint32 *word)
}
*word = RMW(maddr); /* get 1 word */
sim_debug(DEBUG_XIO, &cpu_dev, "READFULL read %08x from addr %08x\n", *word, maddr);
#if 0
#define DO_DYNAMIC_DEBUG
#ifdef DO_DYNAMIC_DEBUG
if (maddr == 0x1aaf4 && *word == 0x017deda5) {
cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
}
#endif
#endif
return 0; /* return OK */
}
@ -532,8 +485,6 @@ int readbuff(CHANP *chp)
"readbuff PCHK addr %08x to big mem %08x status %04x\n",
addr, MEMSIZE, chp->chan_status);
chp->chan_byte = BUFF_CHNEND; /* force channel end & busy */
//sim_debug(DEBUG_EXP, &cpu_dev,
//"readbuff BUFF_CHNEND chp %p chan_byte %04x\n", chp, chp->chan_byte);
return 1; /* done, with error */
}
chp->chan_buf = RMB(addr&MASK24); /* get 1 byte */
@ -554,13 +505,10 @@ int writebuff(CHANP *chp)
"writebuff PCHK addr %08x to big mem %08x status %04x\n",
addr, MEMSIZE, chp->chan_status);
chp->chan_byte = BUFF_CHNEND; /* force channel end & busy */
//sim_debug(DEBUG_EXP, &cpu_dev,
//"writebuff BUFF_CHNEND chp %p chan_byte %04x\n", chp, chp->chan_byte);
return 1;
}
addr &= MASK24; /* good address, write the byte */
sim_debug(DEBUG_DATA, &cpu_dev,
"writebuff WRITE addr %06x DATA %08x status %04x\n",
sim_debug(DEBUG_DATA, &cpu_dev, "writebuff WRITE addr %06x DATA %08x status %04x\n",
addr, chp->chan_buf, chp->chan_status);
WMB(addr, chp->chan_buf); /* write byte to memory */
return 0;
@ -579,14 +527,14 @@ int32 load_ccw(CHANP *chp, int32 tic_ok)
uint16 chan = get_chan(chp->chan_dev); /* our channel */
uint16 devstat = 0;
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_XIO, &cpu_dev,
"load_ccw @%06x entry chan_status[%04x] %04x\n", chp->chan_caw, chan, chp->chan_status);
/* determine if channel DIB has a pre iocl processor */
if (dibp->iocl_io != NULL) { /* NULL if no function */
/* call the device controller to process the iocl */
int32 tempa = dibp->iocl_io(chp, tic_ok); /* process IOCL */
if (tempa != SCPE_OK) { /* see if OK */
sim_debug(DEBUG_XIO, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"load_ccw iocl_io call return ERROR chan %04x cstat %01x\n", chan, tempa);
} else {
sim_debug(DEBUG_XIO, &cpu_dev,
@ -609,7 +557,7 @@ int32 load_ccw(CHANP *chp, int32 tic_ok)
}
loop:
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_XIO, &cpu_dev,
"load_ccw @%06x entry chan_status[%04x] %04x\n", chp->chan_caw, chan, chp->chan_status);
/* Abort if we have any errors */
@ -619,14 +567,6 @@ loop:
return 1;
}
#ifdef DONOTUSETHIS
/* Check if we have status modifier set */
if (chp->chan_status & STATUS_MOD) {
chp->chan_caw += 8; /* move to next IOCD */
chp->chan_status &= ~STATUS_MOD; /* turn off status modifier flag */
}
#endif
/* Read in first CCW */
if (readfull(chp, chp->chan_caw, &word1) != 0) { /* read word1 from memory */
chp->chan_status |= STATUS_PCHK; /* memory read error, program check */
@ -654,7 +594,7 @@ loop:
/* if we did, use previous cmd value */
if (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */
(chp->ccw_flags & FLAG_DC)) { /* last IOCD have DC set? */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_XIO, &cpu_dev,
"ec_iocl @%06x DO DC, ccw_flags %04x cmd %02x\n",
chp->chan_caw, chp->ccw_flags, chp->ccw_cmd);
} else
@ -662,42 +602,17 @@ loop:
if (!MEM_ADDR_OK(word1 & MASK24)) { /* see if memory address invalid */
chp->chan_status |= STATUS_PCHK; /* bad, program check */
//** uptr->SNS |= SNS_INAD; /* invalid address status */
sim_debug(DEBUG_EXP, &cpu_dev,
"load_ccw bad IOCD1 chan_status[%04x] %04x\n", chan, chp->chan_status);
return 1; /* error return */
}
#ifdef PROVIDE_FOR_EACH_DEVICE
/* validate the commands for the disk */
switch (chp->ccw_cmd) {
case DSK_WD: case DSK_RD: case DSK_INCH: case DSK_NOP: case DSK_ICH:
case DSK_SCK: case DSK_XEZ: case DSK_LMR: case DSK_WSL: case DSK_RSL:
case DSK_IHA: case DSK_WTL: case DSK_RTL: case DSK_RAP: case DSK_TESS:
case DSK_FNSK:
/* reset status to on cyl & ready */
// uptr->SNS2 = (SNS_UNR|SNS_ONC|SNS_USEL);
uptr->SNS2 = 0;
case DSK_SNS:
break;
default:
chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */
uptr->SNS |= SNS_CMDREJ; /* cmd rejected */
sim_debug(DEBUG_EXP, &cpu_dev,
"disk_iocl bad cmd chan_status[%04x] %04x\n", chan, chp->chan_status);
return 1; /* error return */
}
#endif
chp->ccw_count = word2 & 0xffff; /* get 16 bit byte count from IOCD WD 2*/
if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */
//** /* 1st command can not be a TIC or NOP */
//** if ((chp->ccw_cmd == 0x03) || (chp->ccw_cmd == CMD_TIC)) {
/* 1st command can not be a TIC */
if (chp->ccw_cmd == CMD_TIC) {
chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */
//** uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */
sim_debug(DEBUG_EXP, &cpu_dev,
"load_ccw TIC/NOP bad cmd chan_status[%04x] %04x\n",
chan, chp->chan_status);
@ -715,8 +630,6 @@ loop:
chan, chp->chan_caw, word1);
chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */
chp->chan_caw = word1 & MASK24; /* get new IOCD address */
//** uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */
//** uptr->SNS |= SNS_INAD; /* invalid address status */
return 1; /* error return */
}
tic_ok = 0; /* another tic not allowed */
@ -728,9 +641,6 @@ loop:
}
chp->chan_caw = word1 & MASK24; /* get new IOCD address */
chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */
//** uptr->SNS |= SNS_CMDREJ; /* cmd rejected status */
//** if (((word1 & MASK24) == 0) || (word1 & 0x3))
//** uptr->SNS |= SNS_INAD; /* invalid address status */
sim_debug(DEBUG_EXP, &cpu_dev,
"load_ccw TIC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status);
return 1; /* error return */
@ -764,18 +674,15 @@ loop:
return 1; /* error return */
}
#ifndef NOT_FOR_EVERYONE
/* DC can only be used with a read/write cmd */
if (chp->ccw_flags & FLAG_DC) {
if ((chp->ccw_cmd != 0x02) && (chp->ccw_cmd != 0x01)) {
chp->chan_status |= STATUS_PCHK; /* program check for invalid DC */
//** uptr->SNS |= SNS_CHER; /* chaining error */
sim_debug(DEBUG_EXP, &cpu_dev,
"disk_iocl DC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status);
return 1; /* error return */
}
}
#endif
chp->chan_byte = BUFF_BUSY; /* busy & no bytes transferred yet */
@ -826,7 +733,7 @@ loop:
"load_ccw continue wait chsa %04x status %08x\n",
chp->chan_dev, chp->chan_status);
}
/*0816*/ } else
} else
/* NOTE this code needed for MPX 1.X to run! */
/* see if command completed */
@ -866,8 +773,6 @@ int chan_read_byte(uint16 chsa, uint8 *data)
if (chp->ccw_count == 0) { /* see if more data required */
if ((chp->ccw_flags & FLAG_DC) == 0) { /* see if Data Chain */
chp->chan_byte = BUFF_CHNEND; /* buffer end too */
//sim_debug(DEBUG_EXP, &cpu_dev,
//"chan_read BUFF_CHNEND chp %p chan_byte %04x\n", chp, chp->chan_byte);
sim_debug(DEBUG_XIO, &cpu_dev,
"chan_read_byte no DC chan end, cnt %04x addr %06x chan %04x\n",
chp->ccw_count, chp->ccw_addr, chan);
@ -909,8 +814,6 @@ int test_write_byte_end(uint16 chsa)
if (chp->ccw_count == 0) {
if ((chp->ccw_flags & FLAG_DC) == 0) { /* see if we have data chaining */
chp->chan_byte = BUFF_CHNEND; /* thats all the data we want */
//sim_debug(DEBUG_EXP, &cpu_dev,
//"test_write_byte BUFF_CHNEND chp %p chan_byte %04x\n", chp, chp->chan_byte);
return 1; /* return done */
}
}
@ -956,8 +859,6 @@ int chan_write_byte(uint16 chsa, uint8 *data)
return 1; /* return done error */
} else {
/* we have data chaining, process iocl */
sim_debug(DEBUG_DETAIL, &cpu_dev,
"chan_write_byte got DC, calling load_ccw chan %04x\n", chan);
if (load_ccw(chp, 1)) { /* process data chaining */
sim_debug(DEBUG_EXP, &cpu_dev,
"chan_write_byte with DC error, cnt %04x addr %06x chan %04x\n",
@ -1044,14 +945,9 @@ void chan_end(uint16 chsa, uint16 flags) {
chsa, flags, chp->chan_status, chp->ccw_cmd);
chp->chan_byte = BUFF_BUSY; /* we are empty & still busy now */
//sim_debug(DEBUG_EXP, &cpu_dev, "chan_end1 BUFF_BUSY chp %p chan_byte %04x\n", chp, chp->chan_byte);
chp->chan_status |= STATUS_CEND; /* set channel end */
chp->chan_status |= ((uint16)flags); /* add in the callers flags */
sim_debug(DEBUG_DETAIL, &cpu_dev,
"chan_end SLI test1 chsa %04x ccw_flags %04x count %04x status %04x\n",
chsa, chp->ccw_flags, chp->ccw_count, chp->chan_status);
/* read/write must have none-zero byte count */
/* all others can be zero, except NOP, which must be 0 */
/* a NOP is Control command 0x03 with no modifier bits */
@ -1068,10 +964,6 @@ void chan_end(uint16 chsa, uint16 flags) {
}
}
sim_debug(DEBUG_DETAIL, &cpu_dev,
"chan_end SLI2 test chsa %04x ccw_flags %04x status %04x\n",
chsa, chp->ccw_flags, chp->chan_status);
/* Diags do not want SLI if we have no device end status */
if ((chp->chan_status & STATUS_LENGTH) && ((chp->chan_status & STATUS_DEND) == 0))
chp->chan_status &= ~STATUS_LENGTH;
@ -1293,8 +1185,6 @@ t_stat checkxio(uint16 lchsa, uint32 *status) {
uint32 spadent;
uint16 rchan, rchsa; /* the real channel number */
sim_debug(DEBUG_DETAIL, &cpu_dev, "checkxio entry lchsa %04x\n", lchsa);
/* get the device entry for the logical channel in SPAD */
spadent = SPAD[lchan]; /* get spad device entry for logical channel */
rchan = (spadent & 0x7f00) >> 8; /* get real channel */
@ -1316,16 +1206,21 @@ nothere:
}
inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */
chp->chan_int = inta; /* make sure it is set in channel */
dptr = get_dev(uptr); /* pointer to DEVICE structure */
/* check for the device being defined and attached in simh */
if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) {
sim_debug(DEBUG_EXP, &cpu_dev,
"checkxio lchsa %04x rchsa %04x is not attached, CC3 return\n", lchsa, rchsa);
*status = CC3BIT; /* not attached, so error CC3 */
/* UTX wants CC1 on "mt offline" call. If not, UTX loops forever */
if ((dptr != NULL) &&
(DEV_TYPE(dptr) == DEV_TAPE)) /* see if this is a tape */
*status = CC1BIT; /* CCs = 1, not busy */
else
*status = CC3BIT; /* not attached, so error CC3 */
return SCPE_OK; /* not found, CC3 */
}
dptr = get_dev(uptr); /* pointer to DEVICE structure */
/* try this as MFP says it returns 0 on OK */
if (dptr->flags & DEV_CHAN)
*status = 0; /* CCs = 0, OK return */
@ -1379,8 +1274,6 @@ t_stat startxio(uint16 lchsa, uint32 *status) {
#endif
DEVICE *dptr;
sim_debug(DEBUG_XIO, &cpu_dev, "startxio entry logical chsa %04x\n", lchsa);
/* get the device entry for the logical channel in SPAD */
spadent = SPAD[lchan]; /* get spad device entry for logical channel */
inta = ((~spadent)>>16)&0x7f; /* get interrupt level */
@ -1434,16 +1327,15 @@ missing:
chsa, chp, (uptr->flags & UNIT_ATTABLE)?1:0, (uptr->flags & UNIT_ATT)?1:0,
(uptr->flags & UNIT_DIS)?1:0);
if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0) &&
(uptr->flags & UNIT_SUBCHAN) == 0) { /* is unit attached? */
/* is unit marked disabled? */
if ((uptr->flags & UNIT_DIS) == 1) {
sim_debug(DEBUG_EXP, &cpu_dev,
"startxio chsa %04x device not present, CC3 returned flags %08x\n", chsa, uptr->flags);
"startxio chsa %04x device disabled, CC3 returned flags %08x\n", chsa, uptr->flags);
*status = CC3BIT; /* not attached, so error CC3 */
return SCPE_OK; /* not found, CC3 */
}
#ifdef FOR_DEBUG
// inta = find_int_lev(chsa); /* Interrupt Level for channel */
if ((INTS[inta]&INTS_ACT) || (SPAD[inta+0x80]&SINT_ACT)) { /* look for level active */
/* just output a warning */
sim_debug(DEBUG_XIO, &cpu_dev,
@ -1478,7 +1370,6 @@ missing:
}
}
// chan_icb = find_int_icb(chsa); /* Interrupt level context block address */
sim_debug(DEBUG_XIO, &cpu_dev,
"startxio int spad %08x icb %06x inta %02x chan %04x\n",
SPAD[inta+0x80], chan_icb, inta, chan);
@ -1487,7 +1378,6 @@ missing:
/* before calling load_ccw which does it again for each IOCL step */
iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */
word1 = RMW(iocla & MASK24); /* get 1st IOCL word */
// incha = word1 & MASK24; /* should be inch addr */
word2 = RMW((iocla + 4) & MASK24); /* get 2nd IOCL word */
cmd = (word1 >> 24) & 0xff; /* get channel cmd from IOCL */
chp = find_chanp_ptr(chsa&0x7f00); /* find the parent chanp pointer */
@ -1504,7 +1394,6 @@ missing:
chsa, iocla, RMW(iocla), RMW(iocla+4));
iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */
// incha = chp->chan_inch_addr; /* get inch address */
sim_debug(DEBUG_CMD, &cpu_dev, "$$$ SIO %04x %04x cmd %02x ccw_flags %04x\n",
chsa, chan, cmd, word2>>16);
@ -1586,8 +1475,6 @@ missing:
/* 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_EXP, &cpu_dev,
"startxio BUFF_NEXT chp %p chan_byte %04x\n", chp, chp->chan_byte);
RDYQ_Put(chsa); /* queue us up */
sim_debug(DEBUG_XIO, &cpu_dev,
"$$$ SIO queued chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n",
@ -1597,8 +1484,8 @@ missing:
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 */
waitqcnt = 25; /* 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 */
*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",
@ -1623,8 +1510,6 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */
rchsa = (spadent & 0x7f00); /* get real channel suba of zero */
rchan = rchsa >> 8; /* get real channel */
sim_debug(DEBUG_XIO, &cpu_dev, "$$ TIO entry lchsa %04x rchsa %02x\n", lchsa, rchsa);
/* get the device entry for the channel in SPAD */
dibp = dib_chan[rchan]; /* get the DIB pointer */
chp = find_chanp_ptr(rchan << 8); /* find the device chanp pointer */
@ -1693,9 +1578,7 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */
}
/* nothing going on, so say all OK */
// *status = CC1BIT; /* request accepted, no status, so CC1 */
WMW(chan_icb+20, 0); /* post sw addr 0 in ICB+5w & reset CCs */
// *status = 0; /* no status stored from TIO, so no CC */
*status = CC1BIT; /* request accepted, no status, so CC1 */
INTS[inta] &= ~INTS_REQ; /* clear any level request if no status */
sim_debug(DEBUG_XIO, &cpu_dev,
@ -1720,8 +1603,6 @@ t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */
rchan = (spadent & 0x7f00) >> 8; /* get real channel */
rchsa = (rchan << 8) | (lchsa & 0xff); /* get the read chan & suba */
sim_debug(DEBUG_XIO, &cpu_dev, "STPIO entry lchsa %04x rchsa %04x\n", lchsa, rchsa);
/* get the device entry for the logical channel in SPAD */
dibp = dib_unit[rchsa]; /* get the DIB pointer */
chp = find_chanp_ptr(rchsa); /* find the device chanp pointer */
@ -1746,16 +1627,11 @@ t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */
chp->chan_int = inta; /* make sure it is set in channel */
itva = SPAD[0xf1] + (inta<<2); /* int vector address */
chan_icb = RMW(itva); /* Interrupt context block addr */
// chan_icb = find_int_icb(chsa); /* Interrupt level context block address */
// inta = find_int_lev(chsa); /* Interrupt Level for channel */
iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */
sim_debug(DEBUG_CMD, &cpu_dev,
"STPIO busy test rchsa %04x cmd %02x ccw_flags %04x IOCD1 %08x IOCD2 %08x\n",
rchsa, chp->ccw_cmd, chp->ccw_flags, M[iocla>>2], M[(iocla+4)>>2]);
sim_debug(DEBUG_CMD, &cpu_dev, "$$$ STPIO %04x %02x %04x\n",
rchsa, chp->ccw_cmd, chp->ccw_flags);
if ((chp->chan_byte & BUFF_BUSY) == 0) {
/* the channel is not busy, so return OK */
*status = CC1BIT; /* request accepted, no status, so CC1 */
@ -1791,9 +1667,8 @@ t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */
"$$$ STOPXIO END2 rchsa %04x rchan %04x cmd %02x ccw_flags %04x status %04x\n",
rchsa, rchan, chp->ccw_cmd, chp->ccw_flags, *status);
/* change status from BUFF_POST to BUFF_DONE */
/*082420*/ if (chp->chan_byte == BUFF_POST) {
/*082420*/ chp->chan_byte = BUFF_DONE; /* show done & not busy */
//sim_debug(DEBUG_EXP, &cpu_dev, "STPIO BUFF_DONE1 chp %p chan_byte %04x\n", chp, chp->chan_byte);
if (chp->chan_byte == BUFF_POST) {
chp->chan_byte = BUFF_DONE; /* show done & not busy */
}
return SCPE_OK; /* CC2 & all OK */
}
@ -1807,9 +1682,6 @@ t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */
return SCPE_OK; /* CC1 & all OK */
}
}
/* the device is not busy, so cmd has not started */
sim_debug(DEBUG_EXP, &cpu_dev,
"STPIO BUFF_DONE2 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 */
sim_debug(DEBUG_CMD, &cpu_dev,
@ -1822,8 +1694,6 @@ t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */
/* set the return to CC3BIT & CC4BIT causes infinite loop in MPX1X */
/* restore code to old CC1BIT return 12/21/2020 */
*status = CC1BIT; /* request accepted, no status, so CC1 */
// *status = CC4BIT; /*1204*/ /* device is busy, so CC4 */
// *status = CC3BIT|CC4BIT; /*1204*/ /* device is busy, so CC3 & CC4 */
/* reset the DC or CC bits to force completion after current IOCD */
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */
sim_debug(DEBUG_CMD, &cpu_dev,
@ -1848,8 +1718,6 @@ t_stat rschnlxio(uint16 lchsa, uint32 *status) { /* reset channel XIO */
rchan = (spadent & 0x7f00) >> 8; /* get real channel */
rchsa = rchan << 8; /* get the real chan & zero suba */
sim_debug(DEBUG_XIO, &cpu_dev, "rschnlxio entry lchan %04x rchan %04x\n", lchan, rchan);
/* get the device entry for the logical channel in SPAD */
dibp = dib_unit[rchsa]; /* get the channel device information pointer */
chp = find_chanp_ptr(rchsa); /* find the channel chanp pointer */
@ -1892,10 +1760,9 @@ t_stat rschnlxio(uint16 lchsa, uint32 *status) { /* reset channel XIO */
chp = find_chanp_ptr(rchsa); /* find the chanp pointer */
if (chp == 0)
continue; /* not used */
/*0202*/uptr = chp->unitptr; /* get the unit ptr */
uptr = chp->unitptr; /* get the unit ptr */
/* see if we have a rschnl device entry */
//sim_debug(DEBUG_EXP, &cpu_dev, "rschnlxio dib->rschnl_io %p\n", dibp->rschnl_io);
if (dibp->rschnl_io != NULL) { /* NULL if no rschnl_io function */
/* call the device controller to process rschnl */
j = dibp->rschnl_io(uptr); /* get status from device */
@ -1904,7 +1771,6 @@ t_stat rschnlxio(uint16 lchsa, uint32 *status) { /* reset channel XIO */
}
chp->chan_status = 0; /* clear the channel status */
chp->chan_byte = BUFF_EMPTY; /* no data yet */
//sim_debug(DEBUG_EXP, &cpu_dev, "rschnlxio BUFF_EMPTY chp %p rchsa %04x\n", chp, rchsa);
chp->ccw_addr = 0; /* clear buffer address */
chp->chan_caw = 0x0; /* clear IOCD address */
chp->ccw_count = 0; /* channel byte count 0 bytes*/
@ -1955,16 +1821,12 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
/* the haltio opcode processing software has already checked for F class */
inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */
chp->chan_int = inta; /* make sure it is set in channel */
// inta = ((spadent & 0x007f0000) >> 16); /* 1's complement of chan int level */
// inta = 127 - inta; /* get positive int level */
// spadent = SPAD[inta + 0x80]; /* get interrupt spad entry */
sim_debug(DEBUG_XIO, &cpu_dev, "HIO int spad %08x inta %02x rchan %02x\n", spadent, inta, rchan);
/* get the address of the interrupt IVL in main memory */
itva = SPAD[0xf1] + (inta<<2); /* int vector address */
chan_icb = RMW(itva); /* Interrupt context block addr */
iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */
// incha = RMW(chan_icb+20); /* post inch addr in ICB+5w */
sim_debug(DEBUG_XIO, &cpu_dev,
"$$ HIO busy test byte %02x rchsa %04x cmd %02x ccw_flags %04x IOCD1 %08x IOCD2 %08x\n",
@ -1996,8 +1858,8 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
"$$$ 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 */
/*082420*/ if (chp->chan_byte == BUFF_POST) {
/*082420*/ chp->chan_byte = BUFF_DONE; /* show done & not busy */
if (chp->chan_byte == BUFF_POST) {
chp->chan_byte = BUFF_DONE; /* show done & not busy */
sim_debug(DEBUG_EXP, &cpu_dev,
"HIO BUFF_DONE1 chp %p chan_byte %04x\n", chp, chp->chan_byte);
}
@ -2007,8 +1869,6 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
chp->ccw_count = 0; /* zero the count */
/* The diags want the interrupt for the disk */
*status = CC1BIT; /* request accepted, no status, so CC1 */
//BAD *status = CC4BIT; /* request accepted, no status, so CC1 */
//BAD *status = 0; /* request accepted, no status, so CC1 */
sim_debug(DEBUG_CMD, &cpu_dev,
"$$$ HIO END2 ECHO rchsa %04x cmd %02x ccw_flags %04x status %04x\n",
rchsa, chp->ccw_cmd, chp->ccw_flags, *status);
@ -2045,14 +1905,12 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
sim_debug(DEBUG_CMD, &cpu_dev,
"$$$ HIO END1 not busy return rchsa %04x cmd %02x ccw_flags %04x status %04x\n",
rchsa, chp->ccw_cmd, chp->ccw_flags, *status);
#ifndef JUNK
#ifndef MAYBE_NOT
chp->chan_byte = BUFF_DONE; /* we are done */
sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
/*1204*/chp->chan_status = (STATUS_DEND|STATUS_CEND|STATUS_EXPT);
chp->chan_status = (STATUS_DEND|STATUS_CEND|STATUS_EXPT);
store_csw(chp); /* store the status */
/* change chan_byte to BUFF_POST */
chp->chan_byte = BUFF_POST; /* show done with data */
//sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_POST chp %p chan_byte %04x\n", chp, chp->chan_byte);
chp->chan_status = 0; /* no status anymore */
chp->ccw_cmd = 0; /* no command anymore */
irq_pend = 1; /* flag to test for int condition */
@ -2069,8 +1927,6 @@ sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE chp %p chan_byte %04x\n", chp,
/* reset the DC or CC bits to force completion */
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */
chp->chan_byte = BUFF_BUSY; /* wait for post_csw to be done */
//sim_debug(DEBUG_EXP, &cpu_dev, "HIO BUFF_DONE3 chp %p chan_byte %04x\n", chp, chp->chan_byte);
// chp->ccw_count = 0; /* zero the count */
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 */
@ -2085,15 +1941,13 @@ sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE chp %p chan_byte %04x\n", chp,
"$$$ HIO END4 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 */
/*082420*/ if (chp->chan_byte == BUFF_POST) {
/*082420*/ chp->chan_byte = BUFF_DONE; /* show done & not busy */
//sim_debug(DEBUG_EXP, &cpu_dev, "HIO BUFF_DONE4 chp %p chan_byte %04x\n", chp, chp->chan_byte);
if (chp->chan_byte == BUFF_POST) {
chp->chan_byte = BUFF_DONE; /* show done & not busy */
}
return SCPE_OK; /* CC2 & all OK */
}
}
chp->chan_byte = BUFF_DONE; /* chan prog done */
sim_debug(DEBUG_EXP, &cpu_dev, "HIO BUFF_DONE5 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 */
sim_debug(DEBUG_CMD, &cpu_dev,
@ -2117,8 +1971,6 @@ t_stat grabxio(uint16 lchsa, uint32 *status) { /* grab controller XIO n/u *
rchan = (spadent & 0x7f00) >> 8; /* get real channel */
rchsa = (rchan << 8) | (lchsa & 0xff); /* merge sa to real channel */
sim_debug(DEBUG_XIO, &cpu_dev, "GRIO entry lchsa %04x rchsa %04x\n", lchsa, rchsa);
/* get the device entry for the logical channel in SPAD */
dibp = dib_unit[rchsa]; /* get the DIB pointer */
chp = find_chanp_ptr(rchsa); /* find the device chanp pointer */
@ -2152,8 +2004,6 @@ t_stat grabxio(uint16 lchsa, uint32 *status) { /* grab controller XIO n/u *
/* returning No CC's causes MPX1X to loop forever */
/* so restore returning CC1 */
*status = 0; /* return no CC's */
// *status = CC1BIT; /* return no CC's */
// *status = CC3BIT|CC4BIT; /* busy */
} else {
/* diags want unsupported transaction for disk */
*status = CC2BIT|CC4BIT; /* unsupported transaction */
@ -2236,7 +2086,6 @@ t_stat rsctlxio(uint16 lchsa, uint32 *status) { /* reset controller XIO */
}
chp->chan_status = 0; /* clear the channel status */
chp->chan_byte = BUFF_EMPTY; /* no data yet */
//sim_debug(DEBUG_EXP, &cpu_dev, "rsctlxio BUFF_EMPTY chp %p chan_byte %04x\n", chp, chp->chan_byte);
chp->ccw_addr = 0; /* clear buffer address */
chp->chan_caw = 0x0; /* clear IOCD address */
chp->ccw_count = 0; /* channel byte count 0 bytes*/
@ -2289,7 +2138,6 @@ t_stat chan_boot(uint16 chsa, DEVICE *dptr) {
chp->chan_status = 0; /* clear the channel status */
chp->chan_dev = chsa; /* save our address (ch/sa) */
chp->chan_byte = BUFF_EMPTY; /* no data yet */
//sim_debug(DEBUG_EXP, &cpu_dev, "chan_boot BUFF_EMPTY chp %p chan_byte %04x\n", chp, chp->chan_byte);
chp->ccw_addr = 0; /* start loading at loc 0 */
chp->chan_caw = 0x0; /* set IOCD address to memory location 0 */
chp->ccw_count = 0; /* channel byte count 0 bytes*/
@ -2310,11 +2158,10 @@ t_stat chan_boot(uint16 chsa, DEVICE *dptr) {
/* start processing the boot IOCL at loc 0 */
if (load_ccw(chp, 0)) { /* load IOCL starting from location 0 */
sim_debug(DEBUG_XIO, &cpu_dev, "Channel Boot Error return from load_ccw chan %04x status %08x\n",
sim_debug(DEBUG_EXP, &cpu_dev, "Channel Boot Error return from load_ccw chan %04x status %08x\n",
chan, chp->chan_status);
chp->ccw_flags = 0; /* clear the command flags */
chp->chan_byte = BUFF_DONE; /* done with errors */
//sim_debug(DEBUG_EXP, &cpu_dev, "chan_boot BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
loading = 0; /* show we are done loading from the boot device */
return SCPE_IOERR; /* return error */
}
@ -2355,7 +2202,7 @@ uint32 cont_chan(uint16 chsa)
chsa, chp->chan_status);
/*NOTE*/ /* if we have an error, we would loop forever if the CC bit was set */
/* the only way to stop was to do a kill */
/*082320*/ chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */
/* DIAG's want CC1 with memory access error */
if (chp->chan_status & STATUS_PCHK) {
chp->chan_status &= ~STATUS_LENGTH; /* clear incorrect length */
@ -2429,12 +2276,8 @@ 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 */
/* now store the status dw address into word 5 of the ICB for the channel */
/* there is no icb when we are ipl booting, so skip this */
//NO_GOOD WMW(chan_icb+20, tempa|BIT1); /* post sw addr in ICB+5w & set CC2 in INCH addr */
#endif
chp->chan_byte = BUFF_DONE; /* we are done */
//sim_debug(DEBUG_EXP, &cpu_dev, "scan_chan BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
sim_debug(DEBUG_IRQ, &cpu_dev,
"LOADING %06x %04x FIFO #%1x read inch %06x sw1 %08x sw2 %08x\n",
chp->chan_caw, chan, FIFO_Num(chan), tempa, sw1|BIT1, sw2);
@ -2446,10 +2289,8 @@ uint32 scan_chan(uint32 *ilev) {
/* see if we are able to look for ints */
if (irq_pend == 0) /* pending int? */
return 0; /* no, done */
#ifndef TRY_121420_NOGOOD
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++) {
@ -2457,14 +2298,6 @@ uint32 scan_chan(uint32 *ilev) {
continue; /* skip this one */
if (SPAD[i+0x80] == 0xffffffff) /* not initialize? */
continue; /* skip this one */
/* this is a bug fix for MPX 1.x restart command */
// if (SPAD[i+0x80] == 0xefffffff) /* not initialize? */
// continue; /* skip this one */
#ifdef CAN_BE_DISABLED_090720
if ((INTS[i] & INTS_ENAB) == 0) /* ints must be enabled */
continue; /* skip this one */
#endif
if (INTS[i] & INTS_REQ) /* if already requesting, skip */
continue; /* skip this one */
@ -2483,7 +2316,7 @@ uint32 scan_chan(uint32 *ilev) {
sim_debug(DEBUG_EXP, &cpu_dev,
"scan_chan FIFO REQ FIFO #%1x irq %02x SPAD %08x INTS %08x\n",
FIFO_Num(SPAD[i+0x80] & 0x7f00), i, SPAD[i+0x80], INTS[i]);
/*1231*/ irq_pend = 1; /* we have pending interrupt */
irq_pend = 1; /* we have pending interrupt */
continue;
}
}
@ -2491,13 +2324,9 @@ uint32 scan_chan(uint32 *ilev) {
/* 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,
// sim_debug(DEBUG_IRQ, &cpu_dev,
"scan_chan waitqcnt %02x\n", waitqcnt);
sim_debug(DEBUG_DETAIL, &cpu_dev, "scan_chan waitqcnt %02x\n", waitqcnt);
if (CPUSTATUS & BIT24) /* interrupts blocked? */
sim_debug(DEBUG_DETAIL, &cpu_dev,
// sim_debug(DEBUG_IRQ, &cpu_dev,
"scan_chan INTS blocked!\n");
sim_debug(DEBUG_DETAIL, &cpu_dev, "scan_chan INTS blocked!\n");
goto tryme; /* needed for MPX */
}
@ -2511,8 +2340,7 @@ uint32 scan_chan(uint32 *ilev) {
if (SPAD[i+0x80] == 0xefffffff) /* not initialize? */
continue; /* skip this one */
if ((INTS[i]&INTS_ACT) || (SPAD[i+0x80]&SINT_ACT)) { /* look for level active */
// sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_IRQ, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"scan_chan INTS ACT irq %02x SPAD %08x INTS %08x\n",
i, SPAD[i+0x80], INTS[i]);
return 0; /* this level active, so stop looking */
@ -2527,8 +2355,7 @@ uint32 scan_chan(uint32 *ilev) {
if (((INTS[i] & INTS_ENAB) && (INTS[i] & INTS_REQ)) ||
((SPAD[i+0x80] & SINT_ENAB) && (INTS[i] & INTS_REQ))) {
// sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_IRQ, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"scan_chan highest int req irq %02x SPAD %08x INTS %08x\n",
i, SPAD[i+0x80], INTS[i]);
@ -2571,9 +2398,8 @@ uint32 scan_chan(uint32 *ilev) {
/* 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 */
/*082420*/ if (chp->chan_byte == BUFF_POST) {
/*082420*/ chp->chan_byte = BUFF_DONE; /* show done & not busy */
//sim_debug(DEBUG_EXP, &cpu_dev, "scan_chanx BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
if (chp->chan_byte == BUFF_POST) {
chp->chan_byte = BUFF_DONE; /* show done & not busy */
}
} else {
sim_debug(DEBUG_IRQ, &cpu_dev,
@ -2661,9 +2487,8 @@ t_stat chan_set_devs() {
continue;
if ((dptr->flags & DEV_DIS) || /* Skip disabled devices */
((dibp->chan_prg) == NULL)) { /* must have channel info for each device */
chsa = GET_UADDR(uptr->u3); /* ch/sa value */
// printf("Device %s chsa %04x not set up dibp %p\n", dptr->name, chsa, dibp);
//printf("Device %s chsa %04x not set up dibp %p\n", dptr->name, chsa, dibp);
continue;
}
@ -2671,14 +2496,13 @@ t_stat chan_set_devs() {
/* Check if address is in unit or dev entry */
for (j = 0; j < dptr->numunits; j++) { /* loop through unit entries */
chsa = GET_UADDR(uptr->u3); /* ch/sa value */
// printf("Setup device %s%d chsa %04x type %03d dibp %p\n",
// dptr->name, j, chsa, GET_TYPE(uptr->flags), dibp);
//printf("Setup device %s%d chsa %04x type %02x dibp %p\n",
//dptr->name, j, chsa, GET_TYPE(uptr->flags), dibp);
/* zero some channel data loc's for device */
chp->unitptr = uptr; /* set the unit back pointer */
chp->chan_status = 0; /* clear the channel status */
chp->chan_dev = chsa; /* save our address (ch/sa) */
chp->chan_byte = BUFF_EMPTY; /* no data yet */
//sim_debug(DEBUG_EXP, &cpu_dev, "chan_set_devs BUFF_EMPTY chp %p chan_byte %04x\n", chp, chp->chan_byte);
chp->ccw_addr = 0; /* start loading at loc 0 */
chp->chan_caw = 0; /* set IOCD address to memory location 0 */
chp->ccw_count = 0; /* channel byte count 0 bytes*/
@ -2694,10 +2518,10 @@ t_stat chan_set_devs() {
if (dptr->flags & DEV_CHAN) {
/* see if channel address already defined */
if (dib_chan[get_chan(chsa)] != 0) {
// printf("Channel mux %04x already defined, aborting\n", chsa);
//printf("Channel mux %04x already defined, aborting\n", chsa);
return SCPE_IERR; /* no, arg error */
}
// printf("Setting Channel mux %04x dibp %p\n", chsa, dibp);
//printf("Setting Channel mux %04x dibp %p\n", chsa, dibp);
/* channel mux, save dib for channel */
dib_chan[get_chan(chsa)] = dibp;
if (dibp->dev_ini != NULL) /* if there is an init routine, call it now */
@ -2705,13 +2529,13 @@ t_stat chan_set_devs() {
} else {
/* we have unit 0 of non-IOP/MFP device */
if (dib_unit[chsa] != 0) {
// printf("Channel/Dev %04x already defined\n", chsa);
//printf("Channel/Dev %04x already defined\n", chsa);
return SCPE_IERR; /* no, arg error */
} else {
/* channel mux, save dib for channel */
/* for now, save any zero dev as chan */
if (chsa) {
// printf("Setting Channel zero unit 0 device %04x dibp %p\n", chsa, dibp);
//printf("Setting Channel zero unit 0 device %04x dibp %p\n", chsa, dibp);
dib_unit[chsa] = dibp; /* no, save the dib address */
if (dibp->dev_ini != NULL) /* if there is an init routine, call it now */
dibp->dev_ini(uptr, 1); /* init the channel */
@ -2721,7 +2545,7 @@ t_stat chan_set_devs() {
} else {
/* see if address already defined */
if (dib_unit[chsa] != 0) {
// printf("Channel/SubAddress %04x multiple defined, aborting\n", chsa);
//printf("Channel/SubAddress %04x multiple defined, aborting\n", chsa);
return SCPE_IERR; /* no, arg error */
}
dib_unit[chsa] = dibp; /* no, save the dib address */
@ -2743,10 +2567,10 @@ t_stat chan_set_devs() {
if (dib_unit[i<<8]) {
/* write dibp to channel array */
dib_chan[i] = dib_unit[i<<8]; /* save the channel dib */
// printf("Chan_set_dev new Channel %04x defined at dibp %p\n", i<<8, dib_unit[i<<8]);
//printf("Chan_set_dev new Channel %04x defined at dibp %p\n", i<<8, dib_unit[i<<8]);
}
} else {
// printf("Chan_set_dev Channel %04x defined at dibp %p\n", i<<8, dib_chan[i]);
//printf("Chan_set_dev Channel %04x defined at dibp %p\n", i<<8, dib_chan[i]);
/* channel is defined, see if defined in dib_unit array */
if ((dib_unit[i<<8]) == 0) {
/* write dibp to units array */
@ -2767,49 +2591,58 @@ t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc) {
int i; /* temp */
int chsa, ochsa; /* dev addr */
// fprintf(stderr, "Set dev entry DEVICE ptr %s\r\n", cptr);
if (cptr == NULL) /* is there a UNIT name specified */
return SCPE_ARG; /* no, arg error */
if (uptr == NULL) /* is there a UNIT pointer */
return SCPE_IERR; /* no, arg error */
dptr = get_dev(uptr); /* find the device from unit pointer */
if (dptr == NULL) { /* device not found, so error */
fprintf(stderr, "Set dev no DEVICE ptr %s\r\n", cptr);
fprintf(stderr, "Set dev no DEVICE cptr %s\r\n", cptr);
//printf("Set dev no DEVICE ptr %s\r\n", cptr);
return SCPE_IERR; /* error */
}
//printf("Set dev DEVICE ptr %s\r\n", cptr);
dibp = (DIB *)dptr->ctxt; /* get dib pointer from device struct */
if (dibp == NULL) { /* we need a DIB */
fprintf(stderr, "Set dev no DIB ptr %s\r\n", cptr);
//printf("Set dev no DIB ptr %s\r\n", cptr);
return SCPE_IERR; /* no DIB, so error */
}
// fprintf(stderr, "Set dev new addr %s\r\n", cptr);
chan = get_uint(cptr, 16, 0xffff, &r); /* get new device address */
if (r != SCPE_OK) /* need good number */
return r; /* number error, return error */
chan &= 0x7f00; /* clean channel address */
//printf("Set new dev DEVICE ptr %s chan %04x\r\n", cptr, chan);
//ZZchan &= 0x7f00; /* clean channel address */
dibp->chan_addr = chan; /* set new parent channel addr */
// fprintf(stderr, "Set dev new addr %s chan %02x\r\n", cptr, chan);
/* change all the unit addresses with the new channel, but keep sub address */
/* Clear out existing entries for all units on this device */
tuptr = dptr->units; /* get pointer to units defined for this device */
// fprintf(stderr, "Set dev new addr %s chan %04X units %02X\r\n", cptr, chan, dibp->numunits);
/* loop through all units for this device */
for (i = 0; i < dibp->numunits; i++) {
ochsa = GET_UADDR(tuptr->u3); /* get old chsa for this unit */
//printf("Got old chsa %04x\r\n", ochsa);
dib_unit[ochsa] = NULL; /* clear sa dib pointer */
dib_unit[ochsa&0x7f00] = NULL; /* clear the channel dib address */
chsa = chan | (ochsa & 0xff); /* merge new channel with old sa */
if (dptr->flags & DEV_CHAN) { /* Is this a channel device IOP/MFP */
chan &= 0x7ff0; /* clean channel sub-address */
chsa = chan | (ochsa & 0xf); /* merge new channel with old sa */
} else {
chan &= 0x7f00; /* clean channel address */
chsa = chan | (ochsa & 0xff); /* merge new channel with old sa */
}
if (chsa != ochsa) {
fprintf(stderr, "Set new chsa %04x old chsa %04x\r\n", chsa, ochsa);
//printf("Set new chsa %04x old chsa %04x\r\n", chsa, ochsa);
}
tuptr->u3 &= ~UNIT_ADDR_MASK; /* clear old chsa for this unit */
tuptr->u3 |= UNIT_ADDR(chsa); /* set new chsa for this unit */
dib_unit[chan&0x7f00] = dibp; /* set the channel dib address */
dib_unit[chsa] = dibp; /* save the dib address for new chsa */
// fprintf(stderr, "Set old chsa %04X to new addr %04X new chsa %04X\r\n",
// ochsa, GET_UADDR(tuptr->u3), chsa);
tuptr++; /* next unit pointer */
}
return SCPE_OK;

View File

@ -268,6 +268,8 @@ DEVICE itm_dev = {
1, 8, 8, 1, 8, 8,
NULL, NULL, &itm_reset, /* examine, deposit, reset */
NULL, NULL, NULL, /* boot, attach, detach */
/* dib, dev flags, debug flags, debug */
// NULL, DEV_DEBUG|DEV_DIS|DEV_DISABLE, 0, dev_debug,
NULL, DEV_DEBUG, 0, dev_debug, /* dib, dev flags, debug flags, debug */
NULL, NULL, &itm_help, /* ?, ?, help */
NULL, NULL, &itm_desc, /* ?, ?, description */
@ -403,8 +405,14 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
sim_activate_after_abs_d(&itm_unit, ((double)cnt*1000000)/rtc_tps);
else
/* use interval timer freq */
//MPX3X sim_activate_after_abs_d(&itm_unit, ((double)cnt*itm_tick_size_x_100)/100.0);
sim_activate_after_abs_d(&itm_unit, ((double)(cnt+1)*itm_tick_size_x_100)/100.0);
#ifdef MAYBE_CHANGE_FOR_MPX3X
/* this fixes an extra interrupt being generated on context switch */
/* the value is load for the new task anyway */
/* need to verify that UTX likes it too */
/*4MPX3X*/ sim_activate_after_abs_d(&itm_unit, ((double)(cnt+1)*itm_tick_size_x_100)/100.0);
#else
sim_activate_after_abs_d(&itm_unit, ((double)cnt*itm_tick_size_x_100)/100.0);
#endif
itm_run = 1; /* set timer running */
}
sim_debug(DEBUG_CMD, &itm_dev,
@ -579,7 +587,7 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
/* get simulated negative start time in counts */
temp = temp - itm_strt; /* make into a negative number */
}
// sim_cancel (&itm_unit); /* cancel timer */
//extra sim_cancel (&itm_unit); /* cancel timer */
}
sim_debug(DEBUG_CMD, &itm_dev,
"Intv 0x%02x temp value %08x (%08d)\n", cmd, temp, temp);

View File

@ -184,6 +184,8 @@ TMXR com_desc = { COM_LINES_DFLT, 0, 0, com_ldsc }; /* com descr */
/* u6 */
/* forward definitions */
uint16 com_preio(UNIT *uptr, uint16 chan);
uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd);
uint16 com_haltio(UNIT *uptr);
void com_ini(UNIT *, t_bool);
@ -197,7 +199,7 @@ t_stat com_reset(DEVICE *dptr);
t_stat com_attach(UNIT *uptr, CONST char *cptr);
t_stat com_detach(UNIT *uptr);
void com_reset_ln(int32 ln);
const char *com_description(DEVICE *dptr); /* device description */
const char *com_description(DEVICE *dptr); /* device description */
/* COM data structures
com_chp COM channel program information
@ -239,10 +241,8 @@ UNIT com_unit[] = {
{UDATA(&comi_srv, UNIT_ATTABLE|UNIT_IDLE, 0), COM_WAIT, UNIT_ADDR(0x0000)}, /* 0 */
};
//DIB com_dib = {NULL, com_startcmd, NULL, NULL, com_ini, com_unit, com_chp, COM_UNITS, 0x0f, 0x7e00, 0, 0, 0};
DIB com_dib = {
NULL, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
com_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
com_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */
NULL, /* uint16 (*halt_io)(UNIT *uptr) */ /* Halt I/O */
NULL, /* uint16 (*stop_io)(UNIT *uptr) */ /* Stop I/O */
@ -298,26 +298,24 @@ CHANP coml_chp[COM_LINES*2] = {0};
UNIT coml_unit[] = {
/* 0-7 is input, 8-f is output */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC0)}, /* 0 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC1)}, /* 1 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC2)}, /* 2 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC3)}, /* 3 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC4)}, /* 4 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC5)}, /* 5 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC6)}, /* 6 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC7)}, /* 7 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC8)}, /* 8 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC9)}, /* 9 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECA)}, /* A */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECB)}, /* B */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECC)}, /* C */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECD)}, /* D */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECE)}, /* E */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECF)}, /* F */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC0)}, /* 0 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC1)}, /* 1 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC2)}, /* 2 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC3)}, /* 3 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC4)}, /* 4 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC5)}, /* 5 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC6)}, /* 6 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC7)}, /* 7 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC8)}, /* 8 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7EC9)}, /* 9 */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECA)}, /* A */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECB)}, /* B */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECC)}, /* C */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECD)}, /* D */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECE)}, /* E */
{UDATA(&como_srv, TT_MODE_UC|UNIT_COML, 0), COML_WAIT, UNIT_ADDR(0x7ECF)}, /* F */
};
//DIB coml_dib = { NULL, com_startcmd, NULL, NULL, NULL, coml_ini,
//coml_unit, coml_chp, COM_LINES*2, 0x0f, 0x7E00};
DIB coml_dib = {
NULL, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
com_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */
@ -342,6 +340,7 @@ REG coml_reg[] = {
};
MTAB coml_mod[] = {
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, &show_dev_addr, NULL},
{ TT_MODE, TT_MODE_UC, "UC", "UC", NULL },
{ TT_MODE, TT_MODE_7B, "7b", "7B", NULL },
{ TT_MODE, TT_MODE_8B, "8b", "8B", NULL },
@ -392,7 +391,8 @@ void com_ini(UNIT *uptr, t_bool f)
{
DEVICE *dptr = get_dev(uptr);
sim_debug(DEBUG_CMD, dptr, "COM init device %s controller 0x7e00\n", dptr->name);
sim_debug(DEBUG_CMD, dptr,
"COM init device %s controller 0x7e00\n", dptr->name);
sim_cancel(uptr); /* stop input poll */
sim_activate(uptr, 1000); /* start input poll */
}
@ -409,6 +409,27 @@ uint16 com_rschnlio(UNIT *uptr) {
return SCPE_OK;
}
/* start a com operation */
uint16 com_preio(UNIT *uptr, uint16 chan) {
DEVICE *dptr = get_dev(uptr);
int unit = (uptr - dptr->units);
uint16 chsa = GET_UADDR(uptr->u3); /* get channel/sub-addr */
// int cmd = uptr->u3 & 0xff;
#ifdef WAIT_FOR_TESTING
sim_debug(DEBUG_CMD, dptr, "com_preio CMD %08x unit %02x chsa %04x\n",
uptr->u3, unit, chsa);
if ((uptr->u3 & COM_MSK) != 0) { /* just return if busy */
sim_debug(DEBUG_CMD, dptr,
"com_preio unit %02x chsa %04x BUSY\n", unit, chsa);
return SNS_BSY;
}
#endif
sim_debug(DEBUG_CMD, dptr, "t_preio unit %02x chsa %04xOK\n", unit, chsa);
return SCPE_OK; /* good to go */
}
/* called from sel32_chan to start an I/O operation */
uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
{
@ -420,7 +441,8 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
return SNS_BSY; /* yes, return busy */
}
sim_debug(DEBUG_CMD, dptr, "CMD unit %04x chan %04x cmd %02x\n", unit, chan, cmd);
sim_debug(DEBUG_CMD, dptr,
"CMD unit %04x chan %04x cmd %02x\n", unit, chan, cmd);
/* process the commands */
switch (cmd & 0xFF) {
@ -436,7 +458,8 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
case COM_WR: /* 0x01 */ /* Write command */
case COM_WRSCM: /* 0x05 */ /* Write w/sub channel monitor */
case COM_WRHFC: /* 0x0D */ /* Write w/hardware flow control */
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd WRITE %02x\n", chan, cmd);
sim_debug(DEBUG_CMD, dptr,
"com_startcmd %04x: Cmd WRITE %02x\n", chan, cmd);
uptr->u3 &= LMASK; /* leave only chsa */
uptr->u3 |= (cmd & COM_MSK); /* save command */
@ -466,12 +489,14 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
uptr->u3 |= COM_READ; /* show read mode */
uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */
sim_debug(DEBUG_CMD, dptr,
"com_startcmd %04x: input cnt = %04x\n", chan, coml_chp[unit].ccw_count);
"com_startcmd %04x: input cnt = %04x\n",
chan, coml_chp[unit].ccw_count);
return 0;
break;
case COM_NOP: /* 0x03 */ /* NOP has do nothing */
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd %02x NOP\n", chan, cmd);
sim_debug(DEBUG_CMD, dptr,
"com_startcmd %04x: Cmd %02x NOP\n", chan, cmd);
uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */
uptr->u3 &= LMASK; /* leave only chsa */
uptr->u3 |= (cmd & COM_MSK); /* save command */
@ -484,7 +509,8 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
/* value 4 is Data Set Ready */
/* value 5 is Data carrier detected n/u */
sim_debug(DEBUG_CMD, dptr,
"com_startcmd %04x: unit %04x Cmd Sense %02x\n", chan, unit, uptr->u5);
"com_startcmd %04x: unit %04x Cmd Sense %02x\n",
chan, unit, uptr->u5);
ch = (com_lstat[unit][0] >> 24) & 0xff;
chan_write_byte(GET_UADDR(uptr->u3), &ch); /* write status */
@ -522,7 +548,8 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
break;
case COM_DEFSC: /* 0x0B */ /* Define special char */
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd %02x DEFSC\n", chan, cmd);
sim_debug(DEBUG_CMD, dptr,
"com_startcmd %04x: Cmd %02x DEFSC\n", chan, cmd);
if (chan_read_byte(GET_UADDR(uptr->u3), &ch)) { /* read char from memory */
/* nothing to read, error */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */
@ -606,8 +633,9 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
#define ACE_WAKE 0x0000FF00 /* 8 bit wake-up character */
#endif
case COM_SACE: /* 0xff */ /* Set ACE parameters (3 chars) */
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd %02x SACE\n", chan, cmd);
case COM_SACE: /* 0xff */ /* Set ACE parameters (3 chars) */
sim_debug(DEBUG_CMD, dptr,
"com_startcmd %04x: Cmd %02x SACE\n", chan, cmd);
if (chan_read_byte(GET_UADDR(uptr->u3), &ch)) { /* read char 0 */
/* nothing to read, error */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */
@ -623,7 +651,8 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */
}
uptr->u4 |= ((uint32)ch)<<8; /* byte 2 of ACE data */
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd %02x ACE bytes %08x\n",
sim_debug(DEBUG_CMD, dptr,
"com_startcmd %04x: Cmd %02x ACE bytes %08x\n",
chan, cmd, uptr->u4);
return SNS_CHNEND|SNS_DEVEND; /* good return */
break;
@ -631,7 +660,8 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
default: /* invalid command */
uptr->u5 |= SNS_CMDREJ; /* command rejected */
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd Invald %02x status %02x\n",
sim_debug(DEBUG_CMD, dptr,
"com_startcmd %04x: Cmd Invald %02x status %02x\n",
chan, cmd, uptr->u5);
return SNS_CHNEND|STATUS_PCHK; /* program check */
break;
@ -656,10 +686,12 @@ t_stat comi_srv(UNIT *uptr)
ln = uptr - com_unit; /* line # */
/* handle NOP and INCH cmds */
sim_debug(DEBUG_CMD, dptr, "comi_srv entry chsa %04x line %02x cmd %02x\n", chsa, ln, cmd);
sim_debug(DEBUG_CMD, dptr,
"comi_srv entry chsa %04x line %02x cmd %02x\n", chsa, ln, cmd);
if (cmd == COM_NOP || cmd == 0x7f) { /* check for NOP or INCH */
uptr->u3 &= LMASK; /* leave only chsa */
sim_debug(DEBUG_CMD, dptr, "comi_srv NOP or INCH done chsa %04x line %02x cmd %02x\n",
sim_debug(DEBUG_CMD, dptr,
"comi_srv NOP or INCH done chsa %04x line %02x cmd %02x\n",
chsa, ln, cmd);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
return SCPE_OK; /* return */
@ -729,7 +761,8 @@ t_stat comi_srv(UNIT *uptr)
if (((comlp->u4 & ACE_WAKE) >> 8) == ch) {
/* send attention to OS here for this channel */
/* need to get chsa here for the channel */
set_devwake(chsa, SNS_ATTN|SNS_DEVEND|SNS_CHNEND); /* tell user */
/* tell user */
set_devwake(chsa, SNS_ATTN|SNS_DEVEND|SNS_CHNEND);
}
}
} /* end else char */
@ -752,10 +785,12 @@ t_stat como_srv(UNIT *uptr)
uint8 ch;
/* handle NOP and INCH cmds */
sim_debug(DEBUG_CMD, dptr, "como_srv entry chsa %04x line %04x cmd %02x\n", chsa, ln, cmd);
sim_debug(DEBUG_CMD, dptr,
"como_srv entry chsa %04x line %04x cmd %02x\n", chsa, ln, cmd);
if (cmd == COM_NOP || cmd == 0x7f) { /* check for NOP or INCH */
uptr->u3 &= LMASK; /* leave only chsa */
sim_debug(DEBUG_CMD, &com_dev, "como_srv NOP or INCH done chsa %04x line %04x cmd %02x\n",
sim_debug(DEBUG_CMD, &com_dev,
"como_srv NOP or INCH done chsa %04x line %04x cmd %02x\n",
chsa, ln, cmd);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
return SCPE_OK; /* return */
@ -771,7 +806,8 @@ t_stat como_srv(UNIT *uptr)
return SCPE_OK; /* return */
}
sim_debug(DEBUG_CMD, dptr, "como_srv entry 1 chsa %04x line %04x cmd %02x\n", chsa, ln, cmd);
sim_debug(DEBUG_CMD, dptr,
"como_srv entry 1 chsa %04x line %04x cmd %02x\n", chsa, ln, cmd);
if (cmd) {
/* get a user byte from memory */
done = chan_read_byte(chsa, &ch); /* get byte from memory */
@ -781,28 +817,33 @@ t_stat como_srv(UNIT *uptr)
return SCPE_OK;
if (com_dev.flags & DEV_DIS) { /* disabled */
sim_debug(DEBUG_CMD, dptr, "como_srv chsa %04x line %04x DEV_DIS set\n", chsa, ln);
sim_debug(DEBUG_CMD, dptr,
"como_srv chsa %04x line %04x DEV_DIS set\n", chsa, ln);
if (done) {
sim_debug(DEBUG_CMD, dptr, "como_srv Write DONE %04x status %04x\n",
sim_debug(DEBUG_CMD, dptr,
"como_srv Write DONE %04x status %04x\n",
ln, SNS_CHNEND|SNS_DEVEND);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
}
return SCPE_OK; /* return */
}
sim_debug(DEBUG_CMD, dptr, "como_srv poll chsa %04x line %04x DEV_DIS set\n", chsa, ln);
sim_debug(DEBUG_CMD, dptr,
"como_srv poll chsa %04x line %04x DEV_DIS set\n", chsa, ln);
if (com_ldsc[ln].conn) { /* connected? */
if (com_ldsc[ln].xmte) { /* xmt enabled? */
if (done) { /* are we done writing */
endit:
uptr->u3 &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, dptr, "com_srvo write %04x: chnend|devend\n", ln);
sim_debug(DEBUG_CMD, dptr,
"com_srvo write %04x: chnend|devend\n", ln);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
return SCPE_OK;
}
/* send the next char out */
tmxr_putc_ln(&com_ldsc[ln], ch); /* output char */
sim_debug(DEBUG_CMD, dptr, "com_srvo writing char 0x%02x to ln %04x\n", ch, ln);
sim_debug(DEBUG_CMD, dptr,
"com_srvo writing char 0x%02x to ln %04x\n", ch, ln);
tmxr_poll_tx(&com_desc); /* poll xmt */
sim_activate(uptr, uptr->wait); /* wait */
return SCPE_OK;
@ -810,7 +851,8 @@ endit:
if (done) /* are we done writing */
goto endit; /* done */
/* just dump the char */
sim_debug(DEBUG_CMD, dptr, "com_srvo write dumping char 0x%02x on line %04x\n", ch, ln);
sim_debug(DEBUG_CMD, dptr,
"com_srvo write dumping char 0x%02x on line %04x\n", ch, ln);
tmxr_poll_tx(&com_desc); /* poll xmt */
sim_activate(uptr, uptr->wait); /* wait */
return SCPE_OK;
@ -818,7 +860,8 @@ endit:
} else {
/* not connected, so dump char on ground */
if (done) {
sim_debug(DEBUG_CMD, dptr, "com_srvo write dump DONE line %04x status %04x\n",
sim_debug(DEBUG_CMD, dptr,
"com_srvo write dump DONE line %04x status %04x\n",
ln, SNS_CHNEND|SNS_DEVEND);
uptr->u3 &= LMASK; /* nothing left, command complete */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
@ -885,7 +928,7 @@ void com_reset_ln (int32 ln)
t_stat com_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
fprintf (st, "SEL32 8-Line Async Controller Terminal Interfaces\n\n");
fprintf (st, "SEL32 8512 8-Line Async Controller Terminal Interfaces\n\n");
fprintf (st, "Terminals perform input and output through Telnet sessions connected to a \n");
fprintf (st, "user-specified port.\n\n");
fprintf (st, "The ATTACH command specifies the port to be used:\n\n");
@ -926,7 +969,7 @@ fprintf (st, "are lost when the simulator shuts down or DCI is detached.\n");
/* description of controller */
const char *com_description (DEVICE *dptr)
{
return "SEL 32 8-Line async communications controller";
return "SEL-32 8512 8-Line async communications controller";
}
#endif

View File

@ -117,10 +117,8 @@ UNIT con_unit[] = {
{UDATA(&con_srvo, UNIT_CON, 0), 0, UNIT_ADDR(0x7EFD)}, /* Output */
};
//DIB con_dib = {NULL,con_startcmd,NULL,NULL,NULL,con_ini,
//con_unit,con_chp,NUM_UNITS_CON,0xf,0x7e00,0,0,0};
DIB con_dib = {
con_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */
con_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
con_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */
con_haltio, /* uint16 (*halt_io)(UNIT *uptr) */ /* Halt I/O */
NULL, /* uint16 (*stop_io)(UNIT *uptr) */ /* Stop I/O */
@ -535,8 +533,10 @@ t_stat con_srvi(UNIT *uptr) {
atbuf = (ch)<<8; /* start anew */
uptr->CMD |= CON_ATAT; /* show getting @ */
}
#ifndef TEST4MPX
if (ch == '\n') /* convert newline */
ch = '\r'; /* make newline into carriage return */
#endif
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi handle readch unit %02x: CMD %08x read %02x u4 %02x incnt %02x r %x\n",
unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt, r);

File diff suppressed because it is too large Load Diff

View File

@ -479,7 +479,6 @@ extern DEBTAB dev_debug[];
/* write halfword to memory address */
#define WMH(a,d) ((a)&2?(M[(a)>>2]=(M[(a)>>2]&LMASK)|((d)&RMASK)):(M[(a)>>2]=(M[(a)>>2]&RMASK)|((d)<<16)))
/* write byte to memory */
//#define WMB(a,d) (M[(a)>>2]=(((M[(a)>>2])&(~(0xff<<(8*(7-(a&3))))))|((d&0xff)<<(8*(7-(a&3))))))
#define WMB(a,d) (M[(a)>>2]=(((M[(a)>>2])&(~(0xff<<(8*(3-(a&3))))))|((d&0xff)<<(8*(3-(a&3))))))
/* map register access macros */

View File

@ -1,6 +1,7 @@
/* sel32_ec.c: SEL-32 8516 Ethernet controller.
Copyright (c) 2020, Richard Cornwell
Copyright (c) 2020-2021, Richard Cornwell
Portions provided by James C. Bevier and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -221,6 +222,11 @@ static CONST ETH_MAC broadcast_ethaddr = {0xff,0xff,0xff,0xff,0xff,0xff};
//CHANP ec_chp[8] = {0};
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);
@ -229,7 +235,9 @@ 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);
@ -266,13 +274,21 @@ 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_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 */
@ -595,18 +611,40 @@ 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 */
sim_debug(DEBUG_CMD, dptr,
"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)
{
DEVICE *dptr = get_dev(uptr);
uint16 chsa = GET_UADDR(uptr->CMD);
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
sim_debug(DEBUG_CMD, dptr,
"ec_startcmd chsa %04x unit %d cmd %02x CMD %08x\n",
chsa, (int)(uptr - ec_unit), cmd, uptr->CMD);
if ((uptr->CMD & 0xff) != 0) { /* if any status info, we are busy */
if ((uptr->CMD & 0xff) != 0) { /* if any status info, we are busy */
sim_debug(DEBUG_CMD, dptr, "ec_startcmd busy\n");
return SNS_BSY;
}
@ -684,7 +722,7 @@ t_stat ec_srv(UNIT *uptr)
{
uint16 chsa = GET_UADDR(uptr->CMD);
DEVICE *dptr = get_dev(uptr);
CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */
CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */
int cmd = uptr->CMD & EC_CMDMSK;
uint32 mema;
int i;
@ -791,9 +829,9 @@ t_stat ec_srv(UNIT *uptr)
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
break;
case EC_WRITE: /* Write command 0x01 */
case EC_WRITE: /* Write command 0x01 */
pirq = 0;
uptr->CMD &= LMASK; /* remove old status bits & cmd */
uptr->CMD &= LMASK; /* remove old status bits & cmd */
hdr = (struct ec_eth_hdr *)(&ec_data.snd_buff.msg[0]);
pck = (uint8 *)(&ec_data.snd_buff.msg[0]);
switch (GET_MODE(ec_master_uptr->flags)) {
@ -1001,23 +1039,25 @@ wr_end:
break;
}
for(i = sizeof(struct ec_eth_hdr); i < len; i++) {
if (chan_write_byte(chsa, &pck[i])) {
// if (len < ec_data.conf[9]) {
// sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv short read size %x %x %x\n",chp->ccw_count, i, ec_data.conf[9]);
// /* diags wants prog check instead of unit check */
// pirq = 1;
// }
if (chan_write_byte(chsa, &pck[i])) {
// if (len < ec_data.conf[9]) {
// sim_debug(DEBUG_DETAIL, &ec_dev,
// "ec_srv short read size %x %x %x\n",
// chp->ccw_count, i, ec_data.conf[9]);
// /* diags wants prog check instead of unit check */
// pirq = 1;
// }
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\n" ,i,
len, ec_data.rx_count);
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 */
// 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);
@ -1043,10 +1083,10 @@ wr_end:
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
break;
case EC_STATS: /* Read Statistics */
case EC_STATS: /* Read Statistics */
ch = 0;
/* First 5 words are always zero since these errors are not supported */
uptr->CMD &= LMASK; /* remove old status bits & cmd */
uptr->CMD &= LMASK; /* remove old status bits & cmd */
for (i = 0; i < STAT_LEN * 2; i++) {
if (i == 6)
ch = (ec_data.drop_cnt >> 8) & 0xff;
@ -1079,8 +1119,8 @@ wr_end:
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
break;
case EC_CSTATS: /* Clear software counters */
uptr->CMD &= LMASK; /* remove old status bits & cmd */
case EC_CSTATS: /* Clear software counters */
uptr->CMD &= LMASK; /* remove old status bits & cmd */
ec_data.rx_count = ec_data.tx_count = 0;
(void)chan_read_byte(chsa, &ch);
sim_debug(DEBUG_CMD, dptr,
@ -1089,24 +1129,24 @@ wr_end:
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
break;
case EC_NOP: /* NOP 0x03 */
uptr->CMD &= LMASK; /* remove old status bits & cmd */
case EC_NOP: /* NOP 0x03 */
uptr->CMD &= LMASK; /* remove old status bits & cmd */
sim_debug(DEBUG_CMD, dptr,
"ec_srv cmd NOP chsa %04x count %04x completed\n",
chsa, chp->ccw_count);
/* diags want the count to be returned zero */
chp->ccw_count = 0; /* NOP command count */
chp->ccw_count = 0; /* NOP command count */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;
case EC_SNS: /* 0x4 */
case EC_SNS: /* 0x4 */
sim_debug(DEBUG_CMD, dptr,
"ec_startcmd CMD sense cnt %02x\n", chp->ccw_count);
uptr->CMD &= LMASK; /* remove old status bits & cmd */
uptr->CMD &= LMASK; /* remove old status bits & cmd */
/* diags want incorrect length or prog check */
if (chp->ccw_count < 0x04) {
chp->ccw_count = 0; /* zero command count */
chp->ccw_count = 0; /* zero command count */
if ((chp->ccw_flags & FLAG_SLI) == 0) {
/* diag wants incorrect length */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_LENGTH);
@ -1153,7 +1193,7 @@ wr_end:
#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 */
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);
@ -1177,26 +1217,26 @@ uint16 ec_haltio(UNIT *uptr) {
/* UTX wants SLI bit, but no unit exception */
/* status must not have an error bit set */
/* otherwise, UTX will panic with "bad status" */
if ((uptr->CMD & EC_CMDMSK) != 0) { /* is unit busy */
if ((uptr->CMD & EC_CMDMSK) != 0) { /* is unit busy */
sim_debug(DEBUG_CMD, dptr,
"ec_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count);
// stop any I/O and post status and return error status */
chp->chan_byte = BUFF_EMPTY; /* there is no data to read/store */
chp->ccw_count = 0; /* zero the count */
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC);/* stop any chaining */
uptr->CMD &= LMASK; /* make non-busy */
uptr->SNS = SNS_RCV_RDY; /* status is online & ready */
sim_cancel(uptr); /* clear the input timer */
chp->chan_byte = BUFF_EMPTY; /* there is no data to read/store */
chp->ccw_count = 0; /* zero the count */
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* stop any chaining */
uptr->CMD &= LMASK; /* make non-busy */
uptr->SNS = SNS_RCV_RDY; /* status is online & ready */
sim_cancel(uptr); /* clear the input timer */
sim_debug(DEBUG_CMD, dptr,
"ec_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */
return SCPE_IOERR;
}
uptr->CMD &= LMASK; /* make non-busy */
uptr->SNS = SNS_RCV_RDY; /* status is online & ready */
uptr->CMD &= LMASK; /* make non-busy */
uptr->SNS = SNS_RCV_RDY; /* status is online & ready */
sim_debug(DEBUG_CMD, dptr,
"ec_haltio HIO I/O not busy chsa %04x cmd = %02x\n", chsa, cmd);
return SCPE_OK; /* not busy */
return SCPE_OK; /* not busy */
}
/* initialize the ethernet */
@ -1204,8 +1244,8 @@ void ec_ini(UNIT *uptr, t_bool f)
{
DEVICE *dptr = get_dev(uptr);
uptr->CMD &= LMASK; /* remove old status bits & cmd */
uptr->SNS = 0; /* save mode value */
uptr->CMD &= LMASK; /* remove old status bits & cmd */
uptr->SNS = 0; /* save mode value */
memset(&ec_data.conf[0], 0, sizeof(ec_data.conf));
ec_data.macs_n = 0;
ec_data.tx_count = 0;
@ -1222,6 +1262,7 @@ void ec_ini(UNIT *uptr, t_bool f)
"EC init device %s on unit EC%04X\n", dptr->name, GET_UADDR(uptr->CMD));
}
#ifdef FOR_TEST
/* handle rschnlio cmds for Ethernet */
uint16 ec_rschnlio(UNIT *uptr) {
DEVICE *dptr = get_dev(uptr);
@ -1230,9 +1271,10 @@ uint16 ec_rschnlio(UNIT *uptr) {
sim_debug(DEBUG_EXP, dptr,
"ec_rschnl chsa %04x cmd = %02x\n", chsa, cmd);
ec_ini(uptr, 0); /* reset the unit */
ec_ini(uptr, 0); /* reset the unit */
return SCPE_OK;
}
#endif
static char *
ipv4_inet_ntoa(struct in_addr ip)
@ -1285,18 +1327,18 @@ void ec_packet_debug(struct ec_device *ec, const char *action,
{NULL, 0}
};
static const char *icmp_types[] = {
"Echo Reply", // Type 0
"Echo Reply", // Type 0
"Type 1 - Unassigned",
"Type 2 - Unassigned",
"Destination Unreachable", // Type 3
"Source Quench (Deprecated)", // Type 4
"Redirect", // Type 5
"Destination Unreachable", // Type 3
"Source Quench (Deprecated)", // Type 4
"Redirect", // Type 5
"Type 6 - Alternate Host Address (Deprecated)",
"Type 7 - Unassigned",
"Echo Request", // Type 8
"Router Advertisement", // Type 9
"Router Selection", // Type 10
"Time Exceeded", // Type 11
"Echo Request", // Type 8
"Router Advertisement", // Type 9
"Router Selection", // Type 10
"Time Exceeded", // Type 11
"Type 12 - Parameter Problem",
"Type 13 - Timestamp",
"Type 14 - Timestamp Reply",
@ -1395,13 +1437,15 @@ void ec_packet_debug(struct ec_device *ec, const char *action,
sim_debug(DEBUG_TCP, &ec_dev, "%s %s%s %d byte packet from %s:%s to %s:%s\n", action,
flags, *flags ? ":" : "", (int)len, src_ip, src_port, dst_ip, dst_port);
if (len && (ec_dev.dctrl & DEBUG_TCP))
sim_data_trace(&ec_dev, ec_unit, payload + 4 * (ntohs(tcp->flags) >> 12), "", len, "", DEBUG_DATA);
sim_data_trace(&ec_dev, ec_unit, payload +
4 * (ntohs(tcp->flags) >> 12), "", len, "", DEBUG_DATA);
break;
case ICMP_PROTO:
icmp = (struct icmp *)payload;
len = ntohs(ip->ip_len) - (ip->ip_v_hl & 0xf) * 4;
sim_debug(DEBUG_ICMP, &ec_dev, "%s %s %d byte packet from %s to %s\n", action,
(icmp->type < sizeof(icmp_types)/sizeof(icmp_types[0])) ? icmp_types[icmp->type] : "", (int)len, src_ip, dst_ip);
(icmp->type < sizeof(icmp_types)/sizeof(icmp_types[0])) ?
icmp_types[icmp->type] : "", (int)len, src_ip, dst_ip);
if (len && (ec_dev.dctrl & DEBUG_ICMP))
sim_data_trace(&ec_dev, ec_unit, payload + sizeof(struct icmp), "", len, "", DEBUG_DATA);
break;
@ -1505,7 +1549,7 @@ t_stat ec_attach(UNIT* uptr, CONST char* cptr)
free(tptr);
return status;
}
eth_mac_fmt(&ec_data.mac, buf); /* format ethernet mac address */
eth_mac_fmt(&ec_data.mac, buf); /* format ethernet mac address */
if (SCPE_OK != eth_check_address_conflict (&ec_data.etherface,
&ec_data.mac)) {
eth_close(&ec_data.etherface);
@ -1524,7 +1568,7 @@ t_stat ec_attach(UNIT* uptr, CONST char* cptr)
uptr->filename = tptr;
uptr->flags |= UNIT_ATT;
eth_setcrc(&ec_data.etherface, 0); /* Enable CRC */
eth_setcrc(&ec_data.etherface, 0); /* Enable CRC */
/* init read queue (first time only) */
status = ethq_init(&ec_data.ReadQ, 8);

View File

@ -834,8 +834,6 @@ uint16 hsdp_preio(UNIT *uptr, uint16 chan)
int32 cnt;
sim_debug(DEBUG_CMD, dptr, "hsdp_preio CMD %08x unit %02x\n", uptr->CMD, unit);
//1215 if (IOCLQ_Num(&dibp->ioclq_ptr[unit]) == IOCLQ_SIZE) {
//1217 1f ((cnt = IOCLQ_Num(&dibp->ioclq_ptr[unit])) >= (IOCLQ_SIZE-2)) {
if ((cnt = IOCLQ_Num(&dibp->ioclq_ptr[unit])) >= (IOCLQ_SIZE)) {
sim_debug(DEBUG_CMD, dptr, "hsdp_preio CMD %08x unit %02x IOCLQ cnt %02x Full\n",
uptr->CMD, unit, cnt);

View File

@ -98,7 +98,6 @@ UNIT iop_unit[] = {
{UDATA(&iop_srv, UNIT_IOP, 0), 0, UNIT_ADDR(0x7E00)}, /* Channel controller */
};
//DIB iop_dib = {NULL, iop_startcmd, NULL, NULL, NULL, iop_ini, iop_unit, iop_chp, NUM_UNITS_IOP, 0xff, 0x7e00,0,0,0};
DIB iop_dib = {
NULL, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */
iop_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command SIO */

View File

@ -135,25 +135,27 @@ LPFCTBL EQU $
struct _lpr_data
{
uint8 lbuff[160]; /* Output line buffer */
uint8 lbuff[160]; /* Output line buffer */
};
struct _lpr_data lpr_data[NUM_DEVS_LPR];
uint16 lpr_startcmd(UNIT *, uint16, uint8);
void lpr_ini(UNIT *, t_bool);
uint16 lpr_rschnlio(UNIT *uptr);
t_stat lpr_srv(UNIT *);
t_stat lpr_reset(DEVICE *);
t_stat lpr_attach(UNIT *, CONST char *);
t_stat lpr_detach(UNIT *);
t_stat lpr_setlpp(UNIT *, int32, CONST char *, void *);
t_stat lpr_getlpp(FILE *, UNIT *, int32, CONST void *);
/* forward definitions */
uint16 lpr_preio(UNIT *uptr, uint16 chan);
uint16 lpr_startcmd(UNIT *, uint16, uint8);
void lpr_ini(UNIT *, t_bool);
uint16 lpr_rschnlio(UNIT *uptr);
t_stat lpr_srv(UNIT *);
t_stat lpr_reset(DEVICE *);
t_stat lpr_attach(UNIT *, CONST char *);
t_stat lpr_detach(UNIT *);
t_stat lpr_setlpp(UNIT *, int32, CONST char *, void *);
t_stat lpr_getlpp(FILE *, UNIT *, int32, CONST void *);
/* channel program information */
CHANP lpr_chp[NUM_DEVS_LPR] = {0};
CHANP lpr_chp[NUM_DEVS_LPR] = {0};
MTAB lpr_mod[] = {
MTAB lpr_mod[] = {
{MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "LINESPERPAGE", "LINESPERPAGE",
&lpr_setlpp, &lpr_getlpp, NULL, "Number of lines per page"},
{MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr,
@ -161,7 +163,7 @@ MTAB lpr_mod[] = {
{0}
};
UNIT lpr_unit[] = {
UNIT lpr_unit[] = {
{UDATA(&lpr_srv, UNIT_LPR, 66), 300, UNIT_ADDR(0x7EF8)}, /* A */
#if NUM_DEVS_LPR > 1
{UDATA(&lpr_srv, UNIT_LPR, 66), 300, UNIT_ADDR(0x7EF9)}, /* B */
@ -169,10 +171,8 @@ UNIT lpr_unit[] = {
};
/* Device Information Block */
//DIB lpr_dib = {NULL, lpr_startcmd, NULL, NULL, lpr_ini, lpr_unit,
//lpr_chp, NUM_DEVS_LPR, 0xff, 0x7e00, 0, 0, 0};
DIB lpr_dib = {
NULL, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */
DIB lpr_dib = {
lpr_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
lpr_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */
NULL, /* uint16 (*halt_io)(UNIT *uptr) */ /* Halt I/O */
NULL, /* uint16 (*stop_io)(UNIT *uptr) */ /* Stop I/O */
@ -192,7 +192,7 @@ DIB lpr_dib = {
{0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */
};
DEVICE lpr_dev = {
DEVICE lpr_dev = {
"LPR", lpr_unit, NULL, lpr_mod,
NUM_DEVS_LPR, 8, 15, 1, 8, 8,
NULL, NULL, NULL, NULL, &lpr_attach, &lpr_detach,
@ -221,6 +221,25 @@ uint16 lpr_rschnlio(UNIT *uptr) {
return SCPE_OK;
}
/* start a line printer operation */
uint16 lpr_preio(UNIT *uptr, uint16 chan) {
DEVICE *dptr = get_dev(uptr);
int unit = (uptr - dptr->units);
uint16 chsa = GET_UADDR(uptr->CMD);
sim_debug(DEBUG_CMD, dptr, "lpr_preio CMD %08x unit %02x chsa %04x\n",
uptr->CMD, unit, chsa);
if ((uptr->CMD & LPR_CMDMSK) != 0) { /* just return if busy */
sim_debug(DEBUG_CMD, dptr,
"lpr_preio unit %02x chsa %04x BUSY\n", unit, chsa);
return SNS_BSY;
}
sim_debug(DEBUG_CMD, dptr,
"lpr_preio unit %02x chsa %04xOK\n", unit, chsa);
return SCPE_OK; /* good to go */
}
/* start an I/O operation */
uint16 lpr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
{

View File

@ -148,6 +148,8 @@
#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF)
#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF
/* forward definitions */
uint16 mt_preio(UNIT *uptr, uint16 chan);
uint16 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ;
t_stat mt_srv(UNIT *uptr);
t_stat mt_boot(int32 unitnum, DEVICE *dptr);
@ -292,7 +294,7 @@ UNIT mta_unit[] = {
CHANP mta_chp[NUM_UNITS_MT] = {0};
DIB mta_dib = {
NULL, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
mt_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
mt_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */
NULL, /* uint16 (*halt_io)(UNIT *uptr) */ /* Halt I/O */
NULL, /* uint16 (*stop_io)(UNIT *uptr) */ /* Stop I/O */
@ -340,7 +342,7 @@ UNIT mtb_unit[] = {
/* device information block */
DIB mtb_dib = {
NULL, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
mt_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
mt_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */
NULL, /* uint16 (*halt_io)(UNIT *uptr) */ /* Halt I/O */
NULL, /* uint16 (*stop_io)(UNIT *uptr) */ /* Stop I/O */
@ -369,6 +371,30 @@ DEVICE mtb_dev = {
};
#endif
/* start a tape operation */
uint16 mt_preio(UNIT *uptr, uint16 chan) {
DEVICE *dptr = get_dev(uptr);
int unit = (uptr - dptr->units);
uint16 chsa = GET_UADDR(uptr->CMD);
sim_debug(DEBUG_CMD, dptr, "mt_preio CMD %08x unit %02x chsa %04x\n",
uptr->CMD, unit, chsa);
if ((uptr->CMD & MT_CMDMSK) != 0) { /* just return if busy */
sim_debug(DEBUG_CMD, dptr,
"mt_preio unit %02x chsa %04x BUSY\n", unit, chsa);
return SNS_BSY;
}
if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
uptr->SNS |= SNS_INTVENT; /* unit intervention required */
uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */
uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */
return SNS_BSY;
}
sim_debug(DEBUG_CMD, dptr, "mt_preio unit %02x chsa %04xOK\n", unit, chsa);
return SCPE_OK; /* good to go */
}
/* start an I/O operation */
uint16 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
{
@ -379,15 +405,16 @@ uint16 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
sim_debug(DEBUG_EXP, dptr, "mt_startcmd entry chan %04x cmd %02x\n", chan, cmd);
if (mt_busy[GET_DEV_BUF(dptr->flags)] != 0 || (uptr->CMD & MT_CMDMSK) != 0) {
sim_debug(DEBUG_EXP, dptr, "mt_startcmd busy chan %04x cmd %02x\n", chan, cmd);
uptr->flags |= MT_BUSY; /* Flag we need to send CUE */
sim_debug(DEBUG_EXP, dptr, "mt_startcmd busy %02x chan %04x flags %08x CMD %02x\n",
mt_busy[GET_DEV_BUF(dptr->flags)], chan, dptr->flags, uptr->CMD);
uptr->flags |= MT_BUSY; /* Flag we need to send CUE */
return SNS_BSY;
}
sim_debug(DEBUG_EXP, dptr, "mt_startcmd processing unit %01x cmd %02x\n", unit, cmd);
switch (cmd & 0xFF) {
case 0x00: /* INCH command */
case 0x00: /* INCH command */
sim_debug(DEBUG_CMD, dptr, "start INCH command\n");
sim_debug(DEBUG_CMD, dptr,
@ -395,24 +422,24 @@ uint16 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
chsa, chp->ccw_addr, chp->ccw_count);
/* UTX_needs_interrupt */
cmd = MT_CMDMSK; /* insert INCH cmd as 0xff */
cmd = MT_CMDMSK; /* insert INCH cmd as 0xff */
/* fall through */
case 0x03: /* Tape motion commands or NOP */
case 0x13: /* Read and compare command */
case 0x23: /* Rewind command */
case 0x33: /* Rewind and unload */
case 0x43: /* Advance record */
case 0x53: /* Backspace record */
case 0x63: /* Advance filemark */
case 0x73: /* Backspace filemark */
case 0x83: /* Set Mode command */
case 0x93: /* Write Tape filemark */
case 0xA3: /* Erase 3.5 of tape */
case 0x03: /* Tape motion commands or NOP */
case 0x13: /* Read and compare command */
case 0x23: /* Rewind command */
case 0x33: /* Rewind and unload */
case 0x43: /* Advance record */
case 0x53: /* Backspace record */
case 0x63: /* Advance filemark */
case 0x73: /* Backspace filemark */
case 0x83: /* Set Mode command */
case 0x93: /* Write Tape filemark */
case 0xA3: /* Erase 3.5 of tape */
/* UTX_needs_interrupt on NOP or INCH */
/* fall through */
case 0x01: /* Write command */
case 0x02: /* Read command */
case 0x0C: /* Read backward */
case 0x01: /* Write command */
case 0x02: /* Read command */
case 0x0C: /* Read backward */
if (cmd == 0x01)
sim_debug(DEBUG_EXP, dptr,
"mt_startcmd WRITE chan %04x addr %06x cnt %04x\n",
@ -421,30 +448,30 @@ uint16 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
sim_debug(DEBUG_EXP, dptr,
"mt_startcmd READ chan %04x addr %06x cnt %04x\n",
chan, chp->ccw_addr, chp->ccw_count);
if (cmd != 0x03) /* if this is a nop do not zero status */
if (cmd != 0x03) /* if this is a nop do not zero status */
uptr->SNS = (uptr->SNS & 0x0000ff00); /* clear all but byte 2 */
uptr->SNS |= (SNS_RDY|SNS_ONLN); /* set ready status */
uptr->SNS |= (SNS_RDY|SNS_ONLN); /* set ready status */
/* Fall through */
if (sim_tape_wrp(uptr))
uptr->SNS |= (SNS_WRP); /* write protected */
uptr->SNS |= (SNS_WRP); /* write protected */
if (sim_tape_bot(uptr))
uptr->SNS |= (SNS_LOAD); /* tape at load point */
uptr->SNS |= (SNS_LOAD); /* tape at load point */
if (sim_tape_eot(uptr))
uptr->SNS |= (SNS_EOT); /* tape at EOM */
uptr->SNS |= (SNS_EOT); /* tape at EOM */
/* Fall through */
case 0x04: /* Sense */
uptr->CMD &= ~(MT_CMDMSK); /* clear out last cmd */
uptr->CMD |= cmd & MT_CMDMSK; /* insert new cmd */
CLR_BUF(uptr); /* buffer is empty */
uptr->POS = 0; /* reset buffer position pointer */
mt_busy[GET_DEV_BUF(dptr->flags)] = 1; /* show we are busy */
uptr->CMD &= ~(MT_CMDMSK); /* clear out last cmd */
uptr->CMD |= cmd & MT_CMDMSK; /* insert new cmd */
CLR_BUF(uptr); /* buffer is empty */
uptr->POS = 0; /* reset buffer position pointer */
mt_busy[GET_DEV_BUF(dptr->flags)] = 1; /* show we are busy */
sim_debug(DEBUG_EXP, dptr, "mt_startcmd sense %08x return 0 chan %04x cmd %02x\n",
uptr->SNS, chan, cmd);
sim_activate(uptr, 100); /* Start unit off */
sim_activate(uptr, 100); /* Start unit off */
return 0;
default: /* invalid command */
default: /* invalid command */
sim_debug(DEBUG_EXP, dptr, "mt_startcmd CMDREJ return chan %04x cmd %02x\n",
chan, cmd);
uptr->SNS |= SNS_CMDREJ;
@ -454,7 +481,7 @@ uint16 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
}
#if 0
/* not reached */
if (uptr->SNS & 0xff000000) /* errors? */
if (uptr->SNS & 0xff000000) /* errors? */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
sim_debug(DEBUG_EXP, dptr,
"mt_startcmd ret CHNEND|DEVEND chan %04x unit %04x cmd %02x\n", chan, unit, cmd);
@ -466,47 +493,49 @@ uint16 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
t_stat mt_error(UNIT *uptr, uint16 chsa, t_stat r, DEVICE *dptr)
{
sim_debug(DEBUG_CMD, dptr, "mt_error status %08x\n", r);
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1; /* not busy anymore */
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1; /* not busy anymore */
switch (r) { /* switch on return value */
case MTSE_OK: /* no error */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
switch (r) { /* switch on return value */
case MTSE_OK: /* no error */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
break;
case MTSE_TMK: /* tape mark */
case MTSE_TMK: /* tape mark */
sim_debug(DEBUG_CMD, dptr, "FILE MARK\n");
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
case MTSE_WRP: /* write protected */
uptr->SNS |= SNS_WRP; /* write protected */
case MTSE_WRP: /* write protected */
uptr->SNS |= SNS_WRP; /* write protected */
sim_debug(DEBUG_CMD, dptr, "WRITE PROTECT %08x\n", r); /* operator intervention */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
break;
case MTSE_UNATT: /* unattached */
uptr->SNS |= SNS_INTVENT; /* unit intervention required */
case MTSE_UNATT: /* unattached */
uptr->SNS |= SNS_INTVENT; /* unit intervention required */
uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */
uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */
sim_debug(DEBUG_CMD, dptr, "ATTENTION %08x\n", r); /* operator intervention */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
break;
case MTSE_IOERR: /* IO error */
case MTSE_FMT: /* invalid format */
case MTSE_RECE: /* error in record */
case MTSE_IOERR: /* IO error */
case MTSE_FMT: /* invalid format */
case MTSE_RECE: /* error in record */
sim_debug(DEBUG_CMD, dptr, "ERROR %08x\n", r);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
break;
case MTSE_BOT: /* beginning of tape */
uptr->SNS |= SNS_LOAD; /* tape at BOT */
case MTSE_BOT: /* beginning of tape */
uptr->SNS |= SNS_LOAD; /* tape at BOT */
sim_debug(DEBUG_CMD, dptr, "BOT\n");
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
break;
case MTSE_INVRL: /* invalid rec lnt */
case MTSE_EOM: /* end of medium */
uptr->SNS |= SNS_EOT; /* tape at EOT */
case MTSE_INVRL: /* invalid rec lnt */
case MTSE_EOM: /* end of medium */
uptr->SNS |= SNS_EOT; /* tape at EOT */
sim_debug(DEBUG_CMD, dptr, "EOT\n");
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
break;
@ -524,7 +553,7 @@ t_stat mt_srv(UNIT *uptr)
int bufnum = GET_DEV_BUF(dptr->flags);
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
t_mtrlnt reclen;
t_stat r = SCPE_ARG; /* Force error if not set */
t_stat r = SCPE_ARG; /* Force error if not set */
int i;
uint32 mema;
uint16 len;
@ -532,10 +561,13 @@ t_stat mt_srv(UNIT *uptr)
// uint8 buf[1024];
sim_debug(DEBUG_DETAIL, dptr, "mt_srv unit %04x cmd %02x\n", unit, cmd);
if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
uptr->SNS |= SNS_INTVENT; /* unit intervention required */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
if (cmd != MT_SENSE) { /* we are completed with unit check status */
if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
uptr->SNS |= SNS_INTVENT; /* unit intervention required */
uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */
uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
if (cmd != MT_SENSE) { /* we are completed with unit check status */
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
}
@ -543,15 +575,15 @@ t_stat mt_srv(UNIT *uptr)
switch (cmd) {
case MT_CMDMSK: /* 0x0ff for inch 0x00 */ /* INCH is for channel, nothing for us */
len = chp->ccw_count; /* INCH command count */
mema = chp->ccw_addr; /* get inch or buffer addr */
len = chp->ccw_count; /* INCH command count */
mema = chp->ccw_addr; /* get inch or buffer addr */
sim_debug(DEBUG_CMD, dptr,
"mt_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
mema, chsa, chp->ccw_addr, chp->ccw_count);
if (len == 0) {
/* we have invalid count, error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
@ -560,7 +592,7 @@ t_stat mt_srv(UNIT *uptr)
for (i=0; i < len; i++) {
if (chan_read_byte(chsa, &buf[i])) {
/* we have error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
@ -570,11 +602,11 @@ t_stat mt_srv(UNIT *uptr)
#endif
/* the chp->ccw_addr location contains the inch address */
/* call set_inch() to setup inch buffer */
i = set_inch(uptr, mema); /* new address */
i = set_inch(uptr, mema); /* new address */
if ((i == SCPE_MEM) || (i == SCPE_ARG)) { /* any error */
/* we have error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
@ -582,81 +614,89 @@ t_stat mt_srv(UNIT *uptr)
/* set halfwords 16 & 17 to 5 as default retry count in inch data */
/* UTX uses this value to see if the device is a buffered tape processor */
/* they must be non-zero and equal to be BTP */
WMH(mema+(16<<1),5); /* write left HW with count */
WMH(mema+(17<<1),5); /* write right HW with count */
WMH(mema+(16<<1),5); /* write left HW with count */
WMH(mema+(17<<1),5); /* write right HW with count */
sim_debug(DEBUG_CMD, dptr,
"mt_srv cmd INCH chsa %04x chsa %06x count %04x completed INCH16 %08x\n",
chsa, mema, chp->ccw_count, RMW(mema+(8<<2)));
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
break;
case 0x80: /* other? */ /* default to NOP */
case 0x80: /* other? */ /* default to NOP */
sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 80 DIAG unit=%04x SNS %08x\n", unit, uptr->SNS);
ch = (uptr->SNS >> 24) & 0xff; /* get sense byte 0 status */
ch = (uptr->SNS >> 24) & 0xff; /* get sense byte 0 status */
sim_debug(DEBUG_CMD, dptr, "sense unit %02x byte 0 %02x\n", unit, ch);
chan_write_byte(chsa, &ch); /* write byte 0 */
ch = (uptr->SNS >> 16) & 0xff; /* get sense byte 1 status */
chan_write_byte(chsa, &ch); /* write byte 0 */
ch = (uptr->SNS >> 16) & 0xff; /* get sense byte 1 status */
sim_debug(DEBUG_CMD, dptr, "sense unit %02x byte 1 %02x\n", unit, ch);
chan_write_byte(chsa, &ch); /* write byte 1 */
ch = (uptr->SNS >> 8) & 0xff; /* get sense byte 2 status */
chan_write_byte(chsa, &ch); /* write byte 1 */
ch = (uptr->SNS >> 8) & 0xff; /* get sense byte 2 status */
sim_debug(DEBUG_CMD, dptr, "sense unit %02x byte 2 %02x\n", unit, ch);
chan_write_byte(chsa, &ch); /* write byte 2 */
ch = (uptr->SNS >> 0) & 0xff; /* get sense byte 3 status */
chan_write_byte(chsa, &ch); /* write byte 2 */
ch = (uptr->SNS >> 0) & 0xff; /* get sense byte 3 status */
sim_debug(DEBUG_CMD, dptr, "sense unit %02x byte 3 %02x\n", unit, ch);
chan_write_byte(chsa, &ch); /* write byte 3 */
chan_write_byte(chsa, &ch); /* write byte 3 */
/* write zero extra status */
for (ch=4; ch < 0xc; ch++) {
uint8 zc = 0;
chan_write_byte(chsa, &zc); /* write zero byte */
chan_write_byte(chsa, &zc); /* write zero byte */
sim_debug(DEBUG_CMD, dptr,
"sense unit %02x byte %1x %02x\n", unit, ch, zc);
}
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
uptr->SNS = (uptr->SNS & 0x0000ff00); /* clear all but byte 2 */
if ((uptr->flags & UNIT_ATT) == 0) /* unit attached status */
uptr->SNS |= SNS_INTVENT; /* unit intervention required */
else
uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */
sim_debug(DEBUG_CMD, dptr, "mt_srv DIAG SNS %08x char complete unit=%02x\n",
uptr->SNS, unit);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
break;
case MT_NOP: /* 0x03 */ /* NOP motion command */
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
case MT_NOP: /* 0x03 */ /* NOP motion command */
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
break;
case MT_SENSE: /* 0x04 */ /* get sense data */
case MT_SENSE: /* 0x04 */ /* get sense data */
/* write requested status */
len = chp->ccw_count; /* command count */
//0905 for (i=0; i<len; i++) {
len = chp->ccw_count; /* command count */
for (i=0; i<4; i++) {
ch = 0;
if (i<4)
ch = (uptr->SNS >> (24-(i*8))) & 0xff; /* get 8 bits of status */
chan_write_byte(chsa, &ch); /* write zero byte */
chan_write_byte(chsa, &ch); /* write zero byte */
sim_debug(DEBUG_CMD, dptr,
"sense unit %02x byte %1x %02x\n", unit, i, ch);
}
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
uptr->SNS = (uptr->SNS & 0x0000ff00); /* clear all but byte 2 */
if ((uptr->flags & UNIT_ATT) == 0) /* unit attached status */
uptr->SNS |= SNS_INTVENT; /* unit intervention required */
else
uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */
sim_debug(DEBUG_CMD, dptr, "mt_srv SENSE %08x char complete unit=%02x\n",
uptr->SNS, unit);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
break;
case MT_READ: /* 0x02 */ /* read a record from the device */
// sim_debug(DEBUG_DETAIL, dptr, "mt_srv cmd 2 READ unit=%02x\n", unit);
sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 2 READ unit=%02x\n", unit);
if (uptr->CMD & MT_READDONE) { /* is the read complete */
uptr->SNS &= ~(SNS_LOAD|SNS_EOT); /* reset BOT & EOT */
if (sim_tape_eot(uptr)) { /* see if at EOM */
uptr->SNS |= SNS_EOT; /* set EOT status */
case MT_READ: /* 0x02 */ /* read a record from the device */
sim_debug(DEBUG_DETAIL, dptr, "mt_srv cmd 2 READ unit=%02x\n", unit);
if (uptr->CMD & MT_READDONE) { /* is the read complete */
uptr->SNS &= ~(SNS_LOAD|SNS_EOT); /* reset BOT & EOT */
if (sim_tape_eot(uptr)) { /* see if at EOM */
uptr->SNS |= SNS_EOT; /* set EOT status */
}
uptr->CMD &= ~(MT_CMDMSK|MT_READDONE); /* clear all but readdone & cmd */
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* not busy anymore */
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* not busy anymore */
sim_debug(DEBUG_CMD, dptr,
"mt_srv READ %04x char complete unit=%02x sense %08x\n",
uptr->POS, unit, uptr->SNS);
@ -672,10 +712,9 @@ t_stat mt_srv(UNIT *uptr)
uptr->CMD &= ~(MT_CMDMSK|MT_READDONE); /* clear all but readdone & cmd */
return mt_error(uptr, chsa, r, dptr); /* process any error & return status */
}
uptr->SNS &= ~(SNS_LOAD|SNS_EOT); /* reset BOT & EOT */
uptr->POS = 0; /* reset buffer position */
uptr->hwmark = reclen; /* set buffer chars read in */
// sim_debug(DEBUG_DETAIL, dptr, "mt_srv READ fill buffer complete count %04x\n", reclen);
uptr->SNS &= ~(SNS_LOAD|SNS_EOT); /* reset BOT & EOT */
uptr->POS = 0; /* reset buffer position */
uptr->hwmark = reclen; /* set buffer chars read in */
sim_debug(DEBUG_CMD, dptr, "mt_srv READ fill buffer complete count %04x\n", reclen);
sim_debug(DEBUG_CMD, dptr,
"mt_srv READ MemBuf %06x cnt %04x %02x%02x%02x%02x\n",
@ -692,20 +731,19 @@ t_stat mt_srv(UNIT *uptr)
/* If not read whole record, skip till end */
if ((uint32)uptr->POS < uptr->hwmark) {
/* Send dummy character to force SLI */
chan_write_byte(chsa, &ch); /* write the byte */
chan_write_byte(chsa, &ch); /* write the byte */
sim_debug(DEBUG_CMD, dptr, "Read unit %02x send dump SLI\n", unit);
sim_activate(uptr, (uptr->hwmark-uptr->POS) * 10); /* wait again */
uptr->CMD |= MT_READDONE; /* read is done */
uptr->CMD |= MT_READDONE; /* read is done */
break;
}
sim_debug(DEBUG_CMD, dptr,
"Read data @1 unit %02x cnt %04x ch %02x hwm %04x\n",
unit, uptr->POS, ch, uptr->hwmark);
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* set not busy */
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* set not busy */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return end status */
} else {
// sim_debug(DEBUG_CMD, dptr,
sim_debug(DEBUG_DETAIL, dptr,
"Read data @2 unit %02x cnt %04x ch %02x hwm %04x\n",
unit, uptr->POS, ch, uptr->hwmark);
@ -714,39 +752,39 @@ t_stat mt_srv(UNIT *uptr)
sim_debug(DEBUG_CMD, dptr,
"Read end of data unit %02x cnt %04x ch %02x hwm %04x\n",
unit, uptr->POS, ch, uptr->hwmark);
uptr->CMD |= MT_READDONE; /* read is done */
sim_activate(uptr, 40); /* wait again */
uptr->CMD |= MT_READDONE; /* read is done */
sim_activate(uptr, 40); /* wait again */
} else
sim_activate(uptr, 40); /* wait again */
sim_activate(uptr, 40); /* wait again */
}
break;
case MT_SETM: /* 0x83 */ /* set mode byte */
case MT_SETM: /* 0x83 */ /* set mode byte */
sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x83 SETM unit=%02x\n", unit);
/* Grab data until channel has no more */
if (chan_read_byte(chsa, &ch)) {
if (uptr->POS > 0) { /* Only if data in record */
reclen = uptr->hwmark; /* set record length */
ch = mt_buffer[bufnum][0]; /* get the first byte read */
if (uptr->POS > 0) { /* Only if data in record */
reclen = uptr->hwmark; /* set record length */
ch = mt_buffer[bufnum][0]; /* get the first byte read */
sim_debug(DEBUG_CMD, dptr,
"Write mode data done unit %02x chars %02x mode %02x\n", unit, reclen, ch);
/* put mode bits into byte 2 of SNS */
uptr->SNS = (uptr->SNS & 0xffff00ff) | (ch << 8);
uptr->POS = 0; /* no bytes anymore */
uptr->CMD &= ~MT_CMDMSK; /* no cmd to do */
mt_busy[bufnum] &= ~1; /* set not busy */
uptr->POS = 0; /* no bytes anymore */
uptr->CMD &= ~MT_CMDMSK; /* no cmd to do */
mt_busy[bufnum] &= ~1; /* set not busy */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return end status */
}
} else {
mt_buffer[bufnum][uptr->POS++] = ch; /* save the character read in */
sim_debug(DEBUG_CMD, dptr, "Write mode data in unit %02x POS %04x mode %02x\n",
unit, uptr->POS, ch);
uptr->hwmark = uptr->POS; /* set high water mark */
sim_activate(uptr, 40); /* wait time */
uptr->hwmark = uptr->POS; /* set high water mark */
sim_activate(uptr, 40); /* wait time */
}
break;
case MT_WRITE: /* 0x01 */ /* write record */
case MT_WRITE: /* 0x01 */ /* write record */
/* Check if write protected */
if (sim_tape_wrp(uptr)) {
uptr->SNS |= SNS_CMDREJ;
@ -759,14 +797,14 @@ t_stat mt_srv(UNIT *uptr)
/* Grab data until channel has no more */
if (chan_read_byte(chsa, &ch)) {
if (uptr->POS > 0) { /* Only if data in record */
if (uptr->POS > 0) { /* Only if data in record */
reclen = uptr->hwmark;
sim_debug(DEBUG_CMD, dptr, "Write unit=%02x Block %04x chars\n",
unit, reclen);
r = sim_tape_wrrecf(uptr, &mt_buffer[bufnum][0], reclen);
uptr->POS = 0;
uptr->CMD &= ~MT_CMDMSK;
mt_error(uptr, chsa, r, dptr); /* Record errors */
mt_error(uptr, chsa, r, dptr); /* Record errors */
}
} else {
mt_buffer[bufnum][uptr->POS++] = ch;
@ -777,7 +815,7 @@ t_stat mt_srv(UNIT *uptr)
sim_activate(uptr, 40);
break;
case MT_RDBK: /* 0x0C */ /* Read Backwards */
case MT_RDBK: /* 0x0C */ /* Read Backwards */
if (uptr->CMD & MT_READDONE) {
uptr->CMD &= ~(MT_CMDMSK|MT_READDONE);
mt_busy[bufnum] &= ~1;
@ -820,7 +858,7 @@ t_stat mt_srv(UNIT *uptr)
} else {
sim_debug(DEBUG_DETAIL, dptr, "Read data unit=%02x %04x %02x\n",
unit, uptr->POS, ch);
if (uptr->POS == 0) { /* In IRG */
if (uptr->POS == 0) { /* In IRG */
uptr->CMD &= ~MT_CMDMSK;
mt_busy[bufnum] &= ~1;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
@ -829,7 +867,7 @@ t_stat mt_srv(UNIT *uptr)
}
break;
case MT_WTM: /* 0x93 */ /* Write tape filemark */
case MT_WTM: /* 0x93 */ /* Write tape filemark */
if (uptr->POS == 0) {
if (sim_tape_wrp(uptr)) {
uptr->SNS |= SNS_CMDREJ;
@ -849,7 +887,7 @@ t_stat mt_srv(UNIT *uptr)
}
break;
case MT_BSR: /* 0x53 */ /* Backspace record */
case MT_BSR: /* 0x53 */ /* Backspace record */
sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x53 BSR unit %02x POS %04x\n",
unit, uptr->POS);
switch (uptr->POS ) {
@ -890,19 +928,19 @@ t_stat mt_srv(UNIT *uptr)
case 3: /* EOF */
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
chan_end(chsa, SNS_DEVEND|SNS_UNITEXP);
break;
case 4: /* BOT */
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
uptr->SNS |= SNS_LOAD; /* set BOT detected */
uptr->SNS |= SNS_LOAD; /* set BOT detected */
chan_end(chsa, SNS_DEVEND|SNS_UNITEXP);
break;
}
break;
case MT_BSF: /* 0x73 */ /* Backspace file */
case MT_BSF: /* 0x73 */ /* Backspace file */
sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x73 BSF unit %02x\n", unit);
switch(uptr->POS) {
case 0:
@ -932,20 +970,20 @@ t_stat mt_srv(UNIT *uptr)
break;
case 2: /* File Mark */
uptr->CMD &= ~(MT_CMDMSK);
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
mt_busy[bufnum] &= ~1;
chan_end(chsa, SNS_DEVEND);
break;
case 3: /* BOT */
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
uptr->SNS |= SNS_LOAD; /* set BOT */
uptr->SNS |= SNS_LOAD; /* set BOT */
chan_end(chsa, SNS_DEVEND);
break;
}
break;
case MT_FSR: /* 0x43 */ /* Advance record */
case MT_FSR: /* 0x43 */ /* Advance record */
switch(uptr->POS) {
case 0:
sim_debug(DEBUG_CMD, dptr, "Skip rec entry unit=%02x ", unit);
@ -959,12 +997,12 @@ t_stat mt_srv(UNIT *uptr)
r = sim_tape_sprecf(uptr, &reclen);
if (r == MTSE_TMK) {
uptr->POS = 3;
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
sim_debug(DEBUG_CMD, dptr, "FSR MARK\n");
sim_activate(uptr, 50);
} else if (r == MTSE_EOM) {
uptr->POS = 4;
uptr->SNS |= SNS_EOT; /* set EOT status */
uptr->SNS |= SNS_EOT; /* set EOT status */
sim_debug(DEBUG_CMD, dptr, "FSR EOT\n");
sim_activate(uptr, 50);
} else {
@ -994,7 +1032,7 @@ t_stat mt_srv(UNIT *uptr)
}
break;
case MT_FSF: /* 0x63 */ /* advance filemark */
case MT_FSF: /* 0x63 */ /* advance filemark */
switch(uptr->POS) {
case 0:
sim_debug(DEBUG_CMD, dptr,
@ -1008,11 +1046,11 @@ t_stat mt_srv(UNIT *uptr)
r = sim_tape_sprecf(uptr, &reclen);
if (r == MTSE_TMK) {
uptr->POS++;
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
sim_debug(DEBUG_CMD, dptr, "FSF EOF MARK sense %08x\n", uptr->SNS);
sim_activate(uptr, 50);
} else if (r == MTSE_EOM) {
uptr->SNS |= SNS_EOT; /* set EOT status */
uptr->SNS |= SNS_EOT; /* set EOT status */
sim_debug(DEBUG_CMD, dptr, "FSF EOT sense %08x\n", uptr->SNS);
uptr->POS+= 2;
sim_activate(uptr, 50);
@ -1030,7 +1068,7 @@ t_stat mt_srv(UNIT *uptr)
break;
case 3:
uptr->CMD &= ~(MT_CMDMSK);
uptr->SNS |= SNS_EOT; /* set EOT status */
uptr->SNS |= SNS_EOT; /* set EOT status */
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, dptr,
"Skip file got EOT sense %08x unit %02x\n", uptr->SNS, unit);
@ -1039,7 +1077,7 @@ t_stat mt_srv(UNIT *uptr)
}
break;
case MT_ERG: /* 0xA3 */ /* Erace 3.5 in tape */
case MT_ERG: /* 0xA3 */ /* Erace 3.5 in tape */
switch (uptr->POS) {
case 0:
if (sim_tape_wrp(uptr)) {
@ -1067,7 +1105,7 @@ t_stat mt_srv(UNIT *uptr)
}
break;
case MT_REW: /* 0x23 */ /* rewind tape */
case MT_REW: /* 0x23 */ /* rewind tape */
if (uptr->POS == 0) {
uptr->POS++;
sim_debug(DEBUG_CMD, dptr, "Start rewind unit %02x\n", unit);
@ -1076,21 +1114,27 @@ t_stat mt_srv(UNIT *uptr)
sim_debug(DEBUG_CMD, dptr, "Rewind complete unit %02x\n", unit);
uptr->CMD &= ~(MT_CMDMSK);
r = sim_tape_rewind(uptr);
uptr->SNS |= SNS_LOAD; /* set BOT */
uptr->SNS |= SNS_LOAD; /* set BOT */
mt_busy[bufnum] &= ~1;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
}
break;
case MT_RUN: /* 0x33 */ /* Rewind and unload tape */
case MT_RUN: /* 0x33 */ /* Rewind and unload tape */
if (uptr->POS == 0) {
uptr->POS++;
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, dptr, "Start rewind/unload unit %02x\n", unit);
sim_activate(uptr, 30000);
} else {
sim_debug(DEBUG_CMD, dptr, "Unload unit=%02x\n", unit);
uptr->CMD &= ~(MT_CMDMSK);
sim_debug(DEBUG_CMD, dptr, "Unload unit=%02x\n", unit);
uptr->CMD &= ~(MT_CMDMSK);
uptr->SNS |= SNS_INTVENT; /* unit intervention required */
uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */
uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */
r = sim_tape_detach(uptr);
//?? set_devattn(chsa, SNS_DEVEND); /* ready int???? */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
}
break;
}
@ -1104,11 +1148,11 @@ void mt_ini(UNIT *uptr, t_bool f)
if (MT_DENS(uptr->dynflags) == 0)
uptr->dynflags |= MT_DENS_6250 << UNIT_S_DF_TAPE;
uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */
uptr->SNS = 0; /* clear sense data */
uptr->SNS |= (SNS_RDY|SNS_ONLN|SNS_LOAD); /* set initial status */
mt_busy[GET_DEV_BUF(dptr->flags)] = 0; /* set not busy */
sim_cancel(uptr); /* cancel any timers */
uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */
uptr->SNS = 0; /* clear sense data */
uptr->SNS |= (SNS_RDY|SNS_ONLN|SNS_LOAD); /* set initial status */
mt_busy[GET_DEV_BUF(dptr->flags)] = 0; /* set not busy */
sim_cancel(uptr); /* cancel any timers */
sim_debug(DEBUG_EXP, dptr, "MT init device %s unit %02x\n",
dptr->name, GET_UADDR(uptr->CMD));
}
@ -1118,10 +1162,9 @@ uint16 mt_rschnlio(UNIT *uptr) {
DEVICE *dptr = get_dev(uptr);
uint16 chsa = GET_UADDR(uptr->CMD);
int cmd = uptr->CMD & MT_CMDMSK;
// int unit = (uptr - mt_unit); /* unit 0 */
sim_debug(DEBUG_EXP, dptr, "mt_rschnl chsa %04x cmd = %02x\n", chsa, cmd);
mt_ini(uptr, 0); /* reset the unit */
mt_ini(uptr, 0); /* reset the unit */
return SCPE_OK;
}
@ -1136,64 +1179,65 @@ t_stat mt_reset(DEVICE *dptr)
/* attach the specified file to the tape device */
t_stat mt_attach(UNIT *uptr, CONST char *file)
{
uint16 chsa = GET_UADDR(uptr->CMD); /* get address of mt device */
CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */
DEVICE *dptr = get_dev(uptr); /* get device pointer */
uint16 chsa = GET_UADDR(uptr->CMD); /* get address of mt device */
CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */
DEVICE *dptr = get_dev(uptr); /* get device pointer */
t_stat r;
DIB *dibp = 0;
/* mount the specified file to the MT */
if ((r = sim_tape_attach(uptr, file)) != SCPE_OK) {
sim_debug(DEBUG_EXP, dptr, "mt_attach ERROR filename %s status %08x\n", file, r);
return r; /* report any error */
return r; /* report any error */
}
sim_debug(DEBUG_EXP, dptr, "mt_attach complete filename %s\n", file);
uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */
uptr->POS = 0; /* clear position data */
uptr->SNS = 0; /* clear sense data */
uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */
uptr->POS = 0; /* clear position data */
uptr->SNS = 0; /* clear sense data */
uptr->SNS |= SNS_ONLN; /* 0x40 Drive Online */
/* check for valid configured tape */
/* must have valid DIB and Channel Program pointer */
dibp = (DIB *)dptr->ctxt; /* get the DIB pointer */
dibp = (DIB *)dptr->ctxt; /* get the DIB pointer */
if ((dib_unit[chsa] == NULL) || (dibp == NULL) || (chp == NULL)) {
sim_debug(DEBUG_CMD, dptr,
"ERROR===ERROR\nMT device %s not configured on system, aborting\n",
dptr->name);
printf("ERROR===ERROR\nMT device %s not configured on system, aborting\n",
dptr->name);
detach_unit(uptr); /* detach if error */
return SCPE_UNATT; /* error */
detach_unit(uptr); /* detach if error */
return SCPE_UNATT; /* error */
}
set_devattn(chsa, SNS_DEVEND); /* ready int???? */
return SCPE_OK; /* return good status */
set_devattn(chsa, SNS_DEVEND); /* ready int???? */
return SCPE_OK; /* return good status */
}
/* detach the MT device and unload any tape */
t_stat mt_detach(UNIT *uptr)
{
DEVICE *dptr = get_dev(uptr); /* get device pointer */
DEVICE *dptr = get_dev(uptr); /* get device pointer */
sim_debug(DEBUG_EXP, dptr, "mt_detach\n");
uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */
uptr->POS = 0; /* clear position data */
uptr->SNS = 0; /* clear sense data */
uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */
uptr->POS = 0; /* clear position data */
uptr->SNS = 0; /* clear sense data */
return sim_tape_detach(uptr);
}
/* boot from the specified tape unit */
t_stat mt_boot(int32 unit_num, DEVICE *dptr)
{
UNIT *uptr = &dptr->units[unit_num]; /* find tape unit pointer */
UNIT *uptr = &dptr->units[unit_num]; /* find tape unit pointer */
sim_debug(DEBUG_EXP, dptr, "MT Boot dev/unit %04x\n", GET_UADDR(uptr->CMD));
if ((uptr->flags & UNIT_ATT) == 0) { /* Is MT device already attached? */
if ((uptr->flags & UNIT_ATT) == 0) { /* Is MT device already attached? */
sim_debug(DEBUG_EXP, dptr,
"MT Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD));
return SCPE_UNATT; /* not attached, return error */
return SCPE_UNATT; /* not attached, return error */
}
SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */
SPAD[0xf8] = 0xF000; /* show as F class device */
SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */
SPAD[0xf8] = 0xF000; /* show as F class device */
uptr->CMD &= ~0xffff; /* clear out old status */
uptr->CMD &= ~0xffff; /* clear out old status */
return chan_boot(GET_UADDR(uptr->CMD), dptr); /* boot the ch/sa */
}

View File

@ -608,8 +608,7 @@ loop:
return 1; /* if none, error */
}
// sim_debug(DEBUG_XIO, dptr,
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_XIO, dptr,
"scfi_iocl @%06x before start_cmd chan %04x status %04x count %04x SNS %08x\n",
chp->chan_caw, chan, chp->chan_status, chp->ccw_count, uptr->u5);
@ -619,8 +618,7 @@ loop:
chp->chan_status = (chp->chan_status & 0xff00) | devstat;
chp->chan_info &= ~INFO_SIOCD; /* show not first IOCD in channel prog */
// sim_debug(DEBUG_XIO, dptr,
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_XIO, dptr,
"scfi_iocl @%06x after start_cmd chan %04x status %08x count %04x\n",
chp->chan_caw, chan, chp->chan_status, chp->ccw_count);
@ -651,16 +649,14 @@ loop:
if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) {
uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */
// sim_debug(DEBUG_XIO, dptr,
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_XIO, dptr,
"scfi_iocl @%06x FIFO #%1x cmd complete chan %04x status %04x count %04x\n",
chp->chan_caw, FIFO_Num(chsa), chan, chp->chan_status, chp->ccw_count);
}
}
/* the device processor returned OK (0), so wait for I/O to complete */
/* nothing happening, so return */
// sim_debug(DEBUG_XIO, dptr,
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_XIO, dptr,
"scfi_iocl @%06x return, chan %04x status %04x count %04x irq_pend %1x\n",
chp->chan_caw, chan, chp->chan_status, chp->ccw_count, irq_pend);
return 0; /* good return */
@ -673,8 +669,7 @@ uint16 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
int32 unit = (uptr - dptr->units);
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
// sim_debug(DEBUG_CMD, dptr,
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_CMD, dptr,
"scfi_startcmd chsa %04x unit %02x cmd %02x CMD %08x\n",
chsa, unit, cmd, uptr->CMD);
if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
@ -690,8 +685,7 @@ uint16 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
return SNS_BSY;
}
uptr->SNS2 |= SNS_USEL; /* unit selected */
// sim_debug(DEBUG_CMD, dptr,
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_CMD, dptr,
"scfi_startcmd CMD continue unit=%02x cmd %02x iocla %06x cnt %04x\n",
unit, cmd, chp->chan_caw, chp->ccw_count);
@ -769,8 +763,7 @@ uint16 scfi_haltio(UNIT *uptr) {
int cmd = uptr->CMD & DSK_CMDMSK;
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
// sim_debug(DEBUG_EXP, dptr,
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_EXP, dptr,
"scfi_haltio enter chsa %04x cmd = %02x\n", chsa, cmd);
/* terminate any input command */
@ -778,8 +771,7 @@ uint16 scfi_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_DETAIL, dptr,
sim_debug(DEBUG_CMD, dptr,
"scfi_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n",
chsa, cmd, chp->ccw_count);
/* stop any I/O and post status and return error status */
@ -787,16 +779,14 @@ uint16 scfi_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,
sim_debug(DEBUG_CMD, dptr,
"scfi_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */
return SCPE_IOERR;
}
uptr->CMD &= LMASK; /* make non-busy */
uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */
// sim_debug(DEBUG_CMD, dptr,
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_CMD, dptr,
"scfi_haltio HIO I/O not busy chsa %04x cmd = %02x\n", chsa, cmd);
return SCPE_OK; /* not busy */
}
@ -820,8 +810,7 @@ t_stat scfi_srv(UNIT *uptr)
uint8 buf[1024];
uint8 buf2[1024];
// sim_debug(DEBUG_CMD, dptr,
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_CMD, dptr,
"scfi_srv entry unit %02x CMD %08x chsa %04x count %04x %x/%x/%x \n",
unit, uptr->CMD, chsa, chp->ccw_count,
STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff));
@ -834,8 +823,7 @@ t_stat scfi_srv(UNIT *uptr)
}
}
// sim_debug(DEBUG_CMD, dptr,
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_CMD, dptr,
"scfi_srv cmd=%02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count);
switch (cmd) {
@ -1063,7 +1051,6 @@ t_stat scfi_srv(UNIT *uptr)
/* we have already seeked to the required sector */
/* we do not need to seek again, so move on */
chan_end(chsa, SNS_DEVEND|SNS_CHNEND);
// return SCPE_OK;
break;
} else {
/* we have wasted enough time, we are there */
@ -1546,7 +1533,6 @@ int scfi_format(UNIT *uptr) {
uint32 laddr = CAP(type) - 1; /* last sector of disk */
/* make up dummy defect map */
// uint32 dmap[4] = {0xf0000000 | (cap-1), 0x8a000000 | daddr,
uint32 dmap[4] = {0xf0000000 | (cap-1), 0x8a000000,
0x9a000000 | (cap-1), 0xf4000000};
@ -1640,9 +1626,7 @@ t_stat scfi_attach(UNIT *uptr, CONST char *file)
/* get sector address of utx diag map (DMAP) track 0 pointer */
/* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */
/* 0x9a000000 + (cyl-1), 0xf4000000 */
// int32 daddr = (CYL(type)-4) * SPC(type) + (HDS(type)-2) * SPT(type);
/* defect map */
// uint32 dmap[4] = {0xf0000000 | (CAP(type)-1), 0x8a000000 | daddr,
uint32 dmap[4] = {0xf0000000 | (CAP(type)-1), 0x8a000000,
0x9a000000 | (CAP(type)-1), 0xf4000000};
@ -1687,7 +1671,8 @@ t_stat scfi_attach(UNIT *uptr, CONST char *file)
printf("SCFI Disk attach ftell failed s=%06d\r\n", s);
goto fmt; /* not setup, go format */
}
sim_debug(DEBUG_CMD, dptr, "SCFI Disk attach ftell value s=%06d b=%06d CAP %06d\n", s/ssize, s, CAP(type));
sim_debug(DEBUG_CMD, dptr,
"SCFI Disk attach ftell value s=%06d b=%06d CAP %06d\n", s/ssize, s, CAP(type));
printf("SCFI 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? */
@ -1706,8 +1691,10 @@ t_stat scfi_attach(UNIT *uptr, CONST char *file)
}
s = ftell(uptr->fileref); /* get current file position */
sim_debug(DEBUG_CMD, dptr,
"SCFI Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\n", s/ssize, s);
printf("SCFI Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\r\n", s/ssize, s);
"SCFI Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\n",
s/ssize, s);
printf("SCFI Disk attach MPX 1.X file extended & sized secs %06d bytes %06d\r\n",
s/ssize, s);
}
/* seek last sector of disk */

View File

@ -320,9 +320,6 @@ UNIT sba_unit[] = {
{UDATA(&scsi_srv, UNIT_SCSI|SET_TYPE(0), 0), 0, UNIT_ADDR(0x7608)}, /* 1 */
};
//DIB sba_dib = {scsi_preio, scsi_startcmd, NULL, NULL, NULL, scsi_ini,
//sba_unit, sba_chp, NUM_UNITS_SCSI, 0x0f, 0x0400, 0, 0, 0};
DIB sba_dib = {
scsi_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */
scsi_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */
@ -481,7 +478,6 @@ uint16 scsi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
uptr->CMD |= cmd; /* save cmd */
sim_debug(DEBUG_CMD, dptr,
"scsi_startcmd starting disk seek r/w cmd %02x chsa %04x\n", cmd, chsa);
// sim_activate(uptr, 20); /* start things off */
sim_activate(uptr, 100); /* start things off */
return 0;
break;
@ -491,7 +487,6 @@ uint16 scsi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
cmd, chsa, uptr->SNS);
if (uptr->SNS & 0xff) /* any other cmd is error */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
// sim_activate(uptr, 20); /* start things off */
sim_activate(uptr, 100); /* start things off */
return SNS_CHNEND|SNS_DEVEND;
}
@ -637,7 +632,6 @@ t_stat scsi_srv(UNIT *uptr)
chan_write_byte(chsa, &ch);
/* bytes 4 - mode reg, byte 0 of SNS */
// ch = (uptr->SNS >> 24) & 0xff; /* return the sense data */
/* skip the TCMD bit */
ch = (uptr->SNS >> 24) & 0xfe; /* return the sense data */
sim_debug(DEBUG_DETAIL, dptr, "scsi_srv sense unit=%02x 1 %02x\n",
@ -681,7 +675,6 @@ t_stat scsi_srv(UNIT *uptr)
sim_debug(DEBUG_CMD, dptr, "scsi_srv seek over on cylinder unit=%02x %04x %04x\n",
unit, uptr->STAR, uptr->CHS);
uptr->CHS = uptr->STAR; /* we are there */
// sim_activate(uptr, 10);
sim_activate(uptr, 40);
break;
}
@ -1263,19 +1256,8 @@ read_cap: /* merge point from TCMD process
/* mema has IOCD word 1 contents. */
/* len has the byte count from IOCD wd2 */
len = chp->ccw_count; /* TCMD command count */
#ifdef NOTNOW
if (len != 36) {
/* we have invalid count, error, bail out */
uptr->CMD &= LMASK; /* remove old status bits & cmd */
uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
#endif
for (i=0; i < len; i++) {
if (chan_read_byte(chsa, &buf[i])) {
/* we have error, bail out */
@ -1319,8 +1301,7 @@ read_cap: /* merge point from TCMD process
return SNS_CHNEND|STATUS_PCHK;
break;
}
// sim_debug(DEBUG_CMD, dptr,
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_CMD, dptr,
"scsi_srv done cmd %02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count);
return SCPE_OK;
}

View File

@ -1024,8 +1024,6 @@ t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw)
rdx = 16; /* hex */
if (sw & SWMASK ('M')) { /* machine base mode? */
// sw &= ~ SWMASK('F'); /* Can't do F and M at same time */
// sw &= ~ SWMASK('W'); /* Can't do W and M at same time */
sw &= ~ SWMASK('B'); /* Can't do B and M at same time */
sw &= ~ SWMASK('C'); /* Can't do C and M at same time */
if (addr & 0x02)

View File

@ -25,55 +25,55 @@ cutostap - This program scans a metadata .tap file and copies files
user sdt tape with files following the sdt image.
command: cutostap <file.tap >stdout
input - stdin <file to remove sdt from
input - stdin <file to remove sdt image from
output - stdout >file to be written with sdt image
diskload - This program reads an MPX load module and stores it into
simulated diskfile. The MPX-1.x SMD entry for the file
simulated diskfile. The MPX 1.X SMD entry for the file
is entered into the SMD for the file. Will not work for
MPX 3.x file systems.
MPX 3.X file systems.
command: diskload -la program diskfile
option -a - add filename to diskfile
option -l - list files in diskfile SMD, ignore filename
input - filename - file to copy to system disk
- diskfile - simulated system disk
output - modified system disk
input - filename - file to copy to system disk
- diskfile - simulated system disk
output - modified system disk
filelist - This program scans a metadata .tap file and prints the
file count and sizes. Used to determine the file
format contained in the metadata .tap file.
command: filelist <file.tap >stdout
input - stdin <file to dump
input - stdin <file to dump
output - stdout
fmgrcopy - This program reads a MPX 1.x filemgr save tape. The tape
fmgrcopy - This program reads a MPX 1.X filemgr save tape. The tape
must contain a filemgr save image with 4608 byte records.
SMD entries and file data are modulo 1152 32 bit words or
4608 bytes. The program will create a directory in the
current directory for each different username. Null user
name will be the system directory. Within each directory
name will use the system directory. Within each directory
each file contained on the tape is extracted and written
as binary data to the named file. The .tap file MUST be
a filemgr save tape and not a MPX-1.x SDT tape.
a filemgr save tape and not a MPX 1.X SDT tape.
command: fmgrcopy file.tap >stdout
input - file.tap file to dump
output - stdout filelist and sizes
output - directory/files extracted to current directory
mkfmtape - This program creates an MPX 1.x filemgr save tape. The
tape can then be used to restore files to the MPX-1.X
mkfmtape - This program creates an MPX 1.X filemgr save tape. The
tape can then be used to restore files to the MPX 1.x
system. The output will be in SIMH simulated .tap format.
command: mkfmtape opts output.tap file1 file2 ...
input - list of filename to save to tape.
output - output.tap a tap formatted file.
options - -p = file type 0xca for programs
- -t = ascii text file 0xee
- -l = library/directory file 0xff
- -o = other 0x00
- -t = ASCII text file type 0xee
- -l = library/directory file type 0xff
- -o = other type 0x00
- -a = append entries to current file
- -u = username (directory)
@ -89,9 +89,9 @@ mkvmtape - This program reads MPX files and stores them into a
output - volmtape file, file list to stdout
options - -p = file type 0xca for programs
- -t = ascii text file 0xee
- -l = library/directory file 0xff
- -o = other 0x00
- -t = ASCII text file type 0xee
- -l = library/directory file type 0xff
- -o = other type 0x00
- -a = append entries to current file
- -u = username (username)
- -d = dirname (directory)
@ -99,7 +99,6 @@ mkvmtape - This program reads MPX files and stores them into a
- -b = bootfile name
- -i = system image file
- -j = j.vfmt filename
04/11/2020 update for mpx3.x
mkdiagtape.c - This program extracts the diag command file (file 2)
from a diagnostic tape in .tap format and replaces it
@ -132,7 +131,7 @@ diagcopy - This program reads a SEL .tap diagnostic boot tape and splits
the contents into multiple files. The first tape record
is 204 bytes of boot code and is put into the file bootcode.
The following records in the file contains the diagnostic
overlay program (DOL) and are in 7680 byte block. The last
overlay program (DOL) and are in 7680 byte blocks. The last
record can be <= 7680 bytes. The data is put into the file
dolfile. The 2nd file on the tape contains the diagnostic
auto execute file. It is a MPX blocked file where the first
@ -152,21 +151,21 @@ diagcopy - This program reads a SEL .tap diagnostic boot tape and splits
tapdump - This program reads a metadata .tap file and prints a side
by side hexdump of the file contents. The records are
displayed as 256 byte chuncks. After each record if 256
bytes are displayed, hitting <cr> will continue dump,
hitting <q> will terminate the display, and hitting <s>
displayed as 256 byte chuncks. After each record of 256
bytes are displayed, hitting C/R will continue dumping,
hitting 'q' will terminate the display, and hitting 's'
will skip to the next file on the simulated tape.
command: tapdump <file.tap >stdout
input - stdin <file to dump
input - stdin <file to dump
output - stdout
tape2disk - This program reads a tape assigned as input device. It
generates a .tap metadata file. Stdout will contain a
listing of the files and sizes written to disk. The define
#define FILEMGR must be compiled in for tapes ending with
two EOFs. Unix and MPX 1.x filemgr tapes use that format.
MPX 3.x volmgr save tapes contain three EOFs so comment out
two EOFs. Unix and MPX 1.X filemgr tapes use that format.
MPX 3.X volmgr save tapes contain three EOFs so comment out
the define for that case.
command: tape2disk mt00 [file.tap]
@ -185,15 +184,15 @@ disk2tap - This program reads a file assigned as input device. It
tapscan - This program scans a metadata .tap file and prints the
file count and sizes. Used to determine the file
format contained in the metadata .tap file.
command: tapscan file.tap >stdout
input - file.tap file to scan
output - stdout filelist and sizes
volmcopy - This program reads a MPX 3.x volmgr save tape. The tape
volmcopy - This program reads a MPX 3.X volmgr save tape. The tape
must contain a volmgr save image with 6144 byte records
containing a list of saved files. Followed by directdory
containing a list of saved files. Followed by directory
entries of 1536 bytes and finally file data of 1 to 8 768
byte records. Files larger than 6144 bytes will be output
as modulo 6144 bytes. There is an EOF after each file
@ -201,7 +200,7 @@ volmcopy - This program reads a MPX 3.x volmgr save tape. The tape
current directory for each different directory. Within
each directory each file contained on the tape is extracted
and written as binary data to the named file. The .tap
file MUST be a volmgr save tape and not a MPX-1.x SDT/save
file MUST be a volmgr save tape and not a MPX 1.X SDT/save
tape.
command: fmgrcopy file.tap >stdout
@ -211,51 +210,51 @@ volmcopy - This program reads a MPX 3.x volmgr save tape. The tape
General utilities for MPX
ddump - Create a sys by side ascii dump of a file. Same operation
ddump - Create a side by side ASCII dump of a file. Same operation
as the DDUMP utility in MPX. 256 bytes are displayed at
a time. Hitting <cr> will continue to next 256 bytes. A
a time. Hitting C/R will continue to next 256 bytes. A
hex address can be input to display data at a given offset
in the file. Optionall, the file data can be modified.
in the file. Optionally, the file data can be modified.
command: ddump -r filename
option - -r means open file read only
input - filename file to read
output - side by size ascii dump of file
output - side by size ASCII dump of file
deblk - read and convert mpx blocked ifile to unblocked unix file
deblk - read and convert a MPX blocked file to unblocked UNIX file
format. Compressed and uncompressed files records can be
read. Output is an ascii string with '\n' termination.
read. Output is an ASCII string with '\n' termination.
command: deblk [filename]
input - filename or if non specified, stdin
output - ascii sting to stdout
output - ASCII sting to stdout
mpxblk - Create an MPX blocked file from a '\n' terminated ascii
mpxblk - Create an MPX blocked file from a '\n' terminated ASCII
character string file. Trailing blanks are not deleted
from the source file. Max line size is 254 bytes.
command: mpxblk <filein >fileout
input - read ascii file from stdin
output - write mpx blocked file to stdout
input - read a '\n' terminated ASCII file from stdin
output - write MPX blocked file to stdout
renum - Create a numbered file from a '\n' terminated ascii file.
The input file is assumed to be a standard unix file. The
renum - Create a numbered file from a '\n' terminated ASCII file.
The input file is assumed to be a standard UNIX file. The
input lines are truncated or expaned to lines of 72 chars.
A line number in the form of XXXX.000 are appended to
A line number in the form of XXXX.000 is appended to
create 80 char '\n' terminated lines.
command: renum <filein >fileout
input - read ascii file from stdin
output - write numbered ascii file to stdout
input - read ASCII file from stdin
output - write numbered ASCII file to stdout
small - Remove line numbers and trailing blanks from an ascii '\n'
small - Remove line numbers and trailing blanks from an ASCII '\n'
terminated file. Lines are terminated at 72 chars and then
stripped of trailing blanks. Output is '\n' terminated
ascii files.
ASCII files.
command: small <filein >fileout
input - read ascii file from stdin
output - write stripped ascii file to stdout
input - read ASCII file from stdin
output - write stripped ASCII file to stdout
James C. Bevier
08/21/2020
02/15/2021

View File

@ -154,24 +154,23 @@ char *argv[];
* This function computes and checks the checksum of a compressed file
*/
int checksum(buf)
char *buf;
unsigned char *buf;
{
int i = 0;
// unsigned int ccs = 0; /*zero checksum */
short int ccs = 0; /*zero checksum */
unsigned int rcs = (((buf[2] << 8) & 0xff00) | (buf[3] & 0xff)); /* get checksum */
int cnt = buf[1]; /* record count */
// fprintf(stderr, "checksum data %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
int cnt = buf[1] & 0xff; /* record count */
//fprintf(stderr, "checksum cnt %x data %x %x %x %x %x %x %x %x\n",
// cnt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
while (cnt > 0) {
// unsigned int v = buf[i+6];
short v = buf[i+6] & 0xff;
unsigned short v = buf[i+6] & 0xff;
ccs += v; /* add the byte */
// fprintf(stderr, "checksum cnt %x val %x sum %x\n", i, v, ccs);
//fprintf(stderr, "checksum cnt %x val %x sum %x\n", i, v, ccs);
i++; /* bump address */
cnt--; /* reduce count */
}
// fprintf(stderr, "checksum size %x read %x calc %x\n", buf[1], rcs, ccs);
//fprintf(stderr, "checksum size %x read %x calc %x\n", buf[1], rcs, ccs);
if (ccs == rcs)
return 0; /* return OK */
return 1; /* return error */
@ -241,18 +240,25 @@ int getb(fp)
FILE *fp;
{
int c;
static int goteof = 0;
/* file is unblocked, get next record */
if (goteof) {
goteof = 0;
//fprintf(stderr, "getb - returning EOF ubdc=%x\n", ubdc);
return (-1); /* this means eof */
}
if (ubdp < ubdc) /* is count exhausted */
c = si[ubdp++] & 0xff; /* copy char */
if (ubdp >= ubdc) { /* is count exhausted */
/* need to read next block, if not first time */
/* we need a new buffer */
/* read in 768 byte block of the file */
if ((ubdc = fread(si, 1, BLKSIZE, fp)) <= 0)
return (-1); /* this means eof */
//fprintf(stderr, "getb - read unblocked file ubdc=%x\n", ubdc);
goteof = 1; /* this means eof */
//fprintf(stderr, "getb - read unblocked file goteof %x ubdc=%x\n", goteof, ubdc);
ubdp = 0;
}
c = si[ubdp++] & 0xff; /* copy char */
return (c);
}
@ -262,7 +268,7 @@ FILE *fp;
unsigned char s[];
int lim;
{
int c, i, cc, rc = 0;
int c, i, cc, bc = 0, rc = 0;
/* see how we are to process data */
if (filetype & blocked) {
@ -312,49 +318,64 @@ newbuf:
if (filetype & compress) {
cc = 120;
rc = 0;
bc = 0;
while ((c = getb(fp)) != -1) {
/* skip any optional newline from previous record */
// if ((rc == 0) && (c == '\n'))
// continue;
/* make sure this is a compressed record */
if ((rc == 0) && ((c & 0x9f) != 0x9f)) {
fprintf(stderr, "getloi - unblocked compressed file read error %x\n", c);
fprintf(stderr, "getloi - unblocked compressed file read error %x rc %x\n", c, rc);
return (0); /* this means error */
}
if (rc == 1)
cc = c + 6; /* get 'real' record count */
s[rc++] = c; /* save the char */
if (rc == cc)
// if (rc == 120) /* compressed is always 120 char buffers */
if (rc == cc) /* compressed record is always <= 120 char buffers */
break; /* done */
}
if (c == -1)
return (0); /* this means EOF */
/* skip any extra chars from short records */
while ((c = getb(fp)) != '\n')
;
bc = rc;
while ((s[0] != 0x9f) && (bc < 120)) {
if ((c = getb(fp)) == -1)
return (0); /* this means EOF */
s[bc++] = c; /* fill extra chars */
//fprintf(stderr, "getloi - filling extra chars with char %x bc %x\n", c, bc);
}
/* next char should be bf/9f */
if ((si[ubdp] & 0x9f) != 0x9f) { /* copy char */
if ((c = getb(fp)) == -1) {
//fprintf(stderr, "getloi skipping exit char %0x at end of line, next %x s[0] %0x\n", c, si[ubdp], s[0]);
if (s[0] != 0x9f)
return (0); /* this means EOF */
}
//fprintf(stderr, "getloi skipping char %0x at end of line, next %x s[0] %0x\n", c, si[ubdp], s[0]);
}
//fprintf(stderr, "getloi unblked comp read done rc %x cc %x s[0] %x s[rc-1] %x next %x\n",
//rc, cc, s[0], s[rc-1], si[ubdp]);
/* checksum the record */
if (checksum(s)) {
fprintf(stderr, "getloi - unblocked compressed file checksum error\n");
//fprintf(stderr, "getloi A unblocked compressed read return rc=%x cc=%x %x %x\n", rc, cc, s[0], s[rc-1]);
//fprintf(stderr, "getloi C unblocked compressed read return %x ubdc %x ubdp %x\n", rc, ubdc, ubdp);
return (0); /* this means error */
return (0); /* this means error */
}
//fprintf(stderr, "getloi B unblocked compressed read return rc=%x cc=%x %x\n", rc, cc, s[1]);
return (rc); /* return data count */
return (rc); /* return data count */
}
/* file is uncompressed, so copy UNIX records */
while ((c = getb(fp)) != -1) {
s[rc++] = c; /* save the char */
s[rc++] = c; /* save the char */
if (c == 0x0a) {
//fprintf(stderr, "getloi C unblocked compressed read return %x ubdc %x ubdp %x\n", rc, ubdc, ubdp);
s[rc++] = 0; /* terminate the line */
return (rc); /* return data */
}
}
return (0); /* EOF */
return (0); /* EOF */
}
return (0);
#ifdef JUNK
@ -405,6 +426,7 @@ unsigned char *s;
}
unsigned char line[BUFSIZ];
unsigned char line2[BUFSIZ];
int cmpop = 0;
int cmpflg = 0;
int bcnt = 0;
@ -518,7 +540,7 @@ int n;
}
}
if ((filetype & compress) && !cmpop) { /* see if we tested for compressed */
cmpop = 1; /* set comp tested flag */
cmpop = 1; /* set compresse tested flag */
/* read in the first record */
if ((recl = getloi(fp, line, BUFSIZ)) == 0)
return (0); /* this means eof */
@ -541,7 +563,7 @@ int n;
if ((recl = getloi(fp, line, BUFSIZ)) == 0)
return (0); /* this means eof */
linadrs = line;
//fprintf(stderr, "rbl re18 - read compressed record cnt %x %x\n", bcnt, linadrs[0]);
//fprintf(stderr, "rbl re18 - read compressed record recl %x cnt %x 1st %x\n", recl, bcnt, linadrs[0]);
if ((*linadrs & 0x9f) != 0x9f) /* is this valid rec */
return (EOF); /* error if not */
bcnt = linadrs[1]; /* set record count */
@ -553,6 +575,7 @@ int n;
if (i = *bptr++) { /* next buffer pointer */
if (i == 0xff)
goto re60; /* if eol, get out */
/* insert the required number of blanks */
while (i--) {
if (count < n) {
*buf++ = ' '; /* put blank in buffer */
@ -565,6 +588,8 @@ int n;
/* get character count */
if (i = *bptr++) { /* next buffer pointer */
/*try*/ if (i == 0xff)
/*0216*/ goto re60; /* if eol, get out */
while (i--) {
if (count < n)
*buf++ = *bptr; /* put char in buffer */
@ -617,6 +642,6 @@ int n;
buf[count++] = '\n';
buf[count] = '\0';
}
//fprintf(stderr, "rbl - read return cnt %x %s\n", count, line);
//fprintf(stderr, "rbl - read return cnt %x\n", count);
return (count);
}

View File

@ -34,7 +34,9 @@ int lim;
i = 72;
for (; i<72; i++)
s[i] = ' ';
sprintf(line, "%04d.000", ln++);
// sprintf(line, "%04d.000", ln++);
sprintf(line, "%04d.%01d00", ln/10, ln%10);
ln++;
for (j=0; j<8; j++)
s[72+j] = line[j];
s[80] = '\n';