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:
parent
478b9b7bf4
commit
00d3dfefe7
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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]);
|
||||
|
||||
@ -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 */
|
||||
};
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user