mirror of https://github.com/xqemu/xqemu.git
Merge 18e7556490
into e1236e1b62
This commit is contained in:
commit
2fa80d62a7
|
@ -312,189 +312,8 @@ void dsp_print_registers(DSPState* dsp)
|
|||
i, dsp->core.registers[DSP_REG_M0+i]);
|
||||
}
|
||||
|
||||
printf("LA: %04x LC: %04x PC: %04x\n", dsp->core.registers[DSP_REG_LA], dsp->core.registers[DSP_REG_LC], dsp->core.pc);
|
||||
printf("SR: %04x OMR: %02x\n", dsp->core.registers[DSP_REG_SR], dsp->core.registers[DSP_REG_OMR]);
|
||||
printf("SP: %02x SSH: %04x SSL: %04x\n",
|
||||
printf("LA: %04x LC: %04x PC: %04x\n", dsp->core.registers[DSP_REG_LA], dsp->core.registers[DSP_REG_LC], dsp->core.pc);
|
||||
printf("SR: %06x OMR: %02x\n", dsp->core.registers[DSP_REG_SR], dsp->core.registers[DSP_REG_OMR]);
|
||||
printf("SP: %02x SSH: %04x SSL: %04x\n",
|
||||
dsp->core.registers[DSP_REG_SP], dsp->core.registers[DSP_REG_SSH], dsp->core.registers[DSP_REG_SSL]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get given DSP register address and required bit mask.
|
||||
* Works for A0-2, B0-2, LA, LC, M0-7, N0-7, R0-7, X0-1, Y0-1, PC, SR, SP,
|
||||
* OMR, SSH & SSL registers, but note that the SP, SSH & SSL registers
|
||||
* need special handling (in DSP*SetRegister()) when they are set.
|
||||
* Return the register width in bits or zero for an error.
|
||||
*/
|
||||
int dsp_get_register_address(DSPState* dsp, const char *regname, uint32_t **addr, uint32_t *mask)
|
||||
{
|
||||
#define MAX_REGNAME_LEN 4
|
||||
typedef struct {
|
||||
const char name[MAX_REGNAME_LEN];
|
||||
uint32_t *addr;
|
||||
size_t bits;
|
||||
uint32_t mask;
|
||||
} reg_addr_t;
|
||||
|
||||
/* sorted by name so that this can be bisected */
|
||||
const reg_addr_t registers[] = {
|
||||
|
||||
/* 56-bit A register */
|
||||
{ "A0", &dsp->core.registers[DSP_REG_A0], 32, BITMASK(24) },
|
||||
{ "A1", &dsp->core.registers[DSP_REG_A1], 32, BITMASK(24) },
|
||||
{ "A2", &dsp->core.registers[DSP_REG_A2], 32, BITMASK(8) },
|
||||
|
||||
/* 56-bit B register */
|
||||
{ "B0", &dsp->core.registers[DSP_REG_B0], 32, BITMASK(24) },
|
||||
{ "B1", &dsp->core.registers[DSP_REG_B1], 32, BITMASK(24) },
|
||||
{ "B2", &dsp->core.registers[DSP_REG_B2], 32, BITMASK(8) },
|
||||
|
||||
/* 16-bit LA & LC registers */
|
||||
{ "LA", &dsp->core.registers[DSP_REG_LA], 32, BITMASK(16) },
|
||||
{ "LC", &dsp->core.registers[DSP_REG_LC], 32, BITMASK(16) },
|
||||
|
||||
/* 16-bit M registers */
|
||||
{ "M0", &dsp->core.registers[DSP_REG_M0], 32, BITMASK(16) },
|
||||
{ "M1", &dsp->core.registers[DSP_REG_M1], 32, BITMASK(16) },
|
||||
{ "M2", &dsp->core.registers[DSP_REG_M2], 32, BITMASK(16) },
|
||||
{ "M3", &dsp->core.registers[DSP_REG_M3], 32, BITMASK(16) },
|
||||
{ "M4", &dsp->core.registers[DSP_REG_M4], 32, BITMASK(16) },
|
||||
{ "M5", &dsp->core.registers[DSP_REG_M5], 32, BITMASK(16) },
|
||||
{ "M6", &dsp->core.registers[DSP_REG_M6], 32, BITMASK(16) },
|
||||
{ "M7", &dsp->core.registers[DSP_REG_M7], 32, BITMASK(16) },
|
||||
|
||||
/* 16-bit N registers */
|
||||
{ "N0", &dsp->core.registers[DSP_REG_N0], 32, BITMASK(16) },
|
||||
{ "N1", &dsp->core.registers[DSP_REG_N1], 32, BITMASK(16) },
|
||||
{ "N2", &dsp->core.registers[DSP_REG_N2], 32, BITMASK(16) },
|
||||
{ "N3", &dsp->core.registers[DSP_REG_N3], 32, BITMASK(16) },
|
||||
{ "N4", &dsp->core.registers[DSP_REG_N4], 32, BITMASK(16) },
|
||||
{ "N5", &dsp->core.registers[DSP_REG_N5], 32, BITMASK(16) },
|
||||
{ "N6", &dsp->core.registers[DSP_REG_N6], 32, BITMASK(16) },
|
||||
{ "N7", &dsp->core.registers[DSP_REG_N7], 32, BITMASK(16) },
|
||||
|
||||
{ "OMR", &dsp->core.registers[DSP_REG_OMR], 32, 0x5f },
|
||||
|
||||
/* 16-bit program counter */
|
||||
{ "PC", (uint32_t*)(&dsp->core.pc), 24, BITMASK(24) },
|
||||
|
||||
/* 16-bit DSP R (address) registers */
|
||||
{ "R0", &dsp->core.registers[DSP_REG_R0], 32, BITMASK(16) },
|
||||
{ "R1", &dsp->core.registers[DSP_REG_R1], 32, BITMASK(16) },
|
||||
{ "R2", &dsp->core.registers[DSP_REG_R2], 32, BITMASK(16) },
|
||||
{ "R3", &dsp->core.registers[DSP_REG_R3], 32, BITMASK(16) },
|
||||
{ "R4", &dsp->core.registers[DSP_REG_R4], 32, BITMASK(16) },
|
||||
{ "R5", &dsp->core.registers[DSP_REG_R5], 32, BITMASK(16) },
|
||||
{ "R6", &dsp->core.registers[DSP_REG_R6], 32, BITMASK(16) },
|
||||
{ "R7", &dsp->core.registers[DSP_REG_R7], 32, BITMASK(16) },
|
||||
|
||||
{ "SSH", &dsp->core.registers[DSP_REG_SSH], 32, BITMASK(16) },
|
||||
{ "SSL", &dsp->core.registers[DSP_REG_SSL], 32, BITMASK(16) },
|
||||
{ "SP", &dsp->core.registers[DSP_REG_SP], 32, BITMASK(6) },
|
||||
|
||||
/* 16-bit status register */
|
||||
{ "SR", &dsp->core.registers[DSP_REG_SR], 32, 0xefff },
|
||||
|
||||
/* 48-bit X register */
|
||||
{ "X0", &dsp->core.registers[DSP_REG_X0], 32, BITMASK(24) },
|
||||
{ "X1", &dsp->core.registers[DSP_REG_X1], 32, BITMASK(24) },
|
||||
|
||||
/* 48-bit Y register */
|
||||
{ "Y0", &dsp->core.registers[DSP_REG_Y0], 32, BITMASK(24) },
|
||||
{ "Y1", &dsp->core.registers[DSP_REG_Y1], 32, BITMASK(24) }
|
||||
};
|
||||
/* left, right, middle, direction */
|
||||
int l, r, m, dir = 0;
|
||||
unsigned int i, len;
|
||||
char reg[MAX_REGNAME_LEN];
|
||||
|
||||
for (i = 0; i < sizeof(reg) && regname[i]; i++) {
|
||||
reg[i] = toupper(regname[i]);
|
||||
}
|
||||
if (i < 2 || regname[i]) {
|
||||
/* too short or longer than any of the names */
|
||||
return 0;
|
||||
}
|
||||
len = i;
|
||||
|
||||
/* bisect */
|
||||
l = 0;
|
||||
r = ARRAYSIZE(registers) - 1;
|
||||
do {
|
||||
m = (l+r) >> 1;
|
||||
for (i = 0; i < len; i++) {
|
||||
dir = (int)reg[i] - registers[m].name[i];
|
||||
if (dir) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dir == 0) {
|
||||
*addr = registers[m].addr;
|
||||
*mask = registers[m].mask;
|
||||
return registers[m].bits;
|
||||
}
|
||||
if (dir < 0) {
|
||||
r = m-1;
|
||||
} else {
|
||||
l = m+1;
|
||||
}
|
||||
} while (l <= r);
|
||||
#undef MAX_REGNAME_LEN
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set given DSP register value, return false if unknown register given
|
||||
*/
|
||||
bool dsp_disasm_set_register(DSPState* dsp, const char *arg, uint32_t value)
|
||||
{
|
||||
uint32_t *addr, mask, sp_value;
|
||||
int bits;
|
||||
|
||||
/* first check registers needing special handling... */
|
||||
if (arg[0]=='S' || arg[0]=='s') {
|
||||
if (arg[1]=='P' || arg[1]=='p') {
|
||||
dsp->core.registers[DSP_REG_SP] = value & BITMASK(6);
|
||||
value &= BITMASK(4);
|
||||
dsp->core.registers[DSP_REG_SSH] = dsp->core.stack[0][value];
|
||||
dsp->core.registers[DSP_REG_SSL] = dsp->core.stack[1][value];
|
||||
return true;
|
||||
}
|
||||
if (arg[1]=='S' || arg[1]=='s') {
|
||||
sp_value = dsp->core.registers[DSP_REG_SP] & BITMASK(4);
|
||||
if (arg[2]=='H' || arg[2]=='h') {
|
||||
if (sp_value == 0) {
|
||||
dsp->core.registers[DSP_REG_SSH] = 0;
|
||||
dsp->core.stack[0][sp_value] = 0;
|
||||
} else {
|
||||
dsp->core.registers[DSP_REG_SSH] = value & BITMASK(16);
|
||||
dsp->core.stack[0][sp_value] = value & BITMASK(16);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (arg[2]=='L' || arg[2]=='l') {
|
||||
if (sp_value == 0) {
|
||||
dsp->core.registers[DSP_REG_SSL] = 0;
|
||||
dsp->core.stack[1][sp_value] = 0;
|
||||
} else {
|
||||
dsp->core.registers[DSP_REG_SSL] = value & BITMASK(16);
|
||||
dsp->core.stack[1][sp_value] = value & BITMASK(16);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ...then registers where address & mask are enough */
|
||||
bits = dsp_get_register_address(dsp, arg, &addr, &mask);
|
||||
switch (bits) {
|
||||
case 32:
|
||||
*addr = value & mask;
|
||||
return true;
|
||||
case 16:
|
||||
*(uint16_t*)addr = value & mask;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -57,8 +57,6 @@ uint32_t dsp_disasm_memory(DSPState* dsp, uint32_t dsp_memdump_addr, uint32_t ds
|
|||
uint32_t dsp_disasm_address(DSPState* dsp, FILE *out, uint32_t lowerAdr, uint32_t UpperAdr);
|
||||
void dsp_info(DSPState* dsp);
|
||||
void dsp_print_registers(DSPState* dsp);
|
||||
int dsp_get_register_address(DSPState* dsp, const char *arg, uint32_t **addr, uint32_t *mask);
|
||||
bool dsp_disasm_set_register(DSPState* dsp, const char *arg, uint32_t value);
|
||||
|
||||
|
||||
#endif /* DSP_H */
|
||||
|
|
|
@ -133,7 +133,7 @@ static const int registers_mask[64] = {
|
|||
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 16, 8, 6,
|
||||
0, 24, 8, 6,
|
||||
16, 16, 16, 16
|
||||
};
|
||||
|
||||
|
@ -393,6 +393,7 @@ void dsp56k_reset_cpu(dsp_core_t* dsp)
|
|||
for (i=0;i<8;i++) {
|
||||
dsp->registers[DSP_REG_M0+i]=0x00ffff;
|
||||
}
|
||||
dsp->registers[DSP_REG_SR]=0xC00300;
|
||||
|
||||
/* Interruptions */
|
||||
memset(dsp->interrupt_is_pending, 0, sizeof(dsp->interrupt_is_pending));
|
||||
|
@ -503,6 +504,7 @@ static void disasm_reg_compare(dsp_core_t* dsp)
|
|||
case DSP_REG_X1:
|
||||
case DSP_REG_Y0:
|
||||
case DSP_REG_Y1:
|
||||
case DSP_REG_SR:
|
||||
printf("\tReg: %s $%06x -> $%06x\n",
|
||||
registers_name[i], dsp->disasm_registers_save[i], dsp->registers[i]);
|
||||
break;
|
||||
|
@ -530,7 +532,6 @@ static void disasm_reg_compare(dsp_core_t* dsp)
|
|||
case DSP_REG_N5:
|
||||
case DSP_REG_N6:
|
||||
case DSP_REG_N7:
|
||||
case DSP_REG_SR:
|
||||
case DSP_REG_LA:
|
||||
case DSP_REG_LC:
|
||||
printf("\tReg: %s $%04x -> $%04x\n",
|
||||
|
@ -819,7 +820,7 @@ static void dsp_postexecute_interrupts(dsp_core_t* dsp)
|
|||
if ( ((instr & 0xfff000) == 0x0d0000) || ((instr & 0xffc0ff) == 0x0bc080) ) {
|
||||
dsp->interrupt_state = DSP_INTERRUPT_LONG;
|
||||
dsp_stack_push(dsp, dsp->interrupt_save_pc, dsp->registers[DSP_REG_SR], 0);
|
||||
dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_LF)|(1<<DSP_SR_T) |
|
||||
emu_clear_sr_flags(dsp, (1<<DSP_SR_LF)|(1<<DSP_SR_T) |
|
||||
(1<<DSP_SR_S1)|(1<<DSP_SR_S0) |
|
||||
(1<<DSP_SR_I0)|(1<<DSP_SR_I1));
|
||||
dsp->registers[DSP_REG_SR] |= dsp->interrupt_ipl_to_raise<<DSP_SR_I0;
|
||||
|
@ -833,7 +834,7 @@ static void dsp_postexecute_interrupts(dsp_core_t* dsp)
|
|||
if ( ((instr & 0xfff000) == 0x0d0000) || ((instr & 0xffc0ff) == 0x0bc080) ) {
|
||||
dsp->interrupt_state = DSP_INTERRUPT_LONG;
|
||||
dsp_stack_push(dsp, dsp->interrupt_save_pc, dsp->registers[DSP_REG_SR], 0);
|
||||
dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_LF)|(1<<DSP_SR_T) |
|
||||
emu_clear_sr_flags(dsp, (1<<DSP_SR_LF)|(1<<DSP_SR_T) |
|
||||
(1<<DSP_SR_S1)|(1<<DSP_SR_S0) |
|
||||
(1<<DSP_SR_I0)|(1<<DSP_SR_I1));
|
||||
dsp->registers[DSP_REG_SR] |= dsp->interrupt_ipl_to_raise<<DSP_SR_I0;
|
||||
|
@ -1081,7 +1082,14 @@ static void dsp_write_reg(dsp_core_t* dsp, uint32_t numreg, uint32_t value)
|
|||
dsp->registers[DSP_REG_OMR] = value & 0xc7;
|
||||
break;
|
||||
case DSP_REG_SR:
|
||||
dsp->registers[DSP_REG_SR] = value & 0xaf7f;
|
||||
|
||||
/* Check for unhandled bits */
|
||||
assert((value & (1 << 7)) == 0); /* Scaling */
|
||||
assert((value & (1 << 12)) == 0); /* Reserved */
|
||||
assert((value & (1 << 14)) == 0); /* Double-Precision */
|
||||
assert((value & 0xFF0000) == 0xC00000); /* EMR */
|
||||
|
||||
dsp->registers[DSP_REG_SR] = value & BITMASK(registers_mask[DSP_REG_SR]);
|
||||
break;
|
||||
case DSP_REG_SP:
|
||||
stack_error = dsp->registers[DSP_REG_SP] & (3<<DSP_SP_SE);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue