mirror of https://github.com/xemu-project/xemu.git
instructions, mix
This commit is contained in:
parent
7f336a762e
commit
5cfb52aebf
|
@ -138,15 +138,28 @@ static const int registers_mask[64] = {
|
|||
|
||||
#include "dsp_dis.inl"
|
||||
|
||||
typedef bool (*match_func_t)(uint32_t op);
|
||||
|
||||
typedef struct OpcodeEntry {
|
||||
const char* template;
|
||||
const char* name;
|
||||
dis_func_t dis_func;
|
||||
emu_func_t emu_func;
|
||||
match_func_t match_func;
|
||||
} OpcodeEntry;
|
||||
|
||||
static bool match_MMMRRR(uint32_t op)
|
||||
{
|
||||
uint32_t RRR = (op >> 8) & BITMASK(3);
|
||||
uint32_t MMM = (op >> 11) & BITMASK(3);
|
||||
if (MMM == 0x6) {
|
||||
return RRR == 0x0 || RRR == 0x4;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const OpcodeEntry nonparallel_opcodes[] = {
|
||||
{ "0000000101iiiiii1000d000", "add #xx, D", NULL, NULL },
|
||||
{ "0000000101iiiiii1000d000", "add #xx, D", dis_add_imm, emu_add_imm },
|
||||
{ "00000001010000001100d000", "add #xxxx, D", dis_add_long, emu_add_long },
|
||||
{ "0000000101iiiiii1000d110", "and #xx, D", NULL, NULL },
|
||||
{ "00000001010000001100d110", "and #xxxx, D", dis_and_long, emu_and_long },
|
||||
|
@ -158,12 +171,12 @@ static const OpcodeEntry nonparallel_opcodes[] = {
|
|||
{ "00001101000100000100CCCC", "bcc xxxx", dis_bcc_long, emu_bcc_long }, //??
|
||||
{ "00000101CCCC01aaaa0aaaaa", "bcc xxx", dis_bcc_imm, emu_bcc_imm },
|
||||
{ "0000110100011RRR0100CCCC", "bcc Rn", NULL, NULL },
|
||||
{ "0000101101MMMRRR0S00bbbb", "bchg #n, [X or Y]:ea", dis_bchg_ea, emu_bchg_ea },
|
||||
{ "0000101101MMMRRR0S00bbbb", "bchg #n, [X or Y]:ea", dis_bchg_ea, emu_bchg_ea, match_MMMRRR },
|
||||
{ "0000101100aaaaaa0S00bbbb", "bchg #n, [X or Y]:aa", dis_bchg_aa, emu_bchg_aa },
|
||||
{ "0000101110pppppp0S00bbbb", "bchg #n, [X or Y]:pp", dis_bchg_pp, emu_bchg_pp },
|
||||
{ "0000000101qqqqqq0S0bbbbb", "bchg #n, [X or Y]:qq", NULL, NULL },
|
||||
{ "0000101111DDDDDD010bbbbb", "bchg, #n, D", dis_bchg_reg, emu_bchg_reg },
|
||||
{ "0000101001MMMRRR0S00bbbb", "bclr #n, [X or Y]:ea", dis_bclr_ea, emu_bclr_ea },
|
||||
{ "0000101001MMMRRR0S00bbbb", "bclr #n, [X or Y]:ea", dis_bclr_ea, emu_bclr_ea, match_MMMRRR },
|
||||
{ "0000101000aaaaaa0S00bbbb", "bclr #n, [X or Y]:aa", dis_bclr_aa, emu_bclr_aa },
|
||||
{ "0000101010pppppp0S00bbbb", "bclr #n, [X or Y]:pp", dis_bclr_pp, emu_bclr_pp },
|
||||
{ "0000000100qqqqqq0S00bbbb", "bclr #n, [X or Y]:qq", NULL, NULL },
|
||||
|
@ -171,26 +184,26 @@ static const OpcodeEntry nonparallel_opcodes[] = {
|
|||
{ "000011010001000011000000", "bra xxxx", NULL, NULL },
|
||||
{ "00000101000011aaaa0aaaaa", "bra xxx", dis_bra_imm, emu_bra_imm },
|
||||
{ "0000110100011RRR11000000", "bra Rn", NULL, NULL },
|
||||
{ "0000110010MMMRRR0S0bbbbb", "brclr #n, [X or Y]:ea, xxxx", NULL, NULL },
|
||||
{ "0000110010MMMRRR0S0bbbbb", "brclr #n, [X or Y]:ea, xxxx", NULL, NULL, match_MMMRRR },
|
||||
{ "0000110010aaaaaa1S0bbbbb", "brclr #n, [X or Y]:aa, xxxx", NULL, NULL },
|
||||
{ "0000110011pppppp0S0bbbbb", "brclr #n, [X or Y]:pp, xxxx", dis_brclr_pp, emu_brclr_pp },
|
||||
{ "0000010010qqqqqq0S0bbbbb", "brclr #n, [X or Y]:qq, xxxx", NULL, NULL },
|
||||
{ "0000110011DDDDDD100bbbbb", "brclr #n, S, xxxx", NULL, NULL },
|
||||
{ "0000110011DDDDDD100bbbbb", "brclr #n, S, xxxx", dis_brclr_reg, emu_brclr_reg },
|
||||
{ "00000000000000100001CCCC", "brkcc", NULL, NULL },
|
||||
{ "0000110010MMMRRR0S1bbbbb", "brset #n, [X or Y]:ea, xxxx", NULL, NULL },
|
||||
{ "0000110010MMMRRR0S1bbbbb", "brset #n, [X or Y]:ea, xxxx", NULL, NULL, match_MMMRRR },
|
||||
{ "0000110010aaaaaa1S1bbbbb", "brset #n, [X or Y]:aa, xxxx", NULL, NULL },
|
||||
{ "0000110011pppppp0S1bbbbb", "brset #n, [X or Y]:pp, xxxx", dis_brset_pp, emu_brset_pp },
|
||||
{ "0000010010qqqqqq0S1bbbbb", "brset #n, [X or Y]:qq, xxxx", NULL, NULL },
|
||||
{ "0000110011DDDDDD101bbbbb", "brset #n, S, xxxx", NULL, NULL },
|
||||
{ "0000110011DDDDDD101bbbbb", "brset #n, S, xxxx", dis_brset_reg, emu_brset_reg },
|
||||
{ "00001101000100000000CCCC", "bscc xxxx", NULL, NULL },
|
||||
{ "00000101CCCC00aaaa0aaaaa", "bscc xxx", NULL, NULL },
|
||||
{ "0000110100011RRR0000CCCC", "bscc Rn", NULL, NULL },
|
||||
{ "0000110110MMMRRR0S0bbbbb", "bsclr #n, [X or Y]:ea, xxxx", NULL, NULL },
|
||||
{ "0000110110MMMRRR0S0bbbbb", "bsclr #n, [X or Y]:ea, xxxx", NULL, NULL, match_MMMRRR },
|
||||
{ "0000110110aaaaaa1S0bbbbb", "bsclr #n, [X or Y]:aa, xxxx", NULL, NULL },
|
||||
{ "0000010010qqqqqq1S0bbbbb", "bsclr #n, [X or Y]:qq, xxxx", NULL, NULL },
|
||||
{ "0000110111pppppp0S0bbbbb", "bsclr #n, [X or Y]:pp, xxxx", NULL, NULL },
|
||||
{ "0000110111DDDDDD100bbbbb", "bsclr, #n, S, xxxx", NULL, NULL },
|
||||
{ "0000101001MMMRRR0S1bbbbb", "bset #n, [X or Y]:ea", dis_bset_ea, emu_bset_ea },
|
||||
{ "0000101001MMMRRR0S1bbbbb", "bset #n, [X or Y]:ea", dis_bset_ea, emu_bset_ea, match_MMMRRR },
|
||||
{ "0000101000aaaaaa0S1bbbbb", "bset #n, [X or Y]:aa", dis_bset_aa, emu_bset_aa },
|
||||
{ "0000101010pppppp0S1bbbbb", "bset #n, [X or Y]:pp", dis_bset_pp, emu_bset_pp },
|
||||
{ "0000000100qqqqqq0S1bbbbb", "bset #n, [X or Y]:qq", NULL, NULL },
|
||||
|
@ -198,18 +211,18 @@ static const OpcodeEntry nonparallel_opcodes[] = {
|
|||
{ "000011010001000010000000", "bsr xxxx", dis_bsr_long, emu_bsr_long },
|
||||
{ "00000101000010aaaa0aaaaa", "bsr xxx", dis_bsr_imm, emu_bsr_imm },
|
||||
{ "0000110100011RRR10000000", "bsr Rn", NULL, NULL },
|
||||
{ "0000110110MMMRRR0S1bbbbb", "bsset #n, [X or Y]:ea, xxxx", NULL, NULL },
|
||||
{ "0000110110MMMRRR0S1bbbbb", "bsset #n, [X or Y]:ea, xxxx", NULL, NULL, match_MMMRRR },
|
||||
{ "0000110110aaaaaa1S1bbbbb", "bsset #n, [X or Y]:aa, xxxx", NULL, NULL },
|
||||
{ "0000110111pppppp0S1bbbbb", "bsset #n, [X or Y]:pp, xxxx", NULL, NULL },
|
||||
{ "0000010010qqqqqq1S1bbbbb", "bsset #n, [X or Y]:qq, xxxx", NULL, NULL },
|
||||
{ "0000110111DDDDDD101bbbbb", "bsset #n, S, xxxx", NULL, NULL },
|
||||
{ "0000101101MMMRRR0S10bbbb", "btst #n, [X or Y]:ea", dis_btst_ea, emu_btst_ea },
|
||||
{ "0000101101MMMRRR0S10bbbb", "btst #n, [X or Y]:ea", dis_btst_ea, emu_btst_ea, match_MMMRRR },
|
||||
{ "0000101100aaaaaa0S10bbbb", "btst #n, [X or Y]:aa", dis_btst_aa, emu_btst_aa },
|
||||
{ "0000101110pppppp0S10bbbb", "btst #n, [X or Y]:pp", dis_btst_pp, emu_btst_pp },
|
||||
{ "0000000101qqqqqq0S10bbbb", "btst #n, [X or Y]:qq", NULL, NULL },
|
||||
{ "0000101111DDDDDD0110bbbb", "btst #n, D", dis_btst_reg, emu_btst_reg },
|
||||
{ "0000110000011110000000SD", "clb S, D", NULL, NULL },
|
||||
{ "0000000101iiiiii1000d101", "cmp #xx, S2", NULL, NULL },
|
||||
{ "0000000101iiiiii1000d101", "cmp #xx, S2", dis_cmp_imm, emu_cmp_imm },
|
||||
{ "00000001010000001100d101", "cmp #xxxx, S2", NULL, NULL },
|
||||
{ "00001100000111111111gggd", "cmpu S1, S2", dis_cmpu, emu_cmpu },
|
||||
{ "000000000000001000000000", "debug", NULL, NULL },
|
||||
|
@ -217,15 +230,15 @@ static const OpcodeEntry nonparallel_opcodes[] = {
|
|||
{ "00000000000000000000101d", "dec D", NULL, NULL, /*dis_dec, emu_dec*/ },
|
||||
{ "000000011000000001JJd000", "div S, D", dis_div, emu_div },
|
||||
{ "000000010010010s1sdkQQQQ", "dmac S1, S2, D", NULL, NULL },
|
||||
{ "0000011001MMMRRR0S000000", "do [X or Y]:ea, expr", dis_do_ea, emu_do_ea },
|
||||
{ "0000011001MMMRRR0S000000", "do [X or Y]:ea, expr", dis_do_ea, emu_do_ea, match_MMMRRR },
|
||||
{ "0000011000aaaaaa0S000000", "do [X or Y]:aa, expr", dis_do_aa, emu_do_aa },
|
||||
{ "00000110iiiiiiii1000hhhh", "do #xxx, expr", dis_do_imm, emu_do_imm },
|
||||
{ "0000011011DDDDDD00000000", "do S, expr", dis_do_reg, emu_do_reg },
|
||||
{ "000000000000001000000011", "do_f", NULL, NULL },
|
||||
{ "0000011001MMMRRR0S010000", "dor [X or Y]:ea, label", NULL, NULL },
|
||||
{ "0000011001MMMRRR0S010000", "dor [X or Y]:ea, label", NULL, NULL, match_MMMRRR },
|
||||
{ "0000011000aaaaaa0S010000", "dor [X or Y]:aa, label", NULL, NULL },
|
||||
{ "00000110iiiiiiii1001hhhh", "dor #xxx, label", dis_dor_imm, emu_dor_imm },
|
||||
{ "0000011011DDDDDD00010000", "dor S, label", NULL, NULL },
|
||||
{ "0000011011DDDDDD00010000", "dor S, label", dis_dor_reg, emu_dor_reg },
|
||||
{ "000000000000001000000010", "dor_f", NULL, NULL },
|
||||
{ "000000000000000010001100", "enddo", NULL, emu_enddo },
|
||||
{ "0000000101iiiiii1000d011", "eor #xx, D", NULL, NULL },
|
||||
|
@ -239,29 +252,29 @@ static const OpcodeEntry nonparallel_opcodes[] = {
|
|||
{ "00001100000110110qqqSSSD", "insert S1, S2, D", NULL, NULL },
|
||||
{ "00001100000110010qqq000D", "insert #CO, S2, D", NULL, NULL },
|
||||
{ "00001110CCCCaaaaaaaaaaaa", "jcc xxx", dis_jcc_imm, emu_jcc_imm },
|
||||
{ "0000101011MMMRRR1010CCCC", "jcc ea", dis_jcc_ea, emu_jcc_ea },
|
||||
{ "0000101001MMMRRR1S00bbbb", "jclr #n, [X or Y]:ea, xxxx", dis_jclr_ea, emu_jclr_ea },
|
||||
{ "0000101011MMMRRR1010CCCC", "jcc ea", dis_jcc_ea, emu_jcc_ea, match_MMMRRR },
|
||||
{ "0000101001MMMRRR1S00bbbb", "jclr #n, [X or Y]:ea, xxxx", dis_jclr_ea, emu_jclr_ea, match_MMMRRR },
|
||||
{ "0000101000aaaaaa1S00bbbb", "jclr #n, [X or Y]:aa, xxxx", dis_jclr_aa, emu_jclr_aa },
|
||||
{ "0000101010pppppp1S00bbbb", "jclr #n, [X or Y]:pp, xxxx", dis_jclr_pp, emu_jclr_pp },
|
||||
{ "0000000110qqqqqq1S00bbbb", "jclr #n, [X or Y]:qq, xxxx", NULL, NULL },
|
||||
{ "0000101011DDDDDD0000bbbb", "jclr #n, S, xxxx", dis_jclr_reg, emu_jclr_reg },
|
||||
{ "0000101011MMMRRR10000000", "jmp ea", dis_jmp_ea, emu_jmp_ea },
|
||||
{ "0000101011MMMRRR10000000", "jmp ea", dis_jmp_ea, emu_jmp_ea, match_MMMRRR },
|
||||
{ "000011000000aaaaaaaaaaaa", "jmp xxx", dis_jmp_imm, emu_jmp_imm },
|
||||
{ "00001111CCCCaaaaaaaaaaaa", "jscc xxx", dis_jscc_imm, emu_jscc_imm },
|
||||
{ "0000101111MMMRRR1010CCCC", "jscc ea", dis_jscc_ea, emu_jscc_ea },
|
||||
{ "0000101101MMMRRR1S00bbbb", "jsclr #n, [X or Y]:ea, xxxx", dis_jsclr_ea, emu_jsclr_ea },
|
||||
{ "0000101100MMMRRR1S00bbbb", "jsclr #n, [X or Y]:aa, xxxx", dis_jsclr_aa, emu_jsclr_aa },
|
||||
{ "0000101111MMMRRR1010CCCC", "jscc ea", dis_jscc_ea, emu_jscc_ea, match_MMMRRR },
|
||||
{ "0000101101MMMRRR1S00bbbb", "jsclr #n, [X or Y]:ea, xxxx", dis_jsclr_ea, emu_jsclr_ea, match_MMMRRR },
|
||||
{ "0000101100MMMRRR1S00bbbb", "jsclr #n, [X or Y]:aa, xxxx", dis_jsclr_aa, emu_jsclr_aa, match_MMMRRR },
|
||||
{ "0000101110pppppp1S0bbbbb", "jsclr #n, [X or Y]:pp, xxxx", dis_jsclr_pp, emu_jsclr_pp },
|
||||
{ "0000000111qqqqqq1S0bbbbb", "jsclr #n, [X or Y]:qq, xxxx", NULL, NULL },
|
||||
{ "0000101111DDDDDD000bbbbb", "jsclr #n, S, xxxx", dis_jsclr_reg, emu_jsclr_reg },
|
||||
{ "0000101001MMMRRR1S10bbbb", "jset #n, [X or Y]:ea, xxxx", dis_jset_ea, emu_jset_ea },
|
||||
{ "0000101000MMMRRR1S10bbbb", "jset #n, [X or Y]:aa, xxxx", dis_jset_aa, emu_jset_aa },
|
||||
{ "0000101001MMMRRR1S10bbbb", "jset #n, [X or Y]:ea, xxxx", dis_jset_ea, emu_jset_ea, match_MMMRRR },
|
||||
{ "0000101000MMMRRR1S10bbbb", "jset #n, [X or Y]:aa, xxxx", dis_jset_aa, emu_jset_aa, match_MMMRRR },
|
||||
{ "0000101010pppppp1S10bbbb", "jset #n, [X or Y]:pp, xxxx", dis_jset_pp, emu_jset_pp },
|
||||
{ "0000000110qqqqqq1S10bbbb", "jset #n, [X or Y]:qq, xxxx", NULL, NULL },
|
||||
{ "0000101011DDDDDD0010bbbb", "jset #n, S, xxxx", dis_jset_reg, emu_jset_reg },
|
||||
{ "0000101111MMMRRR10000000", "jsr ea", dis_jsr_ea, emu_jsr_ea },
|
||||
{ "0000101111MMMRRR10000000", "jsr ea", dis_jsr_ea, emu_jsr_ea, match_MMMRRR },
|
||||
{ "000011010000aaaaaaaaaaaa", "jsr xxx", dis_jsr_imm, emu_jsr_imm },
|
||||
{ "0000101101MMMRRR1S10bbbb", "jsset #n, [X or Y]:ea, xxxx", dis_jsset_ea, emu_jsset_ea },
|
||||
{ "0000101101MMMRRR1S10bbbb", "jsset #n, [X or Y]:ea, xxxx", dis_jsset_ea, emu_jsset_ea, match_MMMRRR },
|
||||
{ "0000101100aaaaaa1S10bbbb", "jsset #n, [X or Y]:aa, xxxx", dis_jsset_aa, emu_jsset_aa },
|
||||
{ "0000101110pppppp1S1bbbbb", "jsset #n, [X or Y]:pp, xxxx", dis_jsset_pp, emu_jsset_pp },
|
||||
{ "0000000111qqqqqq1S1bbbbb", "jsset #n, [X or Y]:qq, xxxx", NULL, NULL },
|
||||
|
@ -284,17 +297,17 @@ static const OpcodeEntry nonparallel_opcodes[] = {
|
|||
{ "0000101101110RRR1WDDDDDD", "move Y:{Rn + xxxx} <-> R", NULL, NULL },
|
||||
{ "0000001aaaaaaRRR1a0WDDDD", "move X:{Rn + xxx} <-> R", dis_move_x_imm, emu_move_x_imm },
|
||||
{ "0000001aaaaaaRRR1a1WDDDD", "move Y:{Rn + xxx} <-> R", NULL, NULL },
|
||||
{ "00000101W1MMMRRR0s1ddddd", "movec [X or Y]:ea <-> R", dis_movec_ea, emu_movec_ea },
|
||||
{ "00000101W0aaaaaa0s1ddddd", "movec [X or Y]:aa <-> R", dis_movec_aa, emu_movec_aa },
|
||||
{ "00000101W1MMMRRR0s1ddddd", "movec [X or Y]:ea <-> R", dis_movec_ea, emu_movec_ea, match_MMMRRR },
|
||||
{ "00000101W0aaaaaa0s1ddddd", "movec [X or Y]:aa <-> R", dis_movec_aa, emu_movec_aa, match_MMMRRR },
|
||||
{ "00000100W1eeeeee101ddddd", "movec R1, R2", dis_movec_reg, emu_movec_reg },
|
||||
{ "00000101iiiiiiii101ddddd", "movec #xx, D1", dis_movec_imm, emu_movec_imm },
|
||||
{ "00000111W1MMMRRR10dddddd", "movem P:ea <-> R", dis_movem_ea, emu_movem_ea },
|
||||
{ "00000111W0aaaaaa00dddddd", "movem P:ea <-> R", dis_movem_aa, emu_movem_aa },
|
||||
{ "0000100sW1MMMRRR1Spppppp", "movep [X or Y]:ea <-> [X or Y]:pp", dis_movep_23, emu_movep_23 },
|
||||
{ "00000111W1MMMRRR0Sqqqqqq", "movep [X or Y]:ea <-> X:qq", dis_movep_x_qq, emu_movep_x_qq },
|
||||
{ "00000111W0MMMRRR1Sqqqqqq", "movep [X or Y]:ea <-> Y:qq", NULL, NULL },
|
||||
{ "0000100sW1MMMRRR01pppppp", "movep [X or Y]:pp <-> P:ea", dis_movep_1, emu_movep_1 },
|
||||
{ "000000001WMMMRRR0sqqqqqq", "movep [X or Y]:qq <-> P:ea", NULL, NULL },
|
||||
{ "00000111W1MMMRRR10dddddd", "movem P:ea <-> R", dis_movem_ea, emu_movem_ea, match_MMMRRR },
|
||||
{ "00000111W0aaaaaa00dddddd", "movem P:ea <-> R", dis_movem_aa, emu_movem_aa, match_MMMRRR },
|
||||
{ "0000100sW1MMMRRR1Spppppp", "movep [X or Y]:ea <-> [X or Y]:pp", dis_movep_23, emu_movep_23, match_MMMRRR },
|
||||
{ "00000111W1MMMRRR0Sqqqqqq", "movep [X or Y]:ea <-> X:qq", dis_movep_x_qq, emu_movep_x_qq, match_MMMRRR },
|
||||
{ "00000111W0MMMRRR1Sqqqqqq", "movep [X or Y]:ea <-> Y:qq", NULL, NULL, match_MMMRRR },
|
||||
{ "0000100sW1MMMRRR01pppppp", "movep [X or Y]:pp <-> P:ea", dis_movep_1, emu_movep_1, match_MMMRRR },
|
||||
{ "000000001WMMMRRR0sqqqqqq", "movep [X or Y]:qq <-> P:ea", NULL, NULL, match_MMMRRR },
|
||||
{ "0000100sW1dddddd00pppppp", "movep [X or Y]:pp <-> R", dis_movep_0, emu_movep_0 },
|
||||
{ "00000100W1dddddd1q0qqqqq", "movep X:qq <-> R", NULL, NULL },
|
||||
{ "00000100W1dddddd0q1qqqqq", "movep Y:qq <-> R", NULL, NULL },
|
||||
|
@ -312,11 +325,11 @@ static const OpcodeEntry nonparallel_opcodes[] = {
|
|||
{ "000000000000000000000011", "pflush", NULL, NULL },
|
||||
{ "000000000000000000000001", "pflushun", NULL, NULL },
|
||||
{ "000000000000000000000010", "pfree", NULL, NULL },
|
||||
{ "0000101111MMMRRR10000001", "plock ea", NULL, NULL },
|
||||
{ "0000101111MMMRRR10000001", "plock ea", NULL, NULL, match_MMMRRR },
|
||||
{ "000000000000000000001111", "plockr xxxx", NULL, NULL },
|
||||
{ "0000101011MMMRRR10000001", "punlock ea", NULL, NULL },
|
||||
{ "0000101011MMMRRR10000001", "punlock ea", NULL, NULL, match_MMMRRR },
|
||||
{ "000000000000000000001110", "punlockr xxxx", NULL, NULL },
|
||||
{ "0000011001MMMRRR0S100000", "rep [X or Y]:ea", dis_rep_ea, emu_rep_ea },
|
||||
{ "0000011001MMMRRR0S100000", "rep [X or Y]:ea", dis_rep_ea, emu_rep_ea, match_MMMRRR },
|
||||
{ "0000011000aaaaaa0S100000", "rep [X or Y]:aa", dis_rep_aa, emu_rep_aa },
|
||||
{ "00000110iiiiiiii1010hhhh", "rep #xxx", dis_rep_imm, emu_rep_imm },
|
||||
{ "0000011011dddddd00100000", "rep S", dis_rep_reg, emu_rep_reg },
|
||||
|
@ -331,7 +344,7 @@ static const OpcodeEntry nonparallel_opcodes[] = {
|
|||
{ "00000010CCCC1ttt00000TTT", "tcc S2, D2", dis_tcc, emu_tcc },
|
||||
{ "000000000000000000000110", "trap", NULL, NULL },
|
||||
{ "00000000000000000001CCCC", "trapcc", NULL, NULL },
|
||||
{ "0000101S11MMMRRR110i0000", "vsl", NULL, NULL },
|
||||
{ "0000101S11MMMRRR110i0000", "vsl", NULL, NULL, match_MMMRRR },
|
||||
{ "000000000000000010000110", "wait", NULL, emu_wait },
|
||||
};
|
||||
|
||||
|
@ -412,6 +425,11 @@ static OpcodeEntry lookup_opcode(uint32_t op) {
|
|||
int i;
|
||||
for (i=0; i<ARRAYSIZE(nonparallel_opcodes); i++) {
|
||||
if ((op & nonparallel_matches[i][0]) == nonparallel_matches[i][1]) {
|
||||
if (nonparallel_opcodes[i].match_func
|
||||
&& !nonparallel_opcodes[i].match_func(op)) continue;
|
||||
if (r.template != NULL) {
|
||||
printf("qqq %x %s\n", op, r.template);
|
||||
}
|
||||
assert(r.template == NULL);
|
||||
r = nonparallel_opcodes[i];
|
||||
}
|
||||
|
@ -949,9 +967,14 @@ uint32_t dsp56k_read_memory(dsp_core_t* dsp, int space, uint32_t address)
|
|||
if (address >= DSP_PERIPH_BASE) {
|
||||
assert(dsp->read_peripheral);
|
||||
return dsp->read_peripheral(dsp, address);
|
||||
} else if (address >= DSP_MIXBUFFER_BASE && address < DSP_MIXBUFFER_BASE+DSP_MIXBUFFER_SIZE) {
|
||||
return dsp->mixbuffer[address-DSP_MIXBUFFER_BASE];
|
||||
} else if (address >= DSP_MIXBUFFER_READ_BASE && address < DSP_MIXBUFFER_READ_BASE+DSP_MIXBUFFER_SIZE) {
|
||||
return dsp->mixbuffer[address-DSP_MIXBUFFER_READ_BASE];
|
||||
} else {
|
||||
assert(address < DSP_XRAM_SIZE);
|
||||
return dsp->xram[address];
|
||||
}
|
||||
assert(address < DSP_XRAM_SIZE);
|
||||
return dsp->xram[address];
|
||||
} else if (space == DSP_SPACE_Y) {
|
||||
assert(address < DSP_YRAM_SIZE);
|
||||
return dsp->yram[address];
|
||||
|
@ -984,9 +1007,14 @@ static void write_memory_raw(dsp_core_t* dsp, int space, uint32_t address, uint3
|
|||
assert(dsp->write_peripheral);
|
||||
dsp->write_peripheral(dsp, address, value);
|
||||
return;
|
||||
} else if (address >= DSP_MIXBUFFER_BASE && address < DSP_MIXBUFFER_BASE+DSP_MIXBUFFER_SIZE) {
|
||||
dsp->mixbuffer[address-DSP_MIXBUFFER_BASE] = value;
|
||||
} else if (address >= DSP_MIXBUFFER_READ_BASE && address < DSP_MIXBUFFER_READ_BASE+DSP_MIXBUFFER_SIZE) {
|
||||
dsp->mixbuffer[address-DSP_MIXBUFFER_READ_BASE] = value;
|
||||
} else {
|
||||
assert(address < DSP_XRAM_SIZE);
|
||||
dsp->xram[address] = value;
|
||||
}
|
||||
assert(address < DSP_XRAM_SIZE);
|
||||
dsp->xram[address] = value;
|
||||
} else if (space == DSP_SPACE_Y) {
|
||||
assert(address < DSP_YRAM_SIZE);
|
||||
dsp->yram[address] = value;
|
||||
|
@ -1027,8 +1055,10 @@ static void write_memory_disasm(dsp_core_t* dsp, int space, uint32_t address, ui
|
|||
}
|
||||
|
||||
curvalue = read_memory_disasm(dsp, space, address);
|
||||
sprintf(dsp->str_disasm_memory[dsp->disasm_memory_ptr],"Mem: %c:0x%04x 0x%06x -> 0x%06x", space_c, address, oldvalue, curvalue);
|
||||
dsp->disasm_memory_ptr ++;
|
||||
if (dsp->disasm_memory_ptr < ARRAYSIZE(dsp->str_disasm_memory)) {
|
||||
sprintf(dsp->str_disasm_memory[dsp->disasm_memory_ptr], "Mem: %c:0x%04x 0x%06x -> 0x%06x", space_c, address, oldvalue, curvalue);
|
||||
dsp->disasm_memory_ptr ++;
|
||||
}
|
||||
}
|
||||
|
||||
static void dsp_write_reg(dsp_core_t* dsp, uint32_t numreg, uint32_t value)
|
||||
|
|
|
@ -111,10 +111,14 @@
|
|||
#define DSP_SPACE_Y 0x01
|
||||
#define DSP_SPACE_P 0x02
|
||||
|
||||
#define DSP_XRAM_SIZE 4096
|
||||
#define DSP_XRAM_SIZE 3072
|
||||
#define DSP_YRAM_SIZE 2048
|
||||
#define DSP_PRAM_SIZE 4096
|
||||
|
||||
#define DSP_MIXBUFFER_BASE 3072
|
||||
#define DSP_MIXBUFFER_SIZE 1024
|
||||
#define DSP_MIXBUFFER_READ_BASE 5120
|
||||
|
||||
#define DSP_PERIPH_BASE 0xFFFF80
|
||||
#define DSP_PERIPH_SIZE 128
|
||||
|
||||
|
@ -164,6 +168,8 @@ struct dsp_core_s {
|
|||
uint32_t yram[DSP_YRAM_SIZE];
|
||||
uint32_t pram[DSP_PRAM_SIZE];
|
||||
|
||||
uint32_t mixbuffer[DSP_MIXBUFFER_SIZE];
|
||||
|
||||
/* peripheral space, x:0xffff80-0xffffff */
|
||||
uint32_t periph[DSP_PERIPH_SIZE];
|
||||
|
||||
|
|
|
@ -219,10 +219,18 @@ static void dis_undefined(dsp_core_t* dsp)
|
|||
}
|
||||
}
|
||||
|
||||
static void dis_add_imm(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xx = (dsp->disasm_cur_inst >> 8) & BITMASK(6);
|
||||
uint32_t accname = ((dsp->disasm_cur_inst >> 3) & 1) ? DSP_REG_B : DSP_REG_A;
|
||||
sprintf(dsp->disasm_str_instr, "add #$%02x,%s", xx, registers_name[accname]);
|
||||
}
|
||||
|
||||
static void dis_add_long(dsp_core_t* dsp)
|
||||
{
|
||||
dsp->disasm_cur_inst_len++;
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->disasm_cur_inst_len++;
|
||||
|
||||
uint32_t accname = ((dsp->disasm_cur_inst >> 3) & 1) ? DSP_REG_B : DSP_REG_A;
|
||||
sprintf(dsp->disasm_str_instr, "add #$%04x,%s", xxxx, registers_name[accname]);
|
||||
}
|
||||
|
@ -424,7 +432,8 @@ static void dis_bra_imm(dsp_core_t* dsp)
|
|||
{
|
||||
uint32_t xxx = (dsp->disasm_cur_inst & BITMASK(5))
|
||||
+ ((dsp->disasm_cur_inst & (BITMASK(4) << 6)) >> 1);
|
||||
sprintf(dsp->disasm_str_instr, "bra p:$%04x", xxx);
|
||||
sprintf(dsp->disasm_str_instr, "bra p:$%04x",
|
||||
(dsp->pc + dsp_signextend(9, xxx)) & BITMASK(24) );
|
||||
}
|
||||
|
||||
static void dis_brclr_pp(dsp_core_t* dsp)
|
||||
|
@ -443,7 +452,20 @@ static void dis_brclr_pp(dsp_core_t* dsp)
|
|||
sprintf(name,"x:$%06x",value+0xffffc0);
|
||||
}
|
||||
|
||||
sprintf(dsp->disasm_str_instr,"brclr #%d,%s,p:$%06x", numbit, name, xxxx);
|
||||
sprintf(dsp->disasm_str_instr,"brclr #%d,%s,p:$%06x",
|
||||
numbit, name, (dsp->pc + xxxx) & BITMASK(24) );
|
||||
}
|
||||
|
||||
static void dis_brclr_reg(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->disasm_cur_inst_len++;
|
||||
|
||||
uint32_t value = (dsp->disasm_cur_inst>>8) & BITMASK(6);
|
||||
uint32_t numbit = dsp->disasm_cur_inst & BITMASK(5);
|
||||
|
||||
sprintf(dsp->disasm_str_instr, "brclr #%d,%s,p:$%04x",
|
||||
numbit, registers_name[value], (dsp->pc + xxxx) & BITMASK(24));
|
||||
}
|
||||
|
||||
static void dis_brset_pp(dsp_core_t* dsp)
|
||||
|
@ -462,7 +484,20 @@ static void dis_brset_pp(dsp_core_t* dsp)
|
|||
sprintf(name,"x:$%06x",value+0xffffc0);
|
||||
}
|
||||
|
||||
sprintf(dsp->disasm_str_instr,"brset #%d,%s,p:$%06x", numbit, name, xxxx);
|
||||
sprintf(dsp->disasm_str_instr,"brset #%d,%s,p:$%06x",
|
||||
numbit, name, (dsp->pc + xxxx) & BITMASK(24) );
|
||||
}
|
||||
|
||||
static void dis_brset_reg(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->disasm_cur_inst_len++;
|
||||
|
||||
uint32_t value = (dsp->disasm_cur_inst>>8) & BITMASK(6);
|
||||
uint32_t numbit = dsp->disasm_cur_inst & BITMASK(5);
|
||||
|
||||
sprintf(dsp->disasm_str_instr, "brset #%d,%s,p:$%04x",
|
||||
numbit, registers_name[value], (dsp->pc + xxxx) & BITMASK(24));
|
||||
}
|
||||
|
||||
static void dis_bset_aa(dsp_core_t* dsp)
|
||||
|
@ -541,14 +576,16 @@ static void dis_bsr_long(dsp_core_t* dsp)
|
|||
{
|
||||
dsp->disasm_cur_inst_len++;
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
sprintf(dsp->disasm_str_instr, "bsr p:$%06x", xxxx);
|
||||
sprintf(dsp->disasm_str_instr, "bsr p:$%06x",
|
||||
(dsp->pc + xxxx) & BITMASK(24));
|
||||
}
|
||||
|
||||
static void dis_bsr_imm(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xxx = (dsp->disasm_cur_inst & BITMASK(5))
|
||||
+ ((dsp->disasm_cur_inst & (BITMASK(4) << 6)) >> 1);
|
||||
sprintf(dsp->disasm_str_instr, "bsr p:$%04x", xxx);
|
||||
sprintf(dsp->disasm_str_instr, "bsr p:$%04x",
|
||||
(dsp->pc + dsp_signextend(9, xxx)) & BITMASK(24) );
|
||||
}
|
||||
|
||||
static void dis_btst_aa(dsp_core_t* dsp)
|
||||
|
@ -623,6 +660,14 @@ static void dis_btst_reg(dsp_core_t* dsp)
|
|||
sprintf(dsp->disasm_str_instr,"btst #%d,%s", numbit, registers_name[value]);
|
||||
}
|
||||
|
||||
static void dis_cmp_imm(dsp_core_t* dsp) {
|
||||
uint32_t xx = (dsp->disasm_cur_inst >> 8) & BITMASK(6);
|
||||
uint32_t d = (dsp->disasm_cur_inst >> 3) & 1;
|
||||
|
||||
sprintf(dsp->disasm_str_instr, "cmp #$%02x,%s",
|
||||
xx, registers_name[d ? DSP_REG_B : DSP_REG_A]);
|
||||
}
|
||||
|
||||
static void dis_cmpu(dsp_core_t* dsp) {
|
||||
uint32_t ggg = (dsp->disasm_cur_inst >> 1) & BITMASK(3);
|
||||
uint32_t d = dsp->disasm_cur_inst & 1;
|
||||
|
@ -725,12 +770,24 @@ static void dis_do_reg(dsp_core_t* dsp)
|
|||
|
||||
static void dis_dor_imm(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t addr = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->disasm_cur_inst_len++;
|
||||
|
||||
uint32_t xxx = ((dsp->disasm_cur_inst>>8) & BITMASK(8)) | ((dsp->disasm_cur_inst & BITMASK(4))<<8);
|
||||
|
||||
sprintf(dsp->disasm_str_instr,"dor #$%04x,p:$%04x",
|
||||
((dsp->disasm_cur_inst>>8) & BITMASK(8))|((dsp->disasm_cur_inst & BITMASK(4))<<8),
|
||||
read_memory_p(dsp, dsp->pc+1)
|
||||
);
|
||||
xxx, (dsp->pc + addr) & BITMASK(24));
|
||||
}
|
||||
|
||||
static void dis_dor_reg(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t addr = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->disasm_cur_inst_len++;
|
||||
|
||||
uint32_t numreg = (dsp->disasm_cur_inst >> 8) & BITMASK(6);
|
||||
|
||||
sprintf(dsp->disasm_str_instr,"dor %s,p:$%04x",
|
||||
registers_name[numreg], (dsp->pc + addr) & BITMASK(24));
|
||||
}
|
||||
|
||||
static void dis_jcc_ea(dsp_core_t* dsp)
|
||||
|
@ -1501,7 +1558,7 @@ static void dis_movep_x_qq(dsp_core_t* dsp) {
|
|||
char srcname[16]="",dstname[16]="",name[16]="";
|
||||
|
||||
uint32_t addr = 0xffff80 + (dsp->disasm_cur_inst & BITMASK(6));
|
||||
uint32_t ea_mode = (dsp->cur_inst>>8) & BITMASK(6);
|
||||
uint32_t ea_mode = (dsp->disasm_cur_inst>>8) & BITMASK(6);
|
||||
uint32_t easpace = (dsp->disasm_cur_inst>>6) & 1;
|
||||
int retour = dis_calc_ea(dsp, ea_mode, name);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define DMA_CONTROL_FROZEN (1 << 3)
|
||||
#define DMA_CONTROL_RUNNING (1 << 4)
|
||||
#define DMA_CONTROL_STOPPED (1 << 5)
|
||||
#define DMA_CONTROL_WRITE_
|
||||
|
||||
#define NODE_POINTER_VAL 0x3fff
|
||||
#define NODE_POINTER_EOL (1 << 14)
|
||||
|
@ -37,13 +38,13 @@ static void dsp_dma_run(DSPDMAState *s)
|
|||
uint32_t addr = s->next_block & NODE_POINTER_VAL;
|
||||
assert((addr+6) < sizeof(s->core->xram));
|
||||
|
||||
uint32_t next_block = s->core->xram[addr];
|
||||
uint32_t control = s->core->xram[addr+1];
|
||||
uint32_t count = s->core->xram[addr+2];
|
||||
uint32_t dsp_offset = s->core->xram[addr+3];
|
||||
uint32_t scratch_offset = s->core->xram[addr+4];
|
||||
uint32_t scratch_base = s->core->xram[addr+5];
|
||||
uint32_t scratch_size = s->core->xram[addr+6]+1;
|
||||
uint32_t next_block = dsp56k_read_memory(s->core, DSP_SPACE_X, addr);
|
||||
uint32_t control = dsp56k_read_memory(s->core, DSP_SPACE_X, addr+1);
|
||||
uint32_t count = dsp56k_read_memory(s->core, DSP_SPACE_X, addr+2);
|
||||
uint32_t dsp_offset = dsp56k_read_memory(s->core, DSP_SPACE_X, addr+3);
|
||||
uint32_t scratch_offset = dsp56k_read_memory(s->core, DSP_SPACE_X, addr+4);
|
||||
uint32_t scratch_base = dsp56k_read_memory(s->core, DSP_SPACE_X, addr+5);
|
||||
uint32_t scratch_size = dsp56k_read_memory(s->core, DSP_SPACE_X, addr+6)+1;
|
||||
|
||||
printf("\n\n\nQQQ DMA addr %x, control %x, count %x, dsp_offset %x, scratch_offset %x, base %x, size %x\n\n\n",
|
||||
addr, control, count, dsp_offset, scratch_offset, scratch_base, scratch_size);
|
||||
|
@ -64,25 +65,31 @@ static void dsp_dma_run(DSPDMAState *s)
|
|||
|
||||
uint32_t buf_id = (control >> 5) & 0xf;
|
||||
|
||||
size_t scratch_addr = scratch_offset;
|
||||
size_t scratch_addr;
|
||||
if (buf_id == 0xe) { // 'circular'?
|
||||
assert(scratch_addr == 0);
|
||||
// assert(scratch_offset == 0);
|
||||
assert(scratch_offset + count * item_size < scratch_size);
|
||||
scratch_addr += scratch_base; //??
|
||||
} else if (buf_id != 0xf) { // 'offset'?
|
||||
scratch_addr = scratch_base + scratch_offset; //??
|
||||
} else if (buf_id == 0xf) { // 'offset'?
|
||||
scratch_addr = scratch_offset;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
uint32_t* dsp_ptr;
|
||||
uint32_t mem_address;
|
||||
int mem_space;
|
||||
if (dsp_offset < 0x1800) {
|
||||
assert(dsp_offset+count < sizeof(s->core->xram));
|
||||
dsp_ptr = s->core->xram + dsp_offset;
|
||||
assert(dsp_offset+count < 0x1800);
|
||||
mem_space = DSP_SPACE_X;
|
||||
mem_address = dsp_offset;
|
||||
} else if (dsp_offset >= 0x1800 && dsp_offset < 0x2000) { //?
|
||||
assert(dsp_offset-0x1800 + count < sizeof(s->core->yram));
|
||||
dsp_ptr = s->core->yram + dsp_offset - 0x1800;
|
||||
assert(dsp_offset+count < 0x2000);
|
||||
mem_space = DSP_SPACE_Y;
|
||||
mem_address = dsp_offset - 0x1800;
|
||||
} else if (dsp_offset >= 0x2800 && dsp_offset < 0x3800) { //?
|
||||
assert(dsp_offset-0x2800 + count < sizeof(s->core->pram));
|
||||
dsp_ptr = s->core->pram + dsp_offset - 0x2800;
|
||||
assert(dsp_offset+count < 0x3800);
|
||||
mem_space = DSP_SPACE_P;
|
||||
mem_address = dsp_offset - 0x2800;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
@ -94,9 +101,10 @@ static void dsp_dma_run(DSPDMAState *s)
|
|||
if (control & NODE_CONTROL_DIRECTION) {
|
||||
int i;
|
||||
for (i=0; i<count; i++) {
|
||||
uint32_t v = dsp56k_read_memory(s->core, mem_space, mem_address+i);
|
||||
switch(item_size) {
|
||||
case 4:
|
||||
*(uint32_t*)(scratch_buf + i*4) = dsp_ptr[i];
|
||||
*(uint32_t*)(scratch_buf + i*4) = v;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
|
@ -112,14 +120,16 @@ static void dsp_dma_run(DSPDMAState *s)
|
|||
|
||||
int i;
|
||||
for (i=0; i<count; i++) {
|
||||
uint32_t v;
|
||||
switch(item_size) {
|
||||
case 4:
|
||||
dsp_ptr[i] = (*(uint32_t*)(scratch_buf + i*4)) & item_mask;
|
||||
v = (*(uint32_t*)(scratch_buf + i*4)) & item_mask;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
dsp56k_write_memory(s->core, mem_space, mem_address+i, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5742,13 +5742,50 @@ static const emu_func_t opcodes_parmove[16] = {
|
|||
* Non-parallel moves instructions
|
||||
**********************************/
|
||||
|
||||
static void emu_add_imm(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xx = (dsp->cur_inst >> 8) & BITMASK(6);
|
||||
|
||||
uint32_t source[3], dest[3];
|
||||
|
||||
if ((dsp->cur_inst >> 3) & 1) {
|
||||
dest[0] = dsp->registers[DSP_REG_B2];
|
||||
dest[1] = dsp->registers[DSP_REG_B1];
|
||||
dest[2] = dsp->registers[DSP_REG_B0];
|
||||
} else {
|
||||
dest[0] = dsp->registers[DSP_REG_A2];
|
||||
dest[1] = dsp->registers[DSP_REG_A1];
|
||||
dest[2] = dsp->registers[DSP_REG_A0];
|
||||
}
|
||||
|
||||
source[2] = 0;
|
||||
source[1] = xx;
|
||||
source[0] = 0;
|
||||
|
||||
uint16_t newsr = dsp_add56(source, dest);
|
||||
|
||||
if ((dsp->cur_inst >> 3) & 1) {
|
||||
dsp->registers[DSP_REG_B2] = dest[0];
|
||||
dsp->registers[DSP_REG_B1] = dest[1];
|
||||
dsp->registers[DSP_REG_B0] = dest[2];
|
||||
} else {
|
||||
dsp->registers[DSP_REG_A2] = dest[0];
|
||||
dsp->registers[DSP_REG_A1] = dest[1];
|
||||
dsp->registers[DSP_REG_A0] = dest[2];
|
||||
}
|
||||
|
||||
emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]);
|
||||
|
||||
dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
|
||||
dsp->registers[DSP_REG_SR] |= newsr;
|
||||
}
|
||||
|
||||
static void emu_add_long(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->cur_inst_len++;
|
||||
|
||||
uint32_t source[3], dest[3];
|
||||
uint16_t newsr;
|
||||
|
||||
if ((dsp->cur_inst >> 3) & 1) {
|
||||
dest[0] = dsp->registers[DSP_REG_B2];
|
||||
|
@ -5764,7 +5801,7 @@ static void emu_add_long(dsp_core_t* dsp)
|
|||
source[1] = xxxx;
|
||||
source[0] = source[1] & (1<<23) ? 0xff : 0x0;
|
||||
|
||||
newsr = dsp_add56(source, dest);
|
||||
uint16_t newsr = dsp_add56(source, dest);
|
||||
|
||||
if ((dsp->cur_inst >> 3) & 1) {
|
||||
dsp->registers[DSP_REG_B2] = dest[0];
|
||||
|
@ -6071,6 +6108,29 @@ static void emu_brclr_pp(dsp_core_t* dsp) {
|
|||
}
|
||||
}
|
||||
|
||||
static void emu_brclr_reg(dsp_core_t* dsp) {
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->cur_inst_len++;
|
||||
|
||||
uint32_t numreg = (dsp->cur_inst>>8) & BITMASK(6);
|
||||
uint32_t numbit = dsp->cur_inst & BITMASK(5);
|
||||
|
||||
uint32_t value;
|
||||
if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) {
|
||||
emu_pm_read_accu24(dsp, numreg, &value);
|
||||
} else {
|
||||
value = dsp->registers[numreg];
|
||||
}
|
||||
|
||||
dsp->instr_cycle += 4;
|
||||
|
||||
if ((value & (1<<numbit)) == 0) {
|
||||
dsp->pc += xxxx;
|
||||
dsp->pc &= BITMASK(24);
|
||||
dsp->cur_inst_len=0;
|
||||
}
|
||||
}
|
||||
|
||||
static void emu_brset_pp(dsp_core_t* dsp) {
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->cur_inst_len++;
|
||||
|
@ -6083,6 +6143,29 @@ static void emu_brset_pp(dsp_core_t* dsp) {
|
|||
|
||||
dsp->instr_cycle += 4;
|
||||
|
||||
if (value & (1<<numbit)) {
|
||||
dsp->pc += xxxx;
|
||||
dsp->pc &= BITMASK(24);
|
||||
dsp->cur_inst_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void emu_brset_reg(dsp_core_t* dsp) {
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->cur_inst_len++;
|
||||
|
||||
uint32_t numreg = (dsp->cur_inst>>8) & BITMASK(6);
|
||||
uint32_t numbit = dsp->cur_inst & BITMASK(5);
|
||||
|
||||
uint32_t value;
|
||||
if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) {
|
||||
emu_pm_read_accu24(dsp, numreg, &value);
|
||||
} else {
|
||||
value = dsp->registers[numreg];
|
||||
}
|
||||
|
||||
dsp->instr_cycle += 4;
|
||||
|
||||
if (value & (1<<numbit)) {
|
||||
dsp->pc += xxxx;
|
||||
dsp->pc &= BITMASK(24);
|
||||
|
@ -6292,9 +6375,37 @@ static void emu_btst_reg(dsp_core_t* dsp)
|
|||
dsp->instr_cycle += 2;
|
||||
}
|
||||
|
||||
static void emu_cmp_imm(dsp_core_t* dsp) {
|
||||
uint32_t xx = (dsp->cur_inst >> 8) & BITMASK(6);
|
||||
uint32_t d = (dsp->cur_inst >> 3) & 1;
|
||||
|
||||
uint32_t source[3], dest[3];
|
||||
|
||||
if (d) {
|
||||
dest[2] = dsp->registers[DSP_REG_B0];
|
||||
dest[1] = dsp->registers[DSP_REG_B1];
|
||||
dest[0] = dsp->registers[DSP_REG_B2];
|
||||
} else {
|
||||
dest[2] = dsp->registers[DSP_REG_A0];
|
||||
dest[1] = dsp->registers[DSP_REG_A1];
|
||||
dest[0] = dsp->registers[DSP_REG_A2];
|
||||
}
|
||||
|
||||
source[2] = 0;
|
||||
source[1] = xx;
|
||||
source[0] = 0x0;
|
||||
|
||||
uint16_t newsr = dsp_sub56(source, dest);
|
||||
|
||||
emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]);
|
||||
|
||||
dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
|
||||
dsp->registers[DSP_REG_SR] |= newsr;
|
||||
}
|
||||
|
||||
static void emu_cmpu(dsp_core_t* dsp) {
|
||||
uint32_t ggg = (dsp->disasm_cur_inst >> 1) & BITMASK(3);
|
||||
uint32_t d = dsp->disasm_cur_inst & 1;
|
||||
uint32_t ggg = (dsp->cur_inst >> 1) & BITMASK(3);
|
||||
uint32_t d = dsp->cur_inst & 1;
|
||||
|
||||
uint32_t srcreg = DSP_REG_NULL;
|
||||
switch (ggg) {
|
||||
|
@ -6503,6 +6614,28 @@ static void emu_dor_imm(dsp_core_t* dsp)
|
|||
dsp->instr_cycle += 4;
|
||||
}
|
||||
|
||||
static void emu_dor_reg(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->cur_inst_len++;
|
||||
|
||||
dsp_stack_push(dsp, dsp->registers[DSP_REG_LA], dsp->registers[DSP_REG_LC], 0);
|
||||
dsp->registers[DSP_REG_LA] = (dsp->pc + xxxx) & BITMASK(16);
|
||||
|
||||
dsp_stack_push(dsp, dsp->pc+dsp->cur_inst_len, dsp->registers[DSP_REG_SR], 0);
|
||||
dsp->registers[DSP_REG_SR] |= (1<<DSP_SR_LF);
|
||||
|
||||
uint32_t numreg = (dsp->cur_inst>>8) & BITMASK(6);
|
||||
if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) {
|
||||
emu_pm_read_accu24(dsp, numreg, &dsp->registers[DSP_REG_LC]);
|
||||
} else {
|
||||
dsp->registers[DSP_REG_LC] = dsp->registers[numreg];
|
||||
}
|
||||
dsp->registers[DSP_REG_LC] &= BITMASK(16);
|
||||
|
||||
dsp->instr_cycle += 4;
|
||||
}
|
||||
|
||||
static void emu_enddo(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t saved_pc, saved_sr;
|
||||
|
@ -7366,11 +7499,11 @@ static void emu_move_x_long(dsp_core_t* dsp) {
|
|||
|
||||
static void emu_move_x_imm(dsp_core_t* dsp) {
|
||||
// 0000001aaaaaaRRR1a0WDDDD
|
||||
uint32_t xxx = (((dsp->disasm_cur_inst >> 11) & BITMASK(6)) << 1)
|
||||
+ ((dsp->disasm_cur_inst >> 6) & 1);
|
||||
int W = (dsp->disasm_cur_inst >> 4) & 1;
|
||||
uint32_t offreg = DSP_REG_R0 + ((dsp->disasm_cur_inst >> 8) & BITMASK(3));
|
||||
uint32_t numreg = dsp->disasm_cur_inst & BITMASK(4);
|
||||
uint32_t xxx = (((dsp->cur_inst >> 11) & BITMASK(6)) << 1)
|
||||
+ ((dsp->cur_inst >> 6) & 1);
|
||||
int W = (dsp->cur_inst >> 4) & 1;
|
||||
uint32_t offreg = DSP_REG_R0 + ((dsp->cur_inst >> 8) & BITMASK(3));
|
||||
uint32_t numreg = dsp->cur_inst & BITMASK(4);
|
||||
uint32_t x_addr = (dsp->registers[offreg] + dsp_signextend(7, xxx)) & BITMASK(24);
|
||||
|
||||
if (!W) {
|
||||
|
|
Loading…
Reference in New Issue