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

SEL32: Modify MFC SCSI disk support for UTX.

SEL32: Add floating point normalize function.
SEL32: Provide MFC support for UTX and MPX3.X.
SEL32: Rewrite console support for type-ahead support.
SEL32: Revise SIO support to always queue I/O request.
SEL32: Allow IOP/MFP address reconfiguration.
SEL32: Add more device reconfigurations.
This commit is contained in:
AZBevier 2020-05-04 19:18:47 -07:00
parent 478b9b7bf4
commit 00d3dfefe7
15 changed files with 1326 additions and 360 deletions

View File

@ -87,8 +87,6 @@ extern uint32 INTS[]; /* Interrupt status flags */
DIB *dib_unit[MAX_DEV]; /* Pointer to Device info block */
DIB *dib_chan[MAX_CHAN]; /* pointer to channel mux dib */
//0401/* device status */
//0401 uint16 dev_status[MAX_DEV]; /* last device status flags */
uint16 loading; /* set when booting */
#define get_chan(chsa) ((chsa>>8)&0x7f) /* get channel number from ch/sa */
@ -139,8 +137,20 @@ void store_csw(CHANP *chp);
/* add an entry to the FIFO */
int32 FIFO_Put(uint16 chsa, uint32 entry)
{
//#define OLD_CHAN
#ifdef OLD_CHAN
DIB *dibp = dib_unit[chsa & 0x7f00]; /* get DIB pointer for channel */
#else
DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */
if (dibp == NULL) {
sim_debug(DEBUG_EXP, &cpu_dev,
"FIFO_Put NULL dib ptr for chsa %04x\n", chsa);
return -1; /* FIFO address error */
}
#endif
if (dibp->chan_fifo_in == ((dibp->chan_fifo_out-1+FIFO_SIZE) % FIFO_SIZE)) {
sim_debug(DEBUG_EXP, &cpu_dev,
"FIFO_Put FIFO full for chsa %04x\n", chsa);
return -1; /* FIFO Full */
}
dibp->chan_fifo[dibp->chan_fifo_in] = entry; /* add new entry */
@ -152,7 +162,16 @@ int32 FIFO_Put(uint16 chsa, uint32 entry)
/* get the next entry from the FIFO */
int32 FIFO_Get(uint16 chsa, uint32 *old)
{
#ifdef OLD_CHAN
DIB *dibp = dib_unit[chsa & 0x7f00]; /* get DIB pointer for channel */
#else
DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */
if (dibp == NULL) {
sim_debug(DEBUG_EXP, &cpu_dev,
"FIFO_Get NULL dib ptr for chsa %04x\n", chsa);
return -1; /* FIFO address error */
}
#endif
/* see if the FIFO is empty */
if (dibp->chan_fifo_in == dibp->chan_fifo_out) {
return -1; /* FIFO is empty, tell caller */
@ -167,12 +186,16 @@ int32 FIFO_Get(uint16 chsa, uint32 *old)
int32 FIFO_Num(uint16 chsa)
{
int32 num; /* number of entries */
#ifdef OLD_CHAN
DIB *dibp = dib_unit[chsa & 0x7f00]; /* get DIB pointer for channel */
#else
DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */
if (dibp == NULL) {
// sim_debug(DEBUG_DETAIL, &cpu_dev,
// "FIFO_Num NULL dibp for chsa %04x\n", chsa);
return 0;
sim_debug(DEBUG_EXP, &cpu_dev,
"FIFO_Num NULL dib ptr for chsa %04x\n", chsa);
return 0; /* FIFO address error */
}
#endif
/* calc entries */
num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE;
return (num>1); /* two words/entry */
@ -218,14 +241,19 @@ int32 RDYQ_Num(void)
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 prog ptr */
DIB *dibp; /* get DIB pointer for channel */
CHANP *chp;
int i;
int i, j;
DIB *dibp = dib_chan[chan>>8]; /* get channel dib ptr */
CHANP *pchp = 0; /* for channel prog ptr */
sim_debug(DEBUG_XIO, &cpu_dev,
"set_inch chan %04x inch addr %06x\n", chan, inch_addr);
/* must be valid DIB pointer */
if (dibp == NULL)
return SCPE_MEM; /* return memory error */
pchp = dibp->chan_prg; /* get parent channel prog ptr */
/* must be valid channel pointer */
if (pchp == NULL)
return SCPE_MEM; /* return memory error */
@ -234,28 +262,27 @@ t_stat set_inch(UNIT *uptr, uint32 inch_addr) {
if (!MEM_ADDR_OK(inch_addr)) /* see if mem addr >= MEMSIZE */
return SCPE_MEM; /* return memory error */
#ifdef NOT_YET
/* see if inch_addr is already defined */
if (pchp->chan_inch_addr != 0)
return SCPE_ARG; /* inch already defined */
#endif
/* set parent */
pchp->chan_inch_addr = inch_addr; /* set the inch addr */
/* set INCH address for all units on master channel */
chp = pchp;
for (i=0; i<dibp->numunits; i++) {
chp->chan_inch_addr = inch_addr; /* set the inch addr */
chp++; /* next unit channel */
}
/* now go through all the sub addresses for the channel and set inch addr */
for (i=0; i<256; i++) {
chsa = chan | i; /* merge sa to real channel */
dibp = dib_unit[chsa]; /* get the DIB pointer */
if (dibp == 0)
if (dib_unit[chsa] == dibp) /* if same dibp already done */
continue;
if (dib_unit[chsa] == 0) /* make sure good address */
continue; /* must have a DIB, so not used */
chp = find_chanp_ptr(chsa); /* find the chanp pointer */
if (chp == 0)
continue; /* not used */
sim_debug(DEBUG_DETAIL, &cpu_dev,
"set_inch2 chsa %04x inch addr %06x\n", chsa, inch_addr);
/* set the inch buffer addr */
chp->chan_inch_addr = inch_addr; /* set inch buffer address */
dibp = dib_unit[chsa]; /* finally get the new dib adddress */
chp = dibp->chan_prg; /* get first unit channel prog ptr */
/* set INCH address for all units on channel */
for (j=0; j<dibp->numunits; j++) {
chp->chan_inch_addr = inch_addr; /* set the inch addr */
chp++; /* next unit channel */
}
}
return SCPE_OK; /* All OK */
}
@ -272,7 +299,7 @@ uint32 find_int_lev(uint16 chsa)
return 0; /* not found */
inta = ((~spadent)>>16)&0x7f; /* get interrupt level */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_IRQ, &cpu_dev,
"find_int_lev class F SPADC %08x chsa %04x lev %02x SPADI %08x INTS %08x\n",
spadent, chsa, inta, SPAD[inta+0x80], INTS[inta]);
return(inta); /* return the level*/
@ -288,9 +315,12 @@ uint32 find_int_icb(uint16 chsa)
inta = find_int_lev(chsa); /* find the int level */
if (inta == 0)
return 0; /* not found */
/* add interrupt vector table base address plus int # byte address offset */
icba = SPAD[0xf1] + (inta<<2); /* interrupt vector address in memory */
if (!MEM_ADDR_OK(icba)) /* needs to be valid address in memory */
return 0; /* not found */
icba = RMW(icba); /* get address of ICB from memory */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_IRQ, &cpu_dev,
"find_int_icb icba %06x SPADC %08x chsa %04x lev %02x SPADI %08x INTS %08x\n",
icba, spadent, chsa, inta, SPAD[inta+0x80], INTS[inta]);
return(icba); /* return the address */
@ -321,7 +351,7 @@ UNIT *find_unit_ptr(uint16 chsa)
return NULL; /* device not found on system */
}
/* Find chanp pointer for given device (ch/sa) */
/* Find channel program pointer for given device (ch/sa) */
CHANP *find_chanp_ptr(uint16 chsa)
{
struct dib *dibp; /* DIB pointer */
@ -364,7 +394,7 @@ int readfull(CHANP *chp, uint32 maddr, uint32 *word)
return 1; /* show we have error */
}
*word = RMW(maddr); /* get 1 word */
sim_debug(DEBUG_EXP, &cpu_dev, "READFULL read %08x from addr %08x\n", *word, maddr);
sim_debug(DEBUG_XIO, &cpu_dev, "READFULL read %08x from addr %08x\n", *word, maddr);
return 0; /* return OK */
}
@ -545,13 +575,25 @@ loop:
chp->chan_status |= STATUS_CEND; /* channel end status */
chp->ccw_flags = 0; /* no flags */
chp->ccw_cmd = 0; /* stop IOCD processing */
irq_pend = 1; /* int coming */
////XXX irq_pend = 1; /* int coming */
sim_debug(DEBUG_EXP, &cpu_dev,
"load_ccw bad status chan %04x status %04x\n",
chan, chp->chan_status);
#ifndef XXX
chp->chan_byte = BUFF_NEXT; /* have main pick us up */
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);
//// irq_pend = 1; /* show pending int */
#else
return 1; /* error return */
#endif
}
#ifdef XXX042320_042720_ADD_BACK
/* NOTE this code needed for MPX 1.X to run! */
/* see if command completed */
/* we have good status */
if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) {
uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */
@ -559,6 +601,16 @@ loop:
"load_ccw @%06x FIFO #%1x cmd complete chan %04x status %04x count %04x\n",
chp->chan_caw, FIFO_Num(chsa), chan, chp->chan_status, chp->ccw_count);
}
#else
/* we have good status */
if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) {
chp->chan_byte = BUFF_NEXT; /* have main pick us up */
RDYQ_Put(chp->chan_dev); /* queue us up */
sim_debug(DEBUG_EXP, &cpu_dev,
"load_ccw good status chan %04x status %04x\n",
chan, chp->chan_status);
}
#endif
}
/* nothing happening, so return */
sim_debug(DEBUG_XIO, &cpu_dev,
@ -587,7 +639,7 @@ int chan_read_byte(uint16 chsa, uint8 *data)
//040120 chp->chan_status |= STATUS_CEND; /* no, end of data */
/*BACK*/ chp->chan_status |= STATUS_CEND; /* no, end of data */
chp->chan_byte = BUFF_CHNEND; /* buffer end too */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_XIO, &cpu_dev,
"chan_read_byte no DC chan end, cnt %04x addr %06x chan %04x\n",
chp->ccw_count, chp->ccw_addr, chan);
return 1; /* return error */
@ -749,8 +801,6 @@ void set_devattn(uint16 chsa, uint16 flags)
if (chp->chan_dev == chsa && (chp->chan_status & STATUS_CEND) != 0 && (flags & SNS_DEVEND) != 0) {
chp->chan_status |= ((uint16)flags);
}
//0401 else
//0401 dev_status[chsa] = flags; /* save device status flags */
sim_debug(DEBUG_CMD, &cpu_dev, "set_devattn(%04x, %04x) %04x\n", chsa, flags, chp->chan_dev);
irq_pend = 1;
}
@ -759,13 +809,13 @@ void set_devattn(uint16 chsa, uint16 flags)
void chan_end(uint16 chsa, uint16 flags) {
CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_XIO, &cpu_dev,
"chan_end entry chsa %04x flags %04x status %04x cmd %02x\n",
chsa, flags, chp->chan_status, chp->ccw_cmd);
// if (chp->chan_byte & BUFF_DIRTY) {
if (chp->chan_byte == BUFF_DIRTY) {
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_XIO, &cpu_dev,
"chan_end writing DIRTY chsa %04x flags %04x status %04x cmd %02x\n",
chsa, flags, chp->chan_status, chp->ccw_cmd);
if (writebuff(chp)) /* write remaining data */
@ -937,8 +987,8 @@ void store_csw(CHANP *chp)
"store_csw FIFO Overflow ERROR on chsa %04x\n", chsa);
}
sim_debug(DEBUG_IRQ, &cpu_dev,
"store_csw FIFO #%1x write chsa %04x sw1 %08x sw2 %08x CPU stat %08x \n",
FIFO_Num(chsa), chsa, stwd1, stwd2, SPAD[0xf9]);
"store_csw FIFO #%1x write chsa %04x sw1 %08x sw2 %08x incha %08x\n",
FIFO_Num(chsa), chsa, stwd1, stwd2, chp->chan_inch_addr);
chp->chan_status = 0; /* no status anymore */
chp->chan_byte = BUFF_CHNEND; /* show done */
irq_pend = 1; /* wakeup controller */
@ -975,11 +1025,13 @@ t_stat checkxio(uint16 chsa, uint32 *status) {
CHANP *chp; /* channel program pointer */
uint16 chan = get_chan(chsa); /* get the logical channel number */
uint32 inta, incha;
DEVICE *dptr; /* DEVICE pointer */
sim_debug(DEBUG_XIO, &cpu_dev, "checkxio entry chsa %04x\n", chsa);
dibp = dib_unit[chsa]; /* get the DIB pointer */
chp = find_chanp_ptr(chsa); /* find the chanp pointer */
uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */
dptr = get_dev(uptr); /* pointer to DEVICE structure */
if (dibp == 0 || uptr == 0 || chp == 0) { /* if no dib or unit ptr, CC3 on return */
*status = CC3BIT; /* not found, so CC3 */
@ -1021,12 +1073,20 @@ t_stat checkxio(uint16 chsa, uint32 *status) {
*status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */
return SCPE_OK; /* just busy CC3&CC4 */
}
*status = CC1BIT; /* CCs = 1, not busy */
sim_debug(DEBUG_XIO, &cpu_dev, "checkxio done CC1 status %08x\n", *status);
/* try this as MFP says it returns 0 on OK */
if (dptr->flags & DEV_CHAN)
*status = 0; /* CCs = 0, OK return */
else
/* return CC1 for non iop/mfp devices */
*status = CC1BIT; /* CCs = 1, not busy */
sim_debug(DEBUG_XIO, &cpu_dev, "checkxio done CC status %08x\n", *status);
return SCPE_OK; /* No CC's all OK */
}
/* start an XIO operation */
/* when we get here the cpu has verified that there is a valid channel address */
/* and an interrupt entry in spad for the channel. The IOCL address in the ICB */
/* has also been verified as present */
/* chan channel number 0-7f */
/* suba unit address within channel 0-ff */
/* Condition codes to return 0-f as specified above */
@ -1039,6 +1099,37 @@ t_stat startxio(uint16 chsa, uint32 *status) {
uint16 chan = get_chan(chsa); /* get the channel number */
uint32 tempa, inta, incha;
#ifndef OLD_CHAN
uint32 word1, word2, cmd;
sim_debug(DEBUG_XIO, &cpu_dev, "startxio entry chsa %04x\n", chsa);
inta = find_int_lev(chsa); /* Interrupt Level for channel */
chan_icb = find_int_icb(chsa); /* Interrupt level context block address */
sim_debug(DEBUG_XIO, &cpu_dev,
"startxio int spad %08x icb %06x inta %02x chan %04x\n",
SPAD[inta+0x80], chan_icb, inta, chan);
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 */
if (cmd == 0) { /* INCH command? */
tempa = word2 & MASK16; /* get count */
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,
"startxio do normal chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n",
chsa, iocla, RMW(iocla), RMW(iocla+4));
#endif
sim_debug(DEBUG_XIO, &cpu_dev, "startxio entry chsa %04x\n", chsa);
dibp = dib_unit[chsa]; /* get the DIB pointer */
chp = find_chanp_ptr(chsa); /* find the chanp pointer */
@ -1050,6 +1141,7 @@ t_stat startxio(uint16 chsa, uint32 *status) {
"startxio chsa %04x device not present, CC3 returned\n", chsa);
return SCPE_OK; /* not found, CC3 */
}
if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { /* is unit attached? */
sim_debug(DEBUG_EXP, &cpu_dev,
"startxio chsa %04x device not present, CC3 returned flags %08x\n", chsa, uptr->flags);
@ -1057,6 +1149,17 @@ t_stat startxio(uint16 chsa, uint32 *status) {
return SCPE_OK; /* not found, CC3 */
}
inta = find_int_lev(chsa); /* Interrupt Level for channel */
#ifdef NONO
if ((INTS[inta]&INTS_ACT) || (SPAD[inta+0x80]&SINT_ACT)) { /* look for level active */
sim_debug(DEBUG_XIO, &cpu_dev,
"SIO Busy INTS ACT FIFO #%1x irq %02x SPAD %08x INTS %08x\n",
FIFO_Num(SPAD[inta+0x80] & 0x7f00), inta, SPAD[inta+0x80], INTS[inta]);
*status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */
return SCPE_OK; /* just busy CC3&CC4 */
}
#endif
/* 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_XIO, &cpu_dev,
@ -1065,7 +1168,6 @@ t_stat startxio(uint16 chsa, uint32 *status) {
return SCPE_OK; /* just busy CC3&CC4 */
}
inta = find_int_lev(chsa); /* Interrupt Level for channel */
chan_icb = find_int_icb(chsa); /* Interrupt level context block address */
sim_debug(DEBUG_XIO, &cpu_dev,
"startxio int spad %08x icb %06x inta %02x chan %04x\n",
@ -1073,8 +1175,10 @@ t_stat startxio(uint16 chsa, uint32 *status) {
iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */
incha = chp->chan_inch_addr; /* get inch address */
#ifdef LEAVE_IT
/* 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
sim_debug(DEBUG_XIO, &cpu_dev,
"startxio test chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n",
@ -1110,12 +1214,23 @@ t_stat startxio(uint16 chsa, uint32 *status) {
"$$ SIO start IOCL processing chsa %04x iocla %08x incha %08x\n",
chsa, iocla, incha);
#ifndef QUEUE_IO
/* try queueing the SIO */
/* Queue us to continue from cpu level */
chp->chan_byte = BUFF_NEXT; /* have main pick us up */
RDYQ_Put(chsa); /* queue us up */
sim_debug(DEBUG_XIO, &cpu_dev,
"$$$ SIO queued chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n",
chsa, iocla, RMW(iocla), RMW(iocla+4));
#endif
#ifdef QUEUE_IO
/* start processing the IOCL */
if (load_ccw(chp, 0) || (chp->chan_status & STATUS_PCI)) {
/* we have an error or user requested interrupt, return status */
sim_debug(DEBUG_EXP, &cpu_dev, "startxio FIFO #%1x store_csw CC2 chan %04x status %08x\n",
FIFO_Num(chsa), chan, chp->chan_status);
#ifndef DISABLE_041320
#ifdef DISABLE_041320
/* DIAG's want CC1 with memory access error */
if (chp->chan_status & STATUS_PCHK) {
chp->chan_status &= ~STATUS_LENGTH; /* clear incorrect length */
@ -1124,7 +1239,7 @@ t_stat startxio(uint16 chsa, uint32 *status) {
"startxio Error1 FIFO #%1x store_csw CC1 chan %04x status %08x\n",
FIFO_Num(chsa), chan, chp->chan_status);
*status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */
irq_pend = 1; /* still pending int */
// irq_pend = 1; /* still pending int */
return SCPE_OK; /* CC2 (0x20) status stored */
}
#endif
@ -1134,28 +1249,22 @@ t_stat startxio(uint16 chsa, uint32 *status) {
chan_end(chsa, SNS_CHNEND); /* show I/O complete & store status in FIFO */
// store_csw(chp); /* store the status in the inch status dw */
/* try 041920 for dexp */
if (FIFO_Num(chsa)) /* post the status */
if (FIFO_Num(chsa)) { /* post the status */
post_csw(chp, 0);
*status = CC2BIT; /* status stored, so CC2 */
sim_debug(DEBUG_EXP, &cpu_dev,
"startxio Error2 FIFO #%1x store_csw CC2 chan %04x status %08x\n",
FIFO_Num(chsa), chan, chp->chan_status);
irq_pend = 1; /* still pending int */
return SCPE_OK; /* CC2 (0x20) status stored */
*status = CC2BIT; /* status stored, so CC2 */
sim_debug(DEBUG_EXP, &cpu_dev,
"startxio Error2 FIFO #%1x store_csw CC2 chan %04x status %08x\n",
FIFO_Num(chsa), chan, chp->chan_status);
irq_pend = 1; /* still pending int */
return SCPE_OK; /* CC2 (0x20) status stored */
}
}
#ifdef NOTNOW
/* try 041920 for dexp */
if (FIFO_Num(chsa)) {
post_csw(chp, 0);
*status = CC2BIT; /* status stored, so CC2 */
irq_pend = 1; /* still pending int */
return SCPE_OK; /* CC2 (0x20) status stored */
}
#endif
*status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */
sim_debug(DEBUG_CMD, &cpu_dev, "$$$ SIO done chsa %04x status %08x iocla %08x\n",
chsa, chp->chan_status, iocla);
// *status = 0; /*TRY*/ /* CCs = 1, SIO accepted & queued, no echo status */
sim_debug(DEBUG_XIO, &cpu_dev, "$$$ SIO done chsa %04x status %08x iocla %08x CC's %08x\n",
chsa, chp->chan_status, iocla, *status);
return SCPE_OK; /* No CC's all OK */
}
@ -1289,7 +1398,6 @@ t_stat stopxio(uint16 chsa, uint32 *status) { /* stop XIO */
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 */
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */
//0401 dev_status[chsa] |= STATUS_ECHO; /* show we stopped the cmd */
*status = CC1BIT; /* request accepted, no status, so CC1 */
return SCPE_OK; /* go wait CC1 */
}
@ -1347,7 +1455,6 @@ t_stat rschnlxio(uint16 chsa, uint32 *status) { /* reset channel XIO */
chp = find_chanp_ptr(chsa); /* find the chanp pointer */
if (chp == 0)
continue; /* not used */
//0401 dev_status[chsa] = 0; /* clear device status */
chp->chan_status = 0; /* clear the channel status */
chp->chan_byte = BUFF_NEWCMD; /* no data yet */
chp->ccw_addr = 0; /* clear buffer address */
@ -1551,7 +1658,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;
//0401 dev_status[chan] = 0; /* clear the channel status location */
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 */
@ -1569,7 +1675,6 @@ t_stat rsctlxio(uint16 lchsa, uint32 *status) { /* reset controller XIO */
if (chp == 0) {
continue; /* not used */
}
//0401 dev_status[chsa] = 0; /* clear device status */
chp->chan_status = 0; /* clear the channel status */
chp->chan_byte = BUFF_NEWCMD; /* no data yet */
chp->ccw_addr = 0; /* clear buffer address */
@ -1597,8 +1702,6 @@ t_stat chan_boot(uint16 chsa, DEVICE *dptr) {
return SCPE_IOERR; /* error */
chp = find_chanp_ptr(chsa); /* find the chanp pointer */
//0401 dev_status[chsa&0x7f00] = 0; /* clear the channel status location */
//0401 dev_status[chsa] = 0; /* device status too */
chp->chan_status = 0; /* clear the channel status */
chp->chan_dev = chsa; /* save our address (ch/sa) */
chp->chan_byte = BUFF_NEWCMD; /* no data yet */
@ -1616,7 +1719,6 @@ t_stat chan_boot(uint16 chsa, DEVICE *dptr) {
if (load_ccw(chp, 0)) { /* load IOCL starting from location 0 */
sim_debug(DEBUG_XIO, &cpu_dev, "Channel Boot Error return from load_ccw chan %04x status %08x\n",
chan, chp->chan_status);
//0401 dev_status[chsa] = 0; /* no device status */
chp->ccw_flags = 0; /* clear the command flags */
chp->chan_byte = BUFF_CHNEND; /* done */
loading = 0; /* show we are done loading from the boot device */
@ -1658,7 +1760,6 @@ uint32 cont_chan(uint16 chsa)
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */
// store_csw(chp); /* store the status in the inch status dw */
// chp->chan_byte = BUFF_NEWCMD; /* read for new cmd */
//0401 dev_status[chsa] = 0; /* no device status */
irq_pend = 1; /* show pending int */
return SCPE_OK; /* done */
}
@ -1675,7 +1776,6 @@ uint32 cont_chan(uint16 chsa)
chsa, chp->chan_status);
// store_csw(chp); /* store the status in the inch status dw */
chp->chan_status &= ~STATUS_PCI; /* remove PCI status bit */
//0401 dev_status[chsa] = 0; /* no device status */
chp->chan_byte = BUFF_NEWCMD; /* we are done */
irq_pend = 1; /* show pending int */
return SCPE_OK; /* done, status stored */
@ -1813,8 +1913,8 @@ uint32 scan_chan(uint32 *ilev) {
chan_icba = RMW(chan_ivl); /* get the interrupt context block addr in memory */
sim_debug(DEBUG_IRQ, &cpu_dev,
"scan_chan INTS REQ FIFO #%1x irq %02x found chan_icba %08x INTS %08x\n",
FIFO_Num(SPAD[i+0x80]&0x7f00), i, chan_icba, INTS[i]);
"scan_chan INTS REQ irq %02x found chan_icba %08x INTS %08x\n",
i, chan_icba, INTS[i]);
sim_debug(DEBUG_IRQ, &cpu_dev,
"scan_chan OPSD1 %08x OPSD2 %08x NPSD1 %08x NPSD2 %08x\n",
RMW(chan_icba), RMW(chan_icba+4), RMW(chan_icba+8), RMW(chan_icba+12));
@ -1881,10 +1981,10 @@ DEVICE *get_dev(UNIT *uptr)
t_stat chan_set_devs() {
uint32 i, j;
for(i = 0; i < MAX_DEV; i++) {
for (i = 0; i < MAX_DEV; i++) {
dib_unit[i] = NULL; /* clear DIB pointer array */
}
for(i = 0; i < MAX_CHAN; i++) {
for (i = 0; i < MAX_CHAN; i++) {
dib_chan[i] = NULL; /* clear DIB pointer array */
}
/* Build channel & device arrays */
@ -1904,23 +2004,22 @@ t_stat chan_set_devs() {
if (dibp == NULL) /* If no DIB, not channel device */
continue;
if (dptr->flags & DEV_DIS) { /* Skip disabled devices */
if ((dptr->flags & DEV_DIS) || /* Skip disabled devices */
((dibp->chan_prg) == NULL)) { /* must have channel info for each device */
chsa = GET_UADDR(uptr->u3); /* ch/sa value */
printf("Device %s chsa %04x not set up dptr %p\n",
dptr->name, chsa, (void *)uptr->dptr);
printf("Device %s chsa %04x not set up dibp %p\n", dptr->name, chsa, dibp);
continue;
}
if ((chp = (CHANP *)dibp->chan_prg) == NULL)/* must have channel information for each device */
continue;
chp = (CHANP *)dibp->chan_prg; /* must have channel information for each device */
/* Check if address is in unit or dev entry */
for (j = 0; j < dptr->numunits; j++) { /* loop through unit entries */
chsa = GET_UADDR(uptr->u3); /* ch/sa value */
printf("Setup device %s%d chsa %04x type %03d dptr %p\n",
dptr->name, j, chsa, GET_TYPE(uptr->flags), (void *)uptr->dptr);
printf("Setup device %s%d chsa %04x type %03d dibp %p\n",
dptr->name, j, chsa, GET_TYPE(uptr->flags), dibp);
/* zero some channel data loc's for device */
//0401 dev_status[chsa] = 0; /* zero device status flags */
//0401 dev_status[chsa&0x7f00] = 0; /* clear the channel status location */
chp->unitptr = uptr; /* set the unit back pointer */
chp->chan_status = 0; /* clear the channel status */
chp->chan_dev = chsa; /* save our address (ch/sa) */
chp->chan_byte = BUFF_EMPTY; /* no data yet */
@ -1930,28 +2029,32 @@ printf("Setup device %s%d chsa %04x type %03d dptr %p\n",
chp->ccw_flags = 0; /* Command chain and supress incorrect length */
chp->ccw_cmd = 0; /* read command */
chp->chan_inch_addr = 0; /* clear address of stat dw in memory */
#ifdef NEWCODE
#ifndef OLD_CHAN
if ((uptr->flags & UNIT_DIS) == 0) { /* is unit marked disabled? */
/* see if this is unit zero */
if ((chsa & 0xff) == 0) {
/* we have channel mux or dev 0 of units */
if (dptr->flags & DEV_CHAN) {
/* see if address already defined */
/* see if channel address already defined */
if (dib_chan[get_chan(chsa)] != 0) {
printf("Channel mux %04x already defined, aborting\n", chsa);
return SCPE_IERR; /* no, arg error */
}
printf("Setting Channel mux %04x\n", chsa);
printf("Setting Channel mux %04x dibp %p\n", chsa, dibp);
/* channel mux, save dib for channel */
dib_chan[get_chan(chsa)] = dibp;
if (dibp->dev_ini != NULL) /* if there is an init routine, call it now */
dibp->dev_ini(uptr, 1); /* init the channel */
} else {
/* we have unit 0 of non-IOP/MFP device */
if (dib_unit[chsa] != 0) {
printf("Channel/Dev %04x already defined\n", chsa);
return SCPE_IERR; /* no, arg error */
} else {
/* channel mux, save dib for channel */
/* for now, save any zero dev as chan */
if (chsa) {
printf("Setting Channel zero unit 0 device %04x\n", chsa);
printf("Setting Channel zero unit 0 device %04x dibp %p\n", chsa, dibp);
dib_unit[chsa] = dibp; /* no, save the dib address */
if (dibp->dev_ini != NULL) /* if there is an init routine, call it now */
dibp->dev_ini(uptr, 1); /* init the channel */
@ -1970,20 +2073,41 @@ printf("Setup device %s%d chsa %04x type %03d dptr %p\n",
#else
if ((uptr->flags & UNIT_DIS) == 0) { /* is unit marked disabled? */
if ((dptr->flags & DEV_CHAN) == 0) {
if (dib_unit[chsa] != 0) {
printf("Channel/SubAddress %04x multiple defined, aborting\n", chsa);
return SCPE_IERR; /* no, arg error */
}
if (dib_unit[chsa] != 0) {
printf("Channel/SubAddress %04x multiply defined, aborting\n", chsa);
return SCPE_IERR; /* no, arg error */
}
}
dib_unit[chsa] = dibp; /* no, save the dib address */
}
#endif
if (dibp->dev_ini != NULL) /* if there is an init routine, call it now */
if (dibp->dev_ini != NULL) /* call channel init if defined */
dibp->dev_ini(uptr, 1); /* init the channel */
uptr++; /* next UNIT pointer */
chp++; /* next CHANP pointer */
}
}
/* now make another pass through the channels and see which integrated */
/* channel/controllers are defined and add them to the dib_chan definitions */
/* this will handle non-MFP/IOP channel controllers */
for (i = 0; i < MAX_CHAN; i++) {
if (dib_chan[i] == 0) {
/* channel not defined, see if defined in dib_unit array */
/* check device zero for suspected channel */
if (dib_unit[i<<8]) {
/* write dibp to channel array */
dib_chan[i] = dib_unit[i<<8]; /* save the channel dib */
printf("Chan_set_dev new Channel %04x defined at dibp %p\n", i<<8, dib_unit[i<<8]);
}
} else {
printf("Chan_set_dev Channel %04x defined at dibp %p\n", i<<8, dib_chan[i]);
/* channel is defined, see if defined in dib_unit array */
if ((dib_unit[i<<8]) == 0) {
/* write dibp to units array */
dib_unit[i<<8] = dib_chan[i]; /* save the channel dib */
}
}
}
return SCPE_OK; /* all is OK */
}

View File

@ -35,7 +35,7 @@
#if NUM_DEVS_RTOM > 0
#define UNIT_CLK UNIT_ATTABLE|UNIT_IDLE|UNIT_DISABLE
#define UNIT_CLK UNIT_IDLE|UNIT_DISABLE
void rtc_setup (uint32 ss, uint32 level);
t_stat rtc_srv (UNIT *uptr);
@ -61,7 +61,7 @@ int32 rtc_lvl = 0x18; /* rtc interrupt level */
rtc_reg RTC register list
*/
/* clock is attached all the time */
/* clock can be enabled / disabled */
/* default to 60 HZ RTC */
UNIT rtc_unit = { UDATA (&rtc_srv, UNIT_IDLE, 0), 16666, UNIT_ADDR(0x7F06)};
//UNIT rtc_unit = { UDATA (&rtc_srv, UNIT_CLK, 0), 16666, UNIT_ADDR(0x7F06)};
@ -93,7 +93,7 @@ DEVICE rtc_dev = {
NULL, NULL, &rtc_reset, /* examine, deposit, reset */
NULL, NULL, NULL, /* boot, attach, detach */
// NULL, 0, 0, NULL, /* dib, dev flags, debug flags, debug */
NULL, DEV_DEBUG, 0, dev_debug, /* dib, dev flags, debug flags, debug */
NULL, DEV_DEBUG|DEV_DISABLE, 0, dev_debug, /* dib, dev flags, debug flags, debug */
NULL, NULL, &rtc_help, /* ?, ?, help */
NULL, NULL, &rtc_desc, /* ?, ?, description */
};
@ -115,7 +115,9 @@ t_stat rtc_srv (UNIT *uptr)
/* stop clock interrupts for dexp debugging */
rtc_pie = 0;
#endif
if (rtc_pie) { /* set pulse intr */
/* id clock sisabled, do not do interrupts */
if (((uptr->flags & DEV_DIS) == 0) && rtc_pie) {
// if (rtc_pie) { /* set pulse intr */
time_t result = time(NULL);
sim_debug(DEBUG_CMD, &rtc_dev, "RT Clock int time %08x\n", (uint32)result);
#ifdef DO_TIME
@ -137,7 +139,13 @@ t_stat rtc_srv (UNIT *uptr)
irq_pend = 1; /* make sure we scan for int */
}
}
#define FOR_MIKE
#ifdef FOR_MIKE
//Mike rtc_unit.wait = sim_rtcn_calb (rtc_tps, TMR_RTC); /* calibrate */
rtc_unit.wait = sim_rtcn_calb (rtc_tps, TMR_RTC); /* calibrate */
#else
rtc_unit.wait = sim_rtcn_calb (rtc_tps, TMR_RTC); /* calibrate */
#endif
sim_activate_after (&rtc_unit, 1000000/rtc_tps);/* reactivate 16666 tics / sec */
return SCPE_OK;
}
@ -160,6 +168,10 @@ void rtc_setup(uint32 ss, uint32 level)
sim_debug(DEBUG_CMD, &rtc_dev,
"RT Clock setup enable int %02x rtc_pie %01x ss %01x\n",
rtc_lvl, rtc_pie, ss);
#ifdef DO_DYNAMIC_DEBUG
/* start debugging */
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ | DEBUG_TRAP);
#endif
} else {
INTS[level] &= ~INTS_ENAB; /* make sure disabled */
SPAD[level+0x80] &= ~SINT_ENAB; /* in spad too */
@ -178,7 +190,12 @@ t_stat rtc_reset(DEVICE *dptr)
{
rtc_pie = 0; /* disable pulse */
/* initialize clock calibration */
#ifdef FOR_MIKE
//Mike rtc_unit.wait = sim_rtcn_init_unit(&rtc_unit, rtc_unit.wait, TMR_RTC);
rtc_unit.wait = sim_rtcn_init_unit(&rtc_unit, rtc_unit.wait, TMR_RTC);
#else
rtc_unit.wait = sim_rtcn_init_unit(&rtc_unit, rtc_unit.wait, TMR_RTC);
#endif
sim_activate (&rtc_unit, rtc_unit.wait); /* activate unit */
return SCPE_OK;
}
@ -208,7 +225,7 @@ t_stat rtc_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
/* sho help rtc */
t_stat rtc_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr)
{
fprintf(st, "SEL 32 IOP realtime clock at 0x7F06\r\n");
fprintf(st, "SEL 32 IOP/MFP realtime clock at 0x7F06\r\n");
fprintf(st, "Use:\r\n");
fprintf(st, " sim> SET RTC [50][60][100][120]\r\n");
fprintf(st, "to set clock interrupt rate in HZ\r\n");
@ -220,7 +237,7 @@ t_stat rtc_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr
/* device description */
const char *rtc_desc(DEVICE *dptr)
{
return "SEL IOP realtime clock @ address 0x7F06";
return "SEL IOP/MFP realtime clock @ address 0x7F06";
}
/************************************************************************/
@ -250,7 +267,14 @@ const char *itm_desc(DEVICE *dptr);
itm_reg Interval Timer ITM register list
*/
#ifdef FOR_MIKE
/* Mike suggested I remove the UNIT_IDLE flag from ITM. This causes SEL32 */
/* to use 100% of the CPU instead of waiting amd ruinning 10% cpu usage */
//BAD Mike UNIT itm_unit = { UDATA (&itm_srv, 0, 0), 26042, UNIT_ADDR(0x7F04)};
UNIT itm_unit = { UDATA (&itm_srv, 0, 0), 26042, UNIT_ADDR(0x7F04)};
#else
UNIT itm_unit = { UDATA (&itm_srv, UNIT_IDLE, 0), 26042, UNIT_ADDR(0x7F04)};
#endif
REG itm_reg[] = {
{ FLDATA (PIE, itm_pie, 0) },
@ -312,7 +336,8 @@ t_stat itm_srv (UNIT *uptr)
itm_lvl, itm_cnt);
/* restart timer with value from user */
if (itm_src) /* use specified src freq */
sim_activate_after_abs_d(&itm_unit, ((double)itm_cnt*400000)/rtc_tps);
sim_activate_after_abs_d(&itm_unit, ((double)itm_cnt*350000)/rtc_tps);
// sim_activate_after_abs_d(&itm_unit, ((double)itm_cnt*400000)/rtc_tps);
// sim_activate_after_abs_d(&itm_unit, ((double)itm_cnt*1000000)/rtc_tps);
else
sim_activate_after_abs_d(&itm_unit, ((double)itm_cnt*itm_tick_size_x_100)/100.0);
@ -386,8 +411,7 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
itm_run = 0; /* timer is not running */
itm_cnt = 0; /* no count reset value */
itm_load = temp; /* last loaded value */
//TRY*/ itm_load = 0; /* last loaded value */
/*TRY*/ itm_strt = 0; /* not restarted neg */
itm_strt = 0; /* not restarted neg */
return 0; /* does not matter, no value returned */
break;
@ -399,6 +423,11 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
case 0x39: /* load timer with new value and start lo rate */
case 0x3a: /* load timer with new value and start hi rate */
case 0x3b: /* load timer with new value and start lo rate */
#ifdef DO_DYNAMIC_DEBUG
if (itm_cmd == 0x38)
/* start debugging */
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ | DEBUG_TRAP);
#endif
// sim_activate_after (&rtc_unit, 1000000/rtc_tps);/* reactivate 16666 tics / sec */
if (itm_run) /* if we were running stop timer */
sim_cancel (&itm_unit); /* cancel timer */
@ -448,11 +477,11 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
}
sim_cancel (&itm_unit); /* cancel timer */
}
if (cmd & 0x40) {
/* timer value already read into temp */
;
}
if (cmd & 0x80) {
// if (cmd & 0x40) {
// /* timer value already read into temp */
// ;
// }
if (cmd & 0x08) {
/* use value from user to load timer */
temp = cnt; /* set user count */
}
@ -487,8 +516,8 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
/* if bits 30-31 == 20, use RTC freq */
itm_src = (cmd>>1)&1; /* set src */
if (itm_src) /* use specified src freq */
// sim_activate_after_abs_d(&itm_unit, ((double)cnt*400000)/rtc_tps);
sim_activate_after_abs_d(&itm_unit, ((double)cnt*1000000)/rtc_tps);
sim_activate_after_abs_d(&itm_unit, ((double)cnt*700000)/rtc_tps);
// sim_activate_after_abs_d(&itm_unit, ((double)cnt*1000000)/rtc_tps);
else
sim_activate_after_abs_d(&itm_unit, ((double)cnt*itm_tick_size_x_100)/100.0);
itm_run = 1; /* set timer running */
@ -500,7 +529,7 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
itm_strt = 0; /* not restarted neg */
itm_load = cnt; /* now loaded */
sim_debug(DEBUG_CMD, &itm_dev, "Intv 0x%02x return value %08x (%08d)\n", cmd, cnt, cnt);
return temp; /* return curr count */
return 0; /* does not matter, no value returned */
break;
case 0x40: /* read the current timer value */
@ -518,6 +547,7 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
}
sim_debug(DEBUG_CMD, &itm_dev, "Intv 0x40 return value %08x (%d)\n", temp, temp);
return temp;
//TRIED return temp << 6;
break;
case 0x60: /* read and stop timer */
@ -682,7 +712,7 @@ t_stat itm_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
/* sho help rtc */
t_stat itm_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr)
{
fprintf(st, "SEL 32 IOP interval timer at 0x7F04\r\n");
fprintf(st, "SEL 32 IOP/MFP interval timer at 0x7F04\r\n");
fprintf(st, "Use:\r\n");
fprintf(st, " sim> SET ITM [3840][7680]\r\n");
fprintf(st, "to set interval timer clock rate in us x 100\r\n");
@ -694,7 +724,7 @@ t_stat itm_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr
/* device description */
const char *itm_desc(DEVICE *dptr)
{
return "SEL IOP Interval Timer @ address 0x7F04";
return "SEL IOP/MFP Interval Timer @ address 0x7F04";
}
#endif

View File

@ -237,7 +237,8 @@ MTAB com_mod[] = {
};
UNIT com_unit[] = {
{UDATA(&comi_srv, UNIT_ATTABLE|UNIT_IDLE, 0), COM_WAIT, UNIT_ADDR(0x0000)}, /* 0 */
// {UDATA(&comi_srv, UNIT_ATTABLE|UNIT_IDLE, 0), COM_WAIT, UNIT_ADDR(0x0000)}, /* 0 */
{UDATA(&comi_srv, UNIT_ATTABLE|UNIT_IDLE, 0), COM_WAIT, UNIT_ADDR(0x4747)}, /* dummy */
};
//DIB com_dib = {NULL, com_startcmd, NULL, NULL, com_ini, com_unit, com_chp, COM_UNITS, 0x0f, 0x7e00, 0, 0, 0};
@ -679,7 +680,7 @@ t_stat comi_srv(UNIT *uptr)
return SCPE_OK; /* return */
}
/* handle SACE, 3 char alread read, so we are done */
/* 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,

View File

@ -40,7 +40,7 @@
#if NUM_DEVS_CON > 0
//#define UNIT_CON UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE
#define UNIT_CON UNIT_IDLE
#define UNIT_CON UNIT_IDLE | UNIT_DISABLE
#define CMD u3
/* Held in u3 is the device command and status */
@ -65,6 +65,7 @@
#define CON_EKO 0x800 /* Echo input character */
#define CON_OUTPUT 0x1000 /* Output ready for unit */
#define CON_READ 0x2000 /* Read mode selected */
#define CON_ATAT 0x4000 /* working on @@A input */
/* Input buffer pointer held in u4 */
@ -141,8 +142,9 @@ DEVICE con_dev = {
"CON", con_unit, NULL, con_mod,
NUM_UNITS_CON, 8, 15, 1, 8, 8,
NULL, NULL, &con_reset, NULL, NULL, NULL,
&con_dib, DEV_DISABLE|DEV_DEBUG, 0, dev_debug
// &con_dib, DEV_DISABLE|DEV_DEBUG, 0, dev_debug
// &con_dib, DEV_UADDR|DEV_DISABLE|DEV_DEBUG, 0, dev_debug
&con_dib, DEV_DIS|DEV_DISABLE|DEV_DEBUG, 0, dev_debug
};
/*
@ -155,8 +157,7 @@ void con_ini(UNIT *uptr, t_bool f) {
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 */
uptr->CMD &= LMASK; /* leave only chsa */
uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */
sim_activate(uptr, 1000); /* time increment */
}
@ -167,7 +168,8 @@ uint16 con_preio(UNIT *uptr, uint16 chan)
DEVICE *dptr = get_dev(uptr);
int unit = (uptr - dptr->units);
if ((uptr->CMD & 0xff00) != 0) { /* just return if busy */
// if ((uptr->CMD & 0xff00) != 0) { /* just return if busy */
if ((uptr->CMD & CON_MSK) != 0) { /* just return if busy */
sim_debug(DEBUG_CMD, &con_dev, "con_preio unit=%02x BUSY\n", unit);
return SNS_BSY;
}
@ -178,7 +180,7 @@ uint16 con_preio(UNIT *uptr, uint16 chan)
/* start an I/O operation */
uint16 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
int unit = (uptr - con_unit); /* unit 0,1 */
int unit = (uptr - con_unit); /* unit 0 is read, unit 1 is write */
uint8 ch;
if ((uptr->CMD & CON_MSK) != 0) { /* is unit busy */
@ -197,7 +199,8 @@ uint16 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
uptr->CMD &= LMASK; /* leave only chsa */
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 */
if (unit == 1)
/*#*/ sim_activate(uptr, 40); /* start us off */
//@41 sim_activate(uptr, 40); /* start us off */
return 0; /* no status change */
break;
@ -208,51 +211,49 @@ uint16 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
uptr->CMD &= LMASK; /* leave only chsa */
uptr->CMD |= (cmd & CON_MSK); /* save command */
uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */
sim_activate(uptr, 20); /* start us off */
if (unit == 1)
/*#*/ sim_activate(uptr, 40); /* start us off */
//@41 sim_activate(uptr, 40); /* start us off */
//@41 sim_activate(uptr, 20); /* start us off */
return 0; /* no status change */
break;
case CON_RD: /* 0x02 */ /* Read command */
case CON_ECHO: /* 0x0a */ /* Read command w/ECHO */
/* if output requested for input device, give error */
uptr->CMD &= LMASK; /* leave only chsa */
// uptr->CMD &= LMASK; /* leave only chsa */
uptr->CMD &= ~CON_MSK; /* remove old CMD */
uptr->CMD |= (cmd & CON_MSK); /* save command */
if (cmd == CON_ECHO) /* echo command? */
uptr->CMD |= CON_EKO; /* save echo status */
uptr->CMD |= CON_READ; /* show read mode */
atbuf = 0; /* reset attention buffer */
uptr->u4 = 0; /* no I/O yet */
con_data[unit].incnt = 0; /* clear any input data */
uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */
sim_activate(uptr, 20); /* start us off */
if (unit == 1)
/*#*/ sim_activate(uptr, 40); /* start us off */
//@41 sim_activate(uptr, 40); /* start us off */
//@41 sim_activate(uptr, 140); /* start us off */
return 0;
break;
case CON_NOP: /* 0x03 */ /* NOP has do nothing */
uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */
uptr->CMD &= LMASK; /* leave only chsa */
// uptr->CMD &= LMASK; /* leave only chsa */
uptr->CMD &= ~CON_MSK; /* remove old 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, 20); /* start us off */
if (unit == 1)
/*#*/ sim_activate(uptr, 40); /* start us off */
//@41 sim_activate(uptr, 40); /* start us off */
return 0; /* no status change */
break;
#ifndef JUNK
case 0x0C: /* 0x0C */ /* Unknown command */
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, 20); /* start us off */
if (unit == 1)
/*#*/ sim_activate(uptr, 40); /* start us off */
//@41 sim_activate(uptr, 40); /* start us off */
return 0; /* no status change */
break;
#endif
case CON_CON: /* 0x1f */ /* Connect, return Data Set ready */
sim_debug(DEBUG_CMD, &con_dev, "con_startcmd %04x: Cmd %02x CON\n", chan, cmd);
@ -280,9 +281,7 @@ uint16 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
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 */
uptr->SNS |= SNS_CMDREJ; /* command rejected */
sim_debug(DEBUG_CMD, &con_dev,
"con_startcmd %04x: Invalid command %02x Sense %02x\n",
chan, cmd, uptr->SNS);
@ -300,9 +299,14 @@ t_stat con_srvo(UNIT *uptr) {
int unit = (uptr - con_unit); /* unit 0 is read, unit 1 is write */
int cmd = uptr->CMD & CON_MSK;
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
#ifdef DO_ALL_CHS
uint8 ch, cp;
#else
uint8 ch;
#endif
sim_debug(DEBUG_CMD, &con_dev, "con_srvo enter chsa %04x cmd = %02x\n", chsa, cmd);
sim_debug(DEBUG_CMD, &con_dev,
"con_srvo enter CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
/* if input tried from output device, error */
if ((cmd == CON_RD) || (cmd == CON_ECHO) || (cmd == 0xC0)) { /* check for output */
@ -313,7 +317,7 @@ t_stat con_srvo(UNIT *uptr) {
uptr->SNS |= SNS_CMDREJ; /* command rejected */
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);
"con_srvo Read to output device CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */
return SCPE_OK;
}
@ -322,8 +326,8 @@ t_stat con_srvo(UNIT *uptr) {
if ((cmd == CON_NOP) || (cmd == CON_INCH2)) { /* NOP has to do nothing */
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvo INCH/NOP unit %02x: cmd %02x incnt %02x u4 %02x\n",
unit, cmd, con_data[unit].incnt, uptr->u4);
"con_srvo INCH/NOP unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n",
unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4);
if (cmd == CON_INCH2) { /* Channel end only for INCH */
int len = chp->ccw_count; /* INCH command count */
uint32 mema = chp->ccw_addr; /* get inch or buffer addr */
@ -332,11 +336,11 @@ t_stat con_srvo(UNIT *uptr) {
set_inch(uptr, mema); /* new address */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvo INCH chsa %04x len %02x inch %06x\n", chsa, len, mema);
"con_srvo INCH CMD %08x chsa %04x len %02x inch %06x\n", uptr->CMD, chsa, len, mema);
chan_end(chsa, SNS_CHNEND); /* INCH done */
} else {
sim_debug(DEBUG_CMD, &con_dev,
"con_srvo NOP chsa %04x cmd = %02x\n", chsa, cmd);
"con_srvo NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
}
return SCPE_OK;
@ -347,12 +351,13 @@ t_stat con_srvo(UNIT *uptr) {
if (chan_read_byte(chsa, &ch)) { /* get byte from memory */
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvo write %02x chsa %04x cmd %02x complete\n",
ch, chsa, cmd);
"con_srvo write %02x CMD %08x chsa %04x cmd %02x complete\n",
ch, uptr->CMD, chsa, cmd);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
} else {
/* HACK HACK HACK */
ch &= 0x7f; /* make 7 bit w/o parity */
#ifdef DO_ALL_CHS
/* simh stops outputting chars to debug file if it is passed a null????? */
if (ch == 0) /* do not pass a null char */
//WAS ch = '@'; /* stop simh abort .... */
@ -363,23 +368,25 @@ t_stat con_srvo(UNIT *uptr) {
else
cp = '^';
sim_debug(DEBUG_CMD, &con_dev,
"con_srvo write %01x: putch 0x%02x %c\n", unit, ch, cp);
"con_srvo write %01x: CMD %08x putch 0x%02x %c\n", unit, uptr->CMD, ch, cp);
sim_putchar(ch); /* output next char to device */
#ifdef DO_DYNAMIC_DEBUG
last2 = ((last2 << 8) & 0xffff) | cp; /* get last 2 chars */
if (last2 == 0x503e) { /* check for DXP> */
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ);
con_dev.dctrl |= (DEBUG_CMD | DEBUG_EXP | DEBUG_DETAIL);
// last2 = ((last2 << 8) & 0xffff) | cp; /* get last 2 chars */
// if (last2 == 0x503e) { /* check for DXP> */
last2 = ((last2 << 8) & 0xffffff) | cp; /* get last 3 chars */
if (last2 == 0x273637) { /* check for '67 */
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ | DEBUG_TRAP);
// con_dev.dctrl |= (DEBUG_CMD | DEBUG_EXP | DEBUG_DETAIL);
}
#endif
//OLD sim_putchar(cp); /* output next char to device */
#else
sim_putchar(ch); /* output next char to device */
//WAS sim_putchar(cp); /* output next char to device */
#endif
sim_activate(uptr, 20); /* keep going */
//@41 sim_activate(uptr, 30); /* start us off */
//@41 sim_activate(uptr, 50); /* start us off */
#else
/* do not output to debug file */
sim_putchar(ch); /* output next char to device */
#endif
sim_activate(uptr, 30); /* start us off */
}
}
return SCPE_OK;
@ -395,28 +402,30 @@ t_stat con_srvi(UNIT *uptr) {
t_stat r;
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi enter chsa %04x cmd %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count);
"con_srvi enter CMD %08x chsa %04x cmd %02x incnt %02x u4 %02x\n",
uptr->CMD, chsa, cmd, con_data[unit].incnt, uptr->u4);
/* if output tried to input device, error */
if ((cmd == CON_RWD) || (cmd == CON_WR) || (cmd == 0x0C)) { /* check for output */
/* CON_RWD: 0x37 */ /* TOF and write line */
/* CON_WR: 0x01 */ /* Write command */
/* CON_RWD: 0x37 */ /* TOF and write line */
/* CON_WR: 0x01 */ /* Write command */
/* if input requested for output device, give error */
if (unit == 0) {
uptr->SNS |= SNS_CMDREJ; /* command rejected */
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);
"con_srvi Write to input device CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */
// fall thru return SCPE_OK;
}
// return sim_activate (uptr, 20);
}
if ((cmd == CON_NOP) || (cmd == CON_INCH2)) { /* NOP is do nothing */
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi INCH/NOP unit %02x: cmd %02x incnt %02x u4 %02x\n",
unit, cmd, con_data[unit].incnt, uptr->u4);
"con_srvi INCH/NOP unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n",
unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4);
if (cmd == CON_INCH2) { /* Channel end only for INCH */
int len = chp->ccw_count; /* INCH command count */
uint32 mema = chp->ccw_addr; /* get inch or buffer addr */
@ -424,53 +433,80 @@ t_stat con_srvi(UNIT *uptr) {
// int i = set_inch(uptr, mema); /* new address */
set_inch(uptr, mema); /* new address */
con_data[unit].incnt = 0; /* buffer empty */
uptr->u4 = 0; /* no I/O yet */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi INCH chsa %04x len %02x inch %06x\n", chsa, len, mema);
"con_srvi INCH CMD %08x chsa %04x len %02x inch %06x\n", uptr->CMD, chsa, len, mema);
//TRY228 chan_end(chsa, SNS_CHNEND); /* INCH done */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
} else {
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi NOP chsa %04x cmd = %02x\n", chsa, cmd);
"con_srvi NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* NOP done */
}
/* drop through to poll input */
return sim_activate (uptr, 20);
// return sim_activate (uptr, 20);
}
switch (cmd) {
case CON_RD: /* 0x02 */ /* read from device */
case CON_ECHO: /* 0x0a */ /* read from device w/ECHO */
if (uptr->CMD & CON_INPUT) { /* input waiting? */
int len = chp->ccw_count; /* get command count */
ch = con_data[unit].ibuff[uptr->u4++]; /* get char from read buffer */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi readbuf unit %02x: read %02x incnt %02x u4 %02x len %02x\n",
unit, ch, con_data[unit].incnt, uptr->u4, len);
if (chan_write_byte(chsa, &ch)) { /* write byte to memory */
con_data[unit].incnt = 0; /* buffer empty */
cmd = 0; /* no cmd either */
if ((uptr->u4 != con_data[unit].incnt) || /* input empty */
(uptr->CMD & CON_INPUT)) { /* input waiting? */
// if (uptr->CMD & CON_INPUT) { /* input waiting? */
ch = con_data[unit].ibuff[uptr->u4]; /* get char from read buffer */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi readbuf unit %02x: CMD %08x read %02x incnt %02x u4 %02x len %02x\n",
unit, uptr->CMD, ch, con_data[unit].incnt, uptr->u4, chp->ccw_count);
/* process any characters */
if (uptr->u4 != con_data[unit].incnt) { /* input available */
ch = con_data[unit].ibuff[uptr->u4]; /* get char from read buffer */
if (chan_write_byte(chsa, &ch)) { /* write byte to memory */
/* write error */
cmd = 0; /* no cmd now */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi write error unit %02x: CMD %08x read %02x u4 %02x ccw_count %02x\n",
unit, uptr->CMD, ch, uptr->u4, chp->ccw_count);
uptr->CMD &= LMASK; /* nothing left, command complete */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */
break;
}
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi write to mem unit %02x: read %02x u4 %02x ccw_count %02x\n",
unit, ch, uptr->u4, chp->ccw_count);
uptr->u4 = 0; /* no I/O yet */
"con_srvi write to mem unit %02x: CMD %08x read %02x u4 %02x incnt %02x\n",
unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt);
/* character accepted, bump buffer pointer */
uptr->u4++; /* next char position */
/* see if at end of buffer */
if (uptr->u4 >= sizeof(con_data[unit].ibuff))
uptr->u4 = 0; /* reset pointer */
/* user want more data? */
if ((test_write_byte_end(chsa)) == 0) {
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi need more unit %02x CMD %08x u4 %02x incnt %02x ccw_count %02x\n",
unit, uptr->CMD, uptr->u4, con_data[unit].incnt, chp->ccw_count);
/* user wants more, look next time */
if (uptr->u4 == con_data[unit].incnt) { /* input empty */
uptr->CMD &= ~CON_INPUT; /* no input available */
}
break;
}
/* command is completed */
cmd = 0; /* no cmd now */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi read done unit %02x: CMD %08x read %02x u4 %02x incnt %02x ccw_count %02x\n",
unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt, chp->ccw_count);
uptr->CMD &= LMASK; /* nothing left, command complete */
if (uptr->u4 != con_data[unit].incnt) { /* input empty */
uptr->CMD |= CON_INPUT; /* input still available */
}
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */
break;
}
return sim_activate (uptr, 20);
#ifdef NOTNOW
if (test_write_byte_end(chsa)) { /* see if read request complete */
con_data[unit].incnt = 0; /* buffer is empty */
cmd = 0; /* no cmd either */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi nothing to write to mem unit %02x: u4 %02x ccw_count %02x\n",
unit, uptr->u4, chp->ccw_count);
uptr->u4 = 0; /* no I/O yet */
uptr->CMD &= LMASK; /* nothing left, command complete */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */
}
#endif
}
break;
}
@ -479,59 +515,99 @@ t_stat con_srvi(UNIT *uptr) {
r = sim_poll_kbd(); /* poll for a char */
if (r & SCPE_KFLAG) { /* got a char */
ch = r & 0xff; /* drop any extra bits */
if ((cmd == CON_RD) || (cmd == CON_ECHO)) { /* looking for input? */
// if (ch == 0x1b) /* esc is bad */
// goto goout; /* skip control char */
// if ((cmd == CON_RD) || (cmd == CON_ECHO)) { /* looking for input? */
if ((uptr->CMD & CON_INPUT) == 0) { /* looking for input? */
atbuf = 0; /* reset attention buffer */
uptr->CMD &= ~CON_ATAT; /* no @@A input */
if (ch == '@') { /* maybe for console int */
atbuf = (ch)<<8; /* start anew */
uptr->CMD |= CON_ATAT; /* show getting @ */
}
if (ch == '\n') /* convert newline */
ch = '\r'; /* make newline into carriage return */
/* Handle end of buffer */
switch (ch) {
case '\r': /* return */
case '\n': /* newline */
uptr->CMD |= CON_CR; /* C/R received */
/* fall through */
default:
if (con_data[unit].incnt < sizeof(con_data[unit].ibuff)) {
if (uptr->CMD & CON_EKO) /* ECHO requested */
sim_putchar(ch); /* ECHO the char */
con_data[unit].ibuff[con_data[unit].incnt++] = ch;
uptr->CMD |= CON_INPUT; /* we have a char available */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi readch unit %02x: read %02x u4 %02x ccw_count %02x\n",
unit, ch, uptr->u4, chp->ccw_count);
}
return sim_activate (uptr, 20);
}
} else {
/* look for attention sequence '@@A' */
if (ch == '@' || ch == 'A' || ch == 'a') {
if (ch == 'a')
ch = 'A';
atbuf = (atbuf|ch)<<8;
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi handle readch unit %02x: CMD %08x read %02x u4 %02x incnt %02x\n",
unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt);
//MOVED /* see if count at max, if so reset to start */
//AFTER if (con_data[unit].incnt >= sizeof(con_data[unit].ibuff))
//incnt++ con_data[unit].incnt = 0; /* reset buffer cnt */
if (uptr->CMD & CON_EKO) /* ECHO requested */
sim_putchar(ch); /* ECHO the char */
/* put char in buffer */
con_data[unit].ibuff[con_data[unit].incnt++] = ch;
/*GEERT*/ /* see if count at max, if so reset to start */
/*MOVED*/ if (con_data[unit].incnt >= sizeof(con_data[unit].ibuff))
/*HERE**/ con_data[unit].incnt = 0; /* reset buffer cnt */
uptr->CMD |= CON_INPUT; /* we have a char available */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi readch unit %02x: CMD %08x read %02x u4 %02x incnt %02x\n",
unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt);
return sim_activate (uptr, 30); /* come back real soon */
// return sim_activate (uptr, 300); /* come back real soon */
}
/* not looking for input, look for attn or wakeup */
if (ch == '?') {
/* set ring bit? */
set_devwake(chsa, SNS_ATTN|SNS_DEVEND|SNS_CHNEND); /* tell user */
}
/* not wanting input, but we have a char, look for @@A */
if (uptr->CMD & CON_ATAT) { /* looking for @@A */
/* we have at least one @, look for another */
if (ch == '@' || ch == 'A' || ch == 'a') {
uint8 cc = ch;
if (cc == 'a')
cc = 'A'; /* make uppercase */
sim_putchar(ch); /* ECHO the char */
atbuf = (atbuf|cc)<<8; /* merge new char */
if (atbuf == 0x40404100) {
attention_trap = CONSOLEATN_TRAP; /* console attn (0xb4) */
atbuf = 0; /* reset attention buffer */
uptr->CMD &= ~CON_ATAT; /* no @@A input */
sim_putchar('\r'); /* return char */
sim_putchar('\n'); /* line feed char */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi unit %02x: read @@A Console Trap\n", unit);
}
} else {
if (ch == '?') {
/* set ring bit? */
set_devwake(chsa, SNS_ATTN|SNS_DEVEND|SNS_CHNEND); /* tell user */
"con_srvi unit %02x: CMD %08x read @@A Console Trap\n", unit, uptr->CMD);
uptr->u4 = 0; /* no input count */
con_data[unit].incnt = 0; /* no input data */
}
goto goout;
}
/* char not for us, so keep looking */
atbuf = 0; /* reset attention buffer */
uptr->CMD &= ~CON_ATAT; /* no @@A input */
}
/* not looking for input, look for attn or wakeup */
if (ch == '@') {
atbuf = (atbuf|ch)<<8; /* merge in char */
uptr->CMD |= CON_ATAT; /* show getting @ */
sim_putchar(ch); /* ECHO the char */
}
/* assume it is for next read request, so save it */
/* see if count at max, if so reset to start */
if (con_data[unit].incnt >= sizeof(con_data[unit].ibuff))
con_data[unit].incnt = 0; /* reset buffer cnt */
if (uptr->CMD & CON_EKO) /* ECHO requested */
sim_putchar(ch); /* ECHO the char */
/* put char in buffer */
con_data[unit].ibuff[con_data[unit].incnt++] = ch;
uptr->CMD |= CON_INPUT; /* we have a char available */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvi readch2 unit %02x: CMD %08x read %02x u4 %02x incnt %02x\n",
unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt);
}
if ((r & SCPE_KFLAG) && /* got something and */
((cmd == CON_RD) || (cmd == CON_ECHO))) /* looking for input */
//LAST return sim_activate (uptr, 200);
return sim_activate (uptr, 40);
//@ return sim_activate(uptr, 80); /* keep going */
// return sim_activate(uptr, 200); /* keep going */
// return sim_activate (uptr, 5000);
return tmxr_clock_coschedule_tmr (uptr, TMR_RTC, 1); /* come back soon */
goout:
// return sim_activate (uptr, 5000);
return tmxr_clock_coschedule_tmr (uptr, TMR_RTC, 1); /* come back soon */
}
t_stat con_reset(DEVICE *dptr) {
@ -543,7 +619,7 @@ t_stat con_reset(DEVICE *dptr) {
uint16 con_haltio(UNIT *uptr) {
uint16 chsa = GET_UADDR(uptr->CMD);
int cmd = uptr->CMD & CON_MSK;
// int unit = (uptr - con_unit); /* unit # 0 is read, 1 is write */
int unit = (uptr - con_unit); /* unit # 0 is read, 1 is write */
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
sim_debug(DEBUG_EXP, &con_dev, "con_haltio enter chsa %04x cmd = %02x\n", chsa, cmd);
@ -558,12 +634,14 @@ uint16 con_haltio(UNIT *uptr) {
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* force error */
uptr->CMD &= LMASK; /* make non-busy */
uptr->u4 = 0; /* no I/O yet */
con_data[unit].incnt = 0; /* no input data */
uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */
sim_debug(DEBUG_CMD, &con_dev,
"con_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd);
return SCPE_IOERR;
}
uptr->u4 = 0; /* no I/O yet */
con_data[unit].incnt = 0; /* no input data */
uptr->CMD &= LMASK; /* make non-busy */
uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */
return SCPE_OK; /* not busy */

View File

@ -283,6 +283,8 @@ extern uint32 s_mpfw(uint32 reg, uint32 mem, uint32 *cc);
extern t_uint64 s_dvfw(uint32 reg, uint32 mem, uint32 *cc);
extern uint32 s_mpfd(t_uint64 reg, t_uint64 mem, uint32 *cc);
extern t_uint64 s_dvfd(t_uint64 reg, t_uint64 mem, uint32 *cc);
extern uint32 s_normfw(uint32 mem, uint32 *cc);
extern t_uint64 s_normfd(t_uint64 mem, uint32 *cc);
/* History information */
int32 hst_p = 0; /* History pointer */
@ -526,8 +528,7 @@ int nobase_mode[] = {
int base_mode[] = {
/* 00 04 08 0C */
/* 00 AND, OR, EOR */
// HLF, SCC|R1|RR|SD|HLF, SCC|R1|RR|SD|HLF, SCC|R1|RR|SD|HLF,
HLF, R1|RR|SD|HLF, SCC|R1|RR|SD|HLF, SCC|R1|RR|SD|HLF,
HLF, SCC|R1|RR|SD|HLF, SCC|R1|RR|SD|HLF, SCC|R1|RR|SD|HLF,
/* 10 14 18 1C */
/* SACZ CMR xBR SRx */
@ -896,13 +897,13 @@ npmem:
}
/* output O/S and User MPX entries */
//041420 sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
// sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"#MEMORY %06x MPL %06x MPL[0] %08x %06x MPL[%04x] %08x %06x\n",
MEMSIZE, mpl, RMW(mpl), RMW(mpl+4), cpix,
RMW(cpix+mpl), RMW(cpix+mpl+4));
//041420 sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
// sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"MEMORY2 %06x BPIX %04x cpix %04x CPIX %04x CPIXPL %04x HIWM %04x\n",
MEMSIZE, BPIX, cpix, CPIX, CPIXPL, HIWM);
@ -1765,11 +1766,11 @@ t_stat Mem_read(uint32 addr, uint32 *data)
}
/* everybody else has read access */
}
sim_debug(DEBUG_DETAIL, &cpu_dev, "Mem_read addr %06x realaddr %08x data %08x prot %02x\n",
sim_debug(DEBUG_DETAIL, &cpu_dev, "Mem_read addr %06x realaddr %06x data %08x prot %02x\n",
addr, realaddr, *data, prot);
} else {
/* RealAddr returned an error */
sim_debug(DEBUG_EXP, &cpu_dev, "Mem_read error addr %.8x realaddr %.8x data %.8x prot %02x status %04x\n",
sim_debug(DEBUG_EXP, &cpu_dev, "Mem_read error addr %06x realaddr %06x data %08x 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)) {
@ -1929,8 +1930,8 @@ uint32 OPSD2=0; /* Original PSD2 */
/* called from simulator */
t_stat sim_instr(void) {
t_stat reason = 0; /* reason for stopping */
t_uint64 dest; /* Holds destination/source register */
t_uint64 source; /* Holds source or memory data */
t_uint64 dest = 0; /* Holds destination/source register */
t_uint64 source = 0; /* Holds source or memory data */
t_uint64 td; /* Temporary */
t_int64 int64a; /* temp int */
t_int64 int64b; /* temp int */
@ -1952,7 +1953,7 @@ t_stat sim_instr(void) {
uint8 EXM_EXR=0; /* PC Increment for EXM/EXR instructions */
uint32 reg; /* GPR or Base register bits 6-8 */
uint32 sreg; /* Source reg in from bits 9-11 reg-reg instructions */
uint32 ix; /* index register */
uint32 ix = 0; /* index register */
uint32 dbl; /* Double word */
uint32 ovr=0; /* Overflow flag */
//FORSTEP uint32 stopnext = 0; /* Stop on next instruction */
@ -2035,11 +2036,14 @@ wait_loop:
sim_debug(DEBUG_IRQ, &cpu_dev,
"CPU RDYQ entry for chsa %04x processed\n", chsa);
}
waitqcnt = 20; /* wait 10 instructions */
// waitqcnt = 50; /* wait 10 instructions */
}
else
waitqcnt -= 1; /* wait another instruction */
}
else
// waitqcnt = 50; /* wait 10 instructions */
waitqcnt = 20; /* wait 10 instructions */
//040120 waitqcnt = 10; /* wait 10 instructions */
//
@ -2333,7 +2337,7 @@ exec:
case IMM:
if (PC & 02) { /* if pc is on HW boundry, bad address */
TRAPME = ADDRSPEC_TRAP; /* bad address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC1 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -2345,7 +2349,7 @@ exec:
case WRD:
if (PC & 02) { /* if pc is on HW boundry, bad address */
TRAPME = ADDRSPEC_TRAP; /* bad address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC2 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -2416,7 +2420,7 @@ exec:
case IMM: /* Immediate mode */
if (PC & 02) { /* if pc is on HW boundry, bad address */
TRAPME = ADDRSPEC_TRAP; /* bad address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC3 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -2561,7 +2565,7 @@ exec:
case 2: /* double word address */
if ((addr & 7) != 2) { /* must be double word adddress */
TRAPME = ADDRSPEC_TRAP; /* bad address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC5 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -2590,7 +2594,7 @@ exec:
if (dbl) { /* is it double regs */
if (reg & 1) { /* check for odd reg load */
TRAPME = ADDRSPEC_TRAP; /* bad address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC6 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -2613,7 +2617,7 @@ exec:
if (dbl) {
if (sreg & 1) {
TRAPME = ADDRSPEC_TRAP; /* bad address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC7 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -2860,6 +2864,7 @@ sim_debug(DEBUG_CMD, &cpu_dev,
}
break;
case 0x04>>2: /* 0x04 RR|R1|SD|HLF - SD|HLF */ /* ANR, SMC, CMC, RPSWT */
i_flags &= ~SCC; /* make sure we do not set CC's for dest value */
switch(opr & 0xF) {
case 0x0: /* ANR */
dest &= source; /* just an and reg to reg */
@ -2918,7 +2923,8 @@ sim_debug(DEBUG_CMD, &cpu_dev,
/* 7 - Read & Lock Enabled (=1)/Disabled (=0) */
/* 8-12 - Lower Bound of Shared Memory */
/* 3-31 - Reserved and must be zero */
sim_debug(DEBUG_EXP, &cpu_dev,
// sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_CMD, &cpu_dev,
"SMC V6/67 GPR[%02x] = %08x SMCR = %08x CPU STATUS SPAD[f9] = %08x\n",
reg, GPR[reg], SMCR, SPAD[0xf9]);
SMCR = GPR[reg]; /* write reg bits 0-12 to shared memory controller */
@ -3427,7 +3433,7 @@ tbr: /* handle basemode TBR too *
/* update the PSD with new address from reg */
PSD1 &= ~temp; /* clean the bits to be changed */
PSD1 |= (addr & temp); /* insert the CC's and address */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_CMD, &cpu_dev,
"TRSW REG %01x PSD %08x %08x modes %08x temp %06x\n",
reg, PSD1, PSD2, modes, temp);
i_flags |= BT; /* we branched, so no PC update */
@ -3703,7 +3709,8 @@ tbr: /* handle basemode TBR too *
goto newpsd; /* handle trap */
}
temp2 = CPUSTATUS; /* save original */
sim_debug(DEBUG_EXP, &cpu_dev,
// sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_CMD, &cpu_dev,
"SETCPU orig %08x user bits %08x New CPUSTATUS %08x\n",
temp2, temp, CPUSTATUS);
/* bits 20-23 and bit 25 can change */
@ -3933,12 +3940,44 @@ skipit:
temp = GPR[reg]; /* reg contents specified by Rd */
addr = GPR[sreg]; /* reg contents specified by Rs */
/* temp has Rd (GPR[reg]), addr has Rs (GPR[sreg]) */
if ((opr & 0xF) == 0x3)
if ((opr & 0xF) == 0x3) {
addr = NEGATE32(addr); /* subtract, so negate source */
temp2 = s_adfw(temp, addr, &CC); /* all add float numbers */
sim_debug(DEBUG_CMD, &cpu_dev,
"%s GPR[%d] %08x addr %08x result %08x\n",
(opr&0xf)==3 ? "SURFW":"ADRFW", reg, GPR[reg], GPR[sreg], temp2);
}
// temp2 = s_adfw(temp, addr, &CC); /* add float numbers */
// } else { /* handle add */
// }
/* test for zero reg value */
if (temp == 0) { /* reg value is zero */
temp2 = s_normfw(addr, &CC); /* normalize addr value */
if (CC & CC1BIT) {
CC = 0; /* remove addr except */
if (temp2 & FSIGN)
CC |= CC3BIT; /* CC3 for neg */
else if (temp2 == 0)
CC |= CC4BIT; /* CC4 for zero */
else
CC |= CC2BIT; /* CC2 for greater than zero */
}
}
else
if (addr == 0) { /* mem value is zero */
temp2 = s_normfw(temp, &CC); /* normalize addr value */
if (CC & CC1BIT) {
CC = 0; /* remove addr except */
if (temp2 & FSIGN)
CC |= CC3BIT; /* CC3 for neg */
else if (temp2 == 0)
CC |= CC4BIT; /* CC4 for zero */
else
CC |= CC2BIT; /* CC2 for greater than zero */
}
}
else
temp2 = s_adfw(temp, addr, &CC); /* do ADFW */
sim_debug(DEBUG_EXP, &cpu_dev,
"%s GPR[%d] %08x addr %08x result %08x CC %08x\n",
(opr&0xf)==3 ? "SURFW":"ADRFW",
reg, GPR[reg], GPR[sreg], temp2, CC);
PSD1 &= 0x87FFFFFE; /* clear the old CC's */
PSD1 |= (CC & 0x78000000); /* update the CC's in the PSD */
if (CC & CC1BIT) { /* check for arithmetic exception */
@ -3980,7 +4019,7 @@ skipit:
addr = GPR[sreg]; /* reg contents specified by Rs */
/* temp has Rd (GPR[reg]), addr has Rs (GPR[sreg]) */
temp2 = (uint32)s_dvfw(temp, addr, &CC); /* divide reg by sreg */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"DVRFW GPR[%d] %08x src %08x result %08x\n",
reg, GPR[reg], addr, temp2);
PSD1 &= 0x87FFFFFE; /* clear the old CC's */
@ -4003,7 +4042,7 @@ skipit:
/* convert from 32 bit float to 32 bit fixed */
addr = GPR[sreg]; /* reg contents specified by Rs */
temp2 = s_fixw(addr, &CC); /* do conversion */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"FIXW GPR[%d] %08x result %08x\n",
sreg, GPR[sreg], temp2);
PSD1 &= 0x87FFFFFE; /* clear the old CC's */
@ -4027,7 +4066,7 @@ skipit:
addr = GPR[sreg]; /* reg contents specified by Rs */
/* temp has Rd (GPR[reg]), addr has Rs (GPR[sreg]) */
temp2 = s_mpfw(temp, addr, &CC); /* mult reg by sreg */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"MPRFW GPR[%d] %08x src %08x result %08x\n",
reg, GPR[reg], addr, temp2);
PSD1 &= 0x87FFFFFE; /* clear the old CC's */
@ -4050,7 +4089,7 @@ skipit:
/* convert from 32 bit integer to 32 bit float */
addr = GPR[sreg]; /* reg contents specified by Rs */
GPR[reg] = s_fltw(addr, &CC); /* do conversion & set CC's */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"FLTW GPR[%d] %08x result %08x\n",
sreg, GPR[sreg], GPR[reg]);
PSD1 &= 0x87FFFFFE; /* clear the old CC's */
@ -4082,12 +4121,39 @@ skipit:
td = (((t_uint64)GPR[reg]) << 32); /* get upper reg value */
td |= (t_uint64)GPR[reg+1]; /* insert low order reg value */
source = (((t_uint64)GPR[sreg]) << 32); /* get upper reg value */
source |= (t_uint64)GPR[sreg+1]; /* insert low order reg value */
if ((opr & 0xF) == 0x9)
dest = s_adfd(td, source, &CC); /* add */
else
dest = s_sufd(td, source, &CC); /* subtract */
sim_debug(DEBUG_CMD, &cpu_dev,
source |= (t_uint64)GPR[sreg+1]; /* insert low order reg value */
if ((opr & 0xF) == 0xb) {
td = NEGATE32(td); /* make negative for subtract */
}
if (td == 0) { /* is reg value zero */
dest = s_normfd(source, &CC); /* normalize addr value */
if (CC & CC1BIT) {
CC = 0; /* remove addr except */
if (dest & DMSIGN)
CC |= CC3BIT; /* CC3 for neg */
else if (dest == 0)
CC |= CC4BIT; /* CC4 for zero */
else
CC |= CC2BIT; /* CC2 for greater than zero */
}
}
else
if (source == 0) { /* memory value zero? */
dest = s_normfd(td, &CC); /* normalize reg value */
if (CC & CC1BIT) {
CC = 0; /* remove addr except */
if (dest & DMSIGN)
CC |= CC3BIT; /* CC3 for neg */
else if (dest == 0)
CC |= CC4BIT; /* CC4 for zero */
else
CC |= CC2BIT; /* CC2 for greater than zero */
}
}
else
dest = s_adfd(td, source, &CC); /* do ADFD */
sim_debug(DEBUG_EXP, &cpu_dev,
"%s GPR[%d] %08x %08x src %016llx result %016llx\n",
(opr&0xf)==8 ? "ADRFD":"SURFD", reg, GPR[reg], GPR[reg+1], source, dest);
PSD1 &= 0x87FFFFFE; /* clear the old CC's */
@ -4157,7 +4223,7 @@ doovr4:
source = (((t_uint64)GPR[sreg]) << 32); /* get upper reg value */
source |= (t_uint64)GPR[sreg+1]; /* insert low order reg value */
dest = s_dvfd(td, source, &CC); /* divide double values */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"DVRFD GPR[%d] %08x %08x src %016llx result %016llx\n",
reg, GPR[reg], GPR[reg+1], source, dest);
PSD1 &= 0x87FFFFFE; /* clear the old CC's */
@ -4187,7 +4253,7 @@ doovr4:
source = (((t_uint64)GPR[sreg]) << 32) | ((t_uint64)GPR[sreg+1]);
/* convert from 64 bit double to 64 bit int */
dest = s_fixd(source, &CC);
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"FIXD GPR[%d] %08x %08x result %016llx\n",
sreg, GPR[sreg], GPR[sreg+1], dest);
PSD1 &= 0x87FFFFFE; /* clear the old CC's */
@ -4217,7 +4283,7 @@ doovr4:
source = (((t_uint64)GPR[sreg]) << 32); /* get upper reg value */
source |= (t_uint64)GPR[sreg+1]; /* insert low order reg value */
dest = s_mpfd(td, source, &CC); /* multiply double values */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"MPRFD GPR[%d] %08x %08x src %016llx result %016llx\n",
reg, GPR[reg], GPR[reg+1], source, dest);
PSD1 &= 0x87FFFFFE; /* clear the old CC's */
@ -4246,7 +4312,7 @@ doovr4:
source = (((t_uint64)GPR[sreg]) << 32); /* get upper reg value */
source |= (t_uint64)GPR[sreg+1]; /* insert low order reg value */
dest = s_fltd(source, &CC); /* do conversion & set CC's */
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"FLTD GPR[%d] %08x %08x result %016llx\n",
sreg, GPR[sreg], GPR[sreg+1], dest);
PSD1 &= 0x87FFFFFE; /* clear the old CC's */
@ -4437,7 +4503,7 @@ doovr3:
goto inv; /* invalid instruction in nonbased mode */
if (FC != 0) { /* word address only */
TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC8 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -4458,7 +4524,7 @@ doovr3:
goto inv; /* invalid instruction in nonbased mode */
if ((FC & 3) != 0) { /* word address only */
TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC9 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -4578,8 +4644,8 @@ doovr3:
/* exponent must not be zero or all 1's */
/* normalize the value Rd in GPR[reg] and put exponent into Rs GPR[sreg] */
temp = s_nor(GPR[reg], &GPR[sreg]);
sim_debug(DEBUG_CMD, &cpu_dev,
"NOR GPR[%d] %08x result %08x exp %08x\n",
sim_debug(DEBUG_EXP, &cpu_dev,
"NOR GPR[%d] %08x result %08x exp %02x\n",
reg, GPR[reg], temp, GPR[sreg]);
GPR[reg] = temp;
break;
@ -4606,8 +4672,8 @@ doovr3:
td = (((t_uint64)GPR[reg]) << 32) | ((t_uint64)GPR[reg+1]);
/* normalize the value Rd in GPR[reg] and put exponent into Rs GPR[sreg] */
dest = s_nord(td, &GPR[sreg]);
sim_debug(DEBUG_CMD, &cpu_dev,
"NORD GPR[%d] %08x %08x result %016llx exp %08x\n",
sim_debug(DEBUG_EXP, &cpu_dev,
"NORD GPR[%d] %08x %08x result %016llx exp %02x\n",
reg, GPR[reg], GPR[reg+1], dest, GPR[sreg]);
GPR[reg+1] = (uint32)(dest & FMASK); /* save the low order reg */
GPR[reg] = (uint32)((dest>>32) & FMASK);/* save the hi order reg */
@ -5100,9 +5166,14 @@ meoa: /* merge point for eor, and, or */
IR = temp; /* get instruction from memory */
if (FC == 3) /* see if right halfword specified */
IR <<= 16; /* move over the HW instruction */
if ((IR & 0xFC7F0000) == 0xC8070000 ||
(IR & 0xFF800000) == 0xA8000000 ||
#ifdef DIAG_SAYS_OK_TO_EXECUTE_ANOTHER_EXECUTE
if ((IR & 0xFC7F0000) == 0xC8070000 || /* No EXR target */
(IR & 0xFF800000) == 0xA8000000 || /* No EXM target */
(IR & 0xFC000000) == 0x80000000) {
#else
/* 32/67 diag says execute of execute is OK */
if ((IR & 0xFC000000) == 0x80000000) {
#endif
/* Fault, attempt to execute another EXR, EXRR, EXM, or LEAR */
goto inv; /* invalid instruction */
}
@ -5505,11 +5576,14 @@ doovr2:
/* if bit 30 set, instruction is in right hw, do EXRR */
if (addr & 2)
IR <<= 16; /* move instruction to left HW */
#ifdef DIAG_SAYS_OK_TO_EXECUTE_ANOTHER_EXECUTE
/* 32/67 diag says execute of execute is OK */
if ((IR & 0xFC7F0000) == 0xC8070000 ||
(IR & 0xFF800000) == 0xA8000000) {
/* Fault, attempt to execute another EXR, EXRR, or EXM */
goto inv; /* invalid instruction */
}
#endif
EXM_EXR = 4; /* set PC increment for EXR */
OPSD1 &= 0x87FFFFFE; /* clear the old CC's */
OPSD1 |= PSD1 & 0x78000000; /* update the CC's in the PSD */
@ -5691,15 +5765,47 @@ doovr2:
/* do ADFW or SUFW instructions */
temp2 = GPR[reg]; /* dest - reg contents specified by Rd */
addr = (uint32)(source & D32RMASK); /* get 32 bits from source memory */
if (opr & 8) { /* Was it ADFW? */
temp = s_adfw(temp2, addr, &CC); /* do ADFW */
} else {
/* s_sufw will negate the value before calling add */
temp = s_sufw(temp2, addr, &CC); /* do SUFW */
if ((opr & 8) == 0) { /* Was it SUFW? */
addr = NEGATE32(addr); /* take negative for add */
}
sim_debug(DEBUG_CMD, &cpu_dev,
"%s GPR[%d] %08x addr %08x result %08x\n",
(opr&8) ? "ADFW":"SUFW", reg, GPR[reg], addr, temp);
// if (opr & 8) { /* Was it ADFW? */
/* test for zero reg value */
// if ((temp2 == 0) && ((addr & 0x80000000) == 0)) { /* is reg value zero */
if (temp2 == 0) { /* reg value is zero */
temp = s_normfw(addr, &CC); /* normalize addr value */
if (CC & CC1BIT) {
CC = 0; /* remove addr except */
if (temp & FSIGN)
CC |= CC3BIT; /* CC3 for neg */
else if (temp == 0)
CC |= CC4BIT; /* CC4 for zero */
else
CC |= CC2BIT; /* CC2 for greater than zero */
}
}
else
// if ((addr == 0) && ((temp2 & 0x80000000) == 0)) { /* is reg value zero */
if (addr == 0) { /* mem value is zero */
temp = s_normfw(temp2, &CC); /* normalize addr value */
if (CC & CC1BIT) {
CC = 0; /* remove addr except */
if (temp & FSIGN)
CC |= CC3BIT; /* CC3 for neg */
else if (temp == 0)
CC |= CC4BIT; /* CC4 for zero */
else
CC |= CC2BIT; /* CC2 for greater than zero */
}
}
else
temp = s_adfw(temp2, addr, &CC); /* do ADFW */
// } else {
// /* s_sufw will negate the value before calling add */
// temp = s_sufw(temp2, addr, &CC); /* do SUFW */
// }
sim_debug(DEBUG_EXP, &cpu_dev,
"%s GPR[%d] %08x addr %08x result %08x CC %08x\n",
(opr&8) ? "ADFW":"SUFW", reg, GPR[reg], addr, temp, CC);
ovr = 0;
if (CC & CC1BIT)
ovr = 1;
@ -5723,15 +5829,45 @@ doovr2:
td = (((t_uint64)GPR[reg]) << 32); /* get upper reg value */
td |= (t_uint64)GPR[reg+1]; /* insert low order reg value */
/* source has 64 bit memory data */
if (opr & 8) { /* Was it ADFD? */
dest = s_adfd(td, source, &CC); /* do ADFD */
} else {
/* s_sufd will negate the memory value before calling add */
dest = s_sufd(td, source, &CC); /* do SUFD */
if ((opr & 8) == 0) { /* Was it SUFD? */
td = NEGATE32(td); /* make negative for subtract */
}
sim_debug(DEBUG_CMD, &cpu_dev,
"%s GPR[%d] %08x %08x src %016llx result %016llx\n",
(opr&8) ? "ADFD":"SUFD", reg, GPR[reg], GPR[reg+1], source, dest);
/* test for zero reg value */
// if ((td == 0) && ((GPR[reg] & 0x80000000) == 0)) { /* is reg value zero */
if (td == 0) { /* is reg value zero */
dest = s_normfd(source, &CC); /* normalize addr value */
if (CC & CC1BIT) {
CC = 0; /* remove addr except */
if (dest & DMSIGN)
CC |= CC3BIT; /* CC3 for neg */
else if (dest == 0)
CC |= CC4BIT; /* CC4 for zero */
else
CC |= CC2BIT; /* CC2 for greater than zero */
}
}
else
if (source == 0) { /* memory value zero? */
dest = s_normfd(td, &CC); /* normalize reg value */
if (CC & CC1BIT) {
CC = 0; /* remove addr except */
if (dest & DMSIGN)
CC |= CC3BIT; /* CC3 for neg */
else if (dest == 0)
CC |= CC4BIT; /* CC4 for zero */
else
CC |= CC2BIT; /* CC2 for greater than zero */
}
}
else
dest = s_adfd(td, source, &CC); /* do ADFD */
// } else {
// /* s_sufd will negate the memory value before calling add */
// dest = s_sufd(td, source, &CC); /* do SUFD */
// }
sim_debug(DEBUG_EXP, &cpu_dev,
"%s GPR[%d] %08x %08x src %016llx result %016llx CC %08x\n",
(opr&8) ? "ADFD":"SUFD", reg, GPR[reg], GPR[reg+1], source, dest, CC);
ovr = 0;
if (CC & CC1BIT) /* test for overflow detection */
ovr = 1;
@ -5769,7 +5905,7 @@ doovr2:
CC = 0; /* clear the CC'ss */
/* handle float or double mul/div instructions */
if (dbl == 0) {
/* do MPFW or DIVW instructions */
/* do MPFW or DVFW instructions */
temp2 = GPR[reg]; /* dest - reg contents specified by Rd */
addr = (uint32)(source & D32RMASK); /* get 32 bits from source memory */
if (opr & 8) { /* Was it MPFW? */
@ -5777,7 +5913,7 @@ doovr2:
} else {
temp = (uint32)s_dvfw(temp2, addr, &CC); /* do DVFW */
}
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"%s GPR[%d] %08x addr %08x result %08x\n",
(opr&8) ? "MPFW":"DVFW", reg, GPR[reg], addr, temp);
if (CC & CC1BIT)
@ -5807,7 +5943,7 @@ doovr2:
} else {
dest = s_dvfd(td, source, &CC); /* do DVFD */
}
sim_debug(DEBUG_CMD, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
"%s GPR[%d] %08x %08x src %016llx result %016llx\n",
(opr&8) ? "MPFD":"DVFD", reg, GPR[reg], GPR[reg+1], source, dest);
if (CC & CC1BIT) /* test for overflow detection */
@ -5914,7 +6050,7 @@ doovr2:
/* if ((FC & 5) != 0) { */
if ((FC & 4) != 0) {
TRAPME = ADDRSPEC_TRAP; /* bad address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC10 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -5949,7 +6085,7 @@ doovr2:
/* if ((FC & 5) != 0) { */
if ((FC & 4) != 0) {
TRAPME = ADDRSPEC_TRAP; /* bad address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC11 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -6036,7 +6172,7 @@ doovr2:
if ((FC & 04) != 0 || FC == 2) { /* can not be byte or doubleword */
/* Fault */
TRAPME = ADDRSPEC_TRAP; /* bad reg address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC12 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -6127,12 +6263,12 @@ doovr2:
if (PSD2 & MAPBIT) {
/* set mapped mode in cpu status */
CPUSTATUS |= 0x00800000; /* set bit 8 of cpu status */
//041420 sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
// sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"B4 LPSDCM temp %06x TPSD %08x %08x PSD %08x %08x\n",
temp, TPSD[0], TPSD[1], PSD1, PSD2);
//041420 sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
// sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"B4 LPSDCM BPIX %04x CPIX %04x CPIXPL %04x\n",
BPIX, CPIX, CPIXPL);
#ifdef FOR_DEBUG_MPX_041420
@ -6199,20 +6335,20 @@ doovr2:
if ((PSD2 & RETMBIT) == 0) { /* don't load maps if retain bit set */
/* we need to load the new maps */
TRAPME = load_maps(PSD, 0); /* load maps for new PSD */
//041420 sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
// sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"AF LPSDCM TPSD %08x %08x PSD %08x %08x TRAPME %02x\n",
TPSD[0], TPSD[1], PSD1, PSD2, TRAPME);
//041420 sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
// sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"AF LPSDCM BPIX %04x CPIX %04x CPIXPL %04x\n",
BPIX, CPIX, CPIXPL);
//041420 sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
// sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"AF LPSDCM OS MAPC[0-5] %08x %08x %08x %08x %08x %08x\n",
MAPC[0], MAPC[1], MAPC[2], MAPC[3], MAPC[4], MAPC[5]);
//041420 sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_EXP, &cpu_dev,
// sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_DETAIL, &cpu_dev,
"AF LPSDCM US MAPC[%x-%x] %08x %08x %08x %08x %08x %08x\n",
BPIX, BPIX+5, MAPC[BPIX], MAPC[BPIX+1], MAPC[BPIX+2],
MAPC[BPIX+3], MAPC[BPIX+4], MAPC[BPIX+5]);
@ -6797,7 +6933,7 @@ mcheck:
if (dbl) { /* if double reg, store 2nd reg */
if (reg & 1) { /* is it double regs into odd reg */
TRAPME = ADDRSPEC_TRAP; /* bad address, error */
sim_debug(DEBUG_EXP, &cpu_dev,
sim_debug(DEBUG_TRAP, &cpu_dev,
"ADDRSPEC13 OP %04x addr %08x\n", OP, addr);
goto newpsd; /* go execute the trap now */
}
@ -7223,7 +7359,8 @@ uint32 def_floppy = 0x7ef0; /* IOP floppy disk channel 7e, device f0
/* do any one time initialization here for cpu */
t_stat cpu_reset(DEVICE *dptr)
{
int i;
int i;
t_stat devs = SCPE_OK;
/* leave regs alone so values can be passed to boot code */
PSD1 = 0x80000000; /* privileged, non mapped, non extended, address 0 */
@ -7246,7 +7383,7 @@ t_stat cpu_reset(DEVICE *dptr)
ISMCW = 0; /* No V9 IPU Shadow Memory Configuration */
RDYQIN = RDYQOUT = 0; /* initialize cheannel ready queue */
chan_set_devs(); /* set up the defined devices on the simulator */
devs = chan_set_devs(); /* set up the defined devices on the simulator */
/* set default breaks to execution tracing */
sim_brk_types = sim_brk_dflt = SWMASK('E');
@ -7306,7 +7443,9 @@ t_stat cpu_reset(DEVICE *dptr)
M[4] = 0x02000000; /* 0x10 IOCD 3 Read into address 0 */
M[5] = 0x000006EC; /* 0x14 IOCD 3 Read 0x6EC bytes */
loading = 0; /* not loading yet */
/* we are good to go */
/* we are good to go or error from device setup */
if (devs != SCPE_OK)
return devs;
return SCPE_OK;
}

View File

@ -191,6 +191,9 @@ extern DEVICE lpr_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 */

View File

@ -266,12 +266,12 @@ disk_type[] =
{"MH300", 19, 192, 20, 800, 823, 0x40}, /* 3 823 300M 8127 */
{"MH600", 40, 192, 20, 800, 843, 0x40}, /* 4 843 600M 8155 */
/* For UTX */
{"9342", 5, 256, 16, 819, 823, 0x40}, /* 5 823 80M XXXX */
{"8148", 10, 256, 16, 819, 823, 0x40}, /* 6 823 160M 8148 */
{"9346", 19, 256, 16, 819, 823, 0x40}, /* 7 823 300M */
{"8858", 24, 256, 16, 707, 711, 0x40}, /* 8 711 340M */
{"8887", 10, 256, 35, 819, 823, 0x40}, /* 9 823 340M */
{"8155", 40, 256, 16, 839, 843, 0x40}, /* 10 843 675M */
{"9342", 5, 256, 16, 819, 823, 0x41}, /* 5 823 80M XXXX */
{"8148", 10, 256, 16, 819, 823, 0x41}, /* 6 823 160M 8148 */
{"9346", 19, 256, 16, 819, 823, 0x41}, /* 7 823 300M */
{"8858", 24, 256, 16, 707, 711, 0x41}, /* 8 711 340M */
{"8887", 10, 256, 35, 819, 823, 0x41}, /* 9 823 340M */
{"8155", 40, 256, 16, 839, 843, 0x41}, /* 10 843 675M */
{NULL, 0}
};
@ -527,7 +527,7 @@ t_stat disk_srv(UNIT *uptr)
CHANP *chp = (CHANP *)dibp->chan_prg; /* get pointer to channel program */
int cmd = uptr->CMDu3 & DSK_CMDMSK;
int type = GET_TYPE(uptr->flags);
uint32 trk, cyl, sec;
uint32 trk=0, cyl=0, sec=0;
int unit = (uptr - dptr->units);
int len;
int i;

View File

@ -71,19 +71,24 @@ uint32 s_mpfw(uint32 reg, uint32 mem, uint32 *cc);
uint32 s_dvfw(uint32 reg, uint32 mem, uint32 *cc);
t_uint64 s_mpfd(t_uint64 reg, t_uint64 mem, uint32 *cc);
t_uint64 s_dvfd(t_uint64 reg, t_uint64 mem, uint32 *cc);
uint32 s_normfw(uint32 mem, uint32 *cc);
t_uint64 s_normfd(t_uint64 mem, uint32 *cc);
#define NORMASK 0xf8000000 /* normalize 5 bit mask */
#define DNORMASK 0xf800000000000000ll /* double normalize 5 bit mask */
#define EXMASK 0x7f000000 /* exponent mask */
#define FRMASK 0x80ffffff /* fraction mask */
#define EXMASK 0x7f000000 /* exponent mask */
#define FRMASK 0x80ffffff /* fraction mask */
#define DEXMASK 0x7f00000000000000ll /* exponent mask */
#define DFSVAL 0xff00000000000000ll /* minus full scale value */
#define DFRMASK 0x80ffffffffffffffll /* fraction mask */
#define NEGATE32(val) ((~val) + 1) /* negate a value 16/32/64 bits */
/* normalize floating point number */
/* normalize floating point fraction */
uint32 s_nor(uint32 reg, uint32 *exp) {
uint32 texp = 0; /* no exponent yet */
sim_debug(DEBUG_EXP, &cpu_dev,
"s_nor entry reg %08x texp %08x\n", reg, texp);
if (reg != 0) { /* do nothing if reg is already zero */
uint32 mv = reg & NORMASK; /* mask off bits 0-4 */
while ((mv == 0) || (mv == NORMASK)) {
@ -94,9 +99,11 @@ uint32 s_nor(uint32 reg, uint32 *exp) {
}
/* bits 0-4 of reg is neither 0 nor all ones */
/* show that reg is normalized */
texp = 0x40 - texp; /* subtract shift count from 0x40 */
texp = (uint32)(0x40-(int32)texp); /* subtract shift count from 0x40 */
}
*exp = texp; /* return exponent */
sim_debug(DEBUG_EXP, &cpu_dev,
"s_nor exit reg %08x texp %08x\n", reg, texp);
return (reg); /* return normalized register */
}
@ -104,6 +111,8 @@ uint32 s_nor(uint32 reg, uint32 *exp) {
t_uint64 s_nord(t_uint64 reg, uint32 *exp) {
uint32 texp = 0; /* no exponent yet */
sim_debug(DEBUG_EXP, &cpu_dev,
"s_nord entry regs %016llx texp %08x\n", reg, texp);
if (reg != 0) { /* do nothing if reg is already zero */
t_uint64 mv = reg & DNORMASK; /* mask off bits 0-4 */
while ((mv == 0) || (mv == DNORMASK)) {
@ -114,23 +123,311 @@ t_uint64 s_nord(t_uint64 reg, uint32 *exp) {
}
/* bits 0-4 of reg is neither 0 nor all ones */
/* show that reg is normalized */
texp = 0x40 - texp; /* subtract shift count from 0x40 */
texp = (uint32)(0x40-(int32)texp); /* subtract shift count from 0x40 */
}
*exp = texp; /* return exponent */
sim_debug(DEBUG_EXP, &cpu_dev,
"s_nord exit reg %016llx texp %08x\n", reg, texp);
return (reg); /* return normalized double register */
}
/**************************************************************
* This routine unpacks the floating point number in (r6,r7). *
* The unbiased, right justified, two's complement exponent *
* is returned in r1. If xxfw is set, the two's complement *
* fraction (with the binary point to the left of bit 8) is *
* returned in r6, and r7 is cleared. if xxfd is reset, the *
* two's complement double precision fraction is returned in *
* (r6,r7). *
***************************************************************/
struct fpnum {
int32 msw; /* most significent word */
int32 lsw; /* least significient word */
int32 exp; /* exponent */
int32 CCs; /* condition codes */
};
/* unpack single precision floating point number */
void unpacks(struct fpnum *np) {
uint32 ex = np->msw & 0xff000000; /* get exponent & sign from msw */
sim_debug(DEBUG_EXP, &cpu_dev,
"unpacks entry msw %08x exp %08x\n", np->msw, ex);
np->lsw = 0; /* 1 word for single precision */
// ex = np->msw & 0xff000000; /* get exponent & sign from msw */
if (ex & 0x80000000) /* check for negative */
ex ^= 0xff000000; /* reset sign & complement exponent */
np->msw ^= ex; /* replace exponent with sign extension */
ex = ((uint32)ex) >> 24; /* right justify the exponent */
ex -= 0x40; /* unbias exponent */
np->exp = ex; /* save the exponent */
np->CCs = 0; /* zero CCs for later */
sim_debug(DEBUG_EXP, &cpu_dev,
"unpacks return msw %08x exp %08x\n", np->msw, ex);
return;
}
/* unpack double precision floating point number */
void unpackd(struct fpnum *np) {
int32 ex = np->msw & 0xff000000; /* get exponent & sign from msw */
if (ex & 0x80000000) /* check for negative */
ex ^= 0xff000000; /* reset sign & complement exponent */
np->msw ^= ex; /* replace exponent with sign extension */
ex = ((uint32)ex) >> 24; /* right justify the exponent */
ex -= 0x40; /* unbias exponent */
np->exp = ex; /* save exponent */
np->CCs = 0; /* zero CCs for later */
return;
}
/**************************************************************
* Common routine for finishing the various F.P. instruction *
* simulations. at this point, r1 = raw exponent, and *
* (r6,r7) = unnormalized fraction, with the binary point to *
* the left of r6[8]. The simulated condition codes will be *
* returned in bits 1 through 4 of "sim.flag." *
* *
* Floating point operations not terminating with an arith- *
* metic exception produce the following condition codes: *
* *
* CC1 CC2 CC3 CC4 Definition *
* ------------------------------------------------------- *
* 0 1 0 0 no exception, fraction positive *
* 0 0 1 0 no exception, fraction negative *
* 0 0 0 1 no exception, fraction = zero *
* *
* *
* an arithmetic exception produces the follwing condition *
* code settings: *
* *
* CC1 CC2 CC3 CC4 Definition *
* -------------------------------------------------------- *
* 1 0 1 0 exp underflow, fraction negative *
* 1 0 1 1 exp overflow, fraction negative *
* 1 1 0 0 exp underflow, fraction positive *
* 1 1 0 1 exp overflow, fraction positive *
* *
**************************************************************/
/** Normalization and rounding of single precision number */
void packs(struct fpnum *np) {
uint32 ex, tmp, tmp2;
t_uint64 num = ((t_uint64)np->msw << 32) | np->lsw; /* make 64 bit num */
sim_debug(DEBUG_EXP, &cpu_dev,
"pack entry msw %08x lsw %08x exp %08x num %016llx\n",
np->msw, np->lsw, np->exp, num);
num = ((t_int64)num) << 3; /* slad 3 to align for normalization */
sim_debug(DEBUG_EXP, &cpu_dev,
"pack pl 0 num %016llx ex %08x exp %08x\n", num, ex, np->exp);
num = s_nord(num, &ex); /* normalize the number with cnt in ex */
sim_debug(DEBUG_EXP, &cpu_dev,
"pack pl 1 num %016llx ex %08x exp %08x\n", num, ex, np->exp);
num = ((t_int64)num) >> 7; /* srad 7 to align & sign extend number */
sim_debug(DEBUG_EXP, &cpu_dev,
"pack pl 2 num %016llx ex %08x exp %08x\n", num, ex, np->exp);
if (num & DMSIGN) /* test for negative fraction */
np->CCs = CC3BIT; /* show fraction negative */
else
if (num == 0) {
np->CCs = CC4BIT; /* show fraction zero */
np->msw = 0; /* save msw */
np->lsw = 0; /* save lsw */
np->exp = 0; /* save exp */
return; /* done if zero */
}
else
np->CCs = CC2BIT; /* show fraction positive */
sim_debug(DEBUG_EXP, &cpu_dev,
"pack pl 3 CC %08x num = %016llx ex = %08x\n", np->CCs, num, ex);
/* we need to round single precision number */
tmp = (num >> 32) & 0xffffffff; /* get msw */
tmp2 = num & 0xffffffff; /* get lsw */
if ((int32)tmp >= 0x00ffffff) { /* if at max, no rounding */
if (tmp2 & 0x80000000) /* round if set */
tmp += 1; /* round fraction */
}
num = (((t_uint64)tmp) << 32); /* make 64 bit num with lo 32 bits zero */
sim_debug(DEBUG_EXP, &cpu_dev,
"pack pl 4 num %016llx msw %08x exp %08x ex %08x\n", num, np->msw, np->exp, ex);
//4110000 bad if ((t_int64)num <= DFSVAL) { /* see if > 0xff00000000000000 */
//4110000 bad if ((t_int64)num == DFSVAL) { /* see if > 0xff00000000000000 */
//80000001 has cc bad if ((t_int64)num >= DFSVAL) { /* see if > 0xff00000000000000 */
//needs >= for BEF -> BEF is EQ to DFSVAL
if (((t_int64)num) >= DFSVAL) { /* see if > 0xff00000000000000 */
/* fixup fraction to not have -1 in results */
num = ((t_int64)num) >> 4; /* sra 4 shift over 4 bits */
ex += 1; /* bump exponent */
sim_debug(DEBUG_EXP, &cpu_dev,
"pack pl 4a num = %016llx exp = %08x ex = %08x\n", num, np->exp, ex);
}
/* end normalization and rounding */
np->exp += ex; /* normalized, biased exp */
np->exp += 1; /* correct shift count */
sim_debug(DEBUG_EXP, &cpu_dev,
"pack n&r num %016llx msw %08x exp %08x ex %08x\n", num, np->msw, np->exp, ex);
if (((int32)(np->exp)) < 0) { /* check for exp neg underflow */
np->CCs |= CC1BIT; /* set CC1 & return zero */
np->msw = 0;
np->lsw = 0;
return;
}
sim_debug(DEBUG_EXP, &cpu_dev,
"pack exp num %016llx msw %08x exp %08x ex %08x\n", num, np->msw, np->exp, ex);
/* if no exponent overflow merge exp & fraction and return */
if (((int32)(np->exp)) <= 0x7f) {
np->msw = (num >> 32); /* get msw */
np->lsw = num & 0xffffffff; /* get lsw */
sim_debug(DEBUG_EXP, &cpu_dev,
"packs ret msw %08x exp %08x\n", np->msw, np->exp);
ex = np->exp << 24; /* put exponent in bits 1-7 */
sim_debug(DEBUG_EXP, &cpu_dev,
"packs ret msw %08x exp %08x ex %08x\n", np->msw, np->exp, ex);
np->msw ^= ex; /* merge exponent & fraction */
sim_debug(DEBUG_EXP, &cpu_dev,
"packs ret CCs %08x msw %08x exp %08x ex %08x\n", np->CCs, np->msw, np->exp, ex);
return; /* CCs already set */
}
/* process overflow exponent */
np->CCs |= CC1BIT; /* set CC1 */
np->CCs |= CC4BIT; /* set CC4 */
/* do SP max value */
if (np->CCs & CC2BIT) { /* see if CC2 is set */
np->msw = 0x7fffffff; /* yes, use max pos value */
np->lsw = 0; /* zero for SP */
sim_debug(DEBUG_EXP, &cpu_dev,
"pack SP xit1 CCs %08x msw %08x exp %08x ex %08x\n",
np->CCs, np->msw, np->exp, ex);
return;
}
np->msw = 0x80000001; /* set max neg value */
np->lsw = 0; /* zero for sp */
sim_debug(DEBUG_EXP, &cpu_dev,
"pack SP xit2 CCs %08x msw %08x exp %08x ex %08x\n",
np->CCs, np->msw, np->exp, ex);
return;
}
/** Normalization and rounding of double precision number */
void packd(struct fpnum *np) {
uint32 ex;
t_uint64 num = ((t_uint64)np->msw << 32) | np->lsw; /* make 64 bit num */
num = ((t_int64)num) << 3; /* sla 3 to align for normalization */
num = s_nord(num, &ex); /* normalize the number with cnt in ex */
num = ((t_int64)num) >> 7; /* align & sign extend number */
if (num & DMSIGN) /* test for negative fraction */
np->CCs = CC3BIT; /* show fraction negative */
else
if (num == 0) {
np->CCs = CC4BIT; /* show fraction zero */
np->msw = 0; /* save msw */
np->lsw = 0; /* save lsw */
np->exp = 0; /* save exp */
return; /* done if zero */
}
else
np->CCs = CC2BIT; /* show fraction positive */
// if ((t_int64)num <= DFSVAL) { /* see if > 0xff00000000000000 */
if ((t_int64)num >= DFSVAL) { /* see if > 0xff00000000000000 */
num >>= 4; /* shift over 4 bits */
ex += 1; /* bump exponent */
}
/* end normalization and rounding */
np->exp += ex; /* normalized, biased exp */
np->exp += 1; /* correct shift count */
if (((int32)(np->exp)) < 0) { /* check for exp neg underflow */
np->CCs |= CC1BIT; /* set CC1 & return zero */
np->msw = 0;
np->lsw = 0;
return;
}
/* if no exponent overflow merge exp & fraction & return */
if (((int32)(np->exp)) <= 0x7f) {
np->msw = (num >> 32); /* get msw */
np->lsw = num & 0xffffffff; /* get lsw */
ex = np->exp << 24; /* put exponent in bits 1-7 */
np->msw ^= ex; /* merge exponent & fraction */
return; /* CCs already set */
}
/* process overflow exponent */
np->CCs |= CC1BIT; /* set CC1 & return zero */
np->CCs |= CC4BIT; /* set CC4 & return zero */
/* do DP max value */
if (np->CCs & CC2BIT) { /* see if CC2 is set */
np->msw = 0x7fffffff; /* CC2=1 set exp overflow, pos frac */
np->lsw = 0xffffffff;
return;
}
np->msw = 0x80000000; /* CC2=0 set exp underflow, frac pos */
np->lsw = 0x00000001;
return;
}
/* normalize the memory value when adding number to zero */
uint32 s_normfw(uint32 mem, uint32 *cc) {
struct fpnum fpn = {0};
uint32 ret;
if (mem == 0) { /* make sure we have a number */
*cc = CC4BIT; /* set the cc's */
return 0; /* return zero */
}
sim_debug(DEBUG_EXP, &cpu_dev,
"NORMFW entry mem %08x\n", mem);
fpn.msw = mem; /* save upper 32 bits */
fpn.lsw = 0; /* clear lower 32 bits */
unpacks(&fpn); /* unpack number */
packs(&fpn); /* pack it back up */
ret = fpn.msw; /* return normalized number */
sim_debug(DEBUG_EXP, &cpu_dev,
"NORMFW return mem %08x result %08x CC's %08x\n", mem, ret, fpn.CCs);
/* return normalized number */
*cc = fpn.CCs; /* set the cc's */
return ret; /* return result */
}
/* add memory floating point number to register floating point number */
/* set CC1 if overflow/underflow */
uint32 s_adfw(uint32 reg, uint32 mem, uint32 *cc) {
uint32 mfrac, rfrac, frac, ret=0, oexp;
uint32 CC, sc, sign, expr, expm, exp;
#ifdef DO_NORMALIZE
struct fpnum fpn = {0};
#endif
*cc = 0; /* clear the CC'ss */
CC = 0; /* clear local CC's */
sim_debug(DEBUG_EXP, &cpu_dev,
// "ADFW entry mem %08x reg %08x result %08x\n", mem, reg, ret);
"ADFW entry mem %08x reg %08x\n", mem, reg);
/* process the memory operand value */
if (mem == 0) { /* test for zero operand */
ret = reg; /* return original register value */
#ifdef DO_NORMALIZE
if (ret == 0)
goto goout; /* nothing + nothing = nothing */
fpn.msw = ret; /* save upper 32 bits */
fpn.lsw = 0; /* clear lower 32 bits */
unpacks(&fpn); /* unpack number */
packs(&fpn); /* pack it back up */
ret = fpn.msw; /* return normalized number */
CC = fpn.CCs; /* set the cc's */
goto goout2; /* go set cc's and return */
#endif
goto goout; /* go set cc's and return */
}
expm = mem & EXMASK; /* extract exponent from operand */
@ -145,6 +442,18 @@ uint32 s_adfw(uint32 reg, uint32 mem, uint32 *cc) {
/* process the register operator value */
if (reg == 0) {
ret = mem; /* return original mem operand value */
#ifdef DO_NORMALIZE
if (ret == 0)
goto goout; /* nothing + nothing = nothing */
/* reg is 0 and mem is not zero, normalize mem */
fpn.msw = ret; /* save upper 32 bits */
fpn.lsw = 0; /* clear lower 32 bits */
unpacks(&fpn); /* unpack number */
packs(&fpn); /* pack it back up */
ret = fpn.msw; /* return normalized number */
CC = fpn.CCs; /* set the cc's */
goto goout2; /* go set cc's and return */
#endif
goto goout; /* go set cc's and return */
}
expr = reg & EXMASK; /* extract exponent from reg operand */
@ -157,6 +466,8 @@ uint32 s_adfw(uint32 reg, uint32 mem, uint32 *cc) {
rfrac = ((int32)rfrac) << 4; /* do sla 4 of fraction */
exp = expr - expm; /* subtract memory exponent from reg exponent */
sim_debug(DEBUG_EXP, &cpu_dev,
"ADFW2 exp calc expr %04x expm %04x exp %04x\n", expr, expm, exp);
if (exp & MSIGN) { /* test for negative */
/* difference is negative, so memory exponent is larger */
exp = NEGATE32(exp); /* make difference positive */
@ -167,7 +478,8 @@ uint32 s_adfw(uint32 reg, uint32 mem, uint32 *cc) {
/* difference is <= 6, so adjust to smaller value for add */
/* difference is number of 4 bit right shifts to do */
/* (exp >> 24) * 4 */
sc = exp >> (24 - 2); /* shift count down to do x4 the count */
//42220 sc = exp >> (24 - 2); /* shift count down to do x4 the count */
/*try*/ sc = (exp >> 24) * 4; /* shift count down to do x4 the count */
rfrac = ((int32)rfrac) >> sc;
oexp = expm; /* mem is larger exponent, save for final exponent add */
} else {
@ -181,11 +493,16 @@ uint32 s_adfw(uint32 reg, uint32 mem, uint32 *cc) {
/* difference is <= 6, so adjust to smaller value for add */
/* difference is number of 4 bit right shifts to do */
/* (exp >> 24) * 4 */
sc = exp >> (24 - 2); /* shift count down to do x4 the count */
mfrac = ((int32)mfrac) >> sc;
//42220 sc = exp >> (24 - 2); /* shift count down to do x4 the count */
/*try*/ sc = (exp >> 24) * 4; /* shift count down to do x4 the count */
frac = ((int32)mfrac) >> sc;
oexp = expr; /* reg is larger exponent, save for final exponent add */
}
sim_debug(DEBUG_EXP, &cpu_dev,
"ADFW3 after exp calc exp %04x sc %04x oexp %04x\n", exp, sc, oexp);
frac = rfrac + mfrac; /* add fractions */
sim_debug(DEBUG_EXP, &cpu_dev,
"ADFW4 frac calc rfrac %06x mfrac %06x frac %04x\n", rfrac, mfrac, frac);
if (frac == 0) {
/* return the zero value */
ret = frac; /* return zero to caller */
@ -290,6 +607,8 @@ goout:
else
CC |= CC2BIT; /* CC2 for greater than zero */
goout2:
sim_debug(DEBUG_EXP, &cpu_dev,
"ADFW return mem %08x reg %08x result %08x CC %08x\n", mem, reg, ret, CC);
/* return temp to destination reg */
*cc = CC; /* return CC's */
return ret; /* return result */
@ -300,6 +619,27 @@ uint32 s_sufw(uint32 reg, uint32 mem, uint32 *cc) {
return s_adfw(reg, NEGATE32(mem), cc);
}
/* normalize the memory value when adding number to zero */
t_uint64 s_normfd(t_uint64 mem, uint32 *cc) {
struct fpnum fpn = {0};
t_uint64 ret;
if (mem == 0) { /* make sure we have a number */
*cc = CC4BIT; /* set the cc's */
return 0; /* return zero */
}
fpn.msw = (mem >> 32); /* get msw */
fpn.lsw = mem & 0xffffffff; /* get lsw */
unpackd(&fpn); /* unpack number */
packd(&fpn); /* pack it back up */
ret = ((t_uint64)fpn.msw << 32) | fpn.lsw; /* make 64 bit num */
sim_debug(DEBUG_EXP, &cpu_dev,
"NORMFD return mem %016llx result %016llx CC's %08x\n", mem, ret, fpn.CCs);
/* return normalized number */
*cc = fpn.CCs; /* set the cc's */
return ret; /* return normalized result */
}
/* add memory floating point number to register floating point number */
/* set CC1 if overflow/underflow */
t_uint64 s_adfd(t_uint64 reg, t_uint64 mem, uint32 *cc) {
@ -308,11 +648,14 @@ t_uint64 s_adfd(t_uint64 reg, t_uint64 mem, uint32 *cc) {
*cc = 0; /* clear the CC'ss */
CC = 0; /* clear local CC's */
#ifndef DO_NORMALIZE
/* process the memory operand value */
if (mem == 0) { /* test for zero operand */
ret = reg; /* return original reg value */
goto goout; /* go set cc's and return */
}
#endif
/* separate mem dw into two 32 bit numbers */
/* mem value is not zero, so extract exponent and mantissa */
expm = (uint32)((mem & DEXMASK) >> 32); /* extract exponent */
@ -323,11 +666,13 @@ t_uint64 s_adfd(t_uint64 reg, t_uint64 mem, uint32 *cc) {
dblmem |= DEXMASK; /* adjust the fraction */
}
#ifndef DO_NORMALIZE
/* process the register operator value */
if (reg == 0) { /* see if reg value is zero */
ret = mem; /* return original mem operand value */
goto goout; /* go set cc's and return */
}
#endif
/* separate reg dw into two 32 bit numbers */
/* reg value is not zero, so extract exponent and mantissa */
expr = (uint32)((reg & DEXMASK) >> 32); /* extract exponent */

View File

@ -630,7 +630,7 @@ t_stat hsdp_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 */
@ -909,7 +909,7 @@ goout:
sim_debug(DEBUG_CMD, dptr,
"hsdp_srv STAR unit=%02x star %02x %02x %02x %02x\n",
unit, buf[0], buf[1], buf[2], buf[3]);
rezero:
//rezero:
sim_debug(DEBUG_DETAIL, dptr,
"hsdp_srv seek unit=%02x star %02x %02x %02x %02x\n",
unit, buf[0], buf[1], buf[2], buf[3]);

View File

@ -123,8 +123,8 @@ DEVICE iop_dev = {
NULL, NULL, &iop_reset, /* examine, deposit, reset */
NULL, NULL, NULL, /* boot, attach, detach */
/* dib ptr, dev flags, debug flags, debug */
&iop_dib, DEV_CHAN|DEV_DISABLE|DEV_DEBUG, 0, dev_debug,
// &iop_dib, DEV_CHAN|DEV_DIS|DEV_DISABLE|DEV_DEBUG, 0, dev_debug,
// &iop_dib, DEV_CHAN|DEV_DISABLE|DEV_DEBUG, 0, dev_debug,
&iop_dib, DEV_CHAN|DEV_DIS|DEV_DISABLE|DEV_DEBUG, 0, dev_debug,
// NULL, NULL, &iop_help, /* ?, ?, help */
// NULL, NULL, &iop_desc /* ?, ?, description */
};

View File

@ -50,6 +50,7 @@ const char *mfp_desc(DEVICE *dptr);
#define MFP_INCH 0x00 /* Initialize channel command */
#define MFP_INCH2 0xf0 /* Initialize channel command after start */
#define MFP_NOP 0x03 /* NOP command */
#define MFP_SID 0x80 /* MFP status command */
#define MFP_MSK 0xff /* Command mask */
/* Status held in u3 */
@ -182,6 +183,16 @@ uint16 mfp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
return 0; /* no status change */
break;
case MFP_SID: /* status ID command */
sim_debug(DEBUG_CMD, &mfp_dev, "mfp_startcmd %04x: Cmd SID\n", chan);
uptr->u5 = SNS_RDY|SNS_ONLN; /* status is online & ready */
uptr->u3 &= LMASK; /* leave only chsa */
uptr->u3 |= (cmd & MFP_MSK); /* save SID command */
sim_activate(uptr, 20); /* TRY 07-13-19 */
//@41 sim_activate(uptr, 40); /* 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",
@ -208,7 +219,7 @@ t_stat mfp_srv(UNIT *uptr)
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 */
if ((cmd != MFP_NOP) && (cmd != MFP_INCH2) && (cmd != MFP_SID)) { /* NOP, SID 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);
@ -218,7 +229,46 @@ t_stat mfp_srv(UNIT *uptr)
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);
sim_debug(DEBUG_CMD, &mfp_dev, "mfp_srv NOP chan %02x: chnend|devend\n", chsa);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
return SCPE_OK;
} else
/* 3 status wds are to be returned */
/* Wd 1 MMXXXXXX board model # assume 00 00 08 02*/
/* Wd 2 MMXXXXXX board firmware model # assume 00 00 08 02*/
/* Wd 3 MMXXXXXX board firmware revision # assume 00 00 00 14*/
if (cmd == MFP_SID) { /* send 12 byte Status ID data */
uint8 ch;
/* Word 0 */
ch = 0x00;
chan_write_byte(chsa, &ch); /* write byte 0 */
chan_write_byte(chsa, &ch); /* write byte 1 */
ch = 0x80;
chan_write_byte(chsa, &ch); /* write byte 2 */
ch = 0x02;
chan_write_byte(chsa, &ch); /* write byte 3 */
/* Word 1 */
ch = 0x00;
chan_write_byte(chsa, &ch); /* write byte 4 */
chan_write_byte(chsa, &ch); /* write byte 5 */
ch = 0x80;
chan_write_byte(chsa, &ch); /* write byte 6 */
ch = 0x02;
chan_write_byte(chsa, &ch); /* write byte 7 */
/* Word 2 */
ch = 0x00;
chan_write_byte(chsa, &ch); /* write byte 8 */
chan_write_byte(chsa, &ch); /* write byte 9 */
chan_write_byte(chsa, &ch); /* write byte 10 */
ch = 0x14;
chan_write_byte(chsa, &ch); /* write byte 11 */
uptr->u3 &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, &mfp_dev, "mfp_srv SID chan %02x: chnend|devend\n", chsa);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
return SCPE_OK;
} else

View File

@ -387,6 +387,10 @@ uint16 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
case 0x00: /* INCH command */
sim_debug(DEBUG_CMD, dptr, "start INCH command\n");
#ifdef DO_DYNAMIC_DEBUG
/* start debugging */
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ | DEBUG_TRAP);
#endif
sim_debug(DEBUG_CMD, dptr,
"mt_startcmd starting INCH cmd, chsa %04x MemBuf %08x cnt %04x\n",
chsa, chp->ccw_addr, chp->ccw_count);
@ -581,10 +585,8 @@ t_stat mt_srv(UNIT *uptr)
"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);
}
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ | DEBUG_TRAP);
#endif
if (len == 0) {
@ -636,11 +638,11 @@ t_stat mt_srv(UNIT *uptr)
/* set halfwords 16 & 17 to 5 as default retry count in inch data */
/* UTX uses this value to see if the device is a buffered tape processor */
/* they must be non-zero and equal to be BTP */
WMH(mema+(16*2),5); /* write left HW with count */
WMH(mema+(17*2),5); /* write right HW with count */
WMH(mema+(16<<1),5); /* write left HW with count */
WMH(mema+(17<<1),5); /* write right HW with count */
sim_debug(DEBUG_CMD, dptr,
"mt_srv cmd INCH chsa %04x addr %06x count %04x completed\n",
addr, mema, chp->ccw_count);
"mt_srv cmd INCH chsa %04x addr %06x count %04x completed INCH16 %08x\n",
addr, mema, chp->ccw_count, RMW(mema+(8<<2)));
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 */
@ -1118,9 +1120,11 @@ t_stat mt_srv(UNIT *uptr)
case 3:
uptr->CMD &= ~(MT_CMDMSK);
uptr->SNS &= ~SNS_LOAD; /* reset BOT */
uptr->SNS |= SNS_EOT; /* set EOT status */
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, &mta_dev, "Skip file got EOT sense %08x unit %02x\n", uptr->SNS, unit);
//BAD chan_end(addr, SNS_DEVEND|SNS_UNITCHK);
//*##*/ chan_end(addr, SNS_DEVEND|SNS_UNITCHK);
chan_end(addr, SNS_DEVEND|SNS_UNITEXP);
break;
}

View File

@ -274,10 +274,10 @@ scsi_type[] =
{"SD300", 9, 192, 32, 648, 1409, 0x40}, /*1 8828 300M 396674 sec */
{"SD700", 15, 192, 35, 648, 1546, 0x40}, /*2 8833 700M 797129 sec */
{"SD1200", 15, 192, 49, 648, 1931, 0x40}, /*3 8835 1200M 1389584 sec */
{"8820", 9, 192, 18, 324, 966, 0x40}, /*4 8820 150M */
{"8828", 9, 192, 36, 648, 966, 0x40}, /*5 8828 300M */
{"8833", 18, 192, 20, 648, 46725, 0x40}, /*6 8833 700M */
{"8835", 18, 192, 20, 648, 46725, 0x40}, /*7 8835 1200M */
{"8820", 9, 256, 18, 324, 967, 0x41}, /*4 8820 150M */
{"8821", 9, 256, 36, 648, 967, 0x41}, /*5 8828 300M */
{"8833", 18, 256, 20, 648, 46725, 0x41}, /*6 8833 700M */
{"8835", 18, 256, 20, 648, 46725, 0x41}, /*7 8835 1200M */
/* For UTX */
{NULL, 0}
};
@ -385,7 +385,7 @@ DIB sbb_dib = {
0x7600, /* 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 */
{0}, /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */
};
DEVICE sbb_dev = {
@ -531,8 +531,8 @@ t_stat scsi_srv(UNIT *uptr)
int i;
uint32 cap = CAP(type);
uint8 ch;
uint16 ssize = scsi_type[type].ssiz*4; /* Size of one sector in bytes */
int32 tstart = 0; /* Location of start of cyl/track/sect in data */
int32 ssize = scsi_type[type].ssiz*4; /* Size of one sector in bytes */
uint32 tstart = 0; /* Location of start of cyl/track/sect in data */
uint8 buf2[1024];
uint8 buf[1024];
@ -558,7 +558,7 @@ t_stat scsi_srv(UNIT *uptr)
uint32 mema; /* memory address */
// uint32 daws[8]; /* drive attribute registers */
// uint32 i, j;
uint32 i;
// uint32 i;
len = chp->ccw_count; /* INCH command count */
mema = chp->ccw_addr; /* get inch or buffer addr */
@ -858,8 +858,8 @@ t_stat scsi_srv(UNIT *uptr)
buf[4] = 0x81;
buf[8] = 0x91;
buf[12] = 0xf4;
buf[17] = HDS(type); /* # of heads */
buf[23] = SPT(type); /* Sect/track */
buf[17] = (uint8)HDS(type); /* # of heads */
buf[23] = (uint8)SPT(type); /* Sect/track */
// buf[27] = SPT(type); /* Sect/track */
for (i=0; i<cnt; i++) {
if (chan_write_byte(chsa, &buf[i])) {
@ -1051,7 +1051,7 @@ t_stat scsi_srv(UNIT *uptr)
}
/* ssize has sector size in bytes */
for (i=0; i<4; i++) {
ch = (ssize >> ((3-i)*8)) & 0xff;
ch = (((int32)ssize) >> ((3-i)*8)) & 0xff;
if (chan_write_byte(chsa, &ch)) {
/* we have error, bail out */
uptr->CMD &= LMASK; /* remove old status bits & cmd */
@ -1077,7 +1077,7 @@ t_stat scsi_srv(UNIT *uptr)
uint32 mema; /* memory address */
// uint32 daws[8]; /* drive attribute registers */
// uint32 i, j;
uint32 i;
int32 i;
uptr->SNS &= ~SNS_TCMD; /* show not presessing TCMD cmd chain */
len = chp->ccw_count; /* INCH command count */

View File

@ -20,12 +20,12 @@ set CPU 32/67 4M
; Set instruction trace history size
;;set cpu history=10000
; useful options
;set cpu debug=cmd;exp
;set cpu debug=exp
;set cpu debug=cmd;exp;irq;trap;xio
;set cpu debug=cmd;irq;trap;exp
;set cpu debug=irq;trap;exp;xio
;set cpu debug=irq;xio
;set cpu debug=irq;exp
;set cpu debug=irq;exp;trap
;
; RTC realtime clock
set RTC 50
@ -34,10 +34,25 @@ set RTC 50
;set RTC debug=cmd
;
; ITM interval timer
set ITM debug=cmd
;set ITM debug=cmd
;
; IOP
; IOP at channel 7e00
; useful options
;set iop debug=cmd;exp
;set iop debug=cmd
; make iop online
set iop enable
; set iop channel address
set iop0 dev=7e00
;
; MFP at channel 7e00
; useful options
;set mfp debug=cmd;exp
; make mfp online
;set mfp enable
; set mfp channel address
;set mfp0 dev=7e00
;set mfp0 dev=7600
;
; COM 8-Line
;set com debug=cmd;
@ -63,12 +78,18 @@ at lpr lprout
; CON Console
;set con debug=cmd;exp;detail
; useful options
;set con debug=cmd;exp;
; enable console
set con enable
; set console address
; set con0 enable
set con0 dev=7efc
; set con1 enable
set con1 dev=7efd
;set con debug=cmd;exp
;
; MTA Buffered tape processor
;set mta debug=cmd;exp;detail;data
; useful options
;set mta debug=cmd;detail;exp
;
; enable MTA to change channel
set mta enable

View File

@ -1,8 +1,62 @@
cd %~p0
; Set debug output
set debug -n sel.log
;set debug stderr
;
; CPU type and memory
; Bad on UTX
;set CPU 32/27 2M
;set CPU 32/27 4M
;set CPU 32/87 4M
set CPU 32/67 4M
;End of Bad
;set CPU 32/97 4M
;set CPU V6 4M
;set CPU 32/67 4M
set CPU 32/27 4M
;set CPU V6 8M
;set CPU V9 4M
;set CPU V9 8M
;
; CPU debug options
;set cpu debug=cmd;exp;inst;detail;trap;xio;irq
; Set instruction trace history size
;;set cpu history=10000
; useful options
;set cpu debug=exp
;set cpu debug=cmd;exp;irq;trap;xio
;set cpu debug=cmd;irq;trap;exp
;set cpu debug=irq;trap;exp;xio
;set cpu debug=irq;xio
;set cpu debug=irq;exp;trap
;
; RTC realtime clock
set RTC 50
;set RTC 60
; RTC debug options
;set RTC debug=cmd
;
; ITM interval timer
;set ITM debug=cmd
;
; IOP at channel 7e00
; useful options
;set iop debug=cmd;exp
;set iop debug=cmd
; make iop online
set iop enable
; set iop channel address
set iop0 dev=7e00
;
; MFP at channel 7e00
; useful options
;set mfp debug=cmd;exp
; make mfp online
;set mfp enable
; set mfp channel address
;set mfp0 dev=7e00
;set mfp0 dev=7600
;
; COM 8-Line
;set com debug=cmd;
set coml0 enable
set coml1 enable
set coml2 enable
@ -12,13 +66,130 @@ set coml5 enable
set coml6 enable
set coml7 enable
;
; Enable telnet sessions on port 4747
set comc enable
at comc 4747
;
; LPR
;set lpr debug=cmd;detail
set lpr enable
; LPR output file
at lpr lprout
;
; CON Console
;set con debug=cmd;exp;detail
; useful options
; enable console
set con enable
; set console address
; set con0 enable
set con0 dev=7efc
; set con1 enable
set con1 dev=7efd
;set con debug=cmd;exp
;
; MTA Buffered tape processor
;set mta debug=cmd;exp;detail;data
; useful options
;
; enable MTA to change channel
set mta enable
; set mta channel
set mta0 dev=1000
; Attach in/out tape files
;at mta0 mpxsdt.tap
;at mta0 nbctape.tap
;at mta0 utx21a1.tap
;at mta0 sim32sdt.tap
at mta0 diag.tap
set mta0 locked
at mta1 temptape.tap
at mta2 output.tap
;
; DMA disk processor II/UDP
; enable DMA to change channel
;set dma enable
; set disk chan to 0800
;set dma0 dev=800
; set disk type to MPX MH300
;set dma0 type=MH300
; set disk type to UTX 9346
;set dma0 type=9346
;set dma0 type=8155
;set dma0 type=8887
;set dma0 type=8148
;
; Attach diskfile
;at dma0 utx0disk
;at dma0 utx1disk
;at dma0 sim32disk
;at dma debug=cmd;exp;detail;data
;at dma0 diagdisk
; useful options
;set dma debug=cmd;exp
;set dma debug=exp;cmd;detail
;
; SDA SCFI disk processor
;set sda debug=cmd;exp;data;detail
; Attach diskfiles
;at sda0 diskfile4
;at sda1 diskfile5
;
; DPA high speed disk processor
; enable the HSDP to change channel
;set dpa enable
; set channel addr
;set dpa dev=800
; set disk type to UTX 8887
;set dpa0 type=8887
;
; Attach diskfiles
;at utxdsk.dsk
;at dpa0 utx0hsdp
;at dpa1 utx1hsdp
;
;set dpa debug=cmd;detail;exp
; useful options
;set dpa debug=cmd;exp
;
; set console switches
deposit CSW 0
;
;UTX boot tape options
;set GPR 7 to 0x00 to boot in multi-user mode
;set GPR 7 to 0x01 to prompt for unix filename
;set GPR 7 to 0x02 to boot in single user mode
;set GPR 7 to 0x10 to disable swapping and paging
;set GPR 7 to 0x20 to boot from device specified in GPR6
;set GPR 7 to 0x40 to allow progress messages on boot
;deposit BOOTR[7] 40
;deposit BOOTR[7] 52
;deposit BOOTR[7] 42
;deposit BOOTR[7] 2
;deposit BOOTR[6] 800
;deposit BOOTR[0] ffffffff
; Set register content at boot for SEL diagnostics
; uncomment next line to get diag loader prompt
;deposit bootr[0] ffffffff
deposit bootr[1] 0
deposit bootr[2] 0
;
; allow cpu idle
set cpu idle
; Set expect script for auto time entry on MPX at OPCOM prompt
;expect haltafter=20000
; wait for expected output from simulator, then enter this text
;expect "??" send " %DATE_MM%/%DATE_DD%/%DATE_YY%,%TIME_HH%:%TIME_MM%:%TIME_SS%\r"; GO
;
; Boot from disk
;bo dpa0
;bo dma0
;
; Go to simh on completion of script
expect "DOL>"^M
; Boot from mag tape
bo mta0
det all
rm temptape.tap