mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
Hello,
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:
parent
c48c851c8d
commit
746ab44148
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) \
|
||||
|
Loading…
Reference in New Issue
Block a user