summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/hp49gp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/hp49gp.cpp')
-rw-r--r--src/mame/drivers/hp49gp.cpp337
1 files changed, 337 insertions, 0 deletions
diff --git a/src/mame/drivers/hp49gp.cpp b/src/mame/drivers/hp49gp.cpp
new file mode 100644
index 00000000000..dafdf563516
--- /dev/null
+++ b/src/mame/drivers/hp49gp.cpp
@@ -0,0 +1,337 @@
+// license:BSD-3-Clause
+// copyright-holders:Tim Schuerewegen
+/*******************************************************************************
+
+ Hewlett Packard 49G+ Graphing Calculator
+
+*******************************************************************************/
+
+#include "emu.h"
+#include "cpu/arm7/arm7.h"
+#include "machine/s3c2410.h"
+#include "rendlay.h"
+
+#define VERBOSE_LEVEL ( 0 )
+
+struct lcd_spi_t
+{
+ int l1;
+ int data;
+ int l3;
+ UINT32 shift, bits;
+};
+
+class hp49gp_state : public driver_device
+{
+public:
+ hp49gp_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag),
+ m_s3c2410(*this, "s3c2410"),
+ m_steppingstone(*this, "steppingstone"),
+ m_maincpu(*this, "maincpu") { }
+
+ UINT32 m_port[9];
+ required_device<s3c2410_device> m_s3c2410;
+ required_shared_ptr<UINT32> m_steppingstone;
+ lcd_spi_t m_lcd_spi;
+ DECLARE_DRIVER_INIT(hp49gp);
+ virtual void machine_start();
+ virtual void machine_reset();
+ DECLARE_INPUT_CHANGED_MEMBER(port_changed);
+ DECLARE_READ32_MEMBER(s3c2410_gpio_port_r);
+ DECLARE_WRITE32_MEMBER(s3c2410_gpio_port_w);
+ inline void verboselog(int n_level, const char *s_fmt, ...) ATTR_PRINTF(3,4);
+ void lcd_spi_reset( );
+ void lcd_spi_init( );
+ void lcd_spi_line_w( int line, int data);
+ int lcd_spi_line_r( int line);
+ required_device<cpu_device> m_maincpu;
+};
+
+/***************************************************************************
+ MACHINE HARDWARE
+***************************************************************************/
+
+// LCD SPI
+
+enum
+{
+ LCD_SPI_LINE_1,
+ LCD_SPI_LINE_DATA,
+ LCD_SPI_LINE_3
+};
+
+inline void hp49gp_state::verboselog(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);
+ }
+}
+
+void hp49gp_state::lcd_spi_reset( )
+{
+ verboselog( 5, "lcd_spi_reset\n");
+ m_lcd_spi.l1 = 0;
+ m_lcd_spi.data = 0;
+ m_lcd_spi.l3 = 0;
+}
+
+void hp49gp_state::lcd_spi_init( )
+{
+ verboselog( 5, "lcd_spi_init\n");
+ lcd_spi_reset();
+}
+
+void hp49gp_state::lcd_spi_line_w( int line, int data)
+{
+ switch (line)
+ {
+ case LCD_SPI_LINE_1 :
+ {
+ if (data != m_lcd_spi.l1)
+ {
+ if (data == 0)
+ {
+ m_lcd_spi.shift = 0;
+ m_lcd_spi.bits = 0;
+ }
+ verboselog( 5, "LCD_SPI_LINE_1 <- %d\n", data);
+ m_lcd_spi.l1 = data;
+ }
+ }
+ break;
+ case LCD_SPI_LINE_DATA :
+ {
+ if (data != m_lcd_spi.data)
+ {
+ verboselog( 5, "LCD_SPI_LINE_DATA <- %d\n", data);
+ m_lcd_spi.data = data;
+ }
+ }
+ break;
+ case LCD_SPI_LINE_3 :
+ {
+ if (data != m_lcd_spi.l3)
+ {
+ if ((data != 0) && (m_lcd_spi.l1 == 0))
+ {
+ verboselog( 5, "LCD SPI write bit %d\n", m_lcd_spi.data ? 1 : 0);
+ if (m_lcd_spi.bits < 8)
+ {
+ m_lcd_spi.shift = (m_lcd_spi.shift << 1) | (m_lcd_spi.data ? 1 : 0);
+ }
+ m_lcd_spi.bits++;
+ if (m_lcd_spi.bits == 8)
+ {
+ verboselog( 5, "LCD SPI write byte %02X\n", m_lcd_spi.shift);
+ }
+ else if (m_lcd_spi.bits == 9)
+ {
+ verboselog( 5, "LCD SPI write ack %d\n", (m_lcd_spi.data ? 1 : 0));
+ }
+ }
+ verboselog( 5, "LCD_SPI_LINE_3 <- %d\n", data);
+ m_lcd_spi.l3 = data;
+ }
+ }
+ break;
+ }
+}
+
+int hp49gp_state::lcd_spi_line_r( int line)
+{
+ switch (line)
+ {
+ case LCD_SPI_LINE_1 :
+ {
+ verboselog( 7, "LCD_SPI_LINE_1 -> %d\n", m_lcd_spi.l1);
+ return m_lcd_spi.l1;
+ }
+ case LCD_SPI_LINE_DATA :
+ {
+ verboselog( 7, "LCD_SPI_LINE_DATA -> %d\n", m_lcd_spi.data);
+ return m_lcd_spi.data;
+ }
+ case LCD_SPI_LINE_3 :
+ {
+ verboselog( 7, "LCD_SPI_LINE_3 -> %d\n", m_lcd_spi.l3);
+ return m_lcd_spi.l3;
+ }
+ }
+ return 0;
+}
+
+// I/O PORT
+
+READ32_MEMBER(hp49gp_state::s3c2410_gpio_port_r)
+{
+ UINT32 data = m_port[offset];
+ switch (offset)
+ {
+ case S3C2410_GPIO_PORT_C :
+ {
+ data = data | 0xF000;
+ }
+ break;
+ case S3C2410_GPIO_PORT_D :
+ {
+ data = data | 0x0008;
+ data = data & ~0x3200;
+ data |= (lcd_spi_line_r( LCD_SPI_LINE_1) ? 1 : 0) << 9;
+ data |= (lcd_spi_line_r( LCD_SPI_LINE_DATA) ? 1 : 0) << 12;
+ data |= (lcd_spi_line_r( LCD_SPI_LINE_3) ? 1 : 0) << 13;
+ }
+ break;
+ case S3C2410_GPIO_PORT_E :
+ {
+ data = data | 0xC000;
+ }
+ break;
+ case S3C2410_GPIO_PORT_F :
+ {
+ data = data | 0x0008;
+ }
+ break;
+ case S3C2410_GPIO_PORT_G :
+ {
+ data = data & ~0xFF00;
+ if ((data & 0x02) == 0) data |= (ioport( "ROW1")->read() << 8);
+ if ((data & 0x04) == 0) data |= (ioport( "ROW2")->read() << 8);
+ if ((data & 0x08) == 0) data |= (ioport( "ROW3")->read() << 8);
+ if ((data & 0x10) == 0) data |= (ioport( "ROW4")->read() << 8);
+ if ((data & 0x20) == 0) data |= (ioport( "ROW5")->read() << 8);
+ if ((data & 0x40) == 0) data |= (ioport( "ROW6")->read() << 8);
+ if ((data & 0x80) == 0) data |= (ioport( "ROW7")->read() << 8);
+ }
+ break;
+ case S3C2410_GPIO_PORT_H :
+ {
+ data = (data | 0x0080) & ~0x0040;
+ }
+ break;
+ }
+ return data;
+}
+
+WRITE32_MEMBER(hp49gp_state::s3c2410_gpio_port_w)
+{
+ m_port[offset] = data;
+ switch (offset)
+ {
+ case S3C2410_GPIO_PORT_D :
+ {
+ lcd_spi_line_w( LCD_SPI_LINE_1, BIT( data, 9) ? 1 : 0);
+ lcd_spi_line_w( LCD_SPI_LINE_DATA, BIT( data, 12) ? 1 : 0);
+ lcd_spi_line_w( LCD_SPI_LINE_3, BIT( data, 13) ? 1 : 0);
+ }
+ break;
+ }
+}
+
+// ...
+
+INPUT_CHANGED_MEMBER(hp49gp_state::port_changed)
+{
+ m_s3c2410->s3c2410_request_eint( (FPTR)param + 8);
+}
+
+// ...
+
+void hp49gp_state::machine_start()
+{
+}
+
+void hp49gp_state::machine_reset()
+{
+ m_maincpu->reset();
+}
+
+/***************************************************************************
+ ADDRESS MAPS
+***************************************************************************/
+
+static ADDRESS_MAP_START( hp49gp_map, AS_PROGRAM, 32, hp49gp_state )
+ AM_RANGE(0x00000000, 0x001fffff) AM_ROM
+ AM_RANGE(0x08000000, 0x0801ffff) AM_RAM
+ AM_RANGE(0x08020000, 0x0803ffff) AM_RAM
+ AM_RANGE(0x08040000, 0x0807ffff) AM_RAM
+ AM_RANGE(0x40000000, 0x40000fff) AM_RAM AM_SHARE("steppingstone")
+ADDRESS_MAP_END
+
+/***************************************************************************
+ MACHINE DRIVERS
+***************************************************************************/
+
+DRIVER_INIT_MEMBER(hp49gp_state,hp49gp)
+{
+ UINT8 *rom = (UINT8 *)memregion( "maincpu")->base();
+ memcpy( m_steppingstone, rom, 1024);
+ lcd_spi_init();
+}
+
+static MACHINE_CONFIG_START( hp49gp, hp49gp_state )
+ MCFG_CPU_ADD("maincpu", ARM9, 400000000)
+ MCFG_CPU_PROGRAM_MAP(hp49gp_map)
+
+ MCFG_PALETTE_ADD("palette", 32768)
+
+ MCFG_SCREEN_ADD("screen", LCD)
+ MCFG_SCREEN_REFRESH_RATE(60)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
+ MCFG_SCREEN_SIZE(160, 85)
+ MCFG_SCREEN_VISIBLE_AREA(0, 131 - 1, 0, 80 - 1)
+ MCFG_SCREEN_UPDATE_DEVICE("s3c2410", s3c2410_device, screen_update)
+
+ MCFG_DEFAULT_LAYOUT(layout_lcd)
+
+
+ MCFG_DEVICE_ADD("s3c2410", S3C2410, 12000000)
+ MCFG_S3C2410_PALETTE("palette")
+ MCFG_S3C2410_GPIO_PORT_R_CB(READ32(hp49gp_state, s3c2410_gpio_port_r))
+ MCFG_S3C2410_GPIO_PORT_W_CB(WRITE32(hp49gp_state, s3c2410_gpio_port_w))
+ MCFG_S3C2410_LCD_FLAGS(S3C24XX_INTERFACE_LCD_REVERSE)
+MACHINE_CONFIG_END
+
+static INPUT_PORTS_START( hp49gp )
+ PORT_START("ROW1")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, hp49gp_state, port_changed, (void *)1) PORT_NAME("F1 | A | Y=") PORT_CODE(KEYCODE_F1) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
+ PORT_BIT( 0xDF, IP_ACTIVE_LOW, IPT_UNUSED)
+ PORT_START("ROW2")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, hp49gp_state, port_changed, (void *)2) PORT_NAME("F2 | B | WIN") PORT_CODE(KEYCODE_F2)
+ PORT_BIT( 0xDF, IP_ACTIVE_LOW, IPT_UNUSED)
+ PORT_START("ROW3")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, hp49gp_state, port_changed, (void *)3) PORT_NAME("F3 | C | GRAPH") PORT_CODE(KEYCODE_F3)
+ PORT_BIT( 0xDF, IP_ACTIVE_LOW, IPT_UNUSED)
+ PORT_START("ROW4")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, hp49gp_state, port_changed, (void *)4) PORT_NAME("F4 | D | 2D/3D") PORT_CODE(KEYCODE_F4)
+ PORT_BIT( 0xDF, IP_ACTIVE_LOW, IPT_UNUSED)
+ PORT_START("ROW5")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, hp49gp_state, port_changed, (void *)5) PORT_NAME("F5 | E | TBLSET") PORT_CODE(KEYCODE_F5)
+ PORT_BIT( 0xDF, IP_ACTIVE_LOW, IPT_UNUSED)
+ PORT_START("ROW6")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, hp49gp_state, port_changed, (void *)6) PORT_NAME("F6 | F | TABLE") PORT_CODE(KEYCODE_F6)
+ PORT_BIT( 0xDF, IP_ACTIVE_LOW, IPT_UNUSED)
+ PORT_START("ROW7")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, hp49gp_state, port_changed, (void *)7) PORT_NAME("APPS | G | FILES | BEGIN") PORT_CODE(KEYCODE_G) PORT_CHAR('G')
+ PORT_BIT( 0xDF, IP_ACTIVE_LOW, IPT_UNUSED)
+INPUT_PORTS_END
+
+/***************************************************************************
+ GAME DRIVERS
+***************************************************************************/
+
+ROM_START( hp49gp )
+ ROM_REGION( 0x200000, "maincpu", 0 )
+ ROM_SYSTEM_BIOS( 0, "319", "Version 3.19" )
+ ROMX_LOAD( "319.bin", 0x0000, 0x4000, CRC(6bb5ebfb) SHA1(089c4e4ee7223b489e2f06c30aab0b89131d1c3c), ROM_BIOS(1) )
+ ROM_SYSTEM_BIOS( 1, "315", "Version 3.15.04" )
+ ROMX_LOAD( "31504.bin", 0x0000, 0x4000, CRC(9c71825e) SHA1(0a12b2b70a8573bc90ab5be06e6b2f814b8544ae), ROM_BIOS(2) )
+ROM_END
+
+COMP(2009, hp49gp, 0, 0, hp49gp, hp49gp, hp49gp_state, hp49gp, "Hewlett Packard", "HP49G+", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)