comparison m68k_to_x86.c @ 343:467bfa17004a

Mostly working runtime generation of memory map read/write functions
author Mike Pavone <pavone@retrodev.com>
date Sat, 18 May 2013 11:44:42 -0700
parents 4f2711899866
children b24556b45d1e
comparison
equal deleted inserted replaced
342:13f994c88c34 343:467bfa17004a
22 #define FLAG_C DH 22 #define FLAG_C DH
23 23
24 char disasm_buf[1024]; 24 char disasm_buf[1024];
25 25
26 void handle_cycle_limit_int(); 26 void handle_cycle_limit_int();
27 void m68k_read_word_scratch1(); 27 void handle_cycle_limit();
28 void m68k_read_long_scratch1();
29 void m68k_read_byte_scratch1();
30 void m68k_write_word();
31 void m68k_write_long_lowfirst();
32 void m68k_write_long_highfirst();
33 void m68k_write_byte();
34 void m68k_save_context(); 28 void m68k_save_context();
35 void m68k_load_context(); 29 void m68k_load_context();
36 void m68k_modified_ret_addr(); 30 void m68k_modified_ret_addr();
37 void m68k_native_addr(); 31 void m68k_native_addr();
38 void m68k_native_addr_and_sync(); 32 void m68k_native_addr_and_sync();
63 dst = call(dst, (uint8_t *)handle_cycle_limit_int); 57 dst = call(dst, (uint8_t *)handle_cycle_limit_int);
64 *jmp_off = dst - (jmp_off+1); 58 *jmp_off = dst - (jmp_off+1);
65 return dst; 59 return dst;
66 } 60 }
67 61
62 uint8_t * check_cycles(uint8_t * dst)
63 {
64 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
65 uint8_t * jmp_off = dst+1;
66 dst = jcc(dst, CC_NC, dst + 7);
67 dst = call(dst, (uint8_t *)handle_cycle_limit);
68 *jmp_off = dst - (jmp_off+1);
69 return dst;
70 }
71
68 int8_t native_reg(m68k_op_info * op, x86_68k_options * opts) 72 int8_t native_reg(m68k_op_info * op, x86_68k_options * opts)
69 { 73 {
70 if (op->addr_mode == MODE_REG) { 74 if (op->addr_mode == MODE_REG) {
71 return opts->dregs[op->params.regs.pri]; 75 return opts->dregs[op->params.regs.pri];
72 } 76 }
153 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 157 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D);
154 } 158 }
155 switch (inst->extra.size) 159 switch (inst->extra.size)
156 { 160 {
157 case OPSIZE_BYTE: 161 case OPSIZE_BYTE:
158 out = call(out, (char *)m68k_read_byte_scratch1); 162 out = call(out, opts->read_8);
159 break; 163 break;
160 case OPSIZE_WORD: 164 case OPSIZE_WORD:
161 out = call(out, (char *)m68k_read_word_scratch1); 165 out = call(out, opts->read_16);
162 break; 166 break;
163 case OPSIZE_LONG: 167 case OPSIZE_LONG:
164 out = call(out, (char *)m68k_read_long_scratch1); 168 out = call(out, opts->read_32);
165 break; 169 break;
166 } 170 }
167 171
168 if (inst->src.addr_mode == MODE_AREG_POSTINC) { 172 if (inst->src.addr_mode == MODE_AREG_POSTINC) {
169 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->src.params.regs.pri == 7 ? 2 : 1)); 173 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->src.params.regs.pri == 7 ? 2 : 1));
185 } 189 }
186 out = add_ir(out, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 190 out = add_ir(out, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
187 switch (inst->extra.size) 191 switch (inst->extra.size)
188 { 192 {
189 case OPSIZE_BYTE: 193 case OPSIZE_BYTE:
190 out = call(out, (char *)m68k_read_byte_scratch1); 194 out = call(out, opts->read_8);
191 break; 195 break;
192 case OPSIZE_WORD: 196 case OPSIZE_WORD:
193 out = call(out, (char *)m68k_read_word_scratch1); 197 out = call(out, opts->read_16);
194 break; 198 break;
195 case OPSIZE_LONG: 199 case OPSIZE_LONG:
196 out = call(out, (char *)m68k_read_long_scratch1); 200 out = call(out, opts->read_32);
197 break; 201 break;
198 } 202 }
199 ea->mode = MODE_REG_DIRECT; 203 ea->mode = MODE_REG_DIRECT;
200 ea->base = SCRATCH1; 204 ea->base = SCRATCH1;
201 break; 205 break;
241 out = add_ir(out, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 245 out = add_ir(out, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
242 } 246 }
243 switch (inst->extra.size) 247 switch (inst->extra.size)
244 { 248 {
245 case OPSIZE_BYTE: 249 case OPSIZE_BYTE:
246 out = call(out, (char *)m68k_read_byte_scratch1); 250 out = call(out, opts->read_8);
247 break; 251 break;
248 case OPSIZE_WORD: 252 case OPSIZE_WORD:
249 out = call(out, (char *)m68k_read_word_scratch1); 253 out = call(out, opts->read_16);
250 break; 254 break;
251 case OPSIZE_LONG: 255 case OPSIZE_LONG:
252 out = call(out, (char *)m68k_read_long_scratch1); 256 out = call(out, opts->read_32);
253 break; 257 break;
254 } 258 }
255 ea->mode = MODE_REG_DIRECT; 259 ea->mode = MODE_REG_DIRECT;
256 ea->base = SCRATCH1; 260 ea->base = SCRATCH1;
257 break; 261 break;
259 out = cycles(out, BUS); 263 out = cycles(out, BUS);
260 out = mov_ir(out, inst->src.params.regs.displacement + inst->address+2, SCRATCH1, SZ_D); 264 out = mov_ir(out, inst->src.params.regs.displacement + inst->address+2, SCRATCH1, SZ_D);
261 switch (inst->extra.size) 265 switch (inst->extra.size)
262 { 266 {
263 case OPSIZE_BYTE: 267 case OPSIZE_BYTE:
264 out = call(out, (char *)m68k_read_byte_scratch1); 268 out = call(out, opts->read_8);
265 break; 269 break;
266 case OPSIZE_WORD: 270 case OPSIZE_WORD:
267 out = call(out, (char *)m68k_read_word_scratch1); 271 out = call(out, opts->read_16);
268 break; 272 break;
269 case OPSIZE_LONG: 273 case OPSIZE_LONG:
270 out = call(out, (char *)m68k_read_long_scratch1); 274 out = call(out, opts->read_32);
271 break; 275 break;
272 } 276 }
273 ea->mode = MODE_REG_DIRECT; 277 ea->mode = MODE_REG_DIRECT;
274 ea->base = SCRATCH1; 278 ea->base = SCRATCH1;
275 break; 279 break;
311 out = add_ir(out, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 315 out = add_ir(out, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
312 } 316 }
313 switch (inst->extra.size) 317 switch (inst->extra.size)
314 { 318 {
315 case OPSIZE_BYTE: 319 case OPSIZE_BYTE:
316 out = call(out, (char *)m68k_read_byte_scratch1); 320 out = call(out, opts->read_8);
317 break; 321 break;
318 case OPSIZE_WORD: 322 case OPSIZE_WORD:
319 out = call(out, (char *)m68k_read_word_scratch1); 323 out = call(out, opts->read_16);
320 break; 324 break;
321 case OPSIZE_LONG: 325 case OPSIZE_LONG:
322 out = call(out, (char *)m68k_read_long_scratch1); 326 out = call(out, opts->read_32);
323 break; 327 break;
324 } 328 }
325 ea->mode = MODE_REG_DIRECT; 329 ea->mode = MODE_REG_DIRECT;
326 ea->base = SCRATCH1; 330 ea->base = SCRATCH1;
327 break; 331 break;
334 } 338 }
335 out = mov_ir(out, inst->src.params.immed, SCRATCH1, SZ_D); 339 out = mov_ir(out, inst->src.params.immed, SCRATCH1, SZ_D);
336 switch (inst->extra.size) 340 switch (inst->extra.size)
337 { 341 {
338 case OPSIZE_BYTE: 342 case OPSIZE_BYTE:
339 out = call(out, (char *)m68k_read_byte_scratch1); 343 out = call(out, opts->read_8);
340 break; 344 break;
341 case OPSIZE_WORD: 345 case OPSIZE_WORD:
342 out = call(out, (char *)m68k_read_word_scratch1); 346 out = call(out, opts->read_16);
343 break; 347 break;
344 case OPSIZE_LONG: 348 case OPSIZE_LONG:
345 out = call(out, (char *)m68k_read_long_scratch1); 349 out = call(out, opts->read_32);
346 break; 350 break;
347 } 351 }
348 ea->mode = MODE_REG_DIRECT; 352 ea->mode = MODE_REG_DIRECT;
349 ea->base = SCRATCH1; 353 ea->base = SCRATCH1;
350 break; 354 break;
414 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), SCRATCH1, SZ_D); 418 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), SCRATCH1, SZ_D);
415 } 419 }
416 switch (inst->extra.size) 420 switch (inst->extra.size)
417 { 421 {
418 case OPSIZE_BYTE: 422 case OPSIZE_BYTE:
419 out = call(out, (char *)m68k_read_byte_scratch1); 423 out = call(out, opts->read_8);
420 break; 424 break;
421 case OPSIZE_WORD: 425 case OPSIZE_WORD:
422 out = call(out, (char *)m68k_read_word_scratch1); 426 out = call(out, opts->read_16);
423 break; 427 break;
424 case OPSIZE_LONG: 428 case OPSIZE_LONG:
425 out = call(out, (char *)m68k_read_long_scratch1); 429 out = call(out, opts->read_32);
426 break; 430 break;
427 } 431 }
428 } 432 }
429 if (inst->src.addr_mode == MODE_AREG_PREDEC) { 433 if (inst->src.addr_mode == MODE_AREG_PREDEC) {
430 //restore src operand to SCRATCH2 434 //restore src operand to SCRATCH2
461 if (!fake_read) { 465 if (!fake_read) {
462 out = push_r(out, SCRATCH1); 466 out = push_r(out, SCRATCH1);
463 switch (inst->extra.size) 467 switch (inst->extra.size)
464 { 468 {
465 case OPSIZE_BYTE: 469 case OPSIZE_BYTE:
466 out = call(out, (char *)m68k_read_byte_scratch1); 470 out = call(out, opts->read_8);
467 break; 471 break;
468 case OPSIZE_WORD: 472 case OPSIZE_WORD:
469 out = call(out, (char *)m68k_read_word_scratch1); 473 out = call(out, opts->read_16);
470 break; 474 break;
471 case OPSIZE_LONG: 475 case OPSIZE_LONG:
472 out = call(out, (char *)m68k_read_long_scratch1); 476 out = call(out, opts->read_32);
473 break; 477 break;
474 } 478 }
475 out = pop_r(out, SCRATCH2); 479 out = pop_r(out, SCRATCH2);
476 } 480 }
477 ea->mode = MODE_REG_DIRECT; 481 ea->mode = MODE_REG_DIRECT;
523 } else { 527 } else {
524 out = push_r(out, SCRATCH1); 528 out = push_r(out, SCRATCH1);
525 switch (inst->extra.size) 529 switch (inst->extra.size)
526 { 530 {
527 case OPSIZE_BYTE: 531 case OPSIZE_BYTE:
528 out = call(out, (char *)m68k_read_byte_scratch1); 532 out = call(out, opts->read_8);
529 break; 533 break;
530 case OPSIZE_WORD: 534 case OPSIZE_WORD:
531 out = call(out, (char *)m68k_read_word_scratch1); 535 out = call(out, opts->read_16);
532 break; 536 break;
533 case OPSIZE_LONG: 537 case OPSIZE_LONG:
534 out = call(out, (char *)m68k_read_long_scratch1); 538 out = call(out, opts->read_32);
535 break; 539 break;
536 } 540 }
537 out = pop_r(out, SCRATCH2); 541 out = pop_r(out, SCRATCH2);
538 } 542 }
539 ea->mode = MODE_REG_DIRECT; 543 ea->mode = MODE_REG_DIRECT;
545 if (!fake_read) { 549 if (!fake_read) {
546 out = push_r(out, SCRATCH1); 550 out = push_r(out, SCRATCH1);
547 switch (inst->extra.size) 551 switch (inst->extra.size)
548 { 552 {
549 case OPSIZE_BYTE: 553 case OPSIZE_BYTE:
550 out = call(out, (char *)m68k_read_byte_scratch1); 554 out = call(out, opts->read_8);
551 break; 555 break;
552 case OPSIZE_WORD: 556 case OPSIZE_WORD:
553 out = call(out, (char *)m68k_read_word_scratch1); 557 out = call(out, opts->read_16);
554 break; 558 break;
555 case OPSIZE_LONG: 559 case OPSIZE_LONG:
556 out = call(out, (char *)m68k_read_long_scratch1); 560 out = call(out, opts->read_32);
557 break; 561 break;
558 } 562 }
559 out = pop_r(out, SCRATCH2); 563 out = pop_r(out, SCRATCH2);
560 } 564 }
561 ea->mode = MODE_REG_DIRECT; 565 ea->mode = MODE_REG_DIRECT;
603 } else { 607 } else {
604 out = push_r(out, SCRATCH1); 608 out = push_r(out, SCRATCH1);
605 switch (inst->extra.size) 609 switch (inst->extra.size)
606 { 610 {
607 case OPSIZE_BYTE: 611 case OPSIZE_BYTE:
608 out = call(out, (char *)m68k_read_byte_scratch1); 612 out = call(out, opts->read_8);
609 break; 613 break;
610 case OPSIZE_WORD: 614 case OPSIZE_WORD:
611 out = call(out, (char *)m68k_read_word_scratch1); 615 out = call(out, opts->read_16);
612 break; 616 break;
613 case OPSIZE_LONG: 617 case OPSIZE_LONG:
614 out = call(out, (char *)m68k_read_long_scratch1); 618 out = call(out, opts->read_32);
615 break; 619 break;
616 } 620 }
617 out = pop_r(out, SCRATCH2); 621 out = pop_r(out, SCRATCH2);
618 } 622 }
619 ea->mode = MODE_REG_DIRECT; 623 ea->mode = MODE_REG_DIRECT;
627 if (!fake_read) { 631 if (!fake_read) {
628 out = push_r(out, SCRATCH1); 632 out = push_r(out, SCRATCH1);
629 switch (inst->extra.size) 633 switch (inst->extra.size)
630 { 634 {
631 case OPSIZE_BYTE: 635 case OPSIZE_BYTE:
632 out = call(out, (char *)m68k_read_byte_scratch1); 636 out = call(out, opts->read_8);
633 break; 637 break;
634 case OPSIZE_WORD: 638 case OPSIZE_WORD:
635 out = call(out, (char *)m68k_read_word_scratch1); 639 out = call(out, opts->read_16);
636 break; 640 break;
637 case OPSIZE_LONG: 641 case OPSIZE_LONG:
638 out = call(out, (char *)m68k_read_long_scratch1); 642 out = call(out, opts->read_32);
639 break; 643 break;
640 } 644 }
641 out = pop_r(out, SCRATCH2); 645 out = pop_r(out, SCRATCH2);
642 } 646 }
643 ea->mode = MODE_REG_DIRECT; 647 ea->mode = MODE_REG_DIRECT;
662 } 666 }
663 } 667 }
664 switch (inst->extra.size) 668 switch (inst->extra.size)
665 { 669 {
666 case OPSIZE_BYTE: 670 case OPSIZE_BYTE:
667 out = call(out, (char *)m68k_write_byte); 671 out = call(out, opts->write_8);
668 break; 672 break;
669 case OPSIZE_WORD: 673 case OPSIZE_WORD:
670 out = call(out, (char *)m68k_write_word); 674 out = call(out, opts->write_16);
671 break; 675 break;
672 case OPSIZE_LONG: 676 case OPSIZE_LONG:
673 out = call(out, (char *)m68k_write_long_lowfirst); 677 out = call(out, opts->write_32_lowfirst);
674 break; 678 break;
675 } 679 }
676 } 680 }
677 return out; 681 return out;
678 } 682 }
849 dst = setcc_r(dst, CC_S, FLAG_N); 853 dst = setcc_r(dst, CC_S, FLAG_N);
850 } 854 }
851 switch (inst->extra.size) 855 switch (inst->extra.size)
852 { 856 {
853 case OPSIZE_BYTE: 857 case OPSIZE_BYTE:
854 dst = call(dst, (char *)m68k_write_byte); 858 dst = call(dst, opts->write_8);
855 break; 859 break;
856 case OPSIZE_WORD: 860 case OPSIZE_WORD:
857 dst = call(dst, (char *)m68k_write_word); 861 dst = call(dst, opts->write_16);
858 break; 862 break;
859 case OPSIZE_LONG: 863 case OPSIZE_LONG:
860 dst = call(dst, (char *)m68k_write_long_highfirst); 864 dst = call(dst, opts->write_32_highfirst);
861 break; 865 break;
862 } 866 }
863 if (inst->dst.addr_mode == MODE_AREG_POSTINC) { 867 if (inst->dst.addr_mode == MODE_AREG_POSTINC) {
864 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); 868 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1));
865 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 869 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
892 dst = setcc_r(dst, CC_S, FLAG_N); 896 dst = setcc_r(dst, CC_S, FLAG_N);
893 } 897 }
894 switch (inst->extra.size) 898 switch (inst->extra.size)
895 { 899 {
896 case OPSIZE_BYTE: 900 case OPSIZE_BYTE:
897 dst = call(dst, (char *)m68k_write_byte); 901 dst = call(dst, opts->write_8);
898 break; 902 break;
899 case OPSIZE_WORD: 903 case OPSIZE_WORD:
900 dst = call(dst, (char *)m68k_write_word); 904 dst = call(dst, opts->write_16);
901 break; 905 break;
902 case OPSIZE_LONG: 906 case OPSIZE_LONG:
903 dst = call(dst, (char *)m68k_write_long_highfirst); 907 dst = call(dst, opts->write_32_highfirst);
904 break; 908 break;
905 } 909 }
906 break; 910 break;
907 case MODE_AREG_INDEX_DISP8: 911 case MODE_AREG_INDEX_DISP8:
908 dst = cycles(dst, 6);//TODO: Check to make sure this is correct 912 dst = cycles(dst, 6);//TODO: Check to make sure this is correct
966 dst = setcc_r(dst, CC_S, FLAG_N); 970 dst = setcc_r(dst, CC_S, FLAG_N);
967 } 971 }
968 switch (inst->extra.size) 972 switch (inst->extra.size)
969 { 973 {
970 case OPSIZE_BYTE: 974 case OPSIZE_BYTE:
971 dst = call(dst, (char *)m68k_write_byte); 975 dst = call(dst, opts->write_8);
972 break; 976 break;
973 case OPSIZE_WORD: 977 case OPSIZE_WORD:
974 dst = call(dst, (char *)m68k_write_word); 978 dst = call(dst, opts->write_16);
975 break; 979 break;
976 case OPSIZE_LONG: 980 case OPSIZE_LONG:
977 dst = call(dst, (char *)m68k_write_long_highfirst); 981 dst = call(dst, opts->write_32_highfirst);
978 break; 982 break;
979 } 983 }
980 break; 984 break;
981 case MODE_PC_DISPLACE: 985 case MODE_PC_DISPLACE:
982 dst = cycles(dst, BUS); 986 dst = cycles(dst, BUS);
996 dst = setcc_r(dst, CC_S, FLAG_N); 1000 dst = setcc_r(dst, CC_S, FLAG_N);
997 } 1001 }
998 switch (inst->extra.size) 1002 switch (inst->extra.size)
999 { 1003 {
1000 case OPSIZE_BYTE: 1004 case OPSIZE_BYTE:
1001 dst = call(dst, (char *)m68k_write_byte); 1005 dst = call(dst, opts->write_8);
1002 break; 1006 break;
1003 case OPSIZE_WORD: 1007 case OPSIZE_WORD:
1004 dst = call(dst, (char *)m68k_write_word); 1008 dst = call(dst, opts->write_16);
1005 break; 1009 break;
1006 case OPSIZE_LONG: 1010 case OPSIZE_LONG:
1007 dst = call(dst, (char *)m68k_write_long_highfirst); 1011 dst = call(dst, opts->write_32_highfirst);
1008 break; 1012 break;
1009 } 1013 }
1010 break; 1014 break;
1011 case MODE_PC_INDEX_DISP8: 1015 case MODE_PC_INDEX_DISP8:
1012 dst = cycles(dst, 6);//TODO: Check to make sure this is correct 1016 dst = cycles(dst, 6);//TODO: Check to make sure this is correct
1066 dst = setcc_r(dst, CC_S, FLAG_N); 1070 dst = setcc_r(dst, CC_S, FLAG_N);
1067 } 1071 }
1068 switch (inst->extra.size) 1072 switch (inst->extra.size)
1069 { 1073 {
1070 case OPSIZE_BYTE: 1074 case OPSIZE_BYTE:
1071 dst = call(dst, (char *)m68k_write_byte); 1075 dst = call(dst, opts->write_8);
1072 break; 1076 break;
1073 case OPSIZE_WORD: 1077 case OPSIZE_WORD:
1074 dst = call(dst, (char *)m68k_write_word); 1078 dst = call(dst, opts->write_16);
1075 break; 1079 break;
1076 case OPSIZE_LONG: 1080 case OPSIZE_LONG:
1077 dst = call(dst, (char *)m68k_write_long_highfirst); 1081 dst = call(dst, opts->write_32_highfirst);
1078 break; 1082 break;
1079 } 1083 }
1080 break; 1084 break;
1081 case MODE_ABSOLUTE: 1085 case MODE_ABSOLUTE:
1082 case MODE_ABSOLUTE_SHORT: 1086 case MODE_ABSOLUTE_SHORT:
1101 dst = setcc_r(dst, CC_S, FLAG_N); 1105 dst = setcc_r(dst, CC_S, FLAG_N);
1102 } 1106 }
1103 switch (inst->extra.size) 1107 switch (inst->extra.size)
1104 { 1108 {
1105 case OPSIZE_BYTE: 1109 case OPSIZE_BYTE:
1106 dst = call(dst, (char *)m68k_write_byte); 1110 dst = call(dst, opts->write_8);
1107 break; 1111 break;
1108 case OPSIZE_WORD: 1112 case OPSIZE_WORD:
1109 dst = call(dst, (char *)m68k_write_word); 1113 dst = call(dst, opts->write_16);
1110 break; 1114 break;
1111 case OPSIZE_LONG: 1115 case OPSIZE_LONG:
1112 dst = call(dst, (char *)m68k_write_long_highfirst); 1116 dst = call(dst, opts->write_32_highfirst);
1113 break; 1117 break;
1114 } 1118 }
1115 break; 1119 break;
1116 default: 1120 default:
1117 m68k_disasm(inst, disasm_buf); 1121 m68k_disasm(inst, disasm_buf);
1273 } else { 1277 } else {
1274 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * (reg), SCRATCH1, inst->extra.size); 1278 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * (reg), SCRATCH1, inst->extra.size);
1275 } 1279 }
1276 } 1280 }
1277 if (inst->extra.size == OPSIZE_LONG) { 1281 if (inst->extra.size == OPSIZE_LONG) {
1278 dst = call(dst, (uint8_t *)m68k_write_long_lowfirst); 1282 dst = call(dst, opts->write_32_lowfirst);
1279 } else { 1283 } else {
1280 dst = call(dst, (uint8_t *)m68k_write_word); 1284 dst = call(dst, opts->write_16);
1281 } 1285 }
1282 dst = pop_r(dst, SCRATCH2); 1286 dst = pop_r(dst, SCRATCH2);
1283 if (inst->dst.addr_mode != MODE_AREG_PREDEC) { 1287 if (inst->dst.addr_mode != MODE_AREG_PREDEC) {
1284 dst = add_ir(dst, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, SCRATCH2, SZ_D); 1288 dst = add_ir(dst, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, SCRATCH2, SZ_D);
1285 } 1289 }
1413 dst = cycles(dst, early_cycles); 1417 dst = cycles(dst, early_cycles);
1414 for(reg = 0; reg < 16; reg ++) { 1418 for(reg = 0; reg < 16; reg ++) {
1415 if (inst->dst.params.immed & (1 << reg)) { 1419 if (inst->dst.params.immed & (1 << reg)) {
1416 dst = push_r(dst, SCRATCH1); 1420 dst = push_r(dst, SCRATCH1);
1417 if (inst->extra.size == OPSIZE_LONG) { 1421 if (inst->extra.size == OPSIZE_LONG) {
1418 dst = call(dst, (uint8_t *)m68k_read_long_scratch1); 1422 dst = call(dst, opts->read_32);
1419 } else { 1423 } else {
1420 dst = call(dst, (uint8_t *)m68k_read_word_scratch1); 1424 dst = call(dst, opts->read_16);
1421 } 1425 }
1422 if (inst->extra.size == OPSIZE_WORD) { 1426 if (inst->extra.size == OPSIZE_WORD) {
1423 dst = movsx_rr(dst, SCRATCH1, SCRATCH1, SZ_W, SZ_D); 1427 dst = movsx_rr(dst, SCRATCH1, SCRATCH1, SZ_W, SZ_D);
1424 } 1428 }
1425 if (reg > 7) { 1429 if (reg > 7) {
1735 printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode); 1739 printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode);
1736 exit(1); 1740 exit(1);
1737 } 1741 }
1738 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1742 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1739 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1743 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1740 dst = call(dst, (uint8_t *)m68k_write_long_lowfirst); 1744 dst = call(dst, opts->write_32_lowfirst);
1741 return dst; 1745 return dst;
1742 } 1746 }
1743 1747
1744 uint8_t * translate_m68k_bsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1748 uint8_t * translate_m68k_bsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
1745 { 1749 {
1751 if (opts->flags & OPT_NATIVE_CALL_STACK) { 1755 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1752 dst = push_r(dst, SCRATCH1); 1756 dst = push_r(dst, SCRATCH1);
1753 } 1757 }
1754 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1758 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1755 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1759 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1756 dst = call(dst, (char *)m68k_write_long_highfirst); 1760 dst = call(dst, opts->write_32_highfirst);
1757 uint8_t * dest_addr = get_native_address(opts->native_code_map, (inst->address+2) + disp); 1761 uint8_t * dest_addr = get_native_address(opts->native_code_map, (inst->address+2) + disp);
1758 if (!dest_addr) { 1762 if (!dest_addr) {
1759 opts->deferred = defer_address(opts->deferred, (inst->address+2) + disp, dst + 1); 1763 opts->deferred = defer_address(opts->deferred, (inst->address+2) + disp, dst + 1);
1760 //dummy address to be replaced later 1764 //dummy address to be replaced later
1761 dest_addr = dst + 256; 1765 dest_addr = dst + 256;
2075 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2079 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2076 dst = push_r(dst, SCRATCH1); 2080 dst = push_r(dst, SCRATCH1);
2077 } 2081 }
2078 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2082 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2079 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2083 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2080 dst = call(dst, (char *)m68k_write_long_highfirst); 2084 dst = call(dst, opts->write_32_highfirst);
2081 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 2085 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2082 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 2086 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
2083 } else { 2087 } else {
2084 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 2088 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D);
2085 } 2089 }
2098 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2102 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2099 dst = push_r(dst, SCRATCH1); 2103 dst = push_r(dst, SCRATCH1);
2100 } 2104 }
2101 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2105 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2102 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2106 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2103 dst = call(dst, (char *)m68k_write_long_highfirst); 2107 dst = call(dst, opts->write_32_highfirst);
2104 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 2108 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2105 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 2109 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
2106 } else { 2110 } else {
2107 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 2111 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D);
2108 } 2112 }
2122 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2126 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2123 dst = push_r(dst, SCRATCH1); 2127 dst = push_r(dst, SCRATCH1);
2124 } 2128 }
2125 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2129 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2126 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2130 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2127 dst = call(dst, (char *)m68k_write_long_highfirst); 2131 dst = call(dst, opts->write_32_highfirst);
2128 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 2132 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2129 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 2133 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
2130 } else { 2134 } else {
2131 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 2135 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D);
2132 } 2136 }
2180 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2184 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2181 dst = push_r(dst, SCRATCH1); 2185 dst = push_r(dst, SCRATCH1);
2182 } 2186 }
2183 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2187 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2184 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2188 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2185 dst = call(dst, (char *)m68k_write_long_highfirst); 2189 dst = call(dst, opts->write_32_highfirst);
2186 m68k_addr = inst->src.params.regs.displacement + inst->address + 2; 2190 m68k_addr = inst->src.params.regs.displacement + inst->address + 2;
2187 if ((m68k_addr & 0xFFFFFF) < 0x400000) { 2191 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2188 dest_addr = get_native_address(opts->native_code_map, m68k_addr); 2192 dest_addr = get_native_address(opts->native_code_map, m68k_addr);
2189 if (!dest_addr) { 2193 if (!dest_addr) {
2190 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); 2194 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1);
2216 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2220 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2217 dst = push_r(dst, SCRATCH1); 2221 dst = push_r(dst, SCRATCH1);
2218 } 2222 }
2219 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2223 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2220 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2224 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2221 dst = call(dst, (char *)m68k_write_long_highfirst); 2225 dst = call(dst, opts->write_32_highfirst);
2222 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); 2226 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
2223 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; 2227 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
2224 if (inst->src.params.regs.sec & 1) { 2228 if (inst->src.params.regs.sec & 1) {
2225 if (inst->src.params.regs.sec & 0x10) { 2229 if (inst->src.params.regs.sec & 0x10) {
2226 if (opts->aregs[sec_reg] >= 0) { 2230 if (opts->aregs[sec_reg] >= 0) {
2271 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2275 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2272 dst = push_r(dst, SCRATCH1); 2276 dst = push_r(dst, SCRATCH1);
2273 } 2277 }
2274 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2278 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2275 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2279 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2276 dst = call(dst, (char *)m68k_write_long_highfirst); 2280 dst = call(dst, opts->write_32_highfirst);
2277 m68k_addr = inst->src.params.immed; 2281 m68k_addr = inst->src.params.immed;
2278 if ((m68k_addr & 0xFFFFFF) < 0x400000) { 2282 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2279 dest_addr = get_native_address(opts->native_code_map, m68k_addr); 2283 dest_addr = get_native_address(opts->native_code_map, m68k_addr);
2280 if (!dest_addr) { 2284 if (!dest_addr) {
2281 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); 2285 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1);
2312 uint8_t * translate_m68k_rts(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 2316 uint8_t * translate_m68k_rts(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
2313 { 2317 {
2314 //TODO: Add cycles 2318 //TODO: Add cycles
2315 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 2319 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
2316 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 2320 dst = add_ir(dst, 4, opts->aregs[7], SZ_D);
2317 dst = call(dst, (char *)m68k_read_long_scratch1); 2321 dst = call(dst, opts->read_32);
2318 if (opts->flags & OPT_NATIVE_CALL_STACK) { 2322 if (opts->flags & OPT_NATIVE_CALL_STACK) {
2319 dst = cmp_rdisp8r(dst, RSP, 8, SCRATCH1, SZ_D); 2323 dst = cmp_rdisp8r(dst, RSP, 8, SCRATCH1, SZ_D);
2320 dst = jcc(dst, CC_NZ, dst+3); 2324 dst = jcc(dst, CC_NZ, dst+3);
2321 dst = retn(dst); 2325 dst = retn(dst);
2322 dst = jmp(dst, (char *)m68k_modified_ret_addr); 2326 dst = jmp(dst, (char *)m68k_modified_ret_addr);
2418 if (reg >= 0) { 2422 if (reg >= 0) {
2419 dst = mov_rr(dst, reg, SCRATCH1, SZ_D); 2423 dst = mov_rr(dst, reg, SCRATCH1, SZ_D);
2420 } else { 2424 } else {
2421 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 2425 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D);
2422 } 2426 }
2423 dst = call(dst, (char *)m68k_write_long_highfirst); 2427 dst = call(dst, opts->write_32_highfirst);
2424 if (reg >= 0) { 2428 if (reg >= 0) {
2425 dst = mov_rr(dst, opts->aregs[7], reg, SZ_D); 2429 dst = mov_rr(dst, opts->aregs[7], reg, SZ_D);
2426 } else { 2430 } else {
2427 dst = mov_rrdisp8(dst, opts->aregs[7], CONTEXT, reg_offset(&(inst->src)), SZ_D); 2431 dst = mov_rrdisp8(dst, opts->aregs[7], CONTEXT, reg_offset(&(inst->src)), SZ_D);
2428 } 2432 }
2449 if (inst->extra.size == OPSIZE_LONG) { 2453 if (inst->extra.size == OPSIZE_LONG) {
2450 if (reg >= 0) { 2454 if (reg >= 0) {
2451 dst = mov_rr(dst, reg, SCRATCH1, SZ_D); 2455 dst = mov_rr(dst, reg, SCRATCH1, SZ_D);
2452 dst = shr_ir(dst, 24, SCRATCH1, SZ_D); 2456 dst = shr_ir(dst, 24, SCRATCH1, SZ_D);
2453 dst = push_r(dst, SCRATCH2); 2457 dst = push_r(dst, SCRATCH2);
2454 dst = call(dst, (uint8_t *)m68k_write_byte); 2458 dst = call(dst, opts->write_8);
2455 dst = pop_r(dst, SCRATCH2); 2459 dst = pop_r(dst, SCRATCH2);
2456 dst = mov_rr(dst, reg, SCRATCH1, SZ_D); 2460 dst = mov_rr(dst, reg, SCRATCH1, SZ_D);
2457 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); 2461 dst = shr_ir(dst, 16, SCRATCH1, SZ_D);
2458 2462
2459 } else { 2463 } else {
2460 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+3, SCRATCH1, SZ_B); 2464 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+3, SCRATCH1, SZ_B);
2461 dst = push_r(dst, SCRATCH2); 2465 dst = push_r(dst, SCRATCH2);
2462 dst = call(dst, (uint8_t *)m68k_write_byte); 2466 dst = call(dst, opts->write_8);
2463 dst = pop_r(dst, SCRATCH2); 2467 dst = pop_r(dst, SCRATCH2);
2464 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+2, SCRATCH1, SZ_B); 2468 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+2, SCRATCH1, SZ_B);
2465 } 2469 }
2466 dst = add_ir(dst, 2, SCRATCH2, SZ_D); 2470 dst = add_ir(dst, 2, SCRATCH2, SZ_D);
2467 dst = push_r(dst, SCRATCH2); 2471 dst = push_r(dst, SCRATCH2);
2468 dst = call(dst, (uint8_t *)m68k_write_byte); 2472 dst = call(dst, opts->write_8);
2469 dst = pop_r(dst, SCRATCH2); 2473 dst = pop_r(dst, SCRATCH2);
2470 dst = add_ir(dst, 2, SCRATCH2, SZ_D); 2474 dst = add_ir(dst, 2, SCRATCH2, SZ_D);
2471 } 2475 }
2472 if (reg >= 0) { 2476 if (reg >= 0) {
2473 dst = mov_rr(dst, reg, SCRATCH1, SZ_W); 2477 dst = mov_rr(dst, reg, SCRATCH1, SZ_W);
2474 dst = shr_ir(dst, 8, SCRATCH1, SZ_W); 2478 dst = shr_ir(dst, 8, SCRATCH1, SZ_W);
2475 dst = push_r(dst, SCRATCH2); 2479 dst = push_r(dst, SCRATCH2);
2476 dst = call(dst, (uint8_t *)m68k_write_byte); 2480 dst = call(dst, opts->write_8);
2477 dst = pop_r(dst, SCRATCH2); 2481 dst = pop_r(dst, SCRATCH2);
2478 dst = mov_rr(dst, reg, SCRATCH1, SZ_W); 2482 dst = mov_rr(dst, reg, SCRATCH1, SZ_W);
2479 } else { 2483 } else {
2480 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+1, SCRATCH1, SZ_B); 2484 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+1, SCRATCH1, SZ_B);
2481 dst = push_r(dst, SCRATCH2); 2485 dst = push_r(dst, SCRATCH2);
2482 dst = call(dst, (uint8_t *)m68k_write_byte); 2486 dst = call(dst, opts->write_8);
2483 dst = pop_r(dst, SCRATCH2); 2487 dst = pop_r(dst, SCRATCH2);
2484 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_B); 2488 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_B);
2485 } 2489 }
2486 dst = add_ir(dst, 2, SCRATCH2, SZ_D); 2490 dst = add_ir(dst, 2, SCRATCH2, SZ_D);
2487 dst = call(dst, (uint8_t *)m68k_write_byte); 2491 dst = call(dst, opts->write_8);
2488 } else { 2492 } else {
2489 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 2493 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2490 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 2494 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
2491 } else { 2495 } else {
2492 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 2496 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D);
2496 } 2500 }
2497 reg = native_reg(&(inst->dst), opts); 2501 reg = native_reg(&(inst->dst), opts);
2498 if (inst->extra.size == OPSIZE_LONG) { 2502 if (inst->extra.size == OPSIZE_LONG) {
2499 if (reg >= 0) { 2503 if (reg >= 0) {
2500 dst = push_r(dst, SCRATCH1); 2504 dst = push_r(dst, SCRATCH1);
2501 dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); 2505 dst = call(dst, opts->read_8);
2502 dst = shl_ir(dst, 24, SCRATCH1, SZ_D); 2506 dst = shl_ir(dst, 24, SCRATCH1, SZ_D);
2503 dst = mov_rr(dst, SCRATCH1, reg, SZ_D); 2507 dst = mov_rr(dst, SCRATCH1, reg, SZ_D);
2504 dst = pop_r(dst, SCRATCH1); 2508 dst = pop_r(dst, SCRATCH1);
2505 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2509 dst = add_ir(dst, 2, SCRATCH1, SZ_D);
2506 dst = push_r(dst, SCRATCH1); 2510 dst = push_r(dst, SCRATCH1);
2507 dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); 2511 dst = call(dst, opts->read_8);
2508 dst = shl_ir(dst, 16, SCRATCH1, SZ_D); 2512 dst = shl_ir(dst, 16, SCRATCH1, SZ_D);
2509 dst = or_rr(dst, SCRATCH1, reg, SZ_D); 2513 dst = or_rr(dst, SCRATCH1, reg, SZ_D);
2510 } else { 2514 } else {
2511 dst = push_r(dst, SCRATCH1); 2515 dst = push_r(dst, SCRATCH1);
2512 dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); 2516 dst = call(dst, opts->read_8);
2513 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+3, SZ_B); 2517 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+3, SZ_B);
2514 dst = pop_r(dst, SCRATCH1); 2518 dst = pop_r(dst, SCRATCH1);
2515 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2519 dst = add_ir(dst, 2, SCRATCH1, SZ_D);
2516 dst = push_r(dst, SCRATCH1); 2520 dst = push_r(dst, SCRATCH1);
2517 dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); 2521 dst = call(dst, opts->read_8);
2518 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+2, SZ_B); 2522 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+2, SZ_B);
2519 } 2523 }
2520 dst = pop_r(dst, SCRATCH1); 2524 dst = pop_r(dst, SCRATCH1);
2521 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2525 dst = add_ir(dst, 2, SCRATCH1, SZ_D);
2522 } 2526 }
2523 dst = push_r(dst, SCRATCH1); 2527 dst = push_r(dst, SCRATCH1);
2524 dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); 2528 dst = call(dst, opts->read_8);
2525 if (reg >= 0) { 2529 if (reg >= 0) {
2526 2530
2527 dst = shl_ir(dst, 8, SCRATCH1, SZ_W); 2531 dst = shl_ir(dst, 8, SCRATCH1, SZ_W);
2528 dst = mov_rr(dst, SCRATCH1, reg, SZ_W); 2532 dst = mov_rr(dst, SCRATCH1, reg, SZ_W);
2529 dst = pop_r(dst, SCRATCH1); 2533 dst = pop_r(dst, SCRATCH1);
2530 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2534 dst = add_ir(dst, 2, SCRATCH1, SZ_D);
2531 dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); 2535 dst = call(dst, opts->read_8);
2532 dst = mov_rr(dst, SCRATCH1, reg, SZ_B); 2536 dst = mov_rr(dst, SCRATCH1, reg, SZ_B);
2533 } else { 2537 } else {
2534 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+1, SZ_B); 2538 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+1, SZ_B);
2535 dst = pop_r(dst, SCRATCH1); 2539 dst = pop_r(dst, SCRATCH1);
2536 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2540 dst = add_ir(dst, 2, SCRATCH1, SZ_D);
2537 dst = call(dst, (uint8_t *)m68k_read_byte_scratch1); 2541 dst = call(dst, opts->read_8);
2538 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst)), SZ_B); 2542 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst)), SZ_B);
2539 } 2543 }
2540 } 2544 }
2541 return dst; 2545 return dst;
2542 } 2546 }
3709 break; 3713 break;
3710 case M68K_RTE: 3714 case M68K_RTE:
3711 //TODO: Trap if not in system mode 3715 //TODO: Trap if not in system mode
3712 //Read saved SR 3716 //Read saved SR
3713 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3717 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3714 dst = call(dst, (uint8_t *)m68k_read_word_scratch1); 3718 dst = call(dst, opts->read_16);
3715 dst = add_ir(dst, 2, opts->aregs[7], SZ_D); 3719 dst = add_ir(dst, 2, opts->aregs[7], SZ_D);
3716 dst = call(dst, (uint8_t *)set_sr); 3720 dst = call(dst, (uint8_t *)set_sr);
3717 //Read saved PC 3721 //Read saved PC
3718 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3722 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3719 dst = call(dst, (uint8_t *)m68k_read_long_scratch1); 3723 dst = call(dst, opts->read_32);
3720 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 3724 dst = add_ir(dst, 4, opts->aregs[7], SZ_D);
3721 //Check if we've switched to user mode and swap stack pointers if needed 3725 //Check if we've switched to user mode and swap stack pointers if needed
3722 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B); 3726 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B);
3723 end_off = dst+1; 3727 end_off = dst+1;
3724 dst = jcc(dst, CC_C, dst+2); 3728 dst = jcc(dst, CC_C, dst+2);
3731 dst = jmp_r(dst, SCRATCH1); 3735 dst = jmp_r(dst, SCRATCH1);
3732 break; 3736 break;
3733 case M68K_RTR: 3737 case M68K_RTR:
3734 //Read saved CCR 3738 //Read saved CCR
3735 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3739 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3736 dst = call(dst, (uint8_t *)m68k_read_word_scratch1); 3740 dst = call(dst, opts->read_16);
3737 dst = add_ir(dst, 2, opts->aregs[7], SZ_D); 3741 dst = add_ir(dst, 2, opts->aregs[7], SZ_D);
3738 dst = call(dst, (uint8_t *)set_ccr); 3742 dst = call(dst, (uint8_t *)set_ccr);
3739 //Read saved PC 3743 //Read saved PC
3740 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3744 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3741 dst = call(dst, (uint8_t *)m68k_read_long_scratch1); 3745 dst = call(dst, opts->read_32);
3742 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 3746 dst = add_ir(dst, 4, opts->aregs[7], SZ_D);
3743 //Get native address and jump to it 3747 //Get native address and jump to it
3744 dst = call(dst, (uint8_t *)m68k_native_addr); 3748 dst = call(dst, (uint8_t *)m68k_native_addr);
3745 dst = jmp_r(dst, SCRATCH1); 3749 dst = jmp_r(dst, SCRATCH1);
3746 break; 3750 break;
3869 dst = mov_rr(dst, dst_op.base, opts->aregs[7], SZ_D); 3873 dst = mov_rr(dst, dst_op.base, opts->aregs[7], SZ_D);
3870 } else { 3874 } else {
3871 dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, opts->aregs[7], SZ_D); 3875 dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, opts->aregs[7], SZ_D);
3872 } 3876 }
3873 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3877 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3874 dst = call(dst, (uint8_t *)m68k_read_long_scratch1); 3878 dst = call(dst, opts->read_32);
3875 if (dst_op.mode == MODE_REG_DIRECT) { 3879 if (dst_op.mode == MODE_REG_DIRECT) {
3876 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_D); 3880 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_D);
3877 } else { 3881 } else {
3878 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_D); 3882 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_D);
3879 } 3883 }
4133 context->aregs[7] = context->mem_pointers[0][0] << 16 | context->mem_pointers[0][1]; 4137 context->aregs[7] = context->mem_pointers[0][0] << 16 | context->mem_pointers[0][1];
4134 uint32_t address = context->mem_pointers[0][2] << 16 | context->mem_pointers[0][3]; 4138 uint32_t address = context->mem_pointers[0][2] << 16 | context->mem_pointers[0][3];
4135 start_68k_context(context, address); 4139 start_68k_context(context, address);
4136 } 4140 }
4137 4141
4138 void init_x86_68k_opts(x86_68k_options * opts) 4142 void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks)
4139 { 4143 {
4140 opts->flags = 0; 4144 opts->flags = 0;
4141 for (int i = 0; i < 8; i++) 4145 for (int i = 0; i < 8; i++)
4142 opts->dregs[i] = opts->aregs[i] = -1; 4146 opts->dregs[i] = opts->aregs[i] = -1;
4143 opts->dregs[0] = R10; 4147 opts->dregs[0] = R10;
4152 size_t size = 1024 * 1024; 4156 size_t size = 1024 * 1024;
4153 opts->cur_code = alloc_code(&size); 4157 opts->cur_code = alloc_code(&size);
4154 opts->code_end = opts->cur_code + size; 4158 opts->code_end = opts->cur_code + size;
4155 opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); 4159 opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64);
4156 memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64); 4160 memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64);
4161 uint8_t * dst = opts->read_16 = opts->cur_code;
4162 dst = check_cycles(dst);
4163 dst = cycles(dst, BUS);
4164 dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D);
4165 uint8_t *lb_jcc = NULL, *ub_jcc = NULL;
4166 for (uint32_t chunk = 0; chunk < num_chunks; chunk++)
4167 {
4168 if (lb_jcc) {
4169 *lb_jcc = dst - (lb_jcc+1);
4170 lb_jcc = NULL;
4171 }
4172 if (ub_jcc) {
4173 *ub_jcc = dst - (ub_jcc+1);
4174 ub_jcc = NULL;
4175 }
4176 if (memmap[chunk].start > 0) {
4177 dst = cmp_ir(dst, memmap[chunk].start, SCRATCH1, SZ_D);
4178 lb_jcc = dst + 1;
4179 dst = jcc(dst, CC_C, dst+2);
4180 }
4181 if (memmap[chunk].end < 0x1000000) {
4182 dst = cmp_ir(dst, memmap[chunk].end, SCRATCH1, SZ_D);
4183 ub_jcc = dst + 1;
4184 dst = jcc(dst, CC_NC, dst+2);
4185 }
4186
4187 if (memmap[chunk].mask != 0xFFFFFF) {
4188 dst = and_ir(dst, memmap[chunk].mask, SCRATCH1, SZ_D);
4189 }
4190
4191 if (memmap[chunk].read_16) {
4192 dst = call(dst, (uint8_t *)m68k_save_context);
4193 dst = push_r(dst, CONTEXT);
4194 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D);
4195 dst = call(dst, (uint8_t *)memmap[chunk].read_16);
4196 dst = pop_r(dst, CONTEXT);
4197 dst = mov_rr(dst, RAX, SCRATCH1, SZ_W);
4198 dst = jmp(dst, (uint8_t *)m68k_load_context);
4199 } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_READ) {
4200 if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) {
4201 dst = mov_rdisp32r(dst, SCRATCH1, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_W);
4202 } else {
4203 dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH2, SZ_Q);
4204 dst = mov_rindexr(dst, SCRATCH2, SCRATCH1, 1, SCRATCH1, SZ_W);
4205 }
4206 dst = retn(dst);
4207 } else {
4208 //Not sure the best course of action here
4209 dst = mov_ir(dst, 0xFFFF, SCRATCH1, SZ_W);
4210 dst = retn(dst);
4211 }
4212 }
4213 if (lb_jcc) {
4214 *lb_jcc = dst - (lb_jcc+1);
4215 lb_jcc = NULL;
4216 }
4217 if (ub_jcc) {
4218 *ub_jcc = dst - (ub_jcc+1);
4219 ub_jcc = NULL;
4220 }
4221 dst = mov_ir(dst, 0xFFFF, SCRATCH1, SZ_W);
4222 dst = retn(dst);
4223
4224 opts->write_16 = dst;
4225 dst = check_cycles(dst);
4226 dst = cycles(dst, BUS);
4227 dst = and_ir(dst, 0xFFFFFF, SCRATCH2, SZ_D);
4228 for (uint32_t chunk = 0; chunk < num_chunks; chunk++)
4229 {
4230 if (lb_jcc) {
4231 *lb_jcc = dst - (lb_jcc+1);
4232 lb_jcc = NULL;
4233 }
4234 if (ub_jcc) {
4235 *ub_jcc = dst - (ub_jcc+1);
4236 ub_jcc = NULL;
4237 }
4238 if (memmap[chunk].start > 0) {
4239 dst = cmp_ir(dst, memmap[chunk].start, SCRATCH2, SZ_D);
4240 lb_jcc = dst + 1;
4241 dst = jcc(dst, CC_C, dst+2);
4242 }
4243 if (memmap[chunk].end < 0x1000000) {
4244 dst = cmp_ir(dst, memmap[chunk].end, SCRATCH2, SZ_D);
4245 ub_jcc = dst + 1;
4246 dst = jcc(dst, CC_NC, dst+2);
4247 }
4248
4249 if (memmap[chunk].mask != 0xFFFFFF) {
4250 dst = and_ir(dst, memmap[chunk].mask, SCRATCH2, SZ_D);
4251 }
4252
4253 if (memmap[chunk].write_16) {
4254 dst = call(dst, (uint8_t *)m68k_save_context);
4255 //SCRATCH2 is RDI, so no need to move it there
4256 dst = mov_rr(dst, SCRATCH1, RDX, SZ_W);
4257 dst = call(dst, (uint8_t *)memmap[chunk].write_16);
4258 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
4259 dst = jmp(dst, (uint8_t *)m68k_load_context);
4260 } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_WRITE) {
4261 if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) {
4262 dst = mov_rrdisp32(dst, SCRATCH1, SCRATCH2, (int64_t)memmap[chunk].buffer, SZ_W);
4263 } else {
4264 dst = push_r(dst, SCRATCH1);
4265 dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_Q);
4266 dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_Q);
4267 dst = pop_r(dst, SCRATCH1);
4268 dst = mov_rrind(dst, SCRATCH1, SCRATCH2, SZ_W);
4269 }
4270 if (memmap[chunk].flags & MMAP_CODE) {
4271 dst = mov_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
4272 dst = shr_ir(dst, 11, SCRATCH1, SZ_D);
4273 dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D);
4274 uint8_t * not_code = dst+1;
4275 dst = jcc(dst, CC_NC, dst+2);
4276 dst = call(dst, (uint8_t *)m68k_save_context);
4277 dst = call(dst, (uint8_t *)m68k_handle_code_write);
4278 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
4279 dst = call(dst, (uint8_t *)m68k_load_context);
4280 *not_code = dst - (not_code+1);
4281 }
4282 dst = retn(dst);
4283 } else {
4284 //Not sure the best course of action here
4285 dst = retn(dst);
4286 }
4287 }
4288 if (lb_jcc) {
4289 *lb_jcc = dst - (lb_jcc+1);
4290 lb_jcc = NULL;
4291 }
4292 if (ub_jcc) {
4293 *ub_jcc = dst - (ub_jcc+1);
4294 ub_jcc = NULL;
4295 }
4296 dst = retn(dst);
4297
4298 opts->read_8 = dst;
4299 dst = check_cycles(dst);
4300 dst = cycles(dst, BUS);
4301 dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D);
4302 for (uint32_t chunk = 0; chunk < num_chunks; chunk++)
4303 {
4304 if (lb_jcc) {
4305 *lb_jcc = dst - (lb_jcc+1);
4306 lb_jcc = NULL;
4307 }
4308 if (ub_jcc) {
4309 *ub_jcc = dst - (ub_jcc+1);
4310 ub_jcc = NULL;
4311 }
4312 if (memmap[chunk].start > 0) {
4313 dst = cmp_ir(dst, memmap[chunk].start, SCRATCH1, SZ_D);
4314 lb_jcc = dst + 1;
4315 dst = jcc(dst, CC_C, dst+2);
4316 }
4317 if (memmap[chunk].end < 0x1000000) {
4318 dst = cmp_ir(dst, memmap[chunk].end, SCRATCH1, SZ_D);
4319 ub_jcc = dst + 1;
4320 dst = jcc(dst, CC_NC, dst+2);
4321 }
4322
4323 if (memmap[chunk].mask != 0xFFFFFF) {
4324 dst = and_ir(dst, memmap[chunk].mask, SCRATCH1, SZ_D);
4325 }
4326
4327 if (memmap[chunk].read_8) {
4328 dst = call(dst, (uint8_t *)m68k_save_context);
4329 dst = push_r(dst, CONTEXT);
4330 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D);
4331 dst = call(dst, (uint8_t *)memmap[chunk].read_8);
4332 dst = pop_r(dst, CONTEXT);
4333 dst = mov_rr(dst, RAX, SCRATCH1, SZ_B);
4334 dst = jmp(dst, (uint8_t *)m68k_load_context);
4335 } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_READ) {
4336 dst = xor_ir(dst, 1, SCRATCH1, SZ_D);
4337 if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) {
4338 dst = mov_rdisp32r(dst, SCRATCH1, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_B);
4339 } else {
4340 dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH2, SZ_Q);
4341 dst = mov_rindexr(dst, SCRATCH2, SCRATCH1, 1, SCRATCH1, SZ_B);
4342 }
4343 dst = retn(dst);
4344 } else {
4345 //Not sure the best course of action here
4346 dst = mov_ir(dst, 0xFF, SCRATCH1, SZ_B);
4347 dst = retn(dst);
4348 }
4349 }
4350 if (lb_jcc) {
4351 *lb_jcc = dst - (lb_jcc+1);
4352 lb_jcc = NULL;
4353 }
4354 if (ub_jcc) {
4355 *ub_jcc = dst - (ub_jcc+1);
4356 ub_jcc = NULL;
4357 }
4358 dst = mov_ir(dst, 0xFFFF, SCRATCH1, SZ_W);
4359 dst = retn(dst);
4360
4361 opts->write_8 = dst;
4362 dst = check_cycles(dst);
4363 dst = cycles(dst, BUS);
4364 dst = and_ir(dst, 0xFFFFFF, SCRATCH2, SZ_D);
4365 for (uint32_t chunk = 0; chunk < num_chunks; chunk++)
4366 {
4367 if (lb_jcc) {
4368 *lb_jcc = dst - (lb_jcc+1);
4369 lb_jcc = NULL;
4370 }
4371 if (ub_jcc) {
4372 *ub_jcc = dst - (ub_jcc+1);
4373 ub_jcc = NULL;
4374 }
4375 if (memmap[chunk].start > 0) {
4376 dst = cmp_ir(dst, memmap[chunk].start, SCRATCH2, SZ_D);
4377 lb_jcc = dst + 1;
4378 dst = jcc(dst, CC_C, dst+2);
4379 }
4380 if (memmap[chunk].end < 0x1000000) {
4381 dst = cmp_ir(dst, memmap[chunk].end, SCRATCH2, SZ_D);
4382 ub_jcc = dst + 1;
4383 dst = jcc(dst, CC_NC, dst+2);
4384 }
4385
4386 if (memmap[chunk].mask != 0xFFFFFF) {
4387 dst = and_ir(dst, memmap[chunk].mask, SCRATCH2, SZ_D);
4388 }
4389
4390 if (memmap[chunk].write_8) {
4391 dst = call(dst, (uint8_t *)m68k_save_context);
4392 //SCRATCH2 is RDI, so no need to move it there
4393 dst = mov_rr(dst, SCRATCH1, RDX, SZ_B);
4394 dst = call(dst, (uint8_t *)memmap[chunk].write_8);
4395 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
4396 dst = jmp(dst, (uint8_t *)m68k_load_context);
4397 } else if(memmap[chunk].buffer && memmap[chunk].flags & MMAP_WRITE) {
4398 dst = xor_ir(dst, 1, SCRATCH2, SZ_D);
4399 if ((int64_t)memmap[chunk].buffer <= 0x7FFFFFFF && (int64_t)memmap[chunk].buffer >= -2147483648) {
4400 dst = mov_rrdisp32(dst, SCRATCH1, SCRATCH2, (int64_t)memmap[chunk].buffer, SZ_B);
4401 } else {
4402 dst = push_r(dst, SCRATCH1);
4403 dst = mov_ir(dst, (int64_t)memmap[chunk].buffer, SCRATCH1, SZ_Q);
4404 dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_Q);
4405 dst = pop_r(dst, SCRATCH1);
4406 dst = mov_rrind(dst, SCRATCH1, SCRATCH2, SZ_B);
4407 }
4408 if (memmap[chunk].flags & MMAP_CODE) {
4409 dst = mov_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
4410 dst = shr_ir(dst, 11, SCRATCH1, SZ_D);
4411 dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D);
4412 uint8_t * not_code = dst+1;
4413 dst = jcc(dst, CC_NC, dst+2);
4414 dst = xor_ir(dst, 1, SCRATCH2, SZ_D);
4415 dst = call(dst, (uint8_t *)m68k_save_context);
4416 dst = call(dst, (uint8_t *)m68k_handle_code_write);
4417 dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
4418 dst = call(dst, (uint8_t *)m68k_load_context);
4419 *not_code = dst - (not_code+1);
4420 }
4421 dst = retn(dst);
4422 } else {
4423 //Not sure the best course of action here
4424 dst = retn(dst);
4425 }
4426 }
4427 if (lb_jcc) {
4428 *lb_jcc = dst - (lb_jcc+1);
4429 lb_jcc = NULL;
4430 }
4431 if (ub_jcc) {
4432 *ub_jcc = dst - (ub_jcc+1);
4433 ub_jcc = NULL;
4434 }
4435 dst = retn(dst);
4436
4437 opts->read_32 = dst;
4438 dst = push_r(dst, SCRATCH1);
4439 dst = call(dst, opts->read_16);
4440 dst = mov_rr(dst, SCRATCH1, SCRATCH2, SZ_W);
4441 dst = pop_r(dst, SCRATCH1);
4442 dst = push_r(dst, SCRATCH2);
4443 dst = add_ir(dst, 2, SCRATCH1, SZ_D);
4444 dst = call(dst, opts->read_16);
4445 dst = pop_r(dst, SCRATCH2);
4446 dst = movzx_rr(dst, SCRATCH1, SCRATCH1, SZ_W, SZ_D);
4447 dst = shl_ir(dst, 16, SCRATCH2, SZ_D);
4448 dst = or_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
4449 dst = retn(dst);
4450
4451 opts->write_32_lowfirst = dst;
4452 dst = push_r(dst, SCRATCH2);
4453 dst = push_r(dst, SCRATCH1);
4454 dst = add_ir(dst, 2, SCRATCH2, SZ_D);
4455 dst = call(dst, opts->write_16);
4456 dst = pop_r(dst, SCRATCH1);
4457 dst = pop_r(dst, SCRATCH2);
4458 dst = shr_ir(dst, 16, SCRATCH1, SZ_D);
4459 dst = jmp(dst, opts->write_16);
4460
4461 opts->write_32_highfirst = dst;
4462 dst = push_r(dst, SCRATCH1);
4463 dst = push_r(dst, SCRATCH2);
4464 dst = shr_ir(dst, 16, SCRATCH1, SZ_D);
4465 dst = call(dst, opts->write_16);
4466 dst = pop_r(dst, SCRATCH2);
4467 dst = pop_r(dst, SCRATCH1);
4468 dst = add_ir(dst, 2, SCRATCH2, SZ_D);
4469 dst = jmp(dst, opts->write_16);
4470
4471 opts->cur_code = dst;
4157 } 4472 }
4158 4473
4159 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) 4474 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts)
4160 { 4475 {
4161 memset(context, 0, sizeof(m68k_context)); 4476 memset(context, 0, sizeof(m68k_context));