Updated LH5801 CPU core [Sandro Ronco]

- Added IO_SPACE and updated all access in ME1 memory for use it.
- Implemented interrupts.
- Fixed the flags in the ROL/ROR/SHL/SHR opcodes.
- Fixed decimal add/sub opcodes.
This commit is contained in:
Miodrag Milanovic 2011-02-19 10:02:31 +00:00
parent bbf581c5f2
commit 943251771c
3 changed files with 227 additions and 140 deletions

View File

@ -35,10 +35,10 @@ INLINE void lh5801_adc(lh5801_state *cpustate, UINT8 data)
cpustate->a=lh5801_add_generic(cpustate,cpustate->a,data,cpustate->t&C);
}
INLINE void lh5801_add_mem(lh5801_state *cpustate, int addr, UINT8 data)
INLINE void lh5801_add_mem(lh5801_state *cpustate, address_space *space, int addr, UINT8 data)
{
int v=lh5801_add_generic(cpustate,cpustate->program->read_byte(addr),data,0);
cpustate->program->write_byte(addr,v);
int v=lh5801_add_generic(cpustate, space->read_byte(addr),data,0);
space->write_byte(addr,v);
}
INLINE void lh5801_adr(lh5801_state *cpustate, PAIR *reg)
@ -51,7 +51,7 @@ INLINE void lh5801_adr(lh5801_state *cpustate, PAIR *reg)
INLINE void lh5801_sbc(lh5801_state *cpustate, UINT8 data)
{
cpustate->a=lh5801_add_generic(cpustate,cpustate->a,data^0xff,(cpustate->t&C)^1);
cpustate->a=lh5801_add_generic(cpustate,cpustate->a,data^0xff,cpustate->t&C);
}
INLINE void lh5801_cpa(lh5801_state *cpustate, UINT8 a, UINT8 b)
@ -61,31 +61,31 @@ INLINE void lh5801_cpa(lh5801_state *cpustate, UINT8 a, UINT8 b)
INLINE UINT8 lh5801_decimaladd_generic(lh5801_state *cpustate, int left, int right, int carry)
{
int res=(left&0xf)+(right&0xf)+carry;
cpustate->t&=~(H|V|Z|C);
int res=lh5801_add_generic(cpustate, left, right, carry);
UINT8 da;
if (res>=10) {
res+=6;
cpustate->t|=H;
}
res+=(left&0xf0)+(right&0xf0);
if (res>=0xa0) {
res+=0x60;
cpustate->t|=C;
}
if (!(res&0xff)) cpustate->t|=Z;
//v???
return res;
//DA values taken from official documentation
if (!(cpustate->t&C) && !(cpustate->t&H))
da = 0x9a;
else if (!(cpustate->t&C) && (cpustate->t&H))
da = 0xa0;
else if ((cpustate->t&C) && !(cpustate->t&H))
da = 0xfa;
else //if ((cpustate->t&C) && (cpustate->t&H))
da = 0x00;
return res + da;
}
INLINE void lh5801_dca(lh5801_state *cpustate, UINT8 data)
{
cpustate->a += 0x66; //taken from official documentation
cpustate->a=lh5801_decimaladd_generic(cpustate, cpustate->a, data, cpustate->t&C);
}
INLINE void lh5801_dcs(lh5801_state *cpustate, UINT8 data)
{
cpustate->a=lh5801_decimaladd_generic(cpustate, cpustate->a, data^0xff, (cpustate->t&C)^1);
cpustate->a=lh5801_decimaladd_generic(cpustate, cpustate->a, data^0xff, cpustate->t&C);
}
INLINE void lh5801_and(lh5801_state *cpustate, UINT8 data)
@ -95,12 +95,12 @@ INLINE void lh5801_and(lh5801_state *cpustate, UINT8 data)
if (!cpustate->a) cpustate->t|=Z;
}
INLINE void lh5801_and_mem(lh5801_state *cpustate, int addr, UINT8 data)
INLINE void lh5801_and_mem(lh5801_state *cpustate, address_space *space, int addr, UINT8 data)
{
data&=cpustate->program->read_byte(addr);
data&=space->read_byte(addr);
cpustate->t&=~Z;
if (!data) cpustate->t|=Z;
cpustate->program->write_byte(addr,data);
space->write_byte(addr,data);
}
INLINE void lh5801_bit(lh5801_state *cpustate, UINT8 a, UINT8 b)
@ -118,17 +118,17 @@ INLINE void lh5801_eor(lh5801_state *cpustate, UINT8 data)
INLINE void lh5801_ora(lh5801_state *cpustate, UINT8 data)
{
cpustate->a^=data;
cpustate->a|=data;
cpustate->t&=~Z;
if (!cpustate->a) cpustate->t|=Z;
}
INLINE void lh5801_ora_mem(lh5801_state *cpustate, int addr, UINT8 data)
INLINE void lh5801_ora_mem(lh5801_state *cpustate, address_space *space, int addr, UINT8 data)
{
data|=cpustate->program->read_byte(addr);
data|=space->read_byte(addr);
cpustate->t&=~Z;
if (!data) cpustate->t|=Z;
cpustate->program->write_byte(addr,data);
space->write_byte(addr,data);
}
INLINE void lh5801_lda(lh5801_state *cpustate, UINT8 data)
@ -270,61 +270,69 @@ INLINE void lh5801_aex(lh5801_state *cpustate)
// flags?
}
INLINE void lh5801_drl(lh5801_state *cpustate, int adr)
INLINE void lh5801_drl(lh5801_state *cpustate, address_space *space, int adr)
{
UINT16 t=cpustate->a|(cpustate->program->read_byte(adr)<<8);
UINT16 t=cpustate->a|(space->read_byte(adr)<<8);
cpustate->a=t>>8;
cpustate->program->write_byte(adr,t>>4);
space->write_byte(adr,t>>4);
}
INLINE void lh5801_drr(lh5801_state *cpustate, int adr)
INLINE void lh5801_drr(lh5801_state *cpustate, address_space *space, int adr)
{
UINT16 t=cpustate->program->read_byte(adr)|(cpustate->a<<8);
UINT16 t=space->read_byte(adr)|(cpustate->a<<8);
cpustate->a=t;
cpustate->program->write_byte(adr,t>>4);
space->write_byte(adr,t>>4);
}
INLINE void lh5801_rol(lh5801_state *cpustate)
{
// maybe use of the adder
int n=(cpustate->a<<1)|(cpustate->t&C);
cpustate->a=n;
int n = cpustate->a;
cpustate->a = (n<<1) | (cpustate->t&C);
// flags cvhz
cpustate->t&=~(C&Z);
if (n&0x100) cpustate->t|=C;
if (!(n&0xff)) cpustate->t|=Z;
cpustate->t&=~(H|V|Z|C);
if (n&0x80) cpustate->t|=C;
if (!cpustate->a) cpustate->t|=Z;
if (cpustate->a & 0x10) cpustate->t|=H;
if ((BIT(n,6) && !BIT(n,7)) || (!BIT(n,6) && BIT(n,7))) cpustate->t|=V;
}
INLINE void lh5801_ror(lh5801_state *cpustate)
{
int n=cpustate->a|((cpustate->t&C)<<8);
cpustate->a=n>>1;
int n = cpustate->a;
cpustate->a=(n | ((cpustate->t&C)<<8))>>1;
// flags cvhz
cpustate->t&=~(C&Z);
cpustate->t|=(n&C);
if (!(n&0x1fe)) cpustate->t|=Z;
cpustate->t&=~(H|V|Z|C);
if (n&0x01) cpustate->t|=C;
if (!cpustate->a) cpustate->t|=Z;
if (cpustate->a & 0x08) cpustate->t|=H;
if ((BIT(n,0) && BIT(cpustate->a,1)) || (BIT(cpustate->a,0) && BIT(n,1))) cpustate->t|=V;
}
INLINE void lh5801_shl(lh5801_state *cpustate)
{
int nc=cpustate->a&0x80;
int n = cpustate->a;
cpustate->a<<=1;
// flags cvhz
cpustate->t&=~(C&Z);
if (nc) cpustate->t|=C;
cpustate->t&=~(H|V|Z|C);
if (n&0x80) cpustate->t|=C;
if (!cpustate->a) cpustate->t|=Z;
if (cpustate->a & 0x10) cpustate->t|=H;
if ((BIT(n,6) && !BIT(n,7)) || (!BIT(n,6) && BIT(n,7))) cpustate->t|=V;
}
INLINE void lh5801_shr(lh5801_state *cpustate)
{
int nc=cpustate->a&1;
int n = cpustate->a;
cpustate->a>>=1;
// flags cvhz
cpustate->t&=~(C|Z);
if (nc) cpustate->t|=C;
cpustate->t&=~(H|V|Z|C);
if (n & 0x01) cpustate->t|=C;
if (!cpustate->a) cpustate->t|=Z;
if (cpustate->a & 0x08) cpustate->t|=H;
if ((BIT(n,0) && BIT(cpustate->a,1)) || (BIT(cpustate->a,0) && BIT(n,1))) cpustate->t|=V;
}
INLINE void lh5801_am(lh5801_state *cpustate, int value)
@ -351,87 +359,87 @@ static void lh5801_instruction_fd(lh5801_state *cpustate)
oper=cpustate->direct->read_decrypted_byte(P++);
switch (oper) {
case 0x01: lh5801_sbc(cpustate,cpustate->program->read_byte(0x10000|X)); cpustate->icount-=11;break;
case 0x03: lh5801_adc(cpustate,cpustate->program->read_byte(0x10000|X)); cpustate->icount-=11;break;
case 0x05: lh5801_lda(cpustate,cpustate->program->read_byte(0x10000|X)); cpustate->icount-=10;break;
case 0x07: lh5801_cpa(cpustate,cpustate->a, cpustate->program->read_byte(0x10000|X)); cpustate->icount-=11;break;
case 0x01: lh5801_sbc(cpustate,cpustate->io->read_byte(X)); cpustate->icount-=11;break;
case 0x03: lh5801_adc(cpustate,cpustate->io->read_byte(X)); cpustate->icount-=11;break;
case 0x05: lh5801_lda(cpustate,cpustate->io->read_byte(X)); cpustate->icount-=10;break;
case 0x07: lh5801_cpa(cpustate,cpustate->a, cpustate->io->read_byte(X)); cpustate->icount-=11;break;
case 0x08: X=X;cpustate->icount-=11;break; //!!!
case 0x09: lh5801_and(cpustate,cpustate->program->read_byte(0x10000|X)); cpustate->icount-=11;break;
case 0x09: lh5801_and(cpustate,cpustate->io->read_byte(X)); cpustate->icount-=11;break;
case 0x0a: lh5801_pop_word(cpustate,&cpustate->x); cpustate->icount-=15;break;
case 0x0b: lh5801_ora(cpustate,cpustate->program->read_byte(0x10000|X)); cpustate->icount-=11;break;
case 0x0c: lh5801_dcs(cpustate,cpustate->program->read_byte(0x10000|X)); cpustate->icount-=17; break;
case 0x0d: lh5801_eor(cpustate,cpustate->program->read_byte(0x10000|X)); cpustate->icount-=11;break;
case 0x0e: cpustate->program->write_byte(0x10000|X,cpustate->a); cpustate->icount-=10;break;
case 0x0f: lh5801_bit(cpustate,cpustate->program->read_byte(0x10000|X),cpustate->a); cpustate->icount-=11;break;
case 0x11: lh5801_sbc(cpustate,cpustate->program->read_byte(0x10000|Y)); cpustate->icount-=11;break;
case 0x13: lh5801_adc(cpustate,cpustate->program->read_byte(0x10000|Y)); cpustate->icount-=11;break;
case 0x15: lh5801_lda(cpustate,cpustate->program->read_byte(0x10000|Y)); cpustate->icount-=10;break;
case 0x17: lh5801_cpa(cpustate,cpustate->a, cpustate->program->read_byte(0x10000|Y)); cpustate->icount-=11;break;
case 0x0b: lh5801_ora(cpustate,cpustate->io->read_byte(X)); cpustate->icount-=11;break;
case 0x0c: lh5801_dcs(cpustate,cpustate->io->read_byte(X)); cpustate->icount-=17; break;
case 0x0d: lh5801_eor(cpustate,cpustate->io->read_byte(X)); cpustate->icount-=11;break;
case 0x0e: cpustate->io->write_byte(X,cpustate->a); cpustate->icount-=10;break;
case 0x0f: lh5801_bit(cpustate,cpustate->io->read_byte(X),cpustate->a); cpustate->icount-=11;break;
case 0x11: lh5801_sbc(cpustate,cpustate->io->read_byte(Y)); cpustate->icount-=11;break;
case 0x13: lh5801_adc(cpustate,cpustate->io->read_byte(Y)); cpustate->icount-=11;break;
case 0x15: lh5801_lda(cpustate,cpustate->io->read_byte(Y)); cpustate->icount-=10;break;
case 0x17: lh5801_cpa(cpustate,cpustate->a, cpustate->io->read_byte(Y)); cpustate->icount-=11;break;
case 0x18: X=Y;cpustate->icount-=11;break;
case 0x19: lh5801_and(cpustate,cpustate->program->read_byte(0x10000|Y)); cpustate->icount-=11;break;
case 0x19: lh5801_and(cpustate,cpustate->io->read_byte(Y)); cpustate->icount-=11;break;
case 0x1a: lh5801_pop_word(cpustate,&cpustate->y); cpustate->icount-=15;break;
case 0x1b: lh5801_ora(cpustate,cpustate->program->read_byte(0x10000|Y)); cpustate->icount-=11;break;
case 0x1c: lh5801_dcs(cpustate,cpustate->program->read_byte(0x10000|Y)); cpustate->icount-=17; break;
case 0x1d: lh5801_eor(cpustate,cpustate->program->read_byte(0x10000|Y)); cpustate->icount-=11;break;
case 0x1e: cpustate->program->write_byte(0x10000|Y,cpustate->a); cpustate->icount-=10;break;
case 0x1f: lh5801_bit(cpustate,cpustate->program->read_byte(0x10000|Y),cpustate->a); cpustate->icount-=11;break;
case 0x21: lh5801_sbc(cpustate,cpustate->program->read_byte(0x10000|U)); cpustate->icount-=11;break;
case 0x23: lh5801_adc(cpustate,cpustate->program->read_byte(0x10000|U)); cpustate->icount-=11;break;
case 0x25: lh5801_lda(cpustate,cpustate->program->read_byte(0x10000|U)); cpustate->icount-=10;break;
case 0x27: lh5801_cpa(cpustate,cpustate->a, cpustate->program->read_byte(0x10000|U)); cpustate->icount-=11;break;
case 0x1b: lh5801_ora(cpustate,cpustate->io->read_byte(Y)); cpustate->icount-=11;break;
case 0x1c: lh5801_dcs(cpustate,cpustate->io->read_byte(Y)); cpustate->icount-=17; break;
case 0x1d: lh5801_eor(cpustate,cpustate->io->read_byte(Y)); cpustate->icount-=11;break;
case 0x1e: cpustate->io->write_byte(Y,cpustate->a); cpustate->icount-=10;break;
case 0x1f: lh5801_bit(cpustate,cpustate->io->read_byte(Y),cpustate->a); cpustate->icount-=11;break;
case 0x21: lh5801_sbc(cpustate,cpustate->io->read_byte(U)); cpustate->icount-=11;break;
case 0x23: lh5801_adc(cpustate,cpustate->io->read_byte(U)); cpustate->icount-=11;break;
case 0x25: lh5801_lda(cpustate,cpustate->io->read_byte(U)); cpustate->icount-=10;break;
case 0x27: lh5801_cpa(cpustate,cpustate->a, cpustate->io->read_byte(U)); cpustate->icount-=11;break;
case 0x28: X=U;cpustate->icount-=11;break;
case 0x29: lh5801_and(cpustate,cpustate->program->read_byte(0x10000|U)); cpustate->icount-=11;break;
case 0x29: lh5801_and(cpustate,cpustate->io->read_byte(U)); cpustate->icount-=11;break;
case 0x2a: lh5801_pop_word(cpustate,&cpustate->u); cpustate->icount-=15;break;
case 0x2b: lh5801_ora(cpustate,cpustate->program->read_byte(0x10000|U)); cpustate->icount-=11;break;
case 0x2c: lh5801_dcs(cpustate,cpustate->program->read_byte(0x10000|U)); cpustate->icount-=17; break;
case 0x2d: lh5801_eor(cpustate,cpustate->program->read_byte(0x10000|U)); cpustate->icount-=11;break;
case 0x2e: cpustate->program->write_byte(0x10000|U,cpustate->a); cpustate->icount-=10;break;
case 0x2f: lh5801_bit(cpustate,cpustate->program->read_byte(0x10000|U),cpustate->a); cpustate->icount-=11;break;
case 0x2b: lh5801_ora(cpustate,cpustate->io->read_byte(U)); cpustate->icount-=11;break;
case 0x2c: lh5801_dcs(cpustate,cpustate->io->read_byte(U)); cpustate->icount-=17; break;
case 0x2d: lh5801_eor(cpustate,cpustate->io->read_byte(U)); cpustate->icount-=11;break;
case 0x2e: cpustate->io->write_byte(U,cpustate->a); cpustate->icount-=10;break;
case 0x2f: lh5801_bit(cpustate,cpustate->io->read_byte(U),cpustate->a); cpustate->icount-=11;break;
case 0x40: lh5801_inc(cpustate,&XH);cpustate->icount-=9;break;
case 0x42: lh5801_dec(cpustate,&XH);cpustate->icount-=9;break;
case 0x48: X=S;cpustate->icount-=11;break;
case 0x49: lh5801_and_mem(cpustate,0x10000|X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x49: lh5801_and_mem(cpustate, cpustate->io, X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x4a: X=X;cpustate->icount-=11;break; //!!!
case 0x4b: lh5801_ora_mem(cpustate,0x10000|X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x4b: lh5801_ora_mem(cpustate, cpustate->io, X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x4c: cpustate->bf=0;/*off !*/ cpustate->icount-=8;break;
case 0x4d: lh5801_bit(cpustate,cpustate->program->read_byte(X|0x10000), cpustate->direct->read_decrypted_byte(P++));cpustate->icount-=14;break;
case 0x4d: lh5801_bit(cpustate,cpustate->io->read_byte(X), cpustate->direct->read_decrypted_byte(P++));cpustate->icount-=14;break;
case 0x4e: S=X;cpustate->icount-=11;break;
case 0x4f: lh5801_add_mem(cpustate,0x10000|X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x4f: lh5801_add_mem(cpustate, cpustate->io, X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x50: lh5801_inc(cpustate,&YH);cpustate->icount-=9;break;
case 0x52: lh5801_dec(cpustate,&YH);cpustate->icount-=9;break;
case 0x58: X=P;cpustate->icount-=11;break;
case 0x59: lh5801_and_mem(cpustate,0x10000|Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x59: lh5801_and_mem(cpustate, cpustate->io, Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x5a: Y=X;cpustate->icount-=11;break;
case 0x5b: lh5801_ora_mem(cpustate,0x10000|Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x5d: lh5801_bit(cpustate,cpustate->program->read_byte(Y|0x10000), cpustate->direct->read_decrypted_byte(P++));cpustate->icount-=14;break;
case 0x5b: lh5801_ora_mem(cpustate, cpustate->io, Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x5d: lh5801_bit(cpustate,cpustate->io->read_byte(Y), cpustate->direct->read_decrypted_byte(P++));cpustate->icount-=14;break;
case 0x5e: lh5801_jmp(cpustate,X);cpustate->icount-=11;break; // P=X
case 0x5f: lh5801_add_mem(cpustate,0x10000|Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x5f: lh5801_add_mem(cpustate, cpustate->io, Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x60: lh5801_inc(cpustate,&UH);cpustate->icount-=9;break;
case 0x62: lh5801_dec(cpustate,&UH);cpustate->icount-=9;break;
case 0x69: lh5801_and_mem(cpustate,0x10000|U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x69: lh5801_and_mem(cpustate, cpustate->io, U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x6a: U=X;cpustate->icount-=11;break;
case 0x6b: lh5801_ora_mem(cpustate,0x10000|U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x6d: lh5801_bit(cpustate,cpustate->program->read_byte(X|0x10000), cpustate->direct->read_decrypted_byte(P++));cpustate->icount-=14;break;
case 0x6f: lh5801_add_mem(cpustate,0x10000|U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x6b: lh5801_ora_mem(cpustate, cpustate->io, U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x6d: lh5801_bit(cpustate,cpustate->io->read_byte(X), cpustate->direct->read_decrypted_byte(P++));cpustate->icount-=14;break;
case 0x6f: lh5801_add_mem(cpustate, cpustate->io, U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=17;break;
case 0x81: cpustate->t|=IE; /*sie !*/cpustate->icount-=8;break;
case 0x88: lh5801_push_word(cpustate,X); cpustate->icount-=14;break;
case 0x8a: lh5801_pop(cpustate); cpustate->icount-=12; break;
case 0x8c: lh5801_dca(cpustate,cpustate->program->read_byte(0x10000|X)); cpustate->icount-=19; break;
case 0x8c: lh5801_dca(cpustate,cpustate->io->read_byte(X)); cpustate->icount-=19; break;
case 0x8e: /*cdv clears internal devider*/cpustate->icount-=8;break;
case 0x98: lh5801_push_word(cpustate,Y); cpustate->icount-=14;break;
case 0x9c: lh5801_dca(cpustate,cpustate->program->read_byte(0x10000|Y)); cpustate->icount-=19; break;
case 0xa1: lh5801_sbc(cpustate,cpustate->program->read_byte(0x10000|lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0xa3: lh5801_adc(cpustate,cpustate->program->read_byte(0x10000|lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0xa5: lh5801_lda(cpustate,cpustate->program->read_byte(0x10000|lh5801_readop_word(cpustate))); cpustate->icount-=16;break;
case 0xa7: lh5801_cpa(cpustate,cpustate->a, cpustate->program->read_byte(0x10000|lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0x9c: lh5801_dca(cpustate,cpustate->io->read_byte(Y)); cpustate->icount-=19; break;
case 0xa1: lh5801_sbc(cpustate,cpustate->io->read_byte(lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0xa3: lh5801_adc(cpustate,cpustate->io->read_byte(lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0xa5: lh5801_lda(cpustate,cpustate->io->read_byte(lh5801_readop_word(cpustate))); cpustate->icount-=16;break;
case 0xa7: lh5801_cpa(cpustate,cpustate->a, cpustate->io->read_byte(lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0xa8: lh5801_push_word(cpustate,U); cpustate->icount-=14;break;
case 0xa9: lh5801_and(cpustate,cpustate->program->read_byte(0x10000|lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0xa9: lh5801_and(cpustate,cpustate->io->read_byte(lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0xaa: lh5801_lda(cpustate,cpustate->t); cpustate->icount-=9;break;
case 0xab: lh5801_ora(cpustate,cpustate->program->read_byte(0x10000|lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0xac: lh5801_dca(cpustate,cpustate->program->read_byte(0x10000|U)); cpustate->icount-=19; break;
case 0xad: lh5801_eor(cpustate,cpustate->program->read_byte(0x10000|lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0xae: cpustate->program->write_byte(0x10000|lh5801_readop_word(cpustate),cpustate->a); cpustate->icount-=16;break;
case 0xaf: lh5801_bit(cpustate,cpustate->program->read_byte(0x10000|lh5801_readop_word(cpustate)),cpustate->a); cpustate->icount-=17;break;
case 0xab: lh5801_ora(cpustate,cpustate->io->read_byte(lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0xac: lh5801_dca(cpustate,cpustate->io->read_byte(U)); cpustate->icount-=19; break;
case 0xad: lh5801_eor(cpustate,cpustate->io->read_byte(lh5801_readop_word(cpustate))); cpustate->icount-=17;break;
case 0xae: cpustate->io->write_byte(lh5801_readop_word(cpustate),cpustate->a); cpustate->icount-=16;break;
case 0xaf: lh5801_bit(cpustate,cpustate->io->read_byte(lh5801_readop_word(cpustate)),cpustate->a); cpustate->icount-=17;break;
case 0xb1: /*hlt*/cpustate->icount-=8;break;
case 0xba: lh5801_ita(cpustate);cpustate->icount-=9;break;
case 0xbe: cpustate->t&=~IE; /*rie !*/cpustate->icount-=8;break;
@ -441,26 +449,27 @@ static void lh5801_instruction_fd(lh5801_state *cpustate)
case 0xca: lh5801_adr(cpustate,&cpustate->x);cpustate->icount-=11;break;
case 0xcc: /*atp sends a to data bus*/cpustate->icount-=9;break;
case 0xce: lh5801_am(cpustate,cpustate->a); cpustate->icount-=9; break;
case 0xd3: lh5801_drr(cpustate,0x10000|X); cpustate->icount-=16; break;
case 0xd7: lh5801_drl(cpustate,0x10000|X); cpustate->icount-=16; break;
case 0xd3: lh5801_drr(cpustate, cpustate->io, X); cpustate->icount-=16; break;
case 0xd7: lh5801_drl(cpustate, cpustate->io, X); cpustate->icount-=16; break;
case 0xda: lh5801_adr(cpustate,&cpustate->y);cpustate->icount-=11;break;
case 0xde: lh5801_am(cpustate,cpustate->a|0x100); cpustate->icount-=9; break;
case 0xea: lh5801_adr(cpustate,&cpustate->u);cpustate->icount-=11;break;
case 0xe9:
adr=lh5801_readop_word(cpustate)|0x10000;
lh5801_and_mem(cpustate,adr, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=23;
adr=lh5801_readop_word(cpustate);
lh5801_and_mem(cpustate, cpustate->io, adr, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=23;
break;
case 0xeb:
adr=lh5801_readop_word(cpustate)|0x10000;
lh5801_ora_mem(cpustate,adr, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=23;
adr=lh5801_readop_word(cpustate);
lh5801_ora_mem(cpustate, cpustate->io, adr, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=23;
break;
case 0xec: cpustate->t=cpustate->a; cpustate->icount-=9;break;
case 0xed:
adr=lh5801_readop_word(cpustate)|0x10000;lh5801_bit(cpustate,cpustate->program->read_byte(adr), cpustate->direct->read_decrypted_byte(P++));
adr=lh5801_readop_word(cpustate);
lh5801_bit(cpustate,cpustate->io->read_byte(adr), cpustate->direct->read_decrypted_byte(P++));
cpustate->icount-=20;break;
case 0xef:
adr=lh5801_readop_word(cpustate)|0x10000;
lh5801_add_mem(cpustate,adr, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=23;
adr=lh5801_readop_word(cpustate);
lh5801_add_mem(cpustate, cpustate->io, adr, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=23;
break;
default:
@ -533,13 +542,13 @@ static void lh5801_instruction(lh5801_state *cpustate)
case 0x46: X--;cpustate->icount-=5;break;
case 0x47: lh5801_lde(cpustate,&cpustate->x);cpustate->icount-=6;break;
case 0x48: XH=cpustate->direct->read_decrypted_byte(P++);cpustate->icount-=6;break;
case 0x49: lh5801_and_mem(cpustate,X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x49: lh5801_and_mem(cpustate, cpustate->program, X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x4a: XL=cpustate->direct->read_decrypted_byte(P++);cpustate->icount-=6;break;
case 0x4b: lh5801_ora_mem(cpustate,X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x4b: lh5801_ora_mem(cpustate, cpustate->program, X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x4c: lh5801_cpa(cpustate,XH, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=7;break;
case 0x4d: lh5801_bit(cpustate,cpustate->program->read_byte(X), cpustate->direct->read_decrypted_byte(P++));cpustate->icount-=10;break;
case 0x4e: lh5801_cpa(cpustate,XL, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=7;break;
case 0x4f: lh5801_add_mem(cpustate,X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x4f: lh5801_add_mem(cpustate, cpustate->program, X, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x50: lh5801_inc(cpustate,&YL);cpustate->icount-=5;break;
case 0x51: lh5801_sin(cpustate,&cpustate->y); cpustate->icount-=6;break;
case 0x52: lh5801_dec(cpustate,&YL);cpustate->icount-=5;break;
@ -549,13 +558,13 @@ static void lh5801_instruction(lh5801_state *cpustate)
case 0x56: Y--;cpustate->icount-=5;break;
case 0x57: lh5801_lde(cpustate,&cpustate->y);cpustate->icount-=6;break;
case 0x58: YH=cpustate->direct->read_decrypted_byte(P++);cpustate->icount-=6;break;
case 0x59: lh5801_and_mem(cpustate,Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x59: lh5801_and_mem(cpustate, cpustate->program, Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x5a: YL=cpustate->direct->read_decrypted_byte(P++);cpustate->icount-=6;break;
case 0x5b: lh5801_ora_mem(cpustate,Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x5b: lh5801_ora_mem(cpustate, cpustate->program, Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x5c: lh5801_cpa(cpustate,YH, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=7;break;
case 0x5d: lh5801_bit(cpustate,cpustate->program->read_byte(Y), cpustate->direct->read_decrypted_byte(P++));cpustate->icount-=10;break;
case 0x5e: lh5801_cpa(cpustate,YL, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=7;break;
case 0x5f: lh5801_add_mem(cpustate,Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x5f: lh5801_add_mem(cpustate, cpustate->program, Y, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x60: lh5801_inc(cpustate,&UL);cpustate->icount-=5;break;
case 0x61: lh5801_sin(cpustate,&cpustate->u); cpustate->icount-=6;break;
case 0x62: lh5801_dec(cpustate,&UL);cpustate->icount-=5;break;
@ -565,13 +574,13 @@ static void lh5801_instruction(lh5801_state *cpustate)
case 0x66: U--;cpustate->icount-=5;break;
case 0x67: lh5801_lde(cpustate,&cpustate->u);cpustate->icount-=6;break;
case 0x68: UH=cpustate->direct->read_decrypted_byte(P++);cpustate->icount-=6;break;
case 0x69: lh5801_and_mem(cpustate,U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x69: lh5801_and_mem(cpustate, cpustate->program, U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x6a: UL=cpustate->direct->read_decrypted_byte(P++);cpustate->icount-=6;break;
case 0x6b: lh5801_ora_mem(cpustate,U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x6b: lh5801_ora_mem(cpustate, cpustate->program, U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x6c: lh5801_cpa(cpustate,UH, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=7;break;
case 0x6d: lh5801_bit(cpustate,cpustate->program->read_byte(U), cpustate->direct->read_decrypted_byte(P++));cpustate->icount-=10;break;
case 0x6e: lh5801_cpa(cpustate,UL, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=7;break;
case 0x6f: lh5801_add_mem(cpustate,U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x6f: lh5801_add_mem(cpustate, cpustate->program, U, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=13;break;
case 0x80: lh5801_sbc(cpustate,XH); cpustate->icount-=6;break;
case 0x81: lh5801_branch_plus(cpustate,!(cpustate->t&C)); cpustate->icount-=8; break;
case 0x82: lh5801_adc(cpustate,XH); cpustate->icount-=6;break;
@ -639,9 +648,9 @@ static void lh5801_instruction(lh5801_state *cpustate)
case 0xcd: lh5801_vector(cpustate,1, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=7;break;
case 0xcf: lh5801_vector(cpustate,cpustate->t&V, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=8;break;
case 0xd1: lh5801_ror(cpustate); cpustate->icount-=6; break;
case 0xd3: lh5801_drr(cpustate,X); cpustate->icount-=12; break;
case 0xd3: lh5801_drr(cpustate, cpustate->program, X); cpustate->icount-=12; break;
case 0xd5: lh5801_shr(cpustate); cpustate->icount-=6; break;
case 0xd7: lh5801_drl(cpustate,X); cpustate->icount-=12; break;
case 0xd7: lh5801_drl(cpustate, cpustate->program, X); cpustate->icount-=12; break;
case 0xd9: lh5801_shl(cpustate); cpustate->icount-=6; break;
case 0xdb: lh5801_rol(cpustate); cpustate->icount-=6; break;
case 0xdd: lh5801_inc(cpustate,&cpustate->a);cpustate->icount-=5;break;
@ -649,17 +658,17 @@ static void lh5801_instruction(lh5801_state *cpustate)
case 0xe1: cpustate->pu=1;/*spu!*/ cpustate->icount-=4; break;
case 0xe3: cpustate->pu=0;/*rpu!*/ cpustate->icount-=4; break;
case 0xe9:
adr=lh5801_readop_word(cpustate);lh5801_and_mem(cpustate,adr, cpustate->direct->read_decrypted_byte(P++));
adr=lh5801_readop_word(cpustate);lh5801_and_mem(cpustate, cpustate->program, adr, cpustate->direct->read_decrypted_byte(P++));
cpustate->icount-=19;break;
case 0xeb:
adr=lh5801_readop_word(cpustate);lh5801_ora_mem(cpustate,adr, cpustate->direct->read_decrypted_byte(P++));
adr=lh5801_readop_word(cpustate);lh5801_ora_mem(cpustate, cpustate->program, adr, cpustate->direct->read_decrypted_byte(P++));
cpustate->icount-=19;break;
case 0xed:
adr=lh5801_readop_word(cpustate);lh5801_bit(cpustate,cpustate->program->read_byte(adr), cpustate->direct->read_decrypted_byte(P++));
cpustate->icount-=16;break;
case 0xef:
adr=lh5801_readop_word(cpustate);
lh5801_add_mem(cpustate,adr, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=19;
lh5801_add_mem(cpustate, cpustate->program, adr, cpustate->direct->read_decrypted_byte(P++)); cpustate->icount-=19;
break;
case 0xf1: lh5801_aex(cpustate); cpustate->icount-=6; break;
case 0xf5: cpustate->program->write_byte(Y++, cpustate->program->read_byte(X++)); cpustate->icount-=7; break; //tin

View File

@ -14,7 +14,15 @@
* terms of its usage and license at any time, including retroactively
* - This entire notice must remain in the source code.
*
*
* 02/2011 (Sandro Ronco)
* - Added IO_SPACE and updated all access in ME1 memory for use it.
* - Implemented interrupts.
* - Fixed the flags in the ROL/ROR/SHL/SHR opcodes.
* - Fixed decimal add/sub opcodes.
*
* based on info found on an artikel for the tandy trs80 pc2
* and on "PC1500 Technical reference manual"
*
*****************************************************************************/
@ -46,12 +54,13 @@ enum
LH5801_IRQ_STATE
};
typedef struct _lh5810_state lh5801_state;
struct _lh5810_state
typedef struct _lh5801_state lh5801_state;
struct _lh5801_state
{
const lh5801_cpu_core *config;
legacy_cpu_device *device;
address_space *program;
address_space *program; //ME0
address_space *io; //ME1
direct_read_data *direct;
PAIR s, p, u, x, y;
@ -65,6 +74,9 @@ struct _lh5810_state
int irq_state;
UINT8 ir_flipflop[3]; //interrupt request flipflop: IR0, IR1, IR2
int lines_status[2]; //MI and NMI lines status
int idle;
int icount;
};
@ -107,6 +119,7 @@ static CPU_INIT( lh5801 )
cpustate->config = (const lh5801_cpu_core *) device->baseconfig().static_config();
cpustate->device = device;
cpustate->program = device->space(AS_PROGRAM);
cpustate->io = device->space(AS_IO);
cpustate->direct = &cpustate->program->direct();
}
@ -117,29 +130,90 @@ static CPU_RESET( lh5801 )
P = (cpustate->program->read_byte(0xfffe)<<8) | cpustate->program->read_byte(0xffff);
cpustate->idle=0;
memset(cpustate->ir_flipflop, 0, sizeof(cpustate->ir_flipflop));
memset(cpustate->lines_status, 0, sizeof(cpustate->lines_status));
}
static void check_irq(device_t *device)
{
lh5801_state *cpustate = get_safe_token(device);
if (cpustate->ir_flipflop[0])
{
//NMI interrupt
cpustate->ir_flipflop[0] = 0;
lh5801_push(cpustate,cpustate->t);
cpustate->t&=~IE;
lh5801_push_word(cpustate,P);
P = (cpustate->program->read_byte(0xfffc)<<8) | cpustate->program->read_byte(0xfffd);
}
else if (cpustate->ir_flipflop[1] && (cpustate->t & IE))
{
//counter interrupt (counter not yet implemented)
cpustate->ir_flipflop[1] = 0;
lh5801_push(cpustate,cpustate->t);
cpustate->t&=~IE;
lh5801_push_word(cpustate,P);
P = (cpustate->program->read_byte(0xfffa)<<8) | cpustate->program->read_byte(0xfffb);
}
else if (cpustate->ir_flipflop[2] && (cpustate->t & IE))
{
//MI interrupt
cpustate->ir_flipflop[2] = 0;
lh5801_push(cpustate, cpustate->t);
cpustate->t&=~IE;
lh5801_push_word(cpustate, P);
P = (cpustate->program->read_byte(0xfff8)<<8) | cpustate->program->read_byte(0xfff9);
}
}
static CPU_EXECUTE( lh5801 )
{
lh5801_state *cpustate = get_safe_token(device);
if (cpustate->idle) {
cpustate->icount=0;
} else {
do
do
{
check_irq(device);
if (cpustate->idle)
cpustate->icount = 0;
else
{
cpustate->oldpc = P;
debugger_instruction_hook(device, P);
lh5801_instruction(cpustate);
}
} while (cpustate->icount > 0);
}
} while (cpustate->icount > 0);
}
static void set_irq_line(lh5801_state *cpustate, int irqline, int state)
{
cpustate->idle=0;
switch( irqline)
{
case LH5801_LINE_MI:
if (cpustate->lines_status[0] == CLEAR_LINE && state == ASSERT_LINE)
{
cpustate->idle = 0;
cpustate->ir_flipflop[2] = 1;
}
cpustate->lines_status[0] = state;
break;
case INPUT_LINE_NMI:
if (cpustate->lines_status[1] == CLEAR_LINE && state == ASSERT_LINE)
{
cpustate->idle = 0;
cpustate->ir_flipflop[0] = 1;
}
cpustate->lines_status[1] = state;
break;
}
}
@ -154,7 +228,8 @@ static CPU_SET_INFO( lh5801 )
switch (state)
{
/* --- the following bits of info are set as 64-bit signed integers --- */
case CPUINFO_INT_INPUT_STATE: set_irq_line(cpustate, 0, info->i); break;
case CPUINFO_INT_INPUT_STATE + LH5801_LINE_MI: set_irq_line(cpustate, LH5801_LINE_MI, info->i); break;
case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(cpustate, INPUT_LINE_NMI, info->i); break;
case CPUINFO_INT_PC:
case CPUINFO_INT_REGISTER + LH5801_P: P = info->i; break;
@ -202,8 +277,8 @@ CPU_GET_INFO( lh5801 )
case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break;
case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break;
case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
case CPUINFO_INT_INPUT_STATE: info->i = cpustate->irq_state; break;

View File

@ -73,8 +73,11 @@ struct _lh5801_cpu_core
lh5801_in_func in;
};
#define LH5801_INT_NONE 0
#define LH5801_IRQ 1
// input lines
enum
{
LH5801_LINE_MI, //maskable interrupt
};
DECLARE_LEGACY_CPU_DEVICE(LH5801, lh5801);
extern CPU_DISASSEMBLE( lh5801 );