mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-22 10:31:12 +00:00
SEL32: Add support for ethernet and disk processor diagnostics.
SEL32: Update error status information for ethernet and disks. SEL32: Update channel program processing. SEL32: Some minor code cleanup.
This commit is contained in:
parent
fa88b294d4
commit
fb4ba5f856
@ -89,19 +89,17 @@ int DoNextCycles = 0;
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
extern uint32 CPUSTATUS; /* CPU status word */
|
||||
extern uint32 INTS[]; /* Interrupt status flags */
|
||||
extern uint32 TPSD[]; /*Temp save of PSD from memory 0&4 */
|
||||
#ifndef TRY_UTX_DELAY
|
||||
extern uint8 waitqcnt; /* # of instructions to xeq b4 int */
|
||||
#endif
|
||||
#ifdef NOT_NOW
|
||||
extern uint8 waitrdyq; /* # of instructions to xeq b4 rdy */
|
||||
#endif
|
||||
extern uint32 CPUSTATUS; /* CPU status word */
|
||||
extern uint32 INTS[]; /* Interrupt status flags */
|
||||
extern uint32 TPSD[]; /*Temp save of PSD from memory 0&4 */
|
||||
extern uint8 waitqcnt; /* # of instructions to xeq b4 int */
|
||||
extern uint8 waitrdyq; /* # of instructions to xeq b4 rdy */
|
||||
extern uint32 inbusy;
|
||||
extern uint32 outbusy;
|
||||
|
||||
DIB *dib_unit[MAX_DEV]; /* Pointer to Device info block */
|
||||
DIB *dib_chan[MAX_CHAN]; /* pointer to channel mux dib */
|
||||
uint16 loading; /* set when booting */
|
||||
DIB *dib_unit[MAX_DEV]; /* Pointer to Device info block */
|
||||
DIB *dib_chan[MAX_CHAN]; /* pointer to channel mux dib */
|
||||
uint16 loading; /* set when booting */
|
||||
|
||||
#define get_chan(chsa) ((chsa>>8)&0x7f) /* get channel number from ch/sa */
|
||||
|
||||
@ -217,11 +215,9 @@ int32 RDYQ_Put(uint32 entry)
|
||||
RDYQIN += 1; /* next entry */
|
||||
RDYQIN %= RDYQ_SIZE; /* modulo RDYQ size */
|
||||
irq_pend = 1; /* do a scan */
|
||||
#ifdef NOT_NOW
|
||||
//25waitrdyq = 5;
|
||||
// waitrdyq = 5;
|
||||
//25waitrdyq = 2;
|
||||
waitrdyq = 1;
|
||||
#endif
|
||||
waitrdyq = 1; /* wait at least 1 instruction */
|
||||
return 0; /* all OK */
|
||||
}
|
||||
|
||||
@ -497,7 +493,7 @@ int32 load_ccw(CHANP *chp, int32 tic_ok)
|
||||
uint16 devstat = 0;
|
||||
|
||||
loop:
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"load_ccw @%06x entry chan_status[%04x] %04x\n", chp->chan_caw, chan, chp->chan_status);
|
||||
/* Abort if we have any errors */
|
||||
if (chp->chan_status & STATUS_ERROR) { /* check channel error status */
|
||||
@ -545,20 +541,19 @@ loop:
|
||||
#endif
|
||||
|
||||
/* TIC can't follow TIC or be first in command chain */
|
||||
//25if (((word1 >> 24) & 0xf) == CMD_TIC) {
|
||||
/* diags send bad commands for testing. Use all of op */
|
||||
if (((word1 >> 24) & 0xff) == CMD_TIC) {
|
||||
if (tic_ok) {
|
||||
/*25*/ if (((word1 & MASK24) == 0) || (word1 & 0x3)) {
|
||||
// if (((word1 & MASK24) == 0) || (word1 & 0x3) || ((word1 & MASK24) == (chp->chan_caw-8))) {
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"load_ccw tic cmd bad address chan %02x tic caw %06x IOCD wd 1 %08x\n",
|
||||
chan, chp->chan_caw, word1);
|
||||
chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */
|
||||
chp->ccw_count = word2 & 0xffff; /* get 16 bit byte count from IOCD WD 2*/
|
||||
return 1; /* error return */
|
||||
}
|
||||
chp->chan_caw = word1 & MASK24; /* get new IOCD address */
|
||||
tic_ok = 0; /* another tic not allowed */
|
||||
chp->chan_caw = word1 & MASK24; /* get new IOCD address */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"load_ccw tic cmd ccw chan %02x tic caw %06x IOCD wd 1 %08x\n",
|
||||
chan, chp->chan_caw, word1);
|
||||
@ -570,6 +565,19 @@ loop:
|
||||
return 1; /* error return */
|
||||
}
|
||||
|
||||
/* validate parts of IOCD that is reserved */
|
||||
if (word2 & 0x07ff0000) {
|
||||
chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"load_ccw bad IOCD2 chan_status[%04x] %04x\n", chan, chp->chan_status);
|
||||
return 1; /* error return */
|
||||
}
|
||||
if (!MEM_ADDR_OK(word1 & MASK24)) { /* see if memory address invalid */
|
||||
chp->chan_status |= STATUS_PCHK; /* bad, program check */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"load_ccw bad IOCD1 chan_status[%04x] %04x\n", chan, chp->chan_status);
|
||||
return 1; /* error return */
|
||||
}
|
||||
/* Check if not chaining data */
|
||||
if ((chp->ccw_flags & FLAG_DC) == 0) {
|
||||
chp->ccw_cmd = (word1 >> 24) & 0xff; /* not DC, so set command from IOCD wd 1 */
|
||||
@ -584,11 +592,11 @@ loop:
|
||||
/* Set up for this command */
|
||||
/* make a 24 bit address */
|
||||
chp->ccw_addr = word1 & MASK24; /* set the data/seek address */
|
||||
chp->chan_caw += 8; /* point to to next IOCD */
|
||||
chp->chan_caw = (chp->chan_caw & 0xfffffc) + 8; /* point to next IOCD */
|
||||
chp->ccw_count = word2 & 0xffff; /* get 16 bit byte count from IOCD WD 2*/
|
||||
chp->chan_byte = BUFF_BUSY; /* busy & no bytes transferred yet */
|
||||
//sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw BUFF_BUSY chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
chp->ccw_flags = (word2 >> 16) & 0xffff; /* get flags from bits 0-7 of WD 2 of IOCD */
|
||||
chp->ccw_flags = (word2 >> 16) & 0xfc00; /* get flags from bits 0-7 of WD 2 of IOCD */
|
||||
if (chp->ccw_flags & FLAG_PCI) { /* do we have prog controlled int? */
|
||||
chp->chan_status |= STATUS_PCI; /* set PCI flag in status */
|
||||
irq_pend = 1; /* interrupt pending */
|
||||
@ -615,28 +623,34 @@ loop:
|
||||
/* just replace device status bits */
|
||||
devstat = dibp->start_cmd(uptr, chan, chp->ccw_cmd);
|
||||
chp->chan_status = (chp->chan_status & 0xff00) | devstat;
|
||||
chp->chan_info &= ~INFO_SIOCD; /* show not first IOCD in channel prog */
|
||||
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"load_ccw @%06x after start_cmd chan %04x status %08x count %04x\n",
|
||||
chp->chan_caw, chan, chp->chan_status, chp->ccw_count);
|
||||
|
||||
/* see if bad status */
|
||||
// if (chp->chan_status & (STATUS_ATTN|STATUS_CHECK|STATUS_EXPT)) {
|
||||
if (chp->chan_status & (STATUS_ATTN|STATUS_ERROR)) {
|
||||
chp->chan_status |= STATUS_CEND; /* channel end status */
|
||||
chp->ccw_flags = 0; /* no flags */
|
||||
// chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */
|
||||
// chp->ccw_cmd = 0; /* stop IOCD processing */
|
||||
//25 chp->ccw_count = 0; /* make count zero */
|
||||
chp->chan_byte = BUFF_NEXT; /* have main pick us up */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"load_ccw bad status chan %04x status %04x cmd %02x\n",
|
||||
chan, chp->chan_status, chp->ccw_cmd);
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw BUFF_NEXT chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
RDYQ_Put(chp->chan_dev); /* queue us up */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"load_ccw continue wait chsa %04x status %08x\n",
|
||||
chp->chan_dev, chp->chan_status);
|
||||
/* see if chan_end already called */
|
||||
if (chp->chan_byte == BUFF_NEXT) {
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"load_ccw BUFF_NEXT ERROR chp %p chan_byte %04x\n",
|
||||
chp, chp->chan_byte);
|
||||
} else {
|
||||
chp->chan_byte = BUFF_NEXT; /* have main pick us up */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"load_ccw bad status chan %04x status %04x cmd %02x\n",
|
||||
chan, chp->chan_status, chp->ccw_cmd);
|
||||
RDYQ_Put(chp->chan_dev); /* queue us up */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"load_ccw continue wait chsa %04x status %08x\n",
|
||||
chp->chan_dev, chp->chan_status);
|
||||
}
|
||||
/*0816*/ } else
|
||||
|
||||
/* NOTE this code needed for MPX 1.X to run! */
|
||||
@ -850,11 +864,11 @@ void chan_end(uint16 chsa, uint16 flags) {
|
||||
chsa, flags, chp->chan_status, chp->ccw_cmd);
|
||||
|
||||
chp->chan_byte = BUFF_BUSY; /* we are empty & still busy now */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "chan_end1 BUFF_BUSY chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
//sim_debug(DEBUG_EXP, &cpu_dev, "chan_end1 BUFF_BUSY chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
chp->chan_status |= STATUS_CEND; /* set channel end */
|
||||
chp->chan_status |= ((uint16)flags); /* add in the callers flags */
|
||||
|
||||
sim_debug(DEBUG_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);
|
||||
|
||||
@ -894,7 +908,7 @@ sim_debug(DEBUG_EXP, &cpu_dev, "chan_end1 BUFF_BUSY chp %p chan_byte %04x\n", ch
|
||||
/* test for device or controller end */
|
||||
if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) {
|
||||
chp->chan_byte = BUFF_BUSY; /* we are empty & still busy now */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "chan_end2 BUFF_BUSY chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
//sim_debug(DEBUG_EXP, &cpu_dev, "chan_end2 BUFF_BUSY chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
while ((chp->ccw_flags & FLAG_DC)) { /* handle data chaining */
|
||||
if (load_ccw(chp, 1)) /* continue channel program */
|
||||
break; /* error */
|
||||
@ -904,7 +918,7 @@ sim_debug(DEBUG_EXP, &cpu_dev, "chan_end2 BUFF_BUSY chp %p chan_byte %04x\n", ch
|
||||
}
|
||||
}
|
||||
chp->chan_byte = BUFF_BUSY; /* we are empty & still busy now */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "chan_end3 BUFF_BUSY chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
//sim_debug(DEBUG_EXP, &cpu_dev, "chan_end3 BUFF_BUSY chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"chan_end FIFO #%1x IOCL done chsa %04x ccw_flags %04x status %04x\n",
|
||||
FIFO_Num(chsa), chsa, chp->ccw_flags, chp->chan_status);
|
||||
@ -936,8 +950,8 @@ sim_debug(DEBUG_EXP, &cpu_dev, "chan_end3 BUFF_BUSY chp %p chan_byte %04x\n", ch
|
||||
chsa, chp->chan_status, chp->chan_caw);
|
||||
/* Queue us to continue from cpu level */
|
||||
chp->chan_byte = BUFF_NEXT; /* have main pick us up */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"chan_end4 BUFF_NEXT chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
// sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
// "chan_end4 BUFF_NEXT chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
RDYQ_Put(chsa); /* queue us up */
|
||||
}
|
||||
/* just return */
|
||||
@ -952,29 +966,29 @@ sim_debug(DEBUG_EXP, &cpu_dev, "chan_end3 BUFF_BUSY chp %p chan_byte %04x\n", ch
|
||||
/* handle case where we are loading the O/S on boot */
|
||||
/* if loading, store status to be discovered by scan_chan */
|
||||
if (!loading) {
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
"chan_end call store_csw dev/chan end chsa %04x cpustat %08x iocla %08x\n",
|
||||
chsa, CPUSTATUS, chp->chan_caw);
|
||||
} else {
|
||||
/* we are loading, so keep moving */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
"chan_end we are loading O/S with DE & CE, keep status chsa %04x status %08x\n",
|
||||
chsa, chp->chan_status);
|
||||
}
|
||||
/* store the status in channel FIFO to continue from cpu level */
|
||||
chp->chan_byte = BUFF_DONE; /* we are done */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "chan_end1 BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
//sim_debug(DEBUG_EXP, &cpu_dev, "chan_end1 BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
store_csw(chp); /* store the status */
|
||||
/* change chan_byte to BUFF_POST */
|
||||
chp->chan_byte = BUFF_POST; /* show done with data */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "chan_end2 BUFF_POST chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
//sim_debug(DEBUG_EXP, &cpu_dev, "chan_end2 BUFF_POST chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
chp->chan_status = 0; /* no status anymore */
|
||||
chp->ccw_cmd = 0; /* no command anymore */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"chan_end after store_csw call chsa %04x status %08x chan_byte %02x\n",
|
||||
chsa, chp->chan_status, chp->chan_byte);
|
||||
}
|
||||
}
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"chan_end done chsa %04x chp %p status %08x chan_byte %02x\n",
|
||||
chsa, chp, chp->chan_status, chp->chan_byte);
|
||||
/* following statement required for boot to work */
|
||||
irq_pend = 1; /* flag to test for int condition */
|
||||
}
|
||||
@ -1002,8 +1016,8 @@ int16 post_csw(CHANP *chp, uint32 rstat)
|
||||
}
|
||||
if (chp->chan_byte != BUFF_POST) {
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"post_csw %04x CHP not BUFF_POST status, ERROR FIFO #%1x inch %06x chan_icb %06x\n",
|
||||
chsa, FIFO_Num(chsa), incha, chan_icb);
|
||||
"post_csw %04x CHP %p not BUFF_POST status, ERROR FIFO #%1x inch %06x chan_icb %06x\n",
|
||||
chsa, chp, FIFO_Num(chsa), incha, chan_icb);
|
||||
}
|
||||
/* remove user specified bits */
|
||||
sw2 &= ~rstat; /* remove bits */
|
||||
@ -1015,11 +1029,6 @@ int16 post_csw(CHANP *chp, uint32 rstat)
|
||||
//sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
//"post_csw BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
/* save the status double word to memory */
|
||||
#ifdef DO_DYNAMIC_DEBUG
|
||||
/* start debugging */
|
||||
if (sw2 == 0x200c0234)
|
||||
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_TRAP | DEBUG_EXP | DEBUG_IRQ);
|
||||
#endif
|
||||
WMW(incha, sw1); /* save sa & IOCD address in status WD 1 loc */
|
||||
WMW(incha+4, sw2); /* save status and residual cnt in status WD 2 loc */
|
||||
/* now store the status dw address into word 5 of the ICB for the channel */
|
||||
@ -1031,8 +1040,8 @@ int16 post_csw(CHANP *chp, uint32 rstat)
|
||||
}
|
||||
// 717 added
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"post_csw %04x READ FIFO #%1x inch %06x No Status chan_byte %02x\n",
|
||||
chsa, FIFO_Num(chsa), incha, chp->chan_byte);
|
||||
"post_csw %04x chp %p READ FIFO #%1x inch %06x No Status chan_byte %02x\n",
|
||||
chsa, chp, FIFO_Num(chsa), incha, chp->chan_byte);
|
||||
return 0; /* no status to post */
|
||||
}
|
||||
|
||||
@ -1100,7 +1109,7 @@ t_stat checkxio(uint16 chsa, uint32 *status) {
|
||||
uint32 inta;
|
||||
DEVICE *dptr; /* DEVICE pointer */
|
||||
|
||||
// sim_debug(DEBUG_XIO, &cpu_dev, "checkxio entry chsa %04x\n", chsa);
|
||||
sim_debug(DEBUG_XIO, &cpu_dev, "checkxio entry chsa %04x\n", chsa);
|
||||
|
||||
dibp = dib_chan[chan]; /* get DIB pointer for channel */
|
||||
if (dibp == 0) goto nothere;
|
||||
@ -1152,15 +1161,19 @@ nothere:
|
||||
chsa, incha, RMW(incha), RMW(incha+4));
|
||||
#endif
|
||||
|
||||
#ifdef NOT_FOR_CHANNEL
|
||||
/* check for a Command or data chain operation in progresss */
|
||||
//715 if (chp->chan_byte & BUFF_BUSY) {
|
||||
if ((chp->chan_byte & BUFF_BUSY) && chp->chan_byte != BUFF_POST) {
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"checkxio busy return CC3&CC4 chsa %04x chan %04x cmd %02x flags %04x byte %02x\n",
|
||||
chsa, chan, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte);
|
||||
"checkxio busy return CC3&CC4 chsa %04x chp %p cmd %02x flags %04x byte %02x\n",
|
||||
chsa, chp, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte);
|
||||
//TODO return busy status for EC device
|
||||
//use same code as PPCI, but be busy
|
||||
*status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */
|
||||
return SCPE_OK; /* just busy CC3&CC4 */
|
||||
}
|
||||
#endif
|
||||
|
||||
dptr = get_dev(uptr); /* pointer to DEVICE structure */
|
||||
/* try this as MFP says it returns 0 on OK */
|
||||
@ -1199,21 +1212,26 @@ t_stat startxio(uint16 chsa, uint32 *status) {
|
||||
"startxio debug chsa %04x iocla %06x incha %06x IOCD1 %08x IOCD2 %08x\n",
|
||||
chsa, iocla, incha, RMW(iocla), RMW(iocla+4));
|
||||
#endif
|
||||
dibp = dib_unit[chsa]; /* get the DIB pointer */
|
||||
chp = find_chanp_ptr(chsa); /* find the chanp pointer */
|
||||
/* check if we have a valid unit */
|
||||
dibp = dib_chan[chan]; /* get DIB pointer for channel */
|
||||
if (dibp == 0) goto missing;
|
||||
|
||||
if (dibp == 0 || chp == 0) { /* if no dib or channel ptr, CC3 return */
|
||||
chp = find_chanp_ptr(chsa); /* find the chanp pointer */
|
||||
if (chp == 0) goto missing;
|
||||
|
||||
uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */
|
||||
|
||||
if (uptr == 0) { /* if no dib or unit ptr, CC3 on return */
|
||||
missing:
|
||||
*status = CC3BIT; /* not found, so CC3 */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"startxio chsa %04x device not present, CC3 returned\n", chsa);
|
||||
"startxio chsa %04x is not found, CC3 returned\n", chsa);
|
||||
return SCPE_OK; /* not found, CC3 */
|
||||
}
|
||||
|
||||
uptr = chp->unitptr; /* get the unit ptr */
|
||||
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"startxio chsa %04x flags UNIT_ATTABLE %1x UNIT_ATT %1x UNIT_DIS %1x\n",
|
||||
chsa, (uptr->flags & UNIT_ATTABLE)?1:0, (uptr->flags & UNIT_ATT)?1:0,
|
||||
"startxio chsa %04x chp %p flags UNIT_ATTABLE %1x UNIT_ATT %1x UNIT_DIS %1x\n",
|
||||
chsa, chp, (uptr->flags & UNIT_ATTABLE)?1:0, (uptr->flags & UNIT_ATT)?1:0,
|
||||
(uptr->flags & UNIT_DIS)?1:0);
|
||||
|
||||
if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0) &&
|
||||
@ -1236,14 +1254,28 @@ t_stat startxio(uint16 chsa, uint32 *status) {
|
||||
|
||||
#ifndef NOTHERE
|
||||
/* check for a Command or data chain operation in progresss */
|
||||
//25if (chp->chan_byte & BUFF_BUSY) {
|
||||
if ((chp->chan_byte & BUFF_BUSY) && chp->chan_byte != BUFF_POST) {
|
||||
uint16 tstat, tcnt;
|
||||
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"startxio busy return CC3&CC4 chsa %04x chan %04x cmd %02x flags %04x byte %02x\n",
|
||||
chsa, chan, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte);
|
||||
// sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
// "startxio busy return CC3&CC4 chsa %04x chan %04x\n", chsa, chan);
|
||||
"startxio busy return CC3&CC4 chsa %04x chp %p cmd %02x flags %04x byte %02x\n",
|
||||
chsa, chp, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte);
|
||||
#ifdef OLDWAY
|
||||
*status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */
|
||||
#else
|
||||
*status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */
|
||||
/* handle an Ethernet controller busy by sending interrupt/status */
|
||||
tstat = chp->chan_status; /* save status */
|
||||
tcnt = chp->ccw_count; /* save count */
|
||||
chp->chan_status = STATUS_BUSY|STATUS_CEND|STATUS_DEND; /* set busy status */
|
||||
chp->ccw_count = 0; /* zero count */
|
||||
store_csw(chp); /* store the status */
|
||||
chp->chan_status = tstat; /* restore status */
|
||||
chp->ccw_count = tcnt; /* restore count */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"startxio done BUSY chp %p chsa %04x ccw_flags %04x stat %04x cnt %04x\n",
|
||||
chp, chsa, chp->ccw_flags, tstat, tcnt);
|
||||
#endif
|
||||
#ifdef DO_DYNAMIC_DEBUG
|
||||
/* start debugging */
|
||||
if (chsa == 0x0c00)
|
||||
@ -1260,23 +1292,12 @@ t_stat startxio(uint16 chsa, uint32 *status) {
|
||||
|
||||
/* We have to validate all the addresses and parameters for the SIO */
|
||||
/* before calling load_ccw which does it again for each IOCL step */
|
||||
// inta = find_int_lev(chsa); /* Interrupt Level for channel */
|
||||
// chan_icb = find_int_icb(chsa); /* Interrupt level context block address */
|
||||
|
||||
iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */
|
||||
word1 = RMW(iocla & MASK24); /* get 1st IOCL word */
|
||||
incha = word1 & MASK24; /* should be inch addr */
|
||||
word2 = RMW((iocla + 4) & MASK24); /* get 2nd IOCL word */
|
||||
cmd = (word1 >> 24) & 0xff; /* get channel cmd from IOCL */
|
||||
chp = find_chanp_ptr(chsa&0x7f00); /* find the parent chanp pointer */
|
||||
if (cmd == 0) { /* INCH command? */
|
||||
if ((word2 & MASK16) == 36) /* see if disk with 224 wd buffer */
|
||||
incha = RMW(incha); /* 224 word buffer is inch addr */
|
||||
dibp = dib_chan[chan]; /* get the channel DIB pointer */
|
||||
chp = dibp->chan_prg; /* get first unit channel prog ptr */
|
||||
chp->chan_inch_addr = incha; /* set the inch addr for channel */
|
||||
}
|
||||
|
||||
incha = chp->chan_inch_addr; /* get inch address */
|
||||
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
@ -1284,12 +1305,6 @@ t_stat startxio(uint16 chsa, uint32 *status) {
|
||||
chsa, iocla, incha, RMW(iocla), RMW(iocla+4));
|
||||
|
||||
iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */
|
||||
// incha = chp->chan_inch_addr; /* get inch address */
|
||||
#ifdef LEAVE_IT_ALONE
|
||||
/* now store the inch status address into word 5 of the ICB for the channel */
|
||||
WMW(chan_icb+20, incha); /* post inch addr in ICB+5w */
|
||||
#endif
|
||||
|
||||
chp = find_chanp_ptr(chsa); /* find the chanp pointer */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"startxio test chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n",
|
||||
@ -1327,6 +1342,7 @@ t_stat startxio(uint16 chsa, uint32 *status) {
|
||||
/* We are queueing the SIO */
|
||||
/* Queue us to continue IOCL from cpu level & make busy */
|
||||
chp->chan_byte = BUFF_NEXT; /* have main pick us up */
|
||||
chp->chan_info = INFO_SIOCD; /* show first IOCD in channel prog */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"startxio BUFF_NEXT chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
RDYQ_Put(chsa); /* queue us up */
|
||||
@ -1386,10 +1402,8 @@ t_stat testxio(uint16 chsa, uint32 *status) { /* test XIO */
|
||||
/* check for a Command or data chain operation in progresss */
|
||||
if ((chp->chan_byte & BUFF_BUSY) && chp->chan_byte != BUFF_POST) {
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"startxio busy return CC3&CC4 chsa %04x chan %04x cmd %02x flags %04x byte %02x\n",
|
||||
chsa, chan, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte);
|
||||
// sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
// "testxio busy return CC3&CC4 chsa %04x chan %04x\n", chsa, chan);
|
||||
"testxio busy return CC3&CC4 chsa %04x chp %p cmd %02x flags %04x byte %02x\n",
|
||||
chsa, chp, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte);
|
||||
*status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */
|
||||
return SCPE_OK; /* just busy CC3&CC4 */
|
||||
}
|
||||
@ -1473,7 +1487,6 @@ t_stat stopxio(uint16 chsa, uint32 *status) { /* stop XIO */
|
||||
chsa, chp->ccw_cmd, chp->ccw_flags);
|
||||
|
||||
/* check for a Command or data chain operation in progresss */
|
||||
//25if (chp->chan_byte & BUFF_BUSY) {
|
||||
if ((chp->chan_byte & BUFF_BUSY) && chp->chan_byte != BUFF_POST) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "stopxio busy return CC1 chsa %04x chan %04x\n", chsa, chan);
|
||||
/* reset the DC or CC bits to force completion after current IOCD */
|
||||
@ -1599,7 +1612,7 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */
|
||||
/* the channel is not busy, so return OK */
|
||||
*status = CC1BIT; /* request accepted, no status, so CC1 */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"$$$ HIO END chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
"$$$ HIO END1 chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
chp->chan_byte = BUFF_DONE; /* we are done */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
@ -1630,37 +1643,39 @@ sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_POST chp %p chan_byte %04x\n", chp,
|
||||
/* chan_end is called in hio device service routine */
|
||||
/* the device is no longer busy, post status */
|
||||
/* remove PPCI status. Unit check should not be set */
|
||||
chp->ccw_count = 0; /* zero the count */
|
||||
#ifndef TRY_THIS
|
||||
if (post_csw(chp, ((STATUS_PCI) << 16))) {
|
||||
INTS[inta] &= ~INTS_REQ; /* clear any level request */
|
||||
*status = CC2BIT; /* status stored */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"$$$ HIO END chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
/* change status from BUFF_POST to BUFF_DONE */
|
||||
/*082420*/ if (chp->chan_byte == BUFF_POST) {
|
||||
/*082420*/ chp->chan_byte = BUFF_DONE; /* show done & not busy */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
if (tempa == 1) { /* see if console HIO */
|
||||
chp->ccw_count = 0; /* zero the count */
|
||||
/* post status for UTX */
|
||||
if (post_csw(chp, ((STATUS_PCI) << 16))) {
|
||||
INTS[inta] &= ~INTS_REQ; /* clear any level request */
|
||||
*status = CC2BIT; /* status stored */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"$$$ HIO END2 chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
/* change status from BUFF_POST to BUFF_DONE */
|
||||
/*082420*/ if (chp->chan_byte == BUFF_POST) {
|
||||
/*082420*/ chp->chan_byte = BUFF_DONE; /* show done & not busy */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE1 chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
}
|
||||
return SCPE_OK; /* CC2 & all OK */
|
||||
}
|
||||
return SCPE_OK; /* CC2 & all OK */
|
||||
} else {
|
||||
chp->ccw_count = 0; /* zero the count */
|
||||
/* The diags want the interrupt for the disk */
|
||||
*status = CC1BIT; /* request accepted, no status, so CC1 */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"$$$ HIO END2 ECHO chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
return SCPE_OK; /* CC1 & all OK */
|
||||
}
|
||||
#else
|
||||
*status = 0; /* status to be echoed */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"$$$ HIO END ECHO chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
return SCPE_OK; /* CC2 & all OK */
|
||||
#endif
|
||||
}
|
||||
/* the device is not busy, so cmd has not started */
|
||||
chp->chan_byte = BUFF_DONE; /* chan prog done */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"haltxioret BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
"haltxio BUFF_DONE2 chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
/* the channel is not busy, so return OK */
|
||||
*status = CC1BIT; /* request accepted, no status, so CC1 */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"$$$ HIO END chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
"$$$ HIO END3 chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
return SCPE_OK; /* No CC's all OK */
|
||||
}
|
||||
@ -1673,12 +1688,10 @@ sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE chp %p chan_byte %04x\n", chp,
|
||||
/* reset the DC or CC bits to force completion */
|
||||
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */
|
||||
chp->chan_byte = BUFF_BUSY; /* wait for post_csw to be done */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "haltxiocan BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
//082020chp->chan_status |= STATUS_ECHO; /* show we stopped the cmd */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE3 chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
// chp->ccw_count = 0; /* zero the count */
|
||||
sim_cancel(uptr); /* cancel timer service */
|
||||
chp->chan_status &= ~STATUS_BUSY; /* remove BUSY status bit */
|
||||
// chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* show I/O complete */
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */
|
||||
|
||||
/* post the channel status */
|
||||
@ -1688,23 +1701,22 @@ sim_debug(DEBUG_EXP, &cpu_dev, "haltxiocan BUFF_DONE chp %p chan_byte %04x\n", c
|
||||
INTS[inta] &= ~INTS_REQ; /* clear any level request */
|
||||
*status = CC2BIT; /* status stored from SIO, so CC2 */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"$$$ HIO END chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
"$$$ HIO END4 chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
/* change status from BUFF_POST to BUFF_DONE */
|
||||
/*082420*/ if (chp->chan_byte == BUFF_DONE) {
|
||||
/*082420*/ chp->chan_byte = BUFF_DONE; /* show done & not busy */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE4 chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
}
|
||||
return SCPE_OK; /* CC2 & all OK */
|
||||
}
|
||||
}
|
||||
//hiogret:
|
||||
chp->chan_byte = BUFF_DONE; /* chan prog done */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE5 chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
/* the channel is not busy, so return OK */
|
||||
*status = CC1BIT; /* request accepted, no status, so CC1 */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||
"$$$ HIO END chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
"$$$ HIO END5 chsa %04x chan %04x cmd %02x ccw_flags %04x status %04x\n",
|
||||
chsa, chan, chp->ccw_cmd, chp->ccw_flags, *status);
|
||||
return SCPE_OK; /* No CC's all OK */
|
||||
}
|
||||
@ -1729,7 +1741,7 @@ t_stat grabxio(uint16 lchsa, uint32 *status) { /* grab controller XIO n/u
|
||||
*status = CC4BIT; /* busy, so CC4 */
|
||||
return SCPE_OK; /* CC4 all OK */
|
||||
}
|
||||
*status = 0; /* not busy, no CC */
|
||||
*status = CC2BIT|CC4BIT; /* unsupported transaction */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "grabxio chsa %04x chan %04x\n", chsa, chan);
|
||||
return 0;
|
||||
}
|
||||
@ -1765,9 +1777,6 @@ t_stat rsctlxio(uint16 lchsa, uint32 *status) { /* reset controller XIO */
|
||||
/* reset the FIFO pointers */
|
||||
dibp->chan_fifo_in = 0;
|
||||
dibp->chan_fifo_out = 0;
|
||||
#ifdef NOT4CONTROLLER
|
||||
chp->chan_inch_addr = 0; /* remove inch status buffer address */
|
||||
#endif
|
||||
lev = find_int_lev(chan); /* get our int level */
|
||||
INTS[lev] &= ~INTS_ACT; /* clear level active */
|
||||
SPAD[lev+0x80] &= ~SINT_ACT; /* clear spad too */
|
||||
@ -1839,6 +1848,7 @@ sim_debug(DEBUG_EXP, &cpu_dev, "chan_boot BUFF_EMPTY chp %p chan_byte %04x\n", c
|
||||
chp->chan_caw = 0x0; /* set IOCD address to memory location 0 */
|
||||
chp->ccw_count = 0; /* channel byte count 0 bytes*/
|
||||
chp->ccw_flags = 0; /* Command chain and supress incorrect length */
|
||||
chp->chan_info = INFO_SIOCD; /* show first IOCD in channel prog */
|
||||
chp->ccw_cmd = 0; /* read command */
|
||||
loading = chsa; /* show we are loading from the boot device */
|
||||
|
||||
@ -1876,17 +1886,15 @@ uint32 cont_chan(uint16 chsa)
|
||||
"cont_chan chan_byte %02x is NOT BUFF_NEXT chsa %04x addr %06x\n",
|
||||
chp->chan_byte, chsa, chp->ccw_addr);
|
||||
return 1;
|
||||
//chp->chan_byte = BUFF_NEXT;
|
||||
//716 return 1;
|
||||
}
|
||||
if (chp->chan_byte == BUFF_NEXT) {
|
||||
uint32 chan = get_chan(chsa);
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"cont_chan resume chan prog chsa %04x iocl %06x\n",
|
||||
chsa, chp->chan_caw);
|
||||
|
||||
/* start a channel program */
|
||||
stat = load_ccw(chp, 1); /* resume the channel program */
|
||||
// if (stat || (chp->chan_status & STATUS_PCI)) {
|
||||
/* we get status returned if there is an error on the startio cmd call */
|
||||
if (stat) {
|
||||
/* we have an error or user requested interrupt, return status */
|
||||
@ -1920,6 +1928,9 @@ uint32 cont_chan(uint16 chsa)
|
||||
return SCPE_OK; /* done, status stored */
|
||||
}
|
||||
/* must be more IOCBs, wait for them */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev,
|
||||
"cont_chan continue not next chsa %04x status %08x iocla %06x\n",
|
||||
chsa, chp->chan_status, chp->chan_caw);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@ -1954,9 +1965,6 @@ uint32 scan_chan(uint32 *ilev) {
|
||||
if ((FIFO_Num(chan)) && ((FIFO_Get(chan, &sw1) == 0) &&
|
||||
(FIFO_Get(chan, &sw2) == 0))) {
|
||||
/* the SPAD entries are not set up, so no access to icb or ints */
|
||||
#if NOT_SETUP_YET
|
||||
uint32 chan_icb = find_int_icb(chan); /* get icb address */
|
||||
#endif
|
||||
/* get the status from the FIFO and throw it away */
|
||||
/* we really should post it to the current inch address */
|
||||
/* there is really no need to post, but it might be helpfull */
|
||||
@ -2009,8 +2017,10 @@ sim_debug(DEBUG_EXP, &cpu_dev, "scan_chan BUFF_DONE chp %p chan_byte %04x\n", ch
|
||||
/* this is a bug fix for MPX 1.x restart command */
|
||||
// if (SPAD[i+0x80] == 0xefffffff) /* not initialize? */
|
||||
// continue; /* skip this one */
|
||||
#ifdef CAN_BE_DISABLED_090720
|
||||
if ((INTS[i] & INTS_ENAB) == 0) /* ints must be enabled */
|
||||
continue; /* skip this one */
|
||||
#endif
|
||||
|
||||
if (INTS[i] & INTS_REQ) /* if already requesting, skip */
|
||||
continue; /* skip this one */
|
||||
@ -2108,13 +2118,15 @@ sim_debug(DEBUG_EXP, &cpu_dev, "scan_chan BUFF_DONE chp %p chan_byte %04x\n", ch
|
||||
chsa = chan | (tempa >> 24); /* find device address for requesting chan prog */
|
||||
chp = find_chanp_ptr(chsa); /* find the chanp pointer for channel */
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"scan_chan %04x LOOK FIFO #%1x irq %02x inch %06x chsa %04x chan_icba %06x chan_byte %02x\n",
|
||||
chan, FIFO_Num(chan), i, chp->chan_inch_addr, chsa, chan_icba, chp->chan_byte);
|
||||
"scan_chan %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n",
|
||||
chsa, FIFO_Num(chan), i, chp->chan_inch_addr, chp, chan_icba, chp->chan_byte);
|
||||
if (post_csw(chp, 0)) {
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"scan_chanx %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n",
|
||||
chan, FIFO_Num(chan), i, chp->chan_inch_addr, RMW(chan_icba+20), chp->chan_byte);
|
||||
/* change status from BUFF_POST to BUFF_DONE */
|
||||
/* change status from BUFF_POST to BUFF_DONE */
|
||||
/* if not BUFF_POST we have a PPCI or channel busy interrupt */
|
||||
/* so leave the channel status alone */
|
||||
/*082420*/ if (chp->chan_byte == BUFF_POST) {
|
||||
/*082420*/ chp->chan_byte = BUFF_DONE; /* show done & not busy */
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "scan_chanx BUFF_DONE chp %p chan_byte %04x\n", chp, chp->chan_byte);
|
||||
@ -2136,9 +2148,10 @@ tryme:
|
||||
//25irq_pend = 0; /* not pending anymore */
|
||||
#ifndef TEST_082520
|
||||
if (RDYQ_Num()) {
|
||||
#ifdef NOTNOW
|
||||
#ifndef NOTNOW
|
||||
if (waitrdyq > 0) {
|
||||
waitrdyq--;
|
||||
irq_pend = 1; /* still pending */
|
||||
} else
|
||||
#endif
|
||||
/* we have entries, continue channel program */
|
||||
@ -2148,7 +2161,7 @@ tryme:
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"scan_chan CPU RDYQ entry for chsa %04x starting\n", chsa);
|
||||
stat = cont_chan(chsa); /* resume the channel program */
|
||||
if (stat)
|
||||
if (stat == SCPE_OK) /* done, status stored */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"CPU RDYQ entry for chsa %04x processed\n", chsa);
|
||||
}
|
||||
|
||||
@ -119,8 +119,9 @@ t_stat rtc_srv (UNIT *uptr)
|
||||
#endif
|
||||
/* if clock disabled, do not do interrupts */
|
||||
if (((rtc_dev.flags & DEV_DIS) == 0) && rtc_pie) {
|
||||
time_t result = time(NULL);
|
||||
sim_debug(DEBUG_CMD, &rtc_dev, "RT Clock int time %08x\n", (uint32)result);
|
||||
sim_debug(DEBUG_CMD, &rtc_dev,
|
||||
"RT Clock int INTS[%02x] %08x SPAD[%02x] %08x\n",
|
||||
rtc_lvl, INTS[rtc_lvl], rtc_lvl+0x80, SPAD[rtc_lvl+0x80]);
|
||||
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 */
|
||||
@ -132,10 +133,13 @@ t_stat rtc_srv (UNIT *uptr)
|
||||
INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */
|
||||
irq_pend = 1; /* make sure we scan for int */
|
||||
}
|
||||
sim_debug(DEBUG_CMD, &rtc_dev,
|
||||
"RT Clock int INTS[%02x] %08x SPAD[%02x] %08x\n",
|
||||
rtc_lvl, INTS[rtc_lvl], rtc_lvl+0x80, SPAD[rtc_lvl+0x80]);
|
||||
}
|
||||
// temp = sim_rtcn_calb(rtc_tps, TMR_RTC); /* timer 0 for RTC */
|
||||
sim_rtcn_calb(rtc_tps, TMR_RTC); /* timer 0 for RTC */
|
||||
sim_activate_after(&rtc_unit, 1000000/rtc_tps); /* reactivate 16666 tics / sec */
|
||||
sim_activate_after(uptr, 1000000/rtc_tps); /* reactivate 16666 tics / sec */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -340,7 +340,7 @@ t_stat con_srvo(UNIT *uptr) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
//Comment out clock flag 072020
|
||||
//*RTC*/ outbusy = 1; /* tell clock output waiting */
|
||||
/*RTC*/ outbusy = 1; /* tell clock output waiting */
|
||||
/* Write to device */
|
||||
while (chan_read_byte(chsa, &ch) == SCPE_OK) { /* get byte from memory */
|
||||
/* HACK HACK HACK */
|
||||
@ -597,9 +597,9 @@ uint16 con_haltio(UNIT *uptr) {
|
||||
if ((uptr->CMD & CON_MSK) != 0) { /* is unit busy */
|
||||
sim_debug(DEBUG_CMD, &con_dev,
|
||||
"con_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count);
|
||||
// stop any I/O and post status and return error status */
|
||||
chp->chan_byte = BUFF_EMPTY; /* there is no data to read/store */
|
||||
// chp->ccw_count = 0; /* zero the count */
|
||||
/* stop any I/O and post status and return error status */
|
||||
// chp->chan_byte = BUFF_EMPTY; /* there is no data to read/store */
|
||||
/*0906*/chp->ccw_count = 0; /* zero the count */
|
||||
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */
|
||||
uptr->CMD &= LMASK; /* make non-busy */
|
||||
uptr->u4 = 0; /* no I/O yet */
|
||||
@ -607,9 +607,9 @@ uint16 con_haltio(UNIT *uptr) {
|
||||
uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */
|
||||
sim_debug(DEBUG_CMD, &con_dev,
|
||||
"con_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd);
|
||||
// chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* force error */
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */
|
||||
return SCPE_IOERR;
|
||||
// return SCPE_IOERR;
|
||||
return 1; /* tell chan code to post status */
|
||||
}
|
||||
uptr->u4 = 0; /* no I/O yet */
|
||||
con_data[unit].incnt = 0; /* no input data */
|
||||
|
||||
@ -221,12 +221,8 @@ uint32 attention_trap = 0; /* set when trap is requested */
|
||||
uint32 RDYQIN; /* fifo input index */
|
||||
uint32 RDYQOUT; /* fifo output index */
|
||||
uint32 RDYQ[128]; /* channel ready queue */
|
||||
#ifndef TRY_UTX_DELAY
|
||||
uint8 waitqcnt = 0; /* # instructions before start */
|
||||
#endif
|
||||
#ifdef NOT_NOW
|
||||
uint8 waitrdyq = 0; /* # instructions before start */
|
||||
#endif
|
||||
uint8 waitrdyq = 0; /* # instructions before post inturrupt */
|
||||
|
||||
struct InstHistory
|
||||
{
|
||||
@ -985,13 +981,6 @@ nomaps:
|
||||
} else {
|
||||
TLB[num] = 0; /* clear the TLB for non valid maps */
|
||||
}
|
||||
#ifdef FOR_DEBUG
|
||||
if ((num < 0x20) || (num > (spc - 0x10)))
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
"OS pad %06x=%04x map #%4x, %04x, map2 %08x, TLB %08x MAPC %08x\n",
|
||||
pad, map, num, map, (((map << 16) & 0xf8000000) | ((map & 0x7ff) << 13)),
|
||||
TLB[num], MAPC[num/2]);
|
||||
#endif
|
||||
}
|
||||
BPIX = num; /* save the # maps loaded in O/S */
|
||||
CPIXPL = 0; /* no user pages */
|
||||
@ -1138,15 +1127,6 @@ loaduser:
|
||||
} else
|
||||
TLB[num] = 0; /* clear the TLB for non valid maps */
|
||||
WMR((num<<1), map); /* store map unmodified into cache */
|
||||
|
||||
#ifdef FOR_DEBUG
|
||||
/* do partial map dump */
|
||||
if ((num < 0x20) || (num > (spc+BPIX) - 0x10))
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
"UserN pad %06x=%04x map #%4x, %04x, map2 %08x, TLB %08x, MAPC %08x\n",
|
||||
pad, map, num, map, (((map << 16) & 0xf8000000) | ((map & 0x7ff) << 13)),
|
||||
TLB[num], MAPC[num/2]);
|
||||
#endif
|
||||
}
|
||||
if (num == 0) { /* see if any maps loaded */
|
||||
sim_debug(DEBUG_TRAP, &cpu_dev,
|
||||
@ -2023,9 +2003,12 @@ wait_loop:
|
||||
if (stat)
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"CPU RDYQ entry for chsa %04x processed\n", chsa);
|
||||
if (stat == SCPE_OK) /* done, status stored */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"CPU RDYQ entry for chsa %04x processed\n", chsa);
|
||||
}
|
||||
}
|
||||
}
|
||||
goto wait_loop; /* continue waiting for boot */
|
||||
goto wait_loop; /* continue waiting for boot */
|
||||
}
|
||||
|
||||
/* we get here when not booting */
|
||||
@ -2123,9 +2106,10 @@ wait_loop:
|
||||
/*25*/ irq_pend = 0; /* not pending anymore */
|
||||
if (RDYQ_Num()) {
|
||||
uint32 chsa; /* channel/sub adddress */
|
||||
#ifdef NOTNOW
|
||||
#ifndef NOTNOW
|
||||
if (waitrdyq > 0) {
|
||||
waitrdyq--;
|
||||
irq_pend = 1; /* still pending */
|
||||
} else
|
||||
#endif
|
||||
/* we have entries, continue channel program */
|
||||
@ -2144,8 +2128,8 @@ wait_loop:
|
||||
/* see if in wait instruction */
|
||||
if (wait4int) { /* keep waiting */
|
||||
/* tell simh we will be waiting */
|
||||
// sim_idle(TMR_RTC, 1); /* wait for clock tick */
|
||||
sim_idle(0, 1); /* wait for clock tick */
|
||||
//0905 sim_idle(TMR_RTC, 1); /* wait for clock tick */
|
||||
sim_idle(TMR_RTC, 0); /* wait for clock tick */
|
||||
/*722*/ irq_pend = 1; /* start scanning interrupts again */
|
||||
goto wait_loop; /* continue waiting */
|
||||
}
|
||||
@ -2666,8 +2650,8 @@ exec:
|
||||
}
|
||||
wait4int = 1; /* show we are waiting for interrupt */
|
||||
/* tell simh we will be waiting */
|
||||
// sim_idle(TMR_RTC, 0); /* wait for next pending device event */
|
||||
sim_idle(0, 0); /* wait for clock tick */
|
||||
//0905 sim_idle(TMR_RTC, 1); /* wait for clock tick */
|
||||
sim_idle(TMR_RTC, 0); /* wait for next pending device event */
|
||||
/*719*/ irq_pend = 1; /* start scanning interrupts again */
|
||||
i_flags |= BT; /* keep PC from being incremented while waiting */
|
||||
break;
|
||||
@ -6008,6 +5992,7 @@ temp2, IR&0xFFF, PSD1, PSD2, CPUSTATUS);
|
||||
case 0x3: /* LPSD F980 */
|
||||
/* fall through */;
|
||||
case 0x5: /* LPSDCM FA80 */
|
||||
/*0904*/ irq_pend = 1; /* start scanning interrupts again */
|
||||
if ((modes & PRIVBIT) == 0) { /* must be privileged */
|
||||
TRAPME = PRIVVIOL_TRAP; /* set the trap to take */
|
||||
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
|
||||
@ -6139,8 +6124,14 @@ temp2, IR&0xFFF, PSD1, PSD2, CPUSTATUS);
|
||||
uint32 cpix = PSD2 & 0x3ff8; /* get cpix 11 bit offset from psd wd 2 */
|
||||
uint32 midl = RMW(mpl+cpix); /* get midl entry for given user cpix */
|
||||
int spc = midl & MASK16; /* get 16 bit user segment description count */
|
||||
if (spc != CPIXPL)
|
||||
if (spc != CPIXPL) {
|
||||
PSD2 &= ~RETMBIT; /* no, turn off retain bit in PSD2 */
|
||||
#ifndef NOTNOW
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"LPSD(CM) RESET RETAIN OPSD %08x %08x NPSD %08x %08x TRAPME %02x\n",
|
||||
TPSD[0], TPSD[1], PSD1, PSD2, TRAPME);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if ((PSD2 & RETMBIT) == 0) { /* don't load maps if retain bit set */
|
||||
@ -6175,6 +6166,11 @@ temp2, IR&0xFFF, PSD1, PSD2, CPUSTATUS);
|
||||
PSD2 |= (SPAD[0xf5] & 0x3fff); /* use new cpix */
|
||||
}
|
||||
}
|
||||
#ifdef NOTNOW
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"At LPSD(CM) OPSD %08x %08x NPSD %08x %08x TRAPME %02x\n",
|
||||
TPSD[0], TPSD[1], PSD1, PSD2, TRAPME);
|
||||
#endif
|
||||
/* TRAPME can be error from LPSDCM or OK here */
|
||||
if (TRAPME) { /* if we have an error, restore old PSD */
|
||||
sim_debug(DEBUG_TRAP, &cpu_dev,
|
||||
@ -6198,10 +6194,10 @@ temp2, IR&0xFFF, PSD1, PSD2, CPUSTATUS);
|
||||
goto newpsd; /* go process error */
|
||||
}
|
||||
drop_nop = 0; /* nothing to drop */
|
||||
#ifdef NOTNOW
|
||||
#ifndef NOTNOW
|
||||
sim_debug(DEBUG_IRQ, &cpu_dev,
|
||||
"LPSD(CM) Done PSD1 %08x PSD2 %08x CPUSTATUS %08x irq %1x BLK %1x\n",
|
||||
PSD1, PSD2, CPUSTATUS, irq_pend, CPUSTATUS&0x80?1:0);
|
||||
"LPSD(CM) END OPSD %08x %08x NPSD %08x %08x CPUSTAT %08x irq %1x BLK %1x\n",
|
||||
TPSD[0], TPSD[1], PSD1, PSD2, CPUSTATUS, irq_pend, CPUSTATUS&0x80?1:0);
|
||||
#endif
|
||||
goto newpsd; /* load the new psd, or process error */
|
||||
break;
|
||||
@ -6233,6 +6229,7 @@ temp2, IR&0xFFF, PSD1, PSD2, CPUSTATUS);
|
||||
/* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */
|
||||
/* */
|
||||
case 0xFC>>2: /* 0xFC IMM - IMM */ /* XIO, CD, TD, Interrupt Control */
|
||||
/*0904*/ irq_pend = 1; /* start scanning interrupts again */
|
||||
if ((modes & PRIVBIT) == 0) { /* must be privileged to do I/O */
|
||||
TRAPME = PRIVVIOL_TRAP; /* set the trap to take */
|
||||
if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9))
|
||||
@ -6512,7 +6509,7 @@ mcheck:
|
||||
}
|
||||
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"XIO rdy PSD1 %08x chan %02x irq %02x icb %06x iocla %06x iocd1 %08x iocd2 %08x\n",
|
||||
"XIO rdy PSD1 %08x chan %02x irq %02x icb %06x iocla %06x iocd %08x %08x\n",
|
||||
PSD1, chan, ix, addr, addr+16, RMW(temp), RMW(temp+4));
|
||||
/* at this point, the channel has a valid SPAD channel entry */
|
||||
/* t is SPAD entry contents for chan device */
|
||||
@ -6524,6 +6521,26 @@ mcheck:
|
||||
/* ix - positive interrupt level */
|
||||
/* addr - ICBA for specified interrupt level, points to 6 wd block */
|
||||
/* temp - First IOCD address */
|
||||
#ifdef DO_DYNAMIC_DEBUG
|
||||
/* start debugging */
|
||||
if (rchsa == 0x0801) {
|
||||
// GPR[5] &= ~1;
|
||||
// GPR[5] |= 2;
|
||||
// rchsa &= ~1;
|
||||
// rchsa |= 2;
|
||||
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_TRAP | DEBUG_EXP | DEBUG_IRQ);
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"\n\tR0=%.8x R1=%.8x R2=%.8x R3=%.8x", GPR[0], GPR[1], GPR[2], GPR[3]);
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
" R4=%.8x R5=%.8x R6=%.8x R7=%.8x\n", GPR[4], GPR[5], GPR[6], GPR[7]);
|
||||
if (modes & BASEBIT) {
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"\tB0=%.8x B1=%.8x B2=%.8x B3=%.8x", BR[0], BR[1], BR[2], BR[3]);
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
" B4=%.8x B5=%.8x B6=%.8x B7=%.8x\n", BR[4], BR[5], BR[6], BR[7]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
"XIO switch %02x lchan %02x irq %02x chsa %04x IOCDa %08x CPUSTATUS %08x BLK %1x\n",
|
||||
((opr>>3)&0x0f), lchan, ix, rchsa, temp, CPUSTATUS, CPUSTATUS&0x80?1:0);
|
||||
@ -6547,20 +6564,22 @@ mcheck:
|
||||
"XIO unsupported WCS chan %04x chsa %04x status %08x\n",
|
||||
chan, rchsa, rstatus);
|
||||
/* just give unsupported transaction */
|
||||
#ifdef JUST_RETURN_STATUS
|
||||
TRAPME = SYSTEMCHK_TRAP; /* trap condition if F class */
|
||||
TRAPSTATUS |= BIT0; /* class F error bit */
|
||||
TRAPSTATUS &= ~BIT1; /* I/O processing error */
|
||||
goto newpsd; /* undefined instruction trap */
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x02: /* Start I/O SIO */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
"XIO SIO b4 call PSD1 %08x chan %04x chsa %04x BLK %1x\n",
|
||||
PSD1, chan, rchsa, CPUSTATUS&0x80?1:0);
|
||||
if ((TRAPME = startxio(rchsa, &rstatus)))
|
||||
goto newpsd; /* error returned, trap cpu */
|
||||
PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */
|
||||
sim_debug(DEBUG_XIO, &cpu_dev,
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||
"XIO SIO ret PSD1 %08x chan %04x chsa %04x status %08x BLK %1x\n",
|
||||
PSD1, chan, rchsa, rstatus, CPUSTATUS&0x80?1:0);
|
||||
break;
|
||||
@ -7376,7 +7395,7 @@ t_stat cpu_show_hist(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||
struct InstHistory *h;
|
||||
|
||||
if (hst_lnt == 0) /* see if show history is enabled */
|
||||
return SCPE_NOFNC; /* no, so are out of here */
|
||||
return SCPE_NOFNC; /* no, so we are out of here */
|
||||
if (cptr) { /* see if user provided a display count */
|
||||
lnt = (int32)get_uint(cptr, 10, hst_lnt, &r); /* get the count */
|
||||
if ((r != SCPE_OK) || (lnt == 0)) /* if error or 0 count */
|
||||
|
||||
@ -86,6 +86,7 @@
|
||||
|
||||
/* Class F channel bits */
|
||||
/* bit 32 - 37 of IOCD word 2 (0-5) */
|
||||
/* ccw_flags bit assignment */
|
||||
#define FLAG_DC 0x8000 /* Data chain */
|
||||
#define FLAG_CC 0x4000 /* Chain command */
|
||||
#define FLAG_SLI 0x2000 /* Suppress length indicator */
|
||||
@ -93,6 +94,7 @@
|
||||
#define FLAG_PCI 0x0800 /* Program controlled interrupt */
|
||||
#define FLAG_RTO 0x0400 /* Real-Time Option */
|
||||
|
||||
/* chan_byte bit assignments */
|
||||
#define BUFF_EMPTY 0x0 /* Buffer is empty */
|
||||
#define BUFF_BUSY 0x4 /* Channel program busy & empty */
|
||||
#define BUFF_NEXT 0xC /* 0x08|0x04 Continue Channel with next IOCB */
|
||||
@ -100,6 +102,10 @@
|
||||
#define BUFF_DONE 0x20 /* 0x20 Channel ready for new command */
|
||||
#define BUFF_POST 0x24 /* 0x20|0x04 Waiting for status to be posted */
|
||||
|
||||
/* chan_info bit flags */
|
||||
#define INFO_SIOCD 0x01 /* Initial IOCD from SIO if set */
|
||||
/* bits 0-6 unused */
|
||||
|
||||
#define MAX_CHAN 128 /* max channels that can be defined */
|
||||
#define SUB_CHANS 256 /* max sub channels that can be defined */
|
||||
#define MAX_DEV (MAX_CHAN * SUB_CHANS) /* max possible */
|
||||
@ -118,8 +124,8 @@
|
||||
#define NUM_DEVS_HSDP 1 /* 1 hspd disk drive controller */
|
||||
#define NUM_UNITS_HSDP 2 /* 2 disk drive devices */
|
||||
#define NUM_DEVS_DISK 1 /* 1 dp02 disk drive controller */
|
||||
#define NUM_UNITS_DISK 2 /* 2 disk drive devices */
|
||||
//#define NUM_UNITS_DISK 4 /* 4 disk drive devices */
|
||||
//#define NUM_UNITS_DISK 2 /* 2 disk drive devices */
|
||||
#define NUM_UNITS_DISK 4 /* 4 disk drive devices */
|
||||
#define NUM_DEVS_SCFI 1 /* 1 scfi (SCSI) disk drive units */
|
||||
#define NUM_UNITS_SCFI 1 /* 1 of 4 disk drive devices */
|
||||
#define NUM_DEVS_SCSI 2 /* 2 scsi (MFP SCSI) scsi buss units */
|
||||
@ -196,9 +202,7 @@ extern DEVICE ec_dev;
|
||||
/* channel program data for a chan/sub-address */
|
||||
typedef struct chp {
|
||||
/* channel program values */
|
||||
#ifndef OLD_CHAN
|
||||
UNIT *unitptr; /* Back pointer to units structure */
|
||||
#endif
|
||||
uint32 chan_inch_addr; /* Channel status dw in memory */
|
||||
uint32 chan_caw; /* Channel command address word */
|
||||
uint32 ccw_addr; /* Channel address */
|
||||
@ -210,6 +214,7 @@ typedef struct chp {
|
||||
uint8 ccw_cmd; /* Channel command and flags */
|
||||
uint8 chan_byte; /* Current byte, empty/full */
|
||||
uint8 chan_int; /* channel interrupt level */
|
||||
uint8 chan_info; /* misc flags for channel */
|
||||
} CHANP;
|
||||
|
||||
/* Device information block */
|
||||
@ -320,6 +325,7 @@ extern DEBTAB dev_debug[];
|
||||
#define MODEL_V9 7 /* V9 CPU */
|
||||
|
||||
#define TMR_RTC 1
|
||||
//#define TMR_RTC 0
|
||||
|
||||
#define HIST_MIN 64
|
||||
#define HIST_MAX 10000
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
108
SEL32/sel32_ec.c
108
SEL32/sel32_ec.c
@ -207,6 +207,7 @@ struct ec_device {
|
||||
int poll; /* Need to poll receiver */
|
||||
} ec_data;
|
||||
|
||||
int8 conf[12] = {0}; /* user specified configuration */
|
||||
|
||||
extern int32 tmxr_poll;
|
||||
|
||||
@ -344,6 +345,7 @@ uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"ec_startcmd illegal at ec_startcmd %02x SNS %08x\n",
|
||||
cmd, uptr->SNS);
|
||||
chp->ccw_count = 0; /* diags want zero count */
|
||||
return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; /* diags want prog check */
|
||||
// return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* diags want unit check */
|
||||
default:
|
||||
@ -358,7 +360,7 @@ uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
|
||||
case EC_READ: /* Read command 0x02 */
|
||||
case EC_TIC: /* Transfer in channel */
|
||||
case EC_CGA: /* Disable multicast address */
|
||||
case EC_LCC: /* Configure LCC */
|
||||
case EC_LCC: /* Configure LCC 0x10 */
|
||||
case EC_STATS: /* Read Statistics */
|
||||
case EC_CSTATS: /* Clear software counters */
|
||||
case EC_NOP: /* NOP 0x03 */
|
||||
@ -369,34 +371,25 @@ uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
|
||||
uptr->SNS &= ~SNS_CMDREJ; /* remove CMD reject status */
|
||||
/* Fall through */
|
||||
case EC_SNS: /* Sense 0x04 */
|
||||
#ifdef FIGURE_THIS_OUT
|
||||
/* diags want 4 byte multiple, but if data chaining is set it can be odd */
|
||||
/* ethernet transfers must be multiple of 4 bytes */
|
||||
if ((cmd == EC_WRITE) || (cmd == EC_READ) ||
|
||||
(cmd == EC_STATS) || (cmd == EC_LCC)) {
|
||||
// (cmd == EC_STATS) || (cmd == EC_LCC) || (cmd == EC_SNS)) {
|
||||
if ((chp->ccw_count & 0x03) != 0)
|
||||
return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; /* diags want prog check */
|
||||
}
|
||||
#endif
|
||||
/* nop must have none zero count */
|
||||
/* nop must have non zero count */
|
||||
if (cmd == EC_NOP) {
|
||||
if (chp->ccw_count == 0)
|
||||
return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; /* diags want prog check */
|
||||
}
|
||||
uptr->CMD |= cmd|EC_BUSY; /* save cmd */
|
||||
sim_activate(uptr, 300); /* start things off */
|
||||
uptr->CMD |= cmd|EC_BUSY; /* save cmd */
|
||||
sim_activate(uptr, 300); /* start things off */
|
||||
return 0;
|
||||
}
|
||||
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
sim_debug(DEBUG_CMD, dptr, "ec_startcmd illegal cmd %02x SNS %08x\n",
|
||||
cmd, uptr->SNS);
|
||||
chp->ccw_count = 0; /* diags want zero count */
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* diags want unit check */
|
||||
// return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; /* diags want prog check */
|
||||
}
|
||||
|
||||
/* Handle processing of disk requests. */
|
||||
/* Handle processing of ethernet requests. */
|
||||
t_stat ec_srv(UNIT *uptr)
|
||||
{
|
||||
uint16 chsa = GET_UADDR(uptr->CMD);
|
||||
@ -412,16 +405,16 @@ t_stat ec_srv(UNIT *uptr)
|
||||
struct ec_eth_hdr *hdr;
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"ec_srv cmd=%02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count);
|
||||
"ec_srv chp %p cmd=%02x chsa %04x count %04x\n", chp, cmd, chsa, chp->ccw_count);
|
||||
|
||||
switch (cmd) {
|
||||
// case EC_INCH: /* INCH cmd 0x0 */
|
||||
case EC_INCH2: /* INCH cmd 0xF0 */
|
||||
len = chp->ccw_count; /* INCH command count */
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"ec_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
|
||||
uptr->u4, chsa, chp->ccw_addr, chp->ccw_count);
|
||||
mema = chp->ccw_addr; /* get inch or buffer addr */
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"ec_srv starting INCH %06x cmd, chsa %04x addr %06x cnt %04x\n",
|
||||
chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
|
||||
uptr->CMD &= LMASK; /* remove old status bits & */
|
||||
|
||||
/* now call set_inch() function to write and test inch buffer addresses */
|
||||
@ -459,24 +452,28 @@ t_stat ec_srv(UNIT *uptr)
|
||||
memcpy(&ec_data.mac, &buf[0], sizeof (ETH_MAC));
|
||||
eth_mac_fmt(&ec_data.mac, (char *)&buf[0]);
|
||||
sim_debug(DEBUG_CMD, dptr, "ec_srv setting mac %s\n", buf);
|
||||
i = buf[0] & 1; /* set/reset promiscuous mode */
|
||||
n = ec_data.macs_n + 2;
|
||||
memcpy(&ec_data.macs[0], &ec_data.mac, sizeof (ETH_MAC));
|
||||
memcpy(&ec_data.macs[1], &broadcast_ethaddr, sizeof (ETH_MAC));
|
||||
if (ec_master_uptr->flags & UNIT_ATT)
|
||||
eth_filter (&ec_data.etherface, n, ec_data.macs, ec_data.amc, 0);
|
||||
//DIAGS eth_filter (&ec_data.etherface, n, ec_data.macs, ec_data.amc, 0);
|
||||
/* set promiscuous if bit 7 of byte zero of mac address is set */
|
||||
eth_filter (&ec_data.etherface, n, ec_data.macs, ec_data.amc, i);
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
|
||||
case EC_CGA: /* Disable multicast address */
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
case EC_CGA: /* Disable multicast address */
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
ec_data.macs_n = 0;
|
||||
ec_data.amc = 0;
|
||||
if (ec_master_uptr->flags & UNIT_ATT)
|
||||
eth_filter (&ec_data.etherface, 1, ec_data.macs, ec_data.amc, 0);
|
||||
eth_filter (&ec_data.etherface, 1, ec_data.macs, ec_data.amc, 0);
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
|
||||
case EC_LGA: /* Load Multicast address */
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
case EC_LGA: /* Load Multicast address */
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
ec_data.macs_n = 0;
|
||||
for(n = 2; n < (int)(sizeof(ec_data.macs_n) / sizeof (ETH_MAC)); n++) {
|
||||
for(i = 0; i < sizeof (ETH_MAC); i++) {
|
||||
@ -489,14 +486,17 @@ t_stat ec_srv(UNIT *uptr)
|
||||
memcpy(&ec_data.macs[n], &buf[0], sizeof (ETH_MAC));
|
||||
}
|
||||
ec_data.macs_n = n - 2;
|
||||
ec_data.amc = 1;
|
||||
|
||||
for(i = 0; i< n; i++) {
|
||||
for (i = 0; i< n; i++) {
|
||||
eth_mac_fmt(&ec_data.macs[i], (char *)&buf[0]);
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv load mcast%d: %s\n",i,buf);
|
||||
}
|
||||
|
||||
if (ec_master_uptr->flags & UNIT_ATT)
|
||||
eth_filter (&ec_data.etherface, n, ec_data.macs, ec_data.amc, 0);
|
||||
//DIAGS eth_filter (&ec_data.etherface, n, ec_data.macs, ec_data.amc, 0);
|
||||
/* multicast on means promiscous is too */
|
||||
eth_filter (&ec_data.etherface, n, ec_data.macs, ec_data.amc, ec_data.amc);
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
|
||||
@ -543,27 +543,43 @@ t_stat ec_srv(UNIT *uptr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* see if too many bytes */
|
||||
if (chp->ccw_count != 0) {
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev,
|
||||
"ec_srv WRITE error user 2manybytes %0x\n", chp->ccw_count);
|
||||
goto runt;
|
||||
}
|
||||
ec_data.snd_buff.len = i + sizeof(struct ec_eth_hdr);
|
||||
ec_packet_debug(&ec_data, "send", &ec_data.snd_buff);
|
||||
if (eth_write(&ec_data.etherface, &ec_data.snd_buff, NULL) != SCPE_OK) {
|
||||
runt:
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv short packet %d\n\r",i);
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv short packet %d\n",i);
|
||||
//DIAGS chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
/* diags wants prog check instead of unit check */
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK);
|
||||
break;
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv sent packet %d bytes\n\r",i);
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv sent packet %d bytes\n",i);
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
|
||||
case EC_READ: /* Read command 0x02 */
|
||||
case EC_READ: /* Read command 0x02 */
|
||||
/* min size is 78 */
|
||||
if (chp->ccw_count < (ETH_MIN_PACKET+sizeof(struct ec_eth_hdr))) {
|
||||
sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv short read size %x\n",chp->ccw_count);
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
/* diags wants prog check instead of unit check */
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK);
|
||||
break;
|
||||
}
|
||||
ec_master_uptr->SNS |= SNS_RCV_RDY;
|
||||
if (eth_read(&ec_data.etherface, &ec_data.rec_buff, NULL) <= 0) {
|
||||
sim_clock_coschedule(uptr, 1000); /* continue poll */
|
||||
sim_clock_coschedule(uptr, 1000); /* continue poll */
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
ec_packet_debug(&ec_data, "recv", &ec_data.rec_buff);
|
||||
ec_data.rx_count++;
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
hdr = (struct ec_eth_hdr *)(&ec_data.rec_buff.msg[0]);
|
||||
pck = (uint8 *)(&ec_data.rec_buff.msg[0]);
|
||||
switch (GET_MODE(ec_master_uptr->flags)) {
|
||||
@ -607,14 +623,18 @@ runt:
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
|
||||
case EC_LCC: /* Configure LCC */
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
/* Read up to 12 bytes */
|
||||
case EC_LCC: /* Configure LCC 0x10 */
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
/* Read up to 12 bytes of configuration data */
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (chan_read_byte(chsa, &ch)) {
|
||||
if (chan_read_byte(chsa, &conf[0])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
sim_debug(DEBUG_CMD, &ec_dev,
|
||||
"ec_srv LCC CONF: %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n",
|
||||
conf[0], conf[1], conf[2], conf[3], conf[4], conf[5], conf[6], conf[7],
|
||||
conf[8], conf[9], conf[10], conf[11]);
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
|
||||
@ -729,7 +749,7 @@ uint16 ec_haltio(UNIT *uptr) {
|
||||
int cmd = uptr->CMD & EC_CMDMSK;
|
||||
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
|
||||
|
||||
sim_debug(DEBUG_EXP, dptr, "ec_haltio enter chsa %04x cmd = %02x\n", chsa, cmd);
|
||||
sim_debug(DEBUG_EXP, dptr, "ec_haltio enter chsa %04x chp %p cmd %02x\n", chsa, chp, cmd);
|
||||
|
||||
/* terminate any input command */
|
||||
/* UTX wants SLI bit, but no unit exception */
|
||||
@ -741,11 +761,12 @@ uint16 ec_haltio(UNIT *uptr) {
|
||||
// stop any I/O and post status and return error status */
|
||||
chp->chan_byte = BUFF_EMPTY; /* there is no data to read/store */
|
||||
// chp->ccw_count = 0; /* zero the count */
|
||||
chp->ccw_flags &= (FLAG_DC|FLAG_CC);/* stop any chaining */
|
||||
chp->ccw_count = 0; /* zero the count */
|
||||
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC);/* stop any chaining */
|
||||
uptr->CMD &= LMASK; /* make non-busy */
|
||||
uptr->SNS = SNS_RCV_RDY; /* status is online & ready */
|
||||
sim_cancel(uptr); /* clear the input timer */
|
||||
sim_debug(DEBUG_CMD, &con_dev,
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"ec_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd);
|
||||
// chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* force error */
|
||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */
|
||||
@ -753,6 +774,8 @@ uint16 ec_haltio(UNIT *uptr) {
|
||||
}
|
||||
uptr->CMD &= LMASK; /* make non-busy */
|
||||
uptr->SNS = SNS_RCV_RDY; /* status is online & ready */
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"ec_haltio HIO I/O not busy chsa %04x cmd = %02x\n", chsa, cmd);
|
||||
return SCPE_OK; /* not busy */
|
||||
}
|
||||
|
||||
@ -764,8 +787,8 @@ void ec_ini(UNIT *uptr, t_bool f)
|
||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||
uptr->SNS = 0; /* save mode value */
|
||||
|
||||
sim_debug(DEBUG_EXP, &dda_dev,
|
||||
"EC init device %s on unit EC%04x\n", dptr->name, GET_UADDR(uptr->CMD));
|
||||
sim_debug(DEBUG_EXP, dptr,
|
||||
"EC init device %s on unit EC%04X\n", dptr->name, GET_UADDR(uptr->CMD));
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -1034,7 +1057,6 @@ t_stat ec_attach(UNIT* uptr, CONST char* cptr)
|
||||
ec_dev.name, buf);
|
||||
}
|
||||
if (SCPE_OK != eth_filter(&ec_data.etherface, 2, ec_data.macs, 0, 0)) {
|
||||
// if (SCPE_OK != eth_filter(&ec_data.etherface, 2, ec_data.macs, 0, 1)) {
|
||||
eth_close(&ec_data.etherface);
|
||||
free(tptr);
|
||||
return sim_messagef (SCPE_NOATT,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -620,7 +620,8 @@ t_stat mt_srv(UNIT *uptr)
|
||||
case MT_SENSE: /* 0x04 */ /* get sense data */
|
||||
/* write requested status */
|
||||
len = chp->ccw_count; /* command count */
|
||||
for (i=0; i<len; i++) {
|
||||
//0905 for (i=0; i<len; i++) {
|
||||
for (i=0; i<4; i++) {
|
||||
ch = 0;
|
||||
if (i<4)
|
||||
ch = (uptr->SNS >> (24-(i*8))) & 0xff; /* get 8 bits of status */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user