Mercurial > repos > blastem
comparison z80_to_x86.c @ 1049:ef7ee9919a73
Partial support for undocumented flag bits
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 28 Jul 2016 22:59:09 -0700 |
parents | 05ecef6c73b6 |
children | d06c947a9a77 |
comparison
equal
deleted
inserted
replaced
1048:05ecef6c73b6 | 1049:ef7ee9919a73 |
---|---|
423 cycles(&opts->gen, num_cycles + 1); | 423 cycles(&opts->gen, num_cycles + 1); |
424 sub_ir(code, 2, opts->regs[Z80_SP], SZ_W); | 424 sub_ir(code, 2, opts->regs[Z80_SP], SZ_W); |
425 if (inst->reg == Z80_AF) { | 425 if (inst->reg == Z80_AF) { |
426 zreg_to_native(opts, Z80_A, opts->gen.scratch1); | 426 zreg_to_native(opts, Z80_A, opts->gen.scratch1); |
427 shl_ir(code, 8, opts->gen.scratch1, SZ_W); | 427 shl_ir(code, 8, opts->gen.scratch1, SZ_W); |
428 mov_rdispr(code, opts->gen.context_reg, zf_off(ZF_S), opts->gen.scratch1, SZ_B); | 428 mov_rdispr(code, opts->gen.context_reg, zf_off(ZF_XY), opts->gen.scratch1, SZ_B); |
429 shl_ir(code, 1, opts->gen.scratch1, SZ_B); | 429 and_ir(code, 0x28, opts->gen.scratch1, SZ_B); |
430 or_rdispr(code, opts->gen.context_reg, zf_off(ZF_C), opts->gen.scratch1, SZ_B); | |
431 ror_ir(code, 1, opts->gen.scratch1, SZ_B); | |
432 or_rdispr(code, opts->gen.context_reg, zf_off(ZF_N), opts->gen.scratch1, SZ_B); | |
433 ror_ir(code, 1, opts->gen.scratch1, SZ_B); | |
434 or_rdispr(code, opts->gen.context_reg, zf_off(ZF_PV), opts->gen.scratch1, SZ_B); | |
435 ror_ir(code, 2, opts->gen.scratch1, SZ_B); | |
436 or_rdispr(code, opts->gen.context_reg, zf_off(ZF_H), opts->gen.scratch1, SZ_B); | |
437 ror_ir(code, 2, opts->gen.scratch1, SZ_B); | |
430 or_rdispr(code, opts->gen.context_reg, zf_off(ZF_Z), opts->gen.scratch1, SZ_B); | 438 or_rdispr(code, opts->gen.context_reg, zf_off(ZF_Z), opts->gen.scratch1, SZ_B); |
431 shl_ir(code, 2, opts->gen.scratch1, SZ_B); | 439 ror_ir(code, 1, opts->gen.scratch1, SZ_B); |
432 or_rdispr(code, opts->gen.context_reg, zf_off(ZF_H), opts->gen.scratch1, SZ_B); | 440 or_rdispr(code, opts->gen.context_reg, zf_off(ZF_S), opts->gen.scratch1, SZ_B); |
433 shl_ir(code, 2, opts->gen.scratch1, SZ_B); | 441 ror_ir(code, 1, opts->gen.scratch1, SZ_B); |
434 or_rdispr(code, opts->gen.context_reg, zf_off(ZF_PV), opts->gen.scratch1, SZ_B); | |
435 shl_ir(code, 1, opts->gen.scratch1, SZ_B); | |
436 or_rdispr(code, opts->gen.context_reg, zf_off(ZF_N), opts->gen.scratch1, SZ_B); | |
437 shl_ir(code, 1, opts->gen.scratch1, SZ_B); | |
438 or_rdispr(code, opts->gen.context_reg, zf_off(ZF_C), opts->gen.scratch1, SZ_B); | |
439 } else { | 442 } else { |
440 zreg_to_native(opts, inst->reg, opts->gen.scratch1); | 443 zreg_to_native(opts, inst->reg, opts->gen.scratch1); |
441 } | 444 } |
442 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch2, SZ_W); | 445 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch2, SZ_W); |
443 call(code, opts->write_16_highfirst); | 446 call(code, opts->write_16_highfirst); |
461 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); | 464 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); |
462 bt_ir(code, 6, opts->gen.scratch1, SZ_W); | 465 bt_ir(code, 6, opts->gen.scratch1, SZ_W); |
463 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_Z)); | 466 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_Z)); |
464 bt_ir(code, 7, opts->gen.scratch1, SZ_W); | 467 bt_ir(code, 7, opts->gen.scratch1, SZ_W); |
465 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_S)); | 468 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_S)); |
469 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
466 shr_ir(code, 8, opts->gen.scratch1, SZ_W); | 470 shr_ir(code, 8, opts->gen.scratch1, SZ_W); |
467 native_to_zreg(opts, opts->gen.scratch1, Z80_A); | 471 native_to_zreg(opts, opts->gen.scratch1, Z80_A); |
468 } else { | 472 } else { |
469 native_to_zreg(opts, opts->gen.scratch1, inst->reg); | 473 native_to_zreg(opts, opts->gen.scratch1, inst->reg); |
470 } | 474 } |
827 } else if (src_op.mode == MODE_IMMED) { | 831 } else if (src_op.mode == MODE_IMMED) { |
828 add_ir(code, src_op.disp, dst_op.base, z80_size(inst)); | 832 add_ir(code, src_op.disp, dst_op.base, z80_size(inst)); |
829 } else { | 833 } else { |
830 add_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); | 834 add_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); |
831 } | 835 } |
836 if (z80_size(inst) == SZ_B) { | |
837 mov_rrdisp(code, dst_op.base, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
838 } | |
832 } else { | 839 } else { |
833 if (src_op.mode == MODE_REG_DIRECT) { | 840 if (src_op.mode == MODE_REG_DIRECT) { |
834 add_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, z80_size(inst)); | 841 add_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, z80_size(inst)); |
835 } else if (src_op.mode == MODE_IMMED) { | 842 } else if (src_op.mode == MODE_IMMED) { |
836 add_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, z80_size(inst)); | 843 add_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, z80_size(inst)); |
837 } else { | 844 } else { |
838 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, z80_size(inst)); | 845 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, z80_size(inst)); |
839 add_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, z80_size(inst)); | 846 add_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, z80_size(inst)); |
840 } | 847 } |
848 mov_rdispr(code, dst_op.base, dst_op.disp + z80_size(inst) == SZ_B ? 0 : 8, opts->gen.scratch1, SZ_B); | |
849 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
841 } | 850 } |
842 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); | 851 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); |
843 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | 852 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); |
844 if (z80_size(inst) == SZ_B) { | 853 if (z80_size(inst) == SZ_B) { |
845 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); | 854 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); |
851 } else { | 860 } else { |
852 xor_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, z80_size(inst)); | 861 xor_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, z80_size(inst)); |
853 } | 862 } |
854 bt_ir(code, z80_size(inst) == SZ_B ? 4 : 12, opts->gen.scratch2, z80_size(inst)); | 863 bt_ir(code, z80_size(inst) == SZ_B ? 4 : 12, opts->gen.scratch2, z80_size(inst)); |
855 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); | 864 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); |
865 if (z80_size(inst) == SZ_W & dst_op.mode == MODE_REG_DIRECT) { | |
866 mov_rr(code, dst_op.base, opts->gen.scratch2, SZ_W); | |
867 shr_ir(code, 8, opts->gen.scratch2, SZ_W); | |
868 mov_rrdisp(code, opts->gen.scratch2, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
869 } | |
856 z80_save_reg(inst, opts); | 870 z80_save_reg(inst, opts); |
857 z80_save_ea(code, inst, opts); | 871 z80_save_ea(code, inst, opts); |
858 break; | 872 break; |
859 case Z80_ADC: | 873 case Z80_ADC: |
860 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 874 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |
886 } else if (src_op.mode == MODE_IMMED) { | 900 } else if (src_op.mode == MODE_IMMED) { |
887 adc_ir(code, src_op.disp, dst_op.base, z80_size(inst)); | 901 adc_ir(code, src_op.disp, dst_op.base, z80_size(inst)); |
888 } else { | 902 } else { |
889 adc_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); | 903 adc_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); |
890 } | 904 } |
905 if (z80_size(inst) == SZ_B) { | |
906 mov_rrdisp(code, dst_op.base, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
907 } | |
891 } else { | 908 } else { |
892 if (src_op.mode == MODE_REG_DIRECT) { | 909 if (src_op.mode == MODE_REG_DIRECT) { |
893 adc_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, z80_size(inst)); | 910 adc_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, z80_size(inst)); |
894 } else if (src_op.mode == MODE_IMMED) { | 911 } else if (src_op.mode == MODE_IMMED) { |
895 adc_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, z80_size(inst)); | 912 adc_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, z80_size(inst)); |
896 } else { | 913 } else { |
897 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, z80_size(inst)); | 914 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, z80_size(inst)); |
898 adc_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, z80_size(inst)); | 915 adc_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, z80_size(inst)); |
899 } | 916 } |
917 mov_rdispr(code, dst_op.base, dst_op.disp + z80_size(inst) == SZ_B ? 0 : 8, opts->gen.scratch1, SZ_B); | |
918 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
900 } | 919 } |
901 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); | 920 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); |
902 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | 921 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); |
903 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); | 922 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); |
904 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | 923 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); |
908 } else { | 927 } else { |
909 xor_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, z80_size(inst)); | 928 xor_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, z80_size(inst)); |
910 } | 929 } |
911 bt_ir(code, z80_size(inst) == SZ_B ? 4 : 12, opts->gen.scratch2, z80_size(inst)); | 930 bt_ir(code, z80_size(inst) == SZ_B ? 4 : 12, opts->gen.scratch2, z80_size(inst)); |
912 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); | 931 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); |
932 if (z80_size(inst) == SZ_W & dst_op.mode == MODE_REG_DIRECT) { | |
933 mov_rr(code, dst_op.base, opts->gen.scratch2, SZ_W); | |
934 shr_ir(code, 8, opts->gen.scratch2, SZ_W); | |
935 mov_rrdisp(code, opts->gen.scratch2, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
936 } | |
913 z80_save_reg(inst, opts); | 937 z80_save_reg(inst, opts); |
914 z80_save_ea(code, inst, opts); | 938 z80_save_ea(code, inst, opts); |
915 break; | 939 break; |
916 case Z80_SUB: | 940 case Z80_SUB: |
917 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 941 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |
940 } else if (src_op.mode == MODE_IMMED) { | 964 } else if (src_op.mode == MODE_IMMED) { |
941 sub_ir(code, src_op.disp, dst_op.base, z80_size(inst)); | 965 sub_ir(code, src_op.disp, dst_op.base, z80_size(inst)); |
942 } else { | 966 } else { |
943 sub_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); | 967 sub_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); |
944 } | 968 } |
969 if (z80_size(inst) == SZ_B) { | |
970 mov_rrdisp(code, dst_op.base, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
971 } | |
945 } else { | 972 } else { |
946 if (src_op.mode == MODE_REG_DIRECT) { | 973 if (src_op.mode == MODE_REG_DIRECT) { |
947 sub_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, z80_size(inst)); | 974 sub_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, z80_size(inst)); |
948 } else if (src_op.mode == MODE_IMMED) { | 975 } else if (src_op.mode == MODE_IMMED) { |
949 sub_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, z80_size(inst)); | 976 sub_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, z80_size(inst)); |
950 } else { | 977 } else { |
951 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, z80_size(inst)); | 978 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, z80_size(inst)); |
952 sub_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, z80_size(inst)); | 979 sub_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, z80_size(inst)); |
953 } | 980 } |
981 mov_rdispr(code, dst_op.base, dst_op.disp + z80_size(inst) == SZ_B ? 0 : 8, opts->gen.scratch1, SZ_B); | |
982 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
954 } | 983 } |
955 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); | 984 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); |
956 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | 985 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); |
957 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); | 986 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); |
958 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | 987 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); |
962 } else { | 991 } else { |
963 xor_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, z80_size(inst)); | 992 xor_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, z80_size(inst)); |
964 } | 993 } |
965 bt_ir(code, z80_size(inst) == SZ_B ? 4 : 12, opts->gen.scratch2, z80_size(inst)); | 994 bt_ir(code, z80_size(inst) == SZ_B ? 4 : 12, opts->gen.scratch2, z80_size(inst)); |
966 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); | 995 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); |
996 if (z80_size(inst) == SZ_W & dst_op.mode == MODE_REG_DIRECT) { | |
997 mov_rr(code, dst_op.base, opts->gen.scratch2, SZ_W); | |
998 shr_ir(code, 8, opts->gen.scratch2, SZ_W); | |
999 mov_rrdisp(code, opts->gen.scratch2, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1000 } | |
967 z80_save_reg(inst, opts); | 1001 z80_save_reg(inst, opts); |
968 z80_save_ea(code, inst, opts); | 1002 z80_save_ea(code, inst, opts); |
969 break; | 1003 break; |
970 case Z80_SBC: | 1004 case Z80_SBC: |
971 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 1005 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |
997 } else if (src_op.mode == MODE_IMMED) { | 1031 } else if (src_op.mode == MODE_IMMED) { |
998 sbb_ir(code, src_op.disp, dst_op.base, z80_size(inst)); | 1032 sbb_ir(code, src_op.disp, dst_op.base, z80_size(inst)); |
999 } else { | 1033 } else { |
1000 sbb_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); | 1034 sbb_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); |
1001 } | 1035 } |
1036 if (z80_size(inst) == SZ_B) { | |
1037 mov_rrdisp(code, dst_op.base, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1038 } | |
1002 } else { | 1039 } else { |
1003 if (src_op.mode == MODE_REG_DIRECT) { | 1040 if (src_op.mode == MODE_REG_DIRECT) { |
1004 sbb_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, z80_size(inst)); | 1041 sbb_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, z80_size(inst)); |
1005 } else if (src_op.mode == MODE_IMMED) { | 1042 } else if (src_op.mode == MODE_IMMED) { |
1006 sbb_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, z80_size(inst)); | 1043 sbb_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, z80_size(inst)); |
1007 } else { | 1044 } else { |
1008 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, z80_size(inst)); | 1045 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, z80_size(inst)); |
1009 sbb_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, z80_size(inst)); | 1046 sbb_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, z80_size(inst)); |
1010 } | 1047 } |
1048 mov_rdispr(code, dst_op.base, dst_op.disp + z80_size(inst) == SZ_B ? 0 : 8, opts->gen.scratch1, SZ_B); | |
1049 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1011 } | 1050 } |
1012 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); | 1051 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); |
1013 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | 1052 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); |
1014 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); | 1053 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); |
1015 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | 1054 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); |
1019 } else { | 1058 } else { |
1020 xor_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, z80_size(inst)); | 1059 xor_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, z80_size(inst)); |
1021 } | 1060 } |
1022 bt_ir(code, z80_size(inst) == SZ_B ? 4 : 12, opts->gen.scratch2, z80_size(inst)); | 1061 bt_ir(code, z80_size(inst) == SZ_B ? 4 : 12, opts->gen.scratch2, z80_size(inst)); |
1023 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); | 1062 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); |
1063 if (z80_size(inst) == SZ_W & dst_op.mode == MODE_REG_DIRECT) { | |
1064 mov_rr(code, dst_op.base, opts->gen.scratch2, SZ_W); | |
1065 shr_ir(code, 8, opts->gen.scratch2, SZ_W); | |
1066 mov_rrdisp(code, opts->gen.scratch2, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1067 } | |
1024 z80_save_reg(inst, opts); | 1068 z80_save_reg(inst, opts); |
1025 z80_save_ea(code, inst, opts); | 1069 z80_save_ea(code, inst, opts); |
1026 break; | 1070 break; |
1027 case Z80_AND: | 1071 case Z80_AND: |
1028 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 1072 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |
1040 } else if (src_op.mode == MODE_IMMED) { | 1084 } else if (src_op.mode == MODE_IMMED) { |
1041 and_ir(code, src_op.disp, dst_op.base, z80_size(inst)); | 1085 and_ir(code, src_op.disp, dst_op.base, z80_size(inst)); |
1042 } else { | 1086 } else { |
1043 and_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); | 1087 and_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); |
1044 } | 1088 } |
1089 mov_rrdisp(code, dst_op.base, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1045 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | 1090 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); |
1046 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_C), SZ_B); | 1091 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_C), SZ_B); |
1047 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_H), SZ_B); | 1092 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_H), SZ_B); |
1048 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); | 1093 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); |
1049 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | 1094 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); |
1067 } else if (src_op.mode == MODE_IMMED) { | 1112 } else if (src_op.mode == MODE_IMMED) { |
1068 or_ir(code, src_op.disp, dst_op.base, z80_size(inst)); | 1113 or_ir(code, src_op.disp, dst_op.base, z80_size(inst)); |
1069 } else { | 1114 } else { |
1070 or_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); | 1115 or_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); |
1071 } | 1116 } |
1117 mov_rrdisp(code, dst_op.base, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1072 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | 1118 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); |
1073 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_C), SZ_B); | 1119 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_C), SZ_B); |
1074 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B); | 1120 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B); |
1075 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); | 1121 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); |
1076 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | 1122 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); |
1094 } else if (src_op.mode == MODE_IMMED) { | 1140 } else if (src_op.mode == MODE_IMMED) { |
1095 xor_ir(code, src_op.disp, dst_op.base, z80_size(inst)); | 1141 xor_ir(code, src_op.disp, dst_op.base, z80_size(inst)); |
1096 } else { | 1142 } else { |
1097 xor_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); | 1143 xor_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); |
1098 } | 1144 } |
1145 mov_rrdisp(code, dst_op.base, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1099 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | 1146 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); |
1100 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_C), SZ_B); | 1147 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_C), SZ_B); |
1101 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B); | 1148 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B); |
1102 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); | 1149 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); |
1103 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | 1150 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); |
1115 translate_z80_reg(inst, &dst_op, opts); | 1162 translate_z80_reg(inst, &dst_op, opts); |
1116 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY); | 1163 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY); |
1117 mov_rr(code, dst_op.base, opts->gen.scratch2, z80_size(inst)); | 1164 mov_rr(code, dst_op.base, opts->gen.scratch2, z80_size(inst)); |
1118 if (src_op.mode == MODE_REG_DIRECT) { | 1165 if (src_op.mode == MODE_REG_DIRECT) { |
1119 sub_rr(code, src_op.base, opts->gen.scratch2, z80_size(inst)); | 1166 sub_rr(code, src_op.base, opts->gen.scratch2, z80_size(inst)); |
1167 mov_rrdisp(code, src_op.base, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1120 } else if (src_op.mode == MODE_IMMED) { | 1168 } else if (src_op.mode == MODE_IMMED) { |
1121 sub_ir(code, src_op.disp, opts->gen.scratch2, z80_size(inst)); | 1169 sub_ir(code, src_op.disp, opts->gen.scratch2, z80_size(inst)); |
1170 mov_irdisp(code, src_op.disp, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1122 } else { | 1171 } else { |
1123 sub_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch2, z80_size(inst)); | 1172 sub_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch2, z80_size(inst)); |
1173 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_B); | |
1174 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1124 } | 1175 } |
1125 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); | 1176 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); |
1126 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | 1177 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); |
1127 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); | 1178 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); |
1128 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | 1179 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); |
1179 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); | 1230 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); |
1180 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | 1231 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); |
1181 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); | 1232 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); |
1182 int bit = 4; | 1233 int bit = 4; |
1183 if (dst_op.mode == MODE_REG_DIRECT) { | 1234 if (dst_op.mode == MODE_REG_DIRECT) { |
1235 mov_rrdisp(code, dst_op.base, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1184 if (dst_op.base >= AH && dst_op.base <= BH) { | 1236 if (dst_op.base >= AH && dst_op.base <= BH) { |
1185 bit = 12; | 1237 bit = 12; |
1186 xor_rr(code, dst_op.base - AH, opts->gen.scratch2, SZ_W); | 1238 xor_rr(code, dst_op.base - AH, opts->gen.scratch2, SZ_W); |
1187 } else { | 1239 } else { |
1188 xor_rr(code, dst_op.base, opts->gen.scratch2, SZ_B); | 1240 xor_rr(code, dst_op.base, opts->gen.scratch2, SZ_B); |
1189 } | 1241 } |
1190 } else { | 1242 } else { |
1243 mov_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch1, SZ_B); | |
1191 xor_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, SZ_B); | 1244 xor_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, SZ_B); |
1245 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1192 } | 1246 } |
1193 bt_ir(code, bit, opts->gen.scratch2, SZ_W); | 1247 bt_ir(code, bit, opts->gen.scratch2, SZ_W); |
1194 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); | 1248 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); |
1195 } | 1249 } |
1196 z80_save_reg(inst, opts); | 1250 z80_save_reg(inst, opts); |
1255 break; | 1309 break; |
1256 case Z80_NEG: | 1310 case Z80_NEG: |
1257 cycles(&opts->gen, num_cycles); | 1311 cycles(&opts->gen, num_cycles); |
1258 mov_rr(code, opts->regs[Z80_A], opts->gen.scratch2, SZ_B); | 1312 mov_rr(code, opts->regs[Z80_A], opts->gen.scratch2, SZ_B); |
1259 neg_r(code, opts->regs[Z80_A], SZ_B); | 1313 neg_r(code, opts->regs[Z80_A], SZ_B); |
1314 mov_rrdisp(code, dst_op.base, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1260 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); | 1315 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); |
1261 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); | 1316 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); |
1262 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); | 1317 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); |
1263 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); | 1318 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); |
1264 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); | 1319 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); |
1734 cmp_irdisp(code, 0, src_op.base, src_op.disp, size); | 1789 cmp_irdisp(code, 0, src_op.base, src_op.disp, size); |
1735 } | 1790 } |
1736 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); | 1791 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); |
1737 } else { | 1792 } else { |
1738 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_S), SZ_B); | 1793 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_S), SZ_B); |
1794 } | |
1795 | |
1796 if ((inst->addr_mode & 0x1F) == Z80_REG) { | |
1797 if (src_op.mode == MODE_REG_DIRECT) { | |
1798 if (size == SZ_W) { | |
1799 mov_rr(code, src_op.base, opts->gen.scratch1, SZ_W); | |
1800 shr_ir(code, 8, opts->gen.scratch1, SZ_W); | |
1801 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1802 } else { | |
1803 mov_rrdisp(code, src_op.base, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1804 } | |
1805 } else { | |
1806 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_B); | |
1807 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1808 } | |
1809 } else if((inst->addr_mode & 0x1F) != Z80_REG_INDIRECT) { | |
1810 zreg_to_native(opts, (inst->addr_mode & 0x1F) == Z80_IX_DISPLACE ? Z80_IX : Z80_IY, opts->gen.scratch2); | |
1811 add_ir(code, inst->ea_reg & 0x80 ? inst->ea_reg - 256 : inst->ea_reg, opts->gen.scratch2, SZ_W); | |
1812 shr_ir(code, 8, opts->gen.scratch2, SZ_W); | |
1813 mov_rrdisp(code, opts->gen.scratch2, opts->gen.context_reg, zf_off(ZF_XY), SZ_B); | |
1739 } | 1814 } |
1740 break; | 1815 break; |
1741 } | 1816 } |
1742 case Z80_SET: { | 1817 case Z80_SET: { |
1743 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 1818 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |