mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-24 06:51:17 +01:00
DSP: I hereby name R08-R11 WR0-WR3, standing for Wrap control Registers 0-3.
Kill "CR". Document decrements a little bit. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3126 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
9b642fa1f8
commit
0d57b7f01a
@ -457,6 +457,7 @@ void lri(const UDSPInstruction& opc)
|
||||
u8 reg = opc.hex & DSP_REG_MASK;
|
||||
u16 imm = dsp_fetch_code();
|
||||
dsp_op_write_reg(reg, imm);
|
||||
dsp_conditional_extend_accum(reg);
|
||||
}
|
||||
|
||||
// LRIS $(0x18+D), #I
|
||||
@ -468,6 +469,7 @@ void lris(const UDSPInstruction& opc)
|
||||
u8 reg = ((opc.hex >> 8) & 0x7) + DSP_REG_AXL0;
|
||||
u16 imm = (s8)opc.hex;
|
||||
dsp_op_write_reg(reg, imm);
|
||||
dsp_conditional_extend_accum(reg);
|
||||
}
|
||||
|
||||
// LR $D, @M
|
||||
@ -481,6 +483,7 @@ void lr(const UDSPInstruction& opc)
|
||||
u16 addr = dsp_fetch_code();
|
||||
u16 val = dsp_dmem_read(addr);
|
||||
dsp_op_write_reg(reg, val);
|
||||
dsp_conditional_extend_accum(reg);
|
||||
}
|
||||
|
||||
// SR @M, $S
|
||||
@ -1392,12 +1395,7 @@ void dar(const UDSPInstruction& opc)
|
||||
{
|
||||
int reg = opc.hex & 0x3;
|
||||
|
||||
int temp = g_dsp.r[reg] + g_dsp.r[DSP_REG_R08];
|
||||
|
||||
if (temp <= 0x7ff) // ???
|
||||
g_dsp.r[reg] = temp;
|
||||
else
|
||||
g_dsp.r[reg]--;
|
||||
g_dsp.r[reg]--; // TODO: Wrap properly.
|
||||
}
|
||||
|
||||
|
||||
@ -1410,12 +1408,7 @@ void iar(const UDSPInstruction& opc)
|
||||
{
|
||||
int reg = opc.hex & 0x3;
|
||||
|
||||
int temp = g_dsp.r[reg] + g_dsp.r[DSP_REG_R08];
|
||||
|
||||
if (temp <= 0x7ff) // ???
|
||||
g_dsp.r[reg] = temp;
|
||||
else
|
||||
g_dsp.r[reg]++;
|
||||
g_dsp.r[reg]++; // TODO: Wrap properly according to the corresponding WR register.
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
@ -1476,7 +1469,7 @@ void srbith(const UDSPInstruction& opc)
|
||||
g_dsp.r[DSP_REG_SR] |= SR_TOP_BIT_UNK;
|
||||
break;
|
||||
|
||||
// 40-bit precision? clamping? no idea :(
|
||||
// Automatic 40-bit sign extension when loading ACx.M.
|
||||
// 40 seems to be the default.
|
||||
// Confirmed these by using DSPSpy and copying the value of SR to R00 after setting.
|
||||
case 0xe: // SET16 (really, clear SR's 0x4000)
|
||||
@ -1583,7 +1576,7 @@ void mulmvz(const UDSPInstruction& opc)
|
||||
dsp_set_long_acc(rreg, acc);
|
||||
|
||||
// math prod
|
||||
prod = (s64)g_dsp.r[DSP_REG_AXL0 + sreg] * (s64)g_dsp.r[DSP_REG_AXH0 + sreg] * GetMultiplyModifier();
|
||||
prod = (s64)(s16)g_dsp.r[DSP_REG_AXL0 + sreg] * (s64)(s16)g_dsp.r[DSP_REG_AXH0 + sreg] * GetMultiplyModifier();
|
||||
dsp_set_long_prod(prod);
|
||||
|
||||
Update_SR_Register64(prod);
|
||||
|
@ -309,7 +309,6 @@ const DSPOPCTemplate cw =
|
||||
const DSPOPCTemplate opcodes_ext[] =
|
||||
{
|
||||
// FIXME: guessing this is cr need checking
|
||||
{"CR", 0x0000, 0x00fc, DSPInterpreter::Ext::cr, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
|
||||
{"DR", 0x0004, 0x00fc, DSPInterpreter::Ext::dr, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
|
||||
{"IR", 0x0008, 0x00fc, DSPInterpreter::Ext::ir, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
|
||||
{"NR", 0x000c, 0x00fc, DSPInterpreter::Ext::nr, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
|
||||
@ -401,14 +400,14 @@ const pdlabel_t regnames[] =
|
||||
{0x01, "AR1", "Addr Reg 01",},
|
||||
{0x02, "AR2", "Addr Reg 02",},
|
||||
{0x03, "AR3", "Addr Reg 03",},
|
||||
{0x04, "IX0", "Index Reg 0(04)",},
|
||||
{0x05, "IX1", "Index Reg 1(05)",},
|
||||
{0x06, "IX2", "Index Reg 2(06)",},
|
||||
{0x07, "IX3", "Indec Reg 3(07)",},
|
||||
{0x08, "R08", "Register 08",},
|
||||
{0x09, "R09", "Register 09",},
|
||||
{0x0a, "R10", "Register 10",},
|
||||
{0x0b, "R11", "Register 11",},
|
||||
{0x04, "IX0", "Index Reg 0",},
|
||||
{0x05, "IX1", "Index Reg 1",},
|
||||
{0x06, "IX2", "Index Reg 2",},
|
||||
{0x07, "IX3", "Index Reg 3",},
|
||||
{0x08, "WR0", "Wrapping Register 0",},
|
||||
{0x09, "WR1", "Wrapping Register 1",},
|
||||
{0x0a, "WR2", "Wrapping Register 2",},
|
||||
{0x0b, "WR3", "Wrapping Register 3",},
|
||||
{0x0c, "ST0", "Call stack",},
|
||||
{0x0d, "ST1", "Data stack",},
|
||||
{0x0e, "ST2", "Loop addr stack",},
|
||||
@ -435,6 +434,12 @@ const pdlabel_t regnames[] =
|
||||
{0x21, "ACC1", "Accu Full 1",},
|
||||
{0x22, "AX0", "Extra Accu 0",},
|
||||
{0x23, "AX1", "Extra Accu 1",},
|
||||
|
||||
// Old names for the wrapping registers, for compatibility.
|
||||
{0x08, "R08", "Wrapping Register 0(08)",},
|
||||
{0x09, "R09", "Wrapping Register 1(09)",},
|
||||
{0x0a, "R10", "Wrapping Register 2(10)",},
|
||||
{0x0b, "R11", "Wrapping Register 3(11)",},
|
||||
};
|
||||
|
||||
u8 opSize[OPTABLE_SIZE];
|
||||
|
@ -29,22 +29,21 @@
|
||||
// attached to opcodes that allow extending (8 lower bits of opcode not used by
|
||||
// opcode). Extended opcodes do not modify program counter $pc register.
|
||||
|
||||
// Most of the suffixes increment or decrement one or more addressing registers
|
||||
// (the first four, ARx). The increment/decrement is either 1, or the corresponding
|
||||
// "index" register (the second four, IXx). The addressing registers will wrap
|
||||
// in odd ways, dictated by the corresponding wrapping register, WP0-3.
|
||||
|
||||
// The following should be applied as a decrement:
|
||||
// ar[i] = (ar[i] & wp[i]) == 0 ? ar[i] | wp[i] : ar[i] - 1;
|
||||
// I have not found the corresponding algorithms for increments yet.
|
||||
// It's gotta be fairly simple though. See R3123, R3125 in Google Code.
|
||||
|
||||
namespace DSPInterpreter
|
||||
{
|
||||
namespace Ext
|
||||
{
|
||||
|
||||
// CR $arR
|
||||
// xxxx xxxx 0000 00rr
|
||||
// Clearing addressing register $arR.
|
||||
// This is not in any doc and as such just a guess
|
||||
void cr(const UDSPInstruction& opc) {
|
||||
u8 reg = opc.hex & 0x3;
|
||||
|
||||
g_dsp.r[reg] = 0;
|
||||
}
|
||||
|
||||
// DR $arR
|
||||
// xxxx xxxx 0000 01rr
|
||||
// Decrement addressing register $arR.
|
||||
@ -208,7 +207,6 @@ void dsp_op_ext_r_epi(const UDSPInstruction& opc)
|
||||
{
|
||||
u8 op = (opc.hex >> 2) & 0x3;
|
||||
u8 reg = opc.hex & 0x3;
|
||||
|
||||
switch (op) {
|
||||
case 0x00: //
|
||||
g_dsp.r[reg] = 0;
|
||||
@ -375,7 +373,6 @@ void dsp_op_ext_ld(const UDSPInstruction& opc)
|
||||
//
|
||||
//
|
||||
// ================================================================================
|
||||
|
||||
void dsp_op_ext_ops_pro(const UDSPInstruction& opc)
|
||||
{
|
||||
if ((opc.hex & 0xFF) == 0){return;}
|
||||
@ -428,7 +425,10 @@ void dsp_op_ext_ops_pro(const UDSPInstruction& opc)
|
||||
|
||||
void dsp_op_ext_ops_epi(const UDSPInstruction& opc)
|
||||
{
|
||||
if ((opc.hex & 0xFF) == 0){return;}
|
||||
if ((opc.hex & 0xFF) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch ((opc.hex >> 4) & 0xf)
|
||||
{
|
||||
@ -436,7 +436,6 @@ void dsp_op_ext_ops_epi(const UDSPInstruction& opc)
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
|
||||
if (opc.hex & 0x2)
|
||||
{
|
||||
dsp_op_ext_sl_epi(opc.hex);
|
||||
@ -450,5 +449,3 @@ void dsp_op_ext_ops_epi(const UDSPInstruction& opc)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,7 +62,6 @@ void ldn(const UDSPInstruction& opc);
|
||||
void ldm(const UDSPInstruction& opc);
|
||||
void ldnm(const UDSPInstruction& opc);
|
||||
void mv(const UDSPInstruction& opc);
|
||||
void cr(const UDSPInstruction& opc);
|
||||
void dr(const UDSPInstruction& opc);
|
||||
void ir(const UDSPInstruction& opc);
|
||||
void nr(const UDSPInstruction& opc);
|
||||
|
@ -83,50 +83,19 @@ inline u16 dsp_op_read_reg(u8 reg)
|
||||
inline void dsp_op_write_reg(u8 reg, u16 val)
|
||||
{
|
||||
switch (reg & 0x1f) {
|
||||
|
||||
|
||||
/*
|
||||
case DSP_REG_ACH0:
|
||||
case DSP_REG_ACH1:
|
||||
// sign extend from the bottom 8 bits.
|
||||
g_dsp.r[reg] = (u16)(s16)(s8)(u8)val;
|
||||
break;
|
||||
*/
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
dsp_reg_store_stack(reg - 0x0c, val);
|
||||
break;
|
||||
#if 0 // FIXME
|
||||
case 0x1e: // AC0.M
|
||||
case 0x1f: // AC1.M
|
||||
// in "s16 mode", LRI $AC0.M, xxx will set AC0.L and AC0.H to 0,
|
||||
// while it won't in "s40 mode".
|
||||
if (g_dsp.r[DSP_REG_SR] & SR_16_BIT) {
|
||||
g_dsp.r[reg - 0x2] = 0; // L
|
||||
g_dsp.r[reg - 0xe] = 0; // H
|
||||
}
|
||||
|
||||
g_dsp.r[reg] = val;
|
||||
break;
|
||||
|
||||
|
||||
case 0x1c: // AC0.L
|
||||
case 0x1d: // AC1.L
|
||||
|
||||
if (g_dsp.r[DSP_REG_SR] & SR_16_BIT) {
|
||||
g_dsp.r[reg + 0x2] = 0; // M
|
||||
g_dsp.r[reg - 0xc] = 0; // H
|
||||
}
|
||||
|
||||
g_dsp.r[reg] = val;
|
||||
break;
|
||||
|
||||
case 0x10: // AC0.H
|
||||
case 0x11: // AC1.H
|
||||
if (g_dsp.r[DSP_REG_SR] & SR_16_BIT) {
|
||||
g_dsp.r[reg + 0xc] = 0; // L
|
||||
g_dsp.r[reg + 0xe] = 0; // M
|
||||
}
|
||||
|
||||
g_dsp.r[reg] = val;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
default:
|
||||
g_dsp.r[reg] = val;
|
||||
@ -134,6 +103,25 @@ inline void dsp_op_write_reg(u8 reg, u16 val)
|
||||
}
|
||||
}
|
||||
|
||||
inline void dsp_conditional_extend_accum(u8 reg)
|
||||
{
|
||||
#if 0
|
||||
switch (reg)
|
||||
{
|
||||
case DSP_REG_ACM0:
|
||||
case DSP_REG_ACM1:
|
||||
if (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT)
|
||||
{
|
||||
// Sign extend into whole accum.
|
||||
u16 val = g_dsp.r[reg];
|
||||
g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0] = (val & 0x8000) ? 0xFFFF : 0x0000;
|
||||
g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0] = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
//
|
||||
@ -253,13 +241,13 @@ inline s64 dsp_get_long_acx(int _reg)
|
||||
inline s16 dsp_get_ax_l(int _reg)
|
||||
{
|
||||
_assert_(_reg < 2);
|
||||
return g_dsp.r[0x18 + _reg];
|
||||
return (s16)g_dsp.r[0x18 + _reg];
|
||||
}
|
||||
|
||||
inline s16 dsp_get_ax_h(int _reg)
|
||||
{
|
||||
_assert_(_reg < 2);
|
||||
return g_dsp.r[0x1a + _reg];
|
||||
return (s16)g_dsp.r[0x1a + _reg];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -31,19 +31,19 @@
|
||||
#define DSP_REG_AR0 0x00 // address registers
|
||||
#define DSP_REG_AR1 0x01
|
||||
#define DSP_REG_AR2 0x02
|
||||
#define DSP_REG_AR3 0x03 // used as jump function selector
|
||||
#define DSP_REG_AR3 0x03
|
||||
|
||||
#define DSP_REG_IX0 0x04 // LEFT_VOLUME accel
|
||||
#define DSP_REG_IX1 0x05 // RIGHT_VOLUME accel
|
||||
#define DSP_REG_IX2 0x06 // ADDRH_SMP accel
|
||||
#define DSP_REG_IX3 0x07 // ADDRL_SMP accel
|
||||
#define DSP_REG_IX0 0x04 // indexing registers (actually, mostly used as increments)
|
||||
#define DSP_REG_IX1 0x05
|
||||
#define DSP_REG_IX2 0x06
|
||||
#define DSP_REG_IX3 0x07
|
||||
|
||||
#define DSP_REG_R08 0x08 // fixed to 48000 value
|
||||
#define DSP_REG_R09 0x09 // problems using this
|
||||
#define DSP_REG_R0A 0x0a // ADDREH_SMP accel
|
||||
#define DSP_REG_R0B 0x0b // ADDREL_SMP accel
|
||||
#define DSP_REG_WR0 0x08 // address wrapping registers. should be initialized to 0xFFFF if not used.
|
||||
#define DSP_REG_WR1 0x09
|
||||
#define DSP_REG_WR2 0x0a
|
||||
#define DSP_REG_WR3 0x0b
|
||||
|
||||
#define DSP_REG_ST0 0x0c
|
||||
#define DSP_REG_ST0 0x0c // stacks.
|
||||
#define DSP_REG_ST1 0x0d
|
||||
#define DSP_REG_ST2 0x0e
|
||||
#define DSP_REG_ST3 0x0f
|
||||
@ -51,15 +51,15 @@
|
||||
#define DSP_REG_CONFIG 0x12
|
||||
#define DSP_REG_SR 0x13
|
||||
|
||||
#define DSP_REG_PRODL 0x14
|
||||
#define DSP_REG_PRODL 0x14 // product.
|
||||
#define DSP_REG_PRODM 0x15
|
||||
#define DSP_REG_PRODH 0x16
|
||||
#define DSP_REG_PRODM2 0x17
|
||||
|
||||
#define DSP_REG_AXL0 0x18
|
||||
#define DSP_REG_AXL1 0x19
|
||||
#define DSP_REG_AXH0 0x1a // SMP_R accel
|
||||
#define DSP_REG_AXH1 0x1b // SMP_L accel
|
||||
#define DSP_REG_AXH0 0x1a
|
||||
#define DSP_REG_AXH1 0x1b
|
||||
|
||||
#define DSP_REG_ACC0 0x1c // accumulator (global)
|
||||
#define DSP_REG_ACC1 0x1d
|
||||
@ -85,6 +85,7 @@
|
||||
#define DSP_REG_CMBH 0xfffe // CPU Mailbox H
|
||||
#define DSP_REG_CMBL 0xffff // CPU Mailbox L
|
||||
|
||||
|
||||
#define DMA_TO_DSP 0
|
||||
#define DMA_TO_CPU 1
|
||||
|
||||
@ -92,7 +93,6 @@
|
||||
#define DSP_STACK_C 0
|
||||
#define DSP_STACK_D 1
|
||||
|
||||
|
||||
// SR bits
|
||||
#define SR_CARRY 0x0001
|
||||
#define SR_2 0x0002 // overflow???
|
||||
@ -107,7 +107,6 @@
|
||||
#define SR_40_MODE_BIT 0x4000 // 0 = "16", 1 = "40" (SET16, SET40) Controls sign extension when loading mid accums.
|
||||
#define SR_TOP_BIT_UNK 0x8000 // 1 = normal. 0 = x2 (CLR15, SET15) ????????
|
||||
|
||||
|
||||
void dsp_reg_store_stack(u8 stack_reg, u16 val);
|
||||
u16 dsp_reg_load_stack(u8 stack_reg);
|
||||
|
||||
|
@ -2,24 +2,24 @@
|
||||
incdir "tests"
|
||||
include "dsp_base.inc"
|
||||
|
||||
; Tests done using AR1 = 0x0010, IX1 = 0. LP1 means R09.
|
||||
; LP1 = 0
|
||||
; Tests done using AR1 = 0x0010, IX1 = 0. WR1 (wrap 1) means R09.
|
||||
; WR1 = 0
|
||||
; 10, 10, 10, 10,
|
||||
; LP1 = 1
|
||||
; WR1 = 1
|
||||
; 10, 11, 10, 11,
|
||||
; LP1 = 2
|
||||
; WR1 = 2
|
||||
; 10, 12, 11, 13, 12, 11, 13, 12, 11, 13, 12, 11
|
||||
; LP1 = 3
|
||||
; WR1 = 3
|
||||
; 10, 13, 12, 11, 10, 13, 12...
|
||||
; LP1 = 4
|
||||
; WR1 = 4
|
||||
; 10, 14, 13, 17, 16, 15, 14, 13, 17, 16, 15, 14, 13, ...
|
||||
; LP1 = 5
|
||||
; WR1 = 5
|
||||
; 10, 15, 14, 13, 12, 17, 16, 15, 14, 13, 12, 17,
|
||||
; LP1 = 6
|
||||
; WR1 = 6
|
||||
; 10, 16, 15, 14, 13, 12, 11, 17, 16, 15, 14, 13
|
||||
; LP1 = 7
|
||||
; WR1 = 7
|
||||
; 10, 17, 16, 15, .. normal
|
||||
; LP1 = 8
|
||||
; WR1 = 8
|
||||
; 10, 18, 17, 1f, 1e, 1d, 1c, 1b, 1a, 19, 18, 17, 1f, 1e, .....
|
||||
|
||||
|
||||
|
@ -8,23 +8,23 @@ include "dsp_base.inc"
|
||||
; These were proven FALSE though by the following:
|
||||
|
||||
; Tests done using AR1 = 0x0010, IX1 = 0
|
||||
; LP1 = 0
|
||||
; WR1 = 0
|
||||
; 10, 11, 11, 11, 11......
|
||||
; LP1 = 1
|
||||
; WR1 = 1
|
||||
; 10, 11, 10, 11, 10......
|
||||
; LP1 = 2
|
||||
; WR1 = 2
|
||||
; 10, 11, 12, 13, 11, 12, 13, 11, 12, 13 ......
|
||||
; LP1 = 3
|
||||
; WR1 = 3
|
||||
; 10, 11, 12, 13, 10, 11, 12, 13, 10, 11, 12, 13.......
|
||||
; LP1 = 4
|
||||
; WR1 = 4
|
||||
; 10, 11, 12, 13, 14, 15, 16, 17, 13, 14, 15, 16, 17, 13, 14, 15 ......
|
||||
; LP1 = 5
|
||||
; WR1 = 5
|
||||
; 10, 11, 12, 13, 14, 15, 16, 17, 12, 13, 14, 15 ...
|
||||
; LP1 = 6
|
||||
; WR1 = 6
|
||||
; 10, 11, 12, 13, 14, 15, 16, 17, 11, 12, 13, 14...
|
||||
; LP1 = 7
|
||||
; WR1 = 7
|
||||
; 10, 11, 12, 13, 14, 15, 16, 17, 10, 11, ....
|
||||
; LP1 = 8
|
||||
; WR1 = 8
|
||||
; 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1a, 1b, 1c, 1d, 1e, 1f, 17, 18, 19, 1a, 1b.....
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user