diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp index 6bff593344..a00cf7a8af 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp @@ -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; diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp index 6c486a8efe..e095b246a6 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp @@ -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) { diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp index 9ae6a58781..915a449f0c 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp @@ -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++; diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_registers.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_registers.h index eaf99b4c42..dd927198db 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_registers.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_registers.h @@ -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)