rewrote bcd_add/sub according to official doc

This commit is contained in:
Michaël Banaan Ananas 2014-04-09 00:08:21 +00:00
parent 5d2e73ffbf
commit 005c314621
3 changed files with 98 additions and 243 deletions

View File

@ -57,9 +57,9 @@ const device_type TMS7000_EXL = &device_creator<tms7000_exl_device>;
static ADDRESS_MAP_START(tms7000_mem, AS_PROGRAM, 8, tms7000_device )
AM_RANGE(0x0000, 0x007f) AM_READWRITE(tms7000_internal_r, tms7000_internal_w) /* tms7000 internal RAM */
AM_RANGE(0x0080, 0x00ff) AM_NOP /* reserved */
AM_RANGE(0x0100, 0x01ff) AM_READWRITE(tms70x0_pf_r, tms70x0_pf_w) /* tms7000 internal I/O ports */
AM_RANGE(0x0000, 0x007f) AM_READWRITE(tms7000_internal_r, tms7000_internal_w) /* tms7000 internal RAM */
AM_RANGE(0x0080, 0x00ff) AM_NOP /* reserved */
AM_RANGE(0x0100, 0x01ff) AM_READWRITE(tms70x0_pf_r, tms70x0_pf_w) /* tms7000 internal I/O ports */
ADDRESS_MAP_END
@ -133,7 +133,7 @@ UINT16 tms7000_device::RM16( UINT32 mAddr ) /* Read memory (16-bit) */
return result | RM((mAddr+1)&0xffff);
}
UINT16 tms7000_device::RRF16( UINT32 mAddr ) /*Read register file (16 bit) */
UINT16 tms7000_device::RRF16( UINT32 mAddr ) /* Read register file (16 bit) */
{
PAIR result;
result.b.h = RM((mAddr-1)&0xffff);
@ -141,7 +141,7 @@ UINT16 tms7000_device::RRF16( UINT32 mAddr ) /*Read register file (16 bit) */
return result.w.l;
}
void tms7000_device::WRF16( UINT32 mAddr, PAIR p ) /*Write register file (16 bit) */
void tms7000_device::WRF16( UINT32 mAddr, PAIR p ) /* Write register file (16 bit) */
{
WM( (mAddr-1)&0xffff, p.b.h );
WM( mAddr, p.b.l );
@ -527,40 +527,62 @@ READ8_MEMBER( tms7000_device::tms70x0_pf_r ) /* Perpherial file read */
}
// BCD arthrimetic handling
UINT16 tms7000_device::bcd_add( UINT16 a, UINT16 b )
{
UINT16 t1,t2,t3,t4,t5,t6;
static const UINT8 lut_bcd_out[6] = { 0x00, 0x06, 0x00, 0x66, 0x60, 0x66 };
/* Sure it is a lot of code, but it works! */
t1 = a + 0x0666;
t2 = t1 + b;
t3 = t1 ^ b;
t4 = t2 ^ t3;
t5 = ~t4 & 0x1110;
t6 = (t5 >> 2) | (t5 >> 3);
return t2-t6;
inline UINT8 tms7000_device::bcd_add( UINT8 a, UINT8 b, UINT8 c )
{
c = (c != 0) ? 1 : 0;
UINT8 h1 = a >> 4 & 0xf;
UINT8 l1 = a >> 0 & 0xf;
UINT8 h2 = b >> 4 & 0xf;
UINT8 l2 = b >> 0 & 0xf;
// compute bcd constant
UINT8 d = ((l1 + l2 + c) < 10) ? 0 : 1;
if ((h1 + h2) == 9)
d |= 2;
else if ((h1 + h2) > 9)
d |= 4;
UINT8 ret = a + b + c + lut_bcd_out[d];
CLR_NZC;
SET_N8(ret);
SET_Z8(ret);
if (d > 2)
pSR |= SR_C;
return ret;
}
UINT16 tms7000_device::bcd_tencomp( UINT16 a )
inline UINT8 tms7000_device::bcd_sub( UINT8 a, UINT8 b, UINT8 c )
{
UINT16 t1,t2,t3,t4,t5,t6;
c = (c != 0) ? 0 : 1;
t1 = 0xffff - a;
t2 = -a;
t3 = t1 ^ 0x0001;
t4 = t2 ^ t3;
t5 = ~t4 & 0x1110;
t6 = (t5 >> 2)|(t5>>3);
return t2-t6;
}
UINT8 h1 = a >> 4 & 0xf;
UINT8 l1 = a >> 0 & 0xf;
UINT8 h2 = b >> 4 & 0xf;
UINT8 l2 = b >> 0 & 0xf;
/*
Compute difference a-b???
*/
UINT16 tms7000_device::bcd_sub( UINT16 a, UINT16 b)
{
//return bcd_tencomp(b) - bcd_tencomp(a);
return bcd_add(a, bcd_tencomp(b) & 0xff);
// compute bcd constant
UINT8 d = ((l1 - c) >= l2) ? 0 : 1;
if (h1 == h2)
d |= 2;
else if (h1 < h2)
d |= 4;
UINT8 ret = a - b - c - lut_bcd_out[d];
CLR_NZC;
SET_N8(ret);
SET_Z8(ret);
if (d > 2)
pSR |= SR_C;
return ret;
}
WRITE8_MEMBER( tms7000_device::tms7000_internal_w )

View File

@ -92,30 +92,32 @@ private:
static const opcode_func s_opfn_exl[0x100];
const opcode_func *m_opcode;
static UINT16 bcd_add( UINT16 a, UINT16 b );
static UINT16 bcd_tencomp( UINT16 a );
static UINT16 bcd_sub( UINT16 a, UINT16 b);
inline UINT8 bcd_add( UINT8 a, UINT8 b, UINT8 c );
inline UINT8 bcd_sub( UINT8 a, UINT8 b, UINT8 c );
PAIR m_pc; /* Program counter */
UINT8 m_sp; /* Stack Pointer */
UINT8 m_sr; /* Status Register */
UINT8 m_irq_state[3]; /* State of the three IRQs */
UINT8 m_rf[0x80]; /* Register file (SJE) */
UINT8 m_pf[0x100]; /* Perpherial file */
PAIR m_pc; /* Program counter */
UINT8 m_sp; /* Stack Pointer */
UINT8 m_sr; /* Status Register */
UINT8 m_irq_state[3]; /* State of the three IRQs */
UINT8 m_rf[0x80]; /* Register file (SJE) */
UINT8 m_pf[0x100]; /* Perpherial file */
address_space *m_program;
direct_read_data *m_direct;
address_space *m_io;
int m_icount;
int m_div_by_16_trigger;
int m_cycles_per_INT2;
UINT8 m_t1_capture_latch; /* Timer 1 capture latch */
INT8 m_t1_prescaler; /* Timer 1 prescaler (5 bits) */
INT16 m_t1_decrementer; /* Timer 1 decrementer (8 bits) */
UINT8 m_idle_state; /* Set after the execution of an idle instruction */
INT8 m_t1_prescaler; /* Timer 1 prescaler (5 bits) */
INT16 m_t1_decrementer; /* Timer 1 decrementer (8 bits) */
UINT8 m_idle_state; /* Set after the execution of an idle instruction */
address_space *m_program;
direct_read_data *m_direct;
address_space *m_io;
inline UINT16 RM16( UINT32 mAddr );
inline UINT16 RRF16( UINT32 mAddr );
inline void WRF16( UINT32 mAddr, PAIR p );
void tms7000_check_IRQ_lines();
void tms7000_do_interrupt( UINT16 address, UINT8 line );
void illegal();
@ -348,7 +350,6 @@ private:
void xorp_b2p();
void xorp_i2p();
void tms7000_service_timer1();
};

View File

@ -1292,153 +1292,69 @@ void tms7000_device::cmpa_inx()
void tms7000_device::dac_b2a()
{
UINT16 t;
t = bcd_add( RDA, RDB );
if (pSR & SR_C)
t = bcd_add( t, 1 );
WRA(t);
CLR_NZC;
SET_C8(t);
SET_N8(t);
SET_Z8(t);
WRA(bcd_add(RDA, RDB, pSR & SR_C));
m_icount -= 7;
}
void tms7000_device::dac_r2a()
{
UINT8 r;
UINT16 t;
UINT8 r;
IMMBYTE(r);
t = bcd_add( RDA, RM(r) );
if (pSR & SR_C)
t = bcd_add( t, 1 );
WRA(t);
CLR_NZC;
SET_C8(t);
SET_N8(t);
SET_Z8(t);
WRA(bcd_add(RDA, RM(r), pSR & SR_C));
m_icount -= 10;
}
void tms7000_device::dac_r2b()
{
UINT8 r;
UINT16 t;
UINT8 r;
IMMBYTE(r);
t = bcd_add( RDB, RM(r) );
if (pSR & SR_C)
t = bcd_add( t, 1 );
WRB(t);
CLR_NZC;
SET_C8(t);
SET_N8(t);
SET_Z8(t);
WRB(bcd_add(RDB, RM(r), pSR & SR_C));
m_icount -= 10;
}
void tms7000_device::dac_r2r()
{
UINT8 r,s;
UINT16 t;
UINT8 s, r;
IMMBYTE(s);
IMMBYTE(r);
t = bcd_add( RM(s), RM(r) );
if (pSR & SR_C)
t = bcd_add( t, 1 );
WM(r,t);
CLR_NZC;
SET_C8(t);
SET_N8(t);
SET_Z8(t);
WM(r, bcd_add(RM(s), RM(r), pSR & SR_C));
m_icount -= 12;
}
void tms7000_device::dac_i2a()
{
UINT8 i;
UINT16 t;
UINT8 i;
IMMBYTE(i);
t = bcd_add( i, RDA );
if (pSR & SR_C)
t = bcd_add( t, 1 );
WRA(t);
CLR_NZC;
SET_C8(t);
SET_N8(t);
SET_Z8(t);
WRA(bcd_add(i, RDA, pSR & SR_C));
m_icount -= 9;
}
void tms7000_device::dac_i2b()
{
UINT8 i;
UINT16 t;
UINT8 i;
IMMBYTE(i);
t = bcd_add( i, RDB );
if (pSR & SR_C)
t = bcd_add( t, 1 );
WRB(t);
CLR_NZC;
SET_C8(t);
SET_N8(t);
SET_Z8(t);
WRB(bcd_add(i, RDB, pSR & SR_C));
m_icount -= 9;
}
void tms7000_device::dac_i2r()
{
UINT8 i,r;
UINT16 t;
UINT8 i, r;
IMMBYTE(i);
IMMBYTE(r);
t = bcd_add( i, RM(r) );
if (pSR & SR_C)
t = bcd_add( t, 1 );
WM(r,t);
CLR_NZC;
SET_C8(t);
SET_N8(t);
SET_Z8(t);
WM(r, bcd_add(i, RM(r), pSR & SR_C));
m_icount -= 11;
}
@ -1642,153 +1558,69 @@ void tms7000_device::djnz_r()
void tms7000_device::dsb_b2a()
{
UINT16 t;
t = bcd_sub( RDA, RDB );
if( !(pSR & SR_C) )
t = bcd_sub( t, 1 );
WRA(t);
CLR_NZC;
SET_C8(~t);
SET_N8(t);
SET_Z8(t);
WRA(bcd_sub(RDA, RDB, pSR & SR_C));
m_icount -= 7;
}
void tms7000_device::dsb_r2a()
{
UINT8 r;
UINT16 t;
UINT8 r;
IMMBYTE(r);
t = bcd_sub( RDA, RM(r) );
if( !(pSR & SR_C) )
t = bcd_sub( t, 1 );
WRA(t);
CLR_NZC;
SET_C8(~t);
SET_N8(t);
SET_Z8(t);
WRA(bcd_sub(RDA, RM(r), pSR & SR_C));
m_icount -= 10;
}
void tms7000_device::dsb_r2b()
{
UINT8 r;
UINT16 t;
UINT8 r;
IMMBYTE(r);
t = bcd_sub( RDB, RM(r) );
if( !(pSR & SR_C) )
t = bcd_sub( t, 1 );
WRB(t);
CLR_NZC;
SET_C8(~t);
SET_N8(t);
SET_Z8(t);
WRB(bcd_sub(RDB, RM(r), pSR & SR_C));
m_icount -= 10;
}
void tms7000_device::dsb_r2r()
{
UINT8 r,s;
UINT16 t;
UINT8 s, r;
IMMBYTE(s);
IMMBYTE(r);
t = bcd_sub( RM(s), RM(r) );
if( !(pSR & SR_C) )
t = bcd_sub( t, 1 );
WM(r,t);
CLR_NZC;
SET_C8(~t);
SET_N8(t);
SET_Z8(t);
WM(r, bcd_sub(RM(s), RM(r), pSR & SR_C));
m_icount -= 12;
}
void tms7000_device::dsb_i2a()
{
UINT8 i;
UINT16 t;
UINT8 i;
IMMBYTE(i);
t = bcd_sub( RDA, i );
if( !(pSR & SR_C) )
t = bcd_sub( t, 1 );
WRA(t);
CLR_NZC;
SET_C8(~t);
SET_N8(t);
SET_Z8(t);
WRA(bcd_sub(RDA, i, pSR & SR_C));
m_icount -= 9;
}
void tms7000_device::dsb_i2b()
{
UINT8 i;
UINT16 t;
UINT8 i;
IMMBYTE(i);
t = bcd_sub( RDB, i );
if( !(pSR & SR_C) )
t = bcd_sub( t, 1 );
WRB(t);
CLR_NZC;
SET_C8(~t);
SET_N8(t);
SET_Z8(t);
WRB(bcd_sub(RDB, i, pSR & SR_C));
m_icount -= 9;
}
void tms7000_device::dsb_i2r()
{
UINT8 r,i;
UINT16 t;
UINT8 i, r;
IMMBYTE(i);
IMMBYTE(r);
t = bcd_sub( RM(r), i );
if( !(pSR & SR_C) )
t = bcd_sub( t, 1 );
WM(r,t);
CLR_NZC;
SET_C8(~t);
SET_N8(t);
SET_Z8(t);
WM(r, bcd_sub(RM(r), i, pSR & SR_C));
m_icount -= 11;
}