Merge remote-tracking branch 'origin/master'

This commit is contained in:
Mark Pizzolato 2014-03-03 08:10:31 -08:00
commit 0c56397289
7 changed files with 157 additions and 57 deletions

View file

@ -428,9 +428,31 @@ while (reason == 0) { /* loop until halted */
int_reqhi = api_findreq (); /* recalc int req */ int_reqhi = api_findreq (); /* recalc int req */
} }
else { /* normal instr */ else { /* normal instr */
if (sim_brk_summ && sim_brk_test (P, SWMASK ('E'))) { /* breakpoint? */ if (sim_brk_summ) {
reason = STOP_IBKPT; /* stop simulation */ uint32 btyp = SWMASK ('E');
break;
if (nml_mode)
btyp = SWMASK ('E') | SWMASK ('N');
else
btyp = usr_mode ? SWMASK ('E') | SWMASK ('U')
: SWMASK ('E') | SWMASK ('M');
btyp = sim_brk_test (P, btyp);
if (btyp) {
if (btyp & SWMASK ('E')) /* unqualified breakpoint? */
reason = STOP_IBKPT; /* stop simulation */
else switch (btyp) { /* qualified breakpoint */
case SWMASK ('M'): /* monitor mode */
reason = STOP_MBKPT; /* stop simulation */
break;
case SWMASK ('N'): /* normal (SDS 930) mode */
reason = STOP_NBKPT; /* stop simulation */
break;
case SWMASK ('U'): /* user mode */
reason = STOP_UBKPT; /* stop simulation */
break;
}
break;
}
} }
reason = Read (save_P = P, &inst); /* get instr */ reason = Read (save_P = P, &inst); /* get instr */
P = (P + 1) & VA_MASK; /* incr PC */ P = (P + 1) & VA_MASK; /* incr PC */
@ -448,6 +470,8 @@ while (reason == 0) { /* loop until halted */
} /* end if r == 0 */ } /* end if r == 0 */
if (reason < 0) { /* mm (fet or ex)? */ if (reason < 0) { /* mm (fet or ex)? */
pa = -reason; /* get vector */ pa = -reason; /* get vector */
if (reason == MM_MONUSR) /* record P of user-mode */
save_P = P; /* transition point */
reason = 0; /* defang */ reason = 0; /* defang */
tinst = ReadP (pa); /* get inst */ tinst = ReadP (pa); /* get inst */
if (I_GETOP (tinst) != BRM) { /* not BRM? */ if (I_GETOP (tinst) != BRM) { /* not BRM? */
@ -505,7 +529,7 @@ if (inst & I_POP) { /* POP? */
if ((r = Write (0, dat))) if ((r = Write (0, dat)))
return r; return r;
} }
} }
else { /* mon mode */ else { /* mon mode */
dat = (OV << 21) | dat; /* ov in <2> */ dat = (OV << 21) | dat; /* ov in <2> */
WriteP (0, dat); /* store return */ WriteP (0, dat); /* store return */
@ -776,7 +800,7 @@ switch (op) { /* case on opcode */
return r; return r;
inst = dat; inst = dat;
goto EXU_LOOP; goto EXU_LOOP;
case BRU: case BRU:
if (nml_mode && (inst & I_IND)) api_dismiss (); /* normal BRU*, dism */ if (nml_mode && (inst & I_IND)) api_dismiss (); /* normal BRU*, dism */
if ((r = Ea (inst, &va))) /* decode eff addr */ if ((r = Ea (inst, &va))) /* decode eff addr */
@ -785,6 +809,11 @@ switch (op) { /* case on opcode */
return r; return r;
PCQ_ENTRY; PCQ_ENTRY;
P = va & VA_MASK; /* branch */ P = va & VA_MASK; /* branch */
if ((va & VA_USR) && !nml_mode && !usr_mode) { /* user ref from mon. mode? */
usr_mode = 1; /* transition to user mode */
if (mon_usr_trap)
return MM_MONUSR;
}
break; break;
case BRX: case BRX:
@ -796,6 +825,11 @@ switch (op) { /* case on opcode */
return r; return r;
PCQ_ENTRY; PCQ_ENTRY;
P = va & VA_MASK; /* branch */ P = va & VA_MASK; /* branch */
if ((va & VA_USR) && !nml_mode && !usr_mode) { /* user ref from mon. mode? */
usr_mode = 1; /* transition to user mode */
if (mon_usr_trap)
return MM_MONUSR;
}
} }
break; break;
@ -810,6 +844,11 @@ switch (op) { /* case on opcode */
return r; return r;
PCQ_ENTRY; PCQ_ENTRY;
P = (va + 1) & VA_MASK; /* branch */ P = (va + 1) & VA_MASK; /* branch */
if ((va & VA_USR) && !nml_mode && !usr_mode) { /* user ref from mon. mode? */
usr_mode = 1; /* transition to user mode */
if (mon_usr_trap)
return MM_MONUSR;
}
break; break;
case BRR: case BRR:
@ -1191,7 +1230,7 @@ uint32 nml = nml_mode, usr = usr_mode;
uint32 pa, pgn, map; uint32 pa, pgn, map;
if (sw & SWMASK ('N')) /* -n: normal */ if (sw & SWMASK ('N')) /* -n: normal */
nml = 1; nml = 1;
else if (sw & SWMASK ('X')) /* -x: mon */ else if (sw & SWMASK ('X')) /* -x: mon */
nml = usr = 0; nml = usr = 0;
else if (sw & SWMASK ('U')) { /* -u: user */ else if (sw & SWMASK ('U')) { /* -u: user */
@ -1269,7 +1308,7 @@ return;
/* Divide - the SDS 940 uses a non-restoring divide. The algorithm /* Divide - the SDS 940 uses a non-restoring divide. The algorithm
runs even for overflow cases. Hence it must be emulated precisely runs even for overflow cases. Hence it must be emulated precisely
to give the right answers for diagnostics. If the dividend is to give the right answers for diagnostics. If the dividend is
negative, AB are 2's complemented starting at B<22>, and B<23> negative, AB are 2's complemented starting at B<22>, and B<23>
is unchanged. */ is unchanged. */
@ -1456,7 +1495,8 @@ pcq_r = find_reg ("PCQ", NULL, dptr);
if (pcq_r) if (pcq_r)
pcq_r->qptr = 0; pcq_r->qptr = 0;
else return SCPE_IERR; else return SCPE_IERR;
sim_brk_types = sim_brk_dflt = SWMASK ('E'); sim_brk_dflt = SWMASK ('E');
sim_brk_types = SWMASK ('E') | SWMASK ('M') | SWMASK ('N') | SWMASK ('U');
return SCPE_OK; return SCPE_OK;
} }
@ -1542,13 +1582,17 @@ return SCPE_OK;
a unit service routine and a reset routine. The service routine a unit service routine and a reset routine. The service routine
sets an interrupt that invokes the clock counter. The clock counter sets an interrupt that invokes the clock counter. The clock counter
is a "one instruction interrupt", and only MIN/SKR are valid. is a "one instruction interrupt", and only MIN/SKR are valid.
Temporarily divide rtc_tps by 2 because clock is running twice as
fast as it should. Eventually have to find problem in the clock
calibration or setup code.
*/ */
t_stat rtc_svc (UNIT *uptr) t_stat rtc_svc (UNIT *uptr)
{ {
if (rtc_pie) /* set pulse intr */ if (rtc_pie) /* set pulse intr */
int_req = int_req | INT_RTCP; int_req = int_req | INT_RTCP;
sim_activate (&rtc_unit, sim_rtcn_calb (rtc_tps, TMR_RTC)); /* reactivate */ sim_activate (&rtc_unit, sim_rtcn_calb (rtc_tps/2, TMR_RTC)); /* reactivate */
return SCPE_OK; return SCPE_OK;
} }
@ -1572,7 +1616,7 @@ if ((r = Read (va, &dat))) /* get operand */
dat = AddM24 (dat, val); /* mem +/- 1 */ dat = AddM24 (dat, val); /* mem +/- 1 */
if ((r = Write (va, dat))) /* rewrite */ if ((r = Write (va, dat))) /* rewrite */
return r; return r;
if (dat == 0) /* set clk sync int */ if ((op == MIN && dat == 0) || (dat & SIGN)) /* set clk sync int */
int_req = int_req | INT_RTCS; int_req = int_req | INT_RTCS;
return SCPE_OK; return SCPE_OK;
} }

View file

@ -1,4 +1,4 @@
/* sds_defs.h: SDS 940 simulator definitions /* sds_defs.h: SDS 940 simulator definitions
Copyright (c) 2001-2010, Robert M. Supnik Copyright (c) 2001-2010, Robert M. Supnik
@ -52,6 +52,9 @@
#define STOP_RTCINS 12 /* rtc inst not MIN/SKR */ #define STOP_RTCINS 12 /* rtc inst not MIN/SKR */
#define STOP_ILLVEC 13 /* zero vector */ #define STOP_ILLVEC 13 /* zero vector */
#define STOP_CCT 14 /* runaway CCT */ #define STOP_CCT 14 /* runaway CCT */
#define STOP_MBKPT 15 /* monitor-mode breakpoint */
#define STOP_NBKPT 16 /* normal-mode breakpoint */
#define STOP_UBKPT 17 /* user-mode breakpoint */
/* Trap codes */ /* Trap codes */

View file

@ -148,7 +148,7 @@ extern void set_dyn_map (void);
Channels could, optionally, handle 12b or 24b characters. The simulator can Channels could, optionally, handle 12b or 24b characters. The simulator can
support all widths. support all widths.
*/ */
t_stat chan_show_reg (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat chan_show_reg (FILE *st, UNIT *uptr, int32 val, void *desc);
struct aldisp { struct aldisp {
@ -233,11 +233,11 @@ t_stat (*dev3_dsp[64])() = { NULL };
struct aldisp dev_alt[] = { struct aldisp dev_alt[] = {
{ NULL, NULL }, { NULL, NULL },
{ NULL, &pot_ilc }, { NULL, &pot_ilc }, { NULL, &pot_ilc }, { NULL, &pot_ilc },
{ NULL, &pot_ilc }, { NULL, &pot_ilc },
{ NULL, &pot_ilc }, { NULL, &pot_ilc }, { NULL, &pot_ilc }, { NULL, &pot_ilc },
{ NULL, &pot_ilc }, { NULL, &pot_ilc }, { NULL, &pot_ilc }, { NULL, &pot_ilc },
{ NULL, &pot_ilc }, { NULL, &pot_ilc },
{ NULL, &pot_dcr }, { NULL, &pot_dcr },
{ NULL, &pot_dcr }, { NULL, &pot_dcr }, { NULL, &pot_dcr }, { NULL, &pot_dcr },
{ NULL, &pot_dcr }, { NULL, &pot_dcr },
{ NULL, &pot_dcr }, { NULL, &pot_dcr }, { NULL, &pot_dcr }, { NULL, &pot_dcr },
{ NULL, &pot_dcr }, { NULL, &pot_dcr }, { NULL, &pot_dcr }, { NULL, &pot_dcr },
{ &pin_adr, NULL }, { &pin_adr, NULL }, { &pin_adr, NULL }, { &pin_adr, NULL },
@ -330,15 +330,22 @@ switch (mod) {
if (INV_DEV (dev, ch)) /* inv dev? err */ if (INV_DEV (dev, ch)) /* inv dev? err */
CRETDEV; CRETDEV;
chan_war[ch] = chan_cnt[ch] = 0; /* init chan */ chan_war[ch] = chan_cnt[ch] = 0; /* init chan */
chan_flag[ch] = chan_dcr[ch] = 0; chan_dcr[ch] = 0;
chan_mode[ch] = chan_uar[ch] = 0; chan_uar[ch] = 0;
if (ch >= CHAN_E) if (!(chan_flag[ch] & CHF_ILCE) && /* ignore if ilc */
chan_mode[ch] = CHM_CE; !QAILCE (alert)) { /* already alerted */
chan_flag[ch] = chan_mode[ch] = 0;
if (ch >= CHAN_E)
chan_mode[ch] = CHM_CE;
}
if ((r = dev_dsp[dev][ch] (IO_CONN, inst, NULL)))/* connect */ if ((r = dev_dsp[dev][ch] (IO_CONN, inst, NULL)))/* connect */
return r; return r;
if ((inst & I_IND) || (ch >= CHAN_C)) { /* C-H? alert ilc */ if (!(chan_flag[ch] & CHF_ILCE) && /* ignore if ilc */
alert = POT_ILCY + ch; !QAILCE (alert)) { /* already alerted */
chan_mar[ch] = chan_wcr[ch] = 0; if ((inst & I_IND) || (ch >= CHAN_C)) { /* C-H? alert ilc */
alert = POT_ILCY + ch;
chan_mar[ch] = chan_wcr[ch] = 0;
}
} }
if (chan_flag[ch] & CHF_24B) /* 24B? 1 ch/wd */ if (chan_flag[ch] & CHF_24B) /* 24B? 1 ch/wd */
chan_cpw[ch] = 0; chan_cpw[ch] = 0;
@ -390,7 +397,7 @@ switch (mod) {
} /* end else change scan */ } /* end else change scan */
} /* end else term output */ } /* end else term output */
} /* end else chan EOM */ } /* end else chan EOM */
break; break;
case 2: /* internal */ case 2: /* internal */
if (ch >= CHAN_E) { /* EOD? */ if (ch >= CHAN_E) { /* EOD? */
@ -432,6 +439,8 @@ switch (mod) {
case 3: /* special */ case 3: /* special */
dev = I_GETDEV3 (inst); /* special device */ dev = I_GETDEV3 (inst); /* special device */
if (dev == DEV3_SMUX && !(cpu_unit.flags & UNIT_GENIE))
dev = DEV3_GMUX;
if (dev3_dsp[dev]) /* defined? */ if (dev3_dsp[dev]) /* defined? */
return dev3_dsp[dev] (IO_CONN, inst, NULL); return dev3_dsp[dev] (IO_CONN, inst, NULL);
CRETINS; CRETINS;
@ -493,8 +502,10 @@ switch (mod) {
case 3: /* special */ case 3: /* special */
dev = I_GETDEV3 (inst); /* special device */ dev = I_GETDEV3 (inst); /* special device */
if (dev == DEV3_SMUX && !(cpu_unit.flags & UNIT_GENIE))
dev = DEV3_GMUX;
if (dev3_dsp[dev]) if (dev3_dsp[dev])
dev3_dsp[dev] (IO_SKS, inst, dat); dev3_dsp[dev] (IO_SKS, inst, dat);
else CRETINS; else CRETINS;
} /* end case */ } /* end case */
@ -540,9 +551,9 @@ return SCPE_OK;
t_stat pot_fork (uint32 num, uint32 *dat) t_stat pot_fork (uint32 num, uint32 *dat)
{ {
uint32 igrp = SYI_GETGRP (*dat); /* get group */ uint32 igrp = SYI_GETGRP (*dat); /* get group */
uint32 fbit = (1 << (VEC_FORK & 017)); /* bit in group */ uint32 fbit = (0100000 >> (VEC_FORK & 017)); /* bit in group */
if (igrp == (VEC_FORK / 020)) { /* right group? */ if (igrp == ((VEC_FORK-0200) / 020)) { /* right group? */
if ((*dat & SYI_ARM) && (*dat & fbit)) /* arm, bit set? */ if ((*dat & SYI_ARM) && (*dat & fbit)) /* arm, bit set? */
int_req = int_req | INT_FORK; int_req = int_req | INT_FORK;
if ((*dat & SYI_DIS) && !(*dat & fbit)) /* disarm, bit clr? */ if ((*dat & SYI_DIS) && !(*dat & fbit)) /* disarm, bit clr? */
@ -568,7 +579,7 @@ return SCPE_OK;
Note that the channel can be disconnected if CHN_EOR is set, but must Note that the channel can be disconnected if CHN_EOR is set, but must
not be if XFR_REQ is set */ not be if XFR_REQ is set */
t_stat chan_read (int32 ch) t_stat chan_read (int32 ch)
{ {
uint32 dat = 0; uint32 dat = 0;
@ -626,7 +637,7 @@ if (TST_EOR (ch)) { /* end record? */
} /* end else if cnt */ } /* end else if cnt */
return chan_eor (ch); /* eot/eor int */ return chan_eor (ch); /* eot/eor int */
} }
return r; return r;
} }
void chan_write_mem (int32 ch) void chan_write_mem (int32 ch)

View file

@ -54,6 +54,7 @@
#define MUX_SETFLG(l,x) mux_flags[((l) * MUX_FLAGS) + (x)] = 1 #define MUX_SETFLG(l,x) mux_flags[((l) * MUX_FLAGS) + (x)] = 1
#define MUX_SETINT(x) int_req = int_req | (INT_MUXR >> (x)) #define MUX_SETINT(x) int_req = int_req | (INT_MUXR >> (x))
#define MUX_CLRINT(x) int_req = int_req & ~(INT_MUXR >> (x)) #define MUX_CLRINT(x) int_req = int_req & ~(INT_MUXR >> (x))
#define MUX_CHKINT(x) (int_req & (INT_MUXR >> (x)))
/* PIN/POT */ /* PIN/POT */
@ -274,7 +275,7 @@ switch (fnc) {
((inst & SKS_DSR) && !(mux_sta[ln] & MUX_SDSR))) ((inst & SKS_DSR) && !(mux_sta[ln] & MUX_SDSR)))
*dat = 0; /* no skip if fail */ *dat = 0; /* no skip if fail */
} }
else CRETINS; else CRETINS;
default: default:
return SCPE_IERR; return SCPE_IERR;
@ -290,6 +291,8 @@ t_stat pin_mux (uint32 num, uint32 *dat)
uint32 ln = mux_scan >> 2; uint32 ln = mux_scan >> 2;
uint32 flag = mux_scan & MUX_FLAGMASK; uint32 flag = mux_scan & MUX_FLAGMASK;
if (!mux_slck) /* scanner must be locked */
return SCPE_IERR;
mux_scan = mux_scan & MUX_SCANMASK; /* mask scan */ mux_scan = mux_scan & MUX_SCANMASK; /* mask scan */
mux_flags[mux_scan] = 0; /* clear flag */ mux_flags[mux_scan] = 0; /* clear flag */
if (flag == MUX_FRCV) { /* rcv event? */ if (flag == MUX_FRCV) { /* rcv event? */
@ -333,6 +336,12 @@ else { /* enabled */
else mux_sta[ln] = mux_sta[ln] & ~MUX_SXIE; else mux_sta[ln] = mux_sta[ln] & ~MUX_SXIE;
mux_sta[ln] = mux_sta[ln] | MUX_SLNE; /* line is enabled */ mux_sta[ln] = mux_sta[ln] | MUX_SLNE; /* line is enabled */
mux_ldsc[ln].rcve = 1; mux_ldsc[ln].rcve = 1;
if ((*dat & POT_NOX) && /* if no transmit char && */
(mux_sta[ln] & MUX_SXIE) && /* line enabled && */
!sim_is_active (&muxl_unit[ln])) { /* tx buffer empty */
MUX_SETFLG (ln, MUX_FXMT); /* then set flag to request */
mux_scan_next (); /* a tx interrupt */
}
} }
return SCPE_OK; return SCPE_OK;
} }
@ -407,7 +416,23 @@ if (mux_sta[ln] & MUX_SXIE) {
return SCPE_OK; return SCPE_OK;
} }
/* Kick scanner */ /* Kick scanner
*
* Per 940 Ref Man:
* If more than one raised flag is encountered by the scanner, only
* the one of highest priority will result in an interrupt. The others
* will be ignored until the scanner has completed scanning all other
* channels. The receive flag will be given highest priority, followed
* by the transmit flag, the carrier-on flag, and the carrier-off flag.
*
* To implement, advance mux_scan to last flag of current channel (by
* merging MUX_FLAGMASK) so scan loop commences with receive flag of next
* channel.
*
* When two or more channels are active, do not queue an interrupt
* request if the same interrupt is already requesting. To do so will
* cause an interrupt to be lost.
*/
void mux_scan_next (void) void mux_scan_next (void)
{ {
@ -415,9 +440,12 @@ int32 i;
if (mux_slck) /* locked? */ if (mux_slck) /* locked? */
return; return;
mux_scan |= MUX_FLAGMASK; /* last flag of current ch. */
/* will be Rx flag of next ch. */
for (i = 0; i < MUX_SCANMAX; i++) { /* scan flags */ for (i = 0; i < MUX_SCANMAX; i++) { /* scan flags */
mux_scan = (mux_scan + 1) & MUX_SCANMASK; /* next flag */ mux_scan = (mux_scan + 1) & MUX_SCANMASK; /* next flag */
if (mux_flags[mux_scan]) { /* flag set? */ if (mux_flags[mux_scan] && /* flag set */
!MUX_CHKINT (mux_scan & MUX_FLAGMASK)) { /* and not requesting int? */
mux_slck = 1; /* lock scanner */ mux_slck = 1; /* lock scanner */
MUX_SETINT (mux_scan & MUX_FLAGMASK); /* request int */ MUX_SETINT (mux_scan & MUX_FLAGMASK); /* request int */
return; return;

View file

@ -116,7 +116,7 @@ DEVICE rad_dev = {
}; };
/* Fixed head disk routine /* Fixed head disk routine
conn - inst = EOM0, dat = NULL conn - inst = EOM0, dat = NULL
eom1 - inst = EOM1, dat = NULL eom1 - inst = EOM1, dat = NULL
sks - inst = SKS, dat = ptr to result sks - inst = SKS, dat = ptr to result
@ -157,7 +157,7 @@ switch (fnc) { /* case function */
if (new_ch != rad_dib.chan) /* wrong chan? */ if (new_ch != rad_dib.chan) /* wrong chan? */
return SCPE_IERR; return SCPE_IERR;
if ((inst & 00600) == 00200) /* alert for sec */ if ((inst & 00600) == 00200) /* alert for sec */
alert = POT_RADS; alert = POT_RADS;
else if ((inst & 06600) == 0) { /* alert for addr */ else if ((inst & 06600) == 0) { /* alert for addr */
if (sim_is_active (&rad_unit)) /* busy? */ if (sim_is_active (&rad_unit)) /* busy? */
rad_err = 1; rad_err = 1;
@ -287,7 +287,7 @@ if (rad_sba >= (RAD_NUMWD * 2)) { /* next sector? */
((rad_da + 1) & RAD_SCMASK); ((rad_da + 1) & RAD_SCMASK);
else rad_da = (rad_da & ~RAD_TRSCMASK) + /* cross band */ else rad_da = (rad_da & ~RAD_TRSCMASK) + /* cross band */
((rad_da + 1) & RAD_TRSCMASK); ((rad_da + 1) & RAD_TRSCMASK);
sba = 0; /* start new sec */ sba = 1; /* start new sec */
} }
return sba; return sba;
} }

View file

@ -96,7 +96,10 @@ const char *sim_stop_messages[] = {
"Trap instruction not BRM", "Trap instruction not BRM",
"RTC instruction not MIN or SKR", "RTC instruction not MIN or SKR",
"Interrupt vector zero", "Interrupt vector zero",
"Runaway carriage control tape" "Runaway carriage control tape",
"Monitor-mode Breakpoint",
"Normal-mode Breakpoint",
"User-mode Breakpoint"
}; };
/* Character conversion tables */ /* Character conversion tables */
@ -212,7 +215,7 @@ for (i = wd = 0; i < 4; ) {
} }
return wd; return wd;
} }
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
{ {
int32 i, wd, buf[8]; int32 i, wd, buf[8];
@ -227,7 +230,7 @@ for (i = 0; i < 8; i++) { /* read boot */
if ((wd = get_word (fileref, &ldr)) < 0) if ((wd = get_word (fileref, &ldr)) < 0)
return SCPE_FMT; return SCPE_FMT;
buf[i] = wd; buf[i] = wd;
} }
if ((buf[0] != 023200012) || /* 2 = WIM 12,2 */ if ((buf[0] != 023200012) || /* 2 = WIM 12,2 */
(buf[1] != 004100002) || /* 3 = BRX 2 */ (buf[1] != 004100002) || /* 3 = BRX 2 */
(buf[2] != 007100011) || /* 4 = LDX 11 */ (buf[2] != 007100011) || /* 4 = LDX 11 */
@ -260,15 +263,15 @@ return SCPE_NXM;
#define I_V_OPO 006 /* opcode only */ #define I_V_OPO 006 /* opcode only */
#define I_V_CHC 007 /* chan cmd */ #define I_V_CHC 007 /* chan cmd */
#define I_V_CHT 010 /* chan test */ #define I_V_CHT 010 /* chan test */
#define I_NPN (I_V_NPN << I_V_FL) #define I_NPN (I_V_NPN << I_V_FL)
#define I_PPO (I_V_PPO << I_V_FL) #define I_PPO (I_V_PPO << I_V_FL)
#define I_IOI (I_V_IOI << I_V_FL) #define I_IOI (I_V_IOI << I_V_FL)
#define I_MRF (I_V_MRF << I_V_FL) #define I_MRF (I_V_MRF << I_V_FL)
#define I_REG (I_V_REG << I_V_FL) #define I_REG (I_V_REG << I_V_FL)
#define I_SHF (I_V_SHF << I_V_FL) #define I_SHF (I_V_SHF << I_V_FL)
#define I_OPO (I_V_OPO << I_V_FL) #define I_OPO (I_V_OPO << I_V_FL)
#define I_CHC (I_V_CHC << I_V_FL) #define I_CHC (I_V_CHC << I_V_FL)
#define I_CHT (I_V_CHT << I_V_FL) #define I_CHT (I_V_CHT << I_V_FL)
static const int32 masks[] = { static const int32 masks[] = {
037777777, 010000000, 017700000, 037777777, 010000000, 017700000,
@ -299,7 +302,7 @@ static const char *opcode[] = {
"SKM", "LDX", "SKA", "SKG", "SKM", "LDX", "SKA", "SKG",
"SKD", "LDB", "LDA", "EAX", "SKD", "LDB", "LDA", "EAX",
"BRU*", "BRU*",
"MIY*", "BRI*", "MIW*", "POT*", "MIY*", "BRI*", "MIW*", "POT*",
"ETR*", "MRG*", "EOR*", "ETR*", "MRG*", "EOR*",
"EXU*", "EXU*",
@ -430,17 +433,17 @@ va = inst & VA_MASK;
shf = inst & I_SHFMSK; shf = inst & I_SHFMSK;
nonop = inst & 077777; nonop = inst & 077777;
if (sw & SWMASK ('A')) { /* ASCII? */ if (sw & SWMASK ('A')) { /* SDS internal ASCII? */
if (inst > 0377) for (i = 16; i >= 0; i -= 8) {
return SCPE_ARG; ch = (inst >> i) & 0377; /* map printable chars */
fprintf (of, FMTASC (inst & 0177)); ch = ch <= 0137 ? ch += 040 : '.'; /* from int. to ext. ASCII */
fprintf (of, "%c", ch);
}
return SCPE_OK; return SCPE_OK;
} }
if (sw & SWMASK ('C')) { /* character? */ if (sw & SWMASK ('C')) { /* six-bit character? */
fprintf (of, "%c", sds_to_ascii[(inst >> 18) & 077]); for (i = 18; i >= 0; i -= 6)
fprintf (of, "%c", sds_to_ascii[(inst >> 12) & 077]); fprintf (of, "%c", sds_to_ascii[(inst >> i) & 077]);
fprintf (of, "%c", sds_to_ascii[(inst >> 6) & 077]);
fprintf (of, "%c", sds_to_ascii[inst & 077]);
return SCPE_OK; return SCPE_OK;
} }
if (!(sw & SWMASK ('M'))) return SCPE_ARG; if (!(sw & SWMASK ('M'))) return SCPE_ARG;
@ -539,7 +542,7 @@ return cptr; /* no change */
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
{ {
int32 i, j, k; int32 i, j, k, ch;
t_value d, tag; t_value d, tag;
t_stat r; t_stat r;
char gbuf[CBUFSIZE]; char gbuf[CBUFSIZE];
@ -554,10 +557,21 @@ for (i = 1; (i < 4) && (cptr[i] != 0); i++) {
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */ if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
if (cptr[0] == 0) /* must have 1 char */ if (cptr[0] == 0) /* must have 1 char */
return SCPE_ARG; return SCPE_ARG;
val[0] = (t_value) cptr[0] | 0200; for (i = j = 0, val[0] = 0; i < 3; i++) {
if (cptr[i] == 0) /* latch str end */
j = 1;
ch = cptr[i] & 0377;
if (ch <= 037 || ch >= 0200)
k = -1;
else
k = ch - 040; /* map ext. to int. ASCII */
if (j || (k < 0)) /* bad, end? spc */
k = 0;
val[0] = (val[0] << 8) | k;
}
return SCPE_OK; return SCPE_OK;
} }
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* string? */ if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* string of 6-bit chars? */
if (cptr[0] == 0) /* must have 1 char */ if (cptr[0] == 0) /* must have 1 char */
return SCPE_ARG; return SCPE_ARG;
for (i = j = 0, val[0] = 0; i < 4; i++) { for (i = j = 0, val[0] = 0; i < 4; i++) {

Binary file not shown.