Mercurial > repos > blastem
annotate jagcpu_x86.c @ 2055:c4d066d798c4 segacd
Fix prog RAM banking and Genesis to SCD cycle conversion. Arkagis Escape demo now works
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 18 Jan 2022 23:54:02 -0800 |
parents | 137dbd05ceab |
children |
rev | line source |
---|---|
1115
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1 #include <stdint.h> |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
2 #include "backend.h" |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
3 #include "jagcpu.h" |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
4 #include "gen_x86.h" |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
5 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
6 void jag_check_resultwrite(jag_cpu_options *opts, uint8_t src, uint8_t dst) |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
7 { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
8 code_info *code = &opts->gen.code; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
9 cmp_ir(code, JAGCPU_NOREG, opts->resultreg, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
10 code_ptr no_result = code->cur + 1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
11 jcc(code, CC_Z, no_result + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
12 //save result to current bank |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
13 movzx_rr(code, opts->resultreg, opts->scratch1, SZ_B, SZ_D); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
14 mov_rrindex(code, opts->result, opts->bankptr, opts->scratch1, 4, SZ_D); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
15 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
16 code_ptr writeback_penatly; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
17 if (dst == src) { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
18 //unclear if src and dst read can share a port if it's the same register |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
19 //assume that is the case for now |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
20 writeback_penalty = NULL; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
21 } else { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
22 cmp_ir(code, JAGCPU_NOREG, opts->writeback, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
23 code_ptr no_writeback_penalty = code->cur + 1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
24 jcc(code, CC_Z, no_writeback_penalty + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
25 cmp_ir(code, src, opts->writeback, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
26 code_ptr no_writeback_penalty2 = code->cur + 1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
27 jcc(code, CC_Z, no_writeback_penalty2 + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 cmp_ir(code, dst, opts->writeback, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 writeback_penalty = code->cur + 1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 jcc(code, CC_NZ, writeback_penalty + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
31 *no_writeback_penalty = code->cur - (no_writeback_penalty + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
32 *no_writeback_penalty2 = code->cur - (no_writeback_penalty2 + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
33 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
34 cmp_ir(code, src, opts->resultreg, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 code_ptr no_result_penalty; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
36 if (dst == src) { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
37 no_result_penalty = code->cur+1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
38 jcc(code, CC_NZ, no_result_penalty+1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
39 } else { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
40 code_ptr result_penalty = code->cur + 1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
41 jcc(code, CC_Z, result_penalty+1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
42 cmp_ir(code, dst, opts->resultreg, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
43 no_result_penalty = code->cur+1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
44 jcc(code, CC_NZ, no_result_penalty+1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
45 *result_penalty = code->cur - (result_penalty + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 code_ptr penalty = code->cur; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
48 cycles(code, 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
49 *no_result_penalty = code->cur - (no_result_penalty + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
50 code_ptr end = code->cur + 1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 jmp(end + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 //No result to save, but there could still be a writeback, source read conflict |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 code_ptr end2 = NULL; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
54 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
55 cmp_ir(code, JAGCPU_NOREG, opts->writeback, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
56 code_ptr no_resultreg_move = code->cur + 1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 jcc(code, CC_Z, no_resultreg_move+1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 if (src != dst) { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 //unclear if src and dst read can share a port if it's the same register |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 //assume that is the case for now |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 cmp_ir(code, src, opts->writeback, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 end2 = code->cur + 1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
64 jcc(code, CC_Z, end2+1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
65 cmp_ir(code, src, opts->writeback, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 jcc(code, CC_NZ, penalty) |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 *end = code->cur - (end + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
69 if (end2) { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
70 *end2 = code->cur - (end2 + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
72 *no_result = code->cur - (no_result + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
73 mov_rr(code, opts->resultreg, opts->writeback, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
74 *no_resultreg_move = code->cur - (no_resultreg_move + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
75 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
76 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
77 void jag_check_resultwrite_noread(jag_cpu_options *opts) |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
78 { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
79 code_info *code = &opts->gen.code; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
80 cmp_ir(code, JAGCPU_NOREG, opts->resultreg, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
81 code_ptr no_result = code->cur + 1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 jcc(code, CC_Z, no_result + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
83 //save result to current bank |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
84 movzx_rr(code, opts->resultreg, opts->scratch1, SZ_B, SZ_D); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
85 mov_rrindex(code, opts->result, opts->bankptr, opts->scratch1, 4, SZ_D); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
86 *no_result = code->cur - (no_result + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
87 mov_rr(code, opts->resultreg, opts->writeback, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
89 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 void jag_check_resultwrite_singleread(jag_cpu options *opts, uint8_t reg) |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
92 code_info *code = &opts->gen.code; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 cmp_ir(code, JAGCPU_NOREG, opts->resultreg, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 code_ptr no_result = code->cur + 1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
95 jcc(code, CC_Z, no_result + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 //save result to current bank |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
97 movzx_rr(code, opts->resultreg, opts->scratch1, SZ_B, SZ_D); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
98 mov_rrindex(code, opts->result, opts->bankptr, opts->scratch1, 4, SZ_D); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 //check for a scoreboard delay |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
101 cmp_ir(code, reg, opts->resultreg, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 code_ptr no_delay = code-.cur + 1; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
103 jcc(code, CC_NZ, no_delay + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
104 ccylces(code, 1); |
1594
137dbd05ceab
Fix some issues identified by cppcheck
Michael Pavone <pavone@retrodev.com>
parents:
1115
diff
changeset
|
105 *no_delay = code->cur - (no_delay + 1); |
1115
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
106 *no_result = code->cur - (no_result + 1); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
107 mov_rr(code, opts->resultreg, opts->writeback, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
109 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
110 void translate_jag_quickimmed(jag_cpu_options *opts, uint32_t address, uint16_t opcode, uint32_t value, uint16_t dest) |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
111 { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 jag_check_resultwrite_singleread(opts, dest); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
113 switch (opcode) |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
114 { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
115 case ADDQ: |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
116 break; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
117 case ADDQT: |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
118 break; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
119 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
120 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
121 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
122 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
123 uint16_t *translate_jag_inst(uint16_t *stream, jag_cpu_options *opts, uint32_t address) |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
124 { |
1594
137dbd05ceab
Fix some issues identified by cppcheck
Michael Pavone <pavone@retrodev.com>
parents:
1115
diff
changeset
|
125 uint16_t inst = *stream; |
1115
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
126 ++stream; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
127 uint16_t opcode = jag_opcode(inst, opts->is_gpu); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
128 check_cycles_int(&opts->gen, address); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
129 code_info *code = &opts->gen.code; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
130 switch (opcode) |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
131 { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
132 case JAG_MOVEI: { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
133 uint32_t value = *stream; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
134 ++stream; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
135 value |= *stream << 16; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
136 ++stream; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
137 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
138 jag_check_resultwrite_noread(opts); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
139 mov_ir(code, value, opts->result, SZ_D); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
140 mov_ir(code, jag_reg2(inst), opts->resultreg, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
141 break; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
142 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
143 case JAG_MOVE: { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
144 uint8_t src = jag_reg1(inst), dst = jag_reg2(inst); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
145 jag_check_resultwrite_singleread(opts, src); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
146 //move has a shorter pipeline than normal instructions |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
147 if (src != dst) { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
148 mov_rdispr(code, opts->bankptr, src * 4, opts->gen.scratch1, SZ_D); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
149 mov_rrdisp(code, opts->gen.scratch1, opts->bankptr, dst * 4, SZ_D); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
150 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
151 mov_ir(code, dst, opts->writeback, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
152 mov_ir(code, JAGCPU_NOREG, opts->resultreg, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
153 break; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
154 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
155 case JAG_MOVEQ: { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
156 uint8_t dst = jag_reg2(inst); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
157 jag_check_resultwrite_noread(opts); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
158 //moveq has a shorter pipeline than normal instructions |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
159 mov_irdisp(code, jag_quick(inst), opts->bankptr, dst * 4, SZ_D); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
160 mov_ir(code, dst, opts->writeback, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
161 mov_ir(code, JAGCPU_NOREG, opts->resultreg, SZ_B); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
162 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
163 break; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
164 case JAG_JR: { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
165 jag_check_resultwrite_noread(opts); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
166 //TODO: Pipeline stalls on flag readiness |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
167 uint16_t cond = jag_reg2(inst); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
168 if (jag_is_always_false(cond)) { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
169 } else { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
170 int32_t offset = jag_quick(inst); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
171 if (offset & 0x10) { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
172 offset = -16 + (offset & 0xF); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
173 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
174 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
175 |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
176 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
177 break; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
178 default: |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
179 if (is_quick_1_32_opcode(opcode, opts->is_gpu)) { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
180 translate_jag_quickimmed(opts, address, jag_quick(inst), jag_reg2(inst)); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
181 } else if (is_quick_0_31_opcode(opcode)) { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
182 translate_jag_quickimmed(opts, address, jag_reg1(inst), jag_reg2(inst)); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
183 } else if (is_single_source(opcode, opts->is_gpu)) { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
184 translate_jag_single_source(opts, address, jag_reg2(isnt)); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
185 } else { |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
186 translate_jag_normal(opts, address, jag_reg1(inst), jag_reg2(inst)); |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
187 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
188 } |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
189 return stream; |
c1e78a101912
WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
190 } |