From ccce9e7adb14afe9cfe798197d69f358034d1bde Mon Sep 17 00:00:00 2001 From: AJR Date: Thu, 12 Sep 2019 15:45:41 -0400 Subject: scc68070: Split up internal register block handlers; add some RESET behavior (nw) --- src/devices/machine/scc68070.cpp | 1256 ++++++++++++++++++++------------------ src/devices/machine/scc68070.h | 50 +- 2 files changed, 697 insertions(+), 609 deletions(-) diff --git a/src/devices/machine/scc68070.cpp b/src/devices/machine/scc68070.cpp index 3ed6dede91c..38511711e75 100644 --- a/src/devices/machine/scc68070.cpp +++ b/src/devices/machine/scc68070.cpp @@ -49,7 +49,23 @@ DEFINE_DEVICE_TYPE(SCC68070, scc68070_device, "scc68070", "Philips SCC68070") void scc68070_device::internal_map(address_map &map) { - map(0x80000000, 0x8000807f).rw(FUNC(scc68070_device::periphs_r), FUNC(scc68070_device::periphs_w)); + map(0x80001001, 0x80001001).rw(FUNC(scc68070_device::lir_r), FUNC(scc68070_device::lir_w)); + map(0x80002001, 0x80002001).rw(FUNC(scc68070_device::idr_r), FUNC(scc68070_device::idr_w)); + map(0x80002003, 0x80002003).rw(FUNC(scc68070_device::iar_r), FUNC(scc68070_device::iar_w)); + map(0x80002005, 0x80002005).rw(FUNC(scc68070_device::isr_r), FUNC(scc68070_device::isr_w)); + map(0x80002007, 0x80002007).rw(FUNC(scc68070_device::icr_r), FUNC(scc68070_device::icr_w)); + map(0x80002009, 0x80002009).rw(FUNC(scc68070_device::iccr_r), FUNC(scc68070_device::iccr_w)); + map(0x80002011, 0x80002011).rw(FUNC(scc68070_device::umr_r), FUNC(scc68070_device::umr_w)); + map(0x80002013, 0x80002013).r(FUNC(scc68070_device::usr_r)); + map(0x80002015, 0x80002015).rw(FUNC(scc68070_device::ucsr_r), FUNC(scc68070_device::ucsr_w)); + map(0x80002017, 0x80002017).rw(FUNC(scc68070_device::ucr_r), FUNC(scc68070_device::ucr_w)); + map(0x80002019, 0x80002019).rw(FUNC(scc68070_device::uth_r), FUNC(scc68070_device::uth_w)); + map(0x8000201b, 0x8000201b).r(FUNC(scc68070_device::urh_r)); + map(0x80002020, 0x80002029).rw(FUNC(scc68070_device::timer_r), FUNC(scc68070_device::timer_w)); + map(0x80002045, 0x80002045).rw(FUNC(scc68070_device::picr1_r), FUNC(scc68070_device::picr1_w)); + map(0x80002047, 0x80002047).rw(FUNC(scc68070_device::picr2_r), FUNC(scc68070_device::picr2_w)); + map(0x80004000, 0x8000406d).rw(FUNC(scc68070_device::dma_r), FUNC(scc68070_device::dma_w)); + map(0x80008000, 0x8000807f).rw(FUNC(scc68070_device::mmu_r), FUNC(scc68070_device::mmu_w)); } void scc68070_device::cpu_space_map(address_map &map) @@ -271,6 +287,34 @@ void scc68070_device::device_reset() update_ipl(); } +void scc68070_device::m68k_reset_peripherals() +{ + m_lir = 0; + + m_picr1 = 0; + m_picr2 = 0; + m_timer_int = false; + m_i2c_int = false; + m_uart_rx_int = false; + m_uart_tx_int = false; + + m_i2c.status_register = 0; + m_i2c.control_register = 0; + m_i2c.clock_control_register = 0; + m_uart.command_register = 0; + m_uart.receive_pointer = -1; + m_uart.transmit_pointer = -1; + + m_uart.mode_register = 0; + m_uart.status_register = USR_TXRDY; + m_uart.clock_select = 0; + + m_timers.timer_status_register = 0; + m_timers.timer_control_register = 0; + + update_ipl(); +} + void scc68070_device::update_ipl() { const uint8_t external_level = (m_nmi_line == ASSERT_LINE) ? 7 @@ -571,641 +615,641 @@ TIMER_CALLBACK_MEMBER( scc68070_device::tx_callback ) uart_tx_check(); } -READ16_MEMBER( scc68070_device::periphs_r ) +uint8_t scc68070_device::lir_r() { - switch (offset) + // LIR priority level: 80001001 + return m_lir; +} + +void scc68070_device::lir_w(uint8_t data) +{ + LOGMASKED(LOG_IRQS, "%s: LIR Write: %02x\n", machine().describe_context(), data); + m_lir = data; +} + +uint8_t scc68070_device::picr1_r() +{ + // PICR1: 80002045 + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_IRQS, "%s: Peripheral Interrupt Control Register 1 Read: %02x\n", machine().describe_context(), m_picr1); + return m_picr1 & 0x77; +} + +void scc68070_device::picr1_w(uint8_t data) +{ + LOGMASKED(LOG_IRQS, "%s: Peripheral Interrupt Control Register 1 Write: %02x\n", machine().describe_context(), data); + m_picr1 = data & 0x77; + switch (data & 0x88) { - // Interrupts: 80001001 - case 0x1000/2: // LIR priority level - return m_lir; + case 0x08: + if (m_timer_int) + { + m_timer_int = false; + update_ipl(); + } + break; - // I2C interface: 80002001 to 80002009 - case 0x2000/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_I2C, "%s: I2C Data Register Read: %04x & %04x\n", machine().describe_context(), m_i2c.data_register, mem_mask); - } - return m_i2c.data_register; - case 0x2002/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_I2C, "%s: I2C Address Register Read: %04x & %04x\n", machine().describe_context(), m_i2c.address_register, mem_mask); - } - return m_i2c.address_register; - case 0x2004/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_I2C, "%s: I2C Status Register Read: %04x & %04x\n", machine().describe_context(), m_i2c.status_register, mem_mask); - } - return m_i2c.status_register & 0xef; // hack for magicard - case 0x2006/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_I2C, "%s: I2C Control Register Read: %04x & %04x\n", machine().describe_context(), m_i2c.control_register, mem_mask); - } - return m_i2c.control_register; - case 0x2008/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_I2C, "%s: I2C Clock Control Register Read: %04x & %04x\n", machine().describe_context(), m_i2c.clock_control_register, mem_mask); - } - return m_i2c.clock_control_register; + case 0x80: + if (m_i2c_int) + { + m_i2c_int = false; + update_ipl(); + } + break; - // UART interface: 80002011 to 8000201b - case 0x2010/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Mode Register Read: %04x & %04x\n", machine().describe_context(), m_uart.mode_register, mem_mask); - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Read: %04x & %04x\n", machine().describe_context(), offset * 2, mem_mask); - } - return m_uart.mode_register | 0x20; - case 0x2012/2: - m_uart.status_register |= (1 << 1); - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Status Register Read: %04x & %04x\n", machine().describe_context(), m_uart.status_register, mem_mask); - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Read: %04x & %04x\n", machine().describe_context(), offset * 2, mem_mask); - } + case 0x88: + if (m_timer_int || m_i2c_int) + { + m_timer_int = false; + m_i2c_int = false; + update_ipl(); + } + break; + } +} - return m_uart.status_register | 0x08; // hack for magicard +uint8_t scc68070_device::picr2_r() +{ + // PICR2: 80002047 + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_IRQS, "%s: Peripheral Interrupt Control Register 2 Read: %02x\n", machine().describe_context(), m_picr2); + return m_picr2 & 0x77; +} - case 0x2014/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Clock Select Read: %04x & %04x\n", machine().describe_context(), m_uart.clock_select, mem_mask); - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Read: %04x & %04x\n", machine().describe_context(), offset * 2, mem_mask); - } - return m_uart.clock_select | 0x08; - case 0x2016/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Command Register Read: %02x & %04x\n", machine().describe_context(), m_uart.command_register, mem_mask); - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Read: %04x & %04x\n", machine().describe_context(), offset * 2, mem_mask); - } - return m_uart.command_register | 0x80; - case 0x2018/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Transmit Holding Register Read: %02x & %04x\n", machine().describe_context(), m_uart.transmit_holding_register, mem_mask); - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Read: %04x & %04x\n", machine().describe_context(), offset * 2, mem_mask); - } - return m_uart.transmit_holding_register; - case 0x201a/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Receive Holding Register Read: %02x & %04x\n", machine().describe_context(), m_uart.receive_holding_register, mem_mask); - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Read: %04x & %04x\n", machine().describe_context(), offset * 2, mem_mask); - } - if (m_uart_rx_int) - { - m_uart_rx_int = false; - update_ipl(); - } +void scc68070_device::picr2_w(uint8_t data) +{ + LOGMASKED(LOG_IRQS, "%s: Peripheral Interrupt Control Register 2 Write: %02x\n", machine().describe_context(), data); + m_picr2 = data & 0x77; + switch (data & 0x88) + { + case 0x08: + if (m_uart_tx_int) + { + m_uart_tx_int = false; + update_ipl(); + } + break; - m_uart.receive_holding_register = m_uart.receive_buffer[0]; - if (m_uart.receive_pointer >= 0) - { - for(int index = 0; index < m_uart.receive_pointer; index++) - { - m_uart.receive_buffer[index] = m_uart.receive_buffer[index + 1]; - } - m_uart.receive_pointer--; - } - return m_uart.receive_holding_register; + case 0x80: + if (m_uart_rx_int) + { + m_uart_rx_int = false; + update_ipl(); + } + break; - // Timers: 80002020 to 80002029 - case 0x2020/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_TIMERS, "%s: Timer Control Register Read: %02x & %04x\n", machine().describe_context(), m_timers.timer_control_register, mem_mask); - } - if (ACCESSING_BITS_8_15) + case 0x88: + if (m_uart_tx_int || m_uart_rx_int) + { + m_uart_tx_int = false; + m_uart_rx_int = false; + update_ipl(); + } + break; + } +} + +uint8_t scc68070_device::idr_r() +{ + // I2C data register: 80002001 + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_I2C, "%s: I2C Data Register Read: %02x\n", machine().describe_context(), m_i2c.data_register); + return m_i2c.data_register; +} + +void scc68070_device::idr_w(uint8_t data) +{ + LOGMASKED(LOG_I2C, "%s: I2C Data Register Write: %02x\n", machine().describe_context(), data); + m_i2c.data_register = data; +} + +uint8_t scc68070_device::iar_r() +{ + // I2C address register: 80002003 + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_I2C, "%s: I2C Address Register Read: %02x\n", machine().describe_context(), m_i2c.address_register); + return m_i2c.address_register; +} + +void scc68070_device::iar_w(uint8_t data) +{ + LOGMASKED(LOG_I2C, "%s: I2C Address Register Write: %02x\n", machine().describe_context(), data); + m_i2c.address_register = data; +} + +uint8_t scc68070_device::isr_r() +{ + // I2C status register: 80002005 + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_I2C, "%s: I2C Status Register Read: %02x\n", machine().describe_context(), m_i2c.status_register); + return m_i2c.status_register & 0xef; // hack for magicard +} + +void scc68070_device::isr_w(uint8_t data) +{ + LOGMASKED(LOG_I2C, "%s: I2C Status Register Write: %02x\n", machine().describe_context(), data); + m_i2c.status_register = data; +} + +uint8_t scc68070_device::icr_r() +{ + // I2C control register: 80002007 + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_I2C, "%s: I2C Control Register Read: %02x\n", machine().describe_context(), m_i2c.control_register); + return m_i2c.control_register; +} + +void scc68070_device::icr_w(uint8_t data) +{ + LOGMASKED(LOG_I2C, "%s: I2C Control Register Write: %02x\n", machine().describe_context(), data); + m_i2c.control_register = data; +} + +uint8_t scc68070_device::iccr_r() +{ + // I2C clock control register: 80002009 + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_I2C, "%s: I2C Clock Control Register Read: %02x\n", machine().describe_context(), m_i2c.clock_control_register); + return m_i2c.clock_control_register | 0xe0; +} + +void scc68070_device::iccr_w(uint8_t data) +{ + LOGMASKED(LOG_I2C, "%s: I2C Clock Control Register Write: %02x\n", machine().describe_context(), data); + m_i2c.clock_control_register = data & 0x1f; +} + +uint8_t scc68070_device::umr_r() +{ + // UART mode register: 80002011 + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_UART, "%s: UART Mode Register Read: %02x\n", machine().describe_context(), m_uart.mode_register); + return m_uart.mode_register | 0x20; +} + +void scc68070_device::umr_w(uint8_t data) +{ + LOGMASKED(LOG_UART, "%s: UART Mode Register Write: %02x\n", machine().describe_context(), data); + m_uart.mode_register = data; +} + +uint8_t scc68070_device::usr_r() +{ + // UART status register: 80002013 + if (!machine().side_effects_disabled()) + { + m_uart.status_register |= (1 << 1); + LOGMASKED(LOG_UART, "%s: UART Status Register Read: %02x\n", machine().describe_context(), m_uart.status_register); + } + return m_uart.status_register | 0x08; // hack for magicard +} + +uint8_t scc68070_device::ucsr_r() +{ + // UART clock select register: 80002015 + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_UART, "%s: UART Clock Select Read: %02x\n", machine().describe_context(), m_uart.clock_select); + return m_uart.clock_select | 0x08; +} + +void scc68070_device::ucsr_w(uint8_t data) +{ + LOGMASKED(LOG_UART, "%s: UART Clock Select Write: %02x\n", machine().describe_context(), data); + m_uart.clock_select = data; +} + +uint8_t scc68070_device::ucr_r() +{ + // UART command register: 80002017 + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_UART, "%s: UART Command Register Read: %02x\n", machine().describe_context(), m_uart.command_register); + return m_uart.command_register | 0x80; +} + +void scc68070_device::ucr_w(uint8_t data) +{ + LOGMASKED(LOG_UART, "%s: UART Command Register Write: %02x\n", machine().describe_context(), data); + m_uart.command_register = data; + uart_rx_check(); + uart_tx_check(); +} + +uint8_t scc68070_device::uth_r() +{ + // UART transmit holding register: 80002019 + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_UART, "%s: UART Transmit Holding Register Read: %02x\n", machine().describe_context(), m_uart.transmit_holding_register); + return m_uart.transmit_holding_register; +} + +void scc68070_device::uth_w(uint8_t data) +{ + LOGMASKED(LOG_UART, "%s: UART Transmit Holding Register Write: %02x ('%c')\n", machine().describe_context(), data, (data >= 0x20 && data < 0x7f) ? data : ' '); + uart_tx(data); + m_uart.transmit_holding_register = data; +} + +uint8_t scc68070_device::urh_r() +{ + // UART receive holding register: 8000201b + if (!machine().side_effects_disabled()) + { + LOGMASKED(LOG_UART, "%s: UART Receive Holding Register Read: %02x\n", machine().describe_context(), m_uart.receive_holding_register); + + if (m_uart_rx_int) + { + m_uart_rx_int = false; + update_ipl(); + } + + m_uart.receive_holding_register = m_uart.receive_buffer[0]; + if (m_uart.receive_pointer >= 0) + { + for(int index = 0; index < m_uart.receive_pointer; index++) { - LOGMASKED(LOG_TIMERS_HF, "%s: Timer Status Register Read: %02x & %04x\n", machine().describe_context(), m_timers.timer_status_register, mem_mask); + m_uart.receive_buffer[index] = m_uart.receive_buffer[index + 1]; } - return (m_timers.timer_status_register << 8) | m_timers.timer_control_register; - case 0x2022/2: + m_uart.receive_pointer--; + } + } + return m_uart.receive_holding_register; +} + +uint16_t scc68070_device::timer_r(offs_t offset, uint16_t mem_mask) +{ + switch (offset) + { + // Timers: 80002020 to 80002029 + case 0x0/2: + if (ACCESSING_BITS_0_7 && !machine().side_effects_disabled()) + { + LOGMASKED(LOG_TIMERS, "%s: Timer Control Register Read: %02x & %04x\n", machine().describe_context(), m_timers.timer_control_register, mem_mask); + } + if (ACCESSING_BITS_8_15 && !machine().side_effects_disabled()) + { + LOGMASKED(LOG_TIMERS_HF, "%s: Timer Status Register Read: %02x & %04x\n", machine().describe_context(), m_timers.timer_status_register, mem_mask); + } + return (m_timers.timer_status_register << 8) | m_timers.timer_control_register; + case 0x2/2: + if (!machine().side_effects_disabled()) LOGMASKED(LOG_TIMERS, "%s: Timer Reload Register Read: %04x & %04x\n", machine().describe_context(), m_timers.reload_register, mem_mask); - return m_timers.reload_register; - case 0x2024/2: + return m_timers.reload_register; + case 0x4/2: + if (!machine().side_effects_disabled()) LOGMASKED(LOG_TIMERS, "%s: Timer 0 Read: %04x & %04x\n", machine().describe_context(), m_timers.timer0, mem_mask); - return m_timers.timer0; - case 0x2026/2: + return m_timers.timer0; + case 0x6/2: + if (!machine().side_effects_disabled()) LOGMASKED(LOG_TIMERS, "%s: Timer 1 Read: %04x & %04x\n", machine().describe_context(), m_timers.timer1, mem_mask); - return m_timers.timer1; - case 0x2028/2: + return m_timers.timer1; + case 0x8/2: + if (!machine().side_effects_disabled()) LOGMASKED(LOG_TIMERS, "%s: Timer 2 Read: %04x & %04x\n", machine().describe_context(), m_timers.timer2, mem_mask); - return m_timers.timer2; - - // PICR1: 80002045 - case 0x2044/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_IRQS, "%s: Peripheral Interrupt Control Register 1 Read: %02x & %04x\n", machine().describe_context(), m_picr1, mem_mask); - } - return m_picr1 & 0x77; - - // PICR2: 80002047 - case 0x2046/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_IRQS, "%s: Peripheral Interrupt Control Register 2 Read: %02x & %04x\n", machine().describe_context(), m_picr2, mem_mask); - } - return m_picr2 & 0x77; - - // DMA controller: 80004000 to 8000406d - case 0x4000/2: - case 0x4040/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Error Register Read: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, m_dma.channel[(offset - 0x2000) / 32].channel_error, mem_mask); - } - if (ACCESSING_BITS_8_15) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Status Register Read: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, m_dma.channel[(offset - 0x2000) / 32].channel_status, mem_mask); - } - return (m_dma.channel[(offset - 0x2000) / 32].channel_status << 8) | m_dma.channel[(offset - 0x2000) / 32].channel_error; - case 0x4004/2: - case 0x4044/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Operation Control Register Read: %02x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, m_dma.channel[(offset - 0x2000) / 32].operation_control, mem_mask); - } - if (ACCESSING_BITS_8_15) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Control Register Read: %02x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, m_dma.channel[(offset - 0x2000) / 32].device_control, mem_mask); - } - return (m_dma.channel[(offset - 0x2000) / 32].device_control << 8) | m_dma.channel[(offset - 0x2000) / 32].operation_control; - case 0x4006/2: - case 0x4046/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Channel Control Register Read: %02x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, m_dma.channel[(offset - 0x2000) / 32].channel_control, mem_mask); - } - if (ACCESSING_BITS_8_15) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Sequence Control Register Read: %02x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, m_dma.channel[(offset - 0x2000) / 32].sequence_control, mem_mask); - } - return (m_dma.channel[(offset - 0x2000) / 32].sequence_control << 8) | m_dma.channel[(offset - 0x2000) / 32].channel_control; - case 0x400a/2: - LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Transfer Counter Read: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, m_dma.channel[(offset - 0x2000) / 32].transfer_counter, mem_mask); - return m_dma.channel[(offset - 0x2000) / 32].transfer_counter; - case 0x400c/2: - case 0x404c/2: - LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Address Counter (High Word) Read: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, (m_dma.channel[(offset - 0x2000) / 32].memory_address_counter >> 16), mem_mask); - return (m_dma.channel[(offset - 0x2000) / 32].memory_address_counter >> 16); - case 0x400e/2: - case 0x404e/2: - LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Address Counter (Low Word) Read: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, m_dma.channel[(offset - 0x2000) / 32].memory_address_counter, mem_mask); - return m_dma.channel[(offset - 0x2000) / 32].memory_address_counter; - case 0x4014/2: - case 0x4054/2: - LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Address Counter (High Word) Read: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, (m_dma.channel[(offset - 0x2000) / 32].device_address_counter >> 16), mem_mask); - return (m_dma.channel[(offset - 0x2000) / 32].device_address_counter >> 16); - case 0x4016/2: - case 0x4056/2: - LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Address Counter (Low Word) Read: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, m_dma.channel[(offset - 0x2000) / 32].device_address_counter, mem_mask); - return m_dma.channel[(offset - 0x2000) / 32].device_address_counter; - - // MMU: 80008000 to 8000807f - case 0x8000/2: // Status / Control register - if (ACCESSING_BITS_0_7) - { // Control - LOGMASKED(LOG_MMU, "%s: MMU Control Read: %02x & %04x\n", machine().describe_context(), m_mmu.control, mem_mask); - return m_mmu.control; - } // Status - else - { - LOGMASKED(LOG_MMU, "%s: MMU Status Read: %02x & %04x\n", machine().describe_context(), m_mmu.status, mem_mask); - return m_mmu.status; - } - case 0x8040/2: - case 0x8048/2: - case 0x8050/2: - case 0x8058/2: - case 0x8060/2: - case 0x8068/2: - case 0x8070/2: - case 0x8078/2: // Attributes (SD0-7) - LOGMASKED(LOG_MMU, "%s: MMU descriptor %d attributes Read: %04x & %04x\n", machine().describe_context(), (offset - 0x4020) / 4, m_mmu.desc[(offset - 0x4020) / 4].attr, mem_mask); - return m_mmu.desc[(offset - 0x4020) / 4].attr; - case 0x8042/2: - case 0x804a/2: - case 0x8052/2: - case 0x805a/2: - case 0x8062/2: - case 0x806a/2: - case 0x8072/2: - case 0x807a/2: // Segment Length (SD0-7) - LOGMASKED(LOG_MMU, "%s: MMU descriptor %d length Read: %04x & %04x\n", machine().describe_context(), (offset - 0x4020) / 4, m_mmu.desc[(offset - 0x4020) / 4].length, mem_mask); - return m_mmu.desc[(offset - 0x4020) / 4].length; - case 0x8044/2: - case 0x804c/2: - case 0x8054/2: - case 0x805c/2: - case 0x8064/2: - case 0x806c/2: - case 0x8074/2: - case 0x807c/2: // Segment Number (SD0-7, A0=1 only) - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_MMU, "%s: MMU descriptor %d segment Read: %02x & %04x\n", machine().describe_context(), (offset - 0x4020) / 4, m_mmu.desc[(offset - 0x4020) / 4].segment, mem_mask); - return m_mmu.desc[(offset - 0x4020) / 4].segment; - } - break; - case 0x8046/2: - case 0x804e/2: - case 0x8056/2: - case 0x805e/2: - case 0x8066/2: - case 0x806e/2: - case 0x8076/2: - case 0x807e/2: // Base Address (SD0-7) - LOGMASKED(LOG_MMU, "%s: MMU descriptor %d base Read: %04x & %04x\n", machine().describe_context(), (offset - 0x4020) / 4, m_mmu.desc[(offset - 0x4020) / 4].base, mem_mask); - return m_mmu.desc[(offset - 0x4020) / 4].base; - default: - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Read: %04x & %04x\n", machine().describe_context(), offset * 2, mem_mask); - break; + return m_timers.timer2; + default: + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_TIMERS | LOG_UNKNOWN, "%s: Timer Unknown Register Read: %04x & %04x\n", machine().describe_context(), offset * 2, mem_mask); + break; } return 0; } -WRITE16_MEMBER( scc68070_device::periphs_w ) +void scc68070_device::timer_w(offs_t offset, uint16_t data, uint16_t mem_mask) { switch (offset) { - // Interrupts: 80001001 - case 0x1000/2: // LIR priority level - LOGMASKED(LOG_IRQS, "%s: LIR Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_lir); - break; - - // I2C interface: 80002001 to 80002009 - case 0x2000/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_I2C, "%s: I2C Data Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_i2c.data_register = data & 0x00ff; - } - break; - case 0x2002/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_I2C, "%s: I2C Address Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_i2c.address_register = data & 0x00ff; - } - break; - case 0x2004/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_I2C, "%s: I2C Status Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_i2c.status_register = data & 0x00ff; - } - break; - case 0x2006/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_I2C, "%s: I2C Control Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_i2c.control_register = data & 0x00ff; - } - break; - case 0x2008/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_I2C, "%s: I2C Clock Control Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_i2c.clock_control_register = data & 0x00ff; - } - break; + // Timers: 80002020 to 80002029 + case 0x0/2: + if (ACCESSING_BITS_0_7) + { + LOGMASKED(LOG_TIMERS, "%s: Timer Control Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); + m_timers.timer_control_register = data & 0x00ff; + } + if (ACCESSING_BITS_8_15) + { + LOGMASKED(LOG_TIMERS_HF, "%s: Timer Status Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); + m_timers.timer_status_register &= ~(data >> 8); + } + break; + case 0x2/2: + LOGMASKED(LOG_TIMERS, "%s: Timer Reload Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_timers.reload_register); + break; + case 0x4/2: + LOGMASKED(LOG_TIMERS, "%s: Timer 0 Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_timers.timer0); + set_timer_callback(0); + break; + case 0x6/2: + LOGMASKED(LOG_TIMERS, "%s: Timer 1 Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_timers.timer1); + break; + case 0x8/2: + LOGMASKED(LOG_TIMERS, "%s: Timer 2 Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_timers.timer2); + break; + default: + LOGMASKED(LOG_TIMERS | LOG_UNKNOWN, "%s: Timer Unknown Register Write: %04x = %04x & %04x\n", machine().describe_context(), offset * 2, data, mem_mask); + break; + } +} - // UART interface: 80002011 to 8000201b - case 0x2010/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Mode Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_uart.mode_register = data & 0x00ff; - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Write: %04x = %04x & %04x\n", machine().describe_context(), offset * 2, data, mem_mask); - } - break; - case 0x2012/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Status Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_uart.status_register = data & 0x00ff; - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Write: %04x = %04x & %04x\n", machine().describe_context(), offset * 2, data, mem_mask); - } - break; - case 0x2014/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Clock Select Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_uart.clock_select = data & 0x00ff; - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Write: %04x = %04x & %04x\n", machine().describe_context(), offset * 2, data, mem_mask); - } - break; - case 0x2016/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Command Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_uart.command_register = data & 0x00ff; - uart_rx_check(); - uart_tx_check(); - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Write: %04x = %04x & %04x\n", machine().describe_context(), offset * 2, data, mem_mask); - } - break; - case 0x2018/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Transmit Holding Register Write: %04x & %04x: %c\n", machine().describe_context(), data, mem_mask, (data >= 0x20 && data < 0x7f) ? (data & 0x00ff) : ' '); - uart_tx(data & 0x00ff); - m_uart.transmit_holding_register = data & 0x00ff; - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Write: %04x = %04x & %04x\n", machine().describe_context(), offset * 2, data, mem_mask); - } - break; - case 0x201a/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_UART, "%s: UART Receive Holding Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_uart.receive_holding_register = data & 0x00ff; - } - else - { - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Write: %04x = %04x & %04x\n", machine().describe_context(), offset * 2, data, mem_mask); - } - break; +uint16_t scc68070_device::dma_r(offs_t offset, uint16_t mem_mask) +{ + switch (offset) + { + // DMA controller: 80004000 to 8000406d + case 0x00/2: + case 0x40/2: + if (ACCESSING_BITS_0_7 && !machine().side_effects_disabled()) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Error Register Read: %04x & %04x\n", machine().describe_context(), offset / 32, m_dma.channel[offset / 32].channel_error, mem_mask); + } + if (ACCESSING_BITS_8_15 && !machine().side_effects_disabled()) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Status Register Read: %04x & %04x\n", machine().describe_context(), offset / 32, m_dma.channel[offset / 32].channel_status, mem_mask); + } + return (m_dma.channel[offset / 32].channel_status << 8) | m_dma.channel[offset / 32].channel_error; + case 0x04/2: + case 0x44/2: + if (ACCESSING_BITS_0_7 && !machine().side_effects_disabled()) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Operation Control Register Read: %02x & %04x\n", machine().describe_context(), offset / 32, m_dma.channel[offset / 32].operation_control, mem_mask); + } + if (ACCESSING_BITS_8_15 && !machine().side_effects_disabled()) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Control Register Read: %02x & %04x\n", machine().describe_context(), offset / 32, m_dma.channel[offset / 32].device_control, mem_mask); + } + return (m_dma.channel[offset / 32].device_control << 8) | m_dma.channel[offset / 32].operation_control; + case 0x06/2: + case 0x46/2: + if (ACCESSING_BITS_0_7 && !machine().side_effects_disabled()) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Channel Control Register Read: %02x & %04x\n", machine().describe_context(), offset / 32, m_dma.channel[offset / 32].channel_control, mem_mask); + } + if (ACCESSING_BITS_8_15 && !machine().side_effects_disabled()) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Sequence Control Register Read: %02x & %04x\n", machine().describe_context(), offset / 32, m_dma.channel[offset / 32].sequence_control, mem_mask); + } + return (m_dma.channel[offset / 32].sequence_control << 8) | m_dma.channel[offset / 32].channel_control; + case 0x0a/2: + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Transfer Counter Read: %04x & %04x\n", machine().describe_context(), offset / 32, m_dma.channel[offset / 32].transfer_counter, mem_mask); + return m_dma.channel[offset / 32].transfer_counter; + case 0x0c/2: + case 0x4c/2: + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Address Counter (High Word) Read: %04x & %04x\n", machine().describe_context(), offset / 32, (m_dma.channel[offset / 32].memory_address_counter >> 16), mem_mask); + return (m_dma.channel[offset / 32].memory_address_counter >> 16); + case 0x0e/2: + case 0x4e/2: + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Address Counter (Low Word) Read: %04x & %04x\n", machine().describe_context(), offset / 32, m_dma.channel[offset / 32].memory_address_counter, mem_mask); + return m_dma.channel[offset / 32].memory_address_counter; + case 0x14/2: + case 0x54/2: + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Address Counter (High Word) Read: %04x & %04x\n", machine().describe_context(), offset / 32, (m_dma.channel[offset / 32].device_address_counter >> 16), mem_mask); + return (m_dma.channel[offset / 32].device_address_counter >> 16); + case 0x16/2: + case 0x56/2: + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Address Counter (Low Word) Read: %04x & %04x\n", machine().describe_context(), offset / 32, m_dma.channel[offset / 32].device_address_counter, mem_mask); + return m_dma.channel[offset / 32].device_address_counter; + + default: + LOGMASKED(LOG_DMA | LOG_UNKNOWN, "%s: DMA Unknown Register Read: %04x & %04x\n", machine().describe_context(), offset * 2, mem_mask); + break; + } - // Timers: 80002020 to 80002029 - case 0x2020/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_TIMERS, "%s: Timer Control Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_timers.timer_control_register = data & 0x00ff; - } - if (ACCESSING_BITS_8_15) - { - LOGMASKED(LOG_TIMERS_HF, "%s: Timer Status Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_timers.timer_status_register &= ~(data >> 8); - } - break; - case 0x2022/2: - LOGMASKED(LOG_TIMERS, "%s: Timer Reload Register Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_timers.reload_register); - break; - case 0x2024/2: - LOGMASKED(LOG_TIMERS, "%s: Timer 0 Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_timers.timer0); - set_timer_callback(0); - break; - case 0x2026/2: - LOGMASKED(LOG_TIMERS, "%s: Timer 1 Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_timers.timer1); - break; - case 0x2028/2: - LOGMASKED(LOG_TIMERS, "%s: Timer 2 Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - COMBINE_DATA(&m_timers.timer2); - break; + return 0; +} - // PICR1: 80002045 - case 0x2044/2: - if (ACCESSING_BITS_0_7) +void scc68070_device::dma_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + switch (offset) + { + // DMA controller: 80004000 to 8000406d + case 0x00/2: + case 0x40/2: + if (ACCESSING_BITS_0_7) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Error (invalid) Write: %04x & %04x\n", machine().describe_context(), offset / 32, data, mem_mask); + } + if (ACCESSING_BITS_8_15) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Status Write: %04x & %04x\n", machine().describe_context(), offset / 32, data, mem_mask); + m_dma.channel[offset / 32].channel_status &= ~((data >> 8) & 0xb0); + update_ipl(); + } + break; + case 0x04/2: + case 0x44/2: + if (ACCESSING_BITS_0_7) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Operation Control Register Write: %04x & %04x\n", machine().describe_context(), offset / 32, data, mem_mask); + m_dma.channel[offset / 32].operation_control = data & 0x00ff; + } + if (ACCESSING_BITS_8_15) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Control Register Write: %04x & %04x\n", machine().describe_context(), offset / 32, data, mem_mask); + m_dma.channel[offset / 32].device_control = data >> 8; + } + break; + case 0x06/2: + case 0x46/2: + if (ACCESSING_BITS_0_7) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Channel Control Register Write: %04x & %04x\n", machine().describe_context(), offset / 32, data, mem_mask); + m_dma.channel[offset / 32].channel_control = data & 0x007f; + if (data & CCR_SO) { - LOGMASKED(LOG_IRQS, "%s: Peripheral Interrupt Control Register 1 Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_picr1 = data & 0x0077; - switch (data & 0x0088) - { - case 0x08: - if (m_timer_int) - { - m_timer_int = false; - update_ipl(); - } - break; - - case 0x80: - if (m_i2c_int) - { - m_i2c_int = false; - update_ipl(); - } - break; - - case 0x88: - if (m_timer_int || m_i2c_int) - { - m_timer_int = false; - m_i2c_int = false; - update_ipl(); - } - break; - } + m_dma.channel[offset / 32].channel_status |= CSR_COC; } - break; + update_ipl(); + } + if (ACCESSING_BITS_8_15) + { + LOGMASKED(LOG_DMA, "%s: DMA(%d) Sequence Control Register Write: %04x & %04x\n", machine().describe_context(), offset / 32, data, mem_mask); + m_dma.channel[offset / 32].sequence_control = data >> 8; + } + break; + case 0x0a/2: + LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Transfer Counter Write: %04x & %04x\n", machine().describe_context(), offset / 32, data, mem_mask); + COMBINE_DATA(&m_dma.channel[offset / 32].transfer_counter); + break; + case 0x0c/2: + case 0x4c/2: + LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Address Counter (High Word) Write: %04x & %04x\n", machine().describe_context(), offset / 32, data, mem_mask); + m_dma.channel[offset / 32].memory_address_counter &= ~(mem_mask << 16); + m_dma.channel[offset / 32].memory_address_counter |= data << 16; + break; + case 0x0e/2: + case 0x4e/2: + LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Address Counter (Low Word) Write: %04x & %04x\n", machine().describe_context(), offset / 32, data, mem_mask); + m_dma.channel[offset / 32].memory_address_counter &= ~mem_mask; + m_dma.channel[offset / 32].memory_address_counter |= data; + break; + case 0x14/2: + case 0x54/2: + LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Address Counter (High Word) Write: %04x & %04x\n", machine().describe_context(), offset / 32, data, mem_mask); + m_dma.channel[offset / 32].device_address_counter &= ~(mem_mask << 16); + m_dma.channel[offset / 32].device_address_counter |= data << 16; + break; + case 0x16/2: + case 0x56/2: + LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Address Counter (Low Word) Write: %04x & %04x\n", machine().describe_context(), offset / 32, data, mem_mask); + m_dma.channel[offset / 32].device_address_counter &= ~mem_mask; + m_dma.channel[offset / 32].device_address_counter |= data; + break; + default: + LOGMASKED(LOG_DMA | LOG_UNKNOWN, "%s: DMA Unknown Register Write: %04x = %04x & %04x\n", machine().describe_context(), offset * 2, data, mem_mask); + break; + } +} - // PICR2: 80002047 - case 0x2046/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_IRQS, "%s: Peripheral Interrupt Control Register 2 Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_picr2 = data & 0x0077; - switch (data & 0x0088) - { - case 0x08: - if (m_uart_tx_int) - { - m_uart_tx_int = false; - update_ipl(); - } - break; - - case 0x80: - if (m_uart_rx_int) - { - m_uart_rx_int = false; - update_ipl(); - } - break; - - case 0x88: - if (m_uart_tx_int || m_uart_rx_int) - { - m_uart_tx_int = false; - m_uart_rx_int = false; - update_ipl(); - } - break; - } - } - break; +uint16_t scc68070_device::mmu_r(offs_t offset, uint16_t mem_mask) +{ + switch (offset) + { + // MMU: 80008000 to 8000807f + case 0x00/2: // Status / Control register + if (ACCESSING_BITS_0_7) + { // Control + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_MMU, "%s: MMU Control Read: %02x & %04x\n", machine().describe_context(), m_mmu.control, mem_mask); + return m_mmu.control; + } // Status + else + { + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_MMU, "%s: MMU Status Read: %02x & %04x\n", machine().describe_context(), m_mmu.status, mem_mask); + return m_mmu.status; + } + case 0x40/2: + case 0x48/2: + case 0x50/2: + case 0x58/2: + case 0x60/2: + case 0x68/2: + case 0x70/2: + case 0x78/2: // Attributes (SD0-7) + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_MMU, "%s: MMU descriptor %d attributes Read: %04x & %04x\n", machine().describe_context(), (offset - 0x20) / 4, m_mmu.desc[(offset - 0x20) / 4].attr, mem_mask); + return m_mmu.desc[(offset - 0x20) / 4].attr; + case 0x42/2: + case 0x4a/2: + case 0x52/2: + case 0x5a/2: + case 0x62/2: + case 0x6a/2: + case 0x72/2: + case 0x7a/2: // Segment Length (SD0-7) + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_MMU, "%s: MMU descriptor %d length Read: %04x & %04x\n", machine().describe_context(), (offset - 0x20) / 4, m_mmu.desc[(offset - 0x20) / 4].length, mem_mask); + return m_mmu.desc[(offset - 0x20) / 4].length; + case 0x44/2: + case 0x4c/2: + case 0x54/2: + case 0x5c/2: + case 0x64/2: + case 0x6c/2: + case 0x74/2: + case 0x7c/2: // Segment Number (SD0-7, A0=1 only) + if (ACCESSING_BITS_0_7) + { + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_MMU, "%s: MMU descriptor %d segment Read: %02x & %04x\n", machine().describe_context(), (offset - 0x20) / 4, m_mmu.desc[(offset - 0x20) / 4].segment, mem_mask); + return m_mmu.desc[(offset - 0x20) / 4].segment; + } + break; + case 0x46/2: + case 0x4e/2: + case 0x56/2: + case 0x5e/2: + case 0x66/2: + case 0x6e/2: + case 0x76/2: + case 0x7e/2: // Base Address (SD0-7) + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_MMU, "%s: MMU descriptor %d base Read: %04x & %04x\n", machine().describe_context(), (offset - 0x20) / 4, m_mmu.desc[(offset - 0x20) / 4].base, mem_mask); + return m_mmu.desc[(offset - 0x20) / 4].base; + default: + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_MMU | LOG_UNKNOWN, "%s: MMU Unknown Register Read: %04x & %04x\n", machine().describe_context(), offset * 2, mem_mask); + break; + } - // DMA controller: 80004000 to 8000406d - case 0x4000/2: - case 0x4040/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Error (invalid) Write: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, data, mem_mask); - } - if (ACCESSING_BITS_8_15) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Status Write: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, data, mem_mask); - m_dma.channel[(offset - 0x2000) / 32].channel_status &= ~((data >> 8) & 0xb0); - update_ipl(); - } - break; - case 0x4004/2: - case 0x4044/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Operation Control Register Write: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, data, mem_mask); - m_dma.channel[(offset - 0x2000) / 32].operation_control = data & 0x00ff; - } - if (ACCESSING_BITS_8_15) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Control Register Write: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, data, mem_mask); - m_dma.channel[(offset - 0x2000) / 32].device_control = data >> 8; - } - break; - case 0x4006/2: - case 0x4046/2: - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Channel Control Register Write: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, data, mem_mask); - m_dma.channel[(offset - 0x2000) / 32].channel_control = data & 0x007f; - if (data & CCR_SO) - { - m_dma.channel[(offset - 0x2000) / 32].channel_status |= CSR_COC; - } - update_ipl(); - } - if (ACCESSING_BITS_8_15) - { - LOGMASKED(LOG_DMA, "%s: DMA(%d) Sequence Control Register Write: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, data, mem_mask); - m_dma.channel[(offset - 0x2000) / 32].sequence_control = data >> 8; - } - break; - case 0x400a/2: - LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Transfer Counter Write: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, data, mem_mask); - COMBINE_DATA(&m_dma.channel[(offset - 0x2000) / 32].transfer_counter); - break; - case 0x400c/2: - case 0x404c/2: - LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Address Counter (High Word) Write: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, data, mem_mask); - m_dma.channel[(offset - 0x2000) / 32].memory_address_counter &= ~(mem_mask << 16); - m_dma.channel[(offset - 0x2000) / 32].memory_address_counter |= data << 16; - break; - case 0x400e/2: - case 0x404e/2: - LOGMASKED(LOG_DMA, "%s: DMA(%d) Memory Address Counter (Low Word) Write: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, data, mem_mask); - m_dma.channel[(offset - 0x2000) / 32].memory_address_counter &= ~mem_mask; - m_dma.channel[(offset - 0x2000) / 32].memory_address_counter |= data; - break; - case 0x4014/2: - case 0x4054/2: - LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Address Counter (High Word) Write: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, data, mem_mask); - m_dma.channel[(offset - 0x2000) / 32].device_address_counter &= ~(mem_mask << 16); - m_dma.channel[(offset - 0x2000) / 32].device_address_counter |= data << 16; - break; - case 0x4016/2: - case 0x4056/2: - LOGMASKED(LOG_DMA, "%s: DMA(%d) Device Address Counter (Low Word) Write: %04x & %04x\n", machine().describe_context(), (offset - 0x2000) / 32, data, mem_mask); - m_dma.channel[(offset - 0x2000) / 32].device_address_counter &= ~mem_mask; - m_dma.channel[(offset - 0x2000) / 32].device_address_counter |= data; - break; + return 0; +} - // MMU: 80008000 to 8000807f - case 0x8000/2: // Status / Control register - if (ACCESSING_BITS_0_7) - { // Control - LOGMASKED(LOG_MMU, "%s: MMU Control Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - m_mmu.control = data & 0x00ff; - } // Status - else - { - LOGMASKED(LOG_MMU, "%s: MMU Status (invalid) Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); - } - break; - case 0x8040/2: - case 0x8048/2: - case 0x8050/2: - case 0x8058/2: - case 0x8060/2: - case 0x8068/2: - case 0x8070/2: - case 0x8078/2: // Attributes (SD0-7) - LOGMASKED(LOG_MMU, "%s: MMU descriptor %d attributes Write: %04x & %04x\n", machine().describe_context(), (offset - 0x4020) / 4, data, mem_mask); - COMBINE_DATA(&m_mmu.desc[(offset - 0x4020) / 4].attr); - break; - case 0x8042/2: - case 0x804a/2: - case 0x8052/2: - case 0x805a/2: - case 0x8062/2: - case 0x806a/2: - case 0x8072/2: - case 0x807a/2: // Segment Length (SD0-7) - LOGMASKED(LOG_MMU, "%s: MMU descriptor %d length Write: %04x & %04x\n", machine().describe_context(), (offset - 0x4020) / 4, data, mem_mask); - COMBINE_DATA(&m_mmu.desc[(offset - 0x4020) / 4].length); - break; - case 0x8044/2: - case 0x804c/2: - case 0x8054/2: - case 0x805c/2: - case 0x8064/2: - case 0x806c/2: - case 0x8074/2: - case 0x807c/2: // Segment Number (SD0-7, A0=1 only) - if (ACCESSING_BITS_0_7) - { - LOGMASKED(LOG_MMU, "%s: MMU descriptor %d segment Write: %04x & %04x\n", machine().describe_context(), (offset - 0x4020) / 4, data, mem_mask); - m_mmu.desc[(offset - 0x4020) / 4].segment = data & 0x00ff; - } - break; - case 0x8046/2: - case 0x804e/2: - case 0x8056/2: - case 0x805e/2: - case 0x8066/2: - case 0x806e/2: - case 0x8076/2: - case 0x807e/2: // Base Address (SD0-7) - LOGMASKED(LOG_MMU, "%s: MMU descriptor %d base Write: %04x & %04x\n", machine().describe_context(), (offset - 0x4020) / 4, data, mem_mask); - COMBINE_DATA(&m_mmu.desc[(offset - 0x4020) / 4].base); - break; - default: - LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Write: %04x = %04x & %04x\n", machine().describe_context(), offset * 2, data, mem_mask); - break; +void scc68070_device::mmu_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + switch (offset) + { + // MMU: 80008000 to 8000807f + case 0x00/2: // Status / Control register + if (ACCESSING_BITS_0_7) + { // Control + LOGMASKED(LOG_MMU, "%s: MMU Control Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); + m_mmu.control = data & 0x00ff; + } // Status + else + { + LOGMASKED(LOG_MMU, "%s: MMU Status (invalid) Write: %04x & %04x\n", machine().describe_context(), data, mem_mask); + } + break; + case 0x40/2: + case 0x48/2: + case 0x50/2: + case 0x58/2: + case 0x60/2: + case 0x68/2: + case 0x70/2: + case 0x78/2: // Attributes (SD0-7) + LOGMASKED(LOG_MMU, "%s: MMU descriptor %d attributes Write: %04x & %04x\n", machine().describe_context(), (offset - 0x20) / 4, data, mem_mask); + COMBINE_DATA(&m_mmu.desc[(offset - 0x20) / 4].attr); + break; + case 0x42/2: + case 0x4a/2: + case 0x52/2: + case 0x5a/2: + case 0x62/2: + case 0x6a/2: + case 0x72/2: + case 0x7a/2: // Segment Length (SD0-7) + LOGMASKED(LOG_MMU, "%s: MMU descriptor %d length Write: %04x & %04x\n", machine().describe_context(), (offset - 0x20) / 4, data, mem_mask); + COMBINE_DATA(&m_mmu.desc[(offset - 0x20) / 4].length); + break; + case 0x44/2: + case 0x4c/2: + case 0x54/2: + case 0x5c/2: + case 0x64/2: + case 0x6c/2: + case 0x74/2: + case 0x7c/2: // Segment Number (SD0-7, A0=1 only) + if (ACCESSING_BITS_0_7) + { + LOGMASKED(LOG_MMU, "%s: MMU descriptor %d segment Write: %04x & %04x\n", machine().describe_context(), (offset - 0x20) / 4, data, mem_mask); + m_mmu.desc[(offset - 0x20) / 4].segment = data & 0x00ff; + } + break; + case 0x46/2: + case 0x4e/2: + case 0x56/2: + case 0x5e/2: + case 0x66/2: + case 0x6e/2: + case 0x76/2: + case 0x7e/2: // Base Address (SD0-7) + LOGMASKED(LOG_MMU, "%s: MMU descriptor %d base Write: %04x & %04x\n", machine().describe_context(), (offset - 0x20) / 4, data, mem_mask); + COMBINE_DATA(&m_mmu.desc[(offset - 0x20) / 4].base); + break; + default: + LOGMASKED(LOG_MMU | LOG_UNKNOWN, "%s: Unknown Register Write: %04x = %04x & %04x\n", machine().describe_context(), offset * 2, data, mem_mask); + break; } } diff --git a/src/devices/machine/scc68070.h b/src/devices/machine/scc68070.h index 0a785f25695..edd9559056c 100644 --- a/src/devices/machine/scc68070.h +++ b/src/devices/machine/scc68070.h @@ -266,6 +266,9 @@ protected: virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return (clocks + 2 - 1) / 2; } virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return (cycles * 2); } + // m68000_base_device overrides + virtual void m68k_reset_peripherals() override; + private: void internal_map(address_map &map); void cpu_space_map(address_map &map); @@ -273,8 +276,49 @@ private: void update_ipl(); uint8_t iack_r(offs_t offset); - DECLARE_READ16_MEMBER(periphs_r); - DECLARE_WRITE16_MEMBER(periphs_w); + // Interrupts + uint8_t lir_r(); + void lir_w(uint8_t data); + uint8_t picr1_r(); + void picr1_w(uint8_t data); + uint8_t picr2_r(); + void picr2_w(uint8_t data); + + // I2C interface + uint8_t idr_r(); + void idr_w(uint8_t data); + uint8_t iar_r(); + void iar_w(uint8_t data); + uint8_t isr_r(); + void isr_w(uint8_t data); + uint8_t icr_r(); + void icr_w(uint8_t data); + uint8_t iccr_r(); + void iccr_w(uint8_t data); + + // UART interface + uint8_t umr_r(); + void umr_w(uint8_t data); + uint8_t usr_r(); + uint8_t ucsr_r(); + void ucsr_w(uint8_t data); + uint8_t ucr_r(); + void ucr_w(uint8_t data); + uint8_t uth_r(); + void uth_w(uint8_t data); + uint8_t urh_r(); + + // Timers + uint16_t timer_r(offs_t offset, uint16_t mem_mask); + void timer_w(offs_t offset, uint16_t data, uint16_t mem_mask); + + // DMA controller + uint16_t dma_r(offs_t offset, uint16_t mem_mask); + void dma_w(offs_t offset, uint16_t data, uint16_t mem_mask); + + // MMU + uint16_t mmu_r(offs_t offset, uint16_t mem_mask); + void mmu_w(offs_t offset, uint16_t data, uint16_t mem_mask); void uart_rx_check(); void uart_tx_check(); @@ -297,7 +341,7 @@ private: int m_int1_line; int m_int2_line; - uint16_t m_lir; + uint8_t m_lir; uint8_t m_picr1; uint8_t m_picr2; bool m_timer_int; -- cgit v1.2.3