comparison z80_to_x86.c @ 1042:a6c6b621d0dc

Implement Z80 DAA. Implement half-carry flag for the rest of the "easy" cases. Implement flags for IN instruction. Fix implementation of IN for IN F, (C) case
author Michael Pavone <pavone@retrodev.com>
date Sun, 24 Jul 2016 17:17:59 -0700
parents fbfb821e92a8
children 3980ef0f6307
comparison
equal deleted inserted replaced
1041:70338a4a9889 1042:a6c6b621d0dc
860 } else if (src_op.mode == MODE_IMMED) { 860 } else if (src_op.mode == MODE_IMMED) {
861 and_ir(code, src_op.disp, dst_op.base, z80_size(inst)); 861 and_ir(code, src_op.disp, dst_op.base, z80_size(inst));
862 } else { 862 } else {
863 and_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); 863 and_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst));
864 } 864 }
865 //TODO: Cleanup flags
866 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C));
867 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 865 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
868 //TODO: Implement half-carry flag 866 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_C), SZ_B);
869 if (z80_size(inst) == SZ_B) { 867 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
870 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); 868 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV));
871 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); 869 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z));
872 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); 870 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S));
873 }
874 z80_save_reg(inst, opts); 871 z80_save_reg(inst, opts);
875 z80_save_ea(code, inst, opts); 872 z80_save_ea(code, inst, opts);
876 break; 873 break;
877 case Z80_OR: 874 case Z80_OR:
878 num_cycles = 4; 875 num_cycles = 4;
891 } else if (src_op.mode == MODE_IMMED) { 888 } else if (src_op.mode == MODE_IMMED) {
892 or_ir(code, src_op.disp, dst_op.base, z80_size(inst)); 889 or_ir(code, src_op.disp, dst_op.base, z80_size(inst));
893 } else { 890 } else {
894 or_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); 891 or_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst));
895 } 892 }
896 //TODO: Cleanup flags
897 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C));
898 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 893 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
899 //TODO: Implement half-carry flag 894 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_C), SZ_B);
900 if (z80_size(inst) == SZ_B) { 895 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
901 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); 896 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV));
902 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); 897 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z));
903 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); 898 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S));
904 }
905 z80_save_reg(inst, opts); 899 z80_save_reg(inst, opts);
906 z80_save_ea(code, inst, opts); 900 z80_save_ea(code, inst, opts);
907 break; 901 break;
908 case Z80_XOR: 902 case Z80_XOR:
909 num_cycles = 4; 903 num_cycles = 4;
922 } else if (src_op.mode == MODE_IMMED) { 916 } else if (src_op.mode == MODE_IMMED) {
923 xor_ir(code, src_op.disp, dst_op.base, z80_size(inst)); 917 xor_ir(code, src_op.disp, dst_op.base, z80_size(inst));
924 } else { 918 } else {
925 xor_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst)); 919 xor_rdispr(code, src_op.base, src_op.disp, dst_op.base, z80_size(inst));
926 } 920 }
927 //TODO: Cleanup flags
928 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C));
929 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);
930 //TODO: Implement half-carry flag 922 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_C), SZ_B);
931 if (z80_size(inst) == SZ_B) { 923 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
932 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); 924 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV));
933 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); 925 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z));
934 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); 926 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S));
935 }
936 z80_save_reg(inst, opts); 927 z80_save_reg(inst, opts);
937 z80_save_ea(code, inst, opts); 928 z80_save_ea(code, inst, opts);
938 break; 929 break;
939 case Z80_CP: 930 case Z80_CP:
940 num_cycles = 4; 931 num_cycles = 4;
1021 } 1012 }
1022 z80_save_reg(inst, opts); 1013 z80_save_reg(inst, opts);
1023 z80_save_ea(code, inst, opts); 1014 z80_save_ea(code, inst, opts);
1024 z80_save_result(opts, inst); 1015 z80_save_result(opts, inst);
1025 break; 1016 break;
1026 //case Z80_DAA: 1017 case Z80_DAA:
1018 cycles(&opts->gen, 4);
1019 xor_rr(code, opts->gen.scratch2, opts->gen.scratch2, SZ_B);
1020 cmp_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1021 code_ptr corf_low = code->cur+1;
1022 jcc(code, CC_NZ, code->cur+2);
1023 zreg_to_native(opts, Z80_A, opts->gen.scratch1);
1024 and_ir(code, 0xF, opts->gen.scratch1, SZ_B);
1025 cmp_ir(code, 0xA, opts->gen.scratch1, SZ_B);
1026
1027 code_ptr no_corf_low = code->cur+1;
1028 jcc(code, CC_C, code->cur+2);
1029 *corf_low = code->cur - (corf_low + 1);
1030 mov_ir(code, 6, opts->gen.scratch2, SZ_B);
1031 //TODO: Deal with edge case of 9 in high nibble
1032 mov_ir(code, 0x90, opts->gen.scratch1, SZ_B);
1033 code_ptr after_cmp_set = code->cur+1;
1034 jmp(code, code->cur+2);
1035
1036 *no_corf_low = code->cur - (no_corf_low + 1);
1037 mov_ir(code, 0xA0, opts->gen.scratch1, SZ_B);
1038 *after_cmp_set = code->cur - (after_cmp_set + 1);
1039 cmp_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_C), SZ_B);
1040 code_ptr corf_high = code->cur+1;
1041 jcc(code, CC_NZ, code->cur+2);
1042 cmp_rr(code, opts->gen.scratch1, opts->regs[Z80_A], SZ_B);
1043 code_ptr no_corf_high = code->cur+1;
1044 jcc(code, CC_C, code->cur+2);
1045 *corf_high = code->cur - (corf_high + 1);
1046 or_ir(code, 0x60, opts->gen.scratch2, SZ_B);
1047 *no_corf_high = code->cur - (no_corf_high + 1);
1048
1049 cmp_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1050 code_ptr not_sub = code->cur+1;
1051 jcc(code, CC_Z, code->cur+2);
1052 neg_r(code, opts->gen.scratch2, SZ_B);
1053 *not_sub = code->cur - (not_sub + 1);
1054 add_rr(code, opts->gen.scratch2, opts->regs[Z80_A], SZ_B);
1055 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z));
1056 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S));
1057 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV));
1058 code_ptr no_carry = code->cur+1;
1059 jcc(code, CC_NC, code->cur+2);
1060 mov_ir(code, 1, opts->gen.context_reg, zf_off(ZF_C));
1061 *no_carry = code->cur - (no_carry + 1);
1062 //TODO: Implement half-carry flag
1063 break;
1027 case Z80_CPL: 1064 case Z80_CPL:
1028 cycles(&opts->gen, 4); 1065 cycles(&opts->gen, 4);
1029 not_r(code, opts->regs[Z80_A], SZ_B); 1066 not_r(code, opts->regs[Z80_A], SZ_B);
1030 //TODO: Implement half-carry flag 1067 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1031 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1068 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1032 break; 1069 break;
1033 case Z80_NEG: 1070 case Z80_NEG:
1034 cycles(&opts->gen, 8); 1071 cycles(&opts->gen, 8);
1035 neg_r(code, opts->regs[Z80_A], SZ_B); 1072 neg_r(code, opts->regs[Z80_A], SZ_B);
1040 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV)); 1077 setcc_rdisp(code, CC_O, opts->gen.context_reg, zf_off(ZF_PV));
1041 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1078 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1042 break; 1079 break;
1043 case Z80_CCF: 1080 case Z80_CCF:
1044 cycles(&opts->gen, 4); 1081 cycles(&opts->gen, 4);
1082 mov_rdispr(code, opts->gen.context_reg, zf_off(ZF_C), opts->gen.scratch1, SZ_B);
1045 xor_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_C), SZ_B); 1083 xor_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_C), SZ_B);
1046 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1084 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1047 //TODO: Implement half-carry flag 1085 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1048 break; 1086 break;
1049 case Z80_SCF: 1087 case Z80_SCF:
1050 cycles(&opts->gen, 4); 1088 cycles(&opts->gen, 4);
1051 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_C), SZ_B); 1089 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_C), SZ_B);
1052 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);
1053 //TODO: Implement half-carry flag 1091 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1054 break; 1092 break;
1055 case Z80_NOP: 1093 case Z80_NOP:
1056 if (inst->immed == 42) { 1094 if (inst->immed == 42) {
1057 call(code, opts->gen.save_context); 1095 call(code, opts->gen.save_context);
1058 call_args(code, (code_ptr)z80_print_regs_exit, 1, opts->gen.context_reg); 1096 call_args(code, (code_ptr)z80_print_regs_exit, 1, opts->gen.context_reg);
1109 } else if(src_op.mode == MODE_REG_DISPLACE8) { 1147 } else if(src_op.mode == MODE_REG_DISPLACE8) {
1110 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B); 1148 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B);
1111 } 1149 }
1112 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); 1150 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C));
1113 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1151 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1114 //TODO: Implement half-carry flag 1152 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1115 if (inst->immed) { 1153 if (inst->immed) {
1116 //rlca does not set these flags 1154 //rlca does not set these flags
1117 if (dst_op.mode == MODE_REG_DIRECT) { 1155 if (dst_op.mode == MODE_REG_DIRECT) {
1118 cmp_ir(code, 0, dst_op.base, SZ_B); 1156 cmp_ir(code, 0, dst_op.base, SZ_B);
1119 } else { 1157 } else {
1154 } else if(src_op.mode == MODE_REG_DISPLACE8) { 1192 } else if(src_op.mode == MODE_REG_DISPLACE8) {
1155 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B); 1193 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B);
1156 } 1194 }
1157 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); 1195 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C));
1158 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1196 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1159 //TODO: Implement half-carry flag 1197 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1160 if (inst->immed) { 1198 if (inst->immed) {
1161 //rla does not set these flags 1199 //rla does not set these flags
1162 if (dst_op.mode == MODE_REG_DIRECT) { 1200 if (dst_op.mode == MODE_REG_DIRECT) {
1163 cmp_ir(code, 0, dst_op.base, SZ_B); 1201 cmp_ir(code, 0, dst_op.base, SZ_B);
1164 } else { 1202 } else {
1198 } else if(src_op.mode == MODE_REG_DISPLACE8) { 1236 } else if(src_op.mode == MODE_REG_DISPLACE8) {
1199 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B); 1237 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B);
1200 } 1238 }
1201 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); 1239 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C));
1202 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1240 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1203 //TODO: Implement half-carry flag 1241 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1204 if (inst->immed) { 1242 if (inst->immed) {
1205 //rrca does not set these flags 1243 //rrca does not set these flags
1206 if (dst_op.mode == MODE_REG_DIRECT) { 1244 if (dst_op.mode == MODE_REG_DIRECT) {
1207 cmp_ir(code, 0, dst_op.base, SZ_B); 1245 cmp_ir(code, 0, dst_op.base, SZ_B);
1208 } else { 1246 } else {
1243 } else if(src_op.mode == MODE_REG_DISPLACE8) { 1281 } else if(src_op.mode == MODE_REG_DISPLACE8) {
1244 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B); 1282 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B);
1245 } 1283 }
1246 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); 1284 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C));
1247 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1285 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1248 //TODO: Implement half-carry flag 1286 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1249 if (inst->immed) { 1287 if (inst->immed) {
1250 //rra does not set these flags 1288 //rra does not set these flags
1251 if (dst_op.mode == MODE_REG_DIRECT) { 1289 if (dst_op.mode == MODE_REG_DIRECT) {
1252 cmp_ir(code, 0, dst_op.base, SZ_B); 1290 cmp_ir(code, 0, dst_op.base, SZ_B);
1253 } else { 1291 } else {
1295 mov_rr(code, dst_op.base, src_op.base, SZ_B); 1333 mov_rr(code, dst_op.base, src_op.base, SZ_B);
1296 } else if(src_op.mode == MODE_REG_DISPLACE8) { 1334 } else if(src_op.mode == MODE_REG_DISPLACE8) {
1297 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B); 1335 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B);
1298 } 1336 }
1299 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1337 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1300 //TODO: Implement half-carry flag 1338 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1301 if (dst_op.mode == MODE_REG_DIRECT) { 1339 if (dst_op.mode == MODE_REG_DIRECT) {
1302 cmp_ir(code, 0, dst_op.base, SZ_B); 1340 cmp_ir(code, 0, dst_op.base, SZ_B);
1303 } else { 1341 } else {
1304 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, SZ_B); 1342 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, SZ_B);
1305 } 1343 }
1336 } else if(src_op.mode == MODE_REG_DISPLACE8) { 1374 } else if(src_op.mode == MODE_REG_DISPLACE8) {
1337 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B); 1375 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B);
1338 } 1376 }
1339 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); 1377 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C));
1340 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1378 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1341 //TODO: Implement half-carry flag 1379 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1342 if (dst_op.mode == MODE_REG_DIRECT) { 1380 if (dst_op.mode == MODE_REG_DIRECT) {
1343 cmp_ir(code, 0, dst_op.base, SZ_B); 1381 cmp_ir(code, 0, dst_op.base, SZ_B);
1344 } else { 1382 } else {
1345 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, SZ_B); 1383 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, SZ_B);
1346 } 1384 }
1377 } else if(src_op.mode == MODE_REG_DISPLACE8) { 1415 } else if(src_op.mode == MODE_REG_DISPLACE8) {
1378 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B); 1416 mov_rrdisp(code, dst_op.base, src_op.base, src_op.disp, SZ_B);
1379 } 1417 }
1380 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); 1418 setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C));
1381 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1419 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1382 //TODO: Implement half-carry flag 1420 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1383 if (dst_op.mode == MODE_REG_DIRECT) { 1421 if (dst_op.mode == MODE_REG_DIRECT) {
1384 cmp_ir(code, 0, dst_op.base, SZ_B); 1422 cmp_ir(code, 0, dst_op.base, SZ_B);
1385 } else { 1423 } else {
1386 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, SZ_B); 1424 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, SZ_B);
1387 } 1425 }
1412 //opts->gen.scratch1 = 0x0124 1450 //opts->gen.scratch1 = 0x0124
1413 ror_ir(code, 8, opts->gen.scratch1, SZ_W); 1451 ror_ir(code, 8, opts->gen.scratch1, SZ_W);
1414 cycles(&opts->gen, 4); 1452 cycles(&opts->gen, 4);
1415 or_rr(code, opts->gen.scratch1, opts->regs[Z80_A], SZ_B); 1453 or_rr(code, opts->gen.scratch1, opts->regs[Z80_A], SZ_B);
1416 //set flags 1454 //set flags
1417 //TODO: Implement half-carry flag 1455 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1418 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1456 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1419 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); 1457 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV));
1420 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); 1458 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z));
1421 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); 1459 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S));
1422 1460
1443 ror_ir(code, 8, opts->gen.scratch1, SZ_W); 1481 ror_ir(code, 8, opts->gen.scratch1, SZ_W);
1444 cycles(&opts->gen, 4); 1482 cycles(&opts->gen, 4);
1445 shr_ir(code, 4, opts->gen.scratch1, SZ_B); 1483 shr_ir(code, 4, opts->gen.scratch1, SZ_B);
1446 or_rr(code, opts->gen.scratch1, opts->regs[Z80_A], SZ_B); 1484 or_rr(code, opts->gen.scratch1, opts->regs[Z80_A], SZ_B);
1447 //set flags 1485 //set flags
1448 //TODO: Implement half-carry flag 1486 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1449 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1487 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1450 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); 1488 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV));
1451 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); 1489 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z));
1452 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); 1490 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S));
1453 1491
1479 bt_irdisp(code, bit, src_op.base, src_op.disp, size); 1517 bt_irdisp(code, bit, src_op.base, src_op.disp, size);
1480 } 1518 }
1481 setcc_rdisp(code, CC_NC, opts->gen.context_reg, zf_off(ZF_Z)); 1519 setcc_rdisp(code, CC_NC, opts->gen.context_reg, zf_off(ZF_Z));
1482 setcc_rdisp(code, CC_NC, opts->gen.context_reg, zf_off(ZF_PV)); 1520 setcc_rdisp(code, CC_NC, opts->gen.context_reg, zf_off(ZF_PV));
1483 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B); 1521 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1522 mov_irdisp(code, 1, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1484 if (inst->immed == 7) { 1523 if (inst->immed == 7) {
1485 if (src_op.mode == MODE_REG_DIRECT) { 1524 if (src_op.mode == MODE_REG_DIRECT) {
1486 cmp_ir(code, 0, src_op.base, size); 1525 cmp_ir(code, 0, src_op.base, size);
1487 } else { 1526 } else {
1488 cmp_irdisp(code, 0, src_op.base, src_op.disp, size); 1527 cmp_irdisp(code, 0, src_op.base, src_op.disp, size);
1893 } 1932 }
1894 jmp(code, call_dst); 1933 jmp(code, call_dst);
1895 break; 1934 break;
1896 } 1935 }
1897 case Z80_IN: 1936 case Z80_IN:
1898 cycles(&opts->gen, inst->reg == Z80_A ? 7 : 8);//T States: 4 3/4 1937 cycles(&opts->gen, inst->reg == inst->addr_mode == Z80_IMMED_INDIRECT ? 7 : 8);//T States: 4 3/4
1899 if (inst->addr_mode == Z80_IMMED_INDIRECT) { 1938 if (inst->addr_mode == Z80_IMMED_INDIRECT) {
1900 mov_ir(code, inst->immed, opts->gen.scratch1, SZ_B); 1939 mov_ir(code, inst->immed, opts->gen.scratch1, SZ_B);
1901 } else { 1940 } else {
1902 mov_rr(code, opts->regs[Z80_C], opts->gen.scratch1, SZ_B); 1941 mov_rr(code, opts->regs[Z80_C], opts->gen.scratch1, SZ_B);
1903 } 1942 }
1904 call(code, opts->read_io); 1943 call(code, opts->read_io);
1905 translate_z80_reg(inst, &dst_op, opts); 1944 if (inst->addr_mode != Z80_IMMED_INDIRECT) {
1906 if (dst_op.mode == MODE_REG_DIRECT) { 1945 or_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_B);
1907 mov_rr(code, opts->gen.scratch1, dst_op.base, SZ_B); 1946 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B);
1908 } else { 1947 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_N), SZ_B);
1909 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_B); 1948 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV));
1949 setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z));
1950 setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S));
1951 }
1952 if (inst->reg != Z80_UNUSED) {
1953 translate_z80_reg(inst, &dst_op, opts);
1954 if (dst_op.mode == MODE_REG_DIRECT) {
1955 mov_rr(code, opts->gen.scratch1, dst_op.base, SZ_B);
1956 } else {
1957 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_B);
1958 }
1910 } 1959 }
1911 z80_save_reg(inst, opts); 1960 z80_save_reg(inst, opts);
1912 break; 1961 break;
1913 /*case Z80_INI: 1962 /*case Z80_INI:
1914 case Z80_INIR: 1963 case Z80_INIR: