comparison z80_to_x86.c @ 505:b7b7a1cab44a

The local clone on my laptop got messed up and some changes had not been pushed. This commit represents the status of the working copy from that clone. It unfortunately contains some changes that I did not intend to commit yet, but this seems like the best option at the moment.
author Michael Pavone <pavone@retrodev.com>
date Mon, 06 Jan 2014 22:54:05 -0800
parents 140af5509ce7
children a3b48a57e847
comparison
equal deleted inserted replaced
504:7b0df1aaf384 505:b7b7a1cab44a
1 /* 1 /*
2 Copyright 2013 Michael Pavone 2 Copyright 2013 Michael Pavone
3 This file is part of BlastEm. 3 This file is part of BlastEm.
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. 4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
5 */ 5 */
6 #include "z80inst.h" 6 #include "z80inst.h"
7 #include "z80_to_x86.h" 7 #include "z80_to_x86.h"
8 #include "gen_x86.h" 8 #include "gen_x86.h"
307 return offsetof(z80_context, alt_regs) + reg; 307 return offsetof(z80_context, alt_regs) + reg;
308 } 308 }
309 309
310 void z80_print_regs_exit(z80_context * context) 310 void z80_print_regs_exit(z80_context * context)
311 { 311 {
312 printf("A: %X\nB: %X\nC: %X\nD: %X\nE: %X\nHL: %X\nIX: %X\nIY: %X\nSP: %X\n\nIM: %d, IFF1: %d, IFF2: %d\n", 312 printf("A: %X\nB: %X\nC: %X\nD: %X\nE: %X\nHL: %X\nIX: %X\nIY: %X\nSP: %X\n\nIM: %d, IFF1: %d, IFF2: %d\n",
313 context->regs[Z80_A], context->regs[Z80_B], context->regs[Z80_C], 313 context->regs[Z80_A], context->regs[Z80_B], context->regs[Z80_C],
314 context->regs[Z80_D], context->regs[Z80_E], 314 context->regs[Z80_D], context->regs[Z80_E],
315 (context->regs[Z80_H] << 8) | context->regs[Z80_L], 315 (context->regs[Z80_H] << 8) | context->regs[Z80_L],
316 (context->regs[Z80_IXH] << 8) | context->regs[Z80_IXL], 316 (context->regs[Z80_IXH] << 8) | context->regs[Z80_IXL],
317 (context->regs[Z80_IYH] << 8) | context->regs[Z80_IYL], 317 (context->regs[Z80_IYH] << 8) | context->regs[Z80_IYL],
318 context->sp, context->im, context->iff1, context->iff2); 318 context->sp, context->im, context->iff1, context->iff2);
319 puts("--Alternate Regs--"); 319 puts("--Alternate Regs--");
320 printf("A: %X\nB: %X\nC: %X\nD: %X\nE: %X\nHL: %X\nIX: %X\nIY: %X\n", 320 printf("A: %X\nB: %X\nC: %X\nD: %X\nE: %X\nHL: %X\nIX: %X\nIY: %X\n",
321 context->alt_regs[Z80_A], context->alt_regs[Z80_B], context->alt_regs[Z80_C], 321 context->alt_regs[Z80_A], context->alt_regs[Z80_B], context->alt_regs[Z80_C],
322 context->alt_regs[Z80_D], context->alt_regs[Z80_E], 322 context->alt_regs[Z80_D], context->alt_regs[Z80_E],
323 (context->alt_regs[Z80_H] << 8) | context->alt_regs[Z80_L], 323 (context->alt_regs[Z80_H] << 8) | context->alt_regs[Z80_L],
324 (context->alt_regs[Z80_IXH] << 8) | context->alt_regs[Z80_IXL], 324 (context->alt_regs[Z80_IXH] << 8) | context->alt_regs[Z80_IXL],
325 (context->alt_regs[Z80_IYH] << 8) | context->alt_regs[Z80_IYL]); 325 (context->alt_regs[Z80_IYH] << 8) | context->alt_regs[Z80_IYL]);
326 exit(0); 326 exit(0);
327 } 327 }
328 328
329 uint8_t * translate_z80inst(z80inst * inst, uint8_t * dst, z80_context * context, uint16_t address) 329 uint8_t * translate_z80inst(z80inst * inst, uint8_t * dst, z80_context * context, uint16_t address)
361 if ((inst->reg >= Z80_IXL && inst->reg <= Z80_IYH) || inst->reg == Z80_IX || inst->reg == Z80_IY) { 361 if ((inst->reg >= Z80_IXL && inst->reg <= Z80_IYH) || inst->reg == Z80_IX || inst->reg == Z80_IY) {
362 cycles += 4; 362 cycles += 4;
363 } 363 }
364 dst = zcycles(dst, cycles); 364 dst = zcycles(dst, cycles);
365 if (inst->addr_mode & Z80_DIR) { 365 if (inst->addr_mode & Z80_DIR) {
366 dst = translate_z80_ea(inst, &dst_op, dst, opts, DONT_READ, MODIFY);
366 dst = translate_z80_reg(inst, &src_op, dst, opts); 367 dst = translate_z80_reg(inst, &src_op, dst, opts);
367 dst = translate_z80_ea(inst, &dst_op, dst, opts, DONT_READ, MODIFY);
368 } else { 368 } else {
369 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY); 369 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY);
370 dst = translate_z80_reg(inst, &dst_op, dst, opts); 370 dst = translate_z80_reg(inst, &dst_op, dst, opts);
371 } 371 }
372 if (src_op.mode == MODE_REG_DIRECT) { 372 if (src_op.mode == MODE_REG_DIRECT) {
416 dst = zcycles(dst, (inst->reg == Z80_IX || inst->reg == Z80_IY) ? 8 : 4); 416 dst = zcycles(dst, (inst->reg == Z80_IX || inst->reg == Z80_IY) ? 8 : 4);
417 dst = mov_rr(dst, opts->regs[Z80_SP], SCRATCH1, SZ_W); 417 dst = mov_rr(dst, opts->regs[Z80_SP], SCRATCH1, SZ_W);
418 dst = call(dst, (uint8_t *)z80_read_word); 418 dst = call(dst, (uint8_t *)z80_read_word);
419 dst = add_ir(dst, 2, opts->regs[Z80_SP], SZ_W); 419 dst = add_ir(dst, 2, opts->regs[Z80_SP], SZ_W);
420 if (inst->reg == Z80_AF) { 420 if (inst->reg == Z80_AF) {
421 421
422 dst = bt_ir(dst, 0, SCRATCH1, SZ_W); 422 dst = bt_ir(dst, 0, SCRATCH1, SZ_W);
423 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C)); 423 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_C));
424 dst = bt_ir(dst, 1, SCRATCH1, SZ_W); 424 dst = bt_ir(dst, 1, SCRATCH1, SZ_W);
425 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_N)); 425 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_N));
426 dst = bt_ir(dst, 2, SCRATCH1, SZ_W); 426 dst = bt_ir(dst, 2, SCRATCH1, SZ_W);
450 if (inst->addr_mode == Z80_REG) { 450 if (inst->addr_mode == Z80_REG) {
451 if(inst->reg == Z80_AF) { 451 if(inst->reg == Z80_AF) {
452 dst = mov_rr(dst, opts->regs[Z80_A], SCRATCH1, SZ_B); 452 dst = mov_rr(dst, opts->regs[Z80_A], SCRATCH1, SZ_B);
453 dst = mov_rdisp8r(dst, CONTEXT, zar_off(Z80_A), opts->regs[Z80_A], SZ_B); 453 dst = mov_rdisp8r(dst, CONTEXT, zar_off(Z80_A), opts->regs[Z80_A], SZ_B);
454 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, zar_off(Z80_A), SZ_B); 454 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, zar_off(Z80_A), SZ_B);
455 455
456 //Flags are currently word aligned, so we can move 456 //Flags are currently word aligned, so we can move
457 //them efficiently a word at a time 457 //them efficiently a word at a time
458 for (int f = ZF_C; f < ZF_NUM; f+=2) { 458 for (int f = ZF_C; f < ZF_NUM; f+=2) {
459 dst = mov_rdisp8r(dst, CONTEXT, zf_off(f), SCRATCH1, SZ_W); 459 dst = mov_rdisp8r(dst, CONTEXT, zf_off(f), SCRATCH1, SZ_W);
460 dst = mov_rdisp8r(dst, CONTEXT, zaf_off(f), SCRATCH2, SZ_W); 460 dst = mov_rdisp8r(dst, CONTEXT, zaf_off(f), SCRATCH2, SZ_W);
523 dst = call(dst, (uint8_t *)z80_read_byte); 523 dst = call(dst, (uint8_t *)z80_read_byte);
524 dst = mov_rr(dst, opts->regs[Z80_DE], SCRATCH2, SZ_W); 524 dst = mov_rr(dst, opts->regs[Z80_DE], SCRATCH2, SZ_W);
525 dst = call(dst, (uint8_t *)z80_write_byte); 525 dst = call(dst, (uint8_t *)z80_write_byte);
526 dst = add_ir(dst, 1, opts->regs[Z80_DE], SZ_W); 526 dst = add_ir(dst, 1, opts->regs[Z80_DE], SZ_W);
527 dst = add_ir(dst, 1, opts->regs[Z80_HL], SZ_W); 527 dst = add_ir(dst, 1, opts->regs[Z80_HL], SZ_W);
528 528
529 dst = sub_ir(dst, 1, opts->regs[Z80_BC], SZ_W); 529 dst = sub_ir(dst, 1, opts->regs[Z80_BC], SZ_W);
530 uint8_t * cont = dst+1; 530 uint8_t * cont = dst+1;
531 dst = jcc(dst, CC_Z, dst+2); 531 dst = jcc(dst, CC_Z, dst+2);
532 dst = zcycles(dst, 7); 532 dst = zcycles(dst, 7);
533 //TODO: Figure out what the flag state should be here 533 //TODO: Figure out what the flag state should be here
561 dst = call(dst, (uint8_t *)z80_read_byte); 561 dst = call(dst, (uint8_t *)z80_read_byte);
562 dst = mov_rr(dst, opts->regs[Z80_DE], SCRATCH2, SZ_W); 562 dst = mov_rr(dst, opts->regs[Z80_DE], SCRATCH2, SZ_W);
563 dst = call(dst, (uint8_t *)z80_write_byte); 563 dst = call(dst, (uint8_t *)z80_write_byte);
564 dst = sub_ir(dst, 1, opts->regs[Z80_DE], SZ_W); 564 dst = sub_ir(dst, 1, opts->regs[Z80_DE], SZ_W);
565 dst = sub_ir(dst, 1, opts->regs[Z80_HL], SZ_W); 565 dst = sub_ir(dst, 1, opts->regs[Z80_HL], SZ_W);
566 566
567 dst = sub_ir(dst, 1, opts->regs[Z80_BC], SZ_W); 567 dst = sub_ir(dst, 1, opts->regs[Z80_BC], SZ_W);
568 uint8_t * cont = dst+1; 568 uint8_t * cont = dst+1;
569 dst = jcc(dst, CC_Z, dst+2); 569 dst = jcc(dst, CC_Z, dst+2);
570 dst = zcycles(dst, 7); 570 dst = zcycles(dst, 7);
571 //TODO: Figure out what the flag state should be here 571 //TODO: Figure out what the flag state should be here
1160 //TODO: Implement half-carry flag 1160 //TODO: Implement half-carry flag
1161 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); 1161 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B);
1162 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); 1162 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV));
1163 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); 1163 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z));
1164 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); 1164 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S));
1165 1165
1166 dst = mov_rr(dst, opts->regs[Z80_HL], SCRATCH2, SZ_W); 1166 dst = mov_rr(dst, opts->regs[Z80_HL], SCRATCH2, SZ_W);
1167 dst = ror_ir(dst, 8, SCRATCH1, SZ_W); 1167 dst = ror_ir(dst, 8, SCRATCH1, SZ_W);
1168 dst = call(dst, (uint8_t *)z80_write_byte); 1168 dst = call(dst, (uint8_t *)z80_write_byte);
1169 break; 1169 break;
1170 case Z80_RRD: 1170 case Z80_RRD:
1190 //TODO: Implement half-carry flag 1190 //TODO: Implement half-carry flag
1191 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B); 1191 dst = mov_irdisp8(dst, 0, CONTEXT, zf_off(ZF_N), SZ_B);
1192 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV)); 1192 dst = setcc_rdisp8(dst, CC_P, CONTEXT, zf_off(ZF_PV));
1193 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z)); 1193 dst = setcc_rdisp8(dst, CC_Z, CONTEXT, zf_off(ZF_Z));
1194 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S)); 1194 dst = setcc_rdisp8(dst, CC_S, CONTEXT, zf_off(ZF_S));
1195 1195
1196 dst = mov_rr(dst, opts->regs[Z80_HL], SCRATCH2, SZ_W); 1196 dst = mov_rr(dst, opts->regs[Z80_HL], SCRATCH2, SZ_W);
1197 dst = ror_ir(dst, 8, SCRATCH1, SZ_W); 1197 dst = ror_ir(dst, 8, SCRATCH1, SZ_W);
1198 dst = call(dst, (uint8_t *)z80_write_byte); 1198 dst = call(dst, (uint8_t *)z80_write_byte);
1199 break; 1199 break;
1200 case Z80_BIT: { 1200 case Z80_BIT: {
1253 dst = ror_ir(dst, 8, src_op.base, SZ_W); 1253 dst = ror_ir(dst, 8, src_op.base, SZ_W);
1254 dst = mov_rr(dst, opts->regs[z80_low_reg(inst->ea_reg)], dst_op.base, SZ_B); 1254 dst = mov_rr(dst, opts->regs[z80_low_reg(inst->ea_reg)], dst_op.base, SZ_B);
1255 dst = ror_ir(dst, 8, src_op.base, SZ_W); 1255 dst = ror_ir(dst, 8, src_op.base, SZ_W);
1256 } else { 1256 } else {
1257 dst = mov_rr(dst, opts->regs[inst->ea_reg], dst_op.base, SZ_B); 1257 dst = mov_rr(dst, opts->regs[inst->ea_reg], dst_op.base, SZ_B);
1258 } 1258 }
1259 } else { 1259 } else {
1260 dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); 1260 dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B);
1261 } 1261 }
1262 } 1262 }
1263 if ((inst->addr_mode & 0x1F) != Z80_REG) { 1263 if ((inst->addr_mode & 0x1F) != Z80_REG) {
1295 dst = ror_ir(dst, 8, src_op.base, SZ_W); 1295 dst = ror_ir(dst, 8, src_op.base, SZ_W);
1296 dst = mov_rr(dst, opts->regs[z80_low_reg(inst->ea_reg)], dst_op.base, SZ_B); 1296 dst = mov_rr(dst, opts->regs[z80_low_reg(inst->ea_reg)], dst_op.base, SZ_B);
1297 dst = ror_ir(dst, 8, src_op.base, SZ_W); 1297 dst = ror_ir(dst, 8, src_op.base, SZ_W);
1298 } else { 1298 } else {
1299 dst = mov_rr(dst, opts->regs[inst->ea_reg], dst_op.base, SZ_B); 1299 dst = mov_rr(dst, opts->regs[inst->ea_reg], dst_op.base, SZ_B);
1300 } 1300 }
1301 } else { 1301 } else {
1302 dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B); 1302 dst = mov_rr(dst, src_op.base, dst_op.base, SZ_B);
1303 } 1303 }
1304 } 1304 }
1305 if (inst->addr_mode != Z80_REG) { 1305 if (inst->addr_mode != Z80_REG) {
1846 char disbuf[80]; 1846 char disbuf[80];
1847 if (z80_get_native_address(context, address)) { 1847 if (z80_get_native_address(context, address)) {
1848 return; 1848 return;
1849 } 1849 }
1850 x86_z80_options * opts = context->options; 1850 x86_z80_options * opts = context->options;
1851 uint32_t start_address = address;
1851 uint8_t * encoded = NULL, *next; 1852 uint8_t * encoded = NULL, *next;
1852 if (address < 0x4000) { 1853 if (address < 0x4000) {
1853 encoded = context->mem_pointers[0] + (address & 0x1FFF); 1854 encoded = context->mem_pointers[0] + (address & 0x1FFF);
1854 } else if(address >= 0x8000 && context->mem_pointers[1]) { 1855 } else if(address >= 0x8000 && context->mem_pointers[1]) {
1855 printf("attempt to translate Z80 code from banked area at address %X\n", address); 1856 printf("attempt to translate Z80 code from banked area at address %X\n", address);
1894 z80_map_native_address(context, address, opts->cur_code, next-encoded, after - opts->cur_code); 1895 z80_map_native_address(context, address, opts->cur_code, next-encoded, after - opts->cur_code);
1895 opts->cur_code = after; 1896 opts->cur_code = after;
1896 address += next-encoded; 1897 address += next-encoded;
1897 if (address > 0xFFFF) { 1898 if (address > 0xFFFF) {
1898 address &= 0xFFFF; 1899 address &= 0xFFFF;
1899 1900
1900 } else { 1901 } else {
1901 encoded = next; 1902 encoded = next;
1902 } 1903 }
1903 } while (!z80_is_terminal(&inst)); 1904 } while (!z80_is_terminal(&inst));
1904 process_deferred(&opts->deferred, context, (native_addr_func)z80_get_native_address); 1905 process_deferred(&opts->deferred, context, (native_addr_func)z80_get_native_address);
1985 dst = alloc_code(&size); 1986 dst = alloc_code(&size);
1986 opts->code_end = dst_end = dst + size; 1987 opts->code_end = dst_end = dst + size;
1987 } 1988 }
1988 bp_stub = dst; 1989 bp_stub = dst;
1989 native = call(native, bp_stub); 1990 native = call(native, bp_stub);
1990 1991
1991 //Calculate length of prologue 1992 //Calculate length of prologue
1992 dst = z80_check_cycles_int(dst, address); 1993 dst = z80_check_cycles_int(dst, address);
1993 int check_int_size = dst-bp_stub; 1994 int check_int_size = dst-bp_stub;
1994 dst = bp_stub; 1995 dst = bp_stub;
1995 1996
1996 //Save context and call breakpoint handler 1997 //Save context and call breakpoint handler
1997 dst = call(dst, (uint8_t *)z80_save_context); 1998 dst = call(dst, (uint8_t *)z80_save_context);
1998 dst = push_r(dst, SCRATCH1); 1999 dst = push_r(dst, SCRATCH1);
1999 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); 2000 dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
2000 dst = mov_rr(dst, SCRATCH1, RSI, SZ_W); 2001 dst = mov_rr(dst, SCRATCH1, RSI, SZ_W);