diff --git a/src/emu/cpu/tms7000/tms7000.c b/src/emu/cpu/tms7000/tms7000.c index 257d8b9e16b..e44b598b72b 100644 --- a/src/emu/cpu/tms7000/tms7000.c +++ b/src/emu/cpu/tms7000/tms7000.c @@ -57,9 +57,9 @@ const device_type TMS7000_EXL = &device_creator; 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 ) diff --git a/src/emu/cpu/tms7000/tms7000.h b/src/emu/cpu/tms7000/tms7000.h index e1de0ab7cf7..27505d854e7 100644 --- a/src/emu/cpu/tms7000/tms7000.h +++ b/src/emu/cpu/tms7000/tms7000.h @@ -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(); - }; diff --git a/src/emu/cpu/tms7000/tms70op.inc b/src/emu/cpu/tms7000/tms70op.inc index 443f07f76a6..9bed2b781cc 100644 --- a/src/emu/cpu/tms7000/tms70op.inc +++ b/src/emu/cpu/tms7000/tms70op.inc @@ -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; }