Mercurial > repos > blastem
annotate jagcpu_x86.c @ 1637:95880d947257
Fix for VRAM byte write order broke VDP FIFO testing ROM results. This change cleans up VRAM writes and fixes the regression while preserving the correct VRAM byte write order
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 11 Nov 2018 22:39:29 -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 } |