Found few things not right in 8080/8085 implementation.
 
1. ANA/ANI instruction, HF flag was not set right because error in calculation of it (missing brackets)
2. 8080 have NF flag always set (it is not used flag but bit is always set)
3. On unused ports/not connected memory values from status word were readed not 00 or FF, that is why I add it as a new internal register, it can also be buffered by some external hardware, so this could help other implementations too.
 
Regards,
Miodrag Milanovic
This commit is contained in:
Aaron Giles 2008-09-11 15:10:41 +00:00
parent c48c851c8d
commit 746ab44148
3 changed files with 29 additions and 8 deletions

View File

@ -146,6 +146,7 @@ typedef struct {
UINT32 INTR; /* vector for INTR */
UINT32 IRQ2; /* scheduled interrupt address */
UINT32 IRQ1; /* executed interrupt address */
UINT8 STATUS; /* status word */
INT8 irq_state[4];
int (*irq_callback)(int);
void (*sod_callback)(int state);
@ -160,6 +161,7 @@ static UINT8 ZSP[256];
static UINT8 RIM_IEN = 0; //AT: IEN status latch used by the RIM instruction
static UINT8 ROP(void)
{
I.STATUS = 0xa2; // instruction fetch
return cpu_readop(I.PC.w.l++);
}
@ -180,11 +182,13 @@ static UINT16 ARG16(void)
static UINT8 RM(UINT32 a)
{
I.STATUS = 0x82; // memory read
return program_read_byte_8le(a);
}
static void WM(UINT32 a, UINT8 v)
{
I.STATUS = 0x00; // memory write
program_write_byte_8le(a, v);
}
@ -684,6 +688,7 @@ INLINE void execute_one(int opcode)
case 0x76: i8085_ICount -= (I.cputype) ? 5 : 7; /* HLT */
I.PC.w.l--;
I.HALT = 1;
I.STATUS = 0x8a; // halt acknowledge
if (i8085_ICount > 0) i8085_ICount = 0;
break;
case 0x77: i8085_ICount -= 7; /* MOV M,A */
@ -1216,6 +1221,10 @@ INLINE void execute_one(int opcode)
M_RST(7);
break;
}
/* For 8080 NF flag is not used but bit is always set */
if(!I.cputype ) {
I.AF.b.l = I.AF.b.l | NF;
}
}
static void Interrupt(void)
@ -1225,6 +1234,9 @@ static void Interrupt(void)
{
I.PC.w.l++; /* skip HALT instr */
I.HALT = 0;
I.STATUS = 0x26; // int ack while halt
} else {
I.STATUS = 0x23; // int ack
}
//AT
I.IREQ &= ~I.ISRV; // remove serviced IRQ flag
@ -1367,6 +1379,7 @@ static void i8085_init(int index, int clock, const void *config, int (*irqcallba
state_save_register_item("i8085", index, I.INTR);
state_save_register_item("i8085", index, I.IRQ2);
state_save_register_item("i8085", index, I.IRQ1);
state_save_register_item("i8085", index, I.STATUS);
state_save_register_item_array("i8085", index, I.irq_state);
}
@ -1601,6 +1614,7 @@ static void i8080_init(int index, int clock, const void *config, int (*irqcallba
state_save_register_item("i8080", index, I.INTR);
state_save_register_item("i8080", index, I.IRQ2);
state_save_register_item("i8080", index, I.IRQ1);
state_save_register_item("i8080", index, I.STATUS);
state_save_register_item_array("i8080", index, I.irq_state);
}
@ -1657,6 +1671,7 @@ static void i8085_set_info(UINT32 state, cpuinfo *info)
case CPUINFO_INT_REGISTER + I8085_IREQ: I.IREQ = info->i; break;
case CPUINFO_INT_REGISTER + I8085_ISRV: I.ISRV = info->i; break;
case CPUINFO_INT_REGISTER + I8085_VECTOR: I.INTR = info->i; break;
case CPUINFO_INT_REGISTER + I8085_STATUS: I.STATUS = info->i; break;
case CPUINFO_INT_I8085_SID: if (info->i) I.IM |= IM_SID; else I.IM &= ~IM_SID; break;
@ -1719,6 +1734,7 @@ void i8085_get_info(UINT32 state, cpuinfo *info)
case CPUINFO_INT_REGISTER + I8085_IREQ: info->i = I.IREQ; break;
case CPUINFO_INT_REGISTER + I8085_ISRV: info->i = I.ISRV; break;
case CPUINFO_INT_REGISTER + I8085_VECTOR: info->i = I.INTR; break;
case CPUINFO_INT_REGISTER + I8085_STATUS: info->i = I.STATUS; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case CPUINFO_PTR_SET_INFO: info->setinfo = i8085_set_info; break;
@ -1762,6 +1778,7 @@ void i8085_get_info(UINT32 state, cpuinfo *info)
case CPUINFO_STR_REGISTER + I8085_IREQ: sprintf(info->s, "IREQ:%02X", I.IREQ); break;
case CPUINFO_STR_REGISTER + I8085_ISRV: sprintf(info->s, "ISRV:%02X", I.ISRV); break;
case CPUINFO_STR_REGISTER + I8085_VECTOR: sprintf(info->s, "VEC:%02X", I.INTR); break;
case CPUINFO_STR_REGISTER + I8085_STATUS: sprintf(info->s, "SW:%02X", I.STATUS); break;
}
}

View File

@ -8,7 +8,7 @@ enum
I8085_PC=1, I8085_SP, I8085_AF ,I8085_BC, I8085_DE, I8085_HL,
I8085_HALT, I8085_IM, I8085_IREQ, I8085_ISRV, I8085_VECTOR,
I8085_TRAP_STATE, I8085_INTR_STATE,
I8085_RST55_STATE, I8085_RST65_STATE, I8085_RST75_STATE
I8085_RST55_STATE, I8085_RST65_STATE, I8085_RST75_STATE, I8085_STATUS
};
enum
@ -41,11 +41,11 @@ void i8085_get_info(UINT32 state, cpuinfo *info);
#define I8080_VECTOR I8085_VECTOR
#define I8080_TRAP_STATE I8085_TRAP_STATE
#define I8080_INTR_STATE I8085_INTR_STATE
#define I8080_STATUS I8085_STATUS
#define I8080_REG_LAYOUT \
{ CPU_8080, \
I8080_AF,I8080_BC,I8080_DE,I8080_HL,I8080_SP,I8080_PC, DBG_ROW, \
I8080_HALT,I8080_IREQ,I8080_ISRV,I8080_VECTOR, \
I8080_HALT,I8080_IREQ,I8080_ISRV,I8080_VECTOR, I8080_STATUS, \
DBG_END }
#define I8080_INTR_LINE I8085_INTR_LINE

View File

@ -41,7 +41,7 @@
#define M_DCR(R) {UINT8 hc = ((R & 0x0f) == 0x00) ? HF : 0; --R; I.AF.b.l= (I.AF.b.l & CF ) | ZSP[R] | hc | NF; }
#define M_MVI(R) R=ARG()
#define M_ANA(R) { int i = ((I.AF.b.h | R)>>3)&1 * HF; I.AF.b.h&=R; I.AF.b.l=ZSP[I.AF.b.h]; if( I.cputype ) { I.AF.b.l |= HF; } else {I.AF.b.l |= i; } }
#define M_ANA(R) { int i = (((I.AF.b.h | R)>>3) & 1)*HF; I.AF.b.h&=R; I.AF.b.l=ZSP[I.AF.b.h]; if( I.cputype ) { I.AF.b.l |= HF; } else {I.AF.b.l |= i; } }
#define M_ORA(R) I.AF.b.h|=R; I.AF.b.l=ZSP[I.AF.b.h]
#define M_XRA(R) I.AF.b.h^=R; I.AF.b.l=ZSP[I.AF.b.h]
@ -107,10 +107,12 @@ int q = I.AF.b.h+R; \
}
#define M_IN \
I.STATUS = 0x42; \
I.XX.d=ARG(); \
I.AF.b.h=io_read_byte_8le(I.XX.d);
#define M_OUT \
I.STATUS = 0x10; \
I.XX.d=ARG(); \
io_write_byte_8le(I.XX.d,I.AF.b.h)
@ -123,13 +125,15 @@ int q = I.AF.b.h+R; \
}
#define M_PUSH(R) { \
WM(--I.SP.w.l, I.R.b.h); \
WM(--I.SP.w.l, I.R.b.l); \
I.STATUS = 0x04; \
program_write_byte_8le(--I.SP.w.l, I.R.b.h); \
program_write_byte_8le(--I.SP.w.l, I.R.b.l); \
}
#define M_POP(R) { \
I.R.b.l = RM(I.SP.w.l++); \
I.R.b.h = RM(I.SP.w.l++); \
I.STATUS = 0x86; \
I.R.b.l = program_read_byte_8le(I.SP.w.l++); \
I.R.b.h = program_read_byte_8le(I.SP.w.l++); \
}
#define M_RET(cc) \