summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/skeleton/dm7000.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/skeleton/dm7000.cpp')
-rw-r--r--src/mame/skeleton/dm7000.cpp435
1 files changed, 435 insertions, 0 deletions
diff --git a/src/mame/skeleton/dm7000.cpp b/src/mame/skeleton/dm7000.cpp
new file mode 100644
index 00000000000..0692a7da716
--- /dev/null
+++ b/src/mame/skeleton/dm7000.cpp
@@ -0,0 +1,435 @@
+// license:BSD-3-Clause
+// copyright-holders:Lukasz Markowski
+/***************************************************************************
+
+ Dream Multimedia Dreambox 7000/5620/500
+
+ 20/03/2010 Skeleton driver.
+
+
+ DM7000 - CPU STB04500 at 252 MHz
+ RAM 64MB
+ Flash 8MB
+ 1 x DVB-S
+ 1 x IDE interface
+ 1 x Common Interface (CI)
+ 1 x Compact flash
+ 2 x Smart card reader
+ 1 x USB
+ 1 x RS232
+ 1 x LAN 100Mbit/s
+ 1 x LCD display
+
+ DM56x0 - CPU STB04500 at 252 MHz
+ RAM 64MB
+ Flash 8MB
+ 1 x DVB-S
+ 2 x Common Interface (CI)
+ 1 x Smart card reader
+ 1 x LAN 100Mbit/s (just on 5620)
+ 1 x LCD display
+
+ DM500 - CPU STBx25xx at 252 MHz
+ RAM 96MB
+ Flash 32MB
+ 1 x DVB-S
+ 1 x Smart card reader
+ 1 x LAN 100Mbit/s
+
+****************************************************************************/
+
+#include "emu.h"
+
+#include "cpu/powerpc/ppc.h"
+#include "machine/terminal.h"
+#include "screen.h"
+
+#define VERBOSE ( 1 )
+#include "logmacro.h"
+
+namespace {
+
+class dm7000_state : public driver_device
+{
+public:
+ dm7000_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_terminal(*this, "terminal")
+ {
+ }
+
+ void dm7000(machine_config &config);
+
+private:
+ required_device<ppc4xx_device> m_maincpu;
+ required_device<generic_terminal_device> m_terminal;
+
+ void dm7000_iic0_w(offs_t offset, uint8_t data);
+ uint8_t dm7000_iic0_r(offs_t offset);
+ void dm7000_iic1_w(offs_t offset, uint8_t data);
+ uint8_t dm7000_iic1_r(offs_t offset);
+
+ void dm7000_scc0_w(offs_t offset, uint8_t data);
+ uint8_t dm7000_scc0_r(offs_t offset);
+ void kbd_put(u8 data);
+ uint8_t m_scc0_lcr = 0U;
+ uint8_t m_scc0_lsr = 0U;
+ uint8_t m_term_data = 0U;
+
+
+ void dm7000_gpio0_w(offs_t offset, uint8_t data);
+ uint8_t dm7000_gpio0_r(offs_t offset);
+
+ void dm7000_scp0_w(offs_t offset, uint8_t data);
+ uint8_t dm7000_scp0_r(offs_t offset);
+
+ void dm7000_enet_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+ uint16_t dm7000_enet_r(offs_t offset);
+
+ uint32_t dcr_r(offs_t offset);
+ void dcr_w(offs_t offset, uint32_t data);
+
+
+ uint16_t m_enet_regs[32]{};
+
+ uint32_t dcr[1024]{};
+ virtual void machine_reset() override ATTR_COLD;
+ virtual void video_start() override ATTR_COLD;
+ uint32_t screen_update_dm7000(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ void dm7000_mem(address_map &map) ATTR_COLD;
+};
+
+/* */
+#define UART_DLL 0
+#define UART_RBR 0
+#define UART_THR 0
+#define UART_DLH 1
+#define UART_IER 1
+#define UART_IIR 2
+#define UART_FCR 2
+#define UART_LCR 3
+#define UART_LCR_DLAB 0x80
+#define UART_MCR 4
+#define UART_LSR 5
+#define UART_LSR_TEMT 0x20
+#define UART_LSR_THRE 0x40
+#define UART_MSR 6
+#define UART_SCR 7
+
+/* */
+#define SCP_SPMODE 0
+#define SCP_RXDATA 1
+#define SCP_TXDATA 2
+#define SCP_SPCOM 3
+#define SCP_STATUS 4
+#define SCP_STATUS_RXRDY 1
+#define SCP_CDM 6
+
+/* STB045xxx DCRs */
+
+#define DCRSTB045_CICVCR 0x033 /* CIC Video Control Register */
+#define DCRSTB045_SCCR 0x120 /* Serial Clock Control Register */
+#define DCRSTB045_VIDEO_CNTL 0x140 /* Video Control Register */
+#define DCRSTB045_CMD_STAT 0x14a /* Command status */
+#define DCRSTB045_DISP_MODE 0x154 /* Display Mode Register */
+#define DCRSTB045_FRAME_BUFR_BASE 0x179 /* Frame Buffers Base Address Register */
+
+uint8_t dm7000_state::dm7000_iic0_r(offs_t offset)
+{
+ uint8_t data = 0; // dummy
+ LOG("%s: (IIC0) %08X -> %08X\n", machine().describe_context(), 0x40030000 + offset, data);
+ return data;
+}
+
+void dm7000_state::dm7000_iic0_w(offs_t offset, uint8_t data)
+{
+ LOG("%s: (IIC0) %08X <- %08X\n", machine().describe_context(), 0x40030000 + offset, data);
+}
+
+uint8_t dm7000_state::dm7000_iic1_r(offs_t offset)
+{
+ uint8_t data = 0; // dummy
+ LOG("%s: (IIC1) %08X -> %08X\n", machine().describe_context(), 0x400b0000 + offset, data);
+ return data;
+}
+
+void dm7000_state::dm7000_iic1_w(offs_t offset, uint8_t data)
+{
+ LOG("%s: (IIC1) %08X <- %08X\n", machine().describe_context(), 0x400b0000 + offset, data);
+}
+
+uint8_t dm7000_state::dm7000_scc0_r(offs_t offset)
+{
+ uint8_t data = 0;
+ switch(offset) {
+ case UART_THR:
+ data = m_term_data;
+ if(m_term_data == 0xd) {
+ m_term_data = 0xa;
+ } else {
+ m_term_data = 0;
+ m_scc0_lsr = 0;
+ }
+ break;
+ case UART_LSR:
+ data = UART_LSR_THRE | UART_LSR_TEMT | m_scc0_lsr;
+ break;
+ }
+ LOG("%s: (SCC0) %08X -> %08X\n", machine().describe_context(), 0x40040000 + offset, data);
+ return data;
+}
+
+void dm7000_state::dm7000_scc0_w(offs_t offset, uint8_t data)
+{
+ switch(offset) {
+ case UART_THR:
+ if(!(m_scc0_lcr & UART_LCR_DLAB)) {
+ m_terminal->write(data);
+ m_scc0_lsr = 1;
+ }
+ break;
+ case UART_LCR:
+ m_scc0_lcr = data;
+ break;
+ }
+ LOG("%s: (SCC0) %08X <- %08X\n", machine().describe_context(), 0x40040000 + offset, data);
+}
+
+uint8_t dm7000_state::dm7000_gpio0_r(offs_t offset)
+{
+ uint8_t data = 0; // dummy
+ LOG("%s: (GPIO0) %08X -> %08X\n", machine().describe_context(), 0x40060000 + offset, data);
+ return data;
+}
+
+void dm7000_state::dm7000_gpio0_w(offs_t offset, uint8_t data)
+{
+ LOG("%s: (GPIO0) %08X <- %08X\n", machine().describe_context(), 0x40060000 + offset, data);
+}
+
+uint8_t dm7000_state::dm7000_scp0_r(offs_t offset)
+{
+ uint8_t data = 0; // dummy
+ switch(offset) {
+ case SCP_STATUS:
+ data = SCP_STATUS_RXRDY;
+ break;
+ }
+ LOG("%s: (SCP0) %08X -> %08X\n", machine().describe_context(), 0x400c0000 + offset, data);
+ return data;
+}
+
+void dm7000_state::dm7000_scp0_w(offs_t offset, uint8_t data)
+{
+ LOG("%s: (SCP0) %08X <- %08X\n", machine().describe_context(), 0x400c0000 + offset, data);
+ switch(offset) {
+ case SCP_TXDATA:
+ //printf("%02X ", data);
+ break;
+ }
+}
+
+uint16_t dm7000_state::dm7000_enet_r(offs_t offset)
+{
+ uint16_t data;
+ switch (offset) {
+ case 0x01:
+ data = 0x1801;
+ break;
+ case 0x05:
+ data = 0x3330;
+ break;
+ case 0x07:
+ data = 0x3300;
+ break;
+ default:
+ data = m_enet_regs[offset];
+ break;
+ }
+ LOG("%s: (ENET) %08X -> %08X\n", machine().describe_context(), 0x72000600 + (offset), data);
+ return data;
+}
+
+void dm7000_state::dm7000_enet_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOG("%s: (ENET) %08X <- %08X\n", machine().describe_context(), 0x72000600 + (offset), data);
+ COMBINE_DATA(&m_enet_regs[offset]);
+}
+
+/*
+ Memory map for the IBM "Redwood-4" STB03xxx evaluation board.
+
+ The STB03xxx internal i/o addresses don't work for us 1:1,
+ so we need to map them at a well know virtual address.
+
+ 4000 000x uart1
+ 4001 00xx ppu
+ 4002 00xx smart card
+ 4003 000x iic
+ 4004 000x uart0
+ 4005 0xxx timer
+ 4006 00xx gpio
+ 4007 00xx smart card
+ 400b 000x iic
+ 400c 000x scp
+ 400d 000x modem
+
+ STBx25xx
+
+ 4000 000x Serial1 Controller
+ 4001 000x Serial2 Controller
+ 4002 00xx Smart Card Interface 0
+ 4003 000x IIC Interface 0
+ 4004 000x Serial0 Controller
+ 4005 0xxx General Purpose Timers
+ 4006 00xx General Purpose Input / Output
+ 4007 00xx Smart Card Interface 1
+ 400c 000x Serial Controller Port
+ 400d 00xx Synchronous Serial Port
+
+ STB04xxx
+
+ 4000 00xx Serial1/Infrared Controller
+ 4001 00xx Universal Serial Bus
+ 4002 00xx Smart Card Interface 0
+ 4003 000x IIC Interface 0
+ 4004 000x Serial0/Uart750 Controller
+ 4005 0xxx General Purpose Timers
+ 4006 00xx General Purpose Input / Output
+ 4007 00xx Smart Card Interface 1
+ 400b 000x IIC Interface 1
+ 400c 000x Serial Controller Port
+ 400d 00xx Synchronous Serial Port
+ 400e 000x Serial2/UART750 Controller
+ 400f 0xxx IDE Controller
+
+*/
+void dm7000_state::dm7000_mem(address_map &map)
+{
+ map.unmap_value_high();
+ map(0x00000000, 0x01ffffff).ram(); // RAM page 0 - 32MB
+ map(0x20000000, 0x21ffffff).ram(); // RAM page 1 - 32MB
+
+ map(0x40030000, 0x4003000f).rw(FUNC(dm7000_state::dm7000_iic0_r), FUNC(dm7000_state::dm7000_iic0_w));
+ map(0x40040000, 0x40040007).rw(FUNC(dm7000_state::dm7000_scc0_r), FUNC(dm7000_state::dm7000_scc0_w));
+ map(0x40060000, 0x40060047).rw(FUNC(dm7000_state::dm7000_gpio0_r), FUNC(dm7000_state::dm7000_gpio0_w));
+ map(0x400b0000, 0x400b000f).rw(FUNC(dm7000_state::dm7000_iic1_r), FUNC(dm7000_state::dm7000_iic1_w));
+ map(0x400c0000, 0x400c0007).rw(FUNC(dm7000_state::dm7000_scp0_r), FUNC(dm7000_state::dm7000_scp0_w));
+
+ /* ENET - ASIX AX88796 */
+ map(0x72000300, 0x720003ff).rw(FUNC(dm7000_state::dm7000_enet_r), FUNC(dm7000_state::dm7000_enet_w));
+
+ map(0x7f800000, 0x7ffdffff).rom().region("user2", 0);
+ map(0x7ffe0000, 0x7fffffff).rom().region("user1", 0);
+ //map(0xfffe0000, 0xffffffff).rom().region("user1",0);
+}
+
+/* Input ports */
+static INPUT_PORTS_START( dm7000 )
+INPUT_PORTS_END
+
+
+void dm7000_state::machine_reset()
+{
+ dcr[DCRSTB045_CICVCR] = 0x00000001;
+ dcr[DCRSTB045_SCCR] = 0x00420080 /* default for serial divs */ | 0x3f /* undocumented?? used to print clocks */;
+ dcr[DCRSTB045_VIDEO_CNTL] = 0x00009000;
+ dcr[DCRSTB045_DISP_MODE] = 0x00880000;
+ dcr[DCRSTB045_FRAME_BUFR_BASE] = 0x0f000000;
+ m_scc0_lsr = UART_LSR_THRE | UART_LSR_TEMT;
+
+ m_maincpu->ppc4xx_set_dcr_read_handler(read32sm_delegate(*this, FUNC(dm7000_state::dcr_r)));
+ m_maincpu->ppc4xx_set_dcr_write_handler(write32sm_delegate(*this, FUNC(dm7000_state::dcr_w)));
+}
+
+void dm7000_state::video_start()
+{
+}
+
+uint32_t dm7000_state::screen_update_dm7000(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ return 0;
+}
+
+uint32_t dm7000_state::dcr_r(offs_t offset)
+{
+ osd_printf_debug("DCR %03X read\n", offset);
+ if(offset>=1024) {printf("get %04X\n", offset); return 0;} else
+ switch(offset) {
+ case DCRSTB045_CMD_STAT:
+ return 0; // assume that video dev is always ready
+ default:
+ return dcr[offset];
+ }
+
+}
+
+void dm7000_state::dcr_w(offs_t offset, uint32_t data)
+{
+ osd_printf_debug("DCR %03X write = %08X\n", offset, data);
+ if(offset>=1024) {printf("get %04X\n", offset); } else
+ dcr[offset] = data;
+}
+
+void dm7000_state::kbd_put(u8 data)
+{
+ //printf("%02X\n", data);
+ m_term_data = data;
+ m_scc0_lsr = 1;
+}
+
+void dm7000_state::dm7000(machine_config &config)
+{
+ /* basic machine hardware */
+ PPC405GP(config, m_maincpu, 252000000 / 10); // Should be PPC405D4?
+ // Slowed down 10 times in order to get normal response for now
+ m_maincpu->set_bus_frequency(252000000);
+ m_maincpu->set_addrmap(AS_PROGRAM, &dm7000_state::dm7000_mem);
+
+ /* video hardware */
+ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
+ screen.set_refresh_hz(50);
+ screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
+ screen.set_size(640, 480);
+ screen.set_visarea(0, 640-1, 0, 480-1);
+ screen.set_screen_update(FUNC(dm7000_state::screen_update_dm7000));
+
+ GENERIC_TERMINAL(config, m_terminal, 0);
+ m_terminal->set_keyboard_callback(FUNC(dm7000_state::kbd_put));
+}
+
+
+/* ROM definition */
+ROM_START( dm7000 )
+ ROM_REGION( 0x20000, "user1", ROMREGION_32BIT | ROMREGION_BE )
+ ROMX_LOAD("dm7000.bin", 0x0000, 0x20000, CRC(8a410f67) SHA1(9d6c9e4f5b05b28453d3558e69a207f05c766f54), ROM_GROUPWORD)
+ ROM_REGION( 0x800000, "user2", ROMREGION_32BIT | ROMREGION_BE | ROMREGION_ERASEFF )
+ ROM_LOAD("rel108_dm7000.img", 0x0000, 0x5e0000, CRC(e78b6407) SHA1(aaa786d341c629eec92fcf04bfafc1de43f6dabf))
+ROM_END
+
+ROM_START( dm5620 )
+ ROM_REGION( 0x20000, "user1", ROMREGION_32BIT | ROMREGION_BE )
+ ROMX_LOAD("dm5620.bin", 0x0000, 0x20000, CRC(ccddb822) SHA1(3ecf553ced0671599438368f59d8d30df4d13ade), ROM_GROUPWORD)
+ ROM_REGION( 0x800000, "user2", ROMREGION_32BIT | ROMREGION_BE | ROMREGION_ERASEFF )
+ ROM_LOAD("rel106_dm5620.img", 0x0000, 0x57b000, CRC(2313d71d) SHA1(0d3d99ab3b3266624f237b7b67e045d7910c44a5))
+ROM_END
+
+ROM_START( dm500 )
+ ROM_REGION( 0x20000, "user1", ROMREGION_32BIT | ROMREGION_BE )
+ ROM_SYSTEM_BIOS( 0, "alps", "Alps" )
+ ROMX_LOAD("dm500-alps-boot.bin", 0x0000, 0x20000, CRC(daf2da34) SHA1(68f3734b4589fcb3e73372e258040bc8b83fd739), ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(0))
+ ROM_SYSTEM_BIOS( 1, "phil", "Philips" )
+ ROMX_LOAD("dm500-philps-boot.bin", 0x0000, 0x20000, CRC(af3477c7) SHA1(9ac918f6984e6927f55bea68d6daaf008787136e), ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(1))
+ ROM_REGION( 0x800000, "user2", ROMREGION_32BIT | ROMREGION_BE | ROMREGION_ERASEFF )
+ ROM_LOAD("rel108_dm500.img", 0x0000, 0x5aa000, CRC(44be2376) SHA1(1f360572998b1bc4dc10c5210a2aed573a75e2fa))
+ROM_END
+
+} // anonymous namespace
+
+/* Driver */
+
+// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
+SYST( 2003, dm7000, 0, 0, dm7000, dm7000, dm7000_state, empty_init, "Dream Multimedia", "Dreambox 7000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
+SYST( 2004, dm5620, dm7000, 0, dm7000, dm7000, dm7000_state, empty_init, "Dream Multimedia", "Dreambox 5620", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
+SYST( 2006, dm500, dm7000, 0, dm7000, dm7000, dm7000_state, empty_init, "Dream Multimedia", "Dreambox 500", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )