changeset 284:ed7098f717d7

Implement IN and OUT (untested)
author Mike Pavone <pavone@retrodev.com>
date Sat, 04 May 2013 15:58:15 -0700
parents 61f5d88ea01a
children 021aeb6df19b
files z80_to_x86.c zruntime.S
diffstat 2 files changed, 53 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/z80_to_x86.c	Sat May 04 15:15:55 2013 -0700
+++ b/z80_to_x86.c	Sat May 04 15:58:15 2013 -0700
@@ -33,6 +33,8 @@
 void z80_do_sync();
 void z80_handle_cycle_limit_int();
 void z80_retrans_stub();
+void z80_io_read();
+void z80_io_write();
 
 uint8_t z80_size(z80inst * inst)
 {
@@ -1407,13 +1409,35 @@
 		dst = jmp(dst, call_dst);
 		break;
 	}
-	/*case Z80_IN:
-	case Z80_INI:
+	case Z80_IN:
+		dst = zcycles(dst, inst->reg == Z80_A ? 7 : 8);//T States: 4 3/4
+		if (inst->addr_mode == Z80_IMMED_INDIRECT) {
+			dst = mov_ir(dst, inst->immed, SCRATCH1, SZ_B);
+		} else {
+			dst = mov_rr(dst, opts->regs[Z80_C], SCRATCH1, SZ_B);
+		}
+		dst = call(dst, (uint8_t *)z80_io_read);
+		translate_z80_reg(inst, &dst_op, dst, opts);
+		dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_B);
+		dst = z80_save_reg(dst, inst, opts);
+		break;
+	/*case Z80_INI:
 	case Z80_INIR:
 	case Z80_IND:
-	case Z80_INDR:
+	case Z80_INDR:*/
 	case Z80_OUT:
-	case Z80_OUTI:
+		dst = zcycles(dst, inst->reg == Z80_A ? 7 : 8);//T States: 4 3/4
+		if ((inst->addr_mode & 0x1F) == Z80_IMMED_INDIRECT) {
+			dst = mov_ir(dst, inst->immed, SCRATCH2, SZ_B);
+		} else {
+			dst = mov_rr(dst, opts->regs[Z80_C], SCRATCH2, SZ_B);
+		}
+		translate_z80_reg(inst, &src_op, dst, opts);
+		dst = mov_rr(dst, dst_op.base, SCRATCH1, SZ_B);
+		dst = call(dst, (uint8_t *)z80_io_write);
+		dst = z80_save_reg(dst, inst, opts);
+		break;
+	/*case Z80_OUTI:
 	case Z80_OTIR:
 	case Z80_OUTD:
 	case Z80_OTDR:*/
--- a/zruntime.S	Sat May 04 15:15:55 2013 -0700
+++ b/zruntime.S	Sat May 04 15:58:15 2013 -0700
@@ -1,3 +1,14 @@
+z_inccycles_io:
+	cmp %edi, %ebp
+	jnb do_limit
+no_sync_io:
+	add $4, %ebp
+	ret
+do_limit_io:
+	cmp 112(%rsi), %ebp
+	jb no_sync_io
+	jmp sync_io
+
 z_inccycles:
 	cmp %edi, %ebp
 	jnb do_limit
@@ -7,6 +18,7 @@
 do_limit:
 	cmp 112(%rsi), %ebp
 	jb no_sync
+sync_io:
 	call z80_save_context_scratch
 	pop %rax /*return address in read/write func*/
 	pop 104(%rsi) /*return address in native code*/
@@ -180,6 +192,19 @@
 	call z_inccycles
 	call z80_write_byte_noinc
 	ret
+
+	.global z80_io_read
+z80_io_read:
+	call z_inccycles_io
+	/* genesis Z80 has no IO port hardware and always returns FF */
+	mov $0xFF, %r13
+	ret
+
+	.global z80_io_write
+z80_io_write:
+	call z_inccycles_io
+	/* genesis Z80 has no IO port hardware and writes have no effect */
+	ret
 	
 	.global z80_retrans_stub
 z80_retrans_stub: