[APEXC] 1. Added pseudo PC register for the debugger, it will now highlight the next instruction to be executed.

2. Added "normal" addresses to disassembler output, so anyone can see the program flow. [Robbbert]
This commit is contained in:
Miodrag Milanovic 2010-01-31 13:19:16 +00:00
parent 439b7362ac
commit a461dfee73
3 changed files with 31 additions and 19 deletions

View File

@ -356,6 +356,7 @@ struct _apexc_state
int running; /* 1 flag: */ int running; /* 1 flag: */
/* running: flag implied by the existence of the stop instruction */ /* running: flag implied by the existence of the stop instruction */
UINT32 pc; /* address of next instruction for the disassembler */
running_device *device; running_device *device;
const address_space *program; const address_space *program;
@ -540,6 +541,7 @@ static void execute(apexc_state *cpustate)
function = (cpustate->cr >> 7) & 0x1F; function = (cpustate->cr >> 7) & 0x1F;
c6 = (cpustate->cr >> 1) & 0x3F; c6 = (cpustate->cr >> 1) & 0x3F;
vector = cpustate->cr & 1; vector = cpustate->cr & 1;
cpustate->pc = y<<2;
function &= 0x1E; /* this is a mere guess - the LSBit is reserved for future additions */ function &= 0x1E; /* this is a mere guess - the LSBit is reserved for future additions */
@ -595,6 +597,7 @@ static void execute(apexc_state *cpustate)
{ {
/* load ml with X */ /* load ml with X */
delay1 = load_ml(cpustate, x, vector); delay1 = load_ml(cpustate, x, vector);
cpustate->pc = x<<2;
/* burn pre-fetch delay if needed */ /* burn pre-fetch delay if needed */
if (delay1) if (delay1)
{ {
@ -827,7 +830,7 @@ static CPU_EXECUTE( apexc )
do do
{ {
debugger_instruction_hook(device, effective_address(cpustate, cpustate->ml)); debugger_instruction_hook(device, cpustate->pc);
if (cpustate->running) if (cpustate->running)
execute(cpustate); execute(cpustate);
@ -870,6 +873,7 @@ static CPU_SET_INFO( apexc )
case CPUINFO_INT_REGISTER + APEXC_A: cpustate->a = info->i; break; case CPUINFO_INT_REGISTER + APEXC_A: cpustate->a = info->i; break;
case CPUINFO_INT_REGISTER + APEXC_R: cpustate->r = info->i; break; case CPUINFO_INT_REGISTER + APEXC_R: cpustate->r = info->i; break;
case CPUINFO_INT_REGISTER + APEXC_ML: cpustate->ml = info->i & 0x3ff; break; case CPUINFO_INT_REGISTER + APEXC_ML: cpustate->ml = info->i & 0x3ff; break;
case CPUINFO_INT_REGISTER + APEXC_PC: cpustate->pc = info->i; break;
case CPUINFO_INT_REGISTER + APEXC_WS: cpustate->working_store = info->i & 0xf; break; case CPUINFO_INT_REGISTER + APEXC_WS: cpustate->working_store = info->i & 0xf; break;
case CPUINFO_INT_REGISTER + APEXC_STATE: cpustate->running = info->i ? TRUE : FALSE; break; case CPUINFO_INT_REGISTER + APEXC_STATE: cpustate->running = info->i ? TRUE : FALSE; break;
} }
@ -904,11 +908,7 @@ CPU_GET_INFO( apexc )
case CPUINFO_INT_SP: info->i = 0; /* no SP */ break; case CPUINFO_INT_SP: info->i = 0; /* no SP */ break;
case CPUINFO_INT_PC: case CPUINFO_INT_PC:
/* no PC - return memory location register instead, this should be case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->pc; /* psuedo-PC */ break;
equivalent unless executed in the midst of an instruction */
info->i = effective_address(cpustate, cpustate->ml);
break;
case CPUINFO_INT_PREVIOUSPC: info->i = 0; /* no PC */ break;
/*case CPUINFO_INT_INPUT_STATE + ...:*/ /* no interrupts */ /*case CPUINFO_INT_INPUT_STATE + ...:*/ /* no interrupts */
@ -916,6 +916,7 @@ CPU_GET_INFO( apexc )
case CPUINFO_INT_REGISTER + APEXC_A: info->i = cpustate->a; break; case CPUINFO_INT_REGISTER + APEXC_A: info->i = cpustate->a; break;
case CPUINFO_INT_REGISTER + APEXC_R: info->i = cpustate->r; break; case CPUINFO_INT_REGISTER + APEXC_R: info->i = cpustate->r; break;
case CPUINFO_INT_REGISTER + APEXC_ML: info->i = cpustate->ml; break; case CPUINFO_INT_REGISTER + APEXC_ML: info->i = cpustate->ml; break;
case CPUINFO_INT_REGISTER + APEXC_PC: info->i = cpustate->pc; break;
case CPUINFO_INT_REGISTER + APEXC_WS: info->i = cpustate->working_store; break; case CPUINFO_INT_REGISTER + APEXC_WS: info->i = cpustate->working_store; break;
case CPUINFO_INT_REGISTER + APEXC_STATE: info->i = cpustate->running; break; case CPUINFO_INT_REGISTER + APEXC_STATE: info->i = cpustate->running; break;
case CPUINFO_INT_REGISTER + APEXC_ML_FULL: info->i = effective_address(cpustate, cpustate->ml); break; case CPUINFO_INT_REGISTER + APEXC_ML_FULL: info->i = effective_address(cpustate, cpustate->ml); break;
@ -940,6 +941,7 @@ CPU_GET_INFO( apexc )
case CPUINFO_STR_REGISTER + APEXC_A: sprintf(info->s, "A :%08X", cpustate->a); break; case CPUINFO_STR_REGISTER + APEXC_A: sprintf(info->s, "A :%08X", cpustate->a); break;
case CPUINFO_STR_REGISTER + APEXC_R: sprintf(info->s, "R :%08X", cpustate->r); break; case CPUINFO_STR_REGISTER + APEXC_R: sprintf(info->s, "R :%08X", cpustate->r); break;
case CPUINFO_STR_REGISTER + APEXC_ML: sprintf(info->s, "ML:%03X", cpustate->ml); break; case CPUINFO_STR_REGISTER + APEXC_ML: sprintf(info->s, "ML:%03X", cpustate->ml); break;
case CPUINFO_STR_REGISTER + APEXC_PC: sprintf(info->s, "PC:%03X", cpustate->pc); break;
case CPUINFO_STR_REGISTER + APEXC_WS: sprintf(info->s, "WS:%01X", cpustate->working_store); break; case CPUINFO_STR_REGISTER + APEXC_WS: sprintf(info->s, "WS:%01X", cpustate->working_store); break;
case CPUINFO_STR_REGISTER + APEXC_STATE: sprintf(info->s, "CPU state:%01X", cpustate->running ? TRUE : FALSE); break; case CPUINFO_STR_REGISTER + APEXC_STATE: sprintf(info->s, "CPU state:%01X", cpustate->running ? TRUE : FALSE); break;

View File

@ -13,9 +13,10 @@ enum
APEXC_WS, /* working store */ APEXC_WS, /* working store */
APEXC_STATE, /* whether CPU is running */ APEXC_STATE, /* whether CPU is running */
APEXC_ML_FULL /* read-only pseudo-register for exclusive use by the control panel code APEXC_ML_FULL, /* read-only pseudo-register for exclusive use by the control panel code
in the apexc driver : enables it to get the complete address computed in the apexc driver : enables it to get the complete address computed
from the contents of ML and WS */ from the contents of ML and WS */
APEXC_PC /* doesn't actually exist; is there for the disassembler */
}; };
CPU_GET_INFO( apexc ); CPU_GET_INFO( apexc );

View File

@ -51,6 +51,15 @@
For vector instructions, replace the first space on the right of the mnemonic For vector instructions, replace the first space on the right of the mnemonic
with a 'v'. with a 'v'.
01-Feb-2010 (Robbbert):
I've added the actual address, (as shown in the extreme left of the debugger
output), so that you can see much easier how the program will flow. Example:
+C XXX(##/##) XXX(##/##)
The X value shows where the data word is located, and the Y value is the
address of the next instruction.
*/ */
enum _format_type {branch, shiftl, shiftr, multiply, store, swap, one_address, two_address}; enum _format_type {branch, shiftl, shiftr, multiply, store, swap, one_address, two_address};
typedef enum _format_type format_type; typedef enum _format_type format_type;
@ -104,7 +113,7 @@ CPU_DISASSEMBLE( apexc )
case two_address: case two_address:
case branch: case branch:
case swap: case swap:
buffer += sprintf(buffer, "%-10s", mnemonic); /* 10 chars*/ buffer += sprintf(buffer, " %-10s", mnemonic); /* 10 chars*/
break; break;
case shiftl: case shiftl:
@ -113,32 +122,32 @@ CPU_DISASSEMBLE( apexc )
n = c6; n = c6;
else else
n = 64-c6; n = 64-c6;
buffer += sprintf(buffer, "%-2s(%2d) ", mnemonic, n); /* 10 chars */ buffer += sprintf(buffer, " %-2s(%2d) ", mnemonic, n); /* 10 chars */
break; break;
case multiply: case multiply:
n = 33-c6; n = 33-c6;
if (n == 32) if (n == 32)
/* case "32" : do not show bit specifier */ /* case "32" : do not show bit specifier */
buffer += sprintf(buffer, "%-10s", mnemonic); /* 10 chars */ buffer += sprintf(buffer, " %-10s", mnemonic); /* 10 chars */
else else
buffer += sprintf(buffer, "%-2s(%2d) ", mnemonic, n); /* 10 chars */ buffer += sprintf(buffer, " %-2s(%2d) ", mnemonic, n); /* 10 chars */
break; break;
case store: case store:
if (c6 == 0) if (c6 == 0)
{ /* case "1-32" : do not show bit specifier */ { /* case "1-32" : do not show bit specifier */
buffer += sprintf(buffer, "%-10s", mnemonic); /* 10 chars*/ buffer += sprintf(buffer, " %-10s", mnemonic); /* 10 chars*/
} }
else if (c6 & 0x20) else if (c6 & 0x20)
{ /* case "1-n" */ { /* case "1-n" */
n = c6-32; n = c6-32;
buffer += sprintf(buffer, "%-2s (1-%02d) ", mnemonic, n); /* 10 chars */ buffer += sprintf(buffer, " %-2s (1-%02d) ", mnemonic, n); /* 10 chars */
} }
else else
{ /* case "n-32" */ { /* case "n-32" */
n = c6+1; n = c6+1;
buffer += sprintf(buffer, "%-2s(%02d-32) ", mnemonic, n); /* 8 chars */ buffer += sprintf(buffer, " %-2s(%02d-32) ", mnemonic, n); /* 8 chars */
} }
} }
@ -147,28 +156,28 @@ CPU_DISASSEMBLE( apexc )
{ {
case branch: case branch:
buffer--; /* eat last char */ buffer--; /* eat last char */
buffer += sprintf(buffer, "<(%02d/%02d) >=", (x >> 5) & 0x1f, x & 0x1f); /* 10+1 chars */ buffer += sprintf(buffer, "<%03X(%02d/%02d) >=", x<<2, (x >> 5) & 0x1f, x & 0x1f); /* 10+1 chars */
break; break;
case multiply: case multiply:
case swap: case swap:
buffer += sprintf(buffer, "(%02d) ", (x >> 5) & 0x1f); /* 10 chars */ buffer += sprintf(buffer, " (%02d) ", (x >> 5) & 0x1f); /* 10 chars */
break; break;
case one_address: case one_address:
case shiftl: case shiftl:
case shiftr: case shiftr:
buffer += sprintf(buffer, " "); /* 10 chars */ buffer += sprintf(buffer, " "); /* 10 chars */
break; break;
case two_address: case two_address:
case store: case store:
buffer += sprintf(buffer, "(%02d/%02d) ", (x >> 5) & 0x1f, x & 0x1f); /* 10 chars */ buffer += sprintf(buffer, "%03X(%02d/%02d) ", x<<2, (x >> 5) & 0x1f, x & 0x1f); /* 10 chars */
break; break;
} }
/* print Y address */ /* print Y address */
buffer += sprintf(buffer, "(%02d/%02d)", (y >> 5) & 0x1f, y & 0x1f); /* 7 chars */ buffer += sprintf(buffer, "%03X(%02d/%02d)", y<<2, (y >> 5) & 0x1f, y & 0x1f); /* 7 chars */
return 4; return 4;
} }