comparison z80_to_x86.c @ 268:6c2d7e003a55

Sync Z80 on writes to busreq/reset ports. NULL out extra_pc on z80 reset
author Mike Pavone <pavone@retrodev.com>
date Thu, 02 May 2013 21:54:04 -0700
parents 1788e3f29c28
children 3c054d977175
comparison
equal deleted inserted replaced
267:1788e3f29c28 268:6c2d7e003a55
12 #define ZCYCLES RBP 12 #define ZCYCLES RBP
13 #define ZLIMIT RDI 13 #define ZLIMIT RDI
14 #define SCRATCH1 R13 14 #define SCRATCH1 R13
15 #define SCRATCH2 R14 15 #define SCRATCH2 R14
16 #define CONTEXT RSI 16 #define CONTEXT RSI
17
18 #ifdef DO_DEBUG_PRINT
19 #define dprintf printf
20 #else
21 #define dprintf
22 #endif
17 23
18 void z80_read_byte(); 24 void z80_read_byte();
19 void z80_read_word(); 25 void z80_read_word();
20 void z80_write_byte(); 26 void z80_write_byte();
21 void z80_write_word_highfirst(); 27 void z80_write_word_highfirst();
112 if (inst->reg == Z80_IYH) { 118 if (inst->reg == Z80_IYH) {
113 ea->base = opts->regs[Z80_IYL]; 119 ea->base = opts->regs[Z80_IYL];
114 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); 120 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W);
115 } else if(opts->regs[inst->reg] >= 0) { 121 } else if(opts->regs[inst->reg] >= 0) {
116 ea->base = opts->regs[inst->reg]; 122 ea->base = opts->regs[inst->reg];
117 if (ea->base >= AH && ea->base <= BH && (inst->addr_mode & 0x1F) == Z80_REG) { 123 if (ea->base >= AH && ea->base <= BH) {
118 uint8_t other_reg = opts->regs[inst->ea_reg]; 124 if ((inst->addr_mode & 0x1F) == Z80_REG) {
119 if (other_reg > R8 || (other_reg >= RSP && other_reg <= RDI)) { 125 uint8_t other_reg = opts->regs[inst->ea_reg];
120 //we can't mix an *H reg with a register that requires the REX prefix 126 if (other_reg > R8 || (other_reg >= RSP && other_reg <= RDI)) {
127 //we can't mix an *H reg with a register that requires the REX prefix
128 ea->base = opts->regs[z80_low_reg(inst->reg)];
129 dst = ror_ir(dst, 8, ea->base, SZ_W);
130 }
131 } else if((inst->addr_mode & 0x1F) != Z80_UNUSED && (inst->addr_mode & 0x1F) != Z80_IMMED) {
132 //temp regs require REX prefix too
121 ea->base = opts->regs[z80_low_reg(inst->reg)]; 133 ea->base = opts->regs[z80_low_reg(inst->reg)];
122 dst = ror_ir(dst, 8, ea->base, SZ_W); 134 dst = ror_ir(dst, 8, ea->base, SZ_W);
123 } 135 }
124 } 136 }
125 } else { 137 } else {
133 145
134 uint8_t * z80_save_reg(uint8_t * dst, z80inst * inst, x86_z80_options * opts) 146 uint8_t * z80_save_reg(uint8_t * dst, z80inst * inst, x86_z80_options * opts)
135 { 147 {
136 if (inst->reg == Z80_IYH) { 148 if (inst->reg == Z80_IYH) {
137 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); 149 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W);
138 } else if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->reg] >= AH && opts->regs[inst->reg] <= BH) { 150 } else if (opts->regs[inst->reg] >= AH && opts->regs[inst->reg] <= BH) {
139 uint8_t other_reg = opts->regs[inst->ea_reg]; 151 if ((inst->addr_mode & 0x1F) == Z80_REG) {
140 if (other_reg > R8 || (other_reg >= RSP && other_reg <= RDI)) { 152 uint8_t other_reg = opts->regs[inst->ea_reg];
141 //we can't mix an *H reg with a register that requires the REX prefix 153 if (other_reg > R8 || (other_reg >= RSP && other_reg <= RDI)) {
154 //we can't mix an *H reg with a register that requires the REX prefix
155 dst = ror_ir(dst, 8, opts->regs[z80_low_reg(inst->reg)], SZ_W);
156 }
157 } else if((inst->addr_mode & 0x1F) != Z80_UNUSED && (inst->addr_mode & 0x1F) != Z80_IMMED) {
158 //temp regs require REX prefix too
142 dst = ror_ir(dst, 8, opts->regs[z80_low_reg(inst->reg)], SZ_W); 159 dst = ror_ir(dst, 8, opts->regs[z80_low_reg(inst->reg)], SZ_W);
143 } 160 }
144 } 161 }
145 return dst; 162 return dst;
146 } 163 }
1270 map = context->static_code_map; 1287 map = context->static_code_map;
1271 } else if (address >= 0x8000) { 1288 } else if (address >= 0x8000) {
1272 address &= 0x7FFF; 1289 address &= 0x7FFF;
1273 map = context->banked_code_map + (context->bank_reg << 15); 1290 map = context->banked_code_map + (context->bank_reg << 15);
1274 } else { 1291 } else {
1275 printf("z80_get_native_address: %X NULL\n", address); 1292 dprintf("z80_get_native_address: %X NULL\n", address);
1276 return NULL; 1293 return NULL;
1277 } 1294 }
1278 if (!map->base || !map->offsets || map->offsets[address] == INVALID_OFFSET) { 1295 if (!map->base || !map->offsets || map->offsets[address] == INVALID_OFFSET || map->offsets[address] == EXTENSION_WORD) {
1279 printf("z80_get_native_address: %X NULL\n", address); 1296 dprintf("z80_get_native_address: %X NULL\n", address);
1280 return NULL; 1297 return NULL;
1281 } 1298 }
1282 printf("z80_get_native_address: %X %p\n", address, map->base + map->offsets[address]); 1299 dprintf("z80_get_native_address: %X %p\n", address, map->base + map->offsets[address]);
1283 return map->base + map->offsets[address]; 1300 return map->base + map->offsets[address];
1284 } 1301 }
1285 1302
1286 uint8_t z80_get_native_inst_size(x86_z80_options * opts, uint32_t address) 1303 uint8_t z80_get_native_inst_size(x86_z80_options * opts, uint32_t address)
1287 { 1304 {
1356 z80_context * z80_handle_code_write(uint32_t address, z80_context * context) 1373 z80_context * z80_handle_code_write(uint32_t address, z80_context * context)
1357 { 1374 {
1358 uint32_t inst_start = z80_get_instruction_start(context->static_code_map, address); 1375 uint32_t inst_start = z80_get_instruction_start(context->static_code_map, address);
1359 if (inst_start != INVALID_INSTRUCTION_START) { 1376 if (inst_start != INVALID_INSTRUCTION_START) {
1360 uint8_t * dst = z80_get_native_address(context, inst_start); 1377 uint8_t * dst = z80_get_native_address(context, inst_start);
1361 printf("patching code at %p for Z80 instruction at %X due to write to %X\n", dst, inst_start, address); 1378 dprintf("patching code at %p for Z80 instruction at %X due to write to %X\n", dst, inst_start, address);
1362 dst = mov_ir(dst, inst_start, SCRATCH1, SZ_D); 1379 dst = mov_ir(dst, inst_start, SCRATCH1, SZ_D);
1363 dst = jmp(dst, (uint8_t *)z80_retrans_stub); 1380 dst = jmp(dst, (uint8_t *)z80_retrans_stub);
1364 } 1381 }
1365 return context; 1382 return context;
1366 } 1383 }
1397 address &= 0x1FFF; 1414 address &= 0x1FFF;
1398 uint8_t * dst = opts->cur_code; 1415 uint8_t * dst = opts->cur_code;
1399 uint8_t * dst_end = opts->code_end; 1416 uint8_t * dst_end = opts->code_end;
1400 uint8_t *after, *inst = context->mem_pointers[0] + address; 1417 uint8_t *after, *inst = context->mem_pointers[0] + address;
1401 z80inst instbuf; 1418 z80inst instbuf;
1402 printf("Retranslating code at Z80 address %X, native address %p\n", address, orig_start); 1419 dprintf("Retranslating code at Z80 address %X, native address %p\n", address, orig_start);
1403 after = z80_decode(inst, &instbuf); 1420 after = z80_decode(inst, &instbuf);
1421 #ifdef DO_DEBUG_PRINT
1404 z80_disasm(&instbuf, disbuf); 1422 z80_disasm(&instbuf, disbuf);
1405 if (instbuf.op == Z80_NOP) { 1423 if (instbuf.op == Z80_NOP) {
1406 printf("%X\t%s(%d)\n", address, disbuf, instbuf.immed); 1424 printf("%X\t%s(%d)\n", address, disbuf, instbuf.immed);
1407 } else { 1425 } else {
1408 printf("%X\t%s\n", address, disbuf); 1426 printf("%X\t%s\n", address, disbuf);
1409 } 1427 }
1428 #endif
1410 if (orig_size != ZMAX_NATIVE_SIZE) { 1429 if (orig_size != ZMAX_NATIVE_SIZE) {
1411 if (dst_end - dst < ZMAX_NATIVE_SIZE) { 1430 if (dst_end - dst < ZMAX_NATIVE_SIZE) {
1412 size_t size = 1024*1024; 1431 size_t size = 1024*1024;
1413 dst = alloc_code(&size); 1432 dst = alloc_code(&size);
1414 opts->code_end = dst_end = dst + size; 1433 opts->code_end = dst_end = dst + size;
1462 encoded = context->mem_pointers[1] + (address & 0x7FFF); 1481 encoded = context->mem_pointers[1] + (address & 0x7FFF);
1463 } 1482 }
1464 while (encoded != NULL) 1483 while (encoded != NULL)
1465 { 1484 {
1466 z80inst inst; 1485 z80inst inst;
1467 printf("translating Z80 code at address %X\n", address); 1486 dprintf("translating Z80 code at address %X\n", address);
1468 do { 1487 do {
1469 if (opts->code_end-opts->cur_code < ZMAX_NATIVE_SIZE) { 1488 if (opts->code_end-opts->cur_code < ZMAX_NATIVE_SIZE) {
1470 if (opts->code_end-opts->cur_code < 5) { 1489 if (opts->code_end-opts->cur_code < 5) {
1471 puts("out of code memory, not enough space for jmp to next chunk"); 1490 puts("out of code memory, not enough space for jmp to next chunk");
1472 exit(1); 1491 exit(1);
1485 if (existing) { 1504 if (existing) {
1486 opts->cur_code = jmp(opts->cur_code, existing); 1505 opts->cur_code = jmp(opts->cur_code, existing);
1487 break; 1506 break;
1488 } 1507 }
1489 next = z80_decode(encoded, &inst); 1508 next = z80_decode(encoded, &inst);
1509 #ifdef DO_DEBUG_PRINT
1490 z80_disasm(&inst, disbuf); 1510 z80_disasm(&inst, disbuf);
1491 if (inst.op == Z80_NOP) { 1511 if (inst.op == Z80_NOP) {
1492 printf("%X\t%s(%d)\n", address, disbuf, inst.immed); 1512 printf("%X\t%s(%d)\n", address, disbuf, inst.immed);
1493 } else { 1513 } else {
1494 printf("%X\t%s\n", address, disbuf); 1514 printf("%X\t%s\n", address, disbuf);
1495 } 1515 }
1516 #endif
1496 uint8_t *after = translate_z80inst(&inst, opts->cur_code, context, address); 1517 uint8_t *after = translate_z80inst(&inst, opts->cur_code, context, address);
1497 z80_map_native_address(context, address, opts->cur_code, next-encoded, after - opts->cur_code); 1518 z80_map_native_address(context, address, opts->cur_code, next-encoded, after - opts->cur_code);
1498 opts->cur_code = after; 1519 opts->cur_code = after;
1499 address += next-encoded; 1520 address += next-encoded;
1500 if (address > 0xFFFF) { 1521 if (address > 0xFFFF) {
1505 } 1526 }
1506 } while (!(inst.op == Z80_RET || inst.op == Z80_RETI || inst.op == Z80_RETN || inst.op == Z80_JP || (inst.op == Z80_NOP && inst.immed == 42))); 1527 } while (!(inst.op == Z80_RET || inst.op == Z80_RETI || inst.op == Z80_RETN || inst.op == Z80_JP || (inst.op == Z80_NOP && inst.immed == 42)));
1507 process_deferred(&opts->deferred, context, (native_addr_func)z80_get_native_address); 1528 process_deferred(&opts->deferred, context, (native_addr_func)z80_get_native_address);
1508 if (opts->deferred) { 1529 if (opts->deferred) {
1509 address = opts->deferred->address; 1530 address = opts->deferred->address;
1510 printf("defferred address: %X\n", address); 1531 dprintf("defferred address: %X\n", address);
1511 if (address < 0x4000) { 1532 if (address < 0x4000) {
1512 encoded = context->mem_pointers[0] + (address & 0x1FFF); 1533 encoded = context->mem_pointers[0] + (address & 0x1FFF);
1513 } else if (address > 0x8000 && context->mem_pointers[1]) { 1534 } else if (address > 0x8000 && context->mem_pointers[1]) {
1514 encoded = context->mem_pointers[1] + (address & 0x7FFF); 1535 encoded = context->mem_pointers[1] + (address & 0x7FFF);
1515 } else { 1536 } else {
1568 void z80_reset(z80_context * context) 1589 void z80_reset(z80_context * context)
1569 { 1590 {
1570 context->im = 0; 1591 context->im = 0;
1571 context->iff1 = context->iff2 = 0; 1592 context->iff1 = context->iff2 = 0;
1572 context->native_pc = z80_get_native_address_trans(context, 0); 1593 context->native_pc = z80_get_native_address_trans(context, 0);
1573 } 1594 context->extra_pc = NULL;
1574 1595 }
1575 1596
1597