RESTRICTION: The PDP-15 FPP is only partially debugged. Do NOT enable this feature for normal operations. 1. New Features in 3.2-1 1.1 SCP and libraries - Added SET CONSOLE subhierarchy. - Added SHOW CONSOLE subhierarchy. - Added limited keyboard mapping capability. 1.2 HP2100 (new features from Dave Bryan) - Added instruction printout to HALT message. - Added M and T internal registers. - Added N, S, and U breakpoints. 1.3 PDP-11 and VAX - Added DHQ11 support (from John Dundas) 2. Bugs Fixed in 3.2-1 2.1 HP2100 (most fixes from Dave Bryan) - SBT increments B after store. - DMS console map must check dms_enb. - SFS x,C and SFC x,C work. - MP violation clears automatically on interrupt. - SFS/SFC 5 is not gated by protection enabled. - DMS enable does not disable mem prot checks. - DMS status inconsistent at simulator halt. - Examine/deposit are checking wrong addresses. - Physical addresses are 20b not 15b. - Revised DMS to use memory rather than internal format. - Revised IBL facility to conform to microcode. - Added DMA EDT I/O pseudo-opcode. - Separated DMA SRQ (service request) from FLG. - Revised peripherals to make SFS x,C and SFC x,C work. - Revised boot ROMs to use IBL facility. - Revised IBL treatment of SR to preserve SR<5:3>. - Fixed LPS, LPT timing. - Fixed DP boot interpretation of SR<0>. - Revised DR boot code to use IBL algorithm. - Fixed TTY input behavior during typeout for RTE-IV. - Suppressed nulls on TTY output for RTE-IV. - Added SFS x,C and SFC x,C to print/parse routines. - Fixed spurious timing error in magtape reads. 2.2 All DEC console devices - Removed SET TTI CTRL-C option. 2.3 PDP-11/VAX peripherals - Fixed bug in TQ reporting write protect status (reported by Lyle Bickley). - Fixed TK70 model number and media ID (found by Robert Schaffrath). - Fixed bug in autoconfigure (found by John Dundas). 2.4 VAX - Fixed bug in DIVBx and DIVWx (reported by Peter Trimmel).
1379 lines
45 KiB
C
1379 lines
45 KiB
C
/* vax_sys.c: VAX simulator interface
|
||
|
||
Copyright (c) 1998-2004, Robert M Supnik
|
||
|
||
Permission is hereby granted, free of charge, to any person obtaining a
|
||
copy of this software and associated documentation files (the "Software"),
|
||
to deal in the Software without restriction, including without limitation
|
||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||
and/or sell copies of the Software, and to permit persons to whom the
|
||
Software is furnished to do so, subject to the following conditions:
|
||
|
||
The above copyright notice and this permission notice shall be included in
|
||
all copies or substantial portions of the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||
in this Software without prior written authorization from Robert M Supnik.
|
||
|
||
16-Jun-04 RMS Added DHQ11 support
|
||
21-Mar-04 RMS Added RXV21 support
|
||
06-May-03 RMS Added support for second DELQA
|
||
12-Oct-02 RMS Added multiple RQ controller support
|
||
10-Oct-02 RMS Added DELQA support
|
||
21-Sep-02 RMS Extended symbolic ex/mod to all byte devices
|
||
06-Sep-02 RMS Added TMSCP support
|
||
14-Jul-02 RMS Added infinite loop message
|
||
*/
|
||
|
||
#include "vax_defs.h"
|
||
#include <ctype.h>
|
||
|
||
extern DEVICE cpu_dev;
|
||
extern DEVICE tlb_dev;
|
||
extern DEVICE rom_dev;
|
||
extern DEVICE nvr_dev;
|
||
extern DEVICE sysd_dev;
|
||
extern DEVICE qba_dev;
|
||
extern DEVICE ptr_dev, ptp_dev;
|
||
extern DEVICE tti_dev, tto_dev;
|
||
extern DEVICE csi_dev, cso_dev;
|
||
extern DEVICE lpt_dev;
|
||
extern DEVICE clk_dev;
|
||
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
|
||
extern DEVICE rl_dev;
|
||
extern DEVICE ry_dev;
|
||
extern DEVICE ts_dev;
|
||
extern DEVICE tq_dev;
|
||
extern DEVICE dz_dev;
|
||
extern DEVICE vh_dev;
|
||
extern DEVICE xq_dev, xqb_dev;
|
||
extern UNIT cpu_unit;
|
||
extern REG cpu_reg[];
|
||
extern uint32 *M;
|
||
extern int32 saved_PC;
|
||
extern int32 sim_switches;
|
||
|
||
extern void WriteB (int32 pa, int32 val);
|
||
extern void rom_wr (int32 pa, int32 val, int32 lnt);
|
||
t_stat fprint_sym_m (FILE *of, uint32 addr, t_value *val);
|
||
int32 fprint_sym_qoimm (FILE *of, t_value *val, int32 vp, int32 lnt);
|
||
t_stat parse_sym_m (char *cptr, uint32 addr, t_value *val);
|
||
int32 parse_brdisp (char *cptr, uint32 addr, t_value *val,
|
||
int32 vp, int32 lnt, t_stat *r);
|
||
int32 parse_spec (char *cptr, uint32 addr, t_value *val,
|
||
int32 vp, int32 disp, t_stat *r);
|
||
char *parse_rnum (char *cptr, int32 *rn);
|
||
int32 parse_sym_qoimm (int32 *lit, t_value *val, int32 vp,
|
||
int lnt, int32 minus);
|
||
|
||
/* SCP data structures and interface routines
|
||
|
||
sim_name simulator name string
|
||
sim_PC pointer to saved PC register descriptor
|
||
sim_emax number of words for examine
|
||
sim_devices array of pointers to simulated devices
|
||
sim_stop_messages array of pointers to stop messages
|
||
sim_load binary loader
|
||
*/
|
||
|
||
char sim_name[] = "VAX";
|
||
|
||
REG *sim_PC = &cpu_reg[0];
|
||
|
||
int32 sim_emax = 60;
|
||
|
||
DEVICE *sim_devices[] = {
|
||
&cpu_dev,
|
||
&tlb_dev,
|
||
&rom_dev,
|
||
&nvr_dev,
|
||
&sysd_dev,
|
||
&qba_dev,
|
||
&tti_dev,
|
||
&tto_dev,
|
||
&csi_dev,
|
||
&cso_dev,
|
||
&clk_dev,
|
||
&ptr_dev,
|
||
&ptp_dev,
|
||
&lpt_dev,
|
||
&dz_dev,
|
||
&vh_dev,
|
||
&rl_dev,
|
||
&rq_dev,
|
||
&rqb_dev,
|
||
&rqc_dev,
|
||
&rqd_dev,
|
||
&ry_dev,
|
||
&ts_dev,
|
||
&tq_dev,
|
||
&xq_dev,
|
||
&xqb_dev,
|
||
NULL };
|
||
|
||
const char *sim_stop_messages[] = {
|
||
"Unknown error",
|
||
"HALT instruction",
|
||
"Breakpoint",
|
||
"CHMx on interrupt stack",
|
||
"Invalid SCB vector",
|
||
"Exception in interrupt or exception",
|
||
"Process PTE in P0 or P1 space",
|
||
"Interrupt at undefined IPL",
|
||
"Fatal RQDX3 error",
|
||
"Infinite loop",
|
||
"Sanity timer expired",
|
||
"Unknown error",
|
||
"Unknown abort code" };
|
||
|
||
/* Binary loader
|
||
|
||
The binary loader handles absolute system images, that is, system
|
||
images linked /SYSTEM. These are simply a byte stream, with no
|
||
origin or relocation information.
|
||
|
||
-r load ROM
|
||
-n load NVR
|
||
-o for memory, specify origin
|
||
*/
|
||
|
||
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
|
||
{
|
||
t_stat r;
|
||
int32 i;
|
||
uint32 origin, limit;
|
||
extern int32 ssc_cnf;
|
||
#define SSCCNF_BLO 0x80000000
|
||
|
||
if (flag) return SCPE_ARG; /* dump? */
|
||
if (sim_switches & SWMASK ('R')) { /* ROM? */
|
||
origin = ROMBASE;
|
||
limit = ROMBASE + ROMSIZE; }
|
||
else if (sim_switches & SWMASK ('N')) { /* NVR? */
|
||
origin = NVRBASE;
|
||
limit = NVRBASE + NVRSIZE;
|
||
ssc_cnf = ssc_cnf & ~SSCCNF_BLO; }
|
||
else { origin = 0; /* memory */
|
||
limit = (uint32) cpu_unit.capac;
|
||
if (sim_switches & SWMASK ('O')) { /* origin? */
|
||
origin = (int32) get_uint (cptr, 16, 0xFFFFFFFF, &r);
|
||
if (r != SCPE_OK) return SCPE_ARG; } }
|
||
|
||
while ((i = getc (fileref)) != EOF) { /* read byte stream */
|
||
if (origin >= limit) return SCPE_NXM; /* NXM? */
|
||
if (sim_switches & SWMASK ('R')) /* ROM? */
|
||
rom_wr (origin, i, L_BYTE); /* not writeable */
|
||
else WriteB (origin, i); /* store byte */
|
||
origin = origin + 1; }
|
||
return SCPE_OK;
|
||
}
|
||
|
||
/* Factory bad block table creation routine
|
||
|
||
This routine writes a DEC standard 044 compliant bad block table on the
|
||
last track of the specified unit. The bad block table consists of 10
|
||
repetitions of the same table, formatted as follows:
|
||
|
||
words 0-1 pack id number
|
||
words 2-3 cylinder/sector/surface specifications
|
||
:
|
||
words n-n+1 end of table (-1,-1)
|
||
|
||
Inputs:
|
||
uptr = pointer to unit
|
||
sec = number of sectors per surface
|
||
wds = number of words per sector
|
||
Outputs:
|
||
sta = status code
|
||
*/
|
||
|
||
t_stat pdp11_bad_block (UNIT *uptr, int32 sec, int32 wds)
|
||
{
|
||
int32 i, da;
|
||
int32 *buf;
|
||
|
||
if ((sec < 2) || (wds < 16)) return SCPE_ARG;
|
||
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT;
|
||
if (!get_yn ("Overwrite last track? [N]", FALSE)) return SCPE_OK;
|
||
da = (int32) (uptr->capac - (sec * wds)) * sizeof (int16);
|
||
if (fseek (uptr->fileref, da, SEEK_SET)) return SCPE_IOERR;
|
||
if ((buf = malloc (wds * sizeof (int32))) == NULL) return SCPE_MEM;
|
||
buf[0] = 0x12345678;
|
||
buf[1] = 0;
|
||
for (i = 2; i < wds; i++) buf[i] = 0xFFFFFFFF;
|
||
for (i = 0; (i < sec) && (i < 10); i++)
|
||
fxwrite (buf, sizeof (int32), wds, uptr->fileref);
|
||
free (buf);
|
||
if (ferror (uptr->fileref)) return SCPE_IOERR;
|
||
return SCPE_OK;
|
||
}
|
||
|
||
/* Dispatch/decoder table
|
||
|
||
The first entry contains:
|
||
- FPD legal flag (DR_F)
|
||
- number of specifiers for decode bits 2:0>
|
||
- number of specifiers for unimplemented instructions bits<6:4>
|
||
*/
|
||
|
||
const uint16 drom[NUM_INST][MAX_SPEC + 1] = {
|
||
0, 0, 0, 0, 0, 0, 0, /* HALT */
|
||
0, 0, 0, 0, 0, 0, 0, /* NOP */
|
||
0, 0, 0, 0, 0, 0, 0, /* REI */
|
||
0, 0, 0, 0, 0, 0, 0, /* BPT */
|
||
0, 0, 0, 0, 0, 0, 0, /* RET */
|
||
0, 0, 0, 0, 0, 0, 0, /* RSB */
|
||
0, 0, 0, 0, 0, 0, 0, /* LDPCTX */
|
||
0, 0, 0, 0, 0, 0, 0, /* SVPCTX */
|
||
4+DR_F, RW, AB, RW, AB, 0, 0, /* CVTPS */
|
||
4+DR_F, RW, AB, RW, AB, 0, 0, /* CVTSP */
|
||
6, RL, RL, RL, RL, RL, WL, /* INDEX */
|
||
4+DR_F, AB, RL, RW, AB, 0, 0, /* CRC */
|
||
3, RB, RW, AB, 0, 0, 0, /* PROBER */
|
||
3, RB, RW, AB, 0, 0, 0, /* PROBEW */
|
||
2, AB, AB, 0, 0, 0, 0, /* INSQUE */
|
||
2, AB, WL, 0, 0, 0, 0, /* REMQUE */
|
||
1, BB, 0, 0, 0, 0, 0, /* BSBB */
|
||
1, BB, 0, 0, 0, 0, 0, /* BRB */
|
||
1, BB, 0, 0, 0, 0, 0, /* BNEQ */
|
||
1, BB, 0, 0, 0, 0, 0, /* BEQL */
|
||
1, BB, 0, 0, 0, 0, 0, /* BGTR */
|
||
1, BB, 0, 0, 0, 0, 0, /* BLEQ */
|
||
1, AB, 0, 0, 0, 0, 0, /* JSB */
|
||
1, AB, 0, 0, 0, 0, 0, /* JMP */
|
||
1, BB, 0, 0, 0, 0, 0, /* BGEQ */
|
||
1, BB, 0, 0, 0, 0, 0, /* BLSS */
|
||
1, BB, 0, 0, 0, 0, 0, /* BGTRU */
|
||
1, BB, 0, 0, 0, 0, 0, /* BLEQU */
|
||
1, BB, 0, 0, 0, 0, 0, /* BVC */
|
||
1, BB, 0, 0, 0, 0, 0, /* BVS */
|
||
1, BB, 0, 0, 0, 0, 0, /* BCC */
|
||
1, BB, 0, 0, 0, 0, 0, /* BCS */
|
||
4+DR_F, RW, AB, RW, AB, 0, 0, /* ADDP4 */
|
||
6+DR_F, RW, AB, RW, AB, RW, AB, /* ADDP6 */
|
||
4+DR_F, RW, AB, RW, AB, 0, 0, /* SUBP4 */
|
||
6+DR_F, RW, AB, RW, AB, RW, AB, /* SUBP6 */
|
||
5+DR_F, RW, AB, AB, RW, AB, 0, /* CVTPT */
|
||
6+DR_F, RW, AB, RW, AB, RW, AB, /* MULP6 */
|
||
5+DR_F, RW, AB, AB, RW, AB, 0, /* CVTTP */
|
||
6+DR_F, RW, AB, RW, AB, RW, AB, /* DIVP6 */
|
||
3+DR_F, RW, AB, AB, 0, 0, 0, /* MOVC3 */
|
||
3+DR_F, RW, AB, AB, 0, 0, 0, /* CMPC3 */
|
||
4+DR_F, RW, AB, AB, RB, 0, 0, /* SCANC */
|
||
4+DR_F, RW, AB, AB, RB, 0, 0, /* SPANC */
|
||
5+DR_F, RW, AB, RB, RW, AB, 0, /* MOVC5 */
|
||
5+DR_F, RW, AB, RB, RW, AB, 0, /* CMPC5 */
|
||
6+DR_F, RW, AB, RB, AB, RW, AB, /* MOVTC */
|
||
6+DR_F, RW, AB, RB, AB, RW, AB, /* MOVTUC */
|
||
1, BW, 0, 0, 0, 0, 0, /* BSBW */
|
||
1, BW, 0, 0, 0, 0, 0, /* BRW */
|
||
2, RW, WL, 0, 0, 0, 0, /* CVTWL */
|
||
2, RW, WB, 0, 0, 0, 0, /* CVTWB */
|
||
3+DR_F, RW, AB, AB, 0, 0, 0, /* MOVP */
|
||
3+DR_F, RW, AB, AB, 0, 0, 0, /* CMPP3 */
|
||
3+DR_F, RW, AB, WL, 0, 0, 0, /* CVTPL */
|
||
4+DR_F, RW, AB, RW, AB, 0, 0, /* CMPP4 */
|
||
4+DR_F, RW, AB, AB, AB, 0, 0, /* EDITPC */
|
||
4+DR_F, RW, AB, RW, AB, 0, 0, /* MATCHC */
|
||
3+DR_F, RB, RW, AB, 0, 0, 0, /* LOCC */
|
||
3+DR_F, RB, RW, AB, 0, 0, 0, /* SKPC */
|
||
2, RW, WL, 0, 0, 0, 0, /* MOVZWL */
|
||
4, RW, RW, MW, BW, 0, 0, /* ACBW */
|
||
2, AW, WL, 0, 0, 0, 0, /* MOVAW */
|
||
1, AW, 0, 0, 0, 0, 0, /* PUSHAW */
|
||
2, RF, ML, 0, 0, 0, 0, /* ADDF2 */
|
||
3, RF, RF, WL, 0, 0, 0, /* ADDF3 */
|
||
2, RF, ML, 0, 0, 0, 0, /* SUBF2 */
|
||
3, RF, RF, WL, 0, 0, 0, /* SUBF3 */
|
||
2, RF, ML, 0, 0, 0, 0, /* MULF2 */
|
||
3, RF, RF, WL, 0, 0, 0, /* MULF3 */
|
||
2, RF, ML, 0, 0, 0, 0, /* DIVF2 */
|
||
3, RF, RF, WL, 0, 0, 0, /* DIVF3 */
|
||
2, RF, WB, 0, 0, 0, 0, /* CVTFB */
|
||
2, RF, WW, 0, 0, 0, 0, /* CVTFW */
|
||
2, RF, WL, 0, 0, 0, 0, /* CVTFL */
|
||
2, RF, WL, 0, 0, 0, 0, /* CVTRFL */
|
||
2, RB, WL, 0, 0, 0, 0, /* CVTBF */
|
||
2, RW, WL, 0, 0, 0, 0, /* CVTWF */
|
||
2, RL, WL, 0, 0, 0, 0, /* CVTLF */
|
||
4, RF, RF, ML, BW, 0, 0, /* ACBF */
|
||
2, RF, WL, 0, 0, 0, 0, /* MOVF */
|
||
2, RF, RF, 0, 0, 0, 0, /* CMPF */
|
||
2, RF, WL, 0, 0, 0, 0, /* MNEGF */
|
||
1, RF, 0, 0, 0, 0, 0, /* TSTF */
|
||
5, RF, RB, RF, WL, WL, 0, /* EMODF */
|
||
3, RF, RW, AB, 0, 0, 0, /* POLYF */
|
||
2, RF, WQ, 0, 0, 0, 0, /* CVTFD */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
2, RW, WW, 0, 0, 0, 0, /* ADAWI */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
2, AB, AQ, 0, 0, 0, 0, /* INSQHI */
|
||
2, AB, AQ, 0, 0, 0, 0, /* INSQTI */
|
||
2, AQ, WL, 0, 0, 0, 0, /* REMQHI */
|
||
2, AQ, WL, 0, 0, 0, 0, /* REMQTI */
|
||
2, RD, MQ, 0, 0, 0, 0, /* ADDD2 */
|
||
3, RD, RD, WQ, 0, 0, 0, /* ADDD3 */
|
||
2, RD, MQ, 0, 0, 0, 0, /* SUBD2 */
|
||
3, RD, RD, WQ, 0, 0, 0, /* SUBD3 */
|
||
2, RD, MQ, 0, 0, 0, 0, /* MULD2 */
|
||
3, RD, RD, WQ, 0, 0, 0, /* MULD3 */
|
||
2, RD, MQ, 0, 0, 0, 0, /* DIVD2 */
|
||
3, RD, RD, WQ, 0, 0, 0, /* DIVD3 */
|
||
2, RD, WB, 0, 0, 0, 0, /* CVTDB */
|
||
2, RD, WW, 0, 0, 0, 0, /* CVTDW */
|
||
2, RD, WL, 0, 0, 0, 0, /* CVTDL */
|
||
2, RD, WL, 0, 0, 0, 0, /* CVTRDL */
|
||
2, RB, WQ, 0, 0, 0, 0, /* CVTBD */
|
||
2, RW, WQ, 0, 0, 0, 0, /* CVTWD */
|
||
2, RL, WQ, 0, 0, 0, 0, /* CVTLD */
|
||
4, RD, RD, MQ, BW, 0, 0, /* ACBD */
|
||
2, RD, WQ, 0, 0, 0, 0, /* MOVD */
|
||
2, RD, RD, 0, 0, 0, 0, /* CMPD */
|
||
2, RD, WQ, 0, 0, 0, 0, /* MNEGD */
|
||
1, RD, 0, 0, 0, 0, 0, /* TSTD */
|
||
5, RD, RB, RD, WL, WQ, 0, /* EMODD */
|
||
3, RD, RW, AB, 0, 0, 0, /* POLYD */
|
||
2, RD, WL, 0, 0, 0, 0, /* CVTDF */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
3, RB, RL, WL, 0, 0, 0, /* ASHL */
|
||
3, RB, RQ, WQ, 0, 0, 0, /* ASHQ */
|
||
4, RL, RL, RL, WQ, 0, 0, /* EMUL */
|
||
4, RL, RQ, WL, WL, 0, 0, /* EDIV */
|
||
1, WQ, 0, 0, 0, 0, 0, /* CLRQ */
|
||
2, RQ, WQ, 0, 0, 0, 0, /* MOVQ */
|
||
2, AQ, WL, 0, 0, 0, 0, /* MOVAQ */
|
||
1, AQ, 0, 0, 0, 0, 0, /* PUSHAQ */
|
||
2, RB, MB, 0, 0, 0, 0, /* ADDB2 */
|
||
3, RB, RB, WB, 0, 0, 0, /* ADDB3 */
|
||
2, RB, MB, 0, 0, 0, 0, /* SUBB2 */
|
||
3, RB, RB, WB, 0, 0, 0, /* SUBB3 */
|
||
2, RB, MB, 0, 0, 0, 0, /* MULB2 */
|
||
3, RB, RB, WB, 0, 0, 0, /* MULB3 */
|
||
2, RB, MB, 0, 0, 0, 0, /* DIVB2 */
|
||
3, RB, RB, WB, 0, 0, 0, /* DIVB3 */
|
||
2, RB, MB, 0, 0, 0, 0, /* BISB2 */
|
||
3, RB, RB, WB, 0, 0, 0, /* BISB3 */
|
||
2, RB, MB, 0, 0, 0, 0, /* BICB2 */
|
||
3, RB, RB, WB, 0, 0, 0, /* BICB3 */
|
||
2, RB, MB, 0, 0, 0, 0, /* XORB2 */
|
||
3, RB, RB, WB, 0, 0, 0, /* XORB3 */
|
||
2, RB, WB, 0, 0, 0, 0, /* MNEGB */
|
||
3, RB, RB, RB, 0, 0, 0, /* CASEB */
|
||
2, RB, WB, 0, 0, 0, 0, /* MOVB */
|
||
2, RB, RB, 0, 0, 0, 0, /* CMPB */
|
||
2, RB, WB, 0, 0, 0, 0, /* MCOMB */
|
||
2, RB, RB, 0, 0, 0, 0, /* BITB */
|
||
1, WB, 0, 0, 0, 0, 0, /* CLRB */
|
||
1, RB, 0, 0, 0, 0, 0, /* TSTB */
|
||
1, MB, 0, 0, 0, 0, 0, /* INCB */
|
||
1, MB, 0, 0, 0, 0, 0, /* DECB */
|
||
2, RB, WL, 0, 0, 0, 0, /* CVTBL */
|
||
2, RB, WW, 0, 0, 0, 0, /* CVTBW */
|
||
2, RB, WL, 0, 0, 0, 0, /* MOVZBL */
|
||
2, RB, WW, 0, 0, 0, 0, /* MOVZBW */
|
||
3, RB, RL, WL, 0, 0, 0, /* ROTL */
|
||
4, RB, RB, MB, BW, 0, 0, /* ACBB */
|
||
2, AB, WL, 0, 0, 0, 0, /* MOVAB */
|
||
1, AB, 0, 0, 0, 0, 0, /* PUSHAB */
|
||
2, RW, MW, 0, 0, 0, 0, /* ADDW2 */
|
||
3, RW, RW, WW, 0, 0, 0, /* ADDW3 */
|
||
2, RW, MW, 0, 0, 0, 0, /* SUBW2 */
|
||
3, RW, RW, WW, 0, 0, 0, /* SUBW3 */
|
||
2, RW, MW, 0, 0, 0, 0, /* MULW2 */
|
||
3, RW, RW, WW, 0, 0, 0, /* MULW3 */
|
||
2, RW, MW, 0, 0, 0, 0, /* DIVW2 */
|
||
3, RW, RW, WW, 0, 0, 0, /* DIVW3 */
|
||
2, RW, MW, 0, 0, 0, 0, /* BISW2 */
|
||
3, RW, RW, WW, 0, 0, 0, /* BISW3 */
|
||
2, RW, MW, 0, 0, 0, 0, /* BICW2 */
|
||
3, RW, RW, WW, 0, 0, 0, /* BICW3 */
|
||
2, RW, MW, 0, 0, 0, 0, /* XORW2 */
|
||
3, RW, RW, WW, 0, 0, 0, /* XORW3 */
|
||
2, RW, WW, 0, 0, 0, 0, /* MNEGW */
|
||
3, RW, RW, RW, 0, 0, 0, /* CASEW */
|
||
2, RW, WW, 0, 0, 0, 0, /* MOVW */
|
||
2, RW, RW, 0, 0, 0, 0, /* CMPW */
|
||
2, RW, WW, 0, 0, 0, 0, /* MCOMW */
|
||
2, RW, RW, 0, 0, 0, 0, /* BITW */
|
||
1, WW, 0, 0, 0, 0, 0, /* CLRW */
|
||
1, RW, 0, 0, 0, 0, 0, /* TSTW */
|
||
1, MW, 0, 0, 0, 0, 0, /* INCW */
|
||
1, MW, 0, 0, 0, 0, 0, /* DECW */
|
||
1, RW, 0, 0, 0, 0, 0, /* BISPSW */
|
||
1, RW, 0, 0, 0, 0, 0, /* BICPSW */
|
||
1, RW, 0, 0, 0, 0, 0, /* POPR */
|
||
1, RW, 0, 0, 0, 0, 0, /* PUSHR */
|
||
1, RW, 0, 0, 0, 0, 0, /* CHMK */
|
||
1, RW, 0, 0, 0, 0, 0, /* CHME */
|
||
1, RW, 0, 0, 0, 0, 0, /* CHMS */
|
||
1, RW, 0, 0, 0, 0, 0, /* CHMU */
|
||
2, RL, ML, 0, 0, 0, 0, /* ADDL2 */
|
||
3, RL, RL, WL, 0, 0, 0, /* ADDL3 */
|
||
2, RL, ML, 0, 0, 0, 0, /* SUBL2 */
|
||
3, RL, RL, WL, 0, 0, 0, /* SUBL3 */
|
||
2, RL, ML, 0, 0, 0, 0, /* MULL2 */
|
||
3, RL, RL, WL, 0, 0, 0, /* MULL3 */
|
||
2, RL, ML, 0, 0, 0, 0, /* DIVL2 */
|
||
3, RL, RL, WL, 0, 0, 0, /* DIVL3 */
|
||
2, RL, ML, 0, 0, 0, 0, /* BISL2 */
|
||
3, RL, RL, WL, 0, 0, 0, /* BISL3 */
|
||
2, RL, ML, 0, 0, 0, 0, /* BICL2 */
|
||
3, RL, RL, WL, 0, 0, 0, /* BICL3 */
|
||
2, RL, ML, 0, 0, 0, 0, /* XORL2 */
|
||
3, RL, RL, WL, 0, 0, 0, /* XORL3 */
|
||
2, RL, WL, 0, 0, 0, 0, /* MNEGL */
|
||
3, RL, RL, RL, 0, 0, 0, /* CASEL */
|
||
2, RL, WL, 0, 0, 0, 0, /* MOVL */
|
||
2, RL, RL, 0, 0, 0, 0, /* CMPL */
|
||
2, RL, WL, 0, 0, 0, 0, /* MCOML */
|
||
2, RL, RL, 0, 0, 0, 0, /* BITL */
|
||
1, WL, 0, 0, 0, 0, 0, /* CLRL */
|
||
1, RL, 0, 0, 0, 0, 0, /* TSTL */
|
||
1, ML, 0, 0, 0, 0, 0, /* INCL */
|
||
1, ML, 0, 0, 0, 0, 0, /* DECL */
|
||
2, RL, ML, 0, 0, 0, 0, /* ADWC */
|
||
2, RL, ML, 0, 0, 0, 0, /* SBWC */
|
||
2, RL, RL, 0, 0, 0, 0, /* MTPR */
|
||
2, RL, WL, 0, 0, 0, 0, /* MFPR */
|
||
1, WL, 0, 0, 0, 0, 0, /* MOVPSL */
|
||
1, RL, 0, 0, 0, 0, 0, /* PUSHL */
|
||
2, AL, WL, 0, 0, 0, 0, /* MOVAL */
|
||
1, AL, 0, 0, 0, 0, 0, /* PUSHAL */
|
||
3, RL, VB, BB, 0, 0, 0, /* BBS */
|
||
3, RL, VB, BB, 0, 0, 0, /* BBC */
|
||
3, RL, VB, BB, 0, 0, 0, /* BBSS */
|
||
3, RL, VB, BB, 0, 0, 0, /* BBCS */
|
||
3, RL, VB, BB, 0, 0, 0, /* BBSC */
|
||
3, RL, VB, BB, 0, 0, 0, /* BBCC */
|
||
3, RL, VB, BB, 0, 0, 0, /* BBSSI */
|
||
3, RL, VB, BB, 0, 0, 0, /* BBCCI */
|
||
2, RL, BB, 0, 0, 0, 0, /* BLBS */
|
||
2, RL, BB, 0, 0, 0, 0, /* BLBC */
|
||
4, RL, RB, VB, WL, 0, 0, /* FFS */
|
||
4, RL, RB, VB, WL, 0, 0, /* FFC */
|
||
4, RL, RB, VB, RL, 0, 0, /* CMPV */
|
||
4, RL, RB, VB, RL, 0, 0, /* CMPZV */
|
||
4, RL, RB, VB, WL, 0, 0, /* EXTV */
|
||
4, RL, RB, VB, WL, 0, 0, /* EXTZV */
|
||
4, RL, RL, RB, VB, 0, 0, /* INSV */
|
||
4, RL, RL, ML, BW, 0, 0, /* ACBL */
|
||
3, RL, ML, BB, 0, 0, 0, /* AOBLSS */
|
||
3, RL, ML, BB, 0, 0, 0, /* AOBLEQ */
|
||
2, ML, BB, 0, 0, 0, 0, /* SOBGEQ */
|
||
2, ML, BB, 0, 0, 0, 0, /* SOBGTR */
|
||
2, RL, WB, 0, 0, 0, 0, /* CVTLB */
|
||
2, RL, WW, 0, 0, 0, 0, /* CVTLW */
|
||
6+DR_F, RB, RW, AB, RB, RW, AB, /* ASHP */
|
||
3+DR_F, RL, RW, AB, 0, 0, 0, /* CVTLP */
|
||
2, AB, AB, 0, 0, 0, 0, /* CALLG */
|
||
2, RL, AB, 0, 0, 0, 0, /* CALLS */
|
||
0, 0, 0, 0, 0, 0, 0, /* XFC */
|
||
0, 0, 0, 0, 0, 0, 0, /* 0FD */
|
||
0, 0, 0, 0, 0, 0, 0, /* 0FE */
|
||
0, 0, 0, 0, 0, 0, 0, /* 0FF */
|
||
0, 0, 0, 0, 0, 0, 0, /* 100-10F */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, /* 110-11F */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, /* 120-12F */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, /* 130-13F */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0x20, RD, OC, 0, 0, 0, 0, /* CVTDH */
|
||
2, RG, WL, 0, 0, 0, 0, /* CVTGF */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
2, RG, MQ, 0, 0, 0, 0, /* ADDG2 */
|
||
3, RG, RG, WQ, 0, 0, 0, /* ADDG3 */
|
||
2, RG, MQ, 0, 0, 0, 0, /* SUBG2 */
|
||
3, RG, RG, WQ, 0, 0, 0, /* SUBG3 */
|
||
2, RG, MQ, 0, 0, 0, 0, /* MULG2 */
|
||
3, RG, RG, WQ, 0, 0, 0, /* MULG3 */
|
||
2, RG, MQ, 0, 0, 0, 0, /* DIVG2 */
|
||
3, RG, RG, WQ, 0, 0, 0, /* DIVG3 */
|
||
2, RG, WB, 0, 0, 0, 0, /* CVTGB */
|
||
2, RG, WW, 0, 0, 0, 0, /* CVTGW */
|
||
2, RG, WL, 0, 0, 0, 0, /* CVTGL */
|
||
2, RG, WL, 0, 0, 0, 0, /* CVTRGL */
|
||
2, RB, WQ, 0, 0, 0, 0, /* CVTBG */
|
||
2, RW, WQ, 0, 0, 0, 0, /* CVTWG */
|
||
2, RL, WQ, 0, 0, 0, 0, /* CVTLG */
|
||
4, RG, RG, MQ, BW, 0, 0, /* ACBG */
|
||
2, RG, WQ, 0, 0, 0, 0, /* MOVG */
|
||
2, RG, RG, 0, 0, 0, 0, /* CMPG */
|
||
2, RG, WQ, 0, 0, 0, 0, /* MNEGG */
|
||
1, RG, 0, 0, 0, 0, 0, /* TSTG */
|
||
5, RG, RW, RG, WL, WQ, 0, /* EMODG */
|
||
3, RG, RW, AB, 0, 0, 0, /* POLYG */
|
||
0x20, RG, OC, 0, 0, 0, 0, /* CVTGH */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0x20, OC, OC, 0, 0, 0, 0, /* ADDH2 */
|
||
0x30, OC, OC, OC, 0, 0, 0, /* ADDH3 */
|
||
0x20, OC, OC, 0, 0, 0, 0, /* SUBH2 */
|
||
0x30, OC, OC, OC, 0, 0, 0, /* SUBH3 */
|
||
0x20, OC, OC, 0, 0, 0, 0, /* MULH2 */
|
||
0x30, OC, OC, OC, 0, 0, 0, /* MULH3 */
|
||
0x20, OC, OC, 0, 0, 0, 0, /* DIVH2 */
|
||
0x30, OC, OC, OC, 0, 0, 0, /* DIVH3 */
|
||
0x20, OC, WB, 0, 0, 0, 0, /* CVTHB */
|
||
0x20, OC, WW, 0, 0, 0, 0, /* CVTHW */
|
||
0x20, OC, WL, 0, 0, 0, 0, /* CVTHL */
|
||
0x20, OC, WL, 0, 0, 0, 0, /* CVTRHL */
|
||
0x20, RB, OC, 0, 0, 0, 0, /* CVTBH */
|
||
0x20, RW, OC, 0, 0, 0, 0, /* CVTWH */
|
||
0x20, RL, OC, 0, 0, 0, 0, /* CVTLH */
|
||
0x40, OC, OC, OC, BW, 0, 0, /* ACBH */
|
||
0x20, OC, OC, 0, 0, 0, 0, /* MOVH */
|
||
0x20, OC, OC, 0, 0, 0, 0, /* CMPH */
|
||
0x20, OC, OC, 0, 0, 0, 0, /* MNEGH */
|
||
0x10, OC, 0, 0, 0, 0, 0, /* TSTH */
|
||
0x50, OC, RW, OC, WL, OC, 0, /* EMODH */
|
||
0x30, OC, RW, AB, 0, 0, 0, /* POLYH */
|
||
0x20, OC, WQ, 0, 0, 0, 0, /* CVTHG */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0, 0, 0, 0, 0, 0, 0, /* reserved */
|
||
0x10, OC, 0, 0, 0, 0, 0, /* CLRO */
|
||
0x20, OC, OC, 0, 0, 0, 0, /* MOVO */
|
||
0x20, OC, WL, 0, 0, 0, 0, /* MOVAO*/
|
||
0x10, OC, 0, 0, 0, 0, 0, /* PUSHAO*/
|
||
0, 0, 0, 0, 0, 0, 0, /* 180-18F */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, /* 190-19F */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0x20, RF, OC, 0, 0, 0, 0, /* CVTFH */
|
||
2, RF, WQ, 0, 0, 0, 0, /* CVTFG */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, /* 1A0-1AF */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, /* 1B0-1BF */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, /* 1C0-1CF */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, /* 1D0-1DF */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, /* 1E0-1EF */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, /* 1F0-1FF */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0x20, OC, WL, 0, 0, 0, 0, /* CVTHF */
|
||
0x20, OC, WQ, 0, 0, 0, 0, /* CVTHD */
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0 };
|
||
|
||
/* Opcode mnemonics table */
|
||
|
||
const char *opcode[] = {
|
||
"HALT", "NOP", "REI", "BPT", "RET", "RSB", "LDPCTX", "SVPCTX",
|
||
"CVTPS", "CVTSP", "INDEX", "CRC", "PROBER", "PROBEW", "INSQUE", "REMQUE",
|
||
"BSBB", "BRB", "BNEQ", "BEQL", "BGTR", "BLEQ", "JSB", "JMP",
|
||
"BGEQ", "BLSS", "BGTRU", "BLEQU", "BVC", "BVS", "BGEQU", "BLSSU",
|
||
"ADDP4", "ADDP6", "SUBP4", "SUBP6", "CVTPT", "MULP6", "CVTTP", "DIVP",
|
||
"MOVC3", "CMPC3", "SCANC", "SPANC", "MOVC5", "CMPC5", "MOVTC", "MOVTUC",
|
||
"BSBW", "BRW", "CVTWL", "CVTWB", "MOVP", "CMPP3", "CVTPL", "CMPP4",
|
||
"EDITPC", "MATCHC", "LOCC", "SKPC", "MOVZWL", "ACBW", "MOVAW", "PUSHAW",
|
||
"ADDF2", "ADDF3", "SUBF2", "SUBF3", "MULF2", "MULF3", "DIVF2", "DIVF3",
|
||
"CVTFB", "CVTFW", "CVTFL", "CVTRFL", "CVTBF", "CVTWF", "CVTLF", "ACBF",
|
||
"MOVF", "CMPF", "MNEGF", "TSTF", "EMODF", "POLYF", "CVTFD", NULL,
|
||
"ADAWI", NULL, NULL, NULL, "INSQHI", "INSQTI", "REMQHI", "REMQTI",
|
||
"ADDD2", "ADDD3", "SUBD2", "SUBD3", "MULD2", "MULD3", "DIVD2", "DIVD3",
|
||
"CVTDB", "CVTDW", "CVTDL", "CVTRDL", "CVTBD", "CVTWD", "CVTLD", "ACBD",
|
||
"MOVD", "CMPD", "MNEGD", "TSTD", "EMODD", "POLYD", "CVTDF", NULL,
|
||
"ASHL", "ASHQ", "EMUL", "EDIV", "CLRQ", "MOVQ", "MOVAQ", "PUSHAQ",
|
||
"ADDB2", "ADDB3", "SUBB2", "SUBB3", "MULB2", "MULB3", "DIVB2", "DIVB3",
|
||
"BISB2", "BISB3", "BICB2", "BICB3", "XORB2", "XORB3", "MNEGB", "CASEB",
|
||
"MOVB", "CMPB", "MCOMB", "BITB", "CLRB", "TSTB", "INCB", "DECB",
|
||
"CVTBL", "CVTBW", "MOVZBL", "MOVZBW", "ROTL", "ACBB", "MOVAB", "PUSHAB",
|
||
"ADDW2", "ADDW3", "SUBW2", "SUBW3", "MULW2", "MULW3", "DIVW2", "DIVW3",
|
||
"BISW2", "BISW3", "BICW2", "BICW3", "XORW2", "XORW3", "MNEGW", "CASEW",
|
||
"MOVW", "CMPW", "MCOMW", "BITW", "CLRW", "TSTW", "INCW", "DECW",
|
||
"BISPSW", "BICPSW", "POPR", "PUSHR", "CHMK", "CHME", "CHMS", "CHMU",
|
||
"ADDL2", "ADDL3", "SUBL2", "SUBL3", "MULL2", "MULL3", "DIVL2", "DIVL3",
|
||
"BISL2", "BISL3", "BICL2", "BICL3", "XORL2", "XORL3", "MNEGL", "CASEL",
|
||
"MOVL", "CMPL", "MCOML", "BITL", "CLRL", "TSTL", "INCL", "DECL",
|
||
"ADWC", "SBWC", "MTPR", "MFPR", "MOVPSL", "PUSHL", "MOVAL", "PUSHAL",
|
||
"BBS", "BBC", "BBSS", "BBCS", "BBSC", "BBCC", "BBSSI", "BBCCI",
|
||
"BLBS", "BLBC", "FFS", "FFC", "CMPV", "CMPZV", "EXTV", "EXTZV",
|
||
"INSV", "ACBL", "AOBLSS", "AOBLEQ", "SOBGEQ", "SOBGTR", "CVTLB", "CVTLW",
|
||
"ASHP", "CVTLP", "CALLG", "CALLS", "XFC", NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 100 - 11F */
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 120 - 13F */
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, "CVTDH", "CVTGF", NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
"ADDG2", "ADDG3", "SUBG2", "SUBG3", "MULG2", "MULG3", "DIVG2", "DIVG3",
|
||
"CVTGB", "CVTGW", "CVTGL", "CVTRGL", "CVTBG", "CVTWG", "CVTLG", "ACBG",
|
||
"MOVG", "CMPG", "MNEGG", "TSTG", "EMODG", "POLYG", "CVTGH", NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
"ADDH2", "ADDH3", "SUBH2", "SUBH3", "MULH2", "MULH3", "DIVH2", "DIVH3",
|
||
"CVTHB", "CVTHW", "CVTHL", "CVTRHL", "CVTBH", "CVTWH", "CVTLH", "ACBH",
|
||
"MOVH", "CMPH", "MNEGH", "TSTH", "EMODH", "POLYH", "CVTHG", NULL,
|
||
NULL, NULL, NULL, NULL, "CLRO", "MOVO", "MOVAO", "PUSHAO",
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 180 - 19F */
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
"CVTFH", "CVTFG", NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 1A0 - 1BF */
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 1C0 - 1DF */
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 1E0 - 1FF */
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, "CVTHF", "CVTHD",
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||
|
||
const char *altcod[] = {
|
||
"CLRF", "CLRD", "CLRG", "CLRH", "MOVAF", "MOVAD", "MOVAG", "MOVAH",
|
||
"PUSHAF", "PUSHAD", "PUSHAG", "PUSHAH", "BNEQU", "BEQLU", "BCC", "BCS",
|
||
NULL };
|
||
|
||
const int32 altop[] = {
|
||
0xD4, 0x7C, 0x7C, 0x17C, 0xDE, 0x7E, 0x7E, 0x17E,
|
||
0xDF, 0x7F, 0x7F, 0x17F, 0x12, 0x13, 0x1E, 0x1F };
|
||
|
||
const char* regname[] = {
|
||
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
|
||
"R8", "R9", "R10", "R11", "AP", "FP", "SP", "PC" };
|
||
|
||
#define GETNUM(d,n) for (k = d = 0; k < n; k++) \
|
||
d = d | (((int32) val[vp++]) << (k * 8))
|
||
|
||
/* Symbolic decode
|
||
|
||
Inputs:
|
||
*of = output stream
|
||
addr = current PC
|
||
*val = values to decode
|
||
*uptr = pointer to unit
|
||
sw = switches
|
||
Outputs:
|
||
return = if >= 0, error code
|
||
if < 0, number of extra bytes retired
|
||
*/
|
||
|
||
t_stat fprint_sym (FILE *of, t_addr exta, t_value *val,
|
||
UNIT *uptr, int32 sw)
|
||
{
|
||
uint32 addr = (uint32) exta;
|
||
int32 c, k, num, vp, lnt, rdx;
|
||
t_stat r;
|
||
DEVICE *dptr;
|
||
|
||
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
||
dptr = find_dev_from_unit (uptr); /* find dev */
|
||
if (dptr == NULL) return SCPE_IERR;
|
||
if (dptr->dwidth != 8) return SCPE_ARG; /* byte dev only */
|
||
if (sw & SWMASK ('B')) lnt = 1; /* get length */
|
||
else if (sw & SWMASK ('W')) lnt = 2;
|
||
else if (sw & SWMASK ('L')) lnt = 4;
|
||
else lnt = (uptr == &cpu_unit)? 4: 1;
|
||
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
||
else if (sw & SWMASK ('O')) rdx = 8;
|
||
else if (sw & SWMASK ('H')) rdx = 16;
|
||
else rdx = dptr->dradix;
|
||
vp = 0; /* init ptr */
|
||
if ((sw & SWMASK ('A')) || (sw & SWMASK ('C'))) { /* char format? */
|
||
if (sw & SWMASK ('C')) lnt = sim_emax; /* -c -> string */
|
||
if ((val[0] & 0x7F) == 0) return SCPE_ARG;
|
||
while (vp < lnt) { /* print string */
|
||
if ((c = (int32) val[vp++] & 0x7F) == 0) break;
|
||
fprintf (of, (c < 0x20)? "<%02X>": "%c", c); }
|
||
return -(vp - 1); } /* return # chars */
|
||
|
||
if (sw & SWMASK ('M') && (uptr == &cpu_unit)) { /* inst format? */
|
||
r = fprint_sym_m (of, addr, val); /* decode inst */
|
||
if (r <= 0) return r; }
|
||
|
||
GETNUM (num, lnt); /* get number */
|
||
fprint_val (of, (uint32) num, rdx, lnt * 8, PV_RZRO);
|
||
return -(vp - 1);
|
||
}
|
||
|
||
/* Symbolic decode for -m
|
||
|
||
Inputs:
|
||
of = output stream
|
||
addr = current PC
|
||
*val = values to decode
|
||
Outputs:
|
||
return = if >= 0, error code
|
||
if < 0, number of extra bytes retired
|
||
*/
|
||
|
||
t_stat fprint_sym_m (FILE *of, uint32 addr, t_value *val)
|
||
{
|
||
int32 i, k, vp, inst, numspec;
|
||
int32 num, spec, rn, disp, index;
|
||
|
||
vp = 0; /* init ptr */
|
||
inst = (int32) val[vp++]; /* get opcode */
|
||
if (inst == 0xFD) inst = 0x100 | (int32) val[vp++]; /* 2 byte op? */
|
||
if (opcode[inst] == NULL) return SCPE_ARG; /* defined? */
|
||
numspec = drom[inst][0] & DR_NSPMASK; /* get # spec */
|
||
if (numspec == 0) numspec = (drom[inst][0] & DR_USPMASK) >> 4;
|
||
fprintf (of, "%s", opcode[inst]); /* print name */
|
||
for (i = 0; i < numspec; i++) { /* loop thru spec */
|
||
fputc (i? ',': ' ', of); /* separator */
|
||
disp = drom[inst][i + 1]; /* get drom value */
|
||
if (disp == BB) { /* byte br disp? */
|
||
GETNUM (num, 1);
|
||
fprintf (of, "%-X", SXTB (num) + addr + vp); }
|
||
else if (disp == BW) { /* word br disp? */
|
||
GETNUM (num, 2);
|
||
fprintf (of, "%-X", SXTW (num) + addr + vp); }
|
||
else {
|
||
spec = (int32) val[vp++]; /* get specifier */
|
||
if ((spec & 0xF0) == IDX) { /* index? */
|
||
index = spec; /* copy, get next */
|
||
spec = (int32) val[vp++]; }
|
||
else index = 0;
|
||
rn = spec & 0xF; /* get reg # */
|
||
switch (spec & 0xF0) { /* case on mode */
|
||
case SH0: case SH1: case SH2: case SH3: /* s^# */
|
||
fprintf (of, "#%-X", spec);
|
||
break;
|
||
case GRN: /* Rn */
|
||
fprintf (of, "%-s", regname[rn]);
|
||
break;
|
||
case RGD: /* (Rn) */
|
||
fprintf (of, "(%-s)", regname[rn]);
|
||
break;
|
||
case ADC: /* -(Rn) */
|
||
fprintf (of, "-(%-s)", regname[rn]);
|
||
break;
|
||
case AIN: /* (Rn)+, #n */
|
||
if (rn != nPC) fprintf (of, "(%-s)+", regname[rn]);
|
||
else {
|
||
if (disp == OC)
|
||
vp = fprint_sym_qoimm (of, val, vp, 4);
|
||
else if (DR_LNT (disp) == L_QUAD)
|
||
vp = fprint_sym_qoimm (of, val, vp, 2);
|
||
else {
|
||
GETNUM (num, DR_LNT (disp));
|
||
fprintf (of, "#%-X", num); } }
|
||
break;
|
||
case AID: /* @(Rn)+, @#n */
|
||
if (rn != nPC) fprintf (of, "@(%-s)+", regname[rn]);
|
||
else {
|
||
GETNUM (num, 4);
|
||
fprintf (of, "@#%-X", num); }
|
||
break;
|
||
case BDD: /* @b^d(r),@b^n */
|
||
fputc ('@', of);
|
||
case BDP: /* b^d(r), b^n */
|
||
GETNUM (num, 1);
|
||
if (rn == nPC) fprintf (of, "%-X", addr + vp + SXTB (num));
|
||
else if (num & BSIGN) fprintf (of, "-%-X(%-s)",
|
||
-num & BMASK, regname[rn]);
|
||
else fprintf (of, "%-X(%-s)", num, regname[rn]);
|
||
break;
|
||
case WDD: /* @w^d(r),@w^n */
|
||
fputc ('@', of);
|
||
case WDP: /* w^d(r), w^n */
|
||
GETNUM (num, 2);
|
||
if (rn == nPC) fprintf (of, "%-X", addr + vp + SXTW (num));
|
||
else if (num & WSIGN) fprintf (of, "-%-X(%-s)",
|
||
-num & WMASK, regname[rn]);
|
||
else fprintf (of, "%-X(%-s)", num, regname[rn]);
|
||
break;
|
||
case LDD: /* @l^d(r),@l^n */
|
||
fputc ('@', of);
|
||
case LDP: /* l^d(r),l^n */
|
||
GETNUM (num, 4);
|
||
if (rn == nPC) fprintf (of, "%-X", addr + vp + num);
|
||
else if (num & LSIGN) fprintf (of, "-%-X(%-s)",
|
||
-num, regname[rn]);
|
||
else fprintf (of, "%-X(%-s)", num, regname[rn]);
|
||
break; } /* end case */
|
||
if (index) fprintf (of, "[%-s]", regname[index & 0xF]);
|
||
} /* end else */
|
||
} /* end for */
|
||
return -(vp - 1);
|
||
}
|
||
|
||
/* Symbolic decode, quad/octa immediates
|
||
|
||
Inputs:
|
||
*of = output stream
|
||
*val = pointer to input values
|
||
vp = current index into val
|
||
lnt = number of longwords in immediate
|
||
Outputs:
|
||
vp = updated index into val
|
||
*/
|
||
|
||
int32 fprint_sym_qoimm (FILE *of, t_value *val, int32 vp, int32 lnt)
|
||
{
|
||
int32 i, k, startp, num[4];
|
||
|
||
for (i = 0; i < lnt; i++) { GETNUM (num[lnt - 1 - i], 4); }
|
||
for (i = startp = 0; i < lnt; i++) {
|
||
if (startp) fprintf (of, "%08X", num[i]);
|
||
else if (num[i] || (i == (lnt - 1))) {
|
||
fprintf (of, "#%-X", num[i]);
|
||
startp = 1; } }
|
||
return vp;
|
||
}
|
||
|
||
#define PUTNUM(d,n) for (k = 0; k < n; k++) val[vp++] = (d >> (k * 8)) & 0xFF
|
||
|
||
/* Symbolic input
|
||
|
||
Inputs:
|
||
*cptr = pointer to input string
|
||
addr = current PC
|
||
*uptr = pointer to unit
|
||
*val = pointer to output values
|
||
sw = switches
|
||
Outputs:
|
||
status = > 0 error code
|
||
<= 0 -number of extra words
|
||
*/
|
||
|
||
t_stat parse_sym (char *cptr, t_addr exta, UNIT *uptr, t_value *val, int32 sw)
|
||
{
|
||
uint32 addr = (uint32) exta;
|
||
int32 k, rdx, lnt, num, vp;
|
||
t_stat r;
|
||
DEVICE *dptr;
|
||
static const uint32 maxv[5] = { 0, 0xFF, 0xFFFF, 0, 0xFFFFFFFF };
|
||
|
||
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
||
dptr = find_dev_from_unit (uptr); /* find dev */
|
||
if (dptr == NULL) return SCPE_IERR;
|
||
if (dptr->dwidth != 8) return SCPE_ARG; /* byte dev only */
|
||
if (sw & SWMASK ('B')) lnt = 1; /* get length */
|
||
else if (sw & SWMASK ('W')) lnt = 2;
|
||
else if (sw & SWMASK ('L')) lnt = 4;
|
||
else lnt = (uptr == &cpu_unit)? 4: 1;
|
||
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
||
else if (sw & SWMASK ('O')) rdx = 8;
|
||
else if (sw & SWMASK ('H')) rdx = 16;
|
||
else rdx = dptr->dradix;
|
||
vp = 0;
|
||
if ((sw & SWMASK ('A')) || (sw & SWMASK ('C'))) { /* char format? */
|
||
if (sw & SWMASK ('C')) lnt = sim_emax; /* -c -> string */
|
||
if (*cptr == 0) return SCPE_ARG;
|
||
while ((vp < lnt) && *cptr) { /* get chars */
|
||
val[vp++] = *cptr++; }
|
||
return -(vp - 1); } /* return # chars */
|
||
|
||
if (uptr == &cpu_unit) { /* cpu only */
|
||
r = parse_sym_m (cptr, addr, val); /* try to parse inst */
|
||
if (r <= 0) return r; }
|
||
|
||
num = (int32) get_uint (cptr, rdx, maxv[lnt], &r); /* get number */
|
||
if (r != SCPE_OK) return r;
|
||
PUTNUM (num, lnt); /* store */
|
||
return -(lnt - 1);
|
||
}
|
||
|
||
/* Symbolic input for -m
|
||
|
||
Inputs:
|
||
*cptr = pointer to input string
|
||
addr = current PC
|
||
*val = pointer to output values
|
||
Outputs:
|
||
status = > 0 error code
|
||
<= 0 -number of extra words
|
||
*/
|
||
|
||
t_stat parse_sym_m (char *cptr, uint32 addr, t_value *val)
|
||
{
|
||
int32 i, numspec, disp, opc, vp;
|
||
t_stat r;
|
||
char gbuf[CBUFSIZE];
|
||
|
||
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
|
||
for (i = 0, opc = -1; (i < NUM_INST) && (opc < 0); i++) {
|
||
if (opcode[i] && strcmp (gbuf, opcode[i]) == 0) opc = i; }
|
||
if (opc < 0) { /* check alternates */
|
||
for (i = 0; altcod[i] && (opc < 0); i++) {
|
||
if (strcmp (gbuf, altcod[i]) == 0) opc = altop[i]; } }
|
||
if (opc < 0) return SCPE_ARG; /* undefined? */
|
||
vp = 0;
|
||
if (opc >= 0x100) val[vp++] = 0xFD; /* 2 byte? */
|
||
val[vp++] = opc & 0xFF; /* store opcode */
|
||
numspec = drom[opc][0] & DR_NSPMASK; /* get # specifiers */
|
||
if (numspec == 0) numspec = (drom[opc][0] & DR_USPMASK) >> 4;
|
||
for (i = 1; i <= numspec; i++) { /* loop thru specs */
|
||
if (i == numspec) cptr = get_glyph (cptr, gbuf, 0);
|
||
else cptr = get_glyph (cptr, gbuf, ','); /* get specifier */
|
||
disp = drom[opc][i]; /* get drom value */
|
||
if (disp == BB) vp = parse_brdisp (gbuf, addr, val, vp, 0, &r);
|
||
else if (disp == BW) vp = parse_brdisp (gbuf, addr, val, vp, 1, &r);
|
||
else vp = parse_spec (gbuf, addr, val, vp, disp, &r);
|
||
if (r != SCPE_OK) return r; }
|
||
if (*cptr != 0) return SCPE_ARG;
|
||
return -(vp - 1);
|
||
}
|
||
|
||
/* Parse a branch displacement
|
||
|
||
Inputs:
|
||
cptr = pointer to input buffer
|
||
addr = current address
|
||
val = pointer to output array
|
||
vp = current pointer in output array
|
||
lnt = length (0 = byte, 1 = word)
|
||
r = pointer to status
|
||
Outputs:
|
||
vp = updated output pointer
|
||
*/
|
||
|
||
int32 parse_brdisp (char *cptr, uint32 addr, t_value *val, int32 vp,
|
||
int32 lnt, t_stat *r)
|
||
{
|
||
int32 k, dest, num;
|
||
|
||
dest = (int32) get_uint (cptr, 16, 0xFFFFFFFF, r); /* get value */
|
||
num = dest - (addr + vp + lnt + 1); /* compute offset */
|
||
if ((num > (lnt? 32767: 127)) || (num < (lnt? -32768: -128))) return SCPE_ARG;
|
||
PUTNUM (num, lnt + 1); /* store offset */
|
||
return vp;
|
||
}
|
||
|
||
/* Parse a specifier
|
||
|
||
Inputs:
|
||
cptr = pointer to input buffer
|
||
addr = current address
|
||
val = pointer to output array
|
||
vp = current pointer in output array
|
||
disp = specifier dispatch
|
||
r = pointer to status
|
||
Outputs:
|
||
vp = updated output pointer
|
||
*/
|
||
|
||
#define SP_IND 0x200 /* indirect */
|
||
#define SP_V_FORCE 6
|
||
#define SP_FS 0x040 /* S^ */
|
||
#define SP_FI 0x080 /* I^ */
|
||
#define SP_FB 0x0C0 /* B^ */
|
||
#define SP_FW 0x100 /* W^ */
|
||
#define SP_FL 0x140 /* L^ */
|
||
#define SP_LIT 0x020 /* # */
|
||
#define SP_PLUS 0x010 /* plus */
|
||
#define SP_MINUS 0x008 /* minus */
|
||
#define SP_NUM 0x004 /* number */
|
||
#define SP_IDX 0x002 /* (Rn) */
|
||
#define SP_POSTP 0x001 /* trailing + */
|
||
#define M1C(c,v) if (*cptr == c) { cptr++; fl = fl | v; }
|
||
#define SPUTNUM(v,d) if (fl & SP_MINUS) v = -v; PUTNUM (v, d)
|
||
#define PARSE_LOSE { *r = SCPE_ARG; return vp; }
|
||
#define SEL_LIM(p,m,u) ((fl & SP_PLUS)? (p): ((fl & SP_MINUS)? (m): (u)))
|
||
|
||
int32 parse_spec (char *cptr, uint32 addr, t_value *val, int32 vp, int32 disp, t_stat *r)
|
||
{
|
||
int32 i, k, litsize, rn, index;
|
||
int32 num, dispsize, mode;
|
||
int32 lit[4] = { 0 };
|
||
int32 fl = 0;
|
||
char c, *tptr;
|
||
const char *force[] = { "S^", "I^", "B^", "W^", "L^", NULL };
|
||
|
||
*r = SCPE_OK; /* assume ok */
|
||
M1C ('@', SP_IND); /* look for @ */
|
||
if (tptr = parse_rnum (cptr, &rn)) { /* look for Rn */
|
||
if (*cptr == '[') { /* look for [Rx] */
|
||
cptr = parse_rnum (++cptr, &index);
|
||
if ((cptr == NULL) || (*cptr++ != ']')) PARSE_LOSE;
|
||
val[vp++] = index | IDX; }
|
||
else val[vp++] = rn | GRN | (fl? 1: 0); /* Rn or @Rn */
|
||
if (*tptr != 0) *r = SCPE_ARG; /* must be done */
|
||
return vp; }
|
||
for (i = 0; force[i]; i++) { /* look for x^ */
|
||
if (strncmp (cptr, force[i], 2) == 0) {
|
||
cptr = cptr + 2;
|
||
fl = fl | ((i + 1) << SP_V_FORCE);
|
||
break; } }
|
||
M1C ('#', SP_LIT); /* look for # */
|
||
M1C ('+', SP_PLUS); /* look for + */
|
||
M1C ('-', SP_MINUS); /* look for - */
|
||
for (litsize = 0;; cptr++) { /* look for mprec int */
|
||
c = *cptr;
|
||
if ((c < '0') || (c > 'F') || ((c > '9') && (c < 'A'))) break;
|
||
num = (c <= '9')? c - '0': c - 'A' + 10;
|
||
fl = fl | SP_NUM;
|
||
for (i = 3; i >= 0; i--) {
|
||
lit[i] = lit[i] << 4;
|
||
if (i > 0) lit[i] = lit[i] | ((lit[i - 1] >> 28) & 0xF);
|
||
else lit[i] = lit[i] | num;
|
||
if (lit[i] && (i > litsize)) litsize = i; } }
|
||
if (*cptr == '(') { /* look for (Rn) */
|
||
cptr = parse_rnum (++cptr, &rn);
|
||
if ((cptr == NULL) || (*cptr++ != ')')) PARSE_LOSE;
|
||
fl = fl | SP_IDX; }
|
||
M1C ('+', SP_POSTP); /* look for + */
|
||
if (*cptr == '[') { /* look for [Rx] */
|
||
cptr = parse_rnum (++cptr, &index);
|
||
if ((cptr == NULL) || (*cptr++ != ']')) PARSE_LOSE;
|
||
val[vp++] = index | IDX; }
|
||
switch (fl) { /* case on state */
|
||
case SP_FS|SP_LIT|SP_NUM: /* S^#n */
|
||
case SP_FS|SP_LIT|SP_PLUS|SP_NUM: /* S^#+n */
|
||
if ((litsize > 0) || (lit[0] & ~0x3F)) PARSE_LOSE;
|
||
val[vp++] = lit[0];
|
||
break;
|
||
case SP_IDX: /* (Rn) */
|
||
val[vp++] = rn | RGD;
|
||
break;
|
||
case SP_MINUS|SP_IDX: /* -(Rn) */
|
||
val[vp++] = rn | ADC;
|
||
break;
|
||
case SP_IDX|SP_POSTP: /* (Rn)+ */
|
||
val[vp++] = rn | AIN;
|
||
break;
|
||
case SP_LIT|SP_NUM: /* #n */
|
||
case SP_LIT|SP_PLUS|SP_NUM: /* #+n */
|
||
if ((litsize == 0) && ((lit[0] & ~0x3F) == 0)) {
|
||
val[vp++] = lit[0];
|
||
break; }
|
||
case SP_LIT|SP_MINUS|SP_NUM: /* #-n */
|
||
case SP_FI|SP_LIT|SP_NUM: /* I^#n */
|
||
case SP_FI|SP_LIT|SP_PLUS|SP_NUM: /* I^#+n */
|
||
case SP_FI|SP_LIT|SP_MINUS|SP_NUM: /* I^#-n */
|
||
val[vp++] = nPC | AIN;
|
||
disp = (disp == OC)? DR_LNMASK + 1: disp & DR_LNMASK;
|
||
switch (disp) { /* case spec lnt */
|
||
case 00: /* check fit */
|
||
if ((litsize > 0) || (lit[0] < 0) ||
|
||
(lit[0] > SEL_LIM (0x7F, 0x80, 0xFF))) PARSE_LOSE;
|
||
SPUTNUM (lit[0], 1); /* store */
|
||
break;
|
||
case 01: /* check fit */
|
||
if ((litsize > 0) || (lit[0] < 0) ||
|
||
(lit[0] > SEL_LIM (0x7FFF, 0x8000, 0xFFFF))) PARSE_LOSE;
|
||
SPUTNUM (lit[0], 2);
|
||
break;
|
||
case 02: /* check 1 lw */
|
||
if (litsize > 0) PARSE_LOSE;
|
||
SPUTNUM (lit[0], 4);
|
||
break;
|
||
case 03: /* check 2 lw */
|
||
if (litsize > 1) PARSE_LOSE;
|
||
vp = parse_sym_qoimm (lit, val, vp, 2, fl & SP_MINUS);
|
||
break;
|
||
case DR_LNMASK + 1:
|
||
vp = parse_sym_qoimm (lit, val, vp, 4, fl & SP_MINUS);
|
||
break; } /* end case disp */
|
||
break;
|
||
case SP_IND|SP_IDX|SP_POSTP: /* @(Rn)+ */
|
||
val[vp++] = rn | AID;
|
||
break;
|
||
case SP_IND|SP_LIT|SP_NUM: /* @#n */
|
||
if (litsize > 0) PARSE_LOSE;
|
||
val[vp++] = nPC | AID;
|
||
PUTNUM (lit[0], 4);
|
||
break;
|
||
case SP_NUM|SP_IDX: /* d(rn) */
|
||
case SP_PLUS|SP_NUM|SP_IDX: /* +d(rn) */
|
||
case SP_MINUS|SP_NUM|SP_IDX: /* -d(rn) */
|
||
case SP_IND|SP_NUM|SP_IDX: /* @d(rn) */
|
||
case SP_IND|SP_PLUS|SP_NUM|SP_IDX: /* @+d(rn) */
|
||
case SP_IND|SP_MINUS|SP_NUM|SP_IDX: /* @-d(rn) */
|
||
if (litsize > 0) PARSE_LOSE;
|
||
dispsize = 4; /* find fit for */
|
||
mode = LDP; /* displacement */
|
||
if (lit[0] >= 0) {
|
||
if (lit[0] <= SEL_LIM (0x7F, 0x80, 0xFF)) {
|
||
dispsize = 1;
|
||
mode = BDP; }
|
||
else if (lit[0] <= SEL_LIM (0x7FFF, 0x8000, 0xFFFF)) {
|
||
dispsize = 2;
|
||
mode = WDP; } }
|
||
val[vp++] = mode | rn | ((fl & SP_IND)? 1: 0);
|
||
SPUTNUM (lit[0], dispsize);
|
||
break;
|
||
case SP_FB|SP_NUM|SP_IDX: /* B^d(rn) */
|
||
case SP_FB|SP_PLUS|SP_NUM|SP_IDX: /* B^+d(rn) */
|
||
case SP_FB|SP_MINUS|SP_NUM|SP_IDX: /* B^-d(rn) */
|
||
case SP_IND|SP_FB|SP_NUM|SP_IDX: /* @B^d(rn) */
|
||
case SP_IND|SP_FB|SP_PLUS|SP_NUM|SP_IDX: /* @B^+d(rn) */
|
||
case SP_IND|SP_FB|SP_MINUS|SP_NUM|SP_IDX: /* @B^-d(rn) */
|
||
if ((litsize > 0) || (lit[0] < 0) ||
|
||
(lit[0] > SEL_LIM (0x7F, 0x80, 0xFF))) PARSE_LOSE;
|
||
val[vp++] = rn | BDP | ((fl & SP_IND)? 1: 0);
|
||
SPUTNUM (lit[0], 1);
|
||
break;
|
||
case SP_FW|SP_NUM|SP_IDX: /* W^d(rn) */
|
||
case SP_FW|SP_PLUS|SP_NUM|SP_IDX: /* W^+d(rn) */
|
||
case SP_FW|SP_MINUS|SP_NUM|SP_IDX: /* W^-d(rn) */
|
||
case SP_IND|SP_FW|SP_NUM|SP_IDX: /* @W^d(rn) */
|
||
case SP_IND|SP_FW|SP_PLUS|SP_NUM|SP_IDX: /* @W^+d(rn) */
|
||
case SP_IND|SP_FW|SP_MINUS|SP_NUM|SP_IDX: /* @W^-d(rn) */
|
||
if ((litsize > 0) || (lit[0] < 0) ||
|
||
(lit[0] > SEL_LIM (0x7FFF, 0x8000, 0xFFFF))) PARSE_LOSE;
|
||
val[vp++] = rn | WDP | ((fl & SP_IND)? 1: 0);
|
||
SPUTNUM (lit[0], 2);
|
||
break;
|
||
case SP_FL|SP_NUM|SP_IDX: /* L^d(rn) */
|
||
case SP_FL|SP_PLUS|SP_NUM|SP_IDX: /* L^+d(rn) */
|
||
case SP_FL|SP_MINUS|SP_NUM|SP_IDX: /* L^-d(rn) */
|
||
case SP_IND|SP_FL|SP_NUM|SP_IDX: /* @L^d(rn) */
|
||
case SP_IND|SP_FL|SP_PLUS|SP_NUM|SP_IDX: /* @L^+d(rn) */
|
||
case SP_IND|SP_FL|SP_MINUS|SP_NUM|SP_IDX: /* @L^-d(rn) */
|
||
if ((litsize > 0) || (lit[0] < 0)) PARSE_LOSE;
|
||
val[vp++] = rn | LDP | ((fl & SP_IND)? 1: 0);
|
||
SPUTNUM (lit[0], 2);
|
||
break;
|
||
case SP_NUM: /* n */
|
||
case SP_IND|SP_NUM: /* @n */
|
||
if (litsize > 0) PARSE_LOSE;
|
||
num = lit[0] - (addr + vp + 2); /* fit in byte? */
|
||
if ((num >= -128) && (num <= 127)) {
|
||
mode = BDP;
|
||
dispsize = 1; }
|
||
else {
|
||
num = lit[0] - (addr + vp + 3); /* fit in word? */
|
||
if ((num >= -32768) && (num <= 32767)) {
|
||
mode = WDP;
|
||
dispsize = 2; }
|
||
else {
|
||
num = lit[0] - (addr + vp + 5); /* no, use lw */
|
||
mode = LDP;
|
||
dispsize = 4; } }
|
||
val[vp++] = mode | nPC | ((fl & SP_IND)? 1: 0);
|
||
PUTNUM (num, dispsize);
|
||
break;
|
||
case SP_FB|SP_NUM: /* B^n */
|
||
case SP_IND|SP_FB|SP_NUM: /* @B^n */
|
||
num = lit[0] - (addr + vp + 2);
|
||
if ((litsize > 0) || (num > 127) || (num < -128)) PARSE_LOSE;
|
||
val[vp++] = nPC | BDP | ((fl & SP_IND)? 1: 0);
|
||
PUTNUM (num, 1);
|
||
break;
|
||
case SP_FW|SP_NUM: /* W^n */
|
||
case SP_IND|SP_FW|SP_NUM: /* @W^n */
|
||
num = lit[0] - (addr + vp + 3);
|
||
if ((litsize > 0) || (num > 32767) || (num < -32768)) PARSE_LOSE;
|
||
val[vp++] = nPC | WDP | ((fl & SP_IND)? 1: 0);
|
||
PUTNUM (num, 2);
|
||
break;
|
||
case SP_FL|SP_NUM: /* L^n */
|
||
case SP_IND|SP_FL|SP_NUM: /* @L^n */
|
||
num = lit[0] - (addr + vp + 5);
|
||
if (litsize > 0) PARSE_LOSE;
|
||
val[vp++] = nPC | LDP | ((fl & SP_IND)? 1: 0);
|
||
PUTNUM (num, 4);
|
||
break;
|
||
default:
|
||
PARSE_LOSE; } /* end case */
|
||
if (*cptr != 0) *r = SCPE_ARG; /* must be done */
|
||
return vp;
|
||
}
|
||
|
||
char *parse_rnum (char *cptr, int32 *rn)
|
||
{
|
||
int32 i, lnt;
|
||
t_value regnum;
|
||
char *tptr;
|
||
|
||
for (i = 15; i >= 0; i--) { /* chk named reg */
|
||
lnt = strlen (regname[i]);
|
||
if (strncmp (cptr, regname[i], lnt) == 0) {
|
||
*rn = i;
|
||
return cptr + lnt; } }
|
||
if (*cptr++ != 'R') return NULL; /* look for R */
|
||
regnum = strtotv (cptr, &tptr, 10); /* look for reg # */
|
||
if ((cptr == tptr) || (regnum > 15)) return NULL;
|
||
*rn = (int32) regnum;
|
||
return tptr;
|
||
}
|
||
|
||
int32 parse_sym_qoimm (int32 *lit, t_value *val, int32 vp, int lnt, int32 minus)
|
||
{
|
||
int32 i, k, prev;
|
||
|
||
for (i = prev = 0; i < lnt; i++) {
|
||
if (minus) prev = lit[i] = ~lit[i] + (prev == 0);
|
||
PUTNUM (lit[i], 4); }
|
||
return vp;
|
||
}
|
||
|