diff options
Diffstat (limited to 'src/mame/drivers/cxhumax.c')
-rw-r--r-- | src/mame/drivers/cxhumax.c | 1085 |
1 files changed, 1085 insertions, 0 deletions
diff --git a/src/mame/drivers/cxhumax.c b/src/mame/drivers/cxhumax.c new file mode 100644 index 00000000000..4fc5ab65151 --- /dev/null +++ b/src/mame/drivers/cxhumax.c @@ -0,0 +1,1085 @@ +// license:BSD-3-Clause +// copyright-holders:Lukasz Markowski +/*************************************************************************** + HUMAX HDCI-2000 ( Conexant CX2417x ) + + http://www.humaxdigital.com/global/products/product_stb_satellite_hdci2000.asp + + Running on Nucleus PLUS - ARM7TDMI ADS v. 1.14 + some Conexant/Nucleus goodies may be found at http://code.google.com/p/cherices/ + + runs up to frame 280 or so... + +****************************************************************************/ + +#include "emu.h" +#include "includes/cxhumax.h" + +#define VERBOSE_LEVEL ( 0 ) + +INLINE void ATTR_PRINTF(3,4) verboselog( running_machine &machine, int n_level, const char *s_fmt, ...) +{ + if (VERBOSE_LEVEL >= n_level) + { + va_list v; + char buf[32768]; + va_start( v, s_fmt); + vsprintf( buf, s_fmt, v); + va_end( v); + logerror( "%s: %s", machine.describe_context( ), buf); + } +} + +READ32_MEMBER ( cxhumax_state::cx_gxa_r ) +{ + UINT32 res = m_gxa_cmd_regs[offset]; + verboselog( machine(), 9, "(GXA) %08X -> %08X\n", 0xE0600000 + (offset << 2), res); +/* UINT8 gxa_command_number = (offset >> 9) & 0x7F; + verboselog( machine(), 9, " Command: %08X\n", gxa_command_number); + switch (gxa_command_number) { + case GXA_CMD_RW_REGISTER: + switch(offset) { + case GXA_CFG2_REG: + break; + default: + verboselog( machine(), 9, " Unimplemented register - TODO?\n"); + break; + } + break; + default: + // do we need it? + verboselog( machine(), 9, " Unimplemented read command - TODO?\n"); + break; + }*/ + return res; +} + +WRITE32_MEMBER( cxhumax_state::cx_gxa_w ) +{ + verboselog( machine(), 9, "(GXA) %08X <- %08X\n", 0xE0600000 + (offset << 2), data); + UINT8 gxa_command_number = (offset >> 9) & 0x7F; + verboselog( machine(), 9, " Command: %08X\n", gxa_command_number); + + /* Clear non persistent data */ + m_gxa_cmd_regs[GXA_CMD_REG] &= 0xfffc0000; + + if (gxa_command_number == GXA_CMD_RW_REGISTER) { + verboselog( machine(), 9, " Register Number: %08X\n", offset & 0xff); + } else { + m_gxa_cmd_regs[GXA_CMD_REG] |= (offset << 2) & 0x3ffff; + verboselog( machine(), 9, " Source Bitmap Selector: %08X\n", (offset >> 6) & 0x7); + verboselog( machine(), 9, " Destination Bitmap Selector: %08X\n", (offset >> 3) & 0x7); + verboselog( machine(), 9, " Parameter Count: %08X\n", offset & 0x7); + } + switch (gxa_command_number) { + case GXA_CMD_RW_REGISTER: + switch(offset) { + case GXA_CFG2_REG: + // clear IRQ_STAT bits if requested + m_gxa_cmd_regs[GXA_CFG2_REG] = (m_gxa_cmd_regs[GXA_CFG2_REG]&(0xfff00000 & ~(data&0x00300000))) | (data & 0x000fffff); + break; + default: + verboselog( machine(), 9, " Unimplemented register - TODO?\n"); + COMBINE_DATA(&m_gxa_cmd_regs[offset]); + break; + } + break; + case GXA_CMD_QMARK: + verboselog( machine(), 9, " QMARK - TODO?\n"); + + /* Set value and copy of WAIT4_VERTICAL bit written by QMARK */ + m_gxa_cmd_regs[GXA_CMD_REG] = (m_gxa_cmd_regs[GXA_CMD_REG] & 0x3ffff) | (data<<24) | ((data&0x10)?1<<23:0); + + /* QMARK command has completed */ + m_gxa_cmd_regs[GXA_CFG2_REG] |= (1<<IRQ_STAT_QMARK); + + // Interrupt + if (m_gxa_cmd_regs[GXA_CFG2_REG] & (1<<IRQ_EN_QMARK)) { + m_intctrl_regs[INTREG(INTGROUP2, INTIRQ)] |= 1<<18; + m_intctrl_regs[INTREG(INTGROUP2, INTSTATCLR)] |= 1<<18; + m_intctrl_regs[INTREG(INTGROUP2, INTSTATSET)] |= 1<<18; + verboselog( machine(), 9, " QMARK INT - TODO?\n"); + } + + if((m_intctrl_regs[INTREG(INTGROUP2, INTIRQ)] & m_intctrl_regs[INTREG(INTGROUP2, INTENABLE)]) + || (m_intctrl_regs[INTREG(INTGROUP1, INTIRQ)] & m_intctrl_regs[INTREG(INTGROUP1, INTENABLE)])) + m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); + + break; + default: + verboselog( machine(), 9, " Unimplemented command - TODO?\n"); + break; + } +} + +WRITE32_MEMBER ( cxhumax_state::flash_w ) +{ + offset *= 2; + if(ACCESSING_BITS_0_15) + m_flash->write(offset, data); + if(ACCESSING_BITS_16_31) + m_flash->write(offset+1, data >> 16); + verboselog( machine(), 9, "(FLASH) %08X <- %08X\n", 0xF0000000 + (offset << 2), data); +} + +READ32_MEMBER ( cxhumax_state::flash_r ) +{ + UINT32 res = 0; + offset *= 2; + if(ACCESSING_BITS_0_15) + res |= m_flash->read(offset); + if(ACCESSING_BITS_16_31) + res |= m_flash->read(offset+1) << 16; + //if(m_flash->m_flash_mode!=FM_NORMAL) verboselog( machine(), 9, "(FLASH) %08X -> %08X\n", 0xF0000000 + (offset << 2), res); + return res; +} + +READ32_MEMBER ( cxhumax_state::dummy_flash_r ) +{ + return 0xFFFFFFFF; +} + +WRITE32_MEMBER ( cxhumax_state::cx_remap_w ) +{ + if(!(data&1)) { + verboselog( machine(), 9, "(REMAP) %08X -> %08X\n", 0xE0400014 + (offset << 2), data); + memset(m_ram, 0, 0x400000); // workaround :P + } +} + +READ32_MEMBER( cxhumax_state::cx_scratch_r ) +{ + UINT32 data = m_scratch_reg; + verboselog( machine(), 9, "(SCRATCH) %08X -> %08X\n", 0xE0400024 + (offset << 2), data); + + if((m_maincpu->pc()==0xF0003BB8) || (m_maincpu->pc()==0x01003724) || (m_maincpu->pc()==0x00005d8c)) { // HDCI-2000 + //we're in disabled debug_printf + unsigned char* buf = (unsigned char *)alloca(200); + unsigned char temp; + address_space &program = m_maincpu->space(AS_PROGRAM); + + memset(buf,0,200); + + int i = 0; + while ((temp=program.read_byte(m_maincpu->state_int(ARM7_R0)+i))) { + buf[i++]=temp; + //m_terminal->write(space, 0, temp); + } + osd_printf_debug("%s", buf); + verboselog( machine(), 9, "(DEBUG) %s", buf); + } + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_scratch_w ) +{ + verboselog( machine(), 9, "(SCRATCH) %08X <- %08X\n", 0xE0400024 + (offset << 2), data); + COMBINE_DATA(&m_scratch_reg); +} + +READ32_MEMBER( cxhumax_state::cx_hsx_r ) +{ + UINT32 data = 0; // dummy + verboselog( machine(), 9, "(HSX) %08X -> %08X\n", 0xE0000000 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_hsx_w ) +{ + verboselog( machine(), 9, "(HSX) %08X <- %08X\n", 0xE0000000 + (offset << 2), data); +} + +READ32_MEMBER( cxhumax_state::cx_romdescr_r ) +{ + UINT32 data = m_romdescr_reg; + verboselog( machine(), 9, "(ROMDESC0) %08X -> %08X\n", 0xE0010000 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_romdescr_w ) +{ + verboselog( machine(), 9, "(ROMDESC0) %08X <- %08X\n", 0xE0010000 + (offset << 2), data); + COMBINE_DATA(&m_romdescr_reg); +} + +READ32_MEMBER( cxhumax_state::cx_isaromdescr_r ) +{ + UINT32 data = m_isaromdescr_regs[offset]; + verboselog( machine(), 9, "(ISAROMDESC%d) %08X -> %08X\n", offset+1, 0xE0010004 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_isaromdescr_w ) +{ + verboselog( machine(), 9, "(ISAROMDESC%d) %08X <- %08X\n", offset+1, 0xE0010004 + (offset << 2), data); + COMBINE_DATA(&m_isaromdescr_regs[offset]); +} + +READ32_MEMBER( cxhumax_state::cx_isadescr_r ) +{ + UINT32 data = m_isaromdescr_regs[offset]; + verboselog( machine(), 9, "(ISA_DESC%d) %08X -> %08X\n", offset+4, 0xE0010010 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_isadescr_w ) +{ + verboselog( machine(), 9, "(ISA_DESC%d) %08X <- %08X\n", offset+4, 0xE0010010 + (offset << 2), data); + COMBINE_DATA(&m_isaromdescr_regs[offset]); +} + +READ32_MEMBER( cxhumax_state::cx_rommap_r ) +{ + UINT32 data = 0; + verboselog( machine(), 9, "(ROM%d_MAP) %08X -> %08X\n", offset, 0xE0010020 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_rommap_w ) +{ + verboselog( machine(), 9, "(ROM%d_MAP) %08X <- %08X\n", offset, 0xE0010020 + (offset << 2), data); +} + +READ32_MEMBER( cxhumax_state::cx_rommode_r ) +{ + UINT32 data = m_rommode_reg; + verboselog( machine(), 9, "(ROMMODE) %08X -> %08X\n", 0xE0010034 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_rommode_w ) +{ + verboselog( machine(), 9, "(ROMMODE) %08X <- %08X\n", 0xE0010034 + (offset << 2), data); + COMBINE_DATA(&m_rommode_reg); +} + +READ32_MEMBER( cxhumax_state::cx_xoemask_r ) +{ + UINT32 data = m_xoemask_reg; + verboselog( machine(), 9, "(XOEMASK) %08X -> %08X\n", 0xE0010034 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_xoemask_w ) +{ + verboselog( machine(), 9, "(XOEMASK) %08X <- %08X\n", 0xE0010034 + (offset << 2), data); + COMBINE_DATA(&m_xoemask_reg); +} + +READ32_MEMBER( cxhumax_state::cx_pci_r ) +{ + UINT32 data = 0; + switch (offset) { + case PCI_CFG_ADDR_REG: + data = m_pci_regs[offset]; break; + case PCI_CFG_DATA_REG: + { + switch (m_pci_regs[PCI_CFG_ADDR_REG]) { + case 0: data = (0x4170<<16) /*Device ID*/ | 0x14f1 /* Vendor ID */; break; + case 8: data = (0x060000 << 8) /* Class Code */ | 0x1f /* Revision ID */; break; + } + } break; + } + verboselog( machine(), 9, "(PCI) %08X -> %08X\n", 0xE0010040 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_pci_w ) +{ + verboselog( machine(), 9, "(PCI) %08X <- %08X\n", 0xE0010040 + (offset << 2), data); + COMBINE_DATA(&m_pci_regs[offset]); +} + +READ32_MEMBER( cxhumax_state::cx_extdesc_r ) +{ + UINT32 data = m_extdesc_regs[offset]; + verboselog( machine(), 9, "(EXTDESC) %08X -> %08X\n", 0xE0010080 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_extdesc_w ) +{ + verboselog( machine(), 9, "(EXTDESC) %08X <- %08X\n", 0xE0010080 + (offset << 2), data); + COMBINE_DATA(&m_extdesc_regs[offset]); +} + +TIMER_CALLBACK_MEMBER(cxhumax_state::timer_tick) +{ + m_timer_regs.timer[param].value++; + if(m_timer_regs.timer[param].value==m_timer_regs.timer[param].limit) { + /* Reset counter when reaching limit and RESET_CNTR bit is cleared */ + if(!(m_timer_regs.timer[param].mode & 2)) + m_timer_regs.timer[param].value=0; + + /* Indicate interrupt request if EN_INT bit is set */ + if (m_timer_regs.timer[param].mode & 8) { + //printf( "IRQ on Timer %d\n", param ); + verboselog( machine(), 9, "(TIMER%d) Interrupt\n", param); + m_intctrl_regs[INTREG(INTGROUP2, INTIRQ)] |= INT_TIMER_BIT; /* Timer interrupt */ + m_intctrl_regs[INTREG(INTGROUP2, INTSTATCLR)] |= INT_TIMER_BIT; /* Timer interrupt */ + m_intctrl_regs[INTREG(INTGROUP2, INTSTATSET)] |= INT_TIMER_BIT; /* Timer interrupt */ + + m_timer_regs.timer_irq |= 1<<param; /* Indicate which timer interrupted */ + + /* Interrupt if Timer interrupt is not masked in ITC_INTENABLE_REG */ + if (m_intctrl_regs[INTREG(INTGROUP2, INTENABLE)] & INT_TIMER_BIT) + m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); + } + } + attotime period = attotime::from_hz(XTAL_54MHz)*m_timer_regs.timer[param].timebase; + m_timer_regs.timer[param].timer->adjust(period,param); +} + +READ32_MEMBER( cxhumax_state::cx_timers_r ) +{ + UINT32 data = 0; + UINT8 index = offset>>2; + if(index==16) { + data = m_timer_regs.timer_irq; + //m_timer_regs.timer_irq=0; + verboselog( machine(), 9, "(TIMERIRQ) %08X -> %08X\n", 0xE0430000 + (offset << 2), data); + } + else { + switch (offset&3) { + case TIMER_VALUE: + data = m_timer_regs.timer[index].value; break; + case TIMER_LIMIT: + data = m_timer_regs.timer[index].limit; break; + case TIMER_MODE: + data = m_timer_regs.timer[index].mode; break; + case TIMER_TIMEBASE: + data = m_timer_regs.timer[index].timebase; break; + } + verboselog( machine(), 9, "(TIMER%d) %08X -> %08X\n", offset>>2, 0xE0430000 + (offset << 2), data); + } + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_timers_w ) +{ + UINT8 index = offset>>2; + if(index==16) { + verboselog( machine(), 9, "(TIMERIRQ) %08X <- %08X\n", 0xE0430000 + (offset << 2), data); + COMBINE_DATA(&m_timer_regs.timer_irq); + } + else { + verboselog( machine(), 9, "(TIMER%d) %08X <- %08X\n", index, 0xE0430000 + (offset << 2), data); + switch(offset&3) { + case TIMER_VALUE: + COMBINE_DATA(&m_timer_regs.timer[index].value); break; + case TIMER_LIMIT: + COMBINE_DATA(&m_timer_regs.timer[index].limit); break; + case TIMER_MODE: + COMBINE_DATA(&m_timer_regs.timer[index].mode); + if(data&1) { + attotime period = attotime::from_hz(XTAL_54MHz)*m_timer_regs.timer[index].timebase; + m_timer_regs.timer[index].timer->adjust(period,index); + } else { + m_timer_regs.timer[index].timer->adjust(attotime::never,index); + } break; + case TIMER_TIMEBASE: + COMBINE_DATA(&m_timer_regs.timer[index].timebase); break; + } + /* A timer will hold an interrupt active until any one of that timer?s registers is written. */ + if(m_timer_regs.timer_irq & (1<<index)) { + m_timer_regs.timer_irq &= ~(1<<index); + } + } +} + +READ32_MEMBER( cxhumax_state::cx_uart2_r ) +{ + UINT32 data; + switch (offset) { + case UART_STAT_REG: + /* Transmitter Idle */ + data = UART_STAT_TID_BIT | UART_STAT_TSR_BIT; break; + default: + data = m_uart2_regs[offset]; break; + } + verboselog( machine(), 9, "(UART2) %08X -> %08X\n", 0xE0411000 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_uart2_w ) +{ + verboselog( machine(), 9, "(UART2) %08X <- %08X\n", 0xE0411000 + (offset << 2), data); + switch (offset) { + case UART_FIFO_REG: + if(!(m_uart2_regs[UART_FRMC_REG]&UART_FRMC_BDS_BIT)) { + /* Sending byte... add logging */ + m_terminal->write(space, 0, data); + + /* Transmitter Idle Interrupt Enable */ + if(m_uart2_regs[UART_IRQE_REG]&UART_IRQE_TIDE_BIT) { + /* Signal pending INT */ + m_intctrl_regs[INTREG(INTGROUP1, INTIRQ)] |= INT_UART2_BIT; + m_intctrl_regs[INTREG(INTGROUP1, INTSTATCLR)] |= INT_UART2_BIT; + m_intctrl_regs[INTREG(INTGROUP1, INTSTATSET)] |= INT_UART2_BIT; + + /* If INT is enabled at INT Ctrl raise it */ + if(m_intctrl_regs[INTREG(INTGROUP1, INTENABLE)]&INT_UART2_BIT) { + m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); + } + } + } + default: + COMBINE_DATA(&m_uart2_regs[offset]); break; + } +} + +READ32_MEMBER( cxhumax_state::cx_pll_r ) +{ + UINT32 data = m_pll_regs[offset]; + verboselog( machine(), 9, "(PLL) %08X -> %08X\n", 0xE0440000 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_pll_w ) +{ + verboselog( machine(), 9, "(PLL) %08X <- %08X\n", 0xE0440000 + (offset << 2), data); + COMBINE_DATA(&m_pll_regs[offset]); +} + +READ32_MEMBER( cxhumax_state::cx_pllprescale_r ) +{ + UINT32 data = m_pllprescale_reg; + verboselog( machine(), 9, "(PLLPRESCALE) %08X -> %08X\n", 0xE0440094 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_pllprescale_w ) +{ + verboselog( machine(), 9, "(PLLPRESCALE) %08X <- %08X\n", 0xE0440094 + (offset << 2), data); + COMBINE_DATA(&m_pllprescale_reg); +} + +READ32_MEMBER( cxhumax_state::cx_clkdiv_r ) +{ + UINT32 data = m_clkdiv_regs[offset]; + verboselog( machine(), 9, "(CLKDIV) %08X -> %08X\n", 0xE0440020 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_clkdiv_w ) +{ + verboselog( machine(), 9, "(CLKDIV) %08X <- %08X\n", 0xE0440020 + (offset << 2), data); + COMBINE_DATA(&m_clkdiv_regs[offset]); +} + +READ32_MEMBER( cxhumax_state::cx_chipcontrol_r ) +{ + UINT32 data = m_chipcontrol_regs[offset]; + verboselog( machine(), 9, "(CHIPCONTROL) %08X -> %08X\n", 0xE0440100 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_chipcontrol_w ) +{ + verboselog( machine(), 9, "(CHIPCONTROL) %08X <- %08X\n", 0xE0440100 + (offset << 2), data); + COMBINE_DATA(&m_chipcontrol_regs[offset]); +} + +READ32_MEMBER( cxhumax_state::cx_intctrl_r ) +{ + UINT32 data = m_intctrl_regs[offset]; + verboselog( machine(), 9, "(INTCTRL) %08X -> %08X\n", 0xE0450000 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_intctrl_w ) +{ + verboselog( machine(), 9, "(INTCTRL) %08X <- %08X\n", 0xE0450000 + (offset << 2), data); + switch (offset >> 3) { // Decode the group + case 0: // Group 1 + switch(offset & 7) { + case INTSTATCLR: // ITC_INTSTATCLR_REG Group 1 + /* + Bits 15 (PWM), 14 (PIO103) of Group 1 are the logical OR of their lower level interrupt + status bits down within the interrupting module and are not registered. + + The source registers must be cleared to clear these interrupt bits. + */ + data &= ~(INT_PWM_BIT|INT_PIO103_BIT); + + m_intctrl_regs[INTREG(INTGROUP1, INTSTATCLR)] &= ~data; + m_intctrl_regs[INTREG(INTGROUP1, INTSTATSET)] &= ~data; + m_intctrl_regs[INTREG(INTGROUP1, INTIRQ)] &= ~data; + break; + default: + COMBINE_DATA(&m_intctrl_regs[offset]); + break; + } + break; + case 1: // Group 2 + switch(offset & 7) { + case INTSTATCLR: // ITC_INTSTATCLR_REG Group 2 + /* + The timer interrupt service routine must write to one of the timer + registers before clearing the corresponding Interrupt Controller ISR timer + interrupt bit. + + Bit 7 (Timers) of Group 2 is the logical OR of its lower level interrupt + status bits down within the interrupting module and are not registered. + + The source registers must be cleared to clear these interrupt bits. + */ + if(m_timer_regs.timer_irq) data &= ~INT_TIMER_BIT; + + m_intctrl_regs[INTREG(INTGROUP2, INTSTATCLR)] &= ~data; + m_intctrl_regs[INTREG(INTGROUP2, INTSTATSET)] &= ~data; + m_intctrl_regs[INTREG(INTGROUP2, INTIRQ)] &= ~data; + break; + default: + COMBINE_DATA(&m_intctrl_regs[offset]); + break; + } + break; + default: + break; + } + + if(m_i2c1_regs[I2C_STAT_REG]&I2C_INT_BIT) + { + m_intctrl_regs[INTREG(INTGROUP1, INTIRQ)] |= 1<<7; + m_intctrl_regs[INTREG(INTGROUP1, INTSTATCLR)] |= 1<<7; + m_intctrl_regs[INTREG(INTGROUP1, INTSTATSET)] |= 1<<7; + } + + /* check if */ + if((m_intctrl_regs[INTREG(INTGROUP2, INTIRQ)] & m_intctrl_regs[INTREG(INTGROUP2, INTENABLE)]) + || (m_intctrl_regs[INTREG(INTGROUP1, INTIRQ)] & m_intctrl_regs[INTREG(INTGROUP1, INTENABLE)])) + m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); + else + m_maincpu->set_input_line(ARM7_IRQ_LINE, CLEAR_LINE); + +} + +READ32_MEMBER( cxhumax_state::cx_ss_r ) +{ + UINT32 data = 0; + switch(offset) { + case SS_FIFC_REG: + data = m_ss_regs[offset] & 0xFFF0; + break; + default: + data = m_ss_regs[offset]; + break; + } + verboselog( machine(), 9, "(SS) %08X -> %08X\n", 0xE0490000 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_ss_w ) +{ + verboselog( machine(), 9, "(SS) %08X <- %08X\n", 0xE0490000 + (offset << 2), data); + switch(offset) { + case SS_CNTL_REG: + if (data&1) { + // "Send" pending data + UINT8 tfd = (m_ss_regs[SS_STAT_REG]>>4) & 0xF; + if ((tfd>1) && (m_ss_tx_fifo[0] == 0) && (m_ss_tx_fifo[1] != 0xFF)) { + // ASCII + printf("%s\n", &m_ss_tx_fifo[1]); + } else { + // UNKNOWN + for (int i=0; i<tfd; i++) { + printf("%02X ", m_ss_tx_fifo[i]); + } + printf("\n"); + } + // Clear TX FIFO + memset(m_ss_tx_fifo,0,sizeof(m_ss_tx_fifo)); + m_ss_regs[SS_STAT_REG] &= 0xFF0F; + } + COMBINE_DATA(&m_ss_regs[offset]); + break; + case SS_FIFO_REG: + { + // Push data into TX FIFO (if it's not full) and adjust transmit FIFO depth + UINT8 tfd = (m_ss_regs[SS_STAT_REG]>>4) & 0xF; + if (tfd<8) { + m_ss_tx_fifo[tfd++] = data; + m_ss_regs[SS_STAT_REG] = (m_ss_regs[SS_STAT_REG] & 0xFF0F) | (tfd<<4); + } + } + break; + case SS_STAT_REG: + // read-only + break; + default: + COMBINE_DATA(&m_ss_regs[offset]); + break; + }; +} + +READ32_MEMBER( cxhumax_state::cx_i2c0_r ) +{ + UINT32 data = m_i2c0_regs[offset]; + verboselog( machine(), 9, "(I2C0) %08X -> %08X\n", 0xE04E0000 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_i2c0_w ) +{ + verboselog( machine(), 9, "(I2C0) %08X <- %08X\n", 0xE04E0000 + (offset << 2), data); + COMBINE_DATA(&m_i2c0_regs[offset]); +} + +UINT8 cxhumax_state::i2cmem_read_byte(int last) +{ + UINT8 data = 0; + int i; + m_i2cmem->write_sda(1); + for (i = 0; i < 8; i++) + { + m_i2cmem->write_scl(1); + data = (data << 1) + (m_i2cmem->read_sda() ? 1 : 0); + m_i2cmem->write_scl(0); + } + m_i2cmem->write_sda(last); + m_i2cmem->write_scl(1); + m_i2cmem->write_scl(0); + return data; +} + +void cxhumax_state::i2cmem_write_byte(UINT8 data) +{ + int i; + for (i = 0; i < 8; i++) + { + m_i2cmem->write_sda((data & 0x80) ? 1 : 0); + data = data << 1; + m_i2cmem->write_scl(1); + m_i2cmem->write_scl(0); + } + m_i2cmem->write_sda(1); // ack bit + m_i2cmem->write_scl(1); + m_i2cmem->write_scl(0); +} + +void cxhumax_state::i2cmem_start() +{ + m_i2cmem->write_sda(1); + m_i2cmem->write_scl(1); + m_i2cmem->write_sda(0); + m_i2cmem->write_scl(0); +} + +void cxhumax_state::i2cmem_stop() +{ + m_i2cmem->write_sda(0); + m_i2cmem->write_scl(1); + m_i2cmem->write_sda(1); + m_i2cmem->write_scl(0); +} + +READ32_MEMBER( cxhumax_state::cx_i2c1_r ) +{ + UINT32 data=0; + switch(offset) { + case I2C_STAT_REG: + data |= m_i2cmem->read_sda()<<3; + // fall + default: + data |= m_i2c1_regs[offset]; break; + } + verboselog( machine(), 9, "(I2C1) %08X -> %08X\n", 0xE04E1000 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_i2c1_w ) +{ + verboselog( machine(), 9, "(I2C1) %08X <- %08X\n", 0xE04E1000 + (offset << 2), data); + switch(offset) { + case I2C_CTRL_REG: + if(data&0x10) {// START + i2cmem_start(); + } + if((data&0x4) || ((data&3)==3)) // I2C READ + { + m_i2c1_regs[I2C_RDATA_REG] = 0; + if(data&0x10) i2cmem_write_byte((data>>24)&0xFF); + if(m_i2c1_regs[I2C_MODE_REG]&(1<<5)) // BYTE_ORDER + { + for(int i=0; i<(data&3); i++) { + m_i2c1_regs[I2C_RDATA_REG] |= i2cmem_read_byte(0) << (i*8); + } + m_i2c1_regs[I2C_RDATA_REG] |= i2cmem_read_byte((data&0x20)?1:0) << ((data&3)*8); + } + else + { + for(int i=0; i<(data&3); i++) { + m_i2c1_regs[I2C_RDATA_REG] |= i2cmem_read_byte(0); + m_i2c1_regs[I2C_RDATA_REG] <<= 8; + } + m_i2c1_regs[I2C_RDATA_REG] |= i2cmem_read_byte((data&0x20)?1:0); + } + } + else + { + for(int i=0; i<=(data&3); i++) { + i2cmem_write_byte((data>>(24-(i*8))&0xFF)); + } + } + if(data&0x20) {// STOP + i2cmem_stop(); + } + + /* The interrupt status bit is set at the end of an I2C read or write operation. */ + m_i2c1_regs[I2C_STAT_REG] |= I2C_INT_BIT; + m_i2c1_regs[I2C_STAT_REG] |= I2C_WACK_BIT; + + m_intctrl_regs[INTREG(INTGROUP1, INTIRQ)] |= 1<<7; + m_intctrl_regs[INTREG(INTGROUP1, INTSTATCLR)] |= 1<<7; + m_intctrl_regs[INTREG(INTGROUP1, INTSTATSET)] |= 1<<7; + if (m_intctrl_regs[INTREG(INTGROUP1, INTENABLE)] & (1<<7)) { + verboselog( machine(), 9, "(I2C1) Int\n" ); + m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); + } + break; + case I2C_STAT_REG: + /* The interrupt status bit may be cleared by writing (anything) to the status register, which also clears the acknowledge status. */ + data&=~(I2C_WACK_BIT|I2C_INT_BIT); + // fall + default: + COMBINE_DATA(&m_i2c1_regs[offset]); + } +} + +READ32_MEMBER( cxhumax_state::cx_i2c2_r ) +{ + UINT32 data = m_i2c2_regs[offset]; + verboselog( machine(), 9, "(I2C2) %08X -> %08X\n", 0xE04E2000 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_i2c2_w ) +{ + verboselog( machine(), 9, "(I2C2) %08X <- %08X\n", 0xE04E2000 + (offset << 2), data); + COMBINE_DATA(&m_i2c2_regs[offset]); +} + +READ32_MEMBER( cxhumax_state::cx_mc_cfg_r ) +{ + UINT32 data = m_mccfg_regs[offset]; + verboselog( machine(), 9, "(MC_CFG) %08X -> %08X\n", 0xE0500300 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_mc_cfg_w ) +{ + verboselog( machine(), 9, "(MC_CFG) %08X <- %08X\n", 0xE0500300 + (offset << 2), data); + COMBINE_DATA(&m_mccfg_regs[offset]); +} + +READ32_MEMBER( cxhumax_state::cx_drm0_r ) +{ + UINT32 data = m_drm0_regs[offset]; + verboselog( machine(), 9, "(DRM0) %08X -> %08X\n", 0xE0560000 + (offset << 2), data); + switch(offset) { + case 0x14/4: // DRM_STATUS_REG + data |= 1<<21; + data |= 1<<20; + } + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_drm0_w ) +{ + verboselog( machine(), 9, "(DRM0) %08X <- %08X\n", 0xE0560000 + (offset << 2), data); + COMBINE_DATA(&m_drm0_regs[offset]); +} + +READ32_MEMBER( cxhumax_state::cx_drm1_r ) +{ + UINT32 data = m_drm1_regs[offset]; + verboselog( machine(), 9, "(DRM1) %08X -> %08X\n", 0xE0570000 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_drm1_w ) +{ + verboselog( machine(), 9, "(DRM1) %08X <- %08X\n", 0xE0570000 + (offset << 2), data); + COMBINE_DATA(&m_drm1_regs[offset]); +} + +READ32_MEMBER( cxhumax_state::cx_hdmi_r ) +{ + UINT32 data = m_hdmi_regs[offset]; + verboselog( machine(), 9, "(HDMI) %08X -> %08X\n", 0xE05D0800 + (offset << 2), data); + return data; +} + +WRITE32_MEMBER( cxhumax_state::cx_hdmi_w ) +{ + verboselog( machine(), 9, "(HDMI) %08X <- %08X\n", 0xE05D0800 + (offset << 2), data); + switch(offset) { + case 0x40/4: // HDMI_CONFIG_REG + if(data&8) m_hdmi_regs[0xc0/4] |= 0x80; + } + COMBINE_DATA(&m_hdmi_regs[offset]); +} + +void cxhumax_state::video_start() +{ +} + +/* copy from emu/rendersw.inc */ +/*------------------------------------------------------------------------ + ycc_to_rgb - convert YCC to RGB; the YCC pixel + contains Y in the LSB, Cb << 8, and Cr << 16 + This actually a YCbCr conversion, + details my be found in chapter 6.4 ff of + http://softwarecommunity.intel.com/isn/downloads/softwareproducts/pdfs/346495.pdf + The document also contains the constants below as floats. +--------------------------------------------------------------------------*/ + +INLINE UINT8 clamp16_shift8(UINT32 x) +{ + return (((INT32) x < 0) ? 0 : (x > 65535 ? 255: x >> 8)); +} + +INLINE UINT32 ycc_to_rgb(UINT32 ycc) +{ + /* original equations: + + C = Y - 16 + D = Cb - 128 + E = Cr - 128 + + R = clip(( 298 * C + 409 * E + 128) >> 8) + G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8) + B = clip(( 298 * C + 516 * D + 128) >> 8) + + R = clip(( 298 * (Y - 16) + 409 * (Cr - 128) + 128) >> 8) + G = clip(( 298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8) + B = clip(( 298 * (Y - 16) + 516 * (Cb - 128) + 128) >> 8) + + R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8) + G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8) + B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8) + + R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8) + G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8) + B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8) + + Now combine constants: + + R = clip(( 298 * Y + 409 * Cr - 56992) >> 8) + G = clip(( 298 * Y - 100 * Cb - 208 * Cr + 34784) >> 8) + B = clip(( 298 * Y + 516 * Cb - 70688) >> 8) + + Define common = 298 * y - 56992. This will save one addition + + R = clip(( common + 409 * Cr - 0) >> 8) + G = clip(( common - 100 * Cb - 208 * Cr + 91776) >> 8) + B = clip(( common + 516 * Cb - 13696) >> 8) + + */ + UINT8 y = ycc; + UINT8 cb = ycc >> 8; + UINT8 cr = ycc >> 16; + UINT32 r, g, b, common; + + common = 298 * y - 56992; + r = (common + 409 * cr); + g = (common - 100 * cb - 208 * cr + 91776); + b = (common + 516 * cb - 13696); + + /* Now clamp and shift back */ + return rgb_t(clamp16_shift8(r), clamp16_shift8(g), clamp16_shift8(b)); +} + +UINT32 cxhumax_state::screen_update_cxhumax(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + int i, j; + + + UINT32 osd_pointer = m_drm1_regs[DRM_OSD_PTR_REG]; + + if(osd_pointer) + { + UINT32 *ram = m_ram; + UINT32 *osd_header = &ram[osd_pointer/4]; + UINT8 *vbuf = (UINT8*)(&ram[osd_header[3]/4]); + UINT32 *palette = &ram[osd_header[7]/4]; + + UINT32 x_disp_start_and_width = osd_header[1]; + UINT32 xdisp_width = (x_disp_start_and_width >> 16) & 0x1fff; + UINT32 xdisp_start = x_disp_start_and_width & 0xfff; + + UINT32 image_height_and_width = osd_header[2]; + UINT32 yimg_height = (image_height_and_width >> 16) & 0x7ff; + UINT32 ximg_width = image_height_and_width & 0x7ff; + + UINT32 y_position_and_region_alpha = osd_header[5]; + UINT32 ydisp_last = (y_position_and_region_alpha >> 12) & 0x7ff; + UINT32 ydisp_start = y_position_and_region_alpha & 0x7ff; + + /* UINT32 first_x = m_drm0_regs[DRM_ACTIVE_X_REG] & 0xffff; + UINT32 last_x = (m_drm0_regs[DRM_ACTIVE_X_REG] >> 16) & 0xffff; + + UINT32 first_y = m_drm0_regs[DRM_ACTIVE_Y_REG] & 0xfff; + UINT32 last_y = (m_drm0_regs[DRM_ACTIVE_Y_REG] >> 16) & 0xfff;*/ + + for (j=ydisp_start; j <= ydisp_last; j++) + { + UINT32 *bmp = &bitmap.pix32(j); + + for (i=xdisp_start; i <= (xdisp_start + xdisp_width); i++) + { + if ((i <= (xdisp_start + ximg_width)) && (j <= (ydisp_start + yimg_height))) { + bmp[i] = palette[vbuf[i+((j-ydisp_start)*ximg_width)]]; + } else { + bmp[i] = ycc_to_rgb(m_drm1_regs[DRM_BCKGND_REG]); + } + } + } + } + return 0; +} + +static ADDRESS_MAP_START(cxhumax_map, AS_PROGRAM, 32, cxhumax_state) + AM_RANGE(0x00000000, 0x03ffffff) AM_RAM AM_SHARE("ram") AM_MIRROR(0x40000000) // 64?MB RAM + AM_RANGE(0xe0000000, 0xe000ffff) AM_READWRITE(cx_hsx_r, cx_hsx_w) // HSX + AM_RANGE(0xe0010000, 0xe0010003) AM_READWRITE(cx_romdescr_r, cx_romdescr_w) // ROM Descriptor + AM_RANGE(0xe0010004, 0xe001000f) AM_READWRITE(cx_isaromdescr_r, cx_isaromdescr_w) // ISA/ROM Descriptors + AM_RANGE(0xe0010010, 0xe001001f) AM_READWRITE(cx_isadescr_r, cx_isadescr_w) // ISA Descriptors + AM_RANGE(0xe0010020, 0xe001002f) AM_READWRITE(cx_rommap_r, cx_rommap_w) // ROM Mapping + AM_RANGE(0xe0010030, 0xe0010033) AM_READWRITE(cx_rommode_r, cx_rommode_w) // ISA Mode + AM_RANGE(0xe0010034, 0xe0010037) AM_READWRITE(cx_xoemask_r, cx_xoemask_w) // XOE Mask + AM_RANGE(0xe0010040, 0xe0010047) AM_READWRITE(cx_pci_r, cx_pci_w) // PCI + AM_RANGE(0xe0010080, 0xe00100ff) AM_READWRITE(cx_extdesc_r, cx_extdesc_w) // Extended Control + AM_RANGE(0xe0400014, 0xe0400017) AM_WRITE(cx_remap_w) // RST_REMAP_REG + AM_RANGE(0xe0400024, 0xe0400027) AM_READWRITE(cx_scratch_r, cx_scratch_w) // RST_SCRATCH_REG - System Scratch Register + AM_RANGE(0xe0430000, 0xe0430103) AM_READWRITE(cx_timers_r, cx_timers_w) // Timers + AM_RANGE(0xe0411000, 0xe0411033) AM_READWRITE(cx_uart2_r, cx_uart2_w) // UART2 + AM_RANGE(0xe0440000, 0xe0440013) AM_READWRITE(cx_pll_r, cx_pll_w) // PLL Registers + AM_RANGE(0xe0440020, 0xe0440037) AM_READWRITE(cx_clkdiv_r, cx_clkdiv_w) // Clock Divider Registers + AM_RANGE(0xe0440094, 0xe0440097) AM_READWRITE(cx_pllprescale_r, cx_pllprescale_w) // PLL Prescale + AM_RANGE(0xe0440100, 0xe0440173) AM_READWRITE(cx_chipcontrol_r, cx_chipcontrol_w) // Chip Control Registers + AM_RANGE(0xe0450000, 0xe0450037) AM_READWRITE(cx_intctrl_r, cx_intctrl_w) // Interrupt Controller Registers + AM_RANGE(0xe0490000, 0xe0490017) AM_READWRITE(cx_ss_r, cx_ss_w) // Synchronous Serial Port + AM_RANGE(0xe04e0000, 0xe04e001f) AM_READWRITE(cx_i2c0_r, cx_i2c0_w) // I2C0 + AM_RANGE(0xe04e1000, 0xe04e101f) AM_READWRITE(cx_i2c1_r, cx_i2c1_w) // I2C1 + AM_RANGE(0xe04e2000, 0xe04e201f) AM_READWRITE(cx_i2c2_r, cx_i2c2_w) // I2C2 + AM_RANGE(0xe0500300, 0xe050030b) AM_READWRITE(cx_mc_cfg_r, cx_mc_cfg_w) // Memory Controller configuration + AM_RANGE(0xe0560000, 0xe05600fb) AM_READWRITE(cx_drm0_r, cx_drm0_w) // DRM0 + AM_RANGE(0xe0570000, 0xe05700fb) AM_READWRITE(cx_drm1_r, cx_drm1_w) // DRM1 + AM_RANGE(0xe05d0800, 0xe05d0bff) AM_READWRITE(cx_hdmi_r, cx_hdmi_w) // HDMI + AM_RANGE(0xe0600000, 0xe063ffff) AM_READWRITE(cx_gxa_r, cx_gxa_w) // GXA + AM_RANGE(0xe4017000, 0xe40173ff) AM_RAM // HSX - BSP - 1K Video Shared Dual Port RAM (shared with MVP) + AM_RANGE(0xe4080000, 0xe4083fff) AM_RAM // HSX - TSP 0 - 16K Private Instructions/Data and Host-Shared Data + AM_RANGE(0xf0000000, 0xf03fffff) AM_READWRITE(flash_r, flash_w) AM_MIRROR(0xf8000000) // 4MB FLASH (INTEL 28F320J3D) + AM_RANGE(0xf4000000, 0xf43fffff) AM_READ(dummy_flash_r) // do we need it? +ADDRESS_MAP_END + +static INPUT_PORTS_START( cxhumax ) +INPUT_PORTS_END + +void cxhumax_state::machine_start() +{ + int index = 0; + for(index = 0; index < MAX_CX_TIMERS; index++) + { + m_timer_regs.timer[index].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(cxhumax_state::timer_tick),this)); + m_timer_regs.timer[index].timer->adjust(attotime::never, index); + } +} + +void cxhumax_state::machine_reset() +{ + m_i2c0_regs[0x08/4] = 0x08; // SDA high + m_i2c2_regs[0x08/4] = 0x08; // SDA high + + UINT8* FLASH = memregion("flash")->base(); + memcpy(m_ram,FLASH,0x400000); + + m_chipcontrol_regs[PIN_CONFIG_0_REG] = + 1 << 0 | /* Short Reset: 0=200ms delay ; 1=1ms delay */ + 1 << 1 | /* Software config bit. OK */ + 1 << 4 | /* SDRAM memory controller data width. 0=16bit 1=32bit */ + 1 << 11 | /* I/O Addr bus width 11=23 bit 10=22bit 01=21bit 00=20bit / PCImode: 0=held in reset 1=normal reset OK? */ + 0 << 16 | /* 0=PCI mode 1=Standard I/O mode */ + 1 << 23 | /* 0=PCI device 1=PCI host bridge OK */ + 1 << 26 | /* 0=SC1 used for NDS 1=SC1 not used for NDS */ + 1 << 27 | /* 0=8bit ROM 1=16bit ROM */ + 1 << 28 | /* 0=SC0 used for NDS 1=SC0 not used for NDS */ + 0 << 29 | /* 0=using SC2 1=not using SC2 */ + 0 << 30 | /* 0=using SC1 (TDA8004) 1=not using SC1 */ + 1 << 31; /* 0=Ext clk for boot 1=Int PLL for boot OK */ + m_chipcontrol_regs[SREG_MODE_REG] = 0x0000020F; + + memset(m_isaromdescr_regs,0,sizeof(m_isaromdescr_regs)); + memset(m_isadescr_regs,0,sizeof(m_isadescr_regs)); + m_rommode_reg=0; + m_xoemask_reg=0; + memset(m_extdesc_regs,0,sizeof(m_extdesc_regs)); + + m_pll_regs[SREG_MPG_0_INTFRAC_REG] = (0x1A << 25) /* integer */ | 0x5D1764 /* fraction */; + m_pll_regs[SREG_MPG_1_INTFRAC_REG] = (0x1A << 25) /* integer */ | 0x5D1764 /* fraction */; + m_pll_regs[SREG_ARM_INTFRAC_REG] = (0x28 << 25) /* integer */ | 0xCEDE62 /* fraction */; + m_pll_regs[SREG_MEM_INTFRAC_REG] = (0x13 << 25) /* integer */ | 0xC9B26D /* fraction */; + m_pll_regs[SREG_USB_INTFRAC_REG] = (0x08 << 25) /* integer */ | 0x52BF5B /* fraction */; + + m_clkdiv_regs[SREG_DIV_0_REG] = (2<<0)|(1<<6)|(2<<8)|(2<<14)|(10<<16)|(1<<22)|(10<<24)|(1<<30); + m_clkdiv_regs[SREG_DIV_1_REG] = (5<<0)|(0<<6)|(12<<8)|(0<<14)|(4<<16)|(1<<22)|(5<<24)|(1<<30); + m_clkdiv_regs[SREG_DIV_2_REG] = (22<<0)|(0<<6)|(12<<8)|(1<<14)|(4<<16)|(3<<22); //|(5<<24)|(1<<30);??? + m_clkdiv_regs[SREG_DIV_3_REG] = (5<<0)|(0<<6)|(5<<8)|(0<<14)|(5<<16)|(0<<22)|(5<<24)|(0<<30); + m_clkdiv_regs[SREG_DIV_4_REG] = (8<<0)|(0<<6)|(5<<8)|(0<<14)|(5<<16)|(0<<22)|(5<<24)|(0<<30); + m_clkdiv_regs[SREG_DIV_5_REG] = (8<<0)|(0<<6)|(5<<8)|(0<<14)|(5<<16)|(0<<22); + + m_pllprescale_reg=0xFFF; + + m_mccfg_regs[MC_CFG0] = ((m_chipcontrol_regs[PIN_CONFIG_0_REG]>>4)&1)<<16; + m_mccfg_regs[MC_CFG1] = 0; + m_mccfg_regs[MC_CFG2] = (7<<8)|(7<<0); + + // UART2 + m_uart2_regs[UART_FIFC_REG] = 0x30; + + // Clear SS TX FIFO + memset(m_ss_tx_fifo,0,sizeof(m_ss_tx_fifo)); + m_ss_regs[SS_BAUD_REG] = 1; // Default SS clock = 13,5MHz + + memset(m_intctrl_regs,0,sizeof(m_intctrl_regs)); + + memset(m_hdmi_regs,0,sizeof(m_hdmi_regs)); + + memset(m_gxa_cmd_regs,0,sizeof(m_gxa_cmd_regs)); +} + +static MACHINE_CONFIG_START( cxhumax, cxhumax_state ) + MCFG_CPU_ADD("maincpu", ARM920T, 180000000) // CX24175 (RevC up?) + MCFG_CPU_PROGRAM_MAP(cxhumax_map) + + + MCFG_INTEL_28F320J3D_ADD("flash") + MCFG_I2CMEM_ADD("eeprom") + MCFG_I2CMEM_DATA_SIZE(0x2000) + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(50) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ + MCFG_SCREEN_SIZE(1920, 1080) + MCFG_SCREEN_VISIBLE_AREA(0, 1920-1, 0, 1080-1) + MCFG_SCREEN_UPDATE_DRIVER(cxhumax_state, screen_update_cxhumax) + + MCFG_PALETTE_ADD_BLACK_AND_WHITE("palette") + + MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) +MACHINE_CONFIG_END + +ROM_START( hxhdci2k ) + ROM_REGION( 0x400000, "flash", 0 ) + ROM_SYSTEM_BIOS( 0, "FW10005", "HDCI REV 1.0 RHDXSCI 1.00.05" ) /* 19 AUG 2008 */ + ROM_LOAD16_WORD_SWAP( "28f320j3d.bin", 0x000000, 0x400000, BAD_DUMP CRC(63d98942) SHA1(c5b8d701677a3edc25f203854f44953b19c9158d) ) + + ROM_REGION16_BE( 0x2000, "eeprom", 0 ) + ROM_LOAD( "24lc64.bin", 0x0000, 0x2000, NO_DUMP) +ROM_END + +/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ +SYST( 2008, hxhdci2k, 0, 0, cxhumax, cxhumax, driver_device, 0, "HUMAX", "HUMAX HDCI-2000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) |