diff --git a/src/devices/machine/sa1110.cpp b/src/devices/machine/sa1110.cpp index 218819f44ad..480f9998131 100644 --- a/src/devices/machine/sa1110.cpp +++ b/src/devices/machine/sa1110.cpp @@ -27,7 +27,8 @@ #define LOG_INTC (1 << 16) #define LOG_PPC (1 << 17) #define LOG_DMA (1 << 18) -#define LOG_ALL (LOG_UNKNOWN | LOG_ICP | LOG_UART3 | LOG_MCP | LOG_OSTIMER | LOG_RTC | LOG_POWER | LOG_RESET | LOG_GPIO | LOG_INTC | LOG_PPC | LOG_DMA) +#define LOG_UDC (1 << 19) +#define LOG_ALL (LOG_UNKNOWN | LOG_ICP | LOG_UART3 | LOG_MCP | LOG_OSTIMER | LOG_RTC | LOG_POWER | LOG_RESET | LOG_GPIO | LOG_INTC | LOG_PPC | LOG_DMA | LOG_UDC) #define VERBOSE (0) #include "logmacro.h" @@ -47,6 +48,109 @@ sa1110_periphs_device::sa1110_periphs_device(const machine_config &mconfig, cons { } +/* + + Intel SA-1110 UDC - USB Device Controller + + pg. 235 to 258 Intel StrongARM SA-1110 Microprocessor Developer's Manual + +*/ + +uint32_t sa1110_periphs_device::udc_r(offs_t offset, uint32_t mem_mask) +{ + switch (offset) + { + case REG_UDCCR: + LOGMASKED(LOG_UDC, "%s: udc_r: UDC Control Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udccr, mem_mask); + return m_udc_regs.udccr; + case REG_UDCAR: + LOGMASKED(LOG_UDC, "%s: udc_r: UDC Address Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udcar, mem_mask); + return m_udc_regs.udcar; + case REG_UDCOMP: + LOGMASKED(LOG_UDC, "%s: udc_r: UDC OUT Max Packet Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udcomp, mem_mask); + return m_udc_regs.udcomp; + case REG_UDCIMP: + LOGMASKED(LOG_UDC, "%s: udc_r: UDC IN Max Packet Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udcimp, mem_mask); + return m_udc_regs.udcimp; + case REG_UDCCS0: + LOGMASKED(LOG_UDC, "%s: udc_r: UDC Endpoint 0 Control/Status Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udccs0, mem_mask); + return m_udc_regs.udccs0; + case REG_UDCCS1: + LOGMASKED(LOG_UDC, "%s: udc_r: UDC Endpoint 1 (OUT) Control/Status Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udccs1, mem_mask); + return m_udc_regs.udccs1; + case REG_UDCCS2: + LOGMASKED(LOG_UDC, "%s: udc_r: UDC Endpoint 2 (IN) Control/Status Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udccs2, mem_mask); + return m_udc_regs.udccs2; + case REG_UDCD0: + LOGMASKED(LOG_UDC, "%s: udc_r: UDC Endpoint 0 Data Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask); + return 0; + case REG_UDCWC: + LOGMASKED(LOG_UDC, "%s: udc_r: UDC Endpoint 0 Write Count Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udcwc, mem_mask); + return m_udc_regs.udcwc; + case REG_UDCDR: + //const uint32_t data = udc_rx_fifo_pop(); + LOGMASKED(LOG_UDC, "%s: udc_r: UDC Data Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask); + return 0; + case REG_UDCSR: + LOGMASKED(LOG_UDC, "%s: udc_r: UDC Status/Interrupt Register: %08x & %08x\n", machine().describe_context(), m_udc_regs.udcsr, mem_mask); + return m_udc_regs.udcsr; + default: + LOGMASKED(LOG_UDC | LOG_UNKNOWN, "%s: udc_r: Unknown address: %08x & %08x\n", machine().describe_context(), UDC_BASE_ADDR | (offset << 2), mem_mask); + return 0; + } +} + +void sa1110_periphs_device::udc_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + switch (offset) + { + case REG_UDCCR: + LOGMASKED(LOG_UDC, "%s: udc_w: UDC Control Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_udc_regs.udccr); + break; + case REG_UDCAR: + LOGMASKED(LOG_UDC, "%s: udc_w: UDC Address Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_udc_regs.udcar); + break; + case REG_UDCOMP: + LOGMASKED(LOG_UDC, "%s: udc_w: UDC OUT Max Packet Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_udc_regs.udcomp); + break; + case REG_UDCIMP: + LOGMASKED(LOG_UDC, "%s: udc_w: UDC IN Max Packet Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_udc_regs.udcimp); + break; + case REG_UDCCS0: + LOGMASKED(LOG_UDC, "%s: udc_w: UDC Endpoint 0 Control/Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_udc_regs.udccs0); + break; + case REG_UDCCS1: + LOGMASKED(LOG_UDC, "%s: udc_w: UDC Endpoint 1 (OUT) Control/Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_udc_regs.udccs1); + break; + case REG_UDCCS2: + LOGMASKED(LOG_UDC, "%s: udc_w: UDC Endpoint 2 (IN) Control/Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_udc_regs.udccs2); + break; + case REG_UDCD0: + LOGMASKED(LOG_UDC, "%s: udc_w: UDC Endpoint 0 Data Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case REG_UDCWC: + LOGMASKED(LOG_UDC, "%s: udc_w: UDC Endpoint 0 Write Count Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + COMBINE_DATA(&m_udc_regs.udcwc); + break; + case REG_UDCDR: + LOGMASKED(LOG_UDC, "%s: udc_w: UDC Data Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + return; + case REG_UDCSR: + LOGMASKED(LOG_UDC, "%s: udc_w: UDC Status/Interrupt Register = %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + default: + LOGMASKED(LOG_UDC | LOG_UNKNOWN, "%s: udc_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), UDC_BASE_ADDR | (offset << 2), data, mem_mask); + break; + } +} + /* Intel SA-1110 ICP - Serial Port 2 @@ -2193,6 +2297,16 @@ void sa1110_periphs_device::dma_w(offs_t offset, uint32_t data, uint32_t mem_mas void sa1110_periphs_device::device_start() { + save_item(NAME(m_udc_regs.udccr)); + save_item(NAME(m_udc_regs.udcar)); + save_item(NAME(m_udc_regs.udcomp)); + save_item(NAME(m_udc_regs.udcimp)); + save_item(NAME(m_udc_regs.udccs0)); + save_item(NAME(m_udc_regs.udccs1)); + save_item(NAME(m_udc_regs.udccs2)); + save_item(NAME(m_udc_regs.udcwc)); + save_item(NAME(m_udc_regs.udcsr)); + save_item(NAME(m_icp_regs.uart.utcr)); save_item(NAME(m_icp_regs.uart.utsr0)); save_item(NAME(m_icp_regs.uart.utsr1)); @@ -2339,6 +2453,16 @@ void sa1110_periphs_device::device_start() void sa1110_periphs_device::device_reset() { + m_udc_regs.udccr = (1 << UDCCR_SUSM_BIT) | (1 << UDCCR_UDD_BIT); + m_udc_regs.udcar = 0; + m_udc_regs.udcomp = 8; + m_udc_regs.udcimp = 8; + m_udc_regs.udccs0 = 0; + m_udc_regs.udccs1 = 0; + m_udc_regs.udccs2 = 0; + m_udc_regs.udcwc = 0; + m_udc_regs.udcsr = 0; + // init ICP memset(m_icp_regs.uart.utcr, 0, sizeof(uint32_t) * 4); m_icp_regs.uart.utsr0 = 0; diff --git a/src/devices/machine/sa1110.h b/src/devices/machine/sa1110.h index 64900bf163b..7693e09dfa3 100644 --- a/src/devices/machine/sa1110.h +++ b/src/devices/machine/sa1110.h @@ -46,6 +46,8 @@ public: auto uart3_tx_out() { return m_uart3_tx_out.bind(); } + uint32_t udc_r(offs_t offset, uint32_t mem_mask = ~0); + void udc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); uint32_t icp_r(offs_t offset, uint32_t mem_mask = ~0); void icp_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); uint32_t uart3_r(offs_t offset, uint32_t mem_mask = ~0); @@ -154,6 +156,19 @@ protected: // register offsets enum { + UDC_BASE_ADDR = 0x80000000, + REG_UDCCR = (0x00000000 >> 2), + REG_UDCAR = (0x00000004 >> 2), + REG_UDCOMP = (0x00000008 >> 2), + REG_UDCIMP = (0x0000000c >> 2), + REG_UDCCS0 = (0x00000010 >> 2), + REG_UDCCS1 = (0x00000014 >> 2), + REG_UDCCS2 = (0x00000018 >> 2), + REG_UDCD0 = (0x0000001c >> 2), + REG_UDCWC = (0x00000020 >> 2), + REG_UDCDR = (0x00000028 >> 2), + REG_UDCSR = (0x00000030 >> 2), + ICP_BASE_ADDR = 0x80030000, REG_UTCR4 = (0x00000010 >> 2), REG_HSCR0 = (0x00000060 >> 2), @@ -253,6 +268,53 @@ protected: // register contents enum : uint32_t { + UDCCR_UDD_BIT = 0, + UDCCR_UDA_BIT = 1, + UDCCR_RESM_BIT = 2, + UDCCR_EIM_BIT = 3, + UDCCR_RIM_BIT = 4, + UDCCR_TIM_BIT = 5, + UDCCR_SUSM_BIT = 6, + UDCCR_WRITE_MASK = 0x7d, + + UDCAR_WRITE_MASK = 0x7f, + + UDCOMP_WRITE_MASK = 0xff, + + UDCIMP_WRITE_MASK = 0xff, + + UDCCS0_OPR_BIT = 0, + UDCCS0_IPR_BIT = 1, + UDCCS0_SST_BIT = 2, + UDCCS0_FST_BIT = 3, + UDCCS0_DE_BIT = 4, + UDCCS0_SE_BIT = 5, + UDCCS0_SO_BIT = 6, + UDCCS0_SSE_BIT = 7, + + UDCCS1_RFS_BIT = 0, + UDCCS1_RPC_BIT = 1, + UDCCS1_RPE_BIT = 2, + UDCCS1_SST_BIT = 3, + UDCCS1_FST_BIT = 4, + UDCCS1_RNE_BIT = 5, + + UDCCS2_TFS_BIT = 0, + UDCCS2_TPC_BIT = 1, + UDCCS2_TPE_BIT = 2, + UDCCS2_TUR_BIT = 3, + UDCCS2_SST_BIT = 4, + UDCCS2_FST_BIT = 5, + + UDCWC_WRITE_MASK = 0x0f, + + UDCSR_EIR_BIT = 0, + UDCSR_RIR_BIT = 1, + UDCSR_TIR_BIT = 2, + UDCSR_SUSIR_BIT = 3, + UDCSR_RESIR_BIT = 4, + UDCSR_RSTIR_BIT = 5, + UART3_FIFO_PRE = 8, UART3_FIFO_FRE = 9, UART3_FIFO_ROR = 10, @@ -462,6 +524,19 @@ protected: MCP_TELECOM_OVERRUN = 7 }; + struct udc_regs + { + uint32_t udccr; + uint32_t udcar; + uint32_t udcomp; + uint32_t udcimp; + uint32_t udccs0; + uint32_t udccs1; + uint32_t udccs2; + uint32_t udcwc; + uint32_t udcsr; + }; + struct uart_regs { uint32_t utcr[4]; @@ -640,6 +715,7 @@ protected: uint32_t dbt[2]; }; + udc_regs m_udc_regs; uart_regs m_uart_regs; icp_regs m_icp_regs; mcp_regs m_mcp_regs; diff --git a/src/devices/machine/sa1111.cpp b/src/devices/machine/sa1111.cpp index c33cf0ba23e..4fbd5545355 100644 --- a/src/devices/machine/sa1111.cpp +++ b/src/devices/machine/sa1111.cpp @@ -504,14 +504,16 @@ TIMER_CALLBACK_MEMBER(sa1111_device::audio_tx_dma_callback) m_audio_regs.sadtcs ^= (1 << SADTCS_TBIU_BIT); m_audio_regs.sadta = m_audio_regs.sadts[1 - buf]; m_audio_regs.sadtcc = m_audio_regs.sadtc[1 - buf]; + if (!BIT(m_audio_regs.sadtcs, s_start_masks[1 - buf])) + { + m_audio_regs.tx_dma_timer->adjust(attotime::never); + } } } TIMER_CALLBACK_MEMBER(sa1111_device::audio_tx_callback) { - const uint32_t data = audio_tx_fifo_pop(); - LOGMASKED(LOG_AUDIO_DMA, "audio_tx_callback: obtained data %08x, passing to codec\n", data); - m_i2s_out(data); + m_i2s_out(audio_tx_fifo_pop()); } void sa1111_device::audio_update_mode() @@ -588,6 +590,11 @@ void sa1111_device::audio_set_tx_dma_enabled(bool enabled) { m_audio_regs.tx_timer->adjust(attotime::never); m_audio_regs.tx_dma_timer->adjust(attotime::never); + + set_irq_line(INT_AUDTXA, 0); + set_irq_line(INT_AUDTXB, 0); + set_irq_line(INT_AUDTFS, 0); + set_irq_line(INT_AUDTUR, 0); } } @@ -608,6 +615,11 @@ void sa1111_device::audio_set_rx_dma_enabled(bool enabled) { m_audio_regs.rx_timer->adjust(attotime::never); m_audio_regs.rx_dma_timer->adjust(attotime::never); + + set_irq_line(INT_AUDRXA, 0); + set_irq_line(INT_AUDRXB, 0); + set_irq_line(INT_AUDRFS, 0); + set_irq_line(INT_AUDROR, 0); } } @@ -621,7 +633,7 @@ void sa1111_device::audio_start_tx_dma(const uint32_t buf) const uint32_t divisor = ((m_sk_regs.skaud & SKAUD_ACD_MASK) >> SKAUD_ACD_BIT) + 1; const uint32_t pll_clock = clock() * 39; - attotime clock_period = attotime::from_ticks(divisor * 256, pll_clock); + attotime clock_period = attotime::from_ticks(divisor * 128, pll_clock); m_audio_regs.tx_dma_timer->adjust(clock_period, 0, clock_period); LOGMASKED(LOG_AUDIO_DMA, "audio_start_tx_dma, setting start address to %08x, Tx clock to %d / %d\n", m_audio_regs.sadta, pll_clock, divisor); diff --git a/src/devices/video/sed1356.cpp b/src/devices/video/sed1356.cpp index ffa63122981..e27eae12c78 100644 --- a/src/devices/video/sed1356.cpp +++ b/src/devices/video/sed1356.cpp @@ -1046,22 +1046,174 @@ void sed1356_device::bitblt_solid_fill() } } +uint16_t sed1356_device::bitblt_rop(const uint8_t rop, const uint16_t s, const uint16_t d) +{ + switch (rop & 0x0f) + { + case 0: + return 0; + case 1: + return ~(s | d); + case 2: + return ~s & d; + case 3: + return ~s; + case 4: + return s | ~d; + case 5: + return ~d; + case 6: + return s ^d; + case 7: + return ~s | ~d; + case 8: + return s & d; + case 9: + return ~(s ^ d); + case 10: + return d; + case 11: + return ~s | d; + case 12: + return s; + case 13: + return s | ~d; + case 14: + return s | d; + case 15: + return 0xffff; + } + return 0; +} + +void sed1356_device::bitblt_async_advance(uint32_t &addr) +{ + m_bitblt_x++; + if (m_bitblt_x > m_bitblt_width) + { + m_bitblt_x = 0; + m_bitblt_y++; + if (!BIT(m_bitblt_ctrl[0], BBCTRL0_DSTLIN_BIT)) + { + addr -= (m_bitblt_width << 1); + addr += (m_bitblt_mem_offset << 1); + } + if (m_bitblt_y > m_bitblt_height) + { + m_bitblt_ctrl[0] &= ~(1 << BBCTRL0_ACTIVE_BIT); + m_bitblt_ctrl[0] &= ~(1 << BBCTRL0_ANY_BIT); + } + } + else + { + addr += 2; + } +} + +void sed1356_device::bitblt_write_continue(const uint16_t s) +{ + uint16_t *dstp = (uint16_t*)&m_vram[m_bitblt_curr_dst_addr >> 2]; + if (m_bitblt_curr_dst_addr & 2) + dstp++; + + *dstp = bitblt_rop(m_bitblt_rop, s, *dstp); + + bitblt_async_advance(m_bitblt_curr_dst_addr); +} + +void sed1356_device::bitblt_write() +{ + m_bitblt_ctrl[0] |= (1 << BBCTRL0_ACTIVE_BIT); + m_bitblt_x = 0; + m_bitblt_y = 0; + m_bitblt_curr_dst_addr = m_bitblt_dst_addr; +} + +uint16_t sed1356_device::bitblt_read_continue() +{ + const uint16_t *srcp = (uint16_t*)&m_vram[m_bitblt_curr_src_addr >> 2]; + if (m_bitblt_curr_src_addr & 2) + srcp++; + + const uint16_t data = *srcp; + + bitblt_async_advance(m_bitblt_curr_src_addr); + + return data; +} + +void sed1356_device::bitblt_read() +{ + m_bitblt_ctrl[0] |= (1 << BBCTRL0_ACTIVE_BIT); + m_bitblt_ctrl[0] |= (1 << BBCTRL0_ANY_BIT); + m_bitblt_x = 0; + m_bitblt_y = 0; + m_bitblt_curr_src_addr = m_bitblt_src_addr; +} + +template +void sed1356_device::bitblt_move_negative() +{ + uint16_t *srcp = (uint16_t*)&m_vram[m_bitblt_src_addr >> 2]; + if (m_bitblt_src_addr & 2) + srcp++; + + uint16_t *dstp = (uint16_t*)&m_vram[m_bitblt_dst_addr >> 2]; + if (m_bitblt_dst_addr & 2) + dstp++; + + for (int32_t y = (int32_t)m_bitblt_height; y >= 0; y--) + { + for (int32_t x = (int32_t)m_bitblt_width; x >= 0; x--) + { + const uint16_t s = (SrcLinear ? *srcp : srcp[x]); + const uint16_t d = (DstLinear ? *dstp : dstp[x]); + + *dstp = bitblt_rop(m_bitblt_rop, s, d); + + if (SrcLinear) + srcp++; + if (DstLinear) + dstp++; + } + + if (!SrcLinear) + srcp += m_bitblt_mem_offset; + if (!DstLinear) + dstp += m_bitblt_mem_offset; + } +} + void sed1356_device::bitblt_execute_command() { switch (m_bitblt_op) { case 0: - LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Write BitBLT with ROP\n"); + LOGMASKED(LOG_BITBLT_OP, "bitblt: Write BitBLT with ROP\n"); + bitblt_write(); return; case 1: - LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Read BitBLT\n"); + LOGMASKED(LOG_BITBLT_OP, "bitblt: Read BitBLT\n"); + bitblt_read(); return; case 2: LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Move BitBLT in + direction with ROP\n"); return; case 3: - LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Move BitBLT in - direction with ROP\n"); + { + LOGMASKED(LOG_BITBLT_OP, "bitblt: Move BitBLT in - direction with ROP\n"); + const bool srclin = BIT(m_bitblt_ctrl[0], BBCTRL0_SRCLIN_BIT); + const bool dstlin = BIT(m_bitblt_ctrl[0], BBCTRL0_DSTLIN_BIT); + if (srclin && dstlin) + bitblt_move_negative(); + else if (srclin) + bitblt_move_negative(); + else if (dstlin) + bitblt_move_negative(); + else + bitblt_move_negative(); return; + } case 4: LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Transparent Write BitBLT\n"); return; @@ -1432,15 +1584,34 @@ void sed1356_device::mplug_data_w(offs_t offset, uint8_t data) } -uint8_t sed1356_device::bitblt_data_r(offs_t offset) +uint16_t sed1356_device::bitblt_data_r(offs_t offset) { - LOGMASKED(LOG_BITBLT_RD, "%s: (not implemented) bitblt_data_r[%06x]: %02x\n", machine().describe_context(), 0x100000 + offset, 0); - return 0; + uint16_t data = 0; + if (BIT(m_bitblt_ctrl[0], BBCTRL0_ACTIVE_BIT) && m_bitblt_op == 1) + { + data = bitblt_read_continue(); + } + + LOGMASKED(LOG_BITBLT_RD, "%s: bitblt_data_r[%06x]: %04x\n", machine().describe_context(), 0x100000 + (offset << 1), data); + return data; } -void sed1356_device::bitblt_data_w(offs_t offset, uint8_t data) +void sed1356_device::bitblt_data_w(offs_t offset, uint16_t data) { - LOGMASKED(LOG_BITBLT_WR, "%s: (not implemented) bitblt_data_w[%06x]: %02x\n", machine().describe_context(), 0x100000 + offset, data); + LOGMASKED(LOG_BITBLT_WR, "%s: bitblt_data_w[%06x]: %04x\n", machine().describe_context(), 0x100000 + (offset << 1), data); + if (BIT(m_bitblt_ctrl[0], BBCTRL0_ACTIVE_BIT)) + { + switch (m_bitblt_op) + { + case 0: // Write BitBLT with ROP + bitblt_write_continue(data); + return; + case 4: // Transparent Write BitBLT + return; + default: + return; + } + } } void sed1356_device::device_start() diff --git a/src/devices/video/sed1356.h b/src/devices/video/sed1356.h index ca32f8dfdb8..98d80684253 100644 --- a/src/devices/video/sed1356.h +++ b/src/devices/video/sed1356.h @@ -171,6 +171,13 @@ protected: void crt_cursor_fifo_thresh_w(offs_t offset, uint8_t data); template void bitblt_solid_fill(); + uint16_t bitblt_rop(const uint8_t rop, const uint16_t s, const uint16_t d); + void bitblt_async_advance(uint32_t &addr); + void bitblt_write_continue(const uint16_t s); + void bitblt_write(); + uint16_t bitblt_read_continue(); + void bitblt_read(); + template void bitblt_move_negative(); void bitblt_execute_command(); uint8_t bitblt_ctrl0_r(offs_t offset); uint8_t bitblt_ctrl1_r(offs_t offset); @@ -223,8 +230,8 @@ protected: void mplug_resv_cmd_w(offs_t offset, uint8_t data); void mplug_data_w(offs_t offset, uint8_t data); - uint8_t bitblt_data_r(offs_t offset); - void bitblt_data_w(offs_t offset, uint8_t data); + uint16_t bitblt_data_r(offs_t offset); + void bitblt_data_w(offs_t offset, uint16_t data); enum { @@ -523,6 +530,11 @@ protected: uint16_t m_bitblt_bgcolor; uint16_t m_bitblt_fgcolor; + uint32_t m_bitblt_curr_src_addr; + uint32_t m_bitblt_curr_dst_addr; + uint32_t m_bitblt_x; + uint32_t m_bitblt_y; + uint8_t m_lut_mode; uint8_t m_lut_addr; uint8_t m_lut_data; diff --git a/src/mame/drivers/jornada.cpp b/src/mame/drivers/jornada.cpp index 25d2c2de387..85046d298ee 100644 --- a/src/mame/drivers/jornada.cpp +++ b/src/mame/drivers/jornada.cpp @@ -119,7 +119,9 @@ protected: MCU_KBD_SEND_COUNT, MCU_KBD_SEND_CODES, - MCU_TOUCH_SEND_DATA + MCU_TOUCH_SEND_DATA, + + MCU_BATTERY_SEND_DATA }; // devices @@ -146,6 +148,8 @@ protected: uint8_t m_mcu_touch_data[2][8]; uint8_t m_mcu_touch_count[2]; uint8_t m_mcu_touch_idx[2]; + uint8_t m_mcu_battery_data[3]; + uint8_t m_mcu_battery_idx; }; void jornada_state::main_map(address_map &map) @@ -155,6 +159,7 @@ void jornada_state::main_map(address_map &map) map(0x40000000, 0x40001fff).m(m_companion, FUNC(sa1111_device::map)); map(0x48000000, 0x481fffff).m(m_epson, FUNC(sed1356_device::map)); map(0x48200000, 0x4827ffff).m(m_epson, FUNC(sed1356_device::vram_map)); + map(0x80000000, 0x80000033).rw(m_sa_periphs, FUNC(sa1110_periphs_device::udc_r), FUNC(sa1110_periphs_device::udc_w)); map(0x80030000, 0x8003007b).rw(m_sa_periphs, FUNC(sa1110_periphs_device::icp_r), FUNC(sa1110_periphs_device::icp_w)); map(0x80050000, 0x80050023).rw(m_sa_periphs, FUNC(sa1110_periphs_device::uart3_r), FUNC(sa1110_periphs_device::uart3_w)); map(0x80060000, 0x8006001b).rw(m_sa_periphs, FUNC(sa1110_periphs_device::mcp_r), FUNC(sa1110_periphs_device::mcp_w)); @@ -174,7 +179,9 @@ void jornada_state::main_map(address_map &map) void jornada_state::device_reset_after_children() { - m_sa_periphs->gpio_in<9>(1); + m_sa_periphs->gpio_in<4>(0); // Flag as plugged into AC power + m_sa_periphs->gpio_in<9>(1); // Pen input is active-high + m_sa_periphs->gpio_in<26>(0); // Flag as charging } void jornada_state::mcu_assemble_touch_data() @@ -214,6 +221,14 @@ void jornada_state::mcu_byte_received(uint16_t data) m_mcu_state = MCU_TOUCH_SEND_DATA; m_mcu_touch_send_idx = 1 - m_mcu_touch_send_idx; break; + case 0xc0: + LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_IDLE: GetBatteryData, entering BATTERY_SEND_DATA state\n"); + m_mcu_state = MCU_BATTERY_SEND_DATA; + m_mcu_battery_idx = 0; + m_mcu_battery_data[0] = 0xff; // LSB of main battery level + m_mcu_battery_data[1] = 0xff; // LSB of backup battery level + m_mcu_battery_data[2] = 0x0f; // MSBs of both battery levels (backup in 3:2, main in 1:0) + break; default: LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_IDLE: Unknown (%02x), ignoring and sending TxDummy response\n", value); break; @@ -234,6 +249,29 @@ void jornada_state::mcu_byte_received(uint16_t data) } break; + case MCU_BATTERY_SEND_DATA: + if (value == MCU_TXDUMMY || value == MCU_TXDUMMY2) + { + response = m_mcu_battery_data[m_mcu_battery_idx]; + m_mcu_battery_idx++; + if (m_mcu_battery_idx < 3) + { + LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_BATTERY_SEND_DATA: TxDummy, sending battery data %02x with %d remaining\n", response, 3 - m_mcu_battery_idx); + } + else + { + LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_BATTERY_SEND_DATA: TxDummy, sending battery data %02x and returning to IDLE state\n", response); + m_mcu_state = MCU_IDLE; + m_mcu_battery_idx = 0; + } + } + else + { + LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_BATTERY_SEND_DATA: Unknown (%02x), sending ErrorCode response and returning to IDLE state\n", value); + response = 0; + } + break; + case MCU_TOUCH_SEND_DATA: if (value == MCU_TXDUMMY || value == MCU_TXDUMMY2) { @@ -392,6 +430,8 @@ void jornada_state::machine_start() save_item(NAME(m_mcu_touch_data)); save_item(NAME(m_mcu_touch_count)); save_item(NAME(m_mcu_touch_idx)); + save_item(NAME(m_mcu_battery_data)); + save_item(NAME(m_mcu_battery_idx)); } void jornada_state::machine_reset() @@ -409,6 +449,9 @@ void jornada_state::machine_reset() memset(m_mcu_touch_data[1], 0, 8); memset(m_mcu_touch_count, 0, 2); memset(m_mcu_touch_idx, 0, 2); + + memset(m_mcu_battery_data, 0, 3); + m_mcu_battery_idx = 0; } void jornada_state::jornada720(machine_config &config)