3b2: Fix fprint_sym_m

This commit is contained in:
Seth Morabito 2018-03-15 16:48:56 -07:00
parent 2e99cd0311
commit 8f87b6e3da
4 changed files with 232 additions and 38 deletions

View file

@ -68,10 +68,6 @@ extern uint16 csr_data;
uint32 R[16];
/* Other global CPU state */
int8 cpu_dtype = -1; /* Default datatype for the current
instruction */
int8 cpu_etype = -1; /* Currently set expanded datatype */
t_bool cpu_nmi = FALSE; /* If set, there has been an NMI */
int32 pc_incr = 0; /* Length (in bytes) of instruction
@ -727,7 +723,196 @@ t_stat cpu_set_hist(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
return SCPE_OK;
}
void fprint_sym_m(FILE *st, instr *ip)
t_stat fprint_sym_m(FILE *of, t_addr addr, t_value *val)
{
uint8 desc, mode, reg, class, etype;
uint32 w;
int32 vp, inst, i;
mnemonic *mn;
char reg_name[8];
mn = NULL;
vp = 0;
etype = -1;
inst = (int32) val[vp++];
if (inst == 0x30) {
/* Scan to find opcode */
inst = 0x3000 | val[vp++];
for (i = 0; i < HWORD_OP_COUNT; i++) {
if (hword_ops[i].opcode == inst) {
mn = &hword_ops[i];
break;
}
}
} else {
mn = &ops[inst];
}
if (mn == NULL) {
fprintf(of, "???");
return -(vp - 1);
}
fprintf(of, "%s", mn->mnemonic);
for (i = 0; i < mn->op_count; i++) {
/* Special cases for non-descriptor opcodes */
if (mn->mode == OP_BYTE) {
mode = 6;
reg = 15;
} else if (mn->mode == OP_HALF) {
mode = 5;
reg = 15;
} else if (mn->mode == OP_COPR) {
mode = 4;
reg = 15;
} else {
desc = val[vp++];
mode = (desc >> 4) & 0xf;
reg = desc & 0xf;
/* Find the expanded data type, if any */
if (mode == 14 &&
(reg == 0 || reg == 2 || reg == 3 ||
reg == 4 || reg == 6 || reg == 7)) {
etype = reg;
/* The real descriptor byte lies one ahead */
desc = val[vp++];
mode = (desc >> 4) & 0xf;
reg = desc & 0xf;
}
}
fputc(i ? ',' : ' ', of);
switch (etype) {
case 0:
fprintf(of, "{uword}");
break;
case 2:
fprintf(of, "{uhalf}");
break;
case 3:
fprintf(of, "{ubyte}");
break;
case 4:
fprintf(of, "{word}");
break;
case 6:
fprintf(of, "{half}");
break;
case 7:
fprintf(of, "{sbyte}");
break;
default:
/* do nothing */
break;
}
switch(mode) {
case 0: /* Positive Literal */
case 1: /* Positive Literal */
case 2: /* Positive Literal */
case 3: /* Positive Literal */
case 15: /* Negative Literal */
fprintf(of, "&%d", desc);
break;
case 4: /* Halfword Immediate, Register Mode */
switch (reg) {
case 15: /* Word Immediate */
OP_R_W(w, val, vp);
fprintf(of, "&0x%x", w);
break;
default: /* Register Mode */
cpu_register_name(reg, reg_name, 8);
fprintf(of, "%s", reg_name);
break;
}
break;
case 5: /* Halfword Immediate, Register Deferred */
switch (reg) {
case 15:
OP_R_H(w, val, vp);
fprintf(of, "&0x%x", w);
break;
default:
cpu_register_name(reg, reg_name, 8);
fprintf(of, "(%s)", reg_name);
break;
}
break;
case 6: /* Byte Immediate, FP Short Offset */
switch (reg) {
case 15:
OP_R_B(w, val, vp);
fprintf(of, "&0x%x", w);
break;
default:
fprintf(of, "%d(%%fp)", reg);
break;
}
break;
case 7: /* Absolute, AP Short Offset */
switch (reg) {
case 15:
OP_R_W(w, val, vp);
fprintf(of, "$0x%x", w);
break;
default:
fprintf(of, "%d(%%ap)", reg);
break;
}
break;
case 8: /* Word Displacement */
OP_R_W(w, val, vp);
cpu_register_name(reg, reg_name, 8);
fprintf(of, "0x%x(%s)", w, reg_name);
break;
case 9: /* Word Displacement Deferred */
OP_R_W(w, val, vp);
cpu_register_name(reg, reg_name, 8);
fprintf(of, "*0x%x(%s)", w, reg_name);
break;
case 10: /* Halfword Displacement */
OP_R_H(w, val, vp);
cpu_register_name(reg, reg_name, 8);
fprintf(of, "0x%x(%s)", w, reg_name);
break;
case 11: /* Halfword Displacement Deferred */
OP_R_H(w, val, vp);
cpu_register_name(reg, reg_name, 8);
fprintf(of, "*0x%x(%s)", w, reg_name);
break;
case 12: /* Byte Displacement */
OP_R_B(w, val, vp);
cpu_register_name(reg, reg_name, 8);
fprintf(of, "%d(%s)", w, reg_name);
break;
case 13: /* Byte Displacement Deferred */
OP_R_B(w, val, vp);
cpu_register_name(reg, reg_name, 8);
fprintf(of, "*%d(%s)", w, reg_name);
break;
case 14:
if (reg == 15) {
OP_R_W(w, val, vp);
fprintf(of, "*$0x%x", w);
}
break;
default:
fprintf(of, "<?>");
break;
}
}
return -(vp - 1);
}
void fprint_sym_hist(FILE *st, instr *ip)
{
int32 i;
@ -794,7 +979,7 @@ t_stat cpu_show_hist(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
if (ip->mn == NULL || ip->mn->op_count < 0) {
fprintf(st, "???");
} else {
fprint_sym_m(st, ip);
fprint_sym_hist(st, ip);
if (ip->mn->op_count > 0 && ip->mn->mode == OP_DESC) {
fprintf(st, "\n ");
for (j = 0; j < (uint32) ip->mn->op_count; j++) {
@ -936,7 +1121,7 @@ void cpu_show_operand(FILE *st, operand *op)
}
break;
case 15:
fprintf(st, "&%d", (int32)op->embedded.w);
fprintf(st, "&0x%x", (int32)op->embedded.w);
break;
}
}
@ -989,26 +1174,21 @@ static SIM_INLINE void clear_instruction(instr *inst)
/*
* Decode a single descriptor-defined operand from the instruction
* stream. Returns the number of bytes consumed during decode.
* stream. Returns the number of bytes consumed during decode.type
*/
static uint8 decode_operand(uint32 pa, instr *instr, uint8 op_number)
static uint8 decode_operand(uint32 pa, instr *instr, uint8 op_number, uint8 *etype)
{
uint8 desc;
uint8 offset = 0;
operand *oper = &instr->operands[op_number];
/* Set the default data type if none is already set */
if (cpu_dtype == -1) {
cpu_dtype = instr->mn->dtype;
}
/* Read in the descriptor byte */
desc = read_b(pa + offset++, ACC_OF);
oper->mode = (desc >> 4) & 0xf;
oper->reg = desc & 0xf;
oper->dtype = instr->mn->dtype;
oper->etype = cpu_etype;
oper->etype = *etype;
switch (oper->mode) {
case 0: /* Positive Literal */
@ -1016,7 +1196,7 @@ static uint8 decode_operand(uint32 pa, instr *instr, uint8 op_number)
case 2: /* Positive Literal */
case 3: /* Positive Literal */
case 15: /* Negative literal */
oper->embedded.b = (uint8)desc;
oper->embedded.b = desc;
oper->data = oper->embedded.b;
break;
case 4: /* Word Immediate, Register Mode */
@ -1110,9 +1290,9 @@ static uint8 decode_operand(uint32 pa, instr *instr, uint8 op_number)
case 7: /* Expanded Datatype */
/* Recursively decode the remainder of the operand after
storing the expanded datatype */
cpu_etype = (int8) oper->reg;
oper->etype = cpu_etype;
offset += decode_operand(pa + offset, instr, op_number);
*etype = (int8) oper->reg;
oper->etype = *etype;
offset += decode_operand(pa + offset, instr, op_number, etype);
break;
default:
cpu_abort(NORMAL_EXCEPTION, RESERVED_DATATYPE);
@ -1134,9 +1314,9 @@ static uint8 decode_operand(uint32 pa, instr *instr, uint8 op_number)
* the opcode type.
* 3. Fetch each opcode from main memory.
*
* This routine may alter the PSW's ET (Exception Type) and
* ISC (Internal State Code) registers if an exceptional condition
* is encountered during decode.
* This routine is guaranteed not to change state.
*
* returns: a Normal Exception if an error occured, or 0 on success.
*/
uint8 decode_instruction(instr *instr)
{
@ -1146,6 +1326,9 @@ uint8 decode_instruction(instr *instr)
uint32 pa;
mnemonic *mn = NULL;
int i;
int8 etype = -1; /* Expanded datatype (if any) */
clear_instruction(instr);
pa = R[NUM_PC];
@ -1154,10 +1337,6 @@ uint8 decode_instruction(instr *instr)
instr->sp = R[NUM_SP];
instr->pc = pa;
/* Reset our data types */
cpu_etype = -1;
cpu_dtype = -1;
if (read_operand(pa + offset++, &b1) != SCPE_OK) {
/* We tried to read out of a page that doesn't exist. We
need to let the operating system handle it.*/
@ -1222,13 +1401,13 @@ uint8 decode_instruction(instr *instr)
/* Decode subsequent operands */
for (i = 1; i < mn->op_count; i++) {
offset += decode_operand(pa + offset, instr, (uint8) i);
offset += decode_operand(pa + offset, instr, (uint8) i, &etype);
}
break;
case OP_DESC:
for (i = 0; i < mn->op_count; i++) {
offset += decode_operand(pa + offset, instr, (uint8) i);
offset += decode_operand(pa + offset, instr, (uint8) i, &etype);
}
break;
}
@ -1508,7 +1687,6 @@ t_stat sim_instr(void)
}
/* Decode the instruction */
clear_instruction(cpu_instr);
pc_incr = decode_instruction(cpu_instr);
/* Make sure to update the valid bit for history keeping (if

View file

@ -403,7 +403,8 @@ t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs);
void cpu_register_name(uint8 reg, char *buf, size_t len);
void cpu_show_operand(FILE *st, operand *op);
void fprint_sym_m(FILE *st, instr *ip);
void fprint_sym_hist(FILE *st, instr *ip);
t_stat fprint_sym_m(FILE *of, t_addr addr, t_value *val);
instr *cpu_next_instruction(void);
@ -488,4 +489,20 @@ static SIM_INLINE void sub(t_uint64 a, t_uint64 b, operand *dst);
} \
}
#define OP_R_W(d,a,p) { \
(d) = (uint32) (a)[(p)++]; \
(d) |= (uint32) (a)[(p)++] << 8u; \
(d) |= (uint32) (a)[(p)++] << 16u; \
(d) |= (uint32) (a)[(p)++] << 24u; \
}
#define OP_R_H(d,a,p) { \
(d) = (uint16) (a)[(p)++]; \
(d) |= (uint16) (a)[(p)++] << 8u; \
}
#define OP_R_B(d,a,p) { \
(d) = (uint8) (a)[(p)++]; \
}
#endif

View file

@ -160,6 +160,10 @@ t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw)
num = 0;
vp = 0;
if (sw & (int32) SWMASK('M')) {
return fprint_sym_m(of, addr, val);
}
if (sw & (int32) SWMASK ('B')) {
len = 1;
} else if (sw & (int32) SWMASK ('H')) {
@ -168,11 +172,6 @@ t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw)
len = 4;
}
if (sw & (int32) SWMASK('M')) {
fprint_sym_m(of, cpu_instr);
return SCPE_OK;
}
if (sw & (int32) SWMASK('C')) {
len = 16;
for (k = (int32) len - 1; k >= 0; k--) {

View file

@ -40,9 +40,9 @@ extern int32 sim_emax;
extern DEVICE *sim_devices[];
void full_reset();
t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag);
t_stat parse_sym (CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val,
t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag);
t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val,
int32 sw);
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw);
t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw);
#endif