comparison z80inst.c @ 205:19b323614309

Add support for IX bit instructions to decoder
author Mike Pavone <pavone@retrodev.com>
date Wed, 23 Jan 2013 21:50:54 -0800
parents 02dfa5962522
children 807ca611b561
comparison
equal deleted inserted replaced
204:02dfa5962522 205:19b323614309
763 NOP2, 763 NOP2,
764 NOP2, 764 NOP2,
765 NOP2 765 NOP2
766 }; 766 };
767 767
768 #define SHIFT_BLOCK_IX(op) \
769 {op, Z80_B, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
770 {op, Z80_C, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
771 {op, Z80_D, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
772 {op, Z80_E, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
773 {op, Z80_H, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
774 {op, Z80_L, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
775 {op, Z80_UNUSED, Z80_IX_DISPLACE | Z80_DIR, 0, 0},\
776 {op, Z80_A, Z80_IX_DISPLACE | Z80_DIR, 0, 0}
777
778 #define BIT_BLOCK_IX(bit) \
779 {Z80_BIT, Z80_USE_IMMED, Z80_IX_DISPLACE, 0, bit},\
780 {Z80_BIT, Z80_USE_IMMED, Z80_IX_DISPLACE, 0, bit},\
781 {Z80_BIT, Z80_USE_IMMED, Z80_IX_DISPLACE, 0, bit},\
782 {Z80_BIT, Z80_USE_IMMED, Z80_IX_DISPLACE, 0, bit},\
783 {Z80_BIT, Z80_USE_IMMED, Z80_IX_DISPLACE, 0, bit},\
784 {Z80_BIT, Z80_USE_IMMED, Z80_IX_DISPLACE, 0, bit},\
785 {Z80_BIT, Z80_USE_IMMED, Z80_IX_DISPLACE, 0, bit},\
786 {Z80_BIT, Z80_USE_IMMED, Z80_IX_DISPLACE, 0, bit}
787
788 #define BIT_BLOCK_IX_REG(op, bit) \
789 {op, Z80_B, Z80_IX_DISPLACE | Z80_DIR, 0, bit},\
790 {op, Z80_C, Z80_IX_DISPLACE | Z80_DIR, 0, bit},\
791 {op, Z80_D, Z80_IX_DISPLACE | Z80_DIR, 0, bit},\
792 {op, Z80_E, Z80_IX_DISPLACE | Z80_DIR, 0, bit},\
793 {op, Z80_H, Z80_IX_DISPLACE | Z80_DIR, 0, bit},\
794 {op, Z80_L, Z80_IX_DISPLACE | Z80_DIR, 0, bit},\
795 {op, Z80_USE_IMMED, Z80_IX_DISPLACE, 0, bit},\
796 {op, Z80_A, Z80_IX_DISPLACE | Z80_DIR, 0, bit}
797
798 z80inst z80_tbl_ix_bit[256] = {
799 //0
800 SHIFT_BLOCK_IX(Z80_RLC),
801 SHIFT_BLOCK_IX(Z80_RRC),
802 //1
803 SHIFT_BLOCK_IX(Z80_RL),
804 SHIFT_BLOCK_IX(Z80_RR),
805 //2
806 SHIFT_BLOCK_IX(Z80_SLA),
807 SHIFT_BLOCK_IX(Z80_SRA),
808 //3
809 SHIFT_BLOCK_IX(Z80_SLL),
810 SHIFT_BLOCK_IX(Z80_SRL),
811 //4
812 BIT_BLOCK_IX(0),
813 BIT_BLOCK_IX(1),
814 //5
815 BIT_BLOCK_IX(2),
816 BIT_BLOCK_IX(3),
817 //6
818 BIT_BLOCK_IX(4),
819 BIT_BLOCK_IX(5),
820 //7
821 BIT_BLOCK_IX(6),
822 BIT_BLOCK_IX(7),
823 //8
824 BIT_BLOCK_IX_REG(Z80_RES, 0),
825 BIT_BLOCK_IX_REG(Z80_RES, 1),
826 //9
827 BIT_BLOCK_IX_REG(Z80_RES, 2),
828 BIT_BLOCK_IX_REG(Z80_RES, 3),
829 //A
830 BIT_BLOCK_IX_REG(Z80_RES, 4),
831 BIT_BLOCK_IX_REG(Z80_RES, 5),
832 //B
833 BIT_BLOCK_IX_REG(Z80_RES, 6),
834 BIT_BLOCK_IX_REG(Z80_RES, 7),
835 //C
836 BIT_BLOCK_IX_REG(Z80_SET, 0),
837 BIT_BLOCK_IX_REG(Z80_SET, 1),
838 //D
839 BIT_BLOCK_IX_REG(Z80_SET, 2),
840 BIT_BLOCK_IX_REG(Z80_SET, 3),
841 //E
842 BIT_BLOCK_IX_REG(Z80_SET, 4),
843 BIT_BLOCK_IX_REG(Z80_SET, 5),
844 //F
845 BIT_BLOCK_IX_REG(Z80_SET, 6),
846 BIT_BLOCK_IX_REG(Z80_SET, 7),
847 };
768 848
769 z80inst z80_tbl_iy[256] = { 849 z80inst z80_tbl_iy[256] = {
770 //0 850 //0
771 NOP2, 851 NOP2,
772 NOP2, 852 NOP2,
1041 NOP2 1121 NOP2
1042 }; 1122 };
1043 1123
1044 uint8_t * z80_decode(uint8_t * istream, z80inst * decoded) 1124 uint8_t * z80_decode(uint8_t * istream, z80inst * decoded)
1045 { 1125 {
1126 uint8_t tmp;
1046 if (*istream == 0xCB) { 1127 if (*istream == 0xCB) {
1047 istream++; 1128 istream++;
1048 memcpy(decoded, z80_tbl_bit + *istream, sizeof(z80inst)); 1129 memcpy(decoded, z80_tbl_bit + *istream, sizeof(z80inst));
1049 } else if (*istream == 0xDD) { 1130 } else if (*istream == 0xDD) {
1050 istream++; 1131 istream++;
1051 if (*istream == 0xCB) { 1132 if (*istream == 0xCB) {
1133 tmp = *(++istream);
1134 istream++;
1135 memcpy(decoded, z80_tbl_ix_bit + *istream, sizeof(z80inst));
1136 decoded->ea_reg = tmp;
1052 } else { 1137 } else {
1053 memcpy(decoded, z80_tbl_ix + *istream, sizeof(z80inst)); 1138 memcpy(decoded, z80_tbl_ix + *istream, sizeof(z80inst));
1139 if ((decoded->addr_mode & 0x1F) == Z80_IX_DISPLACE) {
1140 decoded->ea_reg = *(++istream);
1141 }
1054 } 1142 }
1055 } else if (*istream == 0xED) { 1143 } else if (*istream == 0xED) {
1056 istream++; 1144 istream++;
1057 if (*istream < 0x40 || *istream >= 0xC0) { 1145 if (*istream < 0x40 || *istream >= 0xC0) {
1058 memcpy(decoded, z80_tbl_extd + 0xBF, sizeof(z80inst)); 1146 memcpy(decoded, z80_tbl_extd + 0xBF, sizeof(z80inst));
1062 } else if (*istream == 0xFD) { 1150 } else if (*istream == 0xFD) {
1063 istream++; 1151 istream++;
1064 if (*istream == 0xCB) { 1152 if (*istream == 0xCB) {
1065 } else { 1153 } else {
1066 memcpy(decoded, z80_tbl_iy + *istream, sizeof(z80inst)); 1154 memcpy(decoded, z80_tbl_iy + *istream, sizeof(z80inst));
1155 if ((decoded->addr_mode & 0x1F) == Z80_IY_DISPLACE) {
1156 decoded->ea_reg = *(++istream);
1157 }
1067 } 1158 }
1068 } else { 1159 } else {
1069 memcpy(decoded, z80_tbl_a + *istream, sizeof(z80inst)); 1160 memcpy(decoded, z80_tbl_a + *istream, sizeof(z80inst));
1070 1161
1071 } 1162 }
1072 if ((decoded->addr_mode & 0x1F) == Z80_IX_DISPLACE || (decoded->addr_mode & 0x1F) == Z80_IY_DISPLACE) { 1163 if ((decoded->addr_mode & 0x1F) == Z80_IMMED && decoded->op != Z80_RST && decoded->op != Z80_IM) {
1073 decoded->ea_reg = *(++istream);
1074 } else if ((decoded->addr_mode & 0x1F) == Z80_IMMED && decoded->op != Z80_RST && decoded->op != Z80_IM) {
1075 decoded->immed = *(++istream); 1164 decoded->immed = *(++istream);
1076 if (decoded->reg >= Z80_BC && decoded->reg < Z80_USE_IMMED) { 1165 if (decoded->reg >= Z80_BC && decoded->reg < Z80_UNUSED) {
1077 decoded->immed |= *(++istream) << 8; 1166 decoded->immed |= *(++istream) << 8;
1078 } else if (decoded->immed & 0x80) { 1167 } else if (decoded->immed & 0x80) {
1079 decoded->immed |= 0xFF00; 1168 decoded->immed |= 0xFF00;
1080 } 1169 }
1081 } else if ((decoded->addr_mode & 0x1F) == Z80_IMMED_INDIRECT) { 1170 } else if ((decoded->addr_mode & 0x1F) == Z80_IMMED_INDIRECT) {
1197 }; 1286 };
1198 1287
1199 int z80_disasm(z80inst * decoded, char * dst) 1288 int z80_disasm(z80inst * decoded, char * dst)
1200 { 1289 {
1201 int len = sprintf(dst, "%s", z80_mnemonics[decoded->op]); 1290 int len = sprintf(dst, "%s", z80_mnemonics[decoded->op]);
1291 uint8_t needcomma;
1202 if (decoded->addr_mode & Z80_DIR) { 1292 if (decoded->addr_mode & Z80_DIR) {
1293 needcomma = 1;
1203 switch (decoded->addr_mode & 0x1F) 1294 switch (decoded->addr_mode & 0x1F)
1204 { 1295 {
1205 case Z80_REG: 1296 case Z80_REG:
1206 len += sprintf(dst+len, " %s", z80_regs[decoded->ea_reg]); 1297 len += sprintf(dst+len, " %s", z80_regs[decoded->ea_reg]);
1207 break; 1298 break;
1218 len += sprintf(dst+len, " (ix+%d)", decoded->ea_reg); 1309 len += sprintf(dst+len, " (ix+%d)", decoded->ea_reg);
1219 break; 1310 break;
1220 case Z80_IY_DISPLACE: 1311 case Z80_IY_DISPLACE:
1221 len += sprintf(dst+len, " (iy+%d)", decoded->ea_reg); 1312 len += sprintf(dst+len, " (iy+%d)", decoded->ea_reg);
1222 break; 1313 break;
1314 default:
1315 needcomma = 0;
1223 } 1316 }
1224 if (decoded->reg == Z80_USE_IMMED) { 1317 if (decoded->reg & Z80_IMMED_FLAG) {
1225 len += sprintf(dst+len, " %d", decoded->immed); 1318 len += sprintf(dst+len, "%s %d", needcomma ? "," : "", decoded->immed);
1226 } else if (decoded->reg != Z80_UNUSED) { 1319 }
1320 if ((decoded->reg & 0x1F) != Z80_UNUSED) {
1227 if (decoded->op == Z80_JRCC || decoded->op == Z80_JPCC || decoded->op == Z80_CALLCC || decoded->op == Z80_RETCC) { 1321 if (decoded->op == Z80_JRCC || decoded->op == Z80_JPCC || decoded->op == Z80_CALLCC || decoded->op == Z80_RETCC) {
1228 len += sprintf(dst+len, "%s %s", decoded->reg == Z80_UNUSED ? "" : "," , z80_conditions[decoded->reg]); 1322 len += sprintf(dst+len, "%s %s", needcomma ? "," : "", z80_conditions[decoded->reg & 0x1F]);
1229 } else { 1323 } else {
1230 len += sprintf(dst+len, "%s %s", decoded->reg == Z80_UNUSED ? "" : "," , z80_regs[decoded->reg]); 1324 len += sprintf(dst+len, "%s %s", needcomma ? "," : "", z80_regs[decoded->reg & 0x1F]);
1231 } 1325 }
1232 } 1326 }
1233 } else { 1327 } else {
1234 if (decoded->reg == Z80_USE_IMMED) { 1328 needcomma = 0;
1329 if (decoded->reg & Z80_IMMED_FLAG) {
1235 len += sprintf(dst+len, " %d", decoded->immed); 1330 len += sprintf(dst+len, " %d", decoded->immed);
1236 } else if (decoded->reg != Z80_UNUSED) { 1331 needcomma = 1;
1332 }
1333 if ((decoded->reg & 0x1F) != Z80_UNUSED) {
1237 if (decoded->op == Z80_JRCC || decoded->op == Z80_JPCC || decoded->op == Z80_CALLCC || decoded->op == Z80_RETCC) { 1334 if (decoded->op == Z80_JRCC || decoded->op == Z80_JPCC || decoded->op == Z80_CALLCC || decoded->op == Z80_RETCC) {
1238 len += sprintf(dst+len, " %s", z80_conditions[decoded->reg]); 1335 len += sprintf(dst+len, " %s", z80_conditions[decoded->reg & 0x1F]);
1239 } else { 1336 } else {
1240 len += sprintf(dst+len, " %s", z80_regs[decoded->reg]); 1337 len += sprintf(dst+len, " %s", z80_regs[decoded->reg & 0x1F]);
1241 } 1338 }
1339 needcomma = 1;
1242 } 1340 }
1243 switch (decoded->addr_mode) 1341 switch (decoded->addr_mode)
1244 { 1342 {
1245 case Z80_REG: 1343 case Z80_REG:
1246 len += sprintf(dst+len, "%s %s", decoded->reg == Z80_UNUSED ? "" : "," , z80_regs[decoded->ea_reg]); 1344 len += sprintf(dst+len, "%s %s", needcomma ? "," : "" , z80_regs[decoded->ea_reg]);
1247 break; 1345 break;
1248 case Z80_REG_INDIRECT: 1346 case Z80_REG_INDIRECT:
1249 len += sprintf(dst+len, "%s (%s)", decoded->reg == Z80_UNUSED ? "" : "," , z80_regs[decoded->ea_reg]); 1347 len += sprintf(dst+len, "%s (%s)", needcomma ? "," : "" , z80_regs[decoded->ea_reg]);
1250 break; 1348 break;
1251 case Z80_IMMED: 1349 case Z80_IMMED:
1252 len += sprintf(dst+len, "%s %d", decoded->reg == Z80_UNUSED ? "" : "," , decoded->immed); 1350 len += sprintf(dst+len, "%s %d", needcomma ? "," : "" , decoded->immed);
1253 break; 1351 break;
1254 case Z80_IMMED_INDIRECT: 1352 case Z80_IMMED_INDIRECT:
1255 len += sprintf(dst+len, "%s (%d)", decoded->reg == Z80_UNUSED ? "" : "," , decoded->immed); 1353 len += sprintf(dst+len, "%s (%d)", needcomma ? "," : "" , decoded->immed);
1256 break; 1354 break;
1257 case Z80_IX_DISPLACE: 1355 case Z80_IX_DISPLACE:
1258 len += sprintf(dst+len, "%s (ix+%d)", decoded->reg == Z80_UNUSED ? "" : "," , decoded->ea_reg); 1356 len += sprintf(dst+len, "%s (ix+%d)", needcomma ? "," : "" , decoded->ea_reg);
1259 break; 1357 break;
1260 case Z80_IY_DISPLACE: 1358 case Z80_IY_DISPLACE:
1261 len += sprintf(dst+len, "%s (iy+%d)", decoded->reg == Z80_UNUSED ? "" : "," , decoded->ea_reg); 1359 len += sprintf(dst+len, "%s (iy+%d)", needcomma ? "," : "" , decoded->ea_reg);
1262 break; 1360 break;
1263 } 1361 }
1264 } 1362 }
1265 return len; 1363 return len;
1266 } 1364 }