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) {