mirror of
https://github.com/prirun/p50em.git
synced 2026-03-09 03:49:25 +00:00
large changes to dispatch.h to support 2 tables +
separate R/S-mode mem ref dispatch table to avoid R-mode check in V-mode inst
This commit is contained in:
278
dispatch.h
278
dispatch.h
@@ -1,13 +1,14 @@
|
||||
/* include file to initialize the CPU dispatch tables */
|
||||
|
||||
/* macro MRGEN takes as a Prime opcode number and sets up the disp_mr
|
||||
dispatch table. The Prime opcode number for 4-bit opcode (in
|
||||
instruction bits 3-6) 1101 is 015, and Prime writes it as 01500 in
|
||||
older manuals. If the X bit is used as an opcode extension (only
|
||||
for opcode 01500 - non-indexable instructions), the opcode becomes
|
||||
03500. If bits 7-11 are 11000 (for V-mode; bits 7-12 = 110000 in
|
||||
R-mode), the instruction is long form and has 2 extended opcode
|
||||
bits in bits 13-14. The Prime equivalent would be 03500 - 03503.
|
||||
/* macros MRGEN_(VR) take as a Prime opcode number and set up the
|
||||
disp_(vr)mr V and R-mode dispatch tables. The Prime opcode number
|
||||
for 4-bit opcode (in instruction bits 3-6) 1101 is 015, and Prime
|
||||
writes it as 01500 in older manuals. If the X bit is used as an
|
||||
opcode extension (only for opcode 01500 - non-indexable
|
||||
instructions), the opcode becomes 03500. If bits 7-11 are 11000
|
||||
(for V-mode; bits 7-12 = 110000 in R-mode), the instruction is long
|
||||
form and has 2 extended opcode bits in bits 13-14. The Prime
|
||||
equivalent would be 03500 - 03503.
|
||||
|
||||
To summarize, the mem ref opcode index is a 7-bit value, 0-127:
|
||||
- bit 10 = bit 2 of instruction (X)
|
||||
@@ -23,8 +24,8 @@
|
||||
|
||||
#define VMRINSTIX(inst) ((((inst) >> 8) & 0x7C) | ((((inst) & 0x03E0) == 0x0300) ? (((inst) >> 2) & 3) : 0))
|
||||
|
||||
/* change R-mode MR instruction to opcode index (mask is 1 bit longer
|
||||
for R-mode long instructions */
|
||||
/* change R-mode MR instruction to opcode index
|
||||
(mask is 1 bit longer for R-mode long instructions) */
|
||||
|
||||
#define RMRINSTIX(inst) ((((inst) >> 8) & 0x7C) | ((((inst) & 0x03F0) == 0x0300) ? (((inst) >> 2) & 3) : 0))
|
||||
|
||||
@@ -36,76 +37,203 @@
|
||||
|
||||
#define MRPRIMEIX(primeop) (((primeop) >> 4) | ((primeop) & 3))
|
||||
|
||||
#define MRGEN(opcode, name, target) \
|
||||
gvp->disp_mr[MRPRIMEIX(opcode)] = &⌖ \
|
||||
/* printf("MR opcode %05o (%s), ix=%0d\n", opcode, name, MRPRIMEIX(opcode)); */ \
|
||||
/* set an entry in the R-mode memory reference opcode dispatch table */
|
||||
|
||||
#define MRGEN_R(opcode, name, target) \
|
||||
gvp->disp_rmr[MRPRIMEIX(opcode)] = &⌖ \
|
||||
/* printf("R-MR opcode %05o (%s), ix=%0d\n", opcode, name, MRPRIMEIX(opcode)); */ \
|
||||
if ((opcode & 01700) != 01500) { \
|
||||
gvp->disp_mr[MRPRIMEIX(opcode | 02000)] = &⌖ \
|
||||
/* printf("MR opcode %05o (%s), ix=%0d\n", opcode | 02000, name, MRPRIMEIX(opcode | 02000)); */ \
|
||||
gvp->disp_rmr[MRPRIMEIX(opcode | 02000)] = &⌖ \
|
||||
/* printf("R-MR opcode %05o (%s), ix=%0d\n", opcode | 02000, name, MRPRIMEIX(opcode | 02000)); */ \
|
||||
}
|
||||
|
||||
/* initialize table to "bad memory reference instruction" */
|
||||
/* set an entry in the V-mode memory reference opcode dispatch table */
|
||||
|
||||
for (i=0; i < 128; i++)
|
||||
gvp->disp_mr[i] = &&d_badmr;
|
||||
#define MRGEN_V(opcode, name, target) \
|
||||
gvp->disp_vmr[MRPRIMEIX(opcode)] = &⌖ \
|
||||
/* printf("V-MR opcode %05o (%s), ix=%0d\n", opcode, name, MRPRIMEIX(opcode)); */ \
|
||||
if ((opcode & 01700) != 01500) { \
|
||||
gvp->disp_vmr[MRPRIMEIX(opcode | 02000)] = &⌖ \
|
||||
/* printf("V-MR opcode %05o (%s), ix=%0d\n", opcode | 02000, name, MRPRIMEIX(opcode | 02000)); */ \
|
||||
}
|
||||
|
||||
MRGEN(00100, "JMP", d_jmp);
|
||||
MRGEN(00101, "EAL", d_ealeaa);
|
||||
MRGEN(00102, "XEC", d_xec);
|
||||
MRGEN(00103, "ENTR", d_entr);
|
||||
MRGEN(00200, "LDA", d_ldadld);
|
||||
MRGEN(00201, "FLD", d_fld);
|
||||
MRGEN(00202, "DFLD", d_dfld);
|
||||
MRGEN(00203, "LDL", d_ldljeq);
|
||||
MRGEN(00300, "ANA", d_ana);
|
||||
MRGEN(00301, "STLR", d_stlr);
|
||||
MRGEN(00302, "ORA", d_ora);
|
||||
MRGEN(00303, "ANL", d_anljne);
|
||||
MRGEN(00400, "STA", d_stadst);
|
||||
MRGEN(00401, "FST", d_fst);
|
||||
MRGEN(00402, "DFST", d_dfst);
|
||||
MRGEN(00403, "STL", d_stljle);
|
||||
MRGEN(00500, "ERA", d_era);
|
||||
MRGEN(00501, "LDLR", d_ldlr);
|
||||
MRGEN(00502, "QFxx", d_qfxxuii);
|
||||
MRGEN(00503, "ERL", d_erljgt);
|
||||
MRGEN(00600, "ADD", d_adddad);
|
||||
MRGEN(00601, "FAD", d_fad);
|
||||
MRGEN(00602, "DFAD", d_dfad);
|
||||
MRGEN(00603, "ADL", d_adljlt);
|
||||
MRGEN(00700, "SUB", d_subdsb);
|
||||
MRGEN(00701, "FSB", d_fsb);
|
||||
MRGEN(00702, "DFSB", d_dfsb);
|
||||
MRGEN(00703, "SBL", d_sbljge);
|
||||
MRGEN(01000, "JST", d_jst);
|
||||
MRGEN(01002, "PCL", d_pclcrep);
|
||||
MRGEN(01100, "CAS", d_cas);
|
||||
MRGEN(01101, "FCS", d_fcs);
|
||||
MRGEN(01102, "DFCS", d_dfcs);
|
||||
MRGEN(01103, "CLS", d_cls);
|
||||
MRGEN(01200, "IRS", d_irs);
|
||||
MRGEN(01202, "EAXB", d_eaxb);
|
||||
MRGEN(01300, "IMA", d_ima);
|
||||
MRGEN(01302, "EALB", d_ealb);
|
||||
MRGEN(01400, "JSY", d_jsy);
|
||||
MRGEN(01401, "EIO", d_eio);
|
||||
MRGEN(01402, "JSXB", d_jsxb);
|
||||
MRGEN(01500, "STX", d_stx);
|
||||
MRGEN(01501, "FLX", d_flx);
|
||||
MRGEN(01502, "DFLX", d_dflxjdx);
|
||||
MRGEN(01503, "QFLX", d_qflxjix);
|
||||
MRGEN(01600, "MPY", d_mpy);
|
||||
MRGEN(01601, "FMP", d_fmp);
|
||||
MRGEN(01602, "DFMP", d_dfmp);
|
||||
MRGEN(01603, "MPL", d_mpl);
|
||||
MRGEN(01700, "DIV", d_div);
|
||||
MRGEN(01701, "FDV", d_fdv);
|
||||
MRGEN(01702, "DFDV", d_dfdv);
|
||||
MRGEN(01703, "DVL", d_dvl);
|
||||
MRGEN(03500, "LDX", d_ldx);
|
||||
MRGEN(03501, "LDY", d_ldy);
|
||||
MRGEN(03502, "STY", d_sty);
|
||||
MRGEN(03503, "JSX", d_jsx);
|
||||
/* initialize tables to "bad memory reference instruction" */
|
||||
|
||||
for (i=0; i < 128; i++) {
|
||||
gvp->disp_rmr[i] = &&d_badmr;
|
||||
gvp->disp_vmr[i] = &&d_badmr;
|
||||
}
|
||||
|
||||
MRGEN_R(00100, "JMP", d_jmp);
|
||||
MRGEN_V(00100, "JMP", d_jmp);
|
||||
|
||||
MRGEN_R(00101, "EAA", d_eaa);
|
||||
MRGEN_V(00101, "EAL", d_eal);
|
||||
|
||||
MRGEN_R(00102, "XEC", d_xec);
|
||||
MRGEN_V(00102, "XEC", d_xec);
|
||||
|
||||
MRGEN_R(00103, "ENTR", d_entr);
|
||||
MRGEN_V(00103, "ENTR?", d_uii);
|
||||
|
||||
MRGEN_R(00200, "LDA/DLD", d_ldadld);
|
||||
MRGEN_V(00200, "LDA", d_lda);
|
||||
|
||||
MRGEN_R(00201, "FLD", d_fld);
|
||||
MRGEN_V(00201, "FLD", d_fld);
|
||||
|
||||
MRGEN_R(00202, "DFLD", d_dfld);
|
||||
MRGEN_V(00202, "DFLD", d_dfld);
|
||||
|
||||
MRGEN_R(00203, "JEQ", d_jeq);
|
||||
MRGEN_V(00203, "LDL", d_ldl);
|
||||
|
||||
MRGEN_R(00300, "ANA", d_ana);
|
||||
MRGEN_V(00300, "ANA", d_ana);
|
||||
|
||||
MRGEN_R(00301, "STLR?", d_uii);
|
||||
MRGEN_V(00301, "STLR", d_stlr);
|
||||
|
||||
MRGEN_R(00302, "ORA", d_ora);
|
||||
MRGEN_V(00302, "ORA", d_ora);
|
||||
|
||||
MRGEN_R(00303, "JNE", d_jne);
|
||||
MRGEN_V(00303, "ANL", d_anl);
|
||||
|
||||
MRGEN_R(00400, "STA/DST", d_stadst);
|
||||
MRGEN_V(00400, "STA", d_sta);
|
||||
|
||||
MRGEN_R(00401, "FST", d_fst);
|
||||
MRGEN_V(00401, "FST", d_fst);
|
||||
|
||||
MRGEN_R(00402, "DFST", d_dfst);
|
||||
MRGEN_V(00402, "DFST", d_dfst);
|
||||
|
||||
MRGEN_R(00403, "JLE", d_jle);
|
||||
MRGEN_V(00403, "STL", d_stl);
|
||||
|
||||
MRGEN_R(00500, "ERA", d_era);
|
||||
MRGEN_V(00500, "ERA", d_era);
|
||||
|
||||
MRGEN_R(00501, "LDLR?", d_uii);
|
||||
MRGEN_V(00501, "LDLR", d_ldlr);
|
||||
|
||||
MRGEN_R(00502, "QFxx", d_qfxxuii);
|
||||
MRGEN_V(00502, "QFxx", d_qfxxuii);
|
||||
|
||||
MRGEN_R(00503, "JGT", d_jgt);
|
||||
MRGEN_V(00503, "ERL", d_erl);
|
||||
|
||||
MRGEN_R(00600, "ADD/DAD", d_adddad);
|
||||
MRGEN_V(00600, "ADD", d_add);
|
||||
|
||||
MRGEN_R(00601, "FAD", d_fad);
|
||||
MRGEN_V(00601, "FAD", d_fad);
|
||||
|
||||
MRGEN_R(00602, "DFAD", d_dfad);
|
||||
MRGEN_V(00602, "DFAD", d_dfad);
|
||||
|
||||
MRGEN_R(00603, "JLT", d_jlt);
|
||||
MRGEN_V(00603, "ADL", d_adl);
|
||||
|
||||
MRGEN_R(00700, "SUB/DSB", d_subdsb);
|
||||
MRGEN_V(00700, "SUB", d_sub);
|
||||
|
||||
MRGEN_R(00701, "FSB", d_fsb);
|
||||
MRGEN_V(00701, "FSB", d_fsb);
|
||||
|
||||
MRGEN_R(00702, "DFSB", d_dfsb);
|
||||
MRGEN_V(00702, "DFSB", d_dfsb);
|
||||
|
||||
MRGEN_R(00703, "JGE", d_jge);
|
||||
MRGEN_V(00703, "SBL", d_sbl);
|
||||
|
||||
MRGEN_R(01000, "JST", d_jst);
|
||||
MRGEN_V(01000, "JST", d_jst);
|
||||
|
||||
MRGEN_R(01002, "CREP", d_crep);
|
||||
MRGEN_V(01002, "PCL", d_pcl);
|
||||
|
||||
MRGEN_R(01100, "CAS", d_cas);
|
||||
MRGEN_V(01100, "CAS", d_cas);
|
||||
|
||||
MRGEN_R(01101, "FCS", d_fcs);
|
||||
MRGEN_V(01101, "FCS", d_fcs);
|
||||
|
||||
MRGEN_R(01102, "DFCS", d_dfcs);
|
||||
MRGEN_V(01102, "DFCS", d_dfcs);
|
||||
|
||||
MRGEN_R(01103, "CLS?", d_uii);
|
||||
MRGEN_V(01103, "CLS", d_cls);
|
||||
|
||||
MRGEN_R(01200, "IRS", d_irs);
|
||||
MRGEN_V(01200, "IRS", d_irs);
|
||||
|
||||
MRGEN_R(01202, "EAXB?", d_uii);
|
||||
MRGEN_V(01202, "EAXB", d_eaxb);
|
||||
|
||||
MRGEN_R(01300, "IMA", d_ima);
|
||||
MRGEN_V(01300, "IMA", d_ima);
|
||||
|
||||
MRGEN_R(01302, "EALB?", d_uii);
|
||||
MRGEN_V(01302, "EALB", d_ealb);
|
||||
|
||||
MRGEN_R(01400, "JSY?", d_uii);
|
||||
MRGEN_V(01400, "JSY", d_jsy);
|
||||
|
||||
MRGEN_R(01401, "EIO?", d_uii);
|
||||
MRGEN_V(01401, "EIO", d_eio);
|
||||
|
||||
MRGEN_R(01402, "JSXB?", d_uii);
|
||||
MRGEN_V(01402, "JSXB", d_jsxb);
|
||||
|
||||
MRGEN_R(01500, "STX", d_stx);
|
||||
MRGEN_V(01500, "STX", d_stx);
|
||||
|
||||
MRGEN_R(01501, "FLX", d_flx);
|
||||
MRGEN_V(01501, "FLX", d_flx);
|
||||
|
||||
MRGEN_R(01502, "JDX", d_jdx);
|
||||
MRGEN_V(01502, "DFLX", d_dflx);
|
||||
|
||||
MRGEN_R(01503, "JIX", d_jix);
|
||||
MRGEN_V(01503, "QFLX", d_qflx);
|
||||
|
||||
MRGEN_R(01600, "MPY", d_mpy_r);
|
||||
MRGEN_V(01600, "MPY", d_mpy);
|
||||
|
||||
MRGEN_R(01601, "FMP", d_fmp);
|
||||
MRGEN_V(01601, "FMP", d_fmp);
|
||||
|
||||
MRGEN_R(01602, "DFMP", d_dfmp);
|
||||
MRGEN_V(01602, "DFMP", d_dfmp);
|
||||
|
||||
MRGEN_R(01603, "MPL?", d_uii);
|
||||
MRGEN_V(01603, "MPL", d_mpl);
|
||||
|
||||
MRGEN_R(01700, "DIV", d_div);
|
||||
MRGEN_V(01700, "DIV", d_div);
|
||||
|
||||
MRGEN_R(01701, "FDV", d_fdv);
|
||||
MRGEN_V(01701, "FDV", d_fdv);
|
||||
|
||||
MRGEN_R(01702, "DFDV", d_dfdv);
|
||||
MRGEN_V(01702, "DFDV", d_dfdv);
|
||||
|
||||
MRGEN_R(01703, "DVL?", d_uii);
|
||||
MRGEN_V(01703, "DVL", d_dvl);
|
||||
|
||||
MRGEN_R(03500, "LDX", d_ldx);
|
||||
MRGEN_V(03500, "LDX", d_ldx);
|
||||
|
||||
MRGEN_R(03501, "LDY?", d_uii);
|
||||
MRGEN_V(03501, "LDY", d_ldy);
|
||||
|
||||
MRGEN_R(03502, "STY?", d_uii);
|
||||
MRGEN_V(03502, "STY", d_sty);
|
||||
|
||||
MRGEN_R(03503, "JSX", d_jsx);
|
||||
MRGEN_V(03503, "JSX", d_jsx);
|
||||
|
||||
|
||||
#define GENIX(inst) ((inst>>4) & 06000) | (inst & 01777)
|
||||
|
||||
397
em.c
397
em.c
@@ -428,7 +428,7 @@ typedef struct {
|
||||
order fault bit of vpn is never set. The ring and extension bits
|
||||
are used to store the 3-bit access field from the STLB for the
|
||||
current ring (remember that all brp entries are invalidated by
|
||||
PCL and PRTN when the ring might change).
|
||||
PCL and PRTN when the ring changes).
|
||||
|
||||
Storing the access bits in the vpn allows use of of the brp
|
||||
cache for write accesses as well as read accesses. */
|
||||
@@ -482,7 +482,8 @@ typedef struct {
|
||||
int supercalls; /* supercache hits */
|
||||
int supermisses;
|
||||
|
||||
void *disp_mr[128]; /* V/R memory ref dispatch table */
|
||||
void *disp_rmr[128]; /* R-mode memory ref dispatch table */
|
||||
void *disp_vmr[128]; /* V-mode memory ref dispatch table */
|
||||
|
||||
/* traceflags is the variable used to test tracing of each instruction
|
||||
traceuser is the user number to trace, 0 meaning any user
|
||||
@@ -4510,8 +4511,10 @@ For disk boots, the last 3 digits can be:\n\
|
||||
fetch:
|
||||
|
||||
#if 0
|
||||
if (gvp->instcount > 32727500)
|
||||
gvp->savetraceflags = ~0;
|
||||
if (gvp->instcount > 2681900)
|
||||
gvp->savetraceflags = TB_FLOW;
|
||||
if (gvp->instcount > 3000000)
|
||||
gvp->savetraceflags = 0;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
@@ -4776,7 +4779,7 @@ xec:
|
||||
if ((crs[KEYS] & 016000) == 014000) { /* 64V mode */
|
||||
ea = ea64v(inst, earp);
|
||||
TRACE(T_FLOW, " EA: %o/%o %s\n",ea>>16, ea & 0xFFFF, searchloadmap(ea,' '));
|
||||
goto *(gvp->disp_mr[VMRINSTIX(inst)]);
|
||||
goto *(gvp->disp_vmr[VMRINSTIX(inst)]);
|
||||
|
||||
} else if ((crs[KEYS] & 0016000) == 010000) { /* E32I */
|
||||
goto imode;
|
||||
@@ -4788,17 +4791,17 @@ xec:
|
||||
} else if (crs[KEYS] & 004000) { /* 32R/64R */
|
||||
ea = ea32r64r(earp, inst);
|
||||
TRACE(T_FLOW, " EA: %o/%o %s\n",ea>>16, ea & 0xFFFF, searchloadmap(ea,' '));
|
||||
goto *(gvp->disp_mr[RMRINSTIX(inst)]);
|
||||
goto *(gvp->disp_rmr[RMRINSTIX(inst)]);
|
||||
|
||||
} else if (crs[KEYS] & 002000) {
|
||||
ea = ea32s(inst);
|
||||
TRACE(T_FLOW, " EA: %o/%o %s\n",ea>>16, ea & 0xFFFF, searchloadmap(ea,' '));
|
||||
goto *(gvp->disp_mr[SMRINSTIX(inst)]);
|
||||
goto *(gvp->disp_rmr[SMRINSTIX(inst)]);
|
||||
|
||||
} else if ((crs[KEYS] & 016000) == 0) {
|
||||
ea = ea16s(inst);
|
||||
TRACE(T_FLOW, " EA: %o/%o %s\n",ea>>16, ea & 0xFFFF, searchloadmap(ea,' '));
|
||||
goto *(gvp->disp_mr[SMRINSTIX(inst)]);
|
||||
goto *(gvp->disp_rmr[SMRINSTIX(inst)]);
|
||||
|
||||
} else {
|
||||
printf("Bad CPU mode in EA calculation, keys = %o\n", crs[KEYS]);
|
||||
@@ -8928,12 +8931,17 @@ imodepcl:
|
||||
fatal("I-mode fall-through?");
|
||||
|
||||
|
||||
d_lda: /* 00200 (V-mode) */
|
||||
crs[A] = get16t(ea);
|
||||
TRACE(T_FLOW, " LDA ='%o/%d %03o %03o\n", crs[A], *(short *)(crs+A), crs[A]>>8, crs[A] & 0xFF);
|
||||
goto fetch;
|
||||
|
||||
/* NOTE: don't use get32 for DLD/DST, because it doesn't handle register
|
||||
address traps */
|
||||
|
||||
d_ldadld: /* 00200 */
|
||||
d_ldadld: /* 00200 (R-mode) */
|
||||
crs[A] = get16t(ea);
|
||||
if ((crs[KEYS] & 050000) != 040000) { /* not R-mode or not DP */
|
||||
if (!(crs[KEYS] & 040000)) { /* not DP */
|
||||
TRACE(T_FLOW, " LDA ='%o/%d %03o %03o\n", crs[A], *(short *)(crs+A), crs[A]>>8, crs[A] & 0xFF);
|
||||
} else {
|
||||
TRACE(T_FLOW, " DLD\n");
|
||||
@@ -8941,7 +8949,12 @@ d_ldadld: /* 00200 */
|
||||
}
|
||||
goto fetch;
|
||||
|
||||
d_stadst: /* 00400 */
|
||||
d_sta: /* 00400 (V-mode) */
|
||||
TRACE(T_FLOW, " STA\n");
|
||||
put16t(crs[A],ea);
|
||||
goto fetch;
|
||||
|
||||
d_stadst: /* 00400 (R-mode) */
|
||||
put16t(crs[A],ea);
|
||||
if ((crs[KEYS] & 050000) != 040000) {
|
||||
TRACE(T_FLOW, " STA\n");
|
||||
@@ -8968,66 +8981,73 @@ d_era: /* 00500 */
|
||||
crs[A] ^= m;
|
||||
goto fetch;
|
||||
|
||||
d_adddad: /* 00600 */
|
||||
crs[KEYS] &= ~0120300; /* clear C, L, LT, EQ */
|
||||
d_add: /* 00600 (V-mode) */
|
||||
m = get16t(ea);
|
||||
TRACE(T_FLOW, " ADD ='%o/%d\n", m, *(short *)&m);
|
||||
add16(crs+A, m, 0, ea);
|
||||
goto fetch;
|
||||
|
||||
d_adddad: /* 00600 (R-mode) */
|
||||
if (!(crs[KEYS] & 040000)) /* dbl mode? */
|
||||
goto d_add;
|
||||
TRACE(T_FLOW, " DAD\n");
|
||||
crs[KEYS] &= ~0120300; /* clear C, L, LT, EQ */
|
||||
utempa = crs[A];
|
||||
m = get16t(ea);
|
||||
if ((crs[KEYS] & 050000) != 040000) { /* V/I mode or SP */
|
||||
TRACE(T_FLOW, " ADD ='%o/%d\n", m, *(short *)&m);
|
||||
add16(crs+A, m, 0, ea);
|
||||
} else { /* R-mode and DP */
|
||||
TRACE(T_FLOW, " DAD\n");
|
||||
crs[B] += get16t(INCVA(ea,1));
|
||||
utempl = crs[A];
|
||||
if (crs[B] & 0x8000) {
|
||||
utempl++;
|
||||
crs[B] &= 0x7fff;
|
||||
}
|
||||
utempl += m;
|
||||
crs[A] = utempl;
|
||||
if (utempl & 0x10000) /* set L-bit if carry */
|
||||
crs[KEYS] |= 020000;
|
||||
/* NOTE: this EQ test prevents reusing the ADD code :( */
|
||||
if (*(int *)(crs+L) == 0) /* set EQ? */
|
||||
SETEQ;
|
||||
if (((~utempa ^ m) & (utempa ^ crs[A])) & 0x8000) {
|
||||
if (*(int *)(crs+L) >= 0)
|
||||
SETLT;
|
||||
mathexception('i', FC_INT_OFLOW, 0);
|
||||
} else if (*(int *)(crs+L) < 0)
|
||||
SETLT;
|
||||
crs[B] += get16t(INCVA(ea,1));
|
||||
utempl = crs[A];
|
||||
if (crs[B] & 0x8000) {
|
||||
utempl++;
|
||||
crs[B] &= 0x7fff;
|
||||
}
|
||||
utempl += m;
|
||||
crs[A] = utempl;
|
||||
if (utempl & 0x10000) /* set L-bit if carry */
|
||||
crs[KEYS] |= 020000;
|
||||
/* NOTE: this EQ test prevents reusing the ADD code :( */
|
||||
if (*(int *)(crs+L) == 0) /* set EQ? */
|
||||
SETEQ;
|
||||
if (((~utempa ^ m) & (utempa ^ crs[A])) & 0x8000) {
|
||||
if (*(int *)(crs+L) >= 0)
|
||||
SETLT;
|
||||
mathexception('i', FC_INT_OFLOW, 0);
|
||||
} else if (*(int *)(crs+L) < 0)
|
||||
SETLT;
|
||||
goto fetch;
|
||||
|
||||
d_sub: /* 00700 (V-mode) */
|
||||
m = get16t(ea);
|
||||
utempa = crs[A];
|
||||
TRACE(T_FLOW, " SUB ='%o/%d\n", m, *(short *)&m);
|
||||
add16(crs+A, ~m, 1, ea);
|
||||
goto fetch;
|
||||
|
||||
d_subdsb: /* 00700 */
|
||||
if (!(crs[KEYS] & 040000))
|
||||
goto d_sub;
|
||||
TRACE(T_FLOW, " DSB\n");
|
||||
crs[KEYS] &= ~0120300; /* clear C, L, and CC */
|
||||
utempa = crs[A];
|
||||
m = get16t(ea);
|
||||
if ((crs[KEYS] & 050000) != 040000) {
|
||||
TRACE(T_FLOW, " SUB ='%o/%d\n", m, *(short *)&m);
|
||||
add16(crs+A, ~m, 1, ea);
|
||||
} else {
|
||||
TRACE(T_FLOW, " DSB\n");
|
||||
crs[B] -= get16t(INCVA(ea,1));
|
||||
utempl = crs[A];
|
||||
if (crs[B] & 0x8000) {
|
||||
utempl += 0xFFFF;
|
||||
crs[B] &= 0x7fff;
|
||||
}
|
||||
utempl += (unsigned short) ~m;
|
||||
utempl += 1;
|
||||
crs[A] = utempl; /* truncate results */
|
||||
if (utempl & 0x10000) /* set L-bit if carry */
|
||||
crs[KEYS] |= 020000;
|
||||
if (*(int *)(crs+L) == 0) /* set EQ? */
|
||||
SETEQ;
|
||||
if (((utempa ^ m) & (utempa ^ crs[A])) & 0x8000) {
|
||||
if (*(int *)(crs+L) >= 0)
|
||||
SETLT;
|
||||
mathexception('i', FC_INT_OFLOW, 0);
|
||||
} else if (*(int *)(crs+L) < 0)
|
||||
SETLT;
|
||||
crs[B] -= get16t(INCVA(ea,1));
|
||||
utempl = crs[A];
|
||||
if (crs[B] & 0x8000) {
|
||||
utempl += 0xFFFF;
|
||||
crs[B] &= 0x7fff;
|
||||
}
|
||||
utempl += (unsigned short) ~m;
|
||||
utempl += 1;
|
||||
crs[A] = utempl; /* truncate results */
|
||||
if (utempl & 0x10000) /* set L-bit if carry */
|
||||
crs[KEYS] |= 020000;
|
||||
if (*(int *)(crs+L) == 0) /* set EQ? */
|
||||
SETEQ;
|
||||
if (((utempa ^ m) & (utempa ^ crs[A])) & 0x8000) {
|
||||
if (*(int *)(crs+L) >= 0)
|
||||
SETLT;
|
||||
mathexception('i', FC_INT_OFLOW, 0);
|
||||
} else if (*(int *)(crs+L) < 0)
|
||||
SETLT;
|
||||
goto fetch;
|
||||
|
||||
d_ora: /* 00302 */
|
||||
@@ -9059,13 +9079,13 @@ d_cas: /* 01100 */
|
||||
stopwatch_push(&sw_cas);
|
||||
m = get16t(ea);
|
||||
TRACE(T_FLOW, " CAS ='%o/%d\n", m, *(short *)&m);
|
||||
#if 0
|
||||
if (crs[A] == m) {
|
||||
INCRP;
|
||||
} else if (*(short *)(crs+A) < *(short *)&m) {
|
||||
RPL += 2;
|
||||
}
|
||||
#else
|
||||
|
||||
#if 1
|
||||
|
||||
/* this crap is to set L & CC like subtract would, even though
|
||||
most programs never tested these after CAS. add16 can't be
|
||||
used because docs say CAS leaves C-bit unchanged... :( */
|
||||
|
||||
crs[KEYS] &= ~020300; /* clear L, and CC */
|
||||
utempa = crs[A];
|
||||
utempl = crs[A];
|
||||
@@ -9082,11 +9102,13 @@ d_cas: /* 01100 */
|
||||
} else if (*(short *)(crs+A) < 0)
|
||||
SETLT;
|
||||
crs[A] = utempa; /* restore A reg */
|
||||
if (crs[A] == m)
|
||||
INCRP;
|
||||
else if (*(short *)(crs+A) < *(short *)&m)
|
||||
RPL += 2;
|
||||
#endif
|
||||
|
||||
if (crs[A] == m) {
|
||||
INCRP;
|
||||
} else if (*(short *)(crs+A) < *(short *)&m) {
|
||||
RPL += 2;
|
||||
}
|
||||
stopwatch_pop(&sw_cas);
|
||||
goto fetch;
|
||||
|
||||
@@ -9123,39 +9145,39 @@ d_stx: /* 01500 */
|
||||
put16t(crs[X],ea);
|
||||
goto fetch;
|
||||
|
||||
/* MPY can't overflow in V-mode, but in R-mode (31 bits),
|
||||
-32768*-32768 can overflow and yields 0x8000/0x0000 */
|
||||
/* MPY can't overflow in V-mode */
|
||||
|
||||
d_mpy: /* 01600 */
|
||||
d_mpy: /* 01600 (V-mode) */
|
||||
m = get16t(ea);
|
||||
TRACE(T_FLOW, " MPY ='%o/%d\n", m, *(short *)&m);
|
||||
*(int *)(crs+L) = *(short *)(crs+A) * *(short *)&m;
|
||||
CLEARC;
|
||||
goto fetch;
|
||||
|
||||
/* in R-mode (31 bits), -32768*-32768 can overflow and yields
|
||||
0x8000/0x0000 */
|
||||
|
||||
d_mpy_r: /* 01600 (R-mode) */
|
||||
m = get16t(ea);
|
||||
TRACE(T_FLOW, " MPY ='%o/%d\n", m, *(short *)&m);
|
||||
templ = *(short *)(crs+A) * *(short *)&m;
|
||||
CLEARC;
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
*(int *)(crs+L) = templ;
|
||||
} else { /* R/S mode */
|
||||
utempa = crs[A];
|
||||
crs[A] = (templ >> 15);
|
||||
crs[B] = templ & 077777;
|
||||
if (utempa == 0x8000 && m == 0x8000)
|
||||
mathexception('i', FC_INT_OFLOW, 0);
|
||||
}
|
||||
utempa = crs[A];
|
||||
crs[A] = (templ >> 15);
|
||||
crs[B] = templ & 077777;
|
||||
if (utempa == 0x8000 && m == 0x8000)
|
||||
mathexception('i', FC_INT_OFLOW, 0);
|
||||
goto fetch;
|
||||
|
||||
d_mpl: /* 01603 */
|
||||
d_mpl: /* 01603 (V-mode) */
|
||||
templ = get32(ea);
|
||||
TRACE(T_FLOW, " MPL ='%o/%d\n", templ, *(int *)&templ);
|
||||
*(long long *)(crs+L) = (long long)(*(int *)(crs+L)) * (long long)templ;
|
||||
CLEARC;
|
||||
goto fetch;
|
||||
|
||||
/* DIAG CPU.FAULT uses this instruction in R-mode to triggger a
|
||||
UII fault, so this instruction (unlike most) checks the keys.
|
||||
This is a general problem with all instructions: they don't
|
||||
ensure the instruction is legal in the current mode */
|
||||
|
||||
if ((crs[KEYS] & 010000)) { /* V/I mode */
|
||||
templ = get32(ea);
|
||||
TRACE(T_FLOW, " MPL ='%o/%d\n", templ, *(int *)&templ);
|
||||
*(long long *)(crs+L) = (long long)(*(int *)(crs+L)) * (long long)templ;
|
||||
CLEARC;
|
||||
} else
|
||||
fault(UIIFAULT, RPL, RP);
|
||||
d_uii:
|
||||
fault(UIIFAULT, RPL, RP);
|
||||
goto fetch;
|
||||
|
||||
d_div: /* 01700 */
|
||||
@@ -9203,95 +9225,96 @@ d_ldx: /* 03500 */
|
||||
crs[X] = get16t(ea);
|
||||
goto fetch;
|
||||
|
||||
d_ealeaa: /* 00101 */
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
TRACE(T_FLOW, " EAL\n");
|
||||
*(ea_t *)(crs+L) = ea;
|
||||
} else {
|
||||
TRACE(T_FLOW, " EAA\n");
|
||||
crs[A] = ea;
|
||||
}
|
||||
d_eal: /* 00101 (V-mode) */
|
||||
TRACE(T_FLOW, " EAL\n");
|
||||
*(ea_t *)(crs+L) = ea;
|
||||
goto fetch;
|
||||
|
||||
d_ldljeq: /* 00203 */
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
*(unsigned int *)(crs+L) = get32(ea);
|
||||
TRACE(T_FLOW, " LDL ='%o/%d\n", *(unsigned int *)(crs+A), *(int *)(crs+A));
|
||||
} else {
|
||||
TRACE(T_FLOW, " JEQ\n");
|
||||
if (*(short *)(crs+A) == 0)
|
||||
RPL = ea;
|
||||
}
|
||||
d_eaa: /* 00101 (R-mode) */
|
||||
TRACE(T_FLOW, " EAA\n");
|
||||
crs[A] = ea;
|
||||
goto fetch;
|
||||
|
||||
d_sbljge: /* 00703 */
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
utempl = get32(ea);
|
||||
TRACE(T_FLOW, " SBL ='%o/%d\n", utempl, *(int *)&utempl);
|
||||
add32(crsl+GR2, ~utempl, 1, ea);
|
||||
} else {
|
||||
TRACE(T_FLOW, " JGE\n");
|
||||
if (*(short *)(crs+A) >= 0)
|
||||
RPL = ea;
|
||||
}
|
||||
d_ldl: /* 00203 (V-mode) */
|
||||
*(unsigned int *)(crs+L) = get32(ea);
|
||||
TRACE(T_FLOW, " LDL ='%o/%d\n", *(unsigned int *)(crs+A), *(int *)(crs+A));
|
||||
goto fetch;
|
||||
|
||||
d_pclcrep: /* 01002 */
|
||||
d_jeq: /* 00203 (R-mode) */
|
||||
TRACE(T_FLOW, " JEQ\n");
|
||||
if (*(short *)(crs+A) == 0)
|
||||
RPL = ea;
|
||||
goto fetch;
|
||||
|
||||
d_sbl: /* 00703 (V-mode) */
|
||||
utempl = get32(ea);
|
||||
TRACE(T_FLOW, " SBL ='%o/%d\n", utempl, *(int *)&utempl);
|
||||
add32(crsl+GR2, ~utempl, 1, ea);
|
||||
goto fetch;
|
||||
|
||||
d_jge: /* 00703 (R-mode) */
|
||||
TRACE(T_FLOW, " JGE\n");
|
||||
if (*(short *)(crs+A) >= 0)
|
||||
RPL = ea;
|
||||
goto fetch;
|
||||
|
||||
d_pcl: /* 01002 (V-mode) */
|
||||
|
||||
/* NOTE: real PCL code is in I-mode section! */
|
||||
|
||||
if (crs[KEYS] & 010000) /* V/I mode */
|
||||
goto imodepcl;
|
||||
goto imodepcl;
|
||||
|
||||
d_crep: /* 01002 (R-mode) */
|
||||
TRACE(T_FLOW, " CREP\n");
|
||||
put16t(RPL,crs[S]++);
|
||||
RPL = ea;
|
||||
goto fetch;
|
||||
|
||||
d_erljgt: /* 00503 */
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
utempl = get32(ea);
|
||||
TRACE(T_FLOW, " ERL ='%o/%d '%o/'%o %d/%d\n", utempl, *(int *)&utempl, utempl>>16, utempl&0xFFFF, utempl>>16, utempl&0xFFFF);
|
||||
*(unsigned int *)(crs+L) ^= utempl;
|
||||
} else {
|
||||
TRACE(T_FLOW, " JGT\n");
|
||||
if (*(short *)(crs+A) > 0)
|
||||
RPL = ea;
|
||||
}
|
||||
d_erl: /* 00503 (V-mode) */
|
||||
utempl = get32(ea);
|
||||
TRACE(T_FLOW, " ERL ='%o/%d '%o/'%o %d/%d\n", utempl, *(int *)&utempl, utempl>>16, utempl&0xFFFF, utempl>>16, utempl&0xFFFF);
|
||||
*(unsigned int *)(crs+L) ^= utempl;
|
||||
goto fetch;
|
||||
|
||||
d_stljle: /* 00403 */
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
TRACE(T_FLOW, " STL\n");
|
||||
put32(*(unsigned int *)(crs+L),ea);
|
||||
} else {
|
||||
TRACE(T_FLOW, " JLE\n");
|
||||
if (*(short *)(crs+A) <= 0)
|
||||
RPL = ea;
|
||||
}
|
||||
d_jgt: /* 00503 (R-mode) */
|
||||
TRACE(T_FLOW, " JGT\n");
|
||||
if (*(short *)(crs+A) > 0)
|
||||
RPL = ea;
|
||||
goto fetch;
|
||||
|
||||
d_adljlt: /* 00603 */
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
utempl = get32(ea);
|
||||
TRACE(T_FLOW, " ADL ='%o/%d\n", utempl, *(int *)&utempl);
|
||||
add32(crsl+GR2, utempl, 0, ea);
|
||||
} else {
|
||||
TRACE(T_FLOW, " JLT\n");
|
||||
if (*(short *)(crs+A) < 0)
|
||||
RPL = ea;
|
||||
}
|
||||
d_stl: /* 00403 (V-mode) */
|
||||
TRACE(T_FLOW, " STL\n");
|
||||
put32(*(unsigned int *)(crs+L),ea);
|
||||
goto fetch;
|
||||
|
||||
d_anljne: /* 00303 */
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
utempl = get32(ea);
|
||||
TRACE(T_FLOW, " ANL ='%o\n", utempl);
|
||||
*(unsigned int *)(crs+L) &= utempl;
|
||||
} else {
|
||||
TRACE(T_FLOW, " JNE\n");
|
||||
if (*(short *)(crs+A) != 0)
|
||||
RPL = ea;
|
||||
}
|
||||
d_jle: /* 00403 (R-mode) */
|
||||
TRACE(T_FLOW, " JLE\n");
|
||||
if (*(short *)(crs+A) <= 0)
|
||||
RPL = ea;
|
||||
goto fetch;
|
||||
|
||||
d_adl: /* 00603 (V-mode) */
|
||||
utempl = get32(ea);
|
||||
TRACE(T_FLOW, " ADL ='%o/%d\n", utempl, *(int *)&utempl);
|
||||
add32(crsl+GR2, utempl, 0, ea);
|
||||
goto fetch;
|
||||
|
||||
d_jlt: /* 00603 (R-mode) */
|
||||
TRACE(T_FLOW, " JLT\n");
|
||||
if (*(short *)(crs+A) < 0)
|
||||
RPL = ea;
|
||||
goto fetch;
|
||||
|
||||
d_anl: /* 00303 (V-mode) */
|
||||
utempl = get32(ea);
|
||||
TRACE(T_FLOW, " ANL ='%o\n", utempl);
|
||||
*(unsigned int *)(crs+L) &= utempl;
|
||||
goto fetch;
|
||||
|
||||
d_jne: /* 00303 (R-mode) */
|
||||
TRACE(T_FLOW, " JNE\n");
|
||||
if (*(short *)(crs+A) != 0)
|
||||
RPL = ea;
|
||||
goto fetch;
|
||||
|
||||
d_eaxb: /* 01202 */
|
||||
@@ -9299,16 +9322,16 @@ d_eaxb: /* 01202 */
|
||||
*(ea_t *)(crs+XB) = ea;
|
||||
goto fetch;
|
||||
|
||||
d_dflxjdx: /* 01502 */
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
TRACE(T_FLOW, " DFLX\n");
|
||||
crs[X] = get16(ea) * 4;
|
||||
} else {
|
||||
TRACE(T_FLOW, " JDX\n");
|
||||
crs[X]--;
|
||||
if (crs[X] != 0)
|
||||
RPL = ea;
|
||||
}
|
||||
d_dflx: /* 01502 (V-mode) */
|
||||
TRACE(T_FLOW, " DFLX\n");
|
||||
crs[X] = get16(ea) * 4;
|
||||
goto fetch;
|
||||
|
||||
d_jdx: /* 01502 (R-mode) */
|
||||
TRACE(T_FLOW, " JDX\n");
|
||||
crs[X]--;
|
||||
if (crs[X] != 0)
|
||||
RPL = ea;
|
||||
goto fetch;
|
||||
|
||||
d_sty: /* 03502 */
|
||||
@@ -9316,16 +9339,16 @@ d_sty: /* 03502 */
|
||||
put16(crs[Y],ea);
|
||||
goto fetch;
|
||||
|
||||
d_qflxjix: /* 01503 */
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
TRACE(T_FLOW, " QFLX\n");
|
||||
crs[X] = get16(ea) * 8;
|
||||
} else {
|
||||
TRACE(T_FLOW, " JIX\n");
|
||||
crs[X]++;
|
||||
if (crs[X] != 0)
|
||||
RPL = ea;
|
||||
}
|
||||
d_qflx: /* 01503 (V-mode) */
|
||||
TRACE(T_FLOW, " QFLX\n");
|
||||
crs[X] = get16(ea) * 8;
|
||||
goto fetch;
|
||||
|
||||
d_jix: /* 01503 (R-mode) */
|
||||
TRACE(T_FLOW, " JIX\n");
|
||||
crs[X]++;
|
||||
if (crs[X] != 0)
|
||||
RPL = ea;
|
||||
goto fetch;
|
||||
|
||||
d_flx: /* 01501 */
|
||||
@@ -9577,7 +9600,7 @@ d_dfst: /* 0402 */
|
||||
TRACE(T_FLOW, " Stored %f '%o %o %o %o\n", tempd1, crs[FLTH], crs[FLTL], crs[FLTD], crs[FEXP]);
|
||||
goto fetch;
|
||||
|
||||
d_ealb: /* 01302 */
|
||||
d_ealb: /* 01302 */
|
||||
TRACE(T_FLOW, " EALB\n");
|
||||
*(ea_t *)(crs+LB) = ea;
|
||||
goto fetch;
|
||||
|
||||
Reference in New Issue
Block a user