summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2013-10-27 08:50:53 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2013-10-27 08:50:53 (GMT)
commit3add6c43f43a93c0068727291f076e8d61cff70a (patch)
treecf765c2abddbfba514ea47236c061ee5bb0c262e
parent294d13f41d0e3953fd1a8cd91d4401fbb30427e6 (diff)
downloadabc80sim-3add6c43f43a93c0068727291f076e8d61cff70a.zip
abc80sim-3add6c43f43a93c0068727291f076e8d61cff70a.tar.gz
abc80sim-3add6c43f43a93c0068727291f076e8d61cff70a.tar.bz2
abc80sim-3add6c43f43a93c0068727291f076e8d61cff70a.tar.xz
z80: Implement the R register
Implement the R register. This should be correct except possibly the interrupt behavior. Still better than just returning random contents. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--z80.c37
-rw-r--r--z80.h3
2 files changed, 13 insertions, 27 deletions
diff --git a/z80.c b/z80.c
index 47531d6..bcf999d 100644
--- a/z80.c
+++ b/z80.c
@@ -916,7 +916,7 @@ static void do_lddr(void)
REG_F &= ~(HALF_CARRY_MASK | OVERFLOW_MASK | SUBTRACT_MASK);
}
-static void do_ld_a_i(void)
+static void do_ld_a_ir(uint8_t val)
{
uint8_t clear, set;
@@ -924,29 +924,7 @@ static void do_ld_a_i(void)
SUBTRACT_MASK;
set = 0;
- REG_A = REG_I;
-
- if(REG_A & 0x80)
- set |= SIGN_MASK;
- if(REG_A == 0)
- set |= ZERO_MASK;
-
- if(z80_state.iff2)
- set |= OVERFLOW_MASK;
-
- REG_F = (REG_F & ~clear) | set;
-}
-
-static void do_ld_a_r(void)
-{
- uint8_t clear, set;
-
- clear = SIGN_MASK | ZERO_MASK | HALF_CARRY_MASK | OVERFLOW_MASK |
- SUBTRACT_MASK;
- set = 0;
-
- /* Fetch a random value. */
- REG_A = (rand() >> 8) & 0xFF;
+ REG_A = val;
if(REG_A & 0x80)
set |= SIGN_MASK;
@@ -1373,6 +1351,7 @@ static void do_CB_instruction(wordregister *ix)
*/
instruction = mem_read(REG_PC++);
+ REG_R++;
switch(instruction)
{
@@ -2168,6 +2147,7 @@ static void do_CB_instruction(wordregister *ix)
addr = ix->word + (int8_t)mem_read(REG_PC++);
instruction = mem_read(REG_PC++);
+ REG_R++;
data = mem_read(addr);
@@ -2270,6 +2250,7 @@ static void do_ED_instruction(wordregister *ix)
*/
instruction = mem_read(REG_PC++);
+ REG_R++;
switch(instruction)
{
@@ -2351,14 +2332,17 @@ static void do_ED_instruction(wordregister *ix)
break;
case 0x57: /* ld a, i */
- do_ld_a_i();
+ do_ld_a_ir(REG_I);
break;
case 0x47: /* ld i, a */
REG_I = REG_A;
break;
case 0x5F: /* ld a, r */
- do_ld_a_r();
+ do_ld_a_ir(REG_R & 0x7f); /* The real R register is only 7 bits */
+ break;
+ case 0x4F: /* ld r, a */
+ REG_R = REG_A;
break;
case 0x4B: /* ld bc, (address) */
@@ -2557,6 +2541,7 @@ int z80_run(int continuous)
indexed:
instruction = mem_read(REG_PC++);
+ REG_R++;
switch(instruction)
{
diff --git a/z80.h b/z80.h
index c273549..4056f92 100644
--- a/z80.h
+++ b/z80.h
@@ -57,7 +57,7 @@ struct z80_state_struct
wordregister hl_prime;
uint8_t i; /* interrupt-page address register */
- /* uint8_t r; */ /* no memory-refresh register, just fetch random values */
+ uint8_t r; /* memory-refresh register */
uint8_t iff1, iff2;
uint8_t interrupt_mode;
@@ -106,6 +106,7 @@ struct z80_state_struct
#define REG_IY (z80_state.iy.word)
#define REG_I (z80_state.i)
+#define REG_R (z80_state.r)
/*
* Flag accessors: