Mercurial > repos > blastem
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)); |