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;