Got rid of loop step + added some comments

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2928 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
nakeee 2009-04-08 14:11:23 +00:00
parent 65daec3554
commit 7dccebfef2
4 changed files with 80 additions and 43 deletions

View File

@ -138,6 +138,12 @@ void ret(const UDSPInstruction& opc)
}
}
// RTI
// 0000 0010 1111 1111
// Return from exception. Pops stored status register $sr from data stack
// $st1 and program counter PC from call stack $st0 and sets $pc to this
// location.
// FIXME: is it also conditional? unknown opcodes 0x02fx
void rti(const UDSPInstruction& opc)
{
g_dsp.r[DSP_REG_SR] = dsp_reg_load_stack(DSP_STACK_D);
@ -155,37 +161,64 @@ void halt(const UDSPInstruction& opc)
g_dsp.pc = g_dsp.err_pc;
}
// LOOP handling: Loop stack is used to control execution of repeated blocks of
// instructions. Whenever there is value on stack $st2 and current PC is equal
// value at $st2, then value at stack $st3 is decremented. If value is not zero
// then PC is modified with calue from call stack $st0. Otherwise values from
// callstack $st0 and both loop stacks $st2 and $st3 are poped and execution
// continues at next opcode.
// LOOP $R
// 0000 0000 010r rrrr
// Repeatedly execute following opcode until counter specified by value
// from register $R reaches zero. Each execution decrement counter. Register
// $R remains unchanged. If register $R is set to zero at the beginning of loop
// then looped instruction will not get executed.
void loop(const UDSPInstruction& opc)
{
u16 reg = opc.hex & 0x1f;
u16 cnt = g_dsp.r[reg];
u16 loop_pc = g_dsp.pc;
while (cnt--)
if (cnt)
{
gdsp_loop_step();
g_dsp.pc = loop_pc;
dsp_reg_store_stack(0, g_dsp.pc);
dsp_reg_store_stack(2, loop_pc);
dsp_reg_store_stack(3, cnt);
}
// g_dsp.pc = loop_pc;
g_dsp.pc += opSize[dsp_peek_code()];
}
// LOOPI #I
// 0001 0000 iiii iiii
// Repeatedly execute following opcode until counter specified by
// immediate value I reaches zero. Each execution decrement counter. If
// immediate value I is set to zero at the beginning of loop then looped
// instruction will not get executed.
void loopi(const UDSPInstruction& opc)
{
u16 cnt = opc.hex & 0xff;
u16 loop_pc = g_dsp.pc;
while (cnt--)
if (cnt)
{
gdsp_loop_step();
g_dsp.pc = loop_pc;
dsp_reg_store_stack(0, g_dsp.pc);
dsp_reg_store_stack(2, loop_pc);
dsp_reg_store_stack(3, cnt);
}
// g_dsp.pc = loop_pc;
g_dsp.pc += opSize[dsp_peek_code()];
}
// BLOOP $R, addrA
// 0000 0000 011r rrrr
// aaaa aaaa aaaa aaaa
// Repeatedly execute block of code starting at following opcode until
// counter specified by value from register $R reaches zero. Block ends at
// specified address addrA inclusive, ie. opcode at addrA is the last opcode
// included in loop. Counter is pushed on loop stack $st3, end of block address
// is pushed on loop stack $st2 and repeat address is pushed on call stack $st0.
// Up to 4 nested loops is allowed.
void bloop(const UDSPInstruction& opc)
{
u16 reg = opc.hex & 0x1f;
@ -205,6 +238,15 @@ void bloop(const UDSPInstruction& opc)
}
}
// BLOOPI #I, addrA
// 0001 0001 iiii iiii
// aaaa aaaa aaaa aaaa
// Repeatedly execute block of code starting at following opcode until
// counter specified by immediate value I reaches zero. Block ends at specified
// address addrA inclusive, ie. opcode at addrA is the last opcode included in
// loop. Counter is pushed on loop stack $st3, end of block address is pushed
// on loop stack $st2 and repeat address is pushed on call stack $st0. Up to 4
// nested loops is allowed.
void bloopi(const UDSPInstruction& opc)
{
u16 cnt = opc.hex & 0xff;
@ -344,8 +386,7 @@ void srri(const UDSPInstruction& opc)
// SRRN @$D, $S
// 0001 1011 1dds ssss
// Store value from source register $S to a memory location pointed by
// addressing register $D. Add indexing register $(0x4+D) to register $D.
// addressing register $D. Add DSP_REG_IX0 register to register $D.
// FIXME: Perform additional operation depending on source register.
void srrn(const UDSPInstruction& opc)
{
@ -354,7 +395,7 @@ void srrn(const UDSPInstruction& opc)
u16 val = dsp_op_read_reg(sreg);
dsp_dmem_write(g_dsp.r[dreg], val);
g_dsp.r[dreg] += g_dsp.r[dreg + 4];
g_dsp.r[dreg] += g_dsp.r[DSP_REG_IX0 + dreg];
}
// ILRR $acD.m, @$arS
@ -426,11 +467,11 @@ void lri(const UDSPInstruction& opc)
// LRIS $(0x18+D), #I
// 0000 1ddd iiii iiii
// Load immediate value I (8-bit sign extended) to accumulator register$(0x18+D).
// Load immediate value I (8-bit sign extended) to accumulator register.
// FIXME: Perform additional operation depending on destination register.
void lris(const UDSPInstruction& opc)
{
u8 reg = ((opc.hex >> 8) & 0x7) + 0x18;
u8 reg = ((opc.hex >> 8) & 0x7) + DSP_REG_AXL0;
u16 imm = (s8)opc.hex;
dsp_op_write_reg(reg, imm);
}
@ -516,7 +557,7 @@ void clrl(const UDSPInstruction& opc)
g_dsp.r[reg] &= 0x0000;
// Should this be 64bit?
// nakee: it says the whole reg in doddie's doc sounds weird
// nakee: it says the whole reg in duddie's doc sounds weird
Update_SR_Register64((s64)reg);
}
@ -525,7 +566,7 @@ void clrl(const UDSPInstruction& opc)
// Clears product register $prod.
void clrp(const UDSPInstruction& opc)
{
// Magic numbers taken from doddie's doc
// Magic numbers taken from duddie's doc
g_dsp.r[0x14] = 0x0000;
g_dsp.r[0x15] = 0xfff0;
g_dsp.r[0x16] = 0x00ff;
@ -687,6 +728,10 @@ void movax(const UDSPInstruction& opc)
Update_SR_Register64(acx);
}
// XORR $acD.m, $axS.h
// 0011 00sd xxxx xxxx
// Logic XOR (exclusive or) middle part of accumulator $acD.m with
// high part of secondary accumulator $axS.h.
void xorr(const UDSPInstruction& opc)
{
u8 sreg = (opc.hex >> 9) & 0x1;
@ -699,7 +744,7 @@ void xorr(const UDSPInstruction& opc)
// ANDR $acD.m, $axS.h
// 0011 01sd xxxx xxxx
// Logic AND middle part of accumulator $acD.m with hight part of
// Logic AND middle part of accumulator $acD.m with high part of
// secondary accumulator $axS.h.
void andr(const UDSPInstruction& opc)
{
@ -711,6 +756,11 @@ void andr(const UDSPInstruction& opc)
tsta(dreg);
}
// ORR $acD.m, $axS.h
// 0011 10sd xxxx xxxx
// Logic OR middle part of accumulator $acD.m with high part of
// secondary accumulator $axS.h.
void orr(const UDSPInstruction& opc)
{
u8 sreg = (opc.hex >> 9) & 0x1;
@ -1379,7 +1429,7 @@ void mul(const UDSPInstruction& opc)
dsp_set_long_prod(prod);
// FIXME: no update in doddie's docs
// FIXME: no update in duddie's docs
Update_SR_Register64(prod);
}
@ -1400,7 +1450,7 @@ void mulac(const UDSPInstruction& opc)
s64 prod = dsp_get_ax_l(sreg) * dsp_get_ax_h(sreg) * GetMultiplyModifier();
dsp_set_long_prod(prod);
// FIXME: no update in doddie's docs
// FIXME: no update in duddie's docs
Update_SR_Register64(prod);
}
@ -1626,7 +1676,7 @@ void msubc(const UDSPInstruction& opc)
// Store value from register $(0x18+S) to a memory pointed by address M.
// (8-bit sign extended).
// FIXME: Perform additional operation depending on destination register.
// Note: pc+=2 in doddie's doc seems wrong
// Note: pc+=2 in duddie's doc seems wrong
void srs(const UDSPInstruction& opc)
{
u8 reg = ((opc.hex >> 8) & 0x7) + 0x18;
@ -1639,7 +1689,7 @@ void srs(const UDSPInstruction& opc)
// Move value from data memory pointed by address M (8-bit sign
// extended) to register $(0x18+D).
// FIXME: Perform additional operation depending on destination register.
// Note: pc+=2 in doddie's doc seems wrong
// Note: pc+=2 in duddie's doc seems wrong
void lrs(const UDSPInstruction& opc)
{
u8 reg = ((opc.hex >> 8) & 0x7) + 0x18;

View File

@ -66,6 +66,10 @@ void nop(const UDSPInstruction& opc) {if(opc.hex) DSPInterpreter::unknown(opc);}
DSPOPCTemplate opcodes[] =
{
{"NOP", 0x0000, 0xffff, nop, nop, 1, 0, {}, NULL, NULL},
{"DAR", 0x0004, 0xfffc, DSPInterpreter::dar, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL},
{"IAR", 0x0008, 0xfffc, DSPInterpreter::iar, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL},
{"HALT", 0x0021, 0xffff, DSPInterpreter::halt, nop, 1, 0, {}, NULL, NULL},
{"RETNS", 0x02d0, 0xffff, DSPInterpreter::ret, nop, 1, 0, {}, NULL, NULL},
@ -117,8 +121,6 @@ DSPOPCTemplate opcodes[] =
{"JLZ", 0x029d, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}}, NULL, NULL},
{"JMP", 0x029f, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}}, NULL, NULL},
{"DAR", 0x0004, 0xfffc, DSPInterpreter::dar, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL},
{"IAR", 0x0008, 0xfffc, DSPInterpreter::iar, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL},
{"JRNS", 0x1700, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
{"JRS", 0x1701, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
@ -341,7 +343,7 @@ dspInstFunc epilogueTable[OPTABLE_SIZE];
const DSPOPCTemplate *GetOpTemplate(const UDSPInstruction &inst)
{
for (int i = 0; i < opcodes_size; i++)
for (u32 i = 0; i < opcodes_size; i++)
{
u16 mask = opcodes[i].opcode_mask;
if (opcodes[i].size & P_EXT) {

View File

@ -207,21 +207,6 @@ u16 gdsp_read_cr()
return g_dsp.cr;
}
// special loop step.. because exception in loop or loopi fails
// dunno how we have to fix it
// atm we execute this instructions directly inside the loop command
// so it cant be interrupted by an exception.
// TODO - we really should figure this out - on the real DSP, exception inside
// loop should work. Think through the stack management and how it works
// with exceptions and in loops.
void gdsp_loop_step()
{
g_dsp.err_pc = g_dsp.pc;
u16 opc = dsp_fetch_code();
ComputeInstruction(UDSPInstruction(opc));
}
void gdsp_step()
{
g_dsp.step_counter++;

View File

@ -59,7 +59,7 @@
#define DSP_REG_AXL0 0x18
#define DSP_REG_AXL1 0x19
#define DSP_REG_AXH0 0x1A // SMP_R accel
#define DSP_REG_AXH0 0x1a // SMP_R accel
#define DSP_REG_AXH1 0x1b // SMP_L accel
#define DSP_REG_ACC0 0x1c // accumulator (global)