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

SEL32: Update for simh merge

This commit is contained in:
James C. Bevier 2019-07-17 21:39:18 -04:00 committed by Richard Cornwell
parent e1b4fc55a4
commit 08ec8de37a
9 changed files with 105 additions and 265 deletions

View File

@ -78,12 +78,10 @@
/* Bits 16-23 - Channel address (0-127) */
/* Bits 24-31 - Device Sub address (0-255) */
int channels = MAX_CHAN; /* maximum number of channels */
uint32 channels = MAX_CHAN; /* maximum number of channels */
int subchannels = SUB_CHANS; /* maximum number of subchannel devices */
int irq_pend = 0; /* pending interrupt flag */
#define AMASK 0x00ffffff /* 24 bit mask */
extern uint32 M[]; /* our memory */
extern uint32 SPAD[]; /* CPU scratchpad memory */
extern uint32 CPUSTATUS; /* CPU status word */
@ -291,7 +289,7 @@ CHANP *find_chanp_ptr(uint16 chsa)
*/
int readfull(CHANP *chp, uint32 maddr, uint32 *word)
{
maddr &= AMASK; /* mask addr to 24 bits */
maddr &= MASK24; /* mask addr to 24 bits */
if (maddr > MEMSIZE) { /* see if mem addr > MEMSIZE */
chp->chan_status |= STATUS_PCHK; /* program check error */
return 1; /* show we have error */
@ -312,13 +310,13 @@ int readbuff(CHANP *chp)
uint32 addr = chp->ccw_addr; /* channel buffer address */
uint16 chan = get_chan(chp->chan_dev); /* our channel */
if ((addr & AMASK) > MEMSIZE) { /* see if memory address invalid */
if ((addr & MASK24) > MEMSIZE) { /* see if memory address invalid */
chp->chan_status |= STATUS_PCHK; /* bad, program check */
chp->chan_byte = BUFF_CHNEND; /* force channel end */
irq_pend = 1; /* and we have an interrupt */
return 1; /* done, with error */
}
addr &= AMASK; /* address only */
addr &= MASK24; /* address only */
addr >>= 2; /* byte to word address */
chp->chan_buf = M[addr]; /* get 4 bytes */
@ -342,13 +340,13 @@ int writebuff(CHANP *chp)
{
uint32 addr = chp->ccw_addr;
if ((addr & AMASK) > MEMSIZE) {
if ((addr & MASK24) > MEMSIZE) {
chp->chan_status |= STATUS_PCHK;
chp->chan_byte = BUFF_CHNEND;
irq_pend = 1;
return 1;
}
addr &= AMASK;
addr &= MASK24;
M[addr>>2] = chp->chan_buf;
return 0;
}
@ -388,7 +386,7 @@ loop:
/* TIC can't follow TIC or be first in command chain */
if (((word >> 24) & 0xf) == CMD_TIC) {
if (tic_ok) {
chp->chan_caw = word & AMASK; /* get new IOCD address */
chp->chan_caw = word & MASK24; /* get new IOCD address */
tic_ok = 0; /* another tic not allowed */
goto loop; /* restart the IOCD processing */
}
@ -407,7 +405,7 @@ loop:
docmd = 1; /* show we have a command */
}
/* Set up for this command */
chp->ccw_addr = word & AMASK; /* set the data address */
chp->ccw_addr = word & MASK24; /* set the data address */
readfull(chp, chp->chan_caw, &word); /* get IOCD WD 2 */
sim_debug(DEBUG_CMD, &cpu_dev, "load_ccw read ccw chan %02x caw %06x IOCD wd 2 %08x\n",
@ -855,7 +853,6 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */
UNIT *uptr;
uint32 chan_ivl; /* Interrupt Level ICB address for channel */
uint32 iocla; /* I/O channel IOCL address int ICB */
uint32 stata; /* I/O channel status location in ICB */
uint32 tempa, inta, spadent;
uint16 chsa; /* chan/subaddr */
CHANP *chp, *pchp; /* Channel prog pointers */
@ -1169,7 +1166,6 @@ t_stat chan_boot(uint16 chsa, DEVICE *dptr) {
int chan = get_chan(chsa);
DIB *dibp = dev_unit[chsa];
CHANP *chp = dibp->chan_prg;
int i,j;
sim_debug(DEBUG_EXP, &cpu_dev, "Channel Boot chan/device addr %x\n", chsa);
if (dibp == 0) /* if no channel or device, error */
@ -1341,7 +1337,7 @@ uint32 scan_chan(void) {
/* set up the devices configured into the simulator */
/* only devices with a DIB will be processed */
t_stat chan_set_devs() {
int i, j;
uint32 i, j;
for(i = 0; i < MAX_DEV; i++) {
dev_unit[i] = NULL; /* clear Device pointer array */

View File

@ -66,7 +66,7 @@ int32 rtc_lvl = 0x18; /* rtc interrupt level */
*/
/* clock is attached all the time */
/* defailt to 60 HZ RTC */
/* default to 60 HZ RTC */
UNIT rtc_unit = { UDATA (&rtc_srv, UNIT_ATT, 0), 16666, UNIT_ADDR(0x7F06)};
REG rtc_reg[] = {
@ -109,9 +109,8 @@ t_stat rtc_srv (UNIT *uptr)
INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */
irq_pend = 1; /* make sure we scan for int */
}
// rtc_unit.wait = sim_rtcn_calb (rtc_tps, TMR_RTC); /* calibrate */
// sim_activate (&rtc_unit, rtc_unit.wait); /* reactivate */
sim_activate (&rtc_unit, 16667); /* reactivate */
rtc_unit.wait = sim_rtcn_calb (rtc_tps, TMR_RTC); /* calibrate */
sim_activate_after (&rtc_unit, 1000000/rtc_tps);/* reactivate 16666 tics / sec */
return SCPE_OK;
}
@ -119,11 +118,12 @@ t_stat rtc_srv (UNIT *uptr)
/* ss = 1 - starting clock */
/* ss = 0 - stopping clock */
/* level = interrupt level */
void rtc_setup(uint ss, uint32 level)
void rtc_setup(uint32 ss, uint32 level)
{
uint32 val = SPAD[level+0x80]; /* get SPAD value for interrupt vector */
rtc_lvl = level; /* save the interrupt level */
uint32 addr = SPAD[0xf1] + (level<<2); /* vector address in SPAD */
rtc_lvl = level; /* save the interrupt level */
addr = M[addr>>2]; /* get the interrupt context block addr */
//fprintf(stderr, "rtc_setup called ss %x level %x SPAD %x icba %x\r\n", ss, level, val, addr);
if (ss == 1) { /* starting? */
@ -173,19 +173,13 @@ t_stat rtc_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
/* Interval Timer support */
int32 itm_pie = 0; /* itm pulse enable */
//int32 itm_tps = 38; /* itm 26041 ticks/sec = 38.4 us per tic */
///int32 itm_tps = 48; /* itm 26041 ticks/sec = 38.4 us per tic */
int32 itm_tps = 64; /* itm 26041 ticks/sec = 38.4 us per tic */
int32 itm_tick_size_x_100 = 3840; /* itm 26041 ticks/sec = 38.4 us per tic */
int32 itm_lvl = 0x5f; /* itm interrupt level */
int32 itm_cnt = 26041; /* value that we are downcounting */
int32 itm_run = 0; /* set when timer running */
t_stat itm_srv (UNIT *uptr);
t_stat itm_set_freq (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat itm_reset (DEVICE *dptr);
t_stat itm_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
#define TMR_ITM 2
/* Clock data structures
itm_dev Interval Timer ITM device descriptor
@ -193,24 +187,18 @@ t_stat itm_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
itm_reg Interval Timer ITM register list
*/
/* clock is attached all the time */
/* defailt to 60 HZ RTC */
//UNIT itm_unit = { UDATA (&itm_srv, UNIT_ATT, 0), 38, UNIT_ADDR(0x7F04)};
//UNIT itm_unit = { UDATA (&itm_srv, UNIT_ATT, 0), 48, UNIT_ADDR(0x7F04)};
//UNIT itm_unit = { UDATA (&itm_srv, UNIT_ATT, 0), 26042, UNIT_ADDR(0x7F04)};
UNIT itm_unit = { UDATA (&itm_srv, UNIT_ATT, 0), 26042, UNIT_ADDR(0x7F04)};
UNIT itm_unit = { UDATA (&itm_srv, UNIT_IDLE, 0), 26042, UNIT_ADDR(0x7F04)};
REG itm_reg[] = {
{ FLDATA (PIE, itm_pie, 0) },
{ DRDATA (TIME, itm_unit.wait, 32), REG_NZ + PV_LEFT },
{ DRDATA (TPS, itm_tps, 32), PV_LEFT + REG_HRO },
{ DRDATA (TICK_SIZE, itm_tick_size_x_100, 32), PV_LEFT + REG_HRO },
{ NULL }
};
MTAB itm_mod[] = {
{ MTAB_XTD|MTAB_VDV, 384, NULL, "38.4us",
{ MTAB_XTD|MTAB_VDV, 3840, NULL, "38.40us",
&itm_set_freq, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 768, NULL, "76.86us",
{ MTAB_XTD|MTAB_VDV, 7680, NULL, "76.80us",
&itm_set_freq, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "FREQUENCY", NULL,
NULL, &itm_show_freq, NULL },
@ -230,9 +218,8 @@ DEVICE itm_dev = {
sets an interrupt that invokes the clock counter.
*/
/* service clock signal from simulator */
/* for 38.4 us/tic we get 26041 ticks per second */
/* downcount the loaded value until zero and then cause interrupt */
/* service clock expiration from simulator */
/* cause interrupt */
t_stat itm_srv (UNIT *uptr)
{
// uint32 val = SPAD[itm_lvl+0x80]; /* get SPAD value for interrupt vector */
@ -241,26 +228,10 @@ t_stat itm_srv (UNIT *uptr)
//fprintf(stderr, "itm_srv level %x itm_pie %x wait %x spad %x icba %x\r\n",
// itm_lvl, itm_pie, itm_unit.wait, val, addr);
/* count down about 48 instructions per tick ~38.4 us */
/* we will be called once for each instructon */
itm_unit.wait -= 1; /* subtract 1 from wait count */
if (itm_unit.wait > 0)
return SCPE_OK; /* not time yet */
itm_unit.wait = itm_tps; /* reset wait count */
if (itm_run) { /* see if timer running */
itm_cnt--; /* down count by one */
if ((itm_cnt == 0) && itm_pie) { /* see if reached 0 yet */
// if (itm_cnt == 0) { /* see if reached 0 yet */
//fprintf(stderr, "itm_srv REQ itm_pie %x wait %x itm_cnt %x\r\n", itm_pie, itm_unit.wait, itm_cnt);
INTS[itm_lvl] |= INTS_REQ; /* request the interrupt on zero value */
irq_pend = 1; /* make sure we scan for int */
}
}
#if 0
itm_unit.wait = sim_rtcn_calb (itm_tps, TMR_ITM); /* calibrate */
sim_activate (&itm_unit, itm_unit.wait); /* reactivate */
#endif
if (itm_pie) { /* interrupt enabled? */
INTS[itm_lvl] |= INTS_REQ; /* request the interrupt on zero value */
irq_pend = 1; /* make sure we scan for int */
}
return SCPE_OK;
}
@ -282,26 +253,23 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
// addr = M[addr>>2]; /* get the interrupt context block addr */
//fprintf(stderr, "itm_rdwr called ss %x level %x SPAD %x icba %x\r\n", ss, level, val, addr);
//fprintf(stderr, "itm_rdwr called cmd %x count %x (%d) level %x return cnt %x (%d)\r\n",
// cmd, cnt, cnt, level, itm_cnt, itm_cnt);
// cmd, cnt, cnt, level);
switch (cmd) {
case 0x39: /* load timer with new value and start*/
if (cnt < 0)
cnt = 26042; /* TRY ??*/
itm_cnt = cnt; /* load timer with value from user to down count */
itm_run = 1; /* start timer */
sim_activate_after_abs_d (&itm_unit, ((double)cnt * itm_tick_size_x_100) / 100.0);/* start timer with value from user */
return 0; /* does not matter, no value returned */
case 0x60: /* read and stop timer */
temp = itm_cnt; /* get timer value and stop timer */
itm_run = 0; /* stop timer */
// itm_cnt = 0; /* reset with timer value from user to down count */
temp = (uint32)(100.0 * sim_activate_time_usecs (&itm_unit) / itm_tick_size_x_100);/* get timer value and stop timer */
sim_cancel (&itm_unit);
return temp; /* return current count value */
case 0x79: /* read the current timer value */
temp = itm_cnt; /* get timer value, load new value and start timer */
itm_cnt = cnt; /* load timer with value from user to down count */
itm_run = 1; /* start timer */
temp = (uint32)(100.0 * sim_activate_time_usecs (&itm_unit) / itm_tick_size_x_100); /* get timer value, load new value and start timer */
sim_activate_after_abs_d (&itm_unit, ((double)cnt * itm_tick_size_x_100) / 100.0);/* start timer to fire after cnt ticks */
return temp; /* return current count value */
case 0x40: /* read the current timer value */
return itm_cnt; /* return current count value */
return (uint32)(100.0 * sim_activate_time_usecs (&itm_unit) / itm_tick_size_x_100);/* return current count value */
break;
}
return 0; /* does not matter, no value returned */
@ -311,7 +279,7 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
/* ss = 1 - clock interrupt enabled */
/* ss = 0 - clock interrupt disabled */
/* level = interrupt level */
void itm_setup(uint ss, uint32 level)
void itm_setup(uint32 ss, uint32 level)
{
itm_lvl = level; /* save the interrupt level */
// fprintf(stderr, "itm_setup called ss %x level %x\r\n", ss, level);
@ -319,9 +287,7 @@ void itm_setup(uint ss, uint32 level)
INTS[level] |= INTS_ENAB; /* make sure enabled */
SPAD[level+0x80] |= SINT_ENAB; /* in spad too */
INTS[level] |= INTS_REQ; /* request the interrupt */
itm_cnt = 26042; /* start with 1 sec */
itm_run = 0; /* not running yet */
/// sim_activate(&itm_unit, 48); /* start us off */
sim_cancel (&itm_unit); /* not running yet */
} else {
INTS[level] &= ~INTS_ENAB; /* make sure disabled */
SPAD[level+0x80] &= ~SINT_ENAB; /* in spad too */
@ -335,12 +301,7 @@ t_stat itm_reset (DEVICE *dptr)
// int intlev = 0x5f; /* interrupt level for itm */
//fprintf(stderr, "itm_reset called\r\n");
itm_pie = 0; /* disable pulse */
itm_cnt = 26042; /* start with 1 sec */
itm_run = 0; /* not running yet */
#if 0
rtc_unit.wait = sim_rtcn_init (itm_unit.wait, TMR_ITM); /* initialize clock calibration */
sim_activate (&itm_unit, itm_unit.wait); /* activate unit */
#endif
sim_cancel (&itm_unit); /* not running yet */
return SCPE_OK;
}
@ -349,9 +310,9 @@ t_stat itm_set_freq (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (cptr) /* if chars, bad */
return SCPE_ARG; /* ARG error */
if ((val != 384) && (val != 768))
if ((val != 3840) && (val != 7680))
return SCPE_IERR; /* scope error */
itm_tps = val/10; /* set the new frequency */
itm_tick_size_x_100 = val; /* set the new frequency */
return SCPE_OK; /* we done */
}
@ -359,7 +320,7 @@ t_stat itm_set_freq (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
t_stat itm_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
/* print the cirrent frequency setting */
fprintf (st, (itm_tps == 38)? "38.4us": "76.8us");
fprintf (st, "%0.2fus", (itm_tick_size_x_100 / 100.0));
return SCPE_OK;
}
#endif

View File

@ -245,7 +245,7 @@ MTAB com_mod[] = {
};
UNIT com_unit[] = {
{UDATA(&comi_srv, UNIT_ATTABLE, 0), COM_WAIT, UNIT_ADDR(0x0000)}, /* 0 */
{UDATA(&comi_srv, UNIT_ATTABLE|UNIT_IDLE, 0), COM_WAIT, UNIT_ADDR(0x0000)}, /* 0 */
};
//DIB com_dib = {NULL, com_startcmd, NULL, NULL, com_ini, com_unit, com_chp, COM_UNITS, 0x0f, 0x7e00, 0, 0, 0};
@ -293,7 +293,7 @@ DEVICE com_dev = {
coml_mod COM modifieers list
*/
#define UNIT_COML UNIT_ATTABLE|UNIT_DISABLE|UNIT_ATT
#define UNIT_COML UNIT_ATTABLE|UNIT_DISABLE|UNIT_ATT|UNIT_IDLE
/* channel program information */
CHANP coml_chp[COM_LINES*2] = {0};
@ -637,7 +637,6 @@ t_stat comi_srv(UNIT *uptr)
uint16 chsa = GET_UADDR(uptr->u3); /* get channel/sub-addr */
int cmd = uptr->u3 & 0xff;
uint32 cln = (uptr - coml_unit) & 0x7; /* use line # 0-7 for 8-15 */
UNIT *comlp;
ln = uptr - com_unit; /* line # */
if ((com_unit[COMC].flags & UNIT_ATT) == 0){ /* attached? */

View File

@ -250,6 +250,7 @@ extern DEBTAB dev_debug[];
#define DSEXT16(x) (x&0x8000?(l_uint64)(((l_uint64)x&RMASK)|D48LMASK):(t_uint64)x)
/* sign extend 32 bit value to uint64 */
#define DSEXT32(x) (x&0x8000?(l_uint64)(((l_uint64)x&D32RMASK)|D32LMASK):(t_uint64)x)
#define NEGATE32(val) ((~val) + 1) /* negate a value 16/32/64 bits */
#define UNIT_V_MODEL (UNIT_V_UF + 0)
#define UNIT_MODEL (7 << UNIT_V_MODEL)
@ -348,3 +349,7 @@ extern DEBTAB dev_debug[];
#define INTS_EXTL 0x08000000 /* IOP/RTOM ext interrupt if set, I/O if not set (copy of SPAD) */
#define INTS_REQ 0x04000000 /* Interrupt is requesting */
/* Rename of global PC variable to avoid namespace conflicts on some platforms */
#define PC PC_Global

View File

@ -41,7 +41,7 @@ extern uint32 SPAD[]; /* cpu SPAD memory */
#define GET_TYPE(x) ((UNIT_TYPE & (x)) >> UNIT_V_TYPE)
#define SET_TYPE(x) (UNIT_TYPE & ((x) << UNIT_V_TYPE))
#define UNIT_DISK UNIT_ATTABLE | UNIT_DISABLE | UNIT_ROABLE | UNIT_FIX
#define UNIT_DISK UNIT_ATTABLE | UNIT_DISABLE | UNIT_ROABLE | UNIT_FIX | UNIT_IDLE
/* INCH command information */
/*
@ -204,7 +204,7 @@ struct ddata_t
/* disk definition structure */
struct disk_t
{
char *name; /* Device ID Name */
const char *name; /* Device ID Name */
uint32 taus; /* total allocation units */
uint16 bms; /* bit map size */
uint16 nhds; /* Number of heads */
@ -499,7 +499,7 @@ dosns:
case DSK_INCH: /* INCH 0x00 */
{
uint32 mema; /* memory address */
int i;
uint32 i;
UNIT *up = dptr->units; /* first unit for this device */
sim_debug(DEBUG_CMD, dptr, "disk_startcmd starting inch cmd addr %x u4 %x\n", addr, uptr->u4);
/* u4 has IOCD word 1 contents. For the disk processor it contains */
@ -561,7 +561,7 @@ t_stat disk_srv(UNIT * uptr)
int cmd = uptr->u3 & DSK_CMDMSK;
int type = GET_TYPE(uptr->flags);
int count = data->count;
int trk, cyl;
uint32 trk, cyl;
int unit = (uptr - dptr->units);
int i;
uint8 ch;

View File

@ -158,7 +158,7 @@ uint32 s_adfw(uint32 reg, uint32 mem, uint32 *cc) {
exp = expr - expm; /* subtract memory exponent from reg exponent */
if (exp & MSIGN) { /* test for negative */
/* difference is negative, so memory exponent is larger */
exp = -exp; /* make difference positive */
exp = NEGATE32(exp); /* make difference positive */
if (exp > 0x06000000) { /* test for difference > 6 */
ret = mem; /* assume 0 and return original mem operand value */
goto goout; /* go set cc's and return */
@ -237,7 +237,6 @@ uint32 s_adfw(uint32 reg, uint32 mem, uint32 *cc) {
if ((sign == 3 && (exp & MSIGN) == 0) ||
(sign == 0 && (exp & MSIGN) != 0)) {
/* we have exponent overflow from addition */
AROVFLO:
CC |= CC4BIT; /* set CC4 for exponent overflow */
ARUNFLO:
/* we have exponent underflow from addition */
@ -295,7 +294,7 @@ goout2:
/* subtract memory floating point number from register floating point number */
uint32 s_sufw(uint32 reg, uint32 mem, uint32 *cc) {
return s_adfw(reg, -mem, cc);
return s_adfw(reg, NEGATE32(mem), cc);
}
/* add memory floating point number to register floating point number */
@ -340,7 +339,7 @@ t_uint64 s_adfd(t_uint64 reg, t_uint64 mem, uint32 *cc) {
sign = expr; /* save register exponent */
if (exp & MSIGN) {
/* exponent difference is negative */
exp = -exp; /* make exponent difference positive */
exp = NEGATE32(exp); /* make exponent difference positive */
if (exp > 0x0d000000) {
/* shift count is > 13, so return operand and set cc's */
ret = mem; /* return the original mem operand */
@ -435,7 +434,7 @@ DUNFLO:
/* subtract memory floating point number from register floating point number */
t_uint64 s_sufd(t_uint64 reg, t_uint64 mem, uint32 *cc) {
return s_adfd(reg, -mem, cc);
return s_adfd(reg, NEGATE32(mem), cc);
}
/* convert from 32 bit float to 32 bit integer */
@ -445,7 +444,7 @@ uint32 s_fixw(uint32 fltv, uint32 *cc) {
uint32 neg = 0; /* clear neg flag */
if (fltv & MSIGN) { /* check for negative */
fltv = -fltv; /* make src positive */
fltv = NEGATE32(fltv); /* make src positive */
neg = 1; /* set neg val flag */
} else {
if (fltv == 0) {
@ -468,7 +467,7 @@ uint32 s_fixw(uint32 fltv, uint32 *cc) {
temp = 0x7fffffff; /* too big, set to max value */
goto OVFLO; /* go set CC's */
}
sc = (-temp2 * 4); /* pos shift cnt * 4 */
sc = (NEGATE32(temp2) * 4); /* pos shift cnt * 4 */
fltv >>= sc; /* do 4 bit shifts */
/* see if overflow to neg */
/* set CC1 for overflow */
@ -479,7 +478,7 @@ uint32 s_fixw(uint32 fltv, uint32 *cc) {
}
/* see if original value was negative */
if (neg)
fltv = -fltv; /* put back to negative */
fltv = NEGATE32(fltv); /* put back to negative */
temp = fltv; /* return integer value */
/* come here to set cc's and return */
/* temp has return value */
@ -510,12 +509,12 @@ UNFLO:
/* convert from 32 bit integer to 32 bit float */
/* No overflow (CC1) can be generated */
uint32 s_fltw(uint32 intv, uint32 *cc) {
uint32 CC = 0, temp, temp2;
uint32 CC = 0, temp;
uint32 neg = 0; /* zero sign flag */
uint32 sc = 0; /* zero shift count */
if (intv & MSIGN) {
intv = -intv; /* make src positive */
intv = NEGATE32(intv); /* make src positive */
neg = 1; /* set neg flag */
} else {
if (intv == 0) { /* see if zero */
@ -535,10 +534,10 @@ uint32 s_fltw(uint32 intv, uint32 *cc) {
temp >>= 1; /* one more zeros */
sc >>= 2; /* normalize radix */
sc -= 72; /* make excess 64 notation */
sc = -sc; /* make positive */
sc = NEGATE32(sc); /* make positive */
temp = (temp >> 8) | (sc << 24); /* merge exp with fraction */
if (neg) /* was input negative */
temp = -temp; /* make neg again */
temp = NEGATE32(temp); /* make neg again */
/* come here to set cc's and return */
/* temp has return value */
setcc:
@ -556,12 +555,12 @@ setcc:
/* convert from 64 bit double to 64 bit integer */
/* set CC1 if overflow/underflow exception */
t_uint64 s_fixd(t_uint64 dblv, uint32 *cc) {
uint32 temp, temp2, CC = 0, neg = 0, sc = 0;
uint32 temp2, CC = 0, neg = 0, sc = 0;
t_uint64 dest;
/* neg and CC flags already set to zero */
if ((t_int64)dblv < 0) {
dblv = -dblv; /* make src positive */
dblv = NEGATE32(dblv); /* make src positive */
neg = 1; /* set neg val flag */
} else {
if (dblv == 0) {
@ -584,7 +583,7 @@ t_uint64 s_fixd(t_uint64 dblv, uint32 *cc) {
dest = 0x7fffffffffffffffll; /* too big, set max */
goto DOVFLO; /* go set CC's */
}
sc = (-temp2 * 4); /* pos shift cnt * 4 */
sc = (NEGATE32(temp2) * 4); /* pos shift cnt * 4 */
dblv >>= sc; /* do 4 bit shifts */
/* see if overflow to neg */
/* FIXME set CC1 for overflow? */
@ -595,7 +594,7 @@ t_uint64 s_fixd(t_uint64 dblv, uint32 *cc) {
}
/* see if original values was negative */
if (neg)
dblv = -dblv; /* put back to negative */
dblv = NEGATE32(dblv); /* put back to negative */
dest = dblv; /* return integer value */
dodblcc:
/* dest has return value */
@ -629,7 +628,7 @@ t_uint64 s_fltd(t_uint64 intv, uint32 *cc) {
uint32 CC = 0; /* n0 CC's yet */
if (intv & DMSIGN) {
intv = -intv; /* make src positive */
intv = NEGATE32(intv); /* make src positive */
neg = 1; /* set neg flag */
} else {
if (intv == 0) { /* see if zero */
@ -647,10 +646,10 @@ t_uint64 s_fltd(t_uint64 intv, uint32 *cc) {
temp <<= 4; /* zero, shift in next nibble */
sc++; /* incr shift count */
}
sc = (-sc + 78); /* normalized, make into excess 64 */
sc = (NEGATE32(sc) + 78); /* normalized, make into excess 64 */
temp = (sc << 56) | temp; /* merge exponent into fraction */
if (neg) /* was input negative */
temp = -temp; /* make neg again */
temp = NEGATE32(temp); /* make neg again */
/* come here to set cc's and return */
/* temp has return dbl value */
setcc:
@ -674,7 +673,7 @@ uint32 s_mpfw(uint32 reg, uint32 mem, uint32 *cc) {
/* process operator */
sign = mem; /* save original value for sign */
if (mem & MSIGN) { /* check for negative */
mem = -mem; /* make mem positive */
mem = NEGATE32(mem); /* make mem positive */
} else {
if (mem == 0) {
temp = 0; /* return zero */
@ -689,7 +688,7 @@ uint32 s_mpfw(uint32 reg, uint32 mem, uint32 *cc) {
/* process operand */
if (reg & MSIGN) { /* check for negative */
sign ^= reg; /* adjust sign */
reg = -reg; /* make reg positive */
reg = NEGATE32(reg); /* make reg positive */
} else {
if (reg == 0) {
temp = 0; /* return zero */
@ -705,11 +704,10 @@ uint32 s_mpfw(uint32 reg, uint32 mem, uint32 *cc) {
dtemp = (t_uint64)mem * (t_uint64)reg; /* multiply fractions */
dtemp <<= 1; /* adjust fraction */
if (sign & MSIGN)
dtemp = -dtemp; /* if negative, negate fraction */
dtemp = NEGATE32(dtemp); /* if negative, negate fraction */
/* normalize the value in dtemp and put exponent into expr */
dtemp = s_nord(dtemp, &expr); /* normalize fraction */
temp -= 0x80; /* resize exponent */
RROUND:
temp2 = (uint32)(dtemp >> 32); /* get upper 32 bits */
if ((int32)temp2 >= 0x7fffffc0) /* check for special rounding */
goto RRND2; /* no special handling */
@ -795,7 +793,7 @@ uint32 s_dvfw(uint32 reg, uint32 mem, uint32 *cc) {
/* process operator */
sign = mem; /* save original value for sign */
if (mem & MSIGN) { /* check for negative */
mem = -mem; /* make mem positive */
mem = NEGATE32(mem); /* make mem positive */
} else {
if (mem == 0) { /* check for divide by zero */
goto DOVFLO; /* go process overflow */
@ -809,7 +807,7 @@ uint32 s_dvfw(uint32 reg, uint32 mem, uint32 *cc) {
/* process operand */
if (reg & MSIGN) { /* check for negative */
sign ^= reg; /* adjust sign */
reg = -reg; /* make reg positive */
reg = NEGATE32(reg); /* make reg positive */
} else {
if (reg == 0) {
temp = 0; /* return zero */
@ -827,7 +825,7 @@ uint32 s_dvfw(uint32 reg, uint32 mem, uint32 *cc) {
temp2 >>= 3; /* shift out excess bits */
temp2 <<= 3; /* replace with zero bits */
if (sign & MSIGN)
temp2 = -temp2; /* if negative, negate fraction */
temp2 = NEGATE32(temp2); /* if negative, negate fraction */
/* normalize the result in temp and put exponent into expr */
temp2 = s_nor(temp2, &expr); /* normalize fraction */
temp += 1; /* adjust exponent */
@ -909,14 +907,14 @@ setcc:
/* multiply register double by memory double */
t_uint64 s_mpfd(t_uint64 reg, t_uint64 mem, uint32 *cc) {
t_uint64 tr1, tr2, tl1, tl2, dblreg, ret;
t_uint64 tr1, tr2, tl1, tl2, dblreg;
uint32 CC = 0, temp, temp2, sign = 0;
uint32 expm, expr;
t_uint64 dtemp1, dtemp2;
/* process operator */
if (mem & DMSIGN) { /* check for negative */
mem = -mem; /* make mem positive */
mem = NEGATE32(mem); /* make mem positive */
sign = 1; /* save original value for sign */
} else {
if (mem == 0) { /* check for zero */
@ -935,7 +933,7 @@ t_uint64 s_mpfd(t_uint64 reg, t_uint64 mem, uint32 *cc) {
/* process operand */
if (reg & DMSIGN) { /* check for negative */
sign ^= 1; /* adjust sign */
reg = -reg; /* make reg positive */
reg = NEGATE32(reg); /* make reg positive */
} else {
if (reg == 0) {
dblreg = 0; /* return zero */
@ -968,12 +966,11 @@ t_uint64 s_mpfd(t_uint64 reg, t_uint64 mem, uint32 *cc) {
dtemp2 += dblreg; /* add other partial product */
dblreg = (t_int64)dtemp2 << 1; /* position for normalize */
if (sign) /* see if negative */
dblreg = -dblreg; /* make negative */
dblreg = NEGATE32(dblreg); /* make negative */
/* normalize the value in dblreg and put exponent into expr */
dblreg = s_nord(dblreg, &expr); /* normalize fraction */
if (expr != 0x40) /* is result normalized */
dblreg &= 0xfffffffffffff87fll; /* no, adjust value */
DRND1:
if (dblreg == DMSIGN) { /* check for neg zero */
dblreg = DNORMASK; /* correct the value */
expr++; /* adjust exponent too */
@ -1041,14 +1038,14 @@ setcc:
/* divide register double by memory double */
t_uint64 s_dvfd(t_uint64 reg, t_uint64 mem, uint32 *cc) {
t_uint64 tr1, tr2, tl1, tl2, dblreg, ret;
t_uint64 tr1, tr2, tl1, tl2, dblreg;
uint32 CC = 0, temp, temp2, sign = 0;
uint32 expm, expr;
t_uint64 dtemp1, dtemp2;
/* process operator */
if (mem & DMSIGN) { /* check for negative */
mem = -mem; /* make mem positive */
mem = NEGATE32(mem); /* make mem positive */
sign = 1; /* save original value for sign */
} else {
if (mem == 0) { /* check for divide by zero */
@ -1068,7 +1065,7 @@ t_uint64 s_dvfd(t_uint64 reg, t_uint64 mem, uint32 *cc) {
/* process operand */
if (reg & DMSIGN) { /* check for negative */
sign ^= 1; /* adjust sign */
reg = -reg; /* make reg positive */
reg = NEGATE32(reg); /* make reg positive */
} else {
if (reg == 0) {
dblreg = 0; /* return zero */
@ -1120,10 +1117,9 @@ t_uint64 s_dvfd(t_uint64 reg, t_uint64 mem, uint32 *cc) {
dblreg &= 0xffffffffffffffe0; /* fixup quotient */
/* exp in temp */
if (sign) /* neg input */
dblreg = -dblreg; /* yes, negate result */
dblreg = NEGATE32(dblreg); /* yes, negate result */
/* normalize the value in dblreg and put exponent into expr */
dblreg = s_nord(dblreg, &expr); /* normalize fraction */
DRND1:
if (dblreg == DMSIGN) { /* check for neg zero */
dblreg = DNORMASK; /* correct the value */
expr++; /* adjust exponent too */

View File

@ -97,7 +97,7 @@ MTAB iop_mod[] = {
};
UNIT iop_unit[] = {
{UDATA(iop_srv, UNIT_ATT, 0), 0, UNIT_ADDR(0x7E00)}, /* Channel controlller */
{UDATA(iop_srv, UNIT_ATT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x7E00)}, /* Channel controlller */
};
//DIB iop_dib = {NULL, iop_startcmd, NULL, NULL, NULL, iop_ini, iop_unit, iop_chp, NUM_UNITS_IOP, 0xff, 0x7e00,0,0,0};

View File

@ -39,7 +39,7 @@
#include "sim_tape.h"
extern t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
extern t_stat show_dev_addr(FILE *st, UNIT * uptr, int32 v, CONST void *desc);
extern t_stat show_dev_addr(FILE *st, UNIT *uptr, int32 v, CONST void *desc);
extern void chan_end(uint16 chan, uint8 flags);
extern int chan_read_byte(uint16 chan, uint8 *data);
extern int chan_write_byte(uint16 chan, uint8 *data);
@ -333,83 +333,6 @@ MTAB mt_mod[] = {
{0}
};
#ifdef DEFINED_IN_SIM_DEFS_H
/* Unit data structure from sim_defs.h
Parts of the unit structure are device specific, that is, they are
not referenced by the simulator control package and can be freely
used by device simulators. Fields starting with 'buf', and flags
starting with 'UF', are device specific. The definitions given here
are for a typical sequential device.
*/
struct UNIT {
UNIT *next; /* next active */
t_stat (*action)(UNIT *up); /* action routine */
char *filename; /* open file name */
FILE *fileref; /* file reference */
void *filebuf; /* memory buffer */
uint32 hwmark; /* high water mark */
int32 time; /* time out */
uint32 flags; /* flags */
uint32 dynflags; /* dynamic flags */
t_addr capac; /* capacity */
t_addr pos; /* file position */
void (*io_flush)(UNIT *up); /* io flush routine */
uint32 iostarttime; /* I/O start time */
int32 buf; /* buffer */
int32 wait; /* wait */
int32 u3; /* device specific */
int32 u4; /* device specific */
int32 u5; /* device specific */
int32 u6; /* device specific */
void *up7; /* device specific */
void *up8; /* device specific */
uint16 us9; /* device specific */
uint16 us10; /* device specific */
void *tmxr; /* TMXR linkage */
t_bool (*cancel)(UNIT *);
double usecs_remaining; /* time balance for long delays */
char *uname; /* Unit name */
#ifdef SIM_ASYNCH_IO
void (*a_check_completion)(UNIT *);
t_bool (*a_is_active)(UNIT *);
UNIT *a_next; /* next asynch active */
int32 a_event_time;
ACTIVATE_API a_activate_call;
/* Asynchronous Polling control */
/* These fields should only be referenced when holding the sim_tmxr_poll_lock */
t_bool a_polling_now; /* polling active flag */
int32 a_poll_waiter_count; /* count of polling threads */
/* waiting for this unit */
/* Asynchronous Timer control */
double a_due_time; /* due time for timer event */
double a_due_gtime; /* due time (in instructions) for timer event */
double a_usec_delay; /* time delay for timer event */
#endif /* SIM_ASYNCH_IO */
};
/* Unit flags */
#define UNIT_V_UF_31 12 /* dev spec, V3.1 */
#define UNIT_V_UF 16 /* device specific */
#define UNIT_V_RSV 31 /* reserved!! */
#define UNIT_ATTABLE 0000001 /* attachable */
#define UNIT_RO 0000002 /* read only */
#define UNIT_FIX 0000004 /* fixed capacity */
#define UNIT_SEQ 0000010 /* sequential */
#define UNIT_ATT 0000020 /* attached */
#define UNIT_BINK 0000040 /* K = power of 2 */
#define UNIT_BUFABLE 0000100 /* bufferable */
#define UNIT_MUSTBUF 0000200 /* must buffer */
#define UNIT_BUF 0000400 /* buffered */
#define UNIT_ROABLE 0001000 /* read only ok */
#define UNIT_DISABLE 0002000 /* disable-able */
#define UNIT_DIS 0004000 /* disabled */
#define UNIT_IDLE 0040000 /* idle eligible */
#endif /* DEFINED_IN_SIM_DEFS_H */
UNIT mta_unit[] = {
/* Unit data layout for MT devices */
// {UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1000)}, /* 0 */
@ -421,7 +344,7 @@ UNIT mta_unit[] = {
NULL, /* void *filebuf */ /* memory buffer */
0, /* uint32 hwmark */ /* high water mark */
0, /* int32 time */ /* time out */
UNIT_MT, /* uint32 flags */ /* flags */
UNIT_MT|UNIT_IDLE, /* uint32 flags */ /* flags */
0, /* uint32 dynflags */ /* dynamic flags */
0, /* t_addr capac */ /* capacity */
0, /* t_addr pos */ /* file position */
@ -442,55 +365,15 @@ UNIT mta_unit[] = {
0, /* double usecs_remaining */ /* time balance for long delays */
NULL, /* char *uname */ /* Unit name */
},
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1001)}, /* 1 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1002)}, /* 2 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1003)}, /* 3 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1004)}, /* 4 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1005)}, /* 5 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1006)}, /* 6 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1007)}, /* 7 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1001)}, /* 1 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1002)}, /* 2 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1003)}, /* 3 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1004)}, /* 4 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1005)}, /* 5 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1006)}, /* 6 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1007)}, /* 7 */
};
#if DEFINED_IN_SEL32_DEFS_H
/* Device information block */
typedef struct dib {
/* Pre Start I/O */
uint8 (*pre_io)(UNIT *uptr, uint16 chan);
/* Start a command */
uint8 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd);
/* Halt I/O */
uint8 (*halt_io)(UNIT *uptr);
/* Test I/O */
uint8 (*test_io)(UNIT *uptr);
/* Post I/O */
uint8 (*post_io)(UNIT *uptr);
/* Controller init */
void (*dev_ini)(UNIT *, t_bool); /* init function */
UNIT *units; /* Pointer to units structure */
CHANP *chan_prg; /* Pointer to channel program */
uint8 numunits; /* number of units */
uint8 mask; /* device mask */
uint16 chan_addr; /* parent channel address */
uint32 chan_fifo_in; /* fifo input index */
uint32 chan_fifo_out; /* fifo output index */
uint32 chan_fifo[FIFO_SIZE]; /* interrupt status fifo for each channel */
} DIB;
/* CHAN 0x7F000000 UNIT 0x00ff0000 */
#define DEV_V_ADDR DEV_V_UF /* Pointer to device address (16) */
#define DEV_V_DADDR (DEV_V_UF + 8) /* Device address */
#define DEV_ADDR_MASK (0x7f << DEV_V_DADDR) /* 24 bits shift */
#define DEV_V_UADDR (DEV_V_UF) /* Device address in Unit */
#define DEV_UADDR (1 << DEV_V_UADDR)
#define GET_DADDR(x) (0x7f & ((x) >> DEV_V_ADDR))
#define DEV_ADDR(x) ((x) << DEV_V_ADDR)
#define UNIT_V_ADDR 16
#define UNIT_ADDR_MASK (0x7fff << UNIT_V_ADDR)
#define GET_UADDR(x) ((UNIT_ADDR_MASK & x) >> UNIT_V_ADDR)
#define UNIT_ADDR(x) ((x) << UNIT_V_ADDR)
#endif
/* channel program information */
CHANP mta_chp[NUM_UNITS_MT] = {0};
@ -553,14 +436,14 @@ DEVICE mta_dev = {
CHANP mtb_chp[NUM_UNITS_MT] = {0};
UNIT mtb_unit[] = {
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1800)}, /* 0 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1801)}, /* 1 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1802)}, /* 2 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1803)}, /* 3 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1804)}, /* 4 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1805)}, /* 5 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1806)}, /* 6 */
{UDATA(&mt_srv, UNIT_MT, 0), 0, UNIT_ADDR(0x1807)}, /* 7 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1800)}, /* 0 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1801)}, /* 1 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1802)}, /* 2 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1803)}, /* 3 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1804)}, /* 4 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1805)}, /* 5 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1806)}, /* 6 */
{UDATA(&mt_srv, UNIT_MT|UNIT_IDLE, 0), 0, UNIT_ADDR(0x1807)}, /* 7 */
};
/* device information block */
@ -788,7 +671,7 @@ t_stat mt_srv(UNIT * uptr)
if (chan_write_byte(addr, &ch)) {
sim_debug(DEBUG_CMD, &mta_dev, "Read unit %d EOR\n", unit);
/* If not read whole record, skip till end */
if (uptr->u4 < uptr->hwmark) {
if ((uint32)uptr->u4 < uptr->hwmark) {
/* Send dummy character to force SLI */
chan_write_byte(addr, &ch); /* write the byte */
sim_debug(DEBUG_CMD, &mta_dev, "Read unit %d send dump SLI\n", unit);
@ -804,7 +687,7 @@ t_stat mt_srv(UNIT * uptr)
} else {
sim_debug(DEBUG_DATA, &mta_dev,
"Read data @2 unit %d cnt %x ch %02x hwm %x\n", unit, uptr->u4, ch, uptr->hwmark);
if (uptr->u4 >= uptr->hwmark) { /* In IRG */
if ((uint32)uptr->u4 >= uptr->hwmark) { /* In IRG */
/* Handle end of record */
uptr->u3 &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* set not busy */

View File

@ -41,7 +41,7 @@ extern uint32 SPAD[]; /* cpu SPAD memory */
#define GET_TYPE(x) ((UNIT_TYPE & (x)) >> UNIT_V_TYPE)
#define SET_TYPE(x) (UNIT_TYPE & ((x) << UNIT_V_TYPE))
#define UNIT_SCFI UNIT_ATTABLE | UNIT_DISABLE | UNIT_ROABLE | UNIT_FIX
#define UNIT_SCFI UNIT_ATTABLE | UNIT_DISABLE | UNIT_ROABLE | UNIT_FIX | UNIT_IDLE
/* INCH command information */
/*
@ -206,7 +206,7 @@ struct ddata_t
/* disk definition structure */
struct scfi_t
{
char *name; /* Device ID Name */
const char *name; /* Device ID Name */
uint32 taus; /* total allocation units */
uint16 bms; /* bit map size */
uint16 nhds; /* Number of heads */
@ -507,7 +507,7 @@ dosns:
case DSK_INCH: /* INCH 0x00 */
{
uint32 mema; /* memory address */
int i;
uint32 i;
UNIT *up = dptr->units; /* first unit for this device */
sim_debug(DEBUG_CMD, dptr, "scfi_startcmd starting inch cmd addr %x u4 %x\r\n", addr, uptr->u4);
/* u4 has IOCD word 1 contents. For the disk processor it contains */