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:
parent
296a7b4192
commit
3ddc772ce2
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
8547
SEL32/sel32_cpu.c
8547
SEL32/sel32_cpu.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
||||
|
||||
146
SEL32/sel32_ec.c
146
SEL32/sel32_ec.c
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
398
SEL32/sel32_mt.c
398
SEL32/sel32_mt.c
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user