1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-01-13 07:19:26 +00:00

SEL32: Correct real time clock interrupt processing.

SEL32: start code cleanup.
SEL32: add mfp and mfp scsi disk intitial support code.
SEL32: add new files sel32_mfp.c and sel32_scsi.c to makefile.
SEL32: modify sel32_mt.c code to define tape as BTP for UTX.
This commit is contained in:
AZBevier 2020-03-06 21:41:59 -07:00
parent 5ae42ddddd
commit d198882980
17 changed files with 2335 additions and 394 deletions

View File

@ -102,11 +102,11 @@ uint16 loading; /* set when booting */
/* forward definitions */
CHANP *find_chanp_ptr(uint16 chsa); /* find chanp pointer */
UNIT *find_unit_ptr(uint16 chsa); /* find unit pointer */
int chan_read_byte(uint16 chan, uint8 *data);
int chan_write_byte(uint16 chan, uint8 *data);
int chan_read_byte(uint16 chsa, uint8 *data);
int chan_write_byte(uint16 chsa, uint8 *data);
void set_devattn(uint16 chsa, uint16 flags);
void set_devwake(uint16 chsa, uint16 flags); /* wakeup O/S for async line */
void chan_end(uint16 chan, uint16 flags);
void chan_end(uint16 chsa, uint16 flags);
int test_write_byte_end(uint16 chsa);
t_stat checkxio(uint16 chsa, uint32 *status); /* check XIO */
t_stat startxio(uint16 chsa, uint32 *status); /* start XIO */
@ -125,6 +125,7 @@ t_stat chan_set_devs();
t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat show_dev_addr(FILE *st, UNIT *uptr, int32 v, CONST void *desc);
DEVICE *get_dev(UNIT *uptr);
void store_csw(CHANP *chp);
/* FIFO support */
/* These are FIFO queues which return an error when full.
@ -173,7 +174,7 @@ int FIFO_Get(uint16 chsa, uint32 *old)
t_stat set_inch(UNIT *uptr, uint32 inch_addr) {
uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */
uint32 chan = chsa & 0x7f00; /* get just channel address */
CHANP *pchp = find_chanp_ptr(chan); /* get channel channel prog ptr */
CHANP *pchp = find_chanp_ptr(chan); /* get channel prog ptr */
DIB *dibp; /* get DIB pointer for channel */
CHANP *chp;
int i;
@ -320,7 +321,7 @@ CHANP *find_chanp_ptr(uint16 chsa)
CHANP *chp; /* CHANP pointer */
int i;
dibp = dev_unit[chsa]; /* get DIB pointer from device pointers */
dibp = dev_unit[chsa&0x7fff]; /* get DIB pointer from device pointers */
if (dibp == 0) /* if zero, not defined on system */
return NULL; /* tell caller */
if ((chp = (CHANP *)dibp->chan_prg) == NULL) { /* must have channel information for each device */
@ -369,10 +370,13 @@ int readbuff(CHANP *chp)
{
int k;
uint32 addr = chp->ccw_addr; /* channel buffer address */
uint16 chan = get_chan(chp->chan_dev); /* our channel */
//XXX uint16 chan = get_chan(chp->chan_dev); /* our channel */
if ((addr & MASK24) >= (MEMSIZE*4)) { /* see if memory address invalid */
chp->chan_status |= STATUS_PCHK; /* bad, program check */
sim_debug(DEBUG_EXP, &cpu_dev,
"readbuff PCHK addr %08x to big mem %08x status %04x\n",
addr, MEMSIZE, chp->chan_status);
chp->chan_byte = BUFF_CHNEND; /* force channel end */
irq_pend = 1; /* and we have an interrupt */
return 1; /* done, with error */
@ -386,8 +390,9 @@ int readbuff(CHANP *chp)
#endif
#ifdef TEST
sim_debug(DEBUG_DETAIL, &cpu_dev, "readbuff read memory bytes into buffer %02x %06x %06x %04x [",
chan, chp->ccw_addr & 0xFFFFFC, chp->chan_buf, chp->ccw_count);
sim_debug(DEBUG_DETAIL, &cpu_dev,
"readbuff read memory chsa %04x into buffer %06x %06x %04x [",
chp->chan_dev, chp->ccw_addr & 0xFFFFFC, chp->chan_buf, chp->ccw_count);
for(k = 24; k >= 0; k -= 8) {
char ch = (chp->chan_buf >> k) & 0xFF;
if (ch < 0x20 || ch == 0xff)
@ -409,7 +414,7 @@ int writebuff(CHANP *chp)
if ((addr & MASK24) >= (MEMSIZE*4)) {
chp->chan_status |= STATUS_PCHK;
sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"writebuff PCHK addr %08x to big mem %08x status %04x\n",
addr, MEMSIZE, chp->chan_status);
chp->chan_byte = BUFF_CHNEND;
@ -423,7 +428,7 @@ int writebuff(CHANP *chp)
#ifdef TEST
M[addr>>2] = chp->chan_buf;
#else
WMB(addr, chp->chan_buf); /* write byte to bebory */
WMB(addr, chp->chan_buf); /* write byte to memory */
#endif
return 0;
}
@ -434,7 +439,6 @@ int writebuff(CHANP *chp)
int load_ccw(CHANP *chp, int tic_ok)
{
uint32 word;
// uint8 devstat;
int docmd = 0;
UNIT *uptr = find_unit_ptr(chp->chan_dev); /* find the unit pointer */
uint16 chan = get_chan(chp->chan_dev); /* our channel */
@ -567,24 +571,27 @@ loop:
}
#endif
if (docmd) { /* see if we need to process command */
#ifdef TRY_THIS_TUESDAY_0301
uint8 devstat;
#endif
// DEVICE *dptr = get_dev(uptr); /* find the device from unit pointer */
DIB *dibp = dev_unit[chp->chan_dev]; /* get the device pointer */
uptr = find_unit_ptr(chp->chan_dev); /* find the unit pointer */
if (uptr == 0)
return 1; /* if none, error */
sim_debug(DEBUG_XIO, &cpu_dev,
"load_ccw before start_cmd chan %04x status %04x count %04x\n",
// chan, chp->chan_status, chp->ccw_count, dptr->name);
chan, chp->chan_status, chp->ccw_count);
/* call the device startcmd function to process the current command */
#ifndef TRY_THIS_TUESDAY
#ifndef TRY_THIS_TUESDAY_0301
chp->chan_status = dibp->start_cmd(uptr, chan, chp->ccw_cmd);
#else
/* just replace device status bits */
devstat = dibp->start_cmd(uptr, chan, chp->ccw_cmd);
chp->chan_status = (chp->chan_status & 0xffffff00) | (devstat & 0xff);
chp->chan_status = (chp->chan_status & 0xff00) | (devstat & 0xff);
#endif
sim_debug(DEBUG_XIO, &cpu_dev,
@ -612,6 +619,9 @@ loop:
sim_debug(DEBUG_XIO, &cpu_dev,
"load_ccw cmd complete chan %04x status %04x count %04x\n",
chan, chp->chan_status, chp->ccw_count);
/* we want to terminate if command is complete */
/* go store status and return CC2 */
/*NEW*/ return 1; /* return cmd complete */
}
}
sim_debug(DEBUG_XIO, &cpu_dev,
@ -720,7 +730,7 @@ int chan_write_byte(uint16 chsa, uint8 *data)
}
if (chp->ccw_count == 0) {
sim_debug(DEBUG_EXP, &cpu_dev,
"chan_write_byte ZERO ccw_count[%04x] %04x addr %06x\n",
"chan_write_byte ZERO chan %04x ccw_count %04x addr %06x\n",
chan, chp->ccw_count, chp->ccw_addr);
if (chp->chan_byte & BUFF_DIRTY) {
sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte 2 BUF DIRTY ret\n");
@ -844,7 +854,7 @@ void chan_end(uint16 chsa, uint16 flags) {
chp->chan_status |= ((uint16)flags); /* add in the callers flags */
// chp->ccw_cmd = 0; /* reset the completed channel command */
sim_debug(DEBUG_XIO, &cpu_dev,
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);
#ifdef HACK_HACK
@ -869,12 +879,12 @@ void chan_end(uint16 chsa, uint16 flags) {
}
}
#endif
sim_debug(DEBUG_XIO, &cpu_dev,
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);
chp->ccw_cmd = 0; /* reset the completed channel command */
/* Diags dos not want SLI if we have no device end status */
/* Diags do not want SLI if we have no device end status */
if ((chp->chan_status & FLAG_SLI) && ((chp->chan_status & STATUS_DEND) == 0))
chp->chan_status &= ~FLAG_SLI;
@ -883,7 +893,7 @@ void chan_end(uint16 chsa, uint16 flags) {
chp->ccw_flags = 0; /* no flags */
}
sim_debug(DEBUG_XIO, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"chan_end test end chsa %04x ccw_flags %04x status %04x\n",
chsa, chp->ccw_flags, chp->chan_status);
@ -898,8 +908,57 @@ void chan_end(uint16 chsa, uint16 flags) {
chp->ccw_flags = 0; /* no flags */
}
}
sim_debug(DEBUG_XIO, &cpu_dev,
"chan_end IOCL done chsa %04x ccw_flags %04x status %04x\n",
chsa, chp->ccw_flags, chp->chan_status);
#ifndef NEW_METHOD
/* If channel end, check if we should continue */
if (chp->chan_status & STATUS_CEND) { /* do we have channel end */
sim_debug(DEBUG_XIO, &cpu_dev,
"chan_end chan end chsa %04x flags %04x status %04x\n",
chsa, chp->ccw_flags, chp->chan_status);
if (chp->ccw_flags & FLAG_CC) { /* command chain flag */
/* we have channel end and CC flag, continue channel prog */
sim_debug(DEBUG_XIO, &cpu_dev,
"chan_end chan end & CC chsa %04x status %04x\n",
chsa, chp->chan_status);
if (chp->chan_status & STATUS_DEND) { /* device end? */
sim_debug(DEBUG_XIO, &cpu_dev,
"chan_end dev end & CC chsa %04x status %04x\n",
chsa, chp->chan_status);
(void)load_ccw(chp, 1); /* go load the next IOCB */
} else
irq_pend = 1; /* still pending int */
} else {
/* we have channel end and no CC flag, end command */
chsa = chp->chan_dev; /* get the chan/sa */
sim_debug(DEBUG_XIO, &cpu_dev,
"chan_end chan end & no CC chsa %04x status %04x\n",
chsa, chp->chan_status);
dev_status[chsa] = 0; /* no device status anymore */
/* we have completed channel program */
/* handle case where we are loading the O/S on boot */
/* if loading, leave status to be discovered by scan_chan */
if (!loading) {
sim_debug(DEBUG_DETAIL, &cpu_dev,
"chan_end call store_csw dev end & chan end chsa %04x cpustatus %08x\n",
chsa, CPUSTATUS);
store_csw(chp); /* store the status */
}
irq_pend = 1; /* flag to test for int condition */
else
sim_debug(DEBUG_DETAIL, &cpu_dev,
"chan_end we are loading with DE & CE, keep status chsa %04x status %08x\n",
chsa, chp->chan_status);
//XXX irq_pend = 1; /* still pending int */
}
}
else
sim_debug(DEBUG_DETAIL, &cpu_dev,
"chan_end IOCL2 done chsa %04x ccw_flags %04x status %04x\n",
chsa, chp->ccw_flags, chp->chan_status);
#endif
}
//XXX irq_pend = 1; /* flag to test for int condition */
}
/* store the device status into the status DW in memory */
@ -965,24 +1024,26 @@ t_stat checkxio(uint16 lchsa, uint32 *status) {
chp = find_chanp_ptr(chsa); /* find the chanp pointer */
uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */
sim_debug(DEBUG_CMD, &cpu_dev, "checkxio 1 chsa %04x chan %04x\n", chsa, chan);
sim_debug(DEBUG_DETAIL, &cpu_dev, "checkxio 1 chsa %04x chan %04x\n", chsa, chan);
if (dibp == 0 || uptr == 0) { /* if no dib or unit ptr, CC3 on return */
*status = CC3BIT; /* not found, so CC3 */
sim_debug(DEBUG_XIO, &cpu_dev, "checkxio chsa %04x is not found, CC3 return\n", chsa);
sim_debug(DEBUG_XIO, &cpu_dev,
"checkxio chsa %04x is not found, CC3 return\n", chsa);
return SCPE_OK; /* not found, CC3 */
}
if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { /* is unit attached? */
sim_debug(DEBUG_XIO, &cpu_dev, "checkxio chsa %04x is not attached, CC3 return\n", chsa);
sim_debug(DEBUG_XIO, &cpu_dev,
"checkxio chsa %04x is not attached, CC3 return\n", chsa);
*status = CC3BIT; /* not attached, so error CC3 */
return SCPE_OK; /* not found, CC3 */
}
/* see if interrupt is setup in SPAD and determine IVL for channel */
sim_debug(DEBUG_CMD, &cpu_dev, "checkxio dev spad %08x chsa %04x\n", spadent, chsa);
sim_debug(DEBUG_DETAIL, &cpu_dev, "checkxio dev spad %08x chsa %04x\n", spadent, chsa);
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_CMD, &cpu_dev, "checkxio int spad %08x inta %04x chan %04x\n", spadent, inta, chan);
sim_debug(DEBUG_DETAIL, &cpu_dev, "checkxio int spad %08x inta %04x chan %04x\n", spadent, inta, chan);
/* get the address of the interrupt IVL in main memory */
chan_ivl = SPAD[0xf1] + (inta<<2); /* contents of spad f1 points to chan ivl in mem */
@ -990,8 +1051,11 @@ t_stat checkxio(uint16 lchsa, uint32 *status) {
iocla = M[(chan_ivl+16)>>2]; /* iocla is in wd 4 of ICB */
tempa = M[(chan_ivl+20)>>2]; /* status is in wd 5 of ICB */
sim_debug(DEBUG_CMD, &cpu_dev,
"checkxio busy ck chsa %04x cmd %02x iocla %08x flags %04x IOCD1 %08x IOCD2 %08x status %08x\n",
chsa, chp->ccw_cmd, iocla, chp->ccw_flags, M[iocla>>2], M[(iocla+4)>>2], tempa);
"checkxio busy ck1 chsa %04x cmd %02x iocla %06x flags %04x\n",
chsa, chp->ccw_cmd, iocla, chp->ccw_flags);
sim_debug(DEBUG_CMD, &cpu_dev,
"checkxio busy ck2 chsa %04x IOCD1 %08x IOCD2 %08x INCH %08x\n",
chsa, M[iocla>>2], M[(iocla+4)>>2], tempa);
/* check for a Command or data chain operation in progresss */
if (chp->ccw_cmd != 0 || (chp->ccw_flags & (FLAG_DC|FLAG_CC)) != 0) {
@ -1007,7 +1071,8 @@ t_stat checkxio(uint16 lchsa, uint32 *status) {
tempa = dibp->pre_io(uptr, chan); /* get status from device */
if (tempa != 0) { /* see if sub channel status is ready */
/* The device must be busy or something, but it is not ready. Return busy */
sim_debug(DEBUG_XIO, &cpu_dev, "checkxio CC3 & CC4 return busy chan %04x cstat %08x\n",
sim_debug(DEBUG_XIO, &cpu_dev,
"checkxio CC3 & CC4 return busy chan %04x cstat %08x\n",
chan, tempa);
*status = CC3BIT|CC4BIT; /* sub channel busy, so CC3|CC4 */
return SCPE_OK; /* just busy or something, CC3|CC4 */
@ -1116,7 +1181,7 @@ t_stat startxio(uint16 lchsa, uint32 *status) {
if (chp->chan_status & STATUS_PCHK) {
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */
chp->chan_status &= ~STATUS_LENGTH; /* clear incorrect length */
store_csw(chp); /* store the status in the inch status dw */
//XXX store_csw(chp); /* store the status in the inch status dw */
dev_status[chsa] = 0; /* no device status */
//DIAG *status = CC2BIT; /* status stored, so CC2 */
*status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */
@ -1159,24 +1224,24 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */
uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */
pchp = find_chanp_ptr(chsa & 0x7f00); /* find the channel chanp pointer */
sim_debug(DEBUG_XIO, &cpu_dev, "testxio 1 chsa %04x chan %04x\n", chsa, chan);
sim_debug(DEBUG_DETAIL, &cpu_dev, "testxio 1 chsa %04x chan %04x\n", chsa, chan);
if ((dibp == 0) || (uptr == 0)) { /* if non found, CC3 on return */
*status = CC3BIT; /* not found, so CC3 */
goto tioret; /* not found, CC3 */
}
sim_debug(DEBUG_XIO, &cpu_dev, "testxio 2 chsa %04x chan %04x\n", chsa, chan);
sim_debug(DEBUG_DETAIL, &cpu_dev, "testxio 2 chsa %04x chan %04x\n", chsa, chan);
if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { /* is unit attached? */
*status = CC3BIT; /* not attached, so error CC3 */
goto tioret; /* not found, CC3 */
}
/* see if interrupt is setup in SPAD and determine IVL for channel */
sim_debug(DEBUG_XIO, &cpu_dev, "testxio dev spad %08x chsa %04x chan %04x\n", spadent, chsa, chan);
sim_debug(DEBUG_DETAIL, &cpu_dev, "testxio dev spad %08x chsa %04x chan %04x\n", spadent, chsa, chan);
/* the startio opcode processing software has already checked for F class */
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, "testxio int spad %08x inta %04x chan %04x\n", spadent, inta, chan);
sim_debug(DEBUG_DETAIL, &cpu_dev, "testxio int spad %08x inta %04x chan %04x\n", spadent, inta, chan);
/* get the address of the interrupt IVL in main memory */
chan_ivl = SPAD[0xf1] + (inta<<2); /* contents of spad f1 points to chan ivl in mem */
@ -1187,9 +1252,6 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */
"testxio busy test chsa %04x cmd %02x flags %04x IOCD1 %08x IOCD2 %08x IOCLA %08x\n",
chsa, chp->ccw_cmd, chp->ccw_flags, M[iocla>>2], M[(iocla+4)>>2], iocla);
sim_debug(DEBUG_XIO, &cpu_dev, "$$ TIO chsa %04x chan %04x cmd %02x flags %04x\n",
chsa, chan, chp->ccw_cmd, chp->ccw_flags);
/* check for a Command or data chain operation in progresss */
if (chp->ccw_cmd != 0 || (chp->ccw_flags & (FLAG_DC|FLAG_CC)) != 0) {
sim_debug(DEBUG_CMD, &cpu_dev,
@ -1197,7 +1259,20 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */
*status = CC4BIT; /* busy, so CC4 */
goto tioret; /* just busy CC4 */
}
//#define NEW_LOOK
#ifdef NEW_LOOK
/* see if status already posted and requesting interrupt */
if (INTS[inta] & INTS_REQ) {
/* we have status and a request, tell caller */
*status = CC2BIT; /* status stored from SIO, so CC2 */
INTS[inta] &= ~INTS_REQ; /* turn off request bit */
goto tioret; /* CC2 and OK */
}
#endif
/* the channel is not busy, see if any status to post */
/* see if the FIFO is empty */
if (dibp->chan_fifo_in != dibp->chan_fifo_out) {
if ((FIFO_Get(chsa, &sw1) == 0) && (FIFO_Get(chsa, &sw2) == 0)) {
uint32 chan_icb = find_int_icb(chsa); /* get icb address */
@ -1213,6 +1288,7 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */
*status = CC2BIT; /* status stored from SIO, so CC2 */
goto tioret; /* CC2 and OK */
}
}
/* nothing going on, so say all OK */
*status = CC1BIT; /* request accepted, no status, so CC1 */
tioret:
@ -1323,8 +1399,8 @@ t_stat rschnlxio(uint16 lchsa, uint32 *status) { /* reset channel XIO */
chp->chan_inch_addr = 0; /* remove inch status buffer address */
lev = find_int_lev(chan); /* get our int level */
INTS[lev] &= ~INTS_ACT; /* clear level active */
INTS[lev] &= ~INTS_REQ; /* clear level request */
SPAD[lev+0x80] &= ~SINT_ACT; /* clear spad too */
INTS[lev] &= ~INTS_REQ; /* clear level request */
/* now go through all the sa for the channel and stop any IOCLs */
for (i=0; i<256; i++) {
@ -1414,9 +1490,12 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
return SCPE_OK; /* No CC's all OK */
#else
/* diag wants an interrupt for a non busy HIO ??? */
sim_debug(DEBUG_XIO, &cpu_dev,
"$$$ HIO DIAG chsa %04x chan %04x cmd %02x flags %04x status %04x\n",
chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status);
dev_status[chsa] |= STATUS_ECHO; /* show we stopped the cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */
store_csw(chp); /* store the status in the inch status dw */
//XXX store_csw(chp); /* store the status in the inch status dw */
dev_status[chsa] = 0; /* no device status */
irq_pend = 1; /* still pending int */
// *status = CC2BIT; /* sub channel status posted, CC2BIT */
@ -1443,14 +1522,14 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
/* test for SCPE_IOERR */
if (tempa != 0) { /* sub channel has status ready */
/* The device I/O has been terminated and status stored. */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_XIO, &cpu_dev,
"haltxio halt_io call return ERROR chan %04x retstat %08x cstat %08x\n",
chan, tempa, chp->chan_status);
/*TUE*/ chp->chan_status &= ~STATUS_LENGTH; /* remove SLI status bit */
chp->chan_status &= ~STATUS_PCI; /* remove PCI status bit */
//TUE dev_status[chsa] |= STATUS_ECHO; /* show we stopped the cmd */
/* chan_end called in hio device service routine */
store_csw(chp); /* store the status in the inch status dw */
//XXX store_csw(chp); /* store the status in the inch status dw */
chp->ccw_count = 0; /* force zero count */
dev_status[chsa] = 0; /* no device status */
@ -1465,6 +1544,8 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
sim_debug(DEBUG_IRQ, &cpu_dev,
"haltxio 0 FIFO status stored OK, sw1 %08x sw2 %08x\n", sw1, sw2);
/*TUE*/ sw2 &= ~STATUS_LENGTH; /* remove SLI status bit */
sw2 |= STATUS_ECHO; /* show we stopped the cmd */
/* we have status to return, do it now */
tempa = pchp->chan_inch_addr; /* get inch status buffer address */
M[tempa >> 2] = sw1; /* save sa & IOCD address in status WD 1 loc */
@ -1479,7 +1560,7 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
// UTX likes this return and does not panic */
// The diag's want an interrupt generated, so wait
*status = CC2BIT; /* status stored from HIO, so CC2 */
/* if 0 returned, UTX hans on input */
/* if 0 returned, UTX hangs on input */
goto hioret; /* CC2 and OK */
}
/* nothing going on, so say all OK */
@ -1500,8 +1581,8 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
/* we have completed the I/O without error */
/* the channel is not busy, so return OK */
//WAS *status = 0; /* CCs = 0, accepted */
sim_debug(DEBUG_CMD, &cpu_dev,
"$$$ HALTIO good return chsa %04x chan %04x cmd %02x flags %04x status %04x\n",
sim_debug(DEBUG_XIO, &cpu_dev,
"$$$ HALTXIO good return chsa %04x chan %04x cmd %02x flags %04x status %04x\n",
chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status);
*status = CC1BIT; /* request accepted, no status, so CC1 */
goto hioret; /* just return */
@ -1514,11 +1595,11 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
sim_debug(DEBUG_XIO, &cpu_dev, "haltxio busy return CC4 chsa %04x chan %04x\n", chsa, chan);
/* reset the DC or CC bits to force completion after current IOCD */
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */
//CHG dev_status[chsa] |= STATUS_ECHO; /* show we stopped the cmd */
dev_status[chsa] |= STATUS_ECHO; /* show we stopped the cmd */
/*ADD*/ chp->ccw_count = 0; /* clear remaining count */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */
/*ADD*/ chp->chan_status &= ~STATUS_LENGTH; /* remove SLI status bit */
store_csw(chp); /* store the status in the inch status dw */
//XXX store_csw(chp); /* store the status in the inch status dw */
chp->chan_status &= ~STATUS_PCI; /* remove PCI status bit */
dev_status[chsa] = 0; /* no device status */
irq_pend = 1; /* still pending int */
@ -1596,8 +1677,8 @@ t_stat rsctlxio(uint16 lchsa, uint32 *status) { /* reset controller XIO */
chp->chan_inch_addr = 0; /* remove inch status buffer address */
lev = find_int_lev(chan); /* get our int level */
INTS[lev] &= ~INTS_ACT; /* clear level active */
INTS[lev] &= ~INTS_REQ; /* clear level request */
SPAD[lev+0x80] &= ~SINT_ACT; /* clear spad too */
INTS[lev] &= ~INTS_REQ; /* clear level request */
/* now go through all the sa for the channel and stop any IOCLs */
for (i=0; i<256; i++) {
@ -1629,7 +1710,8 @@ t_stat rsctlxio(uint16 lchsa, uint32 *status) { /* reset controller XIO */
/* on CPU reset, the cpu has set the IOCD data at location 0-4 */
t_stat chan_boot(uint16 chsa, DEVICE *dptr) {
int chan = get_chan(chsa);
DIB *dibp = dev_unit[chsa];
//Z DIB *dibp = dev_unit[chsa];
DIB *dibp = (DIB *)dptr->ctxt; /* get pointer to DIB for this device */
CHANP *chp = 0;
sim_debug(DEBUG_EXP, &cpu_dev, "Channel Boot chan/device addr %04x\n", chsa);
@ -1671,7 +1753,8 @@ t_stat chan_boot(uint16 chsa, DEVICE *dptr) {
interrupt pending. Return icb address and interrupt level
*/
uint32 scan_chan(int *ilev) {
int i,j;
int i;
//XXint j;
uint32 chsa = 0; /* No device */
uint32 chan; /* channel num 0-7f */
uint32 tempa; /* icb address */
@ -1680,7 +1763,9 @@ uint32 scan_chan(int *ilev) {
CHANP *chp; /* channel prog pointer */
DIB *dibp; /* DIB pointer */
if (irq_pend == 1) { /* pending int? */
#ifdef OLD_METHOD
//WAS if (irq_pend == 1) { /* pending int? */
if ((irq_pend == 1) && loading) { /* pending int? */
/* see if we have a channel completed */
/* loop through all the channels/units for channel with pending I/O completion */
for (i = 0; sim_devices[i] != NULL; i++) {
@ -1701,16 +1786,16 @@ uint32 scan_chan(int *ilev) {
/* If channel end, check if we should continue */
if (chp->chan_status & STATUS_CEND) { /* do we have channel end */
sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_XIO, &cpu_dev,
"scan_chan loading %02x chan end chsa %04x flags %04x status %04x\n",
loading, chsa, chp->ccw_flags, chp->chan_status);
if (chp->ccw_flags & FLAG_CC) { /* command chain flag */
/* we have channel end and CC flag, continue channel prog */
sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_XIO, &cpu_dev,
"scan_chan loading %02x chan end & CC chsa %04x status %04x\n",
loading, chsa, chp->chan_status);
if (chp->chan_status & STATUS_DEND) { /* device end? */
sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_XIO, &cpu_dev,
"scan_chan loading %02x dev end & CC chsa %04x status %04x\n",
loading, chsa, chp->chan_status);
(void)load_ccw(chp, 1); /* go load the next IOCB */
@ -1719,7 +1804,7 @@ uint32 scan_chan(int *ilev) {
} else {
/* we have channel end and no CC flag, end command */
chsa = chp->chan_dev; /* get the chan/sa */
sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_XIO, &cpu_dev,
"scan_chan loading %02x chan end & no CC chsa %04x status %04x\n",
loading, chsa, chp->chan_status);
dev_status[chsa] = 0; /* no device status anymore */
@ -1748,6 +1833,105 @@ uint32 scan_chan(int *ilev) {
}
}
//WAS trythis:
#else
if ((irq_pend == 1) && loading) { /* pending int? */
/* see if we have a channel completed for the boot channel */
chp = find_chanp_ptr(loading); /* find the chanp pointer for channel */
/* If channel end, check if we should continue */
if (chp->chan_status & STATUS_CEND) { /* do we have channel end */
sim_debug(DEBUG_DETAIL, &cpu_dev,
"scan_chan loading %02x chan end chsa %04x flags %04x status %02x\n",
loading, chsa, chp->ccw_flags, chp->chan_status);
if (chp->ccw_flags & FLAG_CC) { /* command chain flag */
/* we have channel end and CC flag, continue channel prog */
sim_debug(DEBUG_DETAIL, &cpu_dev,
"scan_chan loading %02x chan end & CC chsa %04x status %02x\n",
loading, chsa, chp->chan_status);
if (chp->chan_status & STATUS_DEND) { /* device end? */
sim_debug(DEBUG_DETAIL, &cpu_dev,
"scan_chan loading %02x dev end & CC chsa %04x status %02x\n",
loading, chsa, chp->chan_status);
(void)load_ccw(chp, 1); /* go load the next IOCB */
} else
irq_pend = 1; /* still pending int */
} else {
/* we have channel end and no CC flag, end command */
chsa = chp->chan_dev; /* get the chan/sa */
sim_debug(DEBUG_DETAIL, &cpu_dev,
"scan_chan loading %02x chan end & no CC chsa %04x status %02x\n",
loading, chsa, chp->chan_status);
dev_status[chsa] = 0; /* no device status anymore */
/* handle case where we are loading the O/S on boot */
if (chp->chan_status & 0x3f03) { /* check if any channel errors */
return 0; /* yes, just return */
}
irq_pend = 0; /* no pending int */
chp->chan_status = 0; /* no channel status */
return chsa; /* if loading, just channel number */
}
}
}
#endif
//#define NEW_LOOK
#ifdef NEW_LOOK
/* Look for channels that are not active and not requesting, */
/* but have status to post. Store the status and make them */
/* into an interest request. They will be found when we scan */
/* for the highest requesting interrupt. */
for (i=0; i<112; i++) {
if (SPAD[i+0x80] == 0) /* not initialize? */
continue; /* skip this one */
if (SPAD[i+0x80] == 0xffffffff) /* not initialize? */
continue; /* skip this one */
/* see if interrupt is enabled */
if (!((INTS[i] & INTS_ENAB) || (SPAD[i+0x80] & SINT_ENAB)))
continue; /* skip this one */
/* we are enabled, see if already active */
if ((INTS[i] & INTS_ACT) || (SPAD[i+0x80] & SINT_ACT))
continue; /* this level active, keep looking */
/* see if status already posted and requesting */
if (INTS[i] & INTS_REQ)
continue; /* this level requesting, keep looking */
/* see if there is pending status for this channel */
/* if there is, load it and request interrupt */
/* get the device entry for the logical channel in SPAD */
chan = (SPAD[i+0x80] & 0x7f00); /* get real channel and zero sa */
dibp = dev_unit[chan]; /* get the device information pointer */
/* no status for non-device entries */
if (dibp == 0) {
sim_debug(DEBUG_DETAIL, &cpu_dev,
"scan_chan %04x int %02x no DIB pointer for requesting interrupt\n", chan, i);
continue; /* skip unconfigured channel */
}
/* see if FIFO has status to post */
if (dibp->chan_fifo_in != dibp->chan_fifo_out) {
uint32 sw1, sw2;
/* fifo is not empty, so post status and request an interrupt */
if ((FIFO_Get(chan, &sw1) == 0) && (FIFO_Get(chan, &sw2) == 0)) {
/* we have status to return, do it now */
chp = find_chanp_ptr(chan); /* find the chanp pointer for channel */
/* get the address of the interrupt IVL table in main memory */
chan_ivl = SPAD[0xf1] + (i<<2); /* contents of spad f1 points to chan ivl in mem */
chan_icba = M[chan_ivl >> 2]; /* get the interrupt context blk addr in memory */
tempa = chp->chan_inch_addr; /* get inch status buffer address */
M[tempa >> 2] = sw1; /* save sa & IOCD address in status WD 1 loc */
/* save the status to memory */
M[(tempa+4) >> 2] = sw2; /* save status and count in status WD 2 loc */
/* now store the status dw address into word 5 of the ICB for the channel */
/* post sw addr in ICB+5w & set CC2 in SW */
M[(chan_icba + 20) >> 2] = tempa | BIT1;
INTS[i] |= INTS_REQ; /* turn on channel interrupt request */
sim_debug(DEBUG_IRQ, &cpu_dev,
"scan_chan REQ %04x FIFO read, irq %02x inch %06x chan_icba %06x sw1 %08x sw2 %08x\n",
chan, i, tempa, chan_icba, sw1, sw2);
irq_pend = 1; /* still pending int */
continue; /* keep looking */
}
}
/* no status to post, so go on */
}
#endif
/* see if we are able to look for ints */
if ((CPUSTATUS & 0x80) == 0) { /* are interrupts blocked */
/* ints not blocked, so look for highest requesting interrupt */
@ -1757,8 +1941,37 @@ uint32 scan_chan(int *ilev) {
if (SPAD[i+0x80] == 0xffffffff) /* not initialize? */
continue; /* skip this one */
// if (INTS[i]&INTS_ACT) /* look for level active */
if (SPAD[i+0x80] & SINT_ACT) /* look for level active */
if (SPAD[i+0x80] & SINT_ACT) { /* look for level active */
sim_debug(DEBUG_IRQ, &cpu_dev,
"scan_chan INTS ACT irq %02x SPAD %08x INTS %08x\n",
i, SPAD[i+0x80], INTS[i]);
break; /* this level active, so stop looking */
}
#ifndef OLD3
/* look for the highest requesting interrupt */
/* that is enabled */
if (((INTS[i] & INTS_ENAB) && (INTS[i] & INTS_REQ)) ||
((SPAD[i+0x80] & SINT_ENAB) && (INTS[i] & INTS_REQ))) {
/* requesting, make active and turn off request flag */
INTS[i] &= ~INTS_REQ; /* turn off request */
INTS[i] |= INTS_ACT; /* turn on active */
SPAD[i+0x80] |= SINT_ACT; /* show active in SPAD too */
/* make sure both enabled too */
/* should already be enabled */
// INTS[i] |= INTS_ENAB; /* turn on enable */
// SPAD[i+0x80] |= SINT_ENAB; /* show enabled in SPAD too */
/* get the address of the interrupt IVL table in main memory */
chan_ivl = SPAD[0xf1] + (i<<2); /* contents of spad f1 points to chan ivl in mem */
chan_icba = M[chan_ivl >> 2]; /* get the interrupt context block addr in memory */
sim_debug(DEBUG_IRQ, &cpu_dev,
"scan_chan INTS REQ irq %02x found chan_icba %08x INTS %08x\n",
i, chan_icba, INTS[i]);
*ilev = i; /* return interrupt level */
irq_pend = 0; /* not pending anymore */
return(chan_icba); /* return ICB address */
}
#endif
#ifndef OLD1
/* see if there is pending status for this channel */
/* if there is and the level is not requesting, do it */
if ((INTS[i] & INTS_ENAB) && !(INTS[i] & INTS_REQ)) {
@ -1786,11 +1999,15 @@ uint32 scan_chan(int *ilev) {
M[(chan_icba + 20) >> 2] = tempa | BIT1;
INTS[i] |= INTS_REQ; /* turn on channel interrupt request */
sim_debug(DEBUG_IRQ, &cpu_dev,
"scan_chan %04x FIFO read, set irq %04x inch %06x chan_icba %06x sw1 %08x sw2 %08x\n",
"scan_chan %04x FIFO read, set irq %02x inch %06x chan_icba %06x sw1 %08x sw2 %08x\n",
chan, i, tempa, chan_icba, sw1, sw2);
irq_pend = 1; /* still pending int */
break; /* quit looking */
}
}
}
#endif
#ifdef OLD2
/* look for the highest requesting interrupt */
/* that is enabled */
if (((INTS[i] & INTS_ENAB) && (INTS[i] & INTS_REQ)) ||
@ -1813,11 +2030,13 @@ uint32 scan_chan(int *ilev) {
irq_pend = 0; /* not pending anymore */
return(chan_icba); /* return ICB address */
}
#endif
}
}
return 0; /* done */
}
/* part of find_dev_from_unit(UNIT *uptr) in scp.c */
/* Find_dev pointer for a unit
Input: uptr = pointer to unit
Output: dptr = pointer to device
@ -1892,8 +2111,10 @@ t_stat chan_set_devs() {
chp->ccw_cmd = 0; /* read command */
chp->chan_inch_addr = 0; /* clear address of stat dw in memory */
if ((uptr->flags & UNIT_DIS) == 0) { /* is unit marked disabled? */
if (dev_unit[chsa] != 0)
printf("Channel/SubAddress %04x multiple defined\n", chsa);
if (dev_unit[chsa] != 0) {
printf("Channel/SubAddress %04x multiple defined, aborting\n", chsa);
return SCPE_IERR; /* no, arg error */
}
dev_unit[chsa] = dibp; /* no, save the dib address */
}
if (dibp->dev_ini != NULL) /* if there is an init routine, call it now */
@ -1962,7 +2183,7 @@ t_stat show_dev_addr(FILE *st, UNIT *uptr, int32 v, CONST void *desc) {
return SCPE_IERR; /* no, error return */
dptr = get_dev(uptr); /* get the device pointer from unit */
if (dptr == NULL) /* valid pointer? */
return SCPE_IERR; /* retunr error */
return SCPE_IERR; /* return error */
chsa = GET_UADDR(uptr->u3); /* get the unit address */
fprintf(st, "CHAN/SA %04x", chsa); /* display channel/subaddress */
return SCPE_OK; /* we done */

View File

@ -115,8 +115,10 @@ t_stat rtc_srv (UNIT *uptr)
time_t result = time(NULL);
// fprintf(stderr, "Clock int time %08x\r\n", (uint32)result);
sim_debug(DEBUG_CMD, &rtc_dev, "RT Clock int time %08x\n", (uint32)result);
if ((INTS[rtc_lvl] & INTS_ENAB) && /* make sure enabled */
(INTS[rtc_lvl] & INTS_ACT) == 0) { /* and not active */
if (((INTS[rtc_lvl] & INTS_ENAB) || /* make sure enabled */
(SPAD[rtc_lvl+0x80] & SINT_ENAB)) && /* in spad too */
(((INTS[rtc_lvl] & INTS_ACT) == 0) || /* and not active */
((SPAD[rtc_lvl+0x80] & SINT_ACT) == 0))) { /* in spad too */
INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */
irq_pend = 1; /* make sure we scan for int */
}
@ -149,6 +151,7 @@ void rtc_setup(uint32 ss, uint32 level)
SPAD[level+0x80] &= ~SINT_ENAB; /* in spad too */
// INTS[level] &= ~INTS_REQ; /* make sure request not requesting */
// INTS[level] &= ~INTS_ACT; /* make sure request not active */
// SPAD[level+0x80] &= ~SINT_ACT; /* in spad too */
sim_debug(DEBUG_CMD, &rtc_dev,
"RT Clock setup disable int %02x rtc_pie %01x ss %01x\n",
rtc_lvl, rtc_pie, ss);
@ -274,9 +277,11 @@ t_stat itm_srv (UNIT *uptr)
sim_debug(DEBUG_CMD, &itm_dev,
"Intv Timer expired status %08x interrupt %02x @ time %08x\n",
INTS[itm_lvl], itm_lvl, (uint32)result);
if ((INTS[itm_lvl] & INTS_ENAB) && /* make sure enabled */
(INTS[itm_lvl] & INTS_ACT) == 0) { /* and not active */
INTS[itm_lvl] |= INTS_REQ; /* request the interrupt on zero value */
if (((INTS[itm_lvl] & INTS_ENAB) || /* make sure enabled */
(SPAD[itm_lvl+0x80] & SINT_ENAB)) && /* in spad too */
(((INTS[itm_lvl] & INTS_ACT) == 0) || /* and not active */
((SPAD[itm_lvl+0x80] & SINT_ACT) == 0))) { /* in spad too */
INTS[itm_lvl] |= INTS_REQ; /* request the interrupt */
irq_pend = 1; /* make sure we scan for int */
}
if ((INTS[itm_lvl] & INTS_ENAB) && (itm_cmd == 0x3d) && (itm_cnt != 0)) {

View File

@ -96,10 +96,10 @@ TMXR com_desc = { COM_LINES_DFLT, 0, 0, com_ldsc }; /* com descr */
/* Status held in u3 */
/* controller/unit address in upper 16 bits */
#define COM_INPUT 0x100 /* Input ready for unit */
#define COM_CR 0x200 /* Output at beginning of line */
#define COM_REQ 0x400 /* Request key pressed */
#define COM_EKO 0x800 /* Echo input character */
#define COM_INPUT 0x0100 /* Input ready for unit */
#define COM_CR 0x0200 /* Output at beginning of line */
#define COM_REQ 0x0400 /* Request key pressed */
#define COM_EKO 0x0800 /* Echo input character */
#define COM_OUTPUT 0x1000 /* Output ready for unit */
#define COM_READ 0x2000 /* Read mode selected */
@ -193,7 +193,7 @@ TMXR com_desc = { COM_LINES_DFLT, 0, 0, com_ldsc }; /* com descr */
/* u6 */
uint8 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd);
uint8 com_haltio(uint16 addr);
uint8 com_haltio(UNIT *uptr);
void com_ini(UNIT *, t_bool);
void coml_ini(UNIT *, t_bool);
t_stat com_reset(DEVICE *);
@ -260,7 +260,7 @@ DIB com_dib = {
com_unit, /* UNIT* units */ /* Pointer to units structure */
com_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */
COM_UNITS, /* uint8 numunits */ /* number of units defined */
0x0f, /* uint8 mask */ /* 16 devices - device mask */
0xFF, /* uint8 mask */ /* 16 devices - device mask */
0x7E00, /* uint16 chan_addr */ /* parent channel address */
0, /* uint32 chan_fifo_in */ /* fifo input index */
0, /* uint32 chan_fifo_out */ /* fifo output index */
@ -282,6 +282,7 @@ DEVICE com_dev = {
"COMC", com_unit, com_reg, com_mod,
COM_UNITS, 8, 15, 1, 8, 8,
&tmxr_ex, &tmxr_dep, &com_reset, NULL, &com_attach, &com_detach,
/* ctxt is the DIB pointer */
&com_dib, DEV_NET | DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
NULL, NULL, NULL, NULL, NULL, &com_description
};
@ -330,7 +331,7 @@ DIB coml_dib = {
coml_unit, /* UNIT* units */ /* Pointer to units structure */
coml_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */
COM_LINES*2, /* uint8 numunits */ /* number of units defined */
0x0f, /* uint8 mask */ /* 16 devices - device mask */
0xff, /* uint8 mask */ /* 16 devices - device mask */
0x7E00, /* uint16 chan_addr */ /* parent channel address */
};
@ -358,6 +359,7 @@ DEVICE coml_dev = {
COM_LINES*2, 10, 31, 1, 8, 8,
NULL, NULL, &com_reset,
NULL, NULL, NULL,
/* ctxt is the DIB pointer */
&coml_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
NULL, NULL, NULL, NULL, NULL, &com_description
};
@ -380,7 +382,7 @@ void com_ini(UNIT *uptr, t_bool f)
{
DEVICE *dptr = get_dev(uptr);
sim_debug(DEBUG_CMD, &com_dev, "COM init device %s controller 0x7e00\n", dptr->name);
sim_debug(DEBUG_CMD, dptr, "COM init device %s controller 0x7e00\n", dptr->name);
sim_activate(uptr, 1000); /* time increment */
}
@ -395,12 +397,12 @@ uint8 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
return SNS_BSY; /* yes, return busy */
}
sim_debug(DEBUG_CMD, &com_dev, "CMD unit %04x chan %04x cmd %02x", 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) {
case COM_INCH: /* 00 */ /* INCH command */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: CMD INCH\n", chan);
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: CMD INCH\n", chan);
uptr->u3 &= LMASK; /* leave only chsa */
uptr->u3 |= (0x7f & COM_MSK); /* save 0x7f as INCH cmd command */
uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */
@ -412,7 +414,7 @@ uint8 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, &com_dev, "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 */
@ -434,19 +436,20 @@ uint8 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
/* if bit 0 set for COM_RDFC, use DTR for flow, else use RTS for flow control */
case COM_RDFC: /* 0x0A */ /* Read command w/flow control */
case COM_RDHFC: /* 0x8E */ /* Read command w/hardware flow control only */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: Cmd read\n", chan);
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd read\n", chan);
uptr->u3 &= LMASK; /* leave only chsa */
uptr->u3 |= (cmd & COM_MSK); /* save command */
if ((cmd & 0x06) == COM_RDECHO) /* echo command? */
uptr->u3 |= COM_EKO; /* save echo status */
uptr->u3 |= COM_READ; /* show read mode */
uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: input cnt = %04x\n", chan, coml_chp[unit].ccw_count);
sim_debug(DEBUG_CMD, dptr,
"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, &com_dev, "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 */
@ -459,7 +462,8 @@ uint8 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
com_lstat[unit][1] = 0; /* Clear status wd 1 */
/* value 4 is Data Set Ready */
/* value 5 is Data carrier detected n/u */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: unit %04x Cmd Sense %02x\n", chan, unit, uptr->u5);
sim_debug(DEBUG_CMD, dptr,
"com_startcmd %04x: unit %04x Cmd Sense %02x\n", chan, unit, uptr->u5);
/* Sense byte 0 */
//#define SNS_CMDREJ 0x80000000 /* Command reject */
//#define SNS_INTVENT 0x40000000 /* Unit intervention required (N/U) */
@ -522,51 +526,54 @@ uint8 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
chan_write_byte(GET_UADDR(uptr->u3), &ch); /* write status */
ch = (com_lstat[unit][1] >> 0) & 0xff;
chan_write_byte(GET_UADDR(uptr->u3), &ch); /* write status */
sim_debug(DEBUG_CMD, &com_dev,
sim_debug(DEBUG_CMD, dptr,
"com_startcmd Cmd SENSE return chan %04x u5-status %04x ls0 %08x ls1 %08x\n",
chan, uptr->u5, com_lstat[unit][0], com_lstat[unit][1]);
return SNS_CHNEND|SNS_DEVEND; /* good return */
break;
case COM_DEFSC: /* 0x0B */ /* Define special char */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: Cmd %02x DEFSC\n", chan, cmd);
chan_read_byte(GET_UADDR(uptr->u3), &ch); /* read char */
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 */
}
uptr->u5 = ~SNS_RTS; /* Request to send not ready */
return SNS_CHNEND|SNS_DEVEND; /* good return */
break;
case COM_RRTS: /* 0x1B */ /* Reset RTS */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: Cmd %02x RRTS\n", chan, cmd);
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd %02x RRTS\n", chan, cmd);
uptr->u5 &= ~SNS_RTS; /* Request to send not ready */
return SNS_CHNEND|SNS_DEVEND; /* good return */
break;
case COM_SRTS: /* 0x1F */ /* Set RTS */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: Cmd %02x SRTS\n", chan, cmd);
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd %02x SRTS\n", chan, cmd);
uptr->u5 |= SNS_RTS; /* Requestd to send ready */
return SNS_CHNEND|SNS_DEVEND; /* good return */
break;
case COM_RBRK: /* 0x33 */ /* Reset BREAK */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: Cmd %02x RBRK\n", chan, cmd);
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd %02x RBRK\n", chan, cmd);
uptr->u5 &= ~SNS_BREAK; /* Request to send not ready */
return SNS_CHNEND|SNS_DEVEND; /* good return */
break;
case COM_SBRK: /* 0x37 */ /* Set BREAK */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: Cmd %02x SBRK\n", chan, cmd);
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd %02x SBRK\n", chan, cmd);
uptr->u5 |= SNS_BREAK; /* Requestd to send ready */
return SNS_CHNEND|SNS_DEVEND; /* good return */
break;
case COM_RDTR: /* 0x13 */ /* Reset DTR (ADVR) */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: Cmd %02x DTR\n", chan, cmd);
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd %02x RDTR\n", chan, cmd);
uptr->u5 &= ~SNS_DTR; /* Data terminal not ready */
return SNS_CHNEND|SNS_DEVEND; /* good return */
break;
case COM_SDTR: /* 0x17 */ /* Set DTR (ADVF) */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: Cmd %02x NOP\n", chan, cmd);
sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd %02x SDTR\n", chan, cmd);
uptr->u5 |= SNS_DTR; /* Data terminal ready */
return SNS_CHNEND|SNS_DEVEND; /* good return */
break;
@ -611,21 +618,38 @@ uint8 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
#endif
case COM_SACE: /* 0xff */ /* Set ACE parameters (3 chars) */
sim_debug(DEBUG_CMD, &com_dev, "com_startcmd %04x: Cmd %02x SACE\n", chan, cmd);
chan_read_byte(GET_UADDR(uptr->u3), &ch); /* read char 0 */
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 */
}
uptr->u4 = ((uint32)ch)<<24; /* byte 0 of ACE data */
chan_read_byte(GET_UADDR(uptr->u3), &ch); /* read char 1 */
if (chan_read_byte(GET_UADDR(uptr->u3), &ch)) { /* read char 1 */
/* nothing to read, error */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */
}
uptr->u4 |= ((uint32)ch)<<16; /* byte 1 of ACE data */
chan_read_byte(GET_UADDR(uptr->u3), &ch); /* read char 2 */
if (chan_read_byte(GET_UADDR(uptr->u3), &ch)) { /* read char 2 */
/* nothing to read, error */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */
}
uptr->u4 |= ((uint32)ch)<<8; /* byte 2 of ACE data */
sim_debug(DEBUG_CMD, &com_dev, "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);
#ifdef USE_INTERUPT
uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */
uptr->u3 &= LMASK; /* leave only chsa */
uptr->u3 |= (cmd & COM_MSK); /* save command */
sim_activate(uptr, 20); /* start us up */
#else
return SNS_CHNEND|SNS_DEVEND; /* good return */
#endif
break;
default: /* invalid command */
uptr->u5 |= SNS_CMDREJ; /* command rejected */
sim_debug(DEBUG_CMD, &com_dev, "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|SNS_DEVEND|SNS_UNITCHK; /* unit check */
break;
@ -643,23 +667,33 @@ uint8 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
t_stat comi_srv(UNIT *uptr)
{
uint8 ch;
DEVICE *dptr = get_dev(uptr);
int32 newln, ln, c;
uint16 chsa = GET_UADDR(uptr->u3); /* get channel/sub-addr */
int cmd = uptr->u3 & 0xff;
// uint32 cln = (uptr - coml_unit) & 0x7; /* use line # 0-7 for 8-15 */
ln = uptr - com_unit; /* line # */
sim_debug(DEBUG_CMD, &com_dev, "comi_srv entry chsa %04x line %04x cmd %02x\n", chsa, ln, cmd);
/* handle NOP and INCH cmds */
sim_debug(DEBUG_CMD, &com_dev, "comi_srv entry chsa %04x line %04x 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, &com_dev, "comi_srv NOP or INCH done chsa %04x line %04x 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 */
}
/* handle SACE, 3 char alread read, so we are done */
if (cmd == COM_SACE) { /* check for SACE 0xff */
uptr->u3 &= LMASK; /* leave only chsa */
sim_debug(DEBUG_CMD, &com_dev,
"comi_srv SACE done chsa %04x line %02x cmd %02x ACE %08x\n",
chsa, ln, cmd, uptr->u4);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
return SCPE_OK; /* return */
}
ln = uptr - com_unit; /* line # */
if ((com_unit[COMC].flags & UNIT_ATT) == 0){ /* attached? */
return SCPE_OK;
@ -740,6 +774,7 @@ t_stat comi_srv(UNIT *uptr)
/* Unit service - output transfers */
t_stat como_srv(UNIT *uptr)
{
DEVICE *dptr = get_dev(uptr);
uint16 chsa = GET_UADDR(uptr->u3); /* get channel/sub-addr */
uint32 ln = (uptr - coml_unit) & 0x7; /* use line # 0-7 for 8-15 */
uint32 done;
@ -747,7 +782,7 @@ t_stat como_srv(UNIT *uptr)
uint8 ch;
/* handle NOP and INCH cmds */
sim_debug(DEBUG_CMD, &com_dev, "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",
@ -756,7 +791,17 @@ t_stat como_srv(UNIT *uptr)
return SCPE_OK; /* return */
}
sim_debug(DEBUG_CMD, &com_dev, "como_srv entry 1 chsa %04x line %04x cmd %02x\n", chsa, ln, cmd);
/* handle SACE, 3 char already read, so we are done */
if (cmd == COM_SACE) { /* check for SACE 0xff */
uptr->u3 &= LMASK; /* leave only chsa */
sim_debug(DEBUG_CMD, &com_dev,
"como_srv SACE done chsa %04x line %02x cmd %02x ACE %08x\n",
chsa, ln, cmd, uptr->u4);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
return SCPE_OK; /* return */
}
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 */
@ -766,28 +811,28 @@ t_stat como_srv(UNIT *uptr)
return SCPE_OK;
if (com_dev.flags & DEV_DIS) { /* disabled */
sim_debug(DEBUG_CMD, &com_dev, "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, &com_dev, "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, &com_dev, "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, &com_dev, "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, &com_dev, "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;
@ -796,7 +841,7 @@ endit:
goto endit; /* done */
/* just dump the char */
// /* xmt disabled, just wait around */
sim_debug(DEBUG_CMD, &com_dev, "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, coml_unit[ln].wait); /* wait */
sim_activate(uptr, uptr->wait); /* wait */
@ -805,10 +850,10 @@ endit:
} else {
/* not connected, so dump char on ground */
if (done) {
sim_debug(DEBUG_CMD, &com_dev, "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);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
uptr->u3 &= LMASK; /* nothing left, command complete */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
}
sim_activate(uptr, uptr->wait); /* wait */
return SCPE_OK;
@ -837,14 +882,16 @@ t_stat com_reset (DEVICE *dptr)
/* attach master unit */
t_stat com_attach(UNIT *uptr, CONST char *cptr)
{
uint16 chsa = GET_UADDR(com_unit[COMC].u3); /* get channel/subaddress */
DEVICE *dptr = get_dev(uptr);
// uint16 chsa = GET_UADDR(com_unit[COMC].u3); /* get channel/subaddress */
// uint16 chsa = GET_UADDR(uptr->u3); /* get channel/subaddress */
t_stat r;
chsa = GET_UADDR(com_unit[COMC].u3); /* get channel/subaddress */
// chsa = GET_UADDR(com_unit[COMC].u3); /* get channel/subaddress */
r = tmxr_attach(&com_desc, uptr, cptr); /* attach */
if (r != SCPE_OK) /* error? */
return r; /* return error */
sim_debug(DEBUG_CMD, &com_dev, "com_srv com is now attached chsa %04x\n", chsa);
sim_debug(DEBUG_CMD, dptr, "com_srv comc is now attached\n");
sim_activate(uptr, 0); /* start poll at once */
return SCPE_OK;
}

View File

@ -163,7 +163,7 @@ void con_ini(UNIT *uptr, t_bool f) {
int unit = (uptr - con_unit); /* unit 0 */
// DEVICE *dptr = get_dev(uptr);
uptr->u4 = 0; /* no input cpunt */
uptr->u4 = 0; /* no input count */
con_data[unit].incnt = 0; /* no input data */
// con_data[0].incnt = 0; /* no input data */
// con_data[1].incnt = 0; /* no output data */
@ -208,7 +208,6 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
uptr->CMD |= CON_INCH2; /* save INCH command as 0xf0 */
uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */
sim_activate(uptr, 20); /* start us off */
//WAS sim_activate(uptr, 10); /* start us off */
return 0; /* no status change */
break;
@ -219,7 +218,6 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
uptr->CMD |= (cmd & CON_MSK); /* save command */
uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */
sim_activate(uptr, 20); /* start us off */
//TRIED sim_activate(uptr, 10); /* start us off */
return 0; /* no status change */
break;
@ -245,7 +243,7 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
uptr->CMD |= (cmd & CON_MSK); /* save command */
// uptr->u4 = 0; /* no I/O yet */
// con_data[unit].incnt = 0; /* clear any input data */
sim_activate(uptr, 10); /* start us off */
sim_activate(uptr, 20); /* start us off */
return 0; /* no status change */
break;
@ -254,7 +252,7 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */
uptr->CMD &= LMASK; /* leave only chsa */
uptr->CMD |= (cmd & CON_MSK); /* save command */
sim_activate(uptr, 10); /* start us off */
sim_activate(uptr, 20); /* start us off */
return 0; /* no status change */
break;
#endif
@ -282,6 +280,9 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
break;
default: /* invalid command */
break;
}
/* invalid command */
uptr->SNS |= SNS_CMDREJ; /* command rejected */
// uptr->u4 = 0; /* no I/O yet */
// con_data[unit].incnt = 0; /* clear any input data */
@ -289,12 +290,6 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
"con_startcmd %04x: Invalid command %02x Sense %02x\n",
chan, cmd, uptr->SNS);
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* unit check */
break;
}
if (uptr->SNS & (~(SNS_RDY|SNS_ONLN|SNS_DSR)))
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
return SNS_CHNEND|SNS_DEVEND;
}
/* Handle output transfers for console */
@ -317,7 +312,6 @@ t_stat con_srvo(UNIT *uptr) {
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvo Read to output device chsa %04x cmd = %02x\n", chsa, cmd);
//DIAG_TUE chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* unit check */
chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */
return SCPE_OK;
}
@ -401,9 +395,8 @@ t_stat con_srvi(UNIT *uptr) {
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi Write to input device chsa %04x cmd = %02x\n", chsa, cmd);
//DIAGTUE chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); /* unit check */
chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */
//fall thru return SCPE_OK;
// fall thru return SCPE_OK;
}
}
#ifdef JUNK

View File

@ -172,7 +172,7 @@ uint32 BR[8]; /* Base registers */
uint32 PC; /* Program counter */
uint32 CC; /* Condition codes, bits 1-4 of PSD1 */
uint32 SPAD[256]; /* Scratch pad memory */
uint32 INTS[128]; /* Interrupt status flags */
uint32 INTS[112]; /* Interrupt status flags */
uint32 CPUSTATUS; /* cpu status word */
uint32 TRAPSTATUS; /* trap status word */
uint32 CMCR; /* Cache Memory Control Register */
@ -689,7 +689,7 @@ t_stat load_maps(uint32 thepsd[2], uint32 lmap)
uint32 MAXMAP = MAX2048; /* default to 2048 maps */
sim_debug(DEBUG_CMD, &cpu_dev,
"Load Maps Entry PSD %08x %08x STATUS %08x lmap %01x CPU Type %2x\n",
"Load Maps Entry PSD %08x %08x STATUS %08x lmap %01x CPU Mode %2x\n",
thepsd[0], thepsd[1], CPUSTATUS, lmap, CPU_MODEL);
/* process 32/7X computers */
@ -887,19 +887,19 @@ npmem:
BPIX = 0; /* no os maps loaded */
CPIXPL = 0; /* no user pages */
CPIX = cpix; /* save user CPIX */
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) {
TRAPSTATUS |= BIT1; /* set bit 1 of trap status */
else
TRAPSTATUS |= BIT8; /* set bit 8 of trap status */
} else
TRAPSTATUS |= BIT10; /* set bit 8 of trap status */
return NPMEM; /* non present memory error */
}
/* output O/S and User MPX entries */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"#MEMORY %06x MPL %06x MPL[0] %08x %06x MPL[%04x] %08x %06x\n",
MEMSIZE*4, mpl, RMW(mpl), RMW(mpl+4), cpix,
RMW(cpix+mpl), RMW(cpix+mpl+4));
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"MEMORY2 %06x BPIX %04x cpix %04x CPIX %04x CPIXPL %04x HIWM %04x\n",
MEMSIZE*4, BPIX, cpix, CPIX, CPIXPL, HIWM);
@ -1068,9 +1068,9 @@ loaduser:
sim_debug(DEBUG_TRAP, &cpu_dev,
"load_maps MEM SIZE4 %06x user page list address %06x invalid\n",
MEMSIZE*4, msdl);
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) {
TRAPSTATUS |= BIT1; /* set bit 1 of trap status */
else
} else
TRAPSTATUS |= BIT28; /* set bit 28 of trap status */
return NPMEM; /* non present memory error */
}
@ -1101,7 +1101,7 @@ loaduser:
if ((CPU_MODEL == MODEL_27) || (CPU_MODEL == MODEL_87)) {
sim_debug(DEBUG_CMD, &cpu_dev,
"load_maps Processing 32/27 & 32/87 Model# %04x\n", CPU_MODEL);
"load_maps Processing 32/27 & 32/87 Model# %02x\n", CPU_MODEL);
/* handle non virtual page loading or diag LMAP instruction */
/* do 32/27 and 32/87 that force load all maps */
@ -1296,9 +1296,9 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access)
if (word >= (MEMSIZE*4)) { /* see if address is within our memory */
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) {
if (access == MEM_RD)
TRAPSTATUS |= 0x40000000; /* set bit 1 of trap status */
TRAPSTATUS |= BIT1; /* set bit 1 of trap status */
if (access == MEM_WR)
TRAPSTATUS |= 0x20000000; /* set bit 2 of trap status */
TRAPSTATUS |= BIT2; /* set bit 2 of trap status */
} else {
TRAPSTATUS |= BIT10; /* set bit 10 of trap status */
}
@ -1333,6 +1333,7 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access)
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) {
// V9 & 32/97 wants MACHINECHK for test 37/1 in CN.MMM & VM.MMM */
TRAPSTATUS |= BIT7; /* set bit 7 of trap status */
TRAPSTATUS |= BIT28; /* set bit 28 of trap status */
return MACHINECHK_TRAP; /* diags want machine check error */
}
}
@ -1398,7 +1399,7 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access)
if ((BIT1 >> offset) & raddr) { /* is 1/4 page write protected */
*prot = 1; /* return memory write protection status */
}
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"RealAddrRa address %08x, TLB %08x MAPC[%03x] %08x wprot %02x prot %02x\n",
word, TLB[index], index/2, MAPC[index/2], (word>>11)&3, *prot);
return ALLOK; /* all OK, return instruction */
@ -1419,16 +1420,23 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access)
"RealAddr loadmap 2a non present memory fault addr %08x raddr %08x index %04x\n",
addr, raddr, index);
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) {
#ifndef TRY_AGAIN
if (access == MEM_RD)
TRAPSTATUS |= BIT1; /* set bit 1 of trap status */
else
if (access == MEM_WR)
TRAPSTATUS |= BIT2; /* set bit 2 of trap status */
/* returning this error fails test 34/2 of mmm diag */
/*NEW*/// return MAPFLT; /* map fault error on memory access */
/*NEW*/// return MACHINECHK_TRAP; /* diags want machine check error */
/* returning this error fixes 34/2, but still fails 46/2 */
return NPMEM; /* none present memory error */
#else
TRAPSTATUS |= BIT7; /* set bit 7 of trap status */
TRAPSTATUS |= BIT12; /* set bit 12 of trap status */
/* returning this error fails test 34/2 of mmm diag */
return MAPFLT; /* map fault error on memory access */
#endif
/*NEW*/// return MAPFLT; /* map fault error on memory access */
/* returning this error fails test 34/2 of mmm diag */
/*NEW*/// return MACHINECHK_TRAP; /* diags want machine check error */
} else
TRAPSTATUS |= BIT28; /* set bit 28 of trap status */
return NPMEM; /* none present memory error */
@ -1449,7 +1457,7 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access)
if ((BIT1 >> offset) & raddr) { /* is 1/4 page write protected */
*prot = 1; /* return memory write protection status */
}
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"RealAddrR address %08x, TLB %08x MAPC[%03x] %08x wprot %02x prot %02x\n",
word, TLB[index], index/2, MAPC[index/2], (word>>11)&3, *prot);
return ALLOK; /* all OK, return instruction */
@ -1463,9 +1471,6 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access)
else
*prot = offset; /* return memory write protection status */
// if (addr != word)
//sim_debug(DEBUG_EXP, &cpu_dev,
//"At RealAddr Hit convert %06x to addr %08x\n", addr, word);
sim_debug(DEBUG_DETAIL, &cpu_dev,
"RealAddrX address %06x, TLB %06x MAPC[%03x] %08x wprot %02x prot %02x\n",
word, TLB[index], index/2, MAPC[index/2], (word>>11)&3, *prot);
@ -1473,7 +1478,7 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access)
}
/* Hit bit is off in TLB, so lets go get some maps */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"$MEMORY %06x HIT MPL %06x MPL[0] %08x %06x MPL[%04x] %08x %06x\n",
MEMSIZE*4, mpl, RMW(mpl), RMW(mpl+4), CPIX, RMW(CPIX+mpl), RMW(CPIX+mpl+4));
@ -1481,7 +1486,7 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access)
msdl = RMW(mpl+CPIX+4); /* get msdl entry for given CPIX */
if ((msdl & MASK24) >= (MEMSIZE*4)) { /* check user midl */
sim_debug(DEBUG_TRAP, &cpu_dev,
"RealAddr Non Present Memory User msdl %06x CPIX %04x\n",
"RealAddr User CPIX Non Present Memory User msdl %06x CPIX %04x\n",
msdl, CPIX);
if (CPU_MODEL == MODEL_67) {
@ -1550,7 +1555,7 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access)
else
mix = nix-BPIX; /* get map index in memory */
map = RMH(msdl+(mix<<1)); /* map content from memory */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"Addr %06x RealAddr %06x Map0[%04x] HIT %04x TLB[%3x] %08x MAPC[%03x] %08x\n",
addr, word, mix, map, nix, TLB[nix], nix/2, MAPC[nix/2]);
@ -1558,10 +1563,6 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access)
if ((map & 0x8000) == 0) {
/* for V6 & V9 handle demand paging */
if (CPU_MODEL >= MODEL_V6) {
#ifdef DO_DYNAMIC_DEBUG
/* start debugging */
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ);
#endif
/* map is not valid, so we have map fault */
sim_debug(DEBUG_TRAP, &cpu_dev,
"AddrMa %06x RealAddr %06x Map0 HIT %04x, TLB[%3x] %08x MAPC[%03x] %08x\n",
@ -1589,24 +1590,16 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access)
TLB[nix] = ((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000) | 0x04000000;
word = (TLB[nix] & 0xffe000) | offset; /* combine map and offset */
WMR((nix<<1), map); /* store the map reg contents into MAPC cache */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"RealAddrm RMH %04x mix %04x TLB[%04x] %08x B+C %04x RMR[nix] %04x\n",
map, mix, nix, TLB[nix], BPIX+CPIXPL, RMR(nix<<1));
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"Addr1c %06x RealAddr %06x Map1[%04x] HIT %04x, TLB[%3x] %08x MAPC[%03x] %08x RMR %04x\n",
addr, word, mix, map, nix, TLB[nix], nix/2, MAPC[nix/2], RMR(nix<<1));
#ifdef DO_DYNAMIC_DEBUG
/* start debugging */
if(word == 0x27000)
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ | DEBUG_XIO);
#endif
*realaddr = word; /* return the real address */
raddr = TLB[nix]; /* get the base address & bits */
// if (addr != word)
//sim_debug(DEBUG_EXP, &cpu_dev,
//"At RealAddr Miss convert %06x to addr %08x\n", addr, word);
if ((CPU_MODEL == MODEL_67) || (CPU_MODEL == MODEL_97)) {
/* get protection status of map */
@ -1644,13 +1637,13 @@ cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ | DEBUG_XIO);
nix -= 1; /* point to last map in MAPC */
}
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"RealAddrp mix %04x nix %04x TLB[%04x] %08x B+C %04x RMR[nix] %04x\n",
mix, nix, nix, TLB[nix], BPIX+CPIXPL, RMR(nix<<1));
/* allow the excess map entry to be loaded, even though bad */
if (nix <= (BPIX+CPIXPL)) { /* needs to be a mapped reg */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"Addr1d BPIX %03x CPIXPL %03x RealAddr %06x TLB[%3x] %08x MAPC[%03x] %08x RMR %04x\n",
BPIX, CPIXPL, word, nix, TLB[nix], nix/2, MAPC[nix/2], RMR(nix<<1));
@ -1660,7 +1653,7 @@ cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ | DEBUG_XIO);
/* allow the excess map entry to be loaded, even though bad */
if (nix <= (BPIX+CPIXPL)) { /* needs to be a mapped reg */
map = RMH(msdl+(mix<<1)); /* map content from memory */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"Addr2a %06x MapX[%04x] HIT %04x, TLB[%3x] %08x MAPC[%03x] %08x\n",
addr, mix, map, nix, TLB[nix], nix/2, MAPC[nix/2]);
@ -1669,7 +1662,7 @@ cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ | DEBUG_XIO);
TLB[nix] = ((map & 0x7ff) << 13) | ((map << 16) & 0xf8000000) | 0x04000000;
word = (TLB[nix] & 0xffe000); /* combine map and offset */
WMR((nix<<1), map); /* store the map reg contents into MAPC cache */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"Addr2b %06x RealAddr %06x Map2[%04x] HIT %04x, TLB[%3x] %08x MAPC[%03x] %08x\n",
addr, word, mix, map, nix, TLB[nix], nix/2, MAPC[nix/2]);
}
@ -1784,14 +1777,14 @@ t_stat Mem_read(uint32 addr, uint32 *data)
sim_debug(DEBUG_EXP, &cpu_dev, "Mem_read error addr %.8x realaddr %.8x data %.8x prot %02x status %04x\n",
addr, realaddr, *data, prot, status);
if (status == NPMEM) { /* operand nonpresent memory error */
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) {
TRAPSTATUS |= BIT1; /* set bit 1 of trap status */
else
} else
TRAPSTATUS |= BIT10; /* set bit 10 of trap status */
}
if (status == MAPFLT) {
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
TRAPSTATUS |= BIT1; /* set bit 1 of trap status */
TRAPSTATUS |= BIT12; /* set bit 12 of trap status */
else
TRAPSTATUS |= BIT10; /* set bit 10 of trap status */
}
@ -1892,14 +1885,14 @@ t_stat Mem_write(uint32 addr, uint32 *data)
"Mem_write error addr %.8x realaddr %.8x data %.8x prot %02x status %04x\n",
addr, realaddr, *data, prot, status);
if (status == NPMEM) { /* operand nonpresent memory error */
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) {
TRAPSTATUS |= BIT2; /* set bit 2 of trap status */
else
} else
TRAPSTATUS |= BIT10; /* set bit 10 of trap status */
}
if (status == MAPFLT) {
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
TRAPSTATUS |= BIT2; /* set bit 2 of trap status */
TRAPSTATUS |= BIT12; /* set bit 12 of trap status */
else
TRAPSTATUS |= BIT10; /* set bit 10 of trap status */
}
@ -1999,10 +1992,10 @@ wait_loop:
PSD1 &= ~1; /* clear bit 31, no lr */
drop_nop = 0; /* we dropped the nop */
}
redo:
if (skipinstr) { /* need to skip interrupt test? */
#ifdef NOTNOW
sim_debug(DEBUG_TRAP, &cpu_dev,
sim_debug(DEBUG_IRQ, &cpu_dev,
"Skipinstr set to zero PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
PSD1, PSD2, CPUSTATUS);
#endif
@ -2016,7 +2009,7 @@ redo:
if (int_icb != 0) { /* was ICB returned for an I/O or interrupt */
int il = ilev; /* get the interrupt level */
sim_debug(DEBUG_IRQ, &cpu_dev,
"Normal int scan return icb %08x level %02x irq_pend %02x wait4int %02x\n",
"<>Normal int return icb %06x level %02x irq_pend %01x wait4int %01x\n",
int_icb, il, irq_pend, wait4int);
/* take interrupt, store the PSD, fetch new PSD */
@ -2029,28 +2022,30 @@ redo:
/* set new map mode and interrupt blocking state in CPUSTATUS */
modes = PSD1 & 0x87000000; /* extract bits 0, 5, 6, 7 from PSD 1 */
CPUSTATUS &= ~0x87000000; /* reset bits in CPUSTATUS */
CPUSTATUS |= modes; /* not insert into CPUSTATUS */
CPUSTATUS |= modes; /* now insert into CPUSTATUS */
if (PSD2 & MAPBIT) {
CPUSTATUS |= 0x00800000; /* set bit 8 of cpu status */
CPUSTATUS |= BIT8; /* set bit 8 of cpu status */
modes |= MAPMODE; /* set mapped mode */
} else
CPUSTATUS &= 0xff7fffff; /* reset bit 8 of cpu status */
if ((PSD2 & 0x8000) == 0) { /* is it retain blocking state */
if (PSD2 & 0x4000) { /* no, is it set blocking state */
CPUSTATUS |= 0x80; /* yes, set blk state in cpu status bit 24 */
t = SPAD[il+0x80]; /* get spad entry for interrupt */
/* This test fixed the hangs on terminal input for diags & UTX! */
/*TRY*/ t = SPAD[il+0x80]; /* get spad entry for interrupt */
/* Class F I/O spec says to reset interrupt active if user's */
/* interrupt service routine runs with interrupts blocked */
// if ((t & 0x0f000000) == 0x0f000000) { /* if class F clear interrupt */
/*TRY*/ if ((t & 0x0f000000) == 0x0f000000) { /* if class F clear interrupt */
/* if this is F class I/O interrupt, clear the active level */
/* SPAD entries for interrupts begin at 0x80 */
INTS[il] &= ~INTS_ACT; /* deactivate specified int level */
SPAD[il+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */
irq_pend = 1; /* scan for interrupts again */
sim_debug(DEBUG_IRQ, &cpu_dev,
"Auto-reset interrupt INTS[%02x] %08x SPAD[%03x] %08x\n",
"<>Auto-reset interrupt INTS[%02x] %08x SPAD[%03x] %08x\n",
il, INTS[il], il+0x80, SPAD[il+0x80]);
// }
/*TRY*/ }
}
else
CPUSTATUS &= ~0x80; /* no, reset blk state in cpu status bit 24 */
@ -2062,20 +2057,25 @@ redo:
SPAD[0xf5] = PSD2; /* save the current PSD2 */
SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */
sim_debug(DEBUG_IRQ, &cpu_dev,
"Inter %03x OPSD1 %08x OPSD2 %08x NPSD1 %08x NPSD2 %08x\n",
"<>Int %03x OPSD1 %08x OPSD2 %08x NPSD1 %08x NPSD2 %08x\n",
il, RMW(int_icb), RMW(int_icb+4), PSD1, PSD2);
bc = RMW(int_icb+20) & 0xffffff;
if (RMW(int_icb+16) == 0)
sim_debug(DEBUG_IRQ, &cpu_dev,
"Inter2 %03x ICBA %06x IOCLA %06x\n",
"<>Int2 %03x ICBA %06x IOCLA %06x\n",
il, int_icb, RMW(int_icb+16));
else
sim_debug(DEBUG_IRQ, &cpu_dev,
"Inter2 %03x ICBA %06x IOCLA %06x STAT %08x SW1 %08x SW2 %08x\n",
"<>Int2 %03x ICBA %06x IOCLA %06x STAT %08x SW1 %08x SW2 %08x\n",
il, int_icb, RMW(int_icb+16), RMW(int_icb+20), RMW(bc), RMW(bc+4));
wait4int = 0; /* wait is over for int */
irq_pend = 1; /* scan for interrupts again */
skipinstr = 1; /* skip next inter test after this instr */
#ifdef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"Skipinstr set to one PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
PSD1, PSD2, CPUSTATUS);
#endif
goto skipi; /* skip int test */
}
/* see if waiting at a wait instruction */
@ -2094,7 +2094,7 @@ redo:
PSD2 = M[4>>2]; /* PSD2 from location 4 */
modes = PSD1 & 0x87000000; /* extract bits 0, 5, 6, 7 from PSD 1 */
CPUSTATUS &= ~0x87000000; /* reset bits in CPUSTATUS */
CPUSTATUS |= modes; /* not insert into CPUSTATUS */
CPUSTATUS |= modes; /* now insert into CPUSTATUS */
sim_debug(DEBUG_IRQ, &cpu_dev, "Boot Loading PSD1 %.8x PSD2 %.8x\n", PSD1, PSD2);
/* set interrupt blocking state in CPUSTATUS */
CPUSTATUS |= 0x80; /* set blocked state in cpu status, bit 24 too */
@ -2103,6 +2103,11 @@ redo:
SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */
loading = 0; /* we are done loading */
skipinstr = 1; /* skip next interrupt test only once */
#ifdef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"Skipinstr set to one PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
PSD1, PSD2, CPUSTATUS);
#endif
}
goto wait_loop; /* continue waiting */
}
@ -2121,12 +2126,17 @@ redo:
attention_trap = 0; /* clear flag */
sim_debug(DEBUG_XIO, &cpu_dev, "Attention TRAP %04x\n", TRAPME);
skipinstr = 1; /* skip next interrupt test only once */
#ifdef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"Skipinstr set to one PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
PSD1, PSD2, CPUSTATUS);
#endif
goto newpsd; /* got process trap */
}
skipi:
i_flags = 0; /* do not update pc if MF or NPM */
skipinstr = 0; /* skip only once */
//XXX skipinstr = 0; /* skip only once */
TRAPSTATUS = CPUSTATUS & 0x57; /* clear all trap status except cpu type */
/* fill IR from logical memory address */
@ -2172,10 +2182,6 @@ skipi:
if (IR == 0x00020000) { /* is this a NOP from rt hw? */
PSD1 = (PSD1 + 2) | (((PSD1 & 2) >> 1) & 1); /* skip this instruction */
// fprintf(stderr, "RIGHT HW skip NOP instr %x skip nop at %x\n", IR, PSD1);
if (skipinstr == 2) { /* last instr was lf hw and rt NOP, try ints again */
skipinstr = 0; /* only test this once */
goto redo; /* check for ints now */
}
skipinstr = 0; /* only test this once */
goto skipi; /* go read next instruction */
}
@ -2920,9 +2926,11 @@ exec:
case 0xB: /* RPSWT */ /* Read Processor Status Word 2 (PSD2) */
if ((GPR[reg] & 0x80000000) && (CPU_MODEL < MODEL_V9)) {
/* if bit 0 of reg set, return (default 0) CPU Configuration Word */
sim_debug(DEBUG_CMD, &cpu_dev,
#ifdef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"RPSWT READ CCW GPR[%x] %08x CCW %04x SPAD[0xf5] %08x PSD2 %08x CPUSTATUS %08x\n",
reg, GPR[reg], CCW, SPAD[0xf5], PSD2, CPUSTATUS);
#endif
dest = CCW; /* no cache or shared memory */
//NO WCS dest |= 0x0000c000; /* set SIM bit for DIAGS */
/* make sure bit 19 is zero saying IPU not present */
@ -2940,31 +2948,39 @@ exec:
CMSMC |= 0x00000200; /* bit 22, Access Protection ECO present */
CMSMC |= 0x00000010; /* CPU Firmware Version 1/Rev level 0 */
dest = CMSMC; /* return starus */
sim_debug(DEBUG_CMD, &cpu_dev,
#ifdef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"RPSWT READ Cache/Shadow CW GPR[%x] = %08x CMSMC %04x SPAD[0xf5] %x PSD2 %x\n",
reg, GPR[reg], CMSMC, SPAD[0xf5], PSD2);
#endif
} else
if ((GPR[reg] & 0x40000000) && (CPU_MODEL == MODEL_V9)) {
/* if bit 1 of reg set, return CPU Shadow Memory Configuration Word */
CSMCW = 0x00000000; /* no Shadow unit present */
sim_debug(DEBUG_CMD, &cpu_dev,
#ifdef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"RPSWT READ V9 CPU Shadow Memory CW GPR[%x] = %08x CSMCW %04x SPAD[0xf5] %x PSD2 %x\n",
reg, GPR[reg], CSMCW, SPAD[0xf5], PSD2);
#endif
dest = CSMCW; /* return starus */
} else
if ((GPR[reg] & 0x20000000) && (CPU_MODEL == MODEL_V9)) {
/* if bit 2 of reg set, return Cache Memory Configuration Word */
ISMCW = 0x00000000; /* no Shadow unit present */
sim_debug(DEBUG_CMD, &cpu_dev,
#ifdef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"RPSWT READ V9 IPU Shadow Memory CW GPR[%x] = %08x ISMCW %04x SPAD[0xf5] %x PSD2 %x\n",
reg, GPR[reg], ISMCW, SPAD[0xf5], PSD2);
#endif
dest = ISMCW; /* return starus */
} else
if ((GPR[reg] & BIT0) == 0x00000000) {
/* if bit 0 of reg not set, return PSD2 */
sim_debug(DEBUG_CMD, &cpu_dev,
#ifdef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"RPSWT READ PSW2 GPR[%x] %08x SPAD[0xf5] %08x PSD2 %08x CPUSTATUS %08x\n",
reg, GPR[reg], SPAD[0xf5], PSD2, CPUSTATUS);
#endif
/* make sure bit 49 (block state is current stat */
dest = SPAD[0xf5]; /* get PSD2 for user from SPAD 0xf5 */
dest &= ~0x0000c000; /* clear bits 48 & 49 */
@ -4023,9 +4039,6 @@ skipit:
break;
}
td = (t_int64)dest % (t_int64)source; /* remainder */
// dbl = !(td >= 0); /* double reg is neg remainder */
// dbl = ((t_int64)td < 0); /* double reg is neg remainder */
dbl = (td < 0); /* double reg is neg remainder */
if (((td & DMSIGN) ^ (dest & DMSIGN)) != 0) /* Fix sign if needed */
td = NEGATE32(td); /* dividend and remainder must be same sign */
dest = (t_int64)dest / (t_int64)source; /* now do the divide */
@ -5906,9 +5919,10 @@ doovr2:
goto newpsd; /* go execute the trap now */
}
if ((TRAPME = Mem_read(addr, &temp))) { /* get PSD1 from memory */
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) {
TRAPSTATUS |= BIT10; /* set bit 10 of trap status */
else
TRAPSTATUS |= BIT7; /* set bit 7 of trap status */
} else
TRAPSTATUS |= BIT18; /* set bit 18 of trap status */
goto newpsd; /* memory read error or map fault */
}
@ -5921,18 +5935,20 @@ doovr2:
if (opr & 0x0200) { /* Was it LPSDCM? */
if ((TRAPME = Mem_read(addr+4, &temp2))) { /* get PSD2 from memory */
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) {
TRAPSTATUS |= BIT10; /* set bit 10 of trap status */
else
TRAPSTATUS |= BIT7; /* set bit 7 of trap status */
} else
TRAPSTATUS |= BIT18; /* set bit 18 of trap status */
goto newpsd; /* memory read error or map fault */
}
PSD2 = temp2; /* PSD2 access good, so save it */
} else {
if ((TRAPME = Mem_read(addr+4, &temp2))) { /* get PSD2 from memory */
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) {
TRAPSTATUS |= BIT10; /* set bit 10 of trap status */
else
TRAPSTATUS |= BIT7; /* set bit 7 of trap status */
} else
TRAPSTATUS |= BIT18; /* set bit 18 of trap status */
goto newpsd; /* memory read error or map fault */
}
@ -6025,7 +6041,7 @@ doovr2:
PSD2 &= ~RETMBIT; /* turn off retain bit in PSD2 */
SPAD[0xf5] = PSD2; /* save the current PSD2 */
SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"LPSDCM MAPS LOADED TRAPME = %02x PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
TRAPME, PSD1, PSD2, CPUSTATUS);
}
@ -6052,14 +6068,25 @@ doovr2:
SPAD[0xf5] = ix; /* restore the current PSD2 to SPAD */
SPAD[0xf9] = CPUSTATUS; /* save the cpu status in SPAD */
irq_pend = reg; /* restore intr status */
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) {
TRAPSTATUS |= BIT10; /* set bit 10 of trap status */
else
TRAPSTATUS |= BIT7; /* set bit 7 of trap status */
} else
TRAPSTATUS |= BIT18; /* set bit 18 of trap status */
goto newpsd; /* go process error */
}
skipinstr = 1; /* do not allow intr on next instruction */
#ifdef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"Skipinstr set to one PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
PSD1, PSD2, CPUSTATUS);
#endif
drop_nop = 0; /* nothing to drop */
#ifdef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"LPSD(CM) Done PSD1 %08x PSD2 %08x CPUSTATUS %08x irq %01x\n",
PSD1, PSD2, CPUSTATUS, irq_pend);
#endif
goto newpsd; /* load the new psd, or process error */
break;
@ -6128,6 +6155,8 @@ doovr2:
// break; /* ignore */
if ((t & 0x0f000000) == 0x0f000000) /* if class F ignore instruction */
break; /* ignore for F class */
/* does not effect REQ status */
INTS[prior] |= INTS_ENAB; /* enable specified int level */
SPAD[prior+0x80] |= SINT_ENAB; /* enable in SPAD too */
irq_pend = 1; /* start scanning interrupts again */
@ -6143,6 +6172,11 @@ doovr2:
sim_debug(DEBUG_IRQ, &cpu_dev, "Intv Timer EI %02x Turn on\n", prior);
itm_setup(1, prior); /* tell timer to start */
}
#ifndef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"EI lev %02x Skipinstr set to one PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
prior, PSD1, PSD2, CPUSTATUS);
#endif
break;
case 0x1: /* DI FC01 */
@ -6155,10 +6189,11 @@ doovr2:
break; /* ignore */
if ((t & 0x0f000000) == 0x0f000000) /* if class F ignore instruction */
break; /* ignore for F class */
/* active state is left alone */
INTS[prior] &= ~INTS_ENAB; /* disable specified int level */
INTS[prior] &= ~INTS_REQ; /* clears any requests also */
SPAD[prior+0x80] &= ~SINT_ENAB; /* disable in SPAD too */
INTS[prior] &= ~INTS_REQ; /* clears any requests also */
/* test for clock at address 0x7f06 and interrupt level 0x18 */
/* the diags want the type to be 0, others want 3, so ignore */
@ -6171,6 +6206,11 @@ doovr2:
itm_setup(0, prior); /* tell timer to stop */
sim_debug(DEBUG_IRQ, &cpu_dev, "Intv Timer DI %02x Turn off\n", prior);
}
#ifndef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"DI lev %02x Skipinstr set to %01x PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
prior, skipinstr, PSD1, PSD2, CPUSTATUS);
#endif
break;
case 0x2: /* RI FC02 */
@ -6185,6 +6225,11 @@ doovr2:
break; /* ignore for F class */
INTS[prior] |= INTS_REQ; /* set the request flag for this level */
irq_pend = 1; /* start scanning interrupts again */
#ifndef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"RI lev %02x Skipinstr set to one PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
prior, PSD1, PSD2, CPUSTATUS);
#endif
break;
case 0x3: /* AI FC03 */
@ -6199,6 +6244,11 @@ doovr2:
INTS[prior] |= INTS_ACT; /* activate specified int level */
SPAD[prior+0x80] |= SINT_ACT; /* activate in SPAD too */
irq_pend = 1; /* start scanning interrupts again */
#ifndef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"AI lev %02x Skipinstr set to one PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
prior, PSD1, PSD2, CPUSTATUS);
#endif
break;
case 0x4: /* DAI FC04 */
@ -6217,6 +6267,11 @@ doovr2:
/* instruction following a DAI can not be interrupted */
/* skip tests for interrupts if this is the case */
skipinstr = 1; /* skip interrupt test */
#ifndef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"DAI lev %02x Skipinstr set to one PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
prior, PSD1, PSD2, CPUSTATUS);
#endif
drop_nop = 0; /* nothing to drop */
break;
@ -6503,15 +6558,17 @@ mcheck:
/* SPAD entries for interrupts begin at 0x80 */
INTS[ix] &= ~INTS_ACT; /* deactivate specified int level */
SPAD[ix+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */
irq_pend = 1; /* start scanning interrupts again */
skipinstr = 1; /* skip interrupt test */
if ((TRAPME = checkxio(chsa, &status)))
goto newpsd; /* error returned, trap cpu */
PSD1 = ((PSD1 & 0x87fffffe) | (status & 0x78000000)); /* insert status */
#ifdef DO_DYNAMIC_DEBUG
/* start debugging */
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ);
irq_pend = 1; /* start scanning interrupts again */
skipinstr = 1; /* skip interrupt test */
#ifdef NOTNOW
sim_debug(DEBUG_IRQ, &cpu_dev,
"Skipinstr set to one PSD1 %08x PSD2 %08x CPUSTATUS %08x\n",
PSD1, PSD2, CPUSTATUS);
#endif
/*XXX*/ drop_nop = 0; /* nothing to drop */
PSD1 = ((PSD1 & 0x87fffffe) | (status & 0x78000000)); /* insert status */
break;
} /* end of XIO switch */
break;

View File

@ -102,6 +102,8 @@
/* simulator devices configuration */
#define NUM_DEVS_IOP 1 /* 1 device IOP channel controller */
#define NUM_UNITS_IOP 1 /* 1 master IOP channel device */
#define NUM_DEVS_MFP 1 /* 1 device MFP channel controller */
#define NUM_UNITS_MFP 1 /* 1 master MFP channel device */
#define NUM_DEVS_COM 2 /* 8-Line async controller */
#define NUM_UNITS_COM 16 /* 8-Line async units */
#define NUM_DEVS_CON 1 /* 1 I/O console controller */
@ -129,6 +131,9 @@ extern UNIT cpu_unit; /* the cpu unit */
#ifdef NUM_DEVS_IOP
extern DEVICE iop_dev; /* IOP channel controller */
#endif
#ifdef NUM_DEVS_MFP
extern DEVICE mfp_dev; /* MFP channel controller */
#endif
#ifdef NUM_DEVS_RTOM
extern DEVICE rtc_dev; /* RTOM rtc */
extern DEVICE itm_dev; /* RTOM itm */

View File

@ -25,7 +25,7 @@
extern t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
extern t_stat show_dev_addr(FILE *st, UNIT *uptr, int32 v, CONST void *desc);
extern void chan_end(uint16 chan, uint8 flags);
extern void chan_end(uint16 chsa, uint8 flags);
extern int chan_read_byte(uint16 chsa, uint8 *data);
extern int chan_write_byte(uint16 chsa, uint8 *data);
extern void set_devattn(uint16 addr, uint8 flags);
@ -44,13 +44,13 @@ extern uint32 SPAD[]; /* cpu SPAD memory */
/* useful conversions */
/* Fill STAR value from cyl, trk, sec data */
#define CHS2STAR(c,h,s) (((c<<16) & 0xffff0000)|((h<<8) & 0xff00)|(s & 0xff))
#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff))
/* convert STAR value to number of sectors */
#define STAR2SEC(star,spt,spc) ((star&0xff)+(((star>>8)&0xff)*spt)+((star>>16)*spc))
/* convert STAR value to number of heads or tracks */
#define STAR2TRK(star,tpc) ((star >> 16) * tpc + ((star >> 8) & 0x0ff))
/* convert STAR value to number of cylinders */
#define STAR2CYL(star) ((star >> 16) & 0xffff)
#define STAR2CYL(star) ((star >> 16) & RMASK)
/* convert byte value to number of sectors mod sector size */
#define BYTES2SEC(bytes,ssize) (((bytes) + (ssize-1)) >> 10)
/* get sectors per track for specified type */
@ -144,7 +144,7 @@ bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option
char ldatrfhdc; FHD head count
*/
#define CMD u3
#define CMDu3 u3
/* u3 */
/* in u3 is device command code and status */
#define DSK_CMDMSK 0x00ff /* Command being run */
@ -254,7 +254,7 @@ bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option
mini-module)
*/
/* Not Used up7 */
/* INCH addr up7 */
#ifdef NOUSED
/* registers */
@ -298,9 +298,9 @@ disk_type[] =
uint8 disk_preio(UNIT *uptr, uint16 chan) ;
uint8 disk_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ;
uint8 disk_haltio(uint16 addr);
t_stat disk_srv(UNIT *);
t_stat disk_boot(int32, DEVICE *);
uint8 disk_haltio(UNIT *uptr);
t_stat disk_srv(UNIT *uptr);
t_stat disk_boot(int32 unitnum, DEVICE *dptr);
void disk_ini(UNIT *, t_bool);
t_stat disk_reset(DEVICE *);
t_stat disk_attach(UNIT *, CONST char *);
@ -363,6 +363,7 @@ DEVICE dda_dev = {
"DMA", dda_unit, NULL/*dda_reg*/, disk_mod,
NUM_UNITS_DISK, 16, 24, 4, 16, 32,
NULL, NULL, &disk_reset, &disk_boot, &disk_attach, &disk_detach,
/* ctxt is the DIB pointer */
&dda_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug,
NULL, NULL, &disk_help, NULL, NULL, &disk_description
};
@ -413,6 +414,7 @@ DEVICE ddb_dev = {
"DMB", ddb_unit, NULL, /*ddb_reg*/, disk_mod,
NUM_UNITS_DISK, 16, 24, 4, 16, 32,
NULL, NULL, &disk_reset, &disk_boot, &disk_attach, &disk_detach,
/* ctxt is the DIB pointer */
&ddb_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug,
NULL, NULL, &disk_help, NULL, NULL, &disk_description
};
@ -434,11 +436,11 @@ uint32 disksec2star(uint32 daddr, int type)
uint8 disk_preio(UNIT *uptr, uint16 chan)
{
DEVICE *dptr = get_dev(uptr);
uint16 chsa = GET_UADDR(uptr->CMD);
uint16 chsa = GET_UADDR(uptr->CMDu3);
int unit = (uptr - dptr->units);
sim_debug(DEBUG_CMD, dptr, "disk_preio CMD %08x unit %02x\n", uptr->CMD, unit);
if ((uptr->CMD & 0xff00) != 0) { /* just return if busy */
sim_debug(DEBUG_CMD, dptr, "disk_preio CMD %08x unit %02x\n", uptr->CMDu3, unit);
if ((uptr->CMDu3 & 0xff00) != 0) { /* just return if busy */
return SNS_BSY;
}
@ -448,25 +450,25 @@ uint8 disk_preio(UNIT *uptr, uint16 chan)
uint8 disk_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
{
uint16 chsa = GET_UADDR(uptr->CMD);
uint16 chsa = GET_UADDR(uptr->CMDu3);
DEVICE *dptr = get_dev(uptr);
int unit = (uptr - dptr->units);
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
sim_debug(DEBUG_CMD, dptr,
"disk_startcmd chsa %04x unit %02x cmd %02x CMD %08x\n",
chsa, unit, cmd, uptr->CMD);
chsa, unit, cmd, uptr->CMDu3);
if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
uptr->SNS |= SNS_INTVENT; /* unit intervention required */
if (cmd != DSK_SNS) /* we are completed with unit check status */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
}
if ((uptr->CMD & DSK_CMDMSK) != 0) {
uptr->CMD |= DSK_BUSY; /* Flag we are busy */
if ((uptr->CMDu3 & DSK_CMDMSK) != 0) {
uptr->CMDu3 |= DSK_BUSY; /* Flag we are busy */
return SNS_BSY;
}
if ((uptr->CMD & 0xff00) != 0) { /* if any status info, we are busy */
if ((uptr->CMDu3 & 0xff00) != 0) { /* if any status info, we are busy */
return SNS_BSY;
}
sim_debug(DEBUG_CMD, dptr, "disk_startcmd CMD continue unit=%02x cmd %02x\n", unit, cmd);
@ -479,18 +481,18 @@ uint8 disk_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
"disk_startcmd starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
uptr->u4, chsa, chp->ccw_addr, chp->ccw_count);
uptr->CMD |= DSK_INCH2; /* use 0xf0 for inch, just need int */
uptr->CMDu3 |= DSK_INCH2; /* use 0xf0 for inch, just need int */
sim_activate(uptr, 20); /* start things off */
return 0;
break;
case DSK_SCK: /* Seek command 0x07 */
case DSK_XEZ: /* Rezero & Read IPL record 0x1f */
case DSK_XEZ: /* Rezero & Read IPL record 0x37 */
case DSK_WD: /* Write command 0x01 */
case DSK_RD: /* Read command 0x02 */
case DSK_LMR: /* read mode register */
case DSK_LMR: /* read mode register 0x15 */
uptr->CMD |= cmd; /* save cmd */
uptr->CMDu3 |= cmd; /* save cmd */
sim_debug(DEBUG_CMD, dptr,
"disk_startcmd starting disk seek r/w cmd %02x chsa %04x\n",
cmd, chsa);
@ -499,36 +501,36 @@ uint8 disk_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
break;
case DSK_NOP: /* NOP 0x03 */
uptr->CMD |= cmd; /* save cmd */
uptr->CMDu3 |= cmd; /* save cmd */
sim_activate(uptr, 20); /* start things off */
return 0;
break;
case DSK_SNS: /* Sense 0x04 */
uptr->CMD |= cmd; /* save cmd */
uptr->CMDu3 |= cmd; /* save cmd */
sim_activate(uptr, 20); /* start things off */
break;
case DSK_WSL: /* WSL 0x31 */
uptr->CMD |= cmd; /* save cmd */
uptr->CMDu3 |= cmd; /* save cmd */
sim_activate(uptr, 20); /* start things off */
return 0;
break;
case DSK_RSL: /* RSL 0x32 */
uptr->CMD |= cmd; /* save cmd */
uptr->CMDu3 |= cmd; /* save cmd */
sim_activate(uptr, 20); /* start things off */
return 0;
break;
case DSK_WTL: /* WTL 0x51 */
uptr->CMD |= cmd; /* save cmd */
uptr->CMDu3 |= cmd; /* save cmd */
sim_activate(uptr, 20); /* start things off */
return 0;
break;
case DSK_RTL: /* RTL 0x52 */
uptr->CMD |= cmd; /* save cmd */
uptr->CMDu3 |= cmd; /* save cmd */
sim_activate(uptr, 20); /* start things off */
return 0;
break;
@ -546,11 +548,11 @@ uint8 disk_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
/* Handle processing of disk requests. */
t_stat disk_srv(UNIT *uptr)
{
uint16 chsa = GET_UADDR(uptr->CMD);
uint16 chsa = GET_UADDR(uptr->CMDu3);
DEVICE *dptr = get_dev(uptr);
DIB *dibp = (DIB *)dptr->ctxt; /* get DIB address */
CHANP *chp = (CHANP *)dibp->chan_prg; /* get pointer to channel program */
int cmd = uptr->CMD & DSK_CMDMSK;
int cmd = uptr->CMDu3 & DSK_CMDMSK;
int type = GET_TYPE(uptr->flags);
uint32 trk, cyl, sec;
int unit = (uptr - dptr->units);
@ -564,7 +566,7 @@ t_stat disk_srv(UNIT *uptr)
sim_debug(DEBUG_CMD, dptr,
"disk_srv entry unit %02x CMD %08x chsa %04x count %04x %x/%x/%x \n",
unit, uptr->CMD, chsa, chp->ccw_count,
unit, uptr->CMDu3, chsa, chp->ccw_count,
STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff));
if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
@ -597,7 +599,7 @@ t_stat disk_srv(UNIT *uptr)
/* a pointer to the INCH buffer followed by 8 drive attribute words that */
/* contains the flags, sector count, MHD head count, and FHD count */
/* len has the byte count from IOCD wd2 and should be 0x24 (36) */
/* the INCH buffer address must be set for the parrent channel as well */
/* the INCH buffer address must be set for the parent channel as well */
/* as all other devices on the channel. Call set_inch() to do this for us */
/* just return OK and channel software will use u4 as status buffer addr */
@ -605,7 +607,7 @@ t_stat disk_srv(UNIT *uptr)
if (len != 36) {
/* we have invalid count, error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
@ -620,7 +622,7 @@ t_stat disk_srv(UNIT *uptr)
for (i=0; i < 36; i++) {
if (chan_read_byte(chsa, &buf[i])) {
/* we have error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
@ -645,13 +647,13 @@ t_stat disk_srv(UNIT *uptr)
#ifdef NOTYET
if ((i == SCPE_MEM) || (i == SCPE_ARG)) { /* any error */
/* we have error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
#endif
uptr->CMD &= ~(0xffff); /* remove old cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
sim_debug(DEBUG_CMD, dptr,
"disk_srv cmd INCH chsa %04x addr %06x count %04x completed\n",
chsa, mema, chp->ccw_count);
@ -664,7 +666,7 @@ t_stat disk_srv(UNIT *uptr)
break;
case DSK_WSL: /* WSL 0x31 make into NOP */
uptr->CMD &= ~(0xffff); /* remove old cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
sim_debug(DEBUG_CMD, dptr,
"disk_srv cmd WSL chsa %04x count %04x completed\n",
chsa, chp->ccw_count);
@ -675,8 +677,10 @@ t_stat disk_srv(UNIT *uptr)
for (i = 0; i < len; i++) {
if (chan_read_byte(chsa, &buf[i])) {
/* we have write error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
//XXX goto goout;
return SCPE_OK;
break;
}
if ((i%16) == 0)
@ -684,12 +688,12 @@ t_stat disk_srv(UNIT *uptr)
sim_debug(DEBUG_DETAIL, dptr, " %02x", buf[i]);
}
sim_debug(DEBUG_DETAIL, dptr, "\n");
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
//XXXgoout:
break;
case DSK_WTL: /* WTL 0x51 make into NOP */
uptr->CMD &= ~(0xffff); /* remove old cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
sim_debug(DEBUG_CMD, dptr,
"disk_srv cmd WTL chsa %04x count %04x completed\n",
chsa, chp->ccw_count);
@ -699,8 +703,10 @@ t_stat disk_srv(UNIT *uptr)
for (i = 0; i < 30; i++) {
if (chan_read_byte(chsa, &buf[i])) {
/* we have read error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
//XXX goto goout;
break;
}
if (i == 16)
@ -708,12 +714,11 @@ t_stat disk_srv(UNIT *uptr)
sim_debug(DEBUG_DETAIL, dptr, " %02x", buf[i]);
}
sim_debug(DEBUG_DETAIL, dptr, "\n");
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;
case DSK_NOP: /* NOP 0x03 */
uptr->CMD &= ~(0xffff); /* remove old cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
sim_debug(DEBUG_CMD, dptr,
"disk_srv cmd NOP chsa %04x count %04x completed\n",
chsa, chp->ccw_count);
@ -794,33 +799,36 @@ t_stat disk_srv(UNIT *uptr)
unit, ch);
chan_write_byte(chsa, &ch);
}
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
break;
case DSK_SCK: /* Seek cylinder, track, sector 0x07 */
/* If we are waiting on seek to finish, check if there yet. */
if (uptr->CMD & DSK_SEEKING) {
if (uptr->CMDu3 & DSK_SEEKING) {
/* see if on cylinder yet */
if (STAR2CYL(uptr->STAR) == STAR2CYL(uptr->CHS)) {
/* we are on cylinder, seek is done */
sim_debug(DEBUG_CMD, dptr, "disk_srv seek on cylinder unit=%02x %04x %04x\n",
unit, uptr->STAR >> 16, uptr->CHS >> 16);
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
/* 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);
sim_activate(uptr, 20);
return SCPE_OK;
//XXX sim_activate(uptr, 20);
break;
} else {
/* we have wasted enough time, we are there */
#ifndef DO_SEEK_AGAIN
#ifdef DO_SEEK_AGAIN
/* calculate file position in bytes of requested sector */
/* file offset in bytes */
tstart = STAR2SEC(uptr->STAR, SPT(type), SPC(type)) * SSB(type);
/* just reseek to the location where we will r/w data */
if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */
sim_debug(DEBUG_DETAIL, dptr, "disk_srv Error on seek to %04x\n", tstart);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
}
#endif
uptr->CHS = uptr->STAR; /* we are there */
@ -849,25 +857,26 @@ t_stat disk_srv(UNIT *uptr)
"disk_srv seek error unit=%02x star %02x %02x %02x %02x\n",
unit, buf[0], buf[1], buf[2], buf[3]);
/* we have error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
break;
}
/* just read the next byte */
}
}
/* done reading, see how many we read */
if (i == 1) {
/* UTX wants to set seek STAR to zero */
buf[0] = buf[1] = buf[2] = buf[3] = 0;
break;
}
/* just read the next byte */
}
}
/* else the cyl, trk, and sect are ready to update */
sim_debug(DEBUG_CMD, dptr,
"disk_srv STAR unit=%02x star %02x %02x %02x %02x\n",
unit, buf[0], buf[1], buf[2], buf[3]);
rezero:
//XXXrezero:
sim_debug(DEBUG_DETAIL, dptr,
"disk_srv seek unit=%02x star %02x %02x %02x %02x\n",
unit, buf[0], buf[1], buf[2], buf[3]);
@ -886,11 +895,11 @@ rezero:
trk >= disk_type[type].nhds ||
buf[3] >= disk_type[type].spt) {
sim_debug(DEBUG_CMD, dptr,
sim_debug(DEBUG_EXP, dptr,
"disk_srv seek ERROR cyl %04x trk %02x sec %02x unit=%02x\n",
cyl, trk, buf[3], unit);
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; /* set error status */
/* we have an error, tell user */
@ -911,15 +920,18 @@ rezero:
/* just seek to the location where we will r/w data */
if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */
sim_debug(DEBUG_DETAIL, dptr, "disk_srv Error on seek to %04x\n", tstart);
sim_debug(DEBUG_EXP, dptr, "disk_srv Error on seek to %04x\n", tstart);
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
}
/* Check if already on correct cylinder */
/* if not, do a delay to slow things down */
if (STAR2CYL(uptr->STAR) != STAR2CYL(uptr->CHS)) {
/* Do a fake seek to kill time */
uptr->CMD |= DSK_SEEKING; /* show we are seeking */
sim_debug(DEBUG_DETAIL, dptr,
uptr->CMDu3 |= DSK_SEEKING; /* show we are seeking */
sim_debug(DEBUG_EXP, dptr,
"disk_srv seeking unit=%02x to cyl %04x trk %02x sec %02x\n",
unit, cyl, trk, buf[3]);
sim_activate(uptr, 20); /* start us off */
@ -928,7 +940,7 @@ rezero:
sim_debug(DEBUG_DETAIL, dptr,
"disk_srv done seeking to %04x cyl %04x trk %02x sec %02x\n",
tstart, cyl, trk, buf[3]);
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_DEVEND|SNS_CHNEND);
}
return SCPE_OK;
@ -939,20 +951,38 @@ rezero:
/* Do a seek to 0 */
uptr->STAR = 0; /* set STAR to 0, 0, 0 */
uptr->CHS = 0; /* set current CHS to 0, 0, 0 */
uptr->CMD &= ~(0xffff); /* remove old cmd */
uptr->CMD |= DSK_SCK; /* show as seek command */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
uptr->CMDu3 |= DSK_SCK; /* show as seek command */
tstart = 0; /* byte offset is 0 */
#ifdef NOT_NEEDED
/* Read in 1 dummy character for length to inhibit SLI posting */
if (chan_read_byte(chsa, &buf[0])) {
/* we have error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
return SCPE_OK;
//XXX break;
}
#endif
#ifndef DO_NEW_WAY
/* just seek to the location where we will r/w data */
if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */
sim_debug(DEBUG_EXP, dptr, "disk_srv Error on seek to %04x\n", tstart);
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
}
/* we are on cylinder/track/sector zero, so go on */
sim_debug(DEBUG_DETAIL, dptr, "disk_srv done seek trk 0\n");
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_DEVEND|SNS_CHNEND);
return SCPE_OK;
#else
/* zero stuff */
buf[0] = buf[1] = buf[2] = buf[3] = 0;
goto rezero; /* merge with seek code */
#endif
break;
case DSK_LMR:
@ -960,28 +990,28 @@ rezero:
/* Read in 1 character of mode data */
if (chan_read_byte(chsa, &buf[0])) {
/* we have error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
sim_debug(DEBUG_CMD, dptr, "Load Mode Reg unit=%02x old %x new %x\n",
unit, (uptr->SNS)&0xff, buf[0]);
uptr->CMD &= ~(0xffff); /* remove old cmd */
uptr->SNS &= 0x00ffffff; /* clear old mode data */
uptr->CMDu3 &= LMASK; /* remove old cmd */
uptr->SNS &= MASK24; /* clear old mode data */
uptr->SNS |= (buf[0] << 24); /* save mode value */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
break;
case DSK_RD: /* Read Data */
if ((uptr->CMD & DSK_READING) == 0) { /* see if we are reading data */
uptr->CMD |= DSK_READING; /* read from disk starting */
if ((uptr->CMDu3 & DSK_READING) == 0) { /* see if we are reading data */
uptr->CMDu3 |= DSK_READING; /* read from disk starting */
sim_debug(DEBUG_CMD, dptr,
"DISK READ starting CMD %08x chsa %04x buffer %06x count %04x\n",
uptr->CMD, chsa, chp->ccw_addr, chp->ccw_count);
uptr->CMDu3, chsa, chp->ccw_addr, chp->ccw_count);
}
if (uptr->CMD & DSK_READING) { /* see if we are reading data */
if (uptr->CMDu3 & DSK_READING) { /* see if we are reading data */
cyl = STAR2CYL(uptr->CHS); /* get current cyl */
trk = (uptr->CHS >> 8) & 0xff; /* get trk/head */
sec = uptr->CHS & 0xff; /* get sec */
@ -989,12 +1019,16 @@ rezero:
// tstart = STAR2SEC(uptr->STAR, SPT(type), SPC(type));
tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type));
sim_debug(DEBUG_CMD, dptr,
"DISK READ reading CMD %08x chsa %04x tstart %04x buffer %06x count %04x\n",
uptr->CMDu3, chsa, tstart, chp->ccw_addr, chp->ccw_count);
/* read in a sector of data from disk */
if ((len=sim_fread(buf, 1, ssize, uptr->fileref)) != ssize) {
sim_debug(DEBUG_CMD, dptr,
"Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n",
len, ssize, cyl, trk, sec);
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
@ -1010,10 +1044,14 @@ rezero:
sim_debug(DEBUG_DATA, dptr,
"DISK Read %04x bytes leaving %04x from diskfile /%04x/%02x/%02x\n",
i, chp->ccw_count, cyl, trk, sec);
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
goto rddone;
return SCPE_OK;
//XXX goto rddone;
}
// sim_debug(DEBUG_DATA, dptr,
// "DISK Read2 %04x bytes leaving %04x from diskfile /%04x/%02x/%02x\n",
// i, chp->ccw_count, cyl, trk, sec);
}
sim_debug(DEBUG_CMD, dptr,
@ -1025,7 +1063,7 @@ rezero:
sim_debug(DEBUG_DATA, dptr,
"DISK Read complete for read from diskfile /%04x/%02x/%02x\n",
STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff));
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
break;
}
@ -1041,7 +1079,7 @@ rezero:
sim_debug(DEBUG_CMD, dptr,
"DISK Read reached EOM for read from disk @ /%04x/%02x/%02x\n",
STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff));
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
uptr->CHS = 0; /* reset cylinder position */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
@ -1052,18 +1090,18 @@ rezero:
chp->ccw_count, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff));
sim_activate(uptr, 10); /* wait to read next sector */
break;
rddone:
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
//XXXrddone:
//XXX uptr->CMDu3 &= ~(0xffff); /* remove old status bits & cmd */
}
break;
case DSK_WD: /* Write Data */
if ((uptr->CMD & DSK_WRITING) == 0) { /* see if we are writing data */
uptr->CMD |= DSK_WRITING; /* write to disk starting */
if ((uptr->CMDu3 & DSK_WRITING) == 0) { /* see if we are writing data */
uptr->CMDu3 |= DSK_WRITING; /* write to disk starting */
sim_debug(DEBUG_CMD, dptr,
"DISK WRITE starting unit=%02x CMD %02x\n", unit, uptr->CMD);
"DISK WRITE starting unit=%02x CMD %02x\n", unit, uptr->CMDu3);
}
if (uptr->CMD & DSK_WRITING) { /* see if we are writing data */
if (uptr->CMDu3 & DSK_WRITING) { /* see if we are writing data */
cyl = STAR2CYL(uptr->CHS); /* get current cyl */
trk = (uptr->CHS >> 8) & 0xff; /* get trk/head */
sec = uptr->CHS & 0xff; /* get sec */
@ -1077,12 +1115,13 @@ rddone:
if (chan_read_byte(chsa, &ch)) { /* get a byte from memory */
/* if error on reading 1st byte, we are done writing */
if (i == 0) {
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
sim_debug(DEBUG_CMD, dptr,
"DISK Wrote %04x bytes to diskfile cyl %04x hds %02x sec %02x\n",
ssize, cyl, trk, sec);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
goto wrdone;
return SCPE_OK;
//XXX goto wrdone;
}
ch = 0; /* finish out the sector with zero */
len++; /* show we have no more data to write */
@ -1095,7 +1134,7 @@ rddone:
sim_debug(DEBUG_CMD, dptr,
"Error %08x on write %04x bytes to diskfile cyl %04x hds %02x sec %02x\n",
i, ssize, cyl, trk, sec);
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
@ -1103,7 +1142,7 @@ rddone:
sim_debug(DEBUG_DATA, dptr,
"DISK WroteB %04x bytes to diskfile cyl %04x hds %02x sec %02x\n",
ssize, cyl, trk, sec);
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */
break;
}
@ -1122,15 +1161,15 @@ rddone:
sim_debug(DEBUG_CMD, dptr,
"DISK Write reached EOM for write to disk @ /%04x/%02x/%02x\n",
STAR2CYL(uptr->CHS), (uptr->CHS >> 8)&0xff, (uptr->CHS&0xff));
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
uptr->CHS = 0; /* reset cylinder position */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
sim_activate(uptr, 10); /* keep writing */
break;
wrdone:
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
//XXXwrdone:
//XXX uptr->CMDu3 &= ~(0xffff); /* remove old status bits & cmd */
}
break;
@ -1216,7 +1255,7 @@ wrdone:
for (i = 0; i < 30; i++) {
if (chan_write_byte(chsa, &buf[i])) {
/* we have write error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
@ -1227,7 +1266,7 @@ wrdone:
sim_debug(DEBUG_DETAIL, dptr, "\n");
/* command done */
uptr->CMD &= ~(0xffff); /* remove old cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
sim_debug(DEBUG_CMD, dptr, "hsdp_srv cmd RSL done chsa %04x count %04x completed\n",
chsa, chp->ccw_count);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
@ -1331,7 +1370,7 @@ wrdone:
for (i = 0; i < 30; i++) {
if (chan_write_byte(chsa, &buf[i])) {
/* we have write error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
@ -1342,7 +1381,7 @@ wrdone:
sim_debug(DEBUG_DETAIL, dptr, "\n");
/* command done */
uptr->CMD &= ~(0xffff); /* remove old cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
sim_debug(DEBUG_CMD, dptr, "disk_srv cmd RTL done chsa %04x count %04x completed\n",
chsa, chp->ccw_count);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
@ -1351,7 +1390,7 @@ wrdone:
default:
sim_debug(DEBUG_CMD, dptr, "invalid command %02x unit %02x\n", cmd, unit);
uptr->SNS |= SNS_CMDREJ;
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
@ -1366,13 +1405,16 @@ void disk_ini(UNIT *uptr, t_bool f)
DEVICE *dptr = get_dev(uptr);
int i = GET_TYPE(uptr->flags);
uptr->CMD &= ~0x7fff; /* clear out the flags but leave ch/sa */
/* start out at sector 0 */
uptr->CHS = 0; /* set CHS to cyl/hd/sec = 0 */
uptr->STAR = 0; /* set STAR to cyl/hd/sec = 0 */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
uptr->SNS = ((uptr->SNS & 0x00ffffff) | (disk_type[i].type << 24)); /* save mode value */
/* total sectors on disk */
uptr->capac = CAP(i); /* size in sectors */
sim_debug(DEBUG_EXP, &dda_dev, "DMA init device %s on unit DMA%.1x cap %x %d\n",
dptr->name, GET_UADDR(uptr->CMD), uptr->capac, uptr->capac);
dptr->name, GET_UADDR(uptr->CMDu3), uptr->capac, uptr->capac);
}
t_stat disk_reset(DEVICE *dptr)
@ -1472,6 +1514,7 @@ int disk_format(UNIT *uptr) {
/* seek to sector 0 */
if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */
fprintf (stderr, "Error on seek to 0\r\n");
return 1;
}
/* get buffer for track data in bytes */
@ -1524,10 +1567,15 @@ int disk_format(UNIT *uptr) {
/* setup dmap pointed to by track label 0 wd[3] = (cyl-4) * spt + (spt - 1) */
/* write dmap data to last sector on disk */
sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET); /* seek last sector */
if ((sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET)) != 0) { /* seek last sector */
sim_debug(DEBUG_CMD, dptr,
"Error on last sector seek to diskfile sect %06x\n", (cap-1) * ssize);
return 1;
}
if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) {
sim_debug(DEBUG_CMD, dptr,
"Error on vendor map write to diskfile sect %06x\n", (cap-1) * ssize);
"Error on last sector write to diskfile sect %06x\n", (cap-1) * ssize);
return 1;
}
/* 1 cylinder is saved for disk manufacture */
@ -1537,26 +1585,41 @@ int disk_format(UNIT *uptr) {
/* vaddr is (cap) - 3 cyl - 1 track */
/* seek to vendor label area */
sim_fseek(uptr->fileref, (vaddr)*ssize, SEEK_SET); /* seek VMAP */
if ((sim_fseek(uptr->fileref, vaddr*ssize, SEEK_SET)) != 0) { /* seek VMAP */
sim_debug(DEBUG_CMD, dptr,
"Error on vendor map seek to diskfile sect %06x\n", (cap-1) * ssize);
return 1;
}
if ((sim_fwrite((char *)&vmap, sizeof(uint32), 2, uptr->fileref)) != 2) {
sim_debug(DEBUG_CMD, dptr,
"Error on vendor map write to diskfile sect %06x\n", vaddr * ssize);
return 1;
}
/* write dmap to daddr that is the address in trk 0 label */
/* daddr is (cap) - 3 cyl - 2 tracks */
/* vaddr is daddr - spt */
sim_fseek(uptr->fileref, (daddr)*ssize, SEEK_SET); /* seek DMAP */
if ((sim_fseek(uptr->fileref, daddr*ssize, SEEK_SET)) != 0) { /* seek DMAP */
sim_debug(DEBUG_CMD, dptr,
"Error on daddr seek to diskfile sect %06x\n", (cap-1) * ssize);
return 1;
}
if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) {
sim_debug(DEBUG_CMD, dptr,
"Error on dmap write to diskfile sect %06x\n", daddr * ssize);
"Error on daddr write to diskfile sect %06x\n", daddr * ssize);
return 1;
}
sim_fseek(uptr->fileref, (uaddr)*ssize, SEEK_SET); /* seek UMAP */
if ((sim_fseek(uptr->fileref, uaddr*ssize, SEEK_SET)) != 0) { /* seek UMAP */
sim_debug(DEBUG_CMD, dptr,
"Error on umap seek to diskfile sect %06x\n", (cap-1) * ssize);
return 1;
}
if ((sim_fwrite((char *)&umap, sizeof(uint32), 256, uptr->fileref)) != 256) {
sim_debug(DEBUG_CMD, dptr,
"Error on umap write to diskfile sect %06x\n", uaddr * ssize);
return 1;
}
printf("writing to vmap sec %x (%d) bytes %x (%d)\n",
@ -1568,7 +1631,10 @@ int disk_format(UNIT *uptr) {
daddr, daddr, daddr*ssize, daddr*ssize);
/* seek home again */
sim_fseek(uptr->fileref, 0, SEEK_SET); /* seek home */
if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */
fprintf (stderr, "Error on seek to 0\r\n");
return 1;
}
free(buff); /* free cylinder buffer */
return 0;
}
@ -1576,7 +1642,7 @@ int disk_format(UNIT *uptr) {
/* attach the selected file to the disk */
t_stat disk_attach(UNIT *uptr, CONST char *file)
{
uint16 chsa = GET_UADDR(uptr->CMD);
uint16 chsa = GET_UADDR(uptr->CMDu3);
int type = GET_TYPE(uptr->flags);
DEVICE *dptr = get_dev(uptr);
t_stat r;
@ -1647,7 +1713,7 @@ fmt:
/* detach a disk device */
t_stat disk_detach(UNIT *uptr) {
uptr->SNS = 0; /* clear sense data */
uptr->CMD &= ~0xffff; /* no cmd and flags */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
return detach_unit(uptr); /* tell simh we are done with disk */
}
@ -1655,13 +1721,19 @@ t_stat disk_detach(UNIT *uptr) {
t_stat disk_boot(int32 unit_num, DEVICE *dptr) {
UNIT *uptr = &dptr->units[unit_num]; /* find disk unit number */
sim_debug(DEBUG_CMD, dptr, "Disk Boot dev/unit %x\n", GET_UADDR(uptr->CMD));
SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */
SPAD[0xf8] = 0xF000; /* show as F class device */
if ((uptr->flags & UNIT_ATT) == 0)
sim_debug(DEBUG_CMD, dptr, "Disk Boot dev/unit %x\n", GET_UADDR(uptr->CMDu3));
if ((uptr->flags & UNIT_ATT) == 0) {
sim_debug(DEBUG_EXP, &mta_dev, "Disk Boot attach error dev/unit %04x\n",
GET_UADDR(uptr->CMDu3));
return SCPE_UNATT; /* attached? */
}
SPAD[0xf4] = GET_UADDR(uptr->CMDu3); /* put boot device chan/sa into spad */
SPAD[0xf8] = 0xF000; /* show as F class device */
/* now boot the disk */
return chan_boot(GET_UADDR(uptr->CMD), dptr); /* boot the ch/sa */
uptr->CMDu3 &= LMASK; /* remove old status bits & cmd */
return chan_boot(GET_UADDR(uptr->CMDu3), dptr); /* boot the ch/sa */
}
/* Disk option setting commands */

View File

@ -833,7 +833,7 @@ uint32 s_dvfw(uint32 reg, uint32 mem, uint32 *cc) {
if (temp2 >= 0x7fffffc0) /* check for special rounding */
goto RRND2; /* no special handling */
/* FIXME dead code */
if (temp2 == MSIGN) { /* check for minux zero */
if (temp2 == MSIGN) { /* check for minus zero */
temp2 = 0xF8000000; /* yes, fixup value */
expr++; /* bump exponent */
}
@ -844,9 +844,11 @@ uint32 s_dvfw(uint32 reg, uint32 mem, uint32 *cc) {
if ((sign & MSIGN) == 0)
goto RRND1; /* if sign set, don't round yet */
expr += temp; /* add exponent */
if (expr < 0) /* test for underflow */
/* FIX unsigned CMP */
// if (expr < 0) /* test for underflow */
if ((int32)expr < 0) /* test for underflow */
goto DUNFLO; /* go process underflow */
if (expr > 0x7f) /* test for overflow */
if ((int32)expr > 0x7f) /* test for overflow */
goto DOVFLO; /* go process overflow */
expr ^= FMASK; /* complement exponent */
temp2 += 0x40; /* round at bit 25 */
@ -858,7 +860,7 @@ RRND2:
if ((int32)expr < 0) { /* test for underflow */
goto DUNFLO; /* go process underflow */
}
if (expr > 0x7f) { /* test for overflow */
if ((int32)expr > 0x7f) { /* test for overflow */
goto DOVFLO; /* go process overflow */
}
if (sign & MSIGN) /* test for negative */

View File

@ -352,9 +352,9 @@ hsdp_type[] =
uint8 hsdp_preio(UNIT *uptr, uint16 chan) ;
uint8 hsdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ;
uint8 hsdp_haltio(uint16 addr);
uint8 hsdp_haltio(UNIT *uptr);
t_stat hsdp_srv(UNIT *);
t_stat hsdp_boot(int32, DEVICE *);
t_stat hsdp_boot(int32 unitnum, DEVICE *);
void hsdp_ini(UNIT *, t_bool);
t_stat hsdp_reset(DEVICE *);
t_stat hsdp_attach(UNIT *, CONST char *);
@ -409,6 +409,7 @@ DEVICE dpa_dev = {
"DPA", dpa_unit, NULL, hsdp_mod,
NUM_UNITS_HSDP, 16, 24, 4, 16, 32,
NULL, NULL, &hsdp_reset, &hsdp_boot, &hsdp_attach, &hsdp_detach,
/* ctxt is the DIB pointer */
&dpa_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug,
NULL, NULL, &hsdp_help, NULL, NULL, &hsdp_description
};
@ -451,6 +452,7 @@ DEVICE dpb_dev = {
"DPB", dpb_unit, NULL, hsdp_mod,
NUM_UNITS_HSDP, 16, 24, 4, 16, 32,
NULL, NULL, &hsdp_reset, &hsdp_boot, &hsdp_attach, &hsdp_detach,
/* ctxt is the DIB pointer */
&dpb_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug,
NULL, NULL, &hsdp_help, NULL, NULL, &hsdp_description
};
@ -723,6 +725,7 @@ t_stat hsdp_srv(UNIT *uptr)
/* we have write error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
goto goout;
break;
}
if ((i%16) == 0)
@ -730,8 +733,8 @@ t_stat hsdp_srv(UNIT *uptr)
sim_debug(DEBUG_DETAIL, dptr, " %02x", buf[i]);
}
sim_debug(DEBUG_DETAIL, dptr, "\n");
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
goout:
break;
case DSK_WTL: /* WTL 0x51 make into NOP */
@ -747,6 +750,7 @@ t_stat hsdp_srv(UNIT *uptr)
/* we have read error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
goto goout;
break;
}
if (i == 16)
@ -857,17 +861,20 @@ t_stat hsdp_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);
sim_activate(uptr, 20);
return SCPE_OK;
//XXX sim_activate(uptr, 20);
break;
} else {
/* we have wasted enough time, we there */
#ifndef DO_SEEK_AGAIN
#ifdef DO_SEEK_AGAIN
/* calculate file position in bytes of requested sector */
/* file offseet in bytes */
tstart = STAR2SEC(uptr->STAR, SPT(type), SPC(type)) * SSB(type);
/* just reseek to the location where we will r/w data */
if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* do seek */
sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv Error on seek to %04x\n", tstart);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
}
#endif
uptr->CHS = uptr->STAR; /* we are there */
@ -903,12 +910,13 @@ t_stat hsdp_srv(UNIT *uptr)
break;
}
/* just read the next byte */
}
}
/* done reading, see how many we read */
if (i == 1) {
/* UTX wants to set seek STAR to zero */
buf[0] = buf[1] = buf[2] = buf[3] = 0;
break;
}
}
}
/* else the cyl, trk, and sect are ready to update */
sim_debug(DEBUG_CMD, dptr,
@ -958,6 +966,8 @@ rezero:
/* just seek to the location where we will r/w data */
if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* seek home */
sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv Error on seek to %08x\n", tstart);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
}
/* Check if already on correct cylinder */
@ -1471,6 +1481,9 @@ void hsdp_ini(UNIT *uptr, t_bool f)
DEVICE *dptr = get_dev(uptr);
int i = GET_TYPE(uptr->flags);
/* start out at sector 0 */
uptr->CHS = 0; /* set CHS to cyl/hd/sec = 0 */
uptr->STAR = 0; /* set STAR to cyl/hd/sec = 0 */
uptr->CMD &= ~0x7fff; /* clear out the flags but leave ch/sa */
uptr->SNS = ((uptr->SNS & 0x00ffffff) | (hsdp_type[i].type << 24)); /* save mode value */
/* total sectors on disk */
@ -1600,6 +1613,7 @@ int hsdp_format(UNIT *uptr) {
/* seek to sector 0 */
if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */
fprintf (stderr, "Error on seek to 0\r\n");
return 1;
}
/* get buffer for track data in bytes */
@ -1652,10 +1666,14 @@ int hsdp_format(UNIT *uptr) {
/* setup dmap pointed to by track label 0 wd[3] = (cyl-4) * spt + (spt - 1) */
/* write dmap data to last sector on disk */
sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET); /* seek last sector */
if ((sim_fseek(uptr->fileref, laddr*ssize, SEEK_SET)) != 0) { /* seek last sector */
sim_debug(DEBUG_CMD, dptr,
"Error on last sector seek to diskfile sect %06x\n", (cap-1) * ssize);
return 1;
}
if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) {
sim_debug(DEBUG_CMD, dptr,
"Error on vendor map write to diskfile sect %06x\n", (cap-1) * ssize);
"Error on last sectdor write to diskfile sect %06x\n", (cap-1) * ssize);
}
/* 1 cylinder is saved for disk manufacture */
@ -1665,7 +1683,11 @@ int hsdp_format(UNIT *uptr) {
/* vaddr is (cap) - 3 cyl - 1 track */
/* seek to vendor label area */
sim_fseek(uptr->fileref, (vaddr)*ssize, SEEK_SET); /* seek UMAP */
if ((sim_fseek(uptr->fileref, vaddr*ssize, SEEK_SET)) != 0) { /* seek VMAP */
sim_debug(DEBUG_CMD, dptr,
"Error on vendor map seek to diskfile sect %06x\n", (cap-1) * ssize);
return 1;
}
if ((sim_fwrite((char *)&vmap, sizeof(uint32), 2, uptr->fileref)) != 2) {
sim_debug(DEBUG_CMD, dptr,
"Error on vendor map write to diskfile sect %06x\n", vaddr * ssize);
@ -1675,16 +1697,26 @@ int hsdp_format(UNIT *uptr) {
/* daddr is (cap) - 3 cyl - 2 tracks */
/* vaddr is daddr - spt */
sim_fseek(uptr->fileref, (daddr)*ssize, SEEK_SET); /* seek DMAP */
if ((sim_fseek(uptr->fileref, daddr*ssize, SEEK_SET)) != 0) { /* seek DMAP */
sim_debug(DEBUG_CMD, dptr,
"Error on dmap seek to diskfile sect %06x\n", (cap-1) * ssize);
return 1;
}
if ((sim_fwrite((char *)&dmap, sizeof(uint32), 4, uptr->fileref)) != 4) {
sim_debug(DEBUG_CMD, dptr,
"Error on dmap write to diskfile sect %06x\n", daddr * ssize);
return 1;
}
sim_fseek(uptr->fileref, (uaddr)*ssize, SEEK_SET); /* seek UMAP */
if ((sim_fseek(uptr->fileref, uaddr*ssize, SEEK_SET)) != 0) { /* seek UMAP */
sim_debug(DEBUG_CMD, dptr,
"Error on umap seek to diskfile sect %06x\n", (cap-1) * ssize);
return 1;
}
if ((sim_fwrite((char *)&umap, sizeof(uint32), 256, uptr->fileref)) != 256) {
sim_debug(DEBUG_CMD, dptr,
"Error on umap write to diskfile sect %06x\n", uaddr * ssize);
return 1;
}
printf("writing to vmap sec %x (%d) bytes %x (%d)\n",
@ -1696,7 +1728,11 @@ int hsdp_format(UNIT *uptr) {
daddr, daddr, daddr*ssize, daddr*ssize);
/* seek home again */
sim_fseek(uptr->fileref, 0, SEEK_SET); /* seek home */
if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */
fprintf (stderr, "Error on seek to 0\r\n");
return 1;
}
free(buff); /* free cylinder buffer */
free(buff); /* free cylinder buffer */
return 0;
}

View File

@ -190,6 +190,7 @@ 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,
/* ctxt is the DIB pointer */
&lpr_dib, DEV_UADDR | DEV_DISABLE | DEV_DEBUG, 0, dev_debug
};

275
SEL32/sel32_mfp.c Normal file
View File

@ -0,0 +1,275 @@
/* sel32_mfp.c: SEL-32 Model 8000/8001/8002 MFP processor controller
Copyright (c) 2018-2020, James C. Bevier
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
JAMES C. BEVIER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This channel is the interrupt fielder for all of the MFP sub channels. It's
channel address is 7600. This code handles the INCH command for the MFP
devices and controls the status FIFO for the mfp devices on interrupts and
TIO instructions..
Possible devices:
The f8iop communication controller (TY76A0), (TY76B0), (TY76C0)
The ctiop console communications controller (CT76FC & CT76FD)
The lpiop line printer controller (LP76F8), (LP76F9)
The scsi SCSI disk controller (DM7600), (DM7640)
*/
#include "sel32_defs.h"
#ifdef NUM_DEVS_MFP
extern t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
extern t_stat show_dev_addr(FILE *st, UNIT * uptr, int32 v, CONST void *desc);
extern void chan_end(uint16 chan, uint8 flags);
extern int chan_read_byte(uint16 chan, uint8 *data);
extern int chan_write_byte(uint16 chan, uint8 *data);
extern void set_devattn(uint16 addr, uint8 flags);
extern void post_extirq(void);
extern uint32 attention_trap; /* set when trap is requested */
extern void set_devwake(uint16 addr, uint8 flags);
extern t_stat set_inch(UNIT *uptr, uint32 inch_addr); /* set channel inch address */
extern CHANP *find_chanp_ptr(uint16 chsa); /* find chanp pointer */
/* forward definitions */
uint8 mfp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd);
void mfp_ini(UNIT *uptr, t_bool f);
t_stat mfp_srv(UNIT *uptr);
t_stat mfp_reset(DEVICE *dptr);
t_stat mfp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
const char *mfp_desc(DEVICE *dptr);
/* Held in u3 is the device command and status */
#define MFP_INCH 0x00 /* Initialize channel command */
#define MFP_INCH2 0xf0 /* Initialize channel command after start */
#define MFP_NOP 0x03 /* NOP command */
#define MFP_MSK 0xff /* Command mask */
/* Status held in u3 */
/* controller/unit address in upper 16 bits */
#define CON_INPUT 0x100 /* Input ready for unit */
#define CON_CR 0x200 /* Output at beginning of line */
#define CON_REQ 0x400 /* Request key pressed */
#define CON_EKO 0x800 /* Echo input character */
#define CON_OUTPUT 0x1000 /* Output ready for unit */
#define CON_READ 0x2000 /* Read mode selected */
/* not used u4 */
/* in u5 packs sense byte 0,1 and 3 */
/* Sense byte 0 */
#define SNS_CMDREJ 0x80000000 /* Command reject */
#define SNS_INTVENT 0x40000000 /* Unit intervention required */
/* sense byte 3 */
#define SNS_RDY 0x80 /* device ready */
#define SNS_ONLN 0x40 /* device online */
/* std devices. data structures
mfp_dev Console device descriptor
mfp_unit Console unit descriptor
mfp_reg Console register list
mfp_mod Console modifiers list
*/
struct _mfp_data
{
uint8 ibuff[145]; /* Input line buffer */
uint8 incnt; /* char count */
}
mfp_data[NUM_UNITS_MFP];
/* channel program information */
CHANP mfp_chp[NUM_UNITS_MFP] = {0};
MTAB mfp_mod[] = {
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV",
&set_dev_addr, &show_dev_addr, NULL, "Device address"},
{0}
};
UNIT mfp_unit[] = {
{UDATA(&mfp_srv, UNIT_IDLE, 0), 0, UNIT_ADDR(0x7600)}, /* Channel controller */
};
//DIB mfp_dib = {NULL, mfp_startcmd, NULL, NULL, NULL, mfp_ini, mfp_unit, mfp_chp, NUM_UNITS_MFP, 0xff, 0x7e00,0,0,0};
DIB mfp_dib = {
NULL, /* uint8 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */
mfp_startcmd, /* uint8 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start a command SIO */
NULL, /* uint8 (*halt_io)(UNIT *uptr) */ /* Stop I/O HIO */
NULL, /* uint8 (*test_io)(UNIT *uptr) */ /* Test I/O TIO */
NULL, /* uint8 (*post_io)(UNIT *uptr) */ /* Post I/O */
mfp_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */
mfp_unit, /* UNIT* units */ /* Pointer to units structure */
mfp_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */
NUM_UNITS_MFP, /* uint8 numunits */ /* number of units defined */
0xff, /* uint8 mask */ /* 16 devices - device mask */
0x7e00, /* uint16 chan_addr */ /* parent channel address */
0, /* uint32 chan_fifo_in */ /* fifo input index */
0, /* uint32 chan_fifo_out */ /* fifo output index */
{0} /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */
};
DEVICE mfp_dev = {
"MFP", mfp_unit, NULL, mfp_mod,
NUM_UNITS_MFP, 8, 15, 1, 8, 8,
NULL, NULL, &mfp_reset, /* examine, deposit, reset */
NULL, NULL, NULL, /* boot, attach, detach */
&mfp_dib, DEV_UADDR|DEV_DISABLE|DEV_DEBUG, 0, dev_debug, /* dib, dev flags, debug flags, debug */
// NULL, NULL, &mfp_help, /* ?, ?, help */
// NULL, NULL, &mfp_desc /* ?, ?, description */
};
/* MFP controller routines */
/* initialize the console chan/unit */
void mfp_ini(UNIT *uptr, t_bool f)
{
int unit = (uptr - mfp_unit); /* unit 0 */
DEVICE *dptr = &mfp_dev; /* one and only dummy device */
sim_debug(DEBUG_CMD, &mfp_dev,
"MFP init device %s controller/device %04x\n",
dptr->name, GET_UADDR(uptr->u3));
mfp_data[unit].incnt = 0; /* no input data */
uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */
}
/* start an I/O operation */
uint8 mfp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
{
sim_debug(DEBUG_CMD, &mfp_dev,
"MFP startcmd %02x controller/device %04x\n",
cmd, GET_UADDR(uptr->u3));
if ((uptr->u3 & MFP_MSK) != 0) /* is unit busy */
return SNS_BSY; /* yes, return busy */
/* process the commands */
switch (cmd & 0xFF) {
/* UTX uses the INCH cmd to detect the MFP or MFP */
/* MFP has INCH cmd of 0, while MFP uses 0x80 */
case MFP_INCH: /* INCH command */
uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */
uptr->u3 &= LMASK; /* leave only chsa */
sim_debug(DEBUG_CMD, &mfp_dev,
"mfp_startcmd %04x: Cmd INCH iptr %06x INCHa %06x\n",
chan, mfp_chp[0].ccw_addr, /* set inch buffer addr */
mfp_chp[0].chan_inch_addr); /* set inch buffer addr */
mfp_chp[0].chan_inch_addr = mfp_chp[0].ccw_addr; /* set inch buffer addr */
// set_inch(uptr, mfp_chp[0].ccw_addr); /* new address */
uptr->u3 |= MFP_INCH2; /* save INCH command as 0xf0 */
sim_activate(uptr, 20); /* go on */
return 0; /* no status change */
break;
case MFP_NOP: /* NOP command */
sim_debug(DEBUG_CMD, &mfp_dev, "mfp_startcmd %04x: Cmd NOP\n", chan);
uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */
uptr->u3 &= LMASK; /* leave only chsa */
uptr->u3 |= (cmd & MFP_MSK); /* save NOP command */
sim_activate(uptr, 20); /* TRY 07-13-19 */
return 0; /* no status change */
break;
default: /* invalid command */
uptr->u5 |= SNS_CMDREJ; /* command rejected */
sim_debug(DEBUG_CMD, &mfp_dev, "mfp_startcmd %04x: Cmd Invalid %02x status %02x\n",
chan, cmd, uptr->u5);
uptr->u3 &= LMASK; /* leave only chsa */
uptr->u3 |= (cmd & MFP_MSK); /* save command */
sim_activate(uptr, 20); /* force interrupt */
return 0; /* no status change */
break;
}
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* not reachable for now */
}
/* Handle transfers for other sub-channels on MFP */
t_stat mfp_srv(UNIT *uptr)
{
uint16 chsa = GET_UADDR(uptr->u3);
int cmd = uptr->u3 & MFP_MSK;
// CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
CHANP *chp = &mfp_chp[0]; /* find the chanp pointer */
// int i;
// int len = chp->ccw_count; /* INCH command count */
uint32 mema = chp->ccw_addr; /* get inch or buffer addr */
/* test for NOP or INCH cmds */
if ((cmd != MFP_NOP) && (cmd != MFP_INCH2)) { /* NOP or INCH */
uptr->u3 &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, &mfp_dev,
"mfp_srv Unknown cmd %02x chan %02x: chnend|devend|unitexp\n", cmd, chsa);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* done */
return SCPE_OK;
} else
if (cmd == MFP_NOP) { /* NOP do nothing */
uptr->u3 &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, &mfp_dev, "mfp_srv INCH/NOP chan %02x: chnend|devend\n", chsa);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
return SCPE_OK;
} else
/* test for INCH cmd */
if (cmd == MFP_INCH2) { /* INCH */
sim_debug(DEBUG_CMD, &mfp_dev,
"mfp_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
mema, chsa, chp->ccw_addr, chp->ccw_count);
/* the chp->ccw_addr location contains the inch address */
/* call set_inch() to setup inch buffer */
// i = set_inch(uptr, mema); /* new address */
set_inch(uptr, mema); /* new address */
// chp->chan_inch_addr = mema; /* set inch buffer addr */
uptr->u3 &= LMASK; /* clear the cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
// chan_end(chsa, SNS_CHNEND); /* we are done dev|chan end */
}
return SCPE_OK;
}
t_stat mfp_reset(DEVICE *dptr)
{
/* add reset code here */
return SCPE_OK;
}
/* sho help mfp */
t_stat mfp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr)
{
fprintf(st, "SEL-32 MFP Model 8002 Channel Controller at 0x7600\r\n");
fprintf(st, "The MFP fields all interrupts and status posting\r\n");
fprintf(st, "for each of the controllers on the system.\r\n");
fprintf(st, "Nothing can be configured for this Channel.\r\n");
// fprint_set_help(st, dptr);
// fprint_show_help(st, dptr);
return SCPE_OK;
}
const char *mfp_desc(DEVICE *dptr)
{
return("SEL-32 MFP Model 8002 Channel Controller @ 0x7600");
}
#endif

View File

@ -161,14 +161,13 @@ extern uint32 SPAD[]; /* cpu SPAD */
#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF
uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ;
t_stat mt_srv(UNIT *);
t_stat mt_boot(int32, DEVICE *);
void mt_ini(UNIT *, t_bool);
t_stat mt_reset(DEVICE *);
t_stat mt_attach(UNIT *, CONST char *);
t_stat mt_detach(UNIT *);
t_stat mt_boot(int32, DEVICE *);
t_stat mt_help(FILE *, DEVICE *, UNIT *, int32, const char *);
t_stat mt_srv(UNIT *uptr);
t_stat mt_boot(int32 unitnum, DEVICE *dptr);
void mt_ini(UNIT *uptr, t_bool);
t_stat mt_reset(DEVICE *dptr);
t_stat mt_attach(UNIT *uptr, CONST char *);
t_stat mt_detach(UNIT *uptr);
t_stat mt_help(FILE *, DEVICE *dptr, UNIT *uptr, int32, const char *);
const char *mt_description(DEVICE *);
/* One buffer per channel */
@ -313,7 +312,7 @@ DIB mta_dib = {
mta_unit, /* Pointer to units structure */
mta_chp, /* Pointer to chan_prg structure */
NUM_UNITS_MT, /* number of units defined */
0xFF, /* 256 devices - device mask */
0x07, /* 8 devices - device mask */
0x1000, /* parent channel address */
0, /* fifo input index */
0, /* fifo output index */
@ -356,8 +355,8 @@ DIB mtb_dib = {
mtb_unit, /* Pointer to units structure */
mtb_chp, /* Pointer to chan_prg structure */
NUM_UNITS_MT, /* number of units defined */
0xFF, /* 256 devices - device mask */
0x1000, /* parent channel address */
0x07, /* 6 devices - device mask */
0x1800, /* parent channel address */
0, /* fifo input index */
0, /* fifo output index */
0, /* interrupt status fifo for channel */
@ -387,15 +386,15 @@ uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
return SNS_BSY;
}
sim_debug(DEBUG_EXP, &mta_dev, "mt_startcmd processing unit %04x cmd %02x\n", unit, cmd);
sim_debug(DEBUG_EXP, &mta_dev, "mt_startcmd processing unit %01x cmd %02x\n", unit, cmd);
switch (cmd & 0xFF) {
case 0x00: /* INCH command */
sim_debug(DEBUG_CMD, dptr, "start INCH command\n");
sim_debug(DEBUG_CMD, dptr,
"mt_startcmd starting INCH %06x cmd, chsa %04x MemBuf %08x cnt %04x\n",
uptr->u4, chsa, chp->ccw_addr, chp->ccw_count);
"mt_startcmd starting INCH cmd, chsa %04x MemBuf %08x cnt %04x\n",
chsa, chp->ccw_addr, chp->ccw_count);
/* UTX_needs_interrupt */
cmd = MT_CMDMSK; /* insert INCH cmd as 0xff */
@ -431,17 +430,21 @@ uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
case 0x4: /* Sense */
#ifndef FIX_DIAG
case 0x80: /* Unknown diag cmd with byte cnt of 0x0c */
#ifdef DO_DYNAMIC_DEBUG
if ((cmd & 0xff) == 0x80) {
/* start debugging */
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ);
}
#endif
#endif
uptr->CMD &= ~(MT_CMDMSK); /* clear out last cmd */
uptr->CMD |= cmd & MT_CMDMSK; /* insert new cmd */
CLR_BUF(uptr); /* buffer is empty */
/* INCH cmd has INCH buffer address in POS, so leave it */
if (cmd != MT_CMDMSK)
uptr->POS = 0; /* reset buffer position pointer */
sim_activate(uptr, 100); /* Start unit off */
mt_busy[GET_DEV_BUF(dptr->flags)] = 1; /* show we are busy */
sim_debug(DEBUG_EXP, &mta_dev, "mt_startcmd sense %08x return 0 chan %04x cmd %02x\n",
uptr->SNS, chan, cmd);
sim_activate(uptr, 100); /* Start unit off */
return 0;
default: /* invalid command */
@ -465,6 +468,7 @@ t_stat mt_error(UNIT *uptr, uint16 addr, t_stat r, DEVICE *dptr)
switch (r) { /* switch on return value */
case MTSE_OK: /* no error */
/*NEW*/ chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
break;
case MTSE_TMK: /* tape mark */
@ -476,6 +480,7 @@ t_stat mt_error(UNIT *uptr, uint16 addr, t_stat r, DEVICE *dptr)
case MTSE_WRP: /* write protected */
uptr->SNS |= SNS_WRP; /* write protected */
sim_debug(DEBUG_CMD, &mta_dev, "WRITE PROTECT %08x\n", r); /* operator intervention */
/*NEW*/ chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
break;
case MTSE_UNATT: /* unattached */
@ -488,11 +493,13 @@ t_stat mt_error(UNIT *uptr, uint16 addr, t_stat r, DEVICE *dptr)
case MTSE_FMT: /* invalid format */
case MTSE_RECE: /* error in record */
sim_debug(DEBUG_CMD, &mta_dev, "ERROR %08x\n", r);
/*NEW*/ chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
break;
case MTSE_BOT: /* beginning of tape */
uptr->SNS |= SNS_LOAD; /* tape at BOT */
sim_debug(DEBUG_CMD, &mta_dev, "BOT\n");
/*NEW*/ chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
break;
case MTSE_INVRL: /* invalid rec lnt */
@ -502,7 +509,7 @@ t_stat mt_error(UNIT *uptr, uint16 addr, t_stat r, DEVICE *dptr)
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
break;
}
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
//WAS chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
return SCPE_OK;
}
@ -521,7 +528,6 @@ t_stat mt_srv(UNIT *uptr)
uint32 mema;
uint16 len;
uint8 ch;
uint8 zc = 0;
uint8 buf[1024];
sim_debug(DEBUG_DETAIL, &mta_dev, "mt_srv unit %04x cmd %02x\n", unit, cmd);
@ -541,6 +547,12 @@ t_stat mt_srv(UNIT *uptr)
sim_debug(DEBUG_CMD, dptr,
"mt_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
mema, addr, chp->ccw_addr, chp->ccw_count);
#ifdef DO_DYNAMIC_DEBUG
if (mema == 0x149d8) {
/* start debugging */
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ);
}
#endif
if (len == 0) {
/* we have invalid count, error, bail out */
@ -559,12 +571,24 @@ t_stat mt_srv(UNIT *uptr)
}
/* just dump data */
}
/* uptr->POS has INCH buffer address, just leave it */
/* a BTP uses a 41 word INCH memory buffer */
// for (i=0; i<41; i++) {
for (i=0; i<9; i++) {
int32 data = RMW(mema+(4*i)); /* get data word */
sim_debug(DEBUG_CMD, dptr,
"mt_srv INCH buffer addr %06x, wd %02x data %08x\n",
mema+(4*i), 4*i, data);
/* zero the data */
if (i == 8)
WMW(mema+(4*i),0x00050005); /* show we are a BTP */
else
WMW(mema+(4*i),0); /* zero work location */
}
/* the chp->ccw_addr location contains the inch address */
/* call set_inch() to setup inch buffer */
i = set_inch(uptr, mema); /* new address */
#ifdef NOTYET
#ifndef NOTYET
if ((i == SCPE_MEM) || (i == SCPE_ARG)) { /* any error */
/* we have error, bail out */
uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */
@ -573,6 +597,11 @@ t_stat mt_srv(UNIT *uptr)
break;
}
#endif
/* 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*2),5); /* write left HW with count */
WMH(mema+(17*2),5); /* write right HW with count */
sim_debug(DEBUG_CMD, dptr,
"mt_srv cmd INCH chsa %04x addr %06x count %04x completed\n",
addr, mema, chp->ccw_count);
@ -596,15 +625,44 @@ t_stat mt_srv(UNIT *uptr)
ch = (uptr->SNS >> 0) & 0xff; /* get sense byte 3 status */
sim_debug(DEBUG_CMD, &mta_dev, "sense unit %02x byte 3 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 3 */
#ifdef TRYTHIS
/* write zero extra status */
for (ch=4; ch < 0xc; ch++) {
// chan_write_byte(addr, &ch); /* write byte */
uint8 zc = 0;
chan_write_byte(addr, &zc); /* write zero byte */
}
#else
/* write status 2 more times */
ch = (uptr->SNS >> 24) & 0xff; /* get sense byte 0 status */
sim_debug(DEBUG_CMD, &mta_dev, "sense unit %02x byte 0 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 0 */
ch = (uptr->SNS >> 16) & 0xff; /* get sense byte 1 status */
sim_debug(DEBUG_CMD, &mta_dev, "sense unit %02x byte 1 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 1 */
ch = (uptr->SNS >> 8) & 0xff; /* get sense byte 2 status */
sim_debug(DEBUG_CMD, &mta_dev, "sense unit %02x byte 2 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 2 */
ch = (uptr->SNS >> 0) & 0xff; /* get sense byte 3 status */
sim_debug(DEBUG_CMD, &mta_dev, "sense unit %02x byte 3 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 3 */
ch = (uptr->SNS >> 24) & 0xff; /* get sense byte 0 status */
sim_debug(DEBUG_CMD, &mta_dev, "sense unit %02x byte 0 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 0 */
ch = (uptr->SNS >> 16) & 0xff; /* get sense byte 1 status */
sim_debug(DEBUG_CMD, &mta_dev, "sense unit %02x byte 1 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 1 */
ch = (uptr->SNS >> 8) & 0xff; /* get sense byte 2 status */
sim_debug(DEBUG_CMD, &mta_dev, "sense unit %02x byte 2 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 2 */
ch = (uptr->SNS >> 0) & 0xff; /* get sense byte 3 status */
sim_debug(DEBUG_CMD, &mta_dev, "sense unit %02x byte 3 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 3 */
#endif
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
sim_debug(DEBUG_CMD, &mta_dev, "mt_srv DIAG SNS %08x char complete unit=%02x\n",
uptr->SNS, unit);
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
break;
#endif
@ -631,9 +689,9 @@ t_stat mt_srv(UNIT *uptr)
ch = 4;
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
sim_debug(DEBUG_CMD, &mta_dev, "mt_srv SENSE %08x char complete unit=%02x\n",
uptr->SNS, unit);
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
break;
case MT_READ: /* 0x02 */ /* read a record from the device */
@ -646,10 +704,10 @@ t_stat mt_srv(UNIT *uptr)
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 */
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* set chan end, dev end status */
sim_debug(DEBUG_CMD, &mta_dev,
"mt_srv READ %04x char complete unit=%02x sense %08x\n",
uptr->POS, unit, uptr->SNS);
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* set chan end, dev end status */
break;
}
/* read is not completed, get an input char */
@ -657,7 +715,7 @@ t_stat mt_srv(UNIT *uptr)
if (BUF_EMPTY(uptr)) {
/* buffer is empty, so fill it with next record data */
if ((r = sim_tape_rdrecf(uptr, &mt_buffer[bufnum][0], &reclen, BUFFSIZE)) != MTSE_OK) {
sim_debug(DEBUG_DETAIL, &mta_dev, "mt_srv READ fill buffer unit=%02x\n", unit);
sim_debug(DEBUG_CMD, &mta_dev, "mt_srv READ fill buffer unit=%02x\n", unit);
uptr->CMD &= ~(MT_CMDMSK|MT_READDONE); /* clear all but readdone & cmd */
return mt_error(uptr, addr, r, dptr); /* process any error & return status */
}
@ -954,8 +1012,8 @@ t_stat mt_srv(UNIT *uptr)
case 3:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND|SNS_UNITEXP); //NEW chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
sim_debug(DEBUG_CMD, &mta_dev, "Skip record at EOF\n");
chan_end(addr, SNS_DEVEND|SNS_UNITEXP); //NEW chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
break;
case 4:
uptr->CMD &= ~(MT_CMDMSK);
@ -1128,8 +1186,8 @@ t_stat mt_boot(int32 unit_num, DEVICE *dptr)
sim_debug(DEBUG_EXP, &mta_dev, "MT Boot dev/unit %04x\n", GET_UADDR(uptr->CMD));
if ((uptr->flags & UNIT_ATT) == 0) { /* Is MT device already attached? */
sim_debug(DEBUG_EXP, &mta_dev, "MT Boot attach error dev/unit %04x\n",
GET_UADDR(uptr->CMD));
sim_debug(DEBUG_EXP, &mta_dev,
"MT Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD));
return SCPE_UNATT; /* not attached, return error */
}
SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */

View File

@ -246,9 +246,9 @@ scfi_type[] =
uint8 scfi_preio(UNIT *uptr, uint16 chan);
uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd);
uint8 scfi_haltio(uint16 addr);
uint8 scfi_haltio(UNIT *uptr);
t_stat scfi_srv(UNIT *);
t_stat scfi_boot(int32, DEVICE *);
t_stat scfi_boot(int32 unitnum, DEVICE *);
void scfi_ini(UNIT *, t_bool);
t_stat scfi_reset(DEVICE *);
t_stat scfi_attach(UNIT *, CONST char *);
@ -304,6 +304,7 @@ DEVICE sda_dev = {
"SDA", sda_unit, NULL, scfi_mod,
NUM_UNITS_SCFI, 16, 24, 4, 16, 32,
NULL, NULL, &scfi_reset, &scfi_boot, &scfi_attach, &scfi_detach,
/* ctxt is the DIB pointer */
&sda_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug,
NULL, NULL, &scfi_help, NULL, NULL, &scfi_description
};
@ -347,6 +348,7 @@ DEVICE sdb_dev = {
"SDB", sdb_unit, NULL, scfi_mod,
NUM_UNITS_SCFI, 16, 24, 4, 16, 32,
NULL, NULL, &scfi_reset, &scfi_boot, &scfi_attach, &scfi_detach,
/* ctxt is the DIB pointer */
&sdb_dib, DEV_DISABLE|DEV_DEBUG|DEV_DIS, 0, dev_debug,
NULL, NULL, &scfi_help, NULL, NULL, &scfi_description
};
@ -682,6 +684,8 @@ rezero:
/* just seek to the location where we will r/w data */
if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* seek home */
sim_debug(DEBUG_DETAIL, dptr, "scfi_srv Error on seek to %08x\n", tstart);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
}
/* Check if already on correct cylinder */
@ -963,6 +967,7 @@ int scfi_format(UNIT *uptr) {
/* seek to sector 0 */
if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */
fprintf (stderr, "Error on seek to 0\r\n");
return 1;
}
/* get buffer for track data */
@ -996,7 +1001,10 @@ int scfi_format(UNIT *uptr) {
fputc('\r', stderr);
fputc('\n', stderr);
/* seek home again */
sim_fseek(uptr->fileref, 0, SEEK_SET); /* seek home */
if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */
fprintf (stderr, "Error on seek to 0\r\n");
return 1;
}
free(buff); /* free cylinder buffer */
set_devattn(addr, SNS_DEVEND); /* start us up */
return 0;

1160
SEL32/sel32_scsi.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -62,6 +62,9 @@ DEVICE *sim_devices[] = {
#ifdef NUM_DEVS_IOP
&iop_dev, /* IOP channel controller */
#endif
#ifdef NUM_DEVS_MFP
&mfp_dev, /* MFP channel controller */
#endif
#ifdef NUM_DEVS_RTOM
&rtc_dev,
&itm_dev,
@ -532,7 +535,9 @@ t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
case FMT_ICL: /* icl file image */
return load_icl(fileref);
#ifdef NO_TAP_FOR_NOW
case FMT_NONE: /* nothing */
#endif
default:
break;
}

View File

@ -159,25 +159,21 @@ int main (int argc, char *argv[])
/* get lines until eof */
while ((ll=getloi(buf, buf_size)) != EOF)
{
if (ll == 0)
{
if (ll == 0) {
/* eof found, process new file */
skipfile = 0;
file_byte_count = 0;
fileaddr = 0;
printf("\nfile %d:\n", filen);
}
else
{
} else {
int cc = 0;
buffptr = 0;
char buff[257];
int ans;
{
/* dump first 2 words */
int w1, w2, i, j;
char path[64], command[128];
{
/* dump first 2 words */
w1 = (buf[0] & 0xff) << 24 | buf[1] << 16 | buf[2] << 8 | (buf[3] & 0xff);
w2 = (buf[4] & 0xff) << 24 | buf[5] << 16 | buf[6] << 8 | (buf[7] & 0xff);
if (filen > 480)

View File

@ -1982,7 +1982,7 @@ SEL32 = ${SEL32D}/sel32_cpu.c ${SEL32D}/sel32_sys.c ${SEL32D}/sel32_chan.c \
${SEL32D}/sel32_iop.c ${SEL32D}/sel32_com.c ${SEL32D}/sel32_con.c \
${SEL32D}/sel32_clk.c ${SEL32D}/sel32_mt.c ${SEL32D}/sel32_lpr.c \
${SEL32D}/sel32_scfi.c ${SEL32D}/sel32_fltpt.c ${SEL32D}/sel32_disk.c \
${SEL32D}/sel32_hsdp.c
${SEL32D}/sel32_hsdp.c ${SEL32D}/sel32_mfp.c ${SEL32D}/sel32_scsi.c
SEL32_OPT = -I $(SEL32D) -DSEL32
#SEL32_OPT = -I $(SEL32D) -DUSE_INT64 -DSEL32