void nsc810_device::device_start() { m_portA_r.resolve_safe(0); m_portB_r.resolve_safe(0); m_portC_r.resolve_safe(0); m_portA_w.resolve_safe(); m_portB_w.resolve_safe(); m_portC_w.resolve_safe(); m_timer0_out.resolve_safe(); m_timer1_out.resolve_safe(); m_portA_w(0); m_portB_w(0); m_portC_w(0); m_timer0_out(0); m_timer1_out(0); m_timer0 = timer_alloc(TIMER0_CLOCK); m_timer1 = timer_alloc(TIMER1_CLOCK); }
void nsc810_device::write(offs_t offset, uint8_t data) { uint32_t rate; if(m_ramselect) { // TODO: 128 byte RAM access } else { // Register access switch(offset & 0x1f) { case REG_PORTA: m_portA_latch = data & ~m_ddrA; m_portA_w((0xff & ~m_ddrA) | (data & m_ddrA)); LOG("NSC810: Port A data write %02x\n",data); break; case REG_PORTB: m_portB_latch = data & ~m_ddrB; m_portB_w((0xff & ~m_ddrB) | (data & m_ddrB)); LOG("NSC810: Port B data write %02x\n",data); break; case REG_PORTC: m_portC_latch = data & ~m_ddrC; m_portC_w((0xff & ~m_ddrC) | (data & m_ddrC)); LOG("NSC810: Port C data write %02x\n",data); break; case REG_DDRA: m_ddrA = data; LOG("NSC810: Port A direction write %02x\n",data); break; case REG_DDRB: m_ddrB = data; LOG("NSC810: Port B direction write %02x\n",data); break; case REG_DDRC: m_ddrC = data; LOG("NSC810: Port C direction write %02x\n",data); break; case REG_MODE_DEF: LOG("NSC810: Mode Definition write %02x\n",data); break; case REG_PORTA_BITCLR: LOG("NSC810: Port A bit-clear write %02x\n",data); break; case REG_PORTB_BITCLR: LOG("NSC810: Port B bit-clear write %02x\n",data); break; case REG_PORTC_BITCLR: LOG("NSC810: Port C bit-clear write %02x\n",data); break; case REG_PORTA_BITSET: LOG("NSC810: Port A bit-set write %02x\n",data); break; case REG_PORTB_BITSET: LOG("NSC810: Port B bit-set write %02x\n",data); break; case REG_PORTC_BITSET: LOG("NSC810: Port C bit-set write %02x\n",data); break; case REG_TIMER0_LOW: m_timer0_base = (m_timer0_base & 0xff00) | data; m_timer0_counter = (m_timer0_counter & 0xff00) | data; LOG("NSC810: Timer 0 low-byte write %02x (base=%04x)\n",data,m_timer0_base); break; case REG_TIMER0_HIGH: m_timer0_base = (m_timer0_base & 0x00ff) | (data << 8); m_timer0_counter = (m_timer0_counter & 0x00ff) | (data << 8); LOG("NSC810: Timer 0 high-byte write %02x (base=%04x)\n",data,m_timer0_base); break; case REG_TIMER1_LOW: m_timer1_base = (m_timer1_base & 0xff00) | data; m_timer1_counter = (m_timer1_counter & 0xff00) | data; LOG("NSC810: Timer 1 low-byte write %02x (base=%04x)\n",data,m_timer1_base); break; case REG_TIMER1_HIGH: m_timer1_base = (m_timer1_base & 0x00ff) | (data << 8); m_timer1_counter = (m_timer1_counter & 0x00ff) | (data << 8); LOG("NSC810: Timer 1 high-byte write %02x (base=%04x)\n",data,m_timer1_base); break; case REG_TIMER0_STOP: m_timer0_running = false; m_timer0->reset(); LOG("NSC810: Timer 0 Stop write %02x\n",tag(),data); break; case REG_TIMER0_START: if((m_timer0_mode & 0x07) != 0x00 && (m_timer0_mode & 0x07) != 0x07) { m_timer0_running = true; if(m_timer0_mode & 0x10) rate = m_timer0_clock / 64; else if(m_timer0_mode & 0x08) rate = m_timer0_clock / 2; else rate = m_timer0_clock; m_timer0->adjust(attotime::zero,0,attotime::from_hz(rate)); } LOG("NSC810: Timer 0 Start write %02x\n",data); break; case REG_TIMER1_STOP: m_timer1_running = false; m_timer1->reset(); LOG("NSC810: Timer 1 Stop write %02x\n",data); break; case REG_TIMER1_START: if((m_timer1_mode & 0x07) != 0x00 && (m_timer1_mode & 0x07) != 0x07) { m_timer1_running = true; // no /64 prescaler on timer 1 if(m_timer0_mode & 0x08) rate = m_timer0_clock / 2; else rate = m_timer0_clock; m_timer1->adjust(attotime::zero,0,attotime::from_hz(rate)); } LOG("NSC810: Timer 1 Start write %02x\n",data); break; case REG_MODE_TIMER0: m_timer0_mode = data; LOG("NSC810: Timer 0 Mode write %02x\n",data); break; case REG_MODE_TIMER1: m_timer1_mode = data; LOG("NSC810: Timer 1 Mode write %02x\n",data); break; default: logerror("NSC810: Unused register %02x write %02x\n",offset,data); } } }