Mercurial > repos > blastem
comparison m68k_to_x86.c @ 569:9b7fcf748be0
Rename x86_68k_options and m68k_to_x86.h to m68k_options and m68k_core.h respectively
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 02 Mar 2014 15:25:52 -0800 |
parents | 8e395210f50f |
children |
comparison
equal
deleted
inserted
replaced
568:19e517735215 | 569:9b7fcf748be0 |
---|---|
2 Copyright 2013 Michael Pavone | 2 Copyright 2013 Michael Pavone |
3 This file is part of BlastEm. | 3 This file is part of BlastEm. |
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. | 4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. |
5 */ | 5 */ |
6 #include "gen_x86.h" | 6 #include "gen_x86.h" |
7 #include "m68k_to_x86.h" | 7 #include "m68k_core.h" |
8 #include "68kinst.h" | 8 #include "68kinst.h" |
9 #include "mem.h" | 9 #include "mem.h" |
10 #include "backend.h" | 10 #include "backend.h" |
11 #include <stdio.h> | 11 #include <stdio.h> |
12 #include <stddef.h> | 12 #include <stddef.h> |
42 void m68k_invalid(); | 42 void m68k_invalid(); |
43 void bcd_add(); | 43 void bcd_add(); |
44 void bcd_sub(); | 44 void bcd_sub(); |
45 | 45 |
46 | 46 |
47 void set_flag(x86_68k_options * opts, uint8_t val, uint8_t flag) | 47 void set_flag(m68k_options * opts, uint8_t val, uint8_t flag) |
48 { | 48 { |
49 if (opts->flag_regs[flag] >= 0) { | 49 if (opts->flag_regs[flag] >= 0) { |
50 mov_ir(&opts->gen.code, val, opts->flag_regs[flag], SZ_B); | 50 mov_ir(&opts->gen.code, val, opts->flag_regs[flag], SZ_B); |
51 } else { | 51 } else { |
52 int8_t offset = offsetof(m68k_context, flags) + flag; | 52 int8_t offset = offsetof(m68k_context, flags) + flag; |
56 mov_irind(&opts->gen.code, val, opts->gen.context_reg, SZ_B); | 56 mov_irind(&opts->gen.code, val, opts->gen.context_reg, SZ_B); |
57 } | 57 } |
58 } | 58 } |
59 } | 59 } |
60 | 60 |
61 void set_flag_cond(x86_68k_options *opts, uint8_t cond, uint8_t flag) | 61 void set_flag_cond(m68k_options *opts, uint8_t cond, uint8_t flag) |
62 { | 62 { |
63 if (opts->flag_regs[flag] >= 0) { | 63 if (opts->flag_regs[flag] >= 0) { |
64 setcc_r(&opts->gen.code, cond, opts->flag_regs[flag]); | 64 setcc_r(&opts->gen.code, cond, opts->flag_regs[flag]); |
65 } else { | 65 } else { |
66 int8_t offset = offsetof(m68k_context, flags) + flag; | 66 int8_t offset = offsetof(m68k_context, flags) + flag; |
70 setcc_rind(&opts->gen.code, cond, opts->gen.context_reg); | 70 setcc_rind(&opts->gen.code, cond, opts->gen.context_reg); |
71 } | 71 } |
72 } | 72 } |
73 } | 73 } |
74 | 74 |
75 void check_flag(x86_68k_options *opts, uint8_t flag) | 75 void check_flag(m68k_options *opts, uint8_t flag) |
76 { | 76 { |
77 if (opts->flag_regs[flag] >= 0) { | 77 if (opts->flag_regs[flag] >= 0) { |
78 cmp_ir(&opts->gen.code, 0, opts->flag_regs[flag], SZ_B); | 78 cmp_ir(&opts->gen.code, 0, opts->flag_regs[flag], SZ_B); |
79 } else { | 79 } else { |
80 cmp_irdisp(&opts->gen.code, 0, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, SZ_B); | 80 cmp_irdisp(&opts->gen.code, 0, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, SZ_B); |
81 } | 81 } |
82 } | 82 } |
83 | 83 |
84 void flag_to_reg(x86_68k_options *opts, uint8_t flag, uint8_t reg) | 84 void flag_to_reg(m68k_options *opts, uint8_t flag, uint8_t reg) |
85 { | 85 { |
86 if (opts->flag_regs[flag] >= 0) { | 86 if (opts->flag_regs[flag] >= 0) { |
87 mov_rr(&opts->gen.code, opts->flag_regs[flag], reg, SZ_B); | 87 mov_rr(&opts->gen.code, opts->flag_regs[flag], reg, SZ_B); |
88 } else { | 88 } else { |
89 int8_t offset = offsetof(m68k_context, flags) + flag; | 89 int8_t offset = offsetof(m68k_context, flags) + flag; |
93 mov_rindr(&opts->gen.code, opts->gen.context_reg, reg, SZ_B); | 93 mov_rindr(&opts->gen.code, opts->gen.context_reg, reg, SZ_B); |
94 } | 94 } |
95 } | 95 } |
96 } | 96 } |
97 | 97 |
98 void reg_to_flag(x86_68k_options *opts, uint8_t reg, uint8_t flag) | 98 void reg_to_flag(m68k_options *opts, uint8_t reg, uint8_t flag) |
99 { | 99 { |
100 if (opts->flag_regs[flag] >= 0) { | 100 if (opts->flag_regs[flag] >= 0) { |
101 mov_rr(&opts->gen.code, reg, opts->flag_regs[flag], SZ_B); | 101 mov_rr(&opts->gen.code, reg, opts->flag_regs[flag], SZ_B); |
102 } else { | 102 } else { |
103 int8_t offset = offsetof(m68k_context, flags) + flag; | 103 int8_t offset = offsetof(m68k_context, flags) + flag; |
107 mov_rrind(&opts->gen.code, reg, opts->gen.context_reg, SZ_B); | 107 mov_rrind(&opts->gen.code, reg, opts->gen.context_reg, SZ_B); |
108 } | 108 } |
109 } | 109 } |
110 } | 110 } |
111 | 111 |
112 void flag_to_flag(x86_68k_options *opts, uint8_t flag1, uint8_t flag2) | 112 void flag_to_flag(m68k_options *opts, uint8_t flag1, uint8_t flag2) |
113 { | 113 { |
114 code_info *code = &opts->gen.code; | 114 code_info *code = &opts->gen.code; |
115 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) { | 115 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) { |
116 mov_rr(code, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B); | 116 mov_rr(code, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B); |
117 } else if(opts->flag_regs[flag1] >= 0) { | 117 } else if(opts->flag_regs[flag1] >= 0) { |
124 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, flags) + flag2, SZ_B); | 124 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, flags) + flag2, SZ_B); |
125 pop_r(code, opts->gen.scratch1); | 125 pop_r(code, opts->gen.scratch1); |
126 } | 126 } |
127 } | 127 } |
128 | 128 |
129 void flag_to_carry(x86_68k_options * opts, uint8_t flag) | 129 void flag_to_carry(m68k_options * opts, uint8_t flag) |
130 { | 130 { |
131 if (opts->flag_regs[flag] >= 0) { | 131 if (opts->flag_regs[flag] >= 0) { |
132 bt_ir(&opts->gen.code, 0, opts->flag_regs[flag], SZ_B); | 132 bt_ir(&opts->gen.code, 0, opts->flag_regs[flag], SZ_B); |
133 } else { | 133 } else { |
134 bt_irdisp(&opts->gen.code, 0, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, SZ_B); | 134 bt_irdisp(&opts->gen.code, 0, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, SZ_B); |
135 } | 135 } |
136 } | 136 } |
137 | 137 |
138 void or_flag_to_reg(x86_68k_options *opts, uint8_t flag, uint8_t reg) | 138 void or_flag_to_reg(m68k_options *opts, uint8_t flag, uint8_t reg) |
139 { | 139 { |
140 if (opts->flag_regs[flag] >= 0) { | 140 if (opts->flag_regs[flag] >= 0) { |
141 or_rr(&opts->gen.code, opts->flag_regs[flag], reg, SZ_B); | 141 or_rr(&opts->gen.code, opts->flag_regs[flag], reg, SZ_B); |
142 } else { | 142 } else { |
143 or_rdispr(&opts->gen.code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, reg, SZ_B); | 143 or_rdispr(&opts->gen.code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, reg, SZ_B); |
144 } | 144 } |
145 } | 145 } |
146 | 146 |
147 void xor_flag_to_reg(x86_68k_options *opts, uint8_t flag, uint8_t reg) | 147 void xor_flag_to_reg(m68k_options *opts, uint8_t flag, uint8_t reg) |
148 { | 148 { |
149 if (opts->flag_regs[flag] >= 0) { | 149 if (opts->flag_regs[flag] >= 0) { |
150 xor_rr(&opts->gen.code, opts->flag_regs[flag], reg, SZ_B); | 150 xor_rr(&opts->gen.code, opts->flag_regs[flag], reg, SZ_B); |
151 } else { | 151 } else { |
152 xor_rdispr(&opts->gen.code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, reg, SZ_B); | 152 xor_rdispr(&opts->gen.code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, reg, SZ_B); |
153 } | 153 } |
154 } | 154 } |
155 | 155 |
156 void xor_flag(x86_68k_options *opts, uint8_t val, uint8_t flag) | 156 void xor_flag(m68k_options *opts, uint8_t val, uint8_t flag) |
157 { | 157 { |
158 if (opts->flag_regs[flag] >= 0) { | 158 if (opts->flag_regs[flag] >= 0) { |
159 xor_ir(&opts->gen.code, val, opts->flag_regs[flag], SZ_B); | 159 xor_ir(&opts->gen.code, val, opts->flag_regs[flag], SZ_B); |
160 } else { | 160 } else { |
161 xor_irdisp(&opts->gen.code, val, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, SZ_B); | 161 xor_irdisp(&opts->gen.code, val, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, SZ_B); |
162 } | 162 } |
163 } | 163 } |
164 | 164 |
165 void cmp_flags(x86_68k_options *opts, uint8_t flag1, uint8_t flag2) | 165 void cmp_flags(m68k_options *opts, uint8_t flag1, uint8_t flag2) |
166 { | 166 { |
167 code_info *code = &opts->gen.code; | 167 code_info *code = &opts->gen.code; |
168 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) { | 168 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) { |
169 cmp_rr(code, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B); | 169 cmp_rr(code, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B); |
170 } else if(opts->flag_regs[flag1] >= 0 || opts->flag_regs[flag2] >= 0) { | 170 } else if(opts->flag_regs[flag1] >= 0 || opts->flag_regs[flag2] >= 0) { |
178 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag1, opts->gen.scratch1, SZ_B); | 178 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag1, opts->gen.scratch1, SZ_B); |
179 cmp_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, flags) + flag2, SZ_B); | 179 cmp_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, flags) + flag2, SZ_B); |
180 } | 180 } |
181 } | 181 } |
182 | 182 |
183 int8_t native_reg(m68k_op_info * op, x86_68k_options * opts) | 183 int8_t native_reg(m68k_op_info * op, m68k_options * opts) |
184 { | 184 { |
185 if (op->addr_mode == MODE_REG) { | 185 if (op->addr_mode == MODE_REG) { |
186 return opts->dregs[op->params.regs.pri]; | 186 return opts->dregs[op->params.regs.pri]; |
187 } | 187 } |
188 if (op->addr_mode == MODE_AREG) { | 188 if (op->addr_mode == MODE_AREG) { |
210 printf("a%d: %X\n", i, context->aregs[i]); | 210 printf("a%d: %X\n", i, context->aregs[i]); |
211 } | 211 } |
212 exit(0); | 212 exit(0); |
213 } | 213 } |
214 | 214 |
215 void m68k_read_size(x86_68k_options *opts, uint8_t size) | 215 void m68k_read_size(m68k_options *opts, uint8_t size) |
216 { | 216 { |
217 switch (size) | 217 switch (size) |
218 { | 218 { |
219 case OPSIZE_BYTE: | 219 case OPSIZE_BYTE: |
220 call(&opts->gen.code, opts->read_8); | 220 call(&opts->gen.code, opts->read_8); |
226 call(&opts->gen.code, opts->read_32); | 226 call(&opts->gen.code, opts->read_32); |
227 break; | 227 break; |
228 } | 228 } |
229 } | 229 } |
230 | 230 |
231 void m68k_write_size(x86_68k_options *opts, uint8_t size) | 231 void m68k_write_size(m68k_options *opts, uint8_t size) |
232 { | 232 { |
233 switch (size) | 233 switch (size) |
234 { | 234 { |
235 case OPSIZE_BYTE: | 235 case OPSIZE_BYTE: |
236 call(&opts->gen.code, opts->write_8); | 236 call(&opts->gen.code, opts->write_8); |
242 call(&opts->gen.code, opts->write_32_highfirst); | 242 call(&opts->gen.code, opts->write_32_highfirst); |
243 break; | 243 break; |
244 } | 244 } |
245 } | 245 } |
246 | 246 |
247 void translate_m68k_src(m68kinst * inst, x86_ea * ea, x86_68k_options * opts) | 247 void translate_m68k_src(m68kinst * inst, x86_ea * ea, m68k_options * opts) |
248 { | 248 { |
249 code_info *code = &opts->gen.code; | 249 code_info *code = &opts->gen.code; |
250 int8_t reg = native_reg(&(inst->src), opts); | 250 int8_t reg = native_reg(&(inst->src), opts); |
251 uint8_t sec_reg; | 251 uint8_t sec_reg; |
252 int32_t dec_amount,inc_amount; | 252 int32_t dec_amount,inc_amount; |
456 } | 456 } |
457 ea->base = opts->gen.scratch1; | 457 ea->base = opts->gen.scratch1; |
458 } | 458 } |
459 } | 459 } |
460 | 460 |
461 void translate_m68k_dst(m68kinst * inst, x86_ea * ea, x86_68k_options * opts, uint8_t fake_read) | 461 void translate_m68k_dst(m68kinst * inst, x86_ea * ea, m68k_options * opts, uint8_t fake_read) |
462 { | 462 { |
463 code_info *code = &opts->gen.code; | 463 code_info *code = &opts->gen.code; |
464 int8_t reg = native_reg(&(inst->dst), opts), sec_reg; | 464 int8_t reg = native_reg(&(inst->dst), opts), sec_reg; |
465 int32_t dec_amount, inc_amount; | 465 int32_t dec_amount, inc_amount; |
466 if (reg >= 0) { | 466 if (reg >= 0) { |
665 printf("%X: %s\naddress mode %d not implemented (dst)\n", inst->address, disasm_buf, inst->dst.addr_mode); | 665 printf("%X: %s\naddress mode %d not implemented (dst)\n", inst->address, disasm_buf, inst->dst.addr_mode); |
666 exit(1); | 666 exit(1); |
667 } | 667 } |
668 } | 668 } |
669 | 669 |
670 void m68k_save_result(m68kinst * inst, x86_68k_options * opts) | 670 void m68k_save_result(m68kinst * inst, m68k_options * opts) |
671 { | 671 { |
672 code_info *code = &opts->gen.code; | 672 code_info *code = &opts->gen.code; |
673 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) { | 673 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) { |
674 if (inst->dst.addr_mode == MODE_AREG_PREDEC && inst->src.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) { | 674 if (inst->dst.addr_mode == MODE_AREG_PREDEC && inst->src.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) { |
675 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { | 675 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { |
734 } | 734 } |
735 | 735 |
736 void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size) | 736 void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size) |
737 { | 737 { |
738 native_map_slot * native_code_map = context->native_code_map; | 738 native_map_slot * native_code_map = context->native_code_map; |
739 x86_68k_options * opts = context->options; | 739 m68k_options * opts = context->options; |
740 address &= 0xFFFFFF; | 740 address &= 0xFFFFFF; |
741 if (address > 0xE00000) { | 741 if (address > 0xE00000) { |
742 context->ram_code_flags[(address & 0xC000) >> 14] |= 1 << ((address & 0x3800) >> 11); | 742 context->ram_code_flags[(address & 0xC000) >> 14] |= 1 << ((address & 0x3800) >> 11); |
743 if (((address & 0x3FFF) + size) & 0xC000) { | 743 if (((address & 0x3FFF) + size) & 0xC000) { |
744 context->ram_code_flags[((address+size) & 0xC000) >> 14] |= 1 << (((address+size) & 0x3800) >> 11); | 744 context->ram_code_flags[((address+size) & 0xC000) >> 14] |= 1 << (((address+size) & 0x3800) >> 11); |
768 } | 768 } |
769 native_code_map[chunk].offsets[offset] = EXTENSION_WORD; | 769 native_code_map[chunk].offsets[offset] = EXTENSION_WORD; |
770 } | 770 } |
771 } | 771 } |
772 | 772 |
773 uint8_t get_native_inst_size(x86_68k_options * opts, uint32_t address) | 773 uint8_t get_native_inst_size(m68k_options * opts, uint32_t address) |
774 { | 774 { |
775 if (address < 0xE00000) { | 775 if (address < 0xE00000) { |
776 return 0; | 776 return 0; |
777 } | 777 } |
778 uint32_t slot = (address & 0xFFFF)/1024; | 778 uint32_t slot = (address & 0xFFFF)/1024; |
779 return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512]; | 779 return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512]; |
780 } | 780 } |
781 | 781 |
782 void translate_m68k_move(x86_68k_options * opts, m68kinst * inst) | 782 void translate_m68k_move(m68k_options * opts, m68kinst * inst) |
783 { | 783 { |
784 code_info *code = &opts->gen.code; | 784 code_info *code = &opts->gen.code; |
785 int8_t reg, flags_reg, sec_reg; | 785 int8_t reg, flags_reg, sec_reg; |
786 uint8_t dir = 0; | 786 uint8_t dir = 0; |
787 int32_t offset; | 787 int32_t offset; |
1073 | 1073 |
1074 //add cycles for prefetch | 1074 //add cycles for prefetch |
1075 cycles(&opts->gen, BUS); | 1075 cycles(&opts->gen, BUS); |
1076 } | 1076 } |
1077 | 1077 |
1078 void translate_m68k_movem(x86_68k_options * opts, m68kinst * inst) | 1078 void translate_m68k_movem(m68k_options * opts, m68kinst * inst) |
1079 { | 1079 { |
1080 code_info *code = &opts->gen.code; | 1080 code_info *code = &opts->gen.code; |
1081 int8_t bit,reg,sec_reg; | 1081 int8_t bit,reg,sec_reg; |
1082 uint8_t early_cycles; | 1082 uint8_t early_cycles; |
1083 if(inst->src.addr_mode == MODE_REG) { | 1083 if(inst->src.addr_mode == MODE_REG) { |
1401 } | 1401 } |
1402 //prefetch | 1402 //prefetch |
1403 cycles(&opts->gen, 4); | 1403 cycles(&opts->gen, 4); |
1404 } | 1404 } |
1405 | 1405 |
1406 void translate_m68k_clr(x86_68k_options * opts, m68kinst * inst) | 1406 void translate_m68k_clr(m68k_options * opts, m68kinst * inst) |
1407 { | 1407 { |
1408 code_info *code = &opts->gen.code; | 1408 code_info *code = &opts->gen.code; |
1409 set_flag(opts, 0, FLAG_N); | 1409 set_flag(opts, 0, FLAG_N); |
1410 set_flag(opts, 0, FLAG_V); | 1410 set_flag(opts, 0, FLAG_V); |
1411 set_flag(opts, 0, FLAG_C); | 1411 set_flag(opts, 0, FLAG_C); |
1424 mov_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size); | 1424 mov_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size); |
1425 } | 1425 } |
1426 m68k_save_result(inst, opts); | 1426 m68k_save_result(inst, opts); |
1427 } | 1427 } |
1428 | 1428 |
1429 void translate_m68k_ext(x86_68k_options * opts, m68kinst * inst) | 1429 void translate_m68k_ext(m68k_options * opts, m68kinst * inst) |
1430 { | 1430 { |
1431 code_info *code = &opts->gen.code; | 1431 code_info *code = &opts->gen.code; |
1432 x86_ea dst_op; | 1432 x86_ea dst_op; |
1433 uint8_t dst_size = inst->extra.size; | 1433 uint8_t dst_size = inst->extra.size; |
1434 inst->extra.size--; | 1434 inst->extra.size--; |
1447 set_flag_cond(opts, CC_Z, FLAG_Z); | 1447 set_flag_cond(opts, CC_Z, FLAG_Z); |
1448 set_flag_cond(opts, CC_S, FLAG_N); | 1448 set_flag_cond(opts, CC_S, FLAG_N); |
1449 //M68K EXT only operates on registers so no need for a call to save result here | 1449 //M68K EXT only operates on registers so no need for a call to save result here |
1450 } | 1450 } |
1451 | 1451 |
1452 void translate_m68k_lea(x86_68k_options * opts, m68kinst * inst) | 1452 void translate_m68k_lea(m68k_options * opts, m68kinst * inst) |
1453 { | 1453 { |
1454 code_info *code = &opts->gen.code; | 1454 code_info *code = &opts->gen.code; |
1455 int8_t dst_reg = native_reg(&(inst->dst), opts), sec_reg; | 1455 int8_t dst_reg = native_reg(&(inst->dst), opts), sec_reg; |
1456 switch(inst->src.addr_mode) | 1456 switch(inst->src.addr_mode) |
1457 { | 1457 { |
1607 printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode); | 1607 printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode); |
1608 exit(1); | 1608 exit(1); |
1609 } | 1609 } |
1610 } | 1610 } |
1611 | 1611 |
1612 void translate_m68k_pea(x86_68k_options * opts, m68kinst * inst) | 1612 void translate_m68k_pea(m68k_options * opts, m68kinst * inst) |
1613 { | 1613 { |
1614 code_info *code = &opts->gen.code; | 1614 code_info *code = &opts->gen.code; |
1615 uint8_t sec_reg; | 1615 uint8_t sec_reg; |
1616 switch(inst->src.addr_mode) | 1616 switch(inst->src.addr_mode) |
1617 { | 1617 { |
1691 sub_ir(code, 4, opts->aregs[7], SZ_D); | 1691 sub_ir(code, 4, opts->aregs[7], SZ_D); |
1692 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); | 1692 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); |
1693 call(code, opts->write_32_lowfirst); | 1693 call(code, opts->write_32_lowfirst); |
1694 } | 1694 } |
1695 | 1695 |
1696 void translate_m68k_bsr(x86_68k_options * opts, m68kinst * inst) | 1696 void translate_m68k_bsr(m68k_options * opts, m68kinst * inst) |
1697 { | 1697 { |
1698 code_info *code = &opts->gen.code; | 1698 code_info *code = &opts->gen.code; |
1699 int32_t disp = inst->src.params.immed; | 1699 int32_t disp = inst->src.params.immed; |
1700 uint32_t after = inst->address + (inst->variant == VAR_BYTE ? 2 : 4); | 1700 uint32_t after = inst->address + (inst->variant == VAR_BYTE ? 2 : 4); |
1701 //TODO: Add cycles in the right place relative to pushing the return address on the stack | 1701 //TODO: Add cycles in the right place relative to pushing the return address on the stack |
1711 dest_addr = code->cur + 256; | 1711 dest_addr = code->cur + 256; |
1712 } | 1712 } |
1713 jmp(code, dest_addr); | 1713 jmp(code, dest_addr); |
1714 } | 1714 } |
1715 | 1715 |
1716 uint8_t m68k_eval_cond(x86_68k_options * opts, uint8_t cc) | 1716 uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc) |
1717 { | 1717 { |
1718 uint8_t cond = CC_NZ; | 1718 uint8_t cond = CC_NZ; |
1719 switch (cc) | 1719 switch (cc) |
1720 { | 1720 { |
1721 case COND_HIGH: | 1721 case COND_HIGH: |
1758 break; | 1758 break; |
1759 } | 1759 } |
1760 return cond; | 1760 return cond; |
1761 } | 1761 } |
1762 | 1762 |
1763 void translate_m68k_bcc(x86_68k_options * opts, m68kinst * inst) | 1763 void translate_m68k_bcc(m68k_options * opts, m68kinst * inst) |
1764 { | 1764 { |
1765 code_info *code = &opts->gen.code; | 1765 code_info *code = &opts->gen.code; |
1766 cycles(&opts->gen, 10);//TODO: Adjust this for branch not taken case | 1766 cycles(&opts->gen, 10);//TODO: Adjust this for branch not taken case |
1767 int32_t disp = inst->src.params.immed; | 1767 int32_t disp = inst->src.params.immed; |
1768 uint32_t after = inst->address + 2; | 1768 uint32_t after = inst->address + 2; |
1783 } | 1783 } |
1784 jcc(code, cond, dest_addr); | 1784 jcc(code, cond, dest_addr); |
1785 } | 1785 } |
1786 } | 1786 } |
1787 | 1787 |
1788 void translate_m68k_scc(x86_68k_options * opts, m68kinst * inst) | 1788 void translate_m68k_scc(m68k_options * opts, m68kinst * inst) |
1789 { | 1789 { |
1790 code_info *code = &opts->gen.code; | 1790 code_info *code = &opts->gen.code; |
1791 uint8_t cond = inst->extra.cond; | 1791 uint8_t cond = inst->extra.cond; |
1792 x86_ea dst_op; | 1792 x86_ea dst_op; |
1793 inst->extra.size = OPSIZE_BYTE; | 1793 inst->extra.size = OPSIZE_BYTE; |
1826 *end_off = code->cur - (end_off+1); | 1826 *end_off = code->cur - (end_off+1); |
1827 } | 1827 } |
1828 m68k_save_result(inst, opts); | 1828 m68k_save_result(inst, opts); |
1829 } | 1829 } |
1830 | 1830 |
1831 void translate_m68k_jmp_jsr(x86_68k_options * opts, m68kinst * inst) | 1831 void translate_m68k_jmp_jsr(m68k_options * opts, m68kinst * inst) |
1832 { | 1832 { |
1833 uint8_t is_jsr = inst->op == M68K_JSR; | 1833 uint8_t is_jsr = inst->op == M68K_JSR; |
1834 code_info *code = &opts->gen.code; | 1834 code_info *code = &opts->gen.code; |
1835 code_ptr dest_addr; | 1835 code_ptr dest_addr; |
1836 uint8_t sec_reg; | 1836 uint8_t sec_reg; |
2023 printf("%s\naddress mode %d not yet supported (%s)\n", disasm_buf, inst->src.addr_mode, is_jsr ? "jsr" : "jmp"); | 2023 printf("%s\naddress mode %d not yet supported (%s)\n", disasm_buf, inst->src.addr_mode, is_jsr ? "jsr" : "jmp"); |
2024 exit(1); | 2024 exit(1); |
2025 } | 2025 } |
2026 } | 2026 } |
2027 | 2027 |
2028 void translate_m68k_rts(x86_68k_options * opts, m68kinst * inst) | 2028 void translate_m68k_rts(m68k_options * opts, m68kinst * inst) |
2029 { | 2029 { |
2030 code_info *code = &opts->gen.code; | 2030 code_info *code = &opts->gen.code; |
2031 //TODO: Add cycles | 2031 //TODO: Add cycles |
2032 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D); | 2032 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D); |
2033 add_ir(code, 4, opts->aregs[7], SZ_D); | 2033 add_ir(code, 4, opts->aregs[7], SZ_D); |
2034 call(code, opts->read_32); | 2034 call(code, opts->read_32); |
2035 call(code, opts->native_addr); | 2035 call(code, opts->native_addr); |
2036 jmp_r(code, opts->gen.scratch1); | 2036 jmp_r(code, opts->gen.scratch1); |
2037 } | 2037 } |
2038 | 2038 |
2039 void translate_m68k_dbcc(x86_68k_options * opts, m68kinst * inst) | 2039 void translate_m68k_dbcc(m68k_options * opts, m68kinst * inst) |
2040 { | 2040 { |
2041 code_info *code = &opts->gen.code; | 2041 code_info *code = &opts->gen.code; |
2042 //best case duration | 2042 //best case duration |
2043 cycles(&opts->gen, 10); | 2043 cycles(&opts->gen, 10); |
2044 code_ptr skip_loc = NULL; | 2044 code_ptr skip_loc = NULL; |
2075 } else { | 2075 } else { |
2076 cycles(&opts->gen, 4); | 2076 cycles(&opts->gen, 4); |
2077 } | 2077 } |
2078 } | 2078 } |
2079 | 2079 |
2080 void translate_m68k_link(x86_68k_options * opts, m68kinst * inst) | 2080 void translate_m68k_link(m68k_options * opts, m68kinst * inst) |
2081 { | 2081 { |
2082 code_info *code = &opts->gen.code; | 2082 code_info *code = &opts->gen.code; |
2083 int8_t reg = native_reg(&(inst->src), opts); | 2083 int8_t reg = native_reg(&(inst->src), opts); |
2084 //compensate for displacement word | 2084 //compensate for displacement word |
2085 cycles(&opts->gen, BUS); | 2085 cycles(&opts->gen, BUS); |
2099 add_ir(code, inst->dst.params.immed, opts->aregs[7], SZ_D); | 2099 add_ir(code, inst->dst.params.immed, opts->aregs[7], SZ_D); |
2100 //prefetch | 2100 //prefetch |
2101 cycles(&opts->gen, BUS); | 2101 cycles(&opts->gen, BUS); |
2102 } | 2102 } |
2103 | 2103 |
2104 void translate_m68k_movep(x86_68k_options * opts, m68kinst * inst) | 2104 void translate_m68k_movep(m68k_options * opts, m68kinst * inst) |
2105 { | 2105 { |
2106 code_info *code = &opts->gen.code; | 2106 code_info *code = &opts->gen.code; |
2107 int8_t reg; | 2107 int8_t reg; |
2108 cycles(&opts->gen, BUS*2); | 2108 cycles(&opts->gen, BUS*2); |
2109 if (inst->src.addr_mode == MODE_REG) { | 2109 if (inst->src.addr_mode == MODE_REG) { |
2208 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_B); | 2208 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_B); |
2209 } | 2209 } |
2210 } | 2210 } |
2211 } | 2211 } |
2212 | 2212 |
2213 void translate_m68k_cmp(x86_68k_options * opts, m68kinst * inst) | 2213 void translate_m68k_cmp(m68k_options * opts, m68kinst * inst) |
2214 { | 2214 { |
2215 code_info *code = &opts->gen.code; | 2215 code_info *code = &opts->gen.code; |
2216 uint8_t size = inst->extra.size; | 2216 uint8_t size = inst->extra.size; |
2217 x86_ea src_op, dst_op; | 2217 x86_ea src_op, dst_op; |
2218 translate_m68k_src(inst, &src_op, opts); | 2218 translate_m68k_src(inst, &src_op, opts); |
2252 typedef void (*shift_ir_t)(code_info *code, uint8_t val, uint8_t dst, uint8_t size); | 2252 typedef void (*shift_ir_t)(code_info *code, uint8_t val, uint8_t dst, uint8_t size); |
2253 typedef void (*shift_irdisp_t)(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size); | 2253 typedef void (*shift_irdisp_t)(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size); |
2254 typedef void (*shift_clr_t)(code_info *code, uint8_t dst, uint8_t size); | 2254 typedef void (*shift_clr_t)(code_info *code, uint8_t dst, uint8_t size); |
2255 typedef void (*shift_clrdisp_t)(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size); | 2255 typedef void (*shift_clrdisp_t)(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size); |
2256 | 2256 |
2257 void translate_shift(x86_68k_options * opts, m68kinst * inst, x86_ea *src_op, x86_ea * dst_op, shift_ir_t shift_ir, shift_irdisp_t shift_irdisp, shift_clr_t shift_clr, shift_clrdisp_t shift_clrdisp, shift_ir_t special, shift_irdisp_t special_disp) | 2257 void translate_shift(m68k_options * opts, m68kinst * inst, x86_ea *src_op, x86_ea * dst_op, shift_ir_t shift_ir, shift_irdisp_t shift_irdisp, shift_clr_t shift_clr, shift_clrdisp_t shift_clrdisp, shift_ir_t special, shift_irdisp_t special_disp) |
2258 { | 2258 { |
2259 code_info *code = &opts->gen.code; | 2259 code_info *code = &opts->gen.code; |
2260 code_ptr end_off = NULL; | 2260 code_ptr end_off = NULL; |
2261 code_ptr nz_off = NULL; | 2261 code_ptr nz_off = NULL; |
2262 code_ptr z_off = NULL; | 2262 code_ptr z_off = NULL; |
2420 } | 2420 } |
2421 } | 2421 } |
2422 | 2422 |
2423 #define BIT_SUPERVISOR 5 | 2423 #define BIT_SUPERVISOR 5 |
2424 | 2424 |
2425 void translate_m68k(x86_68k_options * opts, m68kinst * inst) | 2425 void translate_m68k(m68k_options * opts, m68kinst * inst) |
2426 { | 2426 { |
2427 code_ptr end_off, zero_off, norm_off; | 2427 code_ptr end_off, zero_off, norm_off; |
2428 uint8_t dst_reg; | 2428 uint8_t dst_reg; |
2429 code_info *code = &opts->gen.code; | 2429 code_info *code = &opts->gen.code; |
2430 check_cycles_int(&opts->gen, inst->address); | 2430 check_cycles_int(&opts->gen, inst->address); |
3672 || (inst->op == M68K_BCC && inst->extra.cond == COND_TRUE); | 3672 || (inst->op == M68K_BCC && inst->extra.cond == COND_TRUE); |
3673 } | 3673 } |
3674 | 3674 |
3675 void m68k_handle_deferred(m68k_context * context) | 3675 void m68k_handle_deferred(m68k_context * context) |
3676 { | 3676 { |
3677 x86_68k_options * opts = context->options; | 3677 m68k_options * opts = context->options; |
3678 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context); | 3678 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context); |
3679 if (opts->gen.deferred) { | 3679 if (opts->gen.deferred) { |
3680 translate_m68k_stream(opts->gen.deferred->address, context); | 3680 translate_m68k_stream(opts->gen.deferred->address, context); |
3681 } | 3681 } |
3682 } | 3682 } |
3683 | 3683 |
3684 void translate_m68k_stream(uint32_t address, m68k_context * context) | 3684 void translate_m68k_stream(uint32_t address, m68k_context * context) |
3685 { | 3685 { |
3686 m68kinst instbuf; | 3686 m68kinst instbuf; |
3687 x86_68k_options * opts = context->options; | 3687 m68k_options * opts = context->options; |
3688 code_info *code = &opts->gen.code; | 3688 code_info *code = &opts->gen.code; |
3689 address &= 0xFFFFFF; | 3689 address &= 0xFFFFFF; |
3690 if(get_native_address(opts->gen.native_code_map, address)) { | 3690 if(get_native_address(opts->gen.native_code_map, address)) { |
3691 return; | 3691 return; |
3692 } | 3692 } |
3764 return ret; | 3764 return ret; |
3765 } | 3765 } |
3766 | 3766 |
3767 void * m68k_retranslate_inst(uint32_t address, m68k_context * context) | 3767 void * m68k_retranslate_inst(uint32_t address, m68k_context * context) |
3768 { | 3768 { |
3769 x86_68k_options * opts = context->options; | 3769 m68k_options * opts = context->options; |
3770 code_info *code = &opts->gen.code; | 3770 code_info *code = &opts->gen.code; |
3771 uint8_t orig_size = get_native_inst_size(opts, address); | 3771 uint8_t orig_size = get_native_inst_size(opts, address); |
3772 code_ptr orig_start = get_native_address(context->native_code_map, address); | 3772 code_ptr orig_start = get_native_address(context->native_code_map, address); |
3773 uint32_t orig = address; | 3773 uint32_t orig = address; |
3774 code_info orig_code; | 3774 code_info orig_code; |
3852 | 3852 |
3853 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) | 3853 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) |
3854 { | 3854 { |
3855 uint32_t inst_start = get_instruction_start(context->native_code_map, address | 0xFF0000); | 3855 uint32_t inst_start = get_instruction_start(context->native_code_map, address | 0xFF0000); |
3856 if (inst_start) { | 3856 if (inst_start) { |
3857 x86_68k_options * options = context->options; | 3857 m68k_options * options = context->options; |
3858 code_info *code = &options->gen.code; | 3858 code_info *code = &options->gen.code; |
3859 code_ptr dst = get_native_address(context->native_code_map, inst_start); | 3859 code_ptr dst = get_native_address(context->native_code_map, inst_start); |
3860 code_info orig; | 3860 code_info orig; |
3861 orig.cur = dst; | 3861 orig.cur = dst; |
3862 orig.last = dst + 128; | 3862 orig.last = dst + 128; |
3885 } | 3885 } |
3886 | 3886 |
3887 void insert_breakpoint(m68k_context * context, uint32_t address, code_ptr bp_handler) | 3887 void insert_breakpoint(m68k_context * context, uint32_t address, code_ptr bp_handler) |
3888 { | 3888 { |
3889 static code_ptr bp_stub = NULL; | 3889 static code_ptr bp_stub = NULL; |
3890 x86_68k_options * opts = context->options; | 3890 m68k_options * opts = context->options; |
3891 code_info native; | 3891 code_info native; |
3892 native.cur = get_native_address_trans(context, address); | 3892 native.cur = get_native_address_trans(context, address); |
3893 native.last = native.cur + 128; | 3893 native.last = native.cur + 128; |
3894 code_ptr start_native = native.cur; | 3894 code_ptr start_native = native.cur; |
3895 mov_ir(&native, address, opts->gen.scratch1, SZ_D); | 3895 mov_ir(&native, address, opts->gen.scratch1, SZ_D); |
3944 } | 3944 } |
3945 | 3945 |
3946 void start_68k_context(m68k_context * context, uint32_t address) | 3946 void start_68k_context(m68k_context * context, uint32_t address) |
3947 { | 3947 { |
3948 code_ptr addr = get_native_address_trans(context, address); | 3948 code_ptr addr = get_native_address_trans(context, address); |
3949 x86_68k_options * options = context->options; | 3949 m68k_options * options = context->options; |
3950 options->start_context(addr, context); | 3950 options->start_context(addr, context); |
3951 } | 3951 } |
3952 | 3952 |
3953 void m68k_reset(m68k_context * context) | 3953 void m68k_reset(m68k_context * context) |
3954 { | 3954 { |
4195 } | 4195 } |
4196 retn(code); | 4196 retn(code); |
4197 return start; | 4197 return start; |
4198 } | 4198 } |
4199 | 4199 |
4200 void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks) | 4200 void init_x86_68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks) |
4201 { | 4201 { |
4202 memset(opts, 0, sizeof(*opts)); | 4202 memset(opts, 0, sizeof(*opts)); |
4203 for (int i = 0; i < 8; i++) | 4203 for (int i = 0; i < 8; i++) |
4204 { | 4204 { |
4205 opts->dregs[i] = opts->aregs[i] = -1; | 4205 opts->dregs[i] = opts->aregs[i] = -1; |