summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/drivers/gp32.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/drivers/gp32.c')
-rw-r--r--src/mess/drivers/gp32.c1726
1 files changed, 0 insertions, 1726 deletions
diff --git a/src/mess/drivers/gp32.c b/src/mess/drivers/gp32.c
deleted file mode 100644
index 26dc298a2ff..00000000000
--- a/src/mess/drivers/gp32.c
+++ /dev/null
@@ -1,1726 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Tim Schuerewegen
-/**************************************************************************
- *
- * gp32.c - Game Park GP32
- * Driver by Tim Schuerewegen
- *
- * CPU: Samsung S3C2400X01 SoC
- * S3C2400X01 consists of:
- * ARM920T CPU core + MMU
- * LCD controller
- * DMA controller
- * Interrupt controller
- * USB controller
- * and more.
- *
- **************************************************************************/
-
-#include "emu.h"
-#include "cpu/arm7/arm7.h"
-#include "cpu/arm7/arm7core.h"
-#include "includes/gp32.h"
-#include "rendlay.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);
- }
-}
-
-#define CLOCK_MULTIPLIER 1
-
-#define MPLLCON 1
-#define UPLLCON 2
-
-#define BIT(x,n) (((x)>>(n))&1)
-#define BITS(x,m,n) (((x)>>(n))&((1<<((m)-(n)+1))-1))
-
-
-// LCD CONTROLLER
-
-
-#define BPPMODE_TFT_01 0x08
-#define BPPMODE_TFT_02 0x09
-#define BPPMODE_TFT_04 0x0A
-#define BPPMODE_TFT_08 0x0B
-#define BPPMODE_TFT_16 0x0C
-
-inline rgb_t gp32_state::s3c240x_get_color_5551( UINT16 data)
-{
- UINT8 r, g, b, i;
- r = BITS( data, 15, 11) << 3;
- g = BITS( data, 10, 6) << 3;
- b = BITS( data, 5, 1) << 3;
- i = BIT( data, 1) << 2;
- return rgb_t( r | i, g | i, b | i);
-}
-
-void gp32_state::s3c240x_lcd_dma_reload()
-{
- m_s3c240x_lcd.vramaddr_cur = m_s3c240x_lcd_regs[5] << 1;
- m_s3c240x_lcd.vramaddr_max = ((m_s3c240x_lcd_regs[5] & 0xFFE00000) | m_s3c240x_lcd_regs[6]) << 1;
- m_s3c240x_lcd.offsize = BITS( m_s3c240x_lcd_regs[7], 21, 11);
- m_s3c240x_lcd.pagewidth_cur = 0;
- m_s3c240x_lcd.pagewidth_max = BITS( m_s3c240x_lcd_regs[7], 10, 0);
- verboselog( machine(), 3, "LCD - vramaddr %08X %08X offsize %08X pagewidth %08X\n", m_s3c240x_lcd.vramaddr_cur, m_s3c240x_lcd.vramaddr_max, m_s3c240x_lcd.offsize, m_s3c240x_lcd.pagewidth_max);
-}
-
-void gp32_state::s3c240x_lcd_dma_init()
-{
- s3c240x_lcd_dma_reload();
- m_s3c240x_lcd.bppmode = BITS( m_s3c240x_lcd_regs[0], 4, 1);
- m_s3c240x_lcd.bswp = BIT( m_s3c240x_lcd_regs[4], 1);
- m_s3c240x_lcd.hwswp = BIT( m_s3c240x_lcd_regs[4], 0);
- m_s3c240x_lcd.lineval = BITS( m_s3c240x_lcd_regs[1], 23, 14);
- m_s3c240x_lcd.hozval = BITS( m_s3c240x_lcd_regs[2], 18, 8);
-}
-
-UINT32 gp32_state::s3c240x_lcd_dma_read( )
-{
- UINT8 *vram, data[4];
- int i;
- for (i = 0; i < 2; i++)
- {
- vram = (UINT8 *)m_s3c240x_ram.target() + m_s3c240x_lcd.vramaddr_cur - 0x0C000000;
- data[i*2+0] = vram[0];
- data[i*2+1] = vram[1];
- m_s3c240x_lcd.vramaddr_cur += 2;
- m_s3c240x_lcd.pagewidth_cur++;
- if (m_s3c240x_lcd.pagewidth_cur >= m_s3c240x_lcd.pagewidth_max)
- {
- m_s3c240x_lcd.vramaddr_cur += m_s3c240x_lcd.offsize << 1;
- m_s3c240x_lcd.pagewidth_cur = 0;
- }
- }
- if (m_s3c240x_lcd.hwswp == 0)
- {
- if (m_s3c240x_lcd.bswp == 0)
- {
- return (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | (data[0] << 0);
- }
- else
- {
- return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3] << 0);
- }
- }
- else
- {
- if (m_s3c240x_lcd.bswp == 0)
- {
- return (data[1] << 24) | (data[0] << 16) | (data[3] << 8) | (data[2] << 0);
- }
- else
- {
- return (data[2] << 24) | (data[3] << 16) | (data[0] << 8) | (data[1] << 0);
- }
- }
-}
-
-void gp32_state::s3c240x_lcd_render_01( )
-{
- bitmap_rgb32 &bitmap = m_bitmap;
- UINT32 *scanline = &bitmap.pix32(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos);
- int i, j;
- for (i = 0; i < 4; i++)
- {
- UINT32 data = s3c240x_lcd_dma_read();
- for (j = 0; j < 32; j++)
- {
- *scanline++ = m_palette->pen_color((data >> 31) & 0x01);
- data = data << 1;
- m_s3c240x_lcd.hpos++;
- if (m_s3c240x_lcd.hpos >= (m_s3c240x_lcd.pagewidth_max << 4))
- {
- m_s3c240x_lcd.vpos = (m_s3c240x_lcd.vpos + 1) % (m_s3c240x_lcd.lineval + 1);
- m_s3c240x_lcd.hpos = 0;
- scanline = &bitmap.pix32(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos);
- }
- }
- }
-}
-
-void gp32_state::s3c240x_lcd_render_02( )
-{
- bitmap_rgb32 &bitmap = m_bitmap;
- UINT32 *scanline = &bitmap.pix32(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos);
- int i, j;
- for (i = 0; i < 4; i++)
- {
- UINT32 data = s3c240x_lcd_dma_read();
- for (j = 0; j < 16; j++)
- {
- *scanline++ = m_palette->pen_color((data >> 30) & 0x03);
- data = data << 2;
- m_s3c240x_lcd.hpos++;
- if (m_s3c240x_lcd.hpos >= (m_s3c240x_lcd.pagewidth_max << 3))
- {
- m_s3c240x_lcd.vpos = (m_s3c240x_lcd.vpos + 1) % (m_s3c240x_lcd.lineval + 1);
- m_s3c240x_lcd.hpos = 0;
- scanline = &bitmap.pix32(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos);
- }
- }
- }
-}
-
-void gp32_state::s3c240x_lcd_render_04( )
-{
- bitmap_rgb32 &bitmap = m_bitmap;
- UINT32 *scanline = &bitmap.pix32(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos);
- int i, j;
- for (i = 0; i < 4; i++)
- {
- UINT32 data = s3c240x_lcd_dma_read( );
- for (j = 0; j < 8; j++)
- {
- *scanline++ = m_palette->pen_color((data >> 28) & 0x0F);
- data = data << 4;
- m_s3c240x_lcd.hpos++;
- if (m_s3c240x_lcd.hpos >= (m_s3c240x_lcd.pagewidth_max << 2))
- {
- m_s3c240x_lcd.vpos = (m_s3c240x_lcd.vpos + 1) % (m_s3c240x_lcd.lineval + 1);
- m_s3c240x_lcd.hpos = 0;
- scanline = &bitmap.pix32(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos);
- }
- }
- }
-}
-
-void gp32_state::s3c240x_lcd_render_08( )
-{
- bitmap_rgb32 &bitmap = m_bitmap;
- UINT32 *scanline = &bitmap.pix32(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos);
- int i, j;
- for (i = 0; i < 4; i++)
- {
- UINT32 data = s3c240x_lcd_dma_read();
- for (j = 0; j < 4; j++)
- {
- *scanline++ = m_palette->pen_color((data >> 24) & 0xFF);
- data = data << 8;
- m_s3c240x_lcd.hpos++;
- if (m_s3c240x_lcd.hpos >= (m_s3c240x_lcd.pagewidth_max << 1))
- {
- m_s3c240x_lcd.vpos = (m_s3c240x_lcd.vpos + 1) % (m_s3c240x_lcd.lineval + 1);
- m_s3c240x_lcd.hpos = 0;
- scanline = &bitmap.pix32(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos);
- }
- }
- }
-}
-
-void gp32_state::s3c240x_lcd_render_16( )
-{
- bitmap_rgb32 &bitmap = m_bitmap;
- UINT32 *scanline = &bitmap.pix32(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos);
- int i, j;
- for (i = 0; i < 4; i++)
- {
- UINT32 data = s3c240x_lcd_dma_read();
- for (j = 0; j < 2; j++)
- {
- *scanline++ = s3c240x_get_color_5551( (data >> 16) & 0xFFFF);
- data = data << 16;
- m_s3c240x_lcd.hpos++;
- if (m_s3c240x_lcd.hpos >= (m_s3c240x_lcd.pagewidth_max << 0))
- {
- m_s3c240x_lcd.vpos = (m_s3c240x_lcd.vpos + 1) % (m_s3c240x_lcd.lineval + 1);
- m_s3c240x_lcd.hpos = 0;
- scanline = &bitmap.pix32(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos);
- }
- }
- }
-}
-
-TIMER_CALLBACK_MEMBER(gp32_state::s3c240x_lcd_timer_exp)
-{
- screen_device *screen = machine().first_screen();
- verboselog( machine(), 2, "LCD timer callback\n");
- m_s3c240x_lcd.vpos = screen->vpos();
- m_s3c240x_lcd.hpos = screen->hpos();
- verboselog( machine(), 3, "LCD - vpos %d hpos %d\n", m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos);
- if (m_s3c240x_lcd.vramaddr_cur >= m_s3c240x_lcd.vramaddr_max)
- {
- s3c240x_lcd_dma_reload();
- }
- verboselog( machine(), 3, "LCD - vramaddr %08X\n", m_s3c240x_lcd.vramaddr_cur);
- while (m_s3c240x_lcd.vramaddr_cur < m_s3c240x_lcd.vramaddr_max)
- {
- switch (m_s3c240x_lcd.bppmode)
- {
- case BPPMODE_TFT_01 : s3c240x_lcd_render_01(); break;
- case BPPMODE_TFT_02 : s3c240x_lcd_render_02(); break;
- case BPPMODE_TFT_04 : s3c240x_lcd_render_04(); break;
- case BPPMODE_TFT_08 : s3c240x_lcd_render_08(); break;
- case BPPMODE_TFT_16 : s3c240x_lcd_render_16(); break;
- default : verboselog( machine(), 0, "s3c240x_lcd_timer_exp: bppmode %d not supported\n", m_s3c240x_lcd.bppmode); break;
- }
- if ((m_s3c240x_lcd.vpos == 0) && (m_s3c240x_lcd.hpos == 0)) break;
- }
- m_s3c240x_lcd_timer->adjust( screen->time_until_pos(m_s3c240x_lcd.vpos, m_s3c240x_lcd.hpos));
-}
-
-void gp32_state::video_start()
-{
- machine().first_screen()->register_screen_bitmap(m_bitmap);
-}
-
-UINT32 gp32_state::screen_update_gp32(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
-{
- copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
- s3c240x_lcd_dma_init();
- return 0;
-}
-
-READ32_MEMBER(gp32_state::s3c240x_lcd_r)
-{
- UINT32 data = m_s3c240x_lcd_regs[offset];
- switch (offset)
- {
- // LCDCON1
- case 0x00 / 4 :
- {
- // make sure line counter is going
- UINT32 lineval = BITS( m_s3c240x_lcd_regs[1], 23, 14);
- data = (data & ~0xFFFC0000) | ((lineval - machine().first_screen()->vpos()) << 18);
- }
- break;
- }
- verboselog( machine(), 9, "(LCD) %08X -> %08X (PC %08X)\n", 0x14A00000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-void gp32_state::s3c240x_lcd_configure()
-{
- screen_device *screen = machine().first_screen();
- UINT32 vspw, vbpd, lineval, vfpd, hspw, hbpd, hfpd, hozval, clkval, hclk;
- double framerate, vclk;
- rectangle visarea;
- vspw = BITS( m_s3c240x_lcd_regs[1], 5, 0);
- vbpd = BITS( m_s3c240x_lcd_regs[1], 31, 24);
- lineval = BITS( m_s3c240x_lcd_regs[1], 23, 14);
- vfpd = BITS( m_s3c240x_lcd_regs[1], 13, 6);
- hspw = BITS( m_s3c240x_lcd_regs[3], 7, 0);
- hbpd = BITS( m_s3c240x_lcd_regs[2], 25, 19);
- hfpd = BITS( m_s3c240x_lcd_regs[2], 7, 0);
- hozval = BITS( m_s3c240x_lcd_regs[2], 18, 8);
- clkval = BITS( m_s3c240x_lcd_regs[0], 17, 8);
- hclk = s3c240x_get_hclk(MPLLCON);
- verboselog( machine(), 3, "LCD - vspw %d vbpd %d lineval %d vfpd %d hspw %d hbpd %d hfpd %d hozval %d clkval %d hclk %d\n", vspw, vbpd, lineval, vfpd, hspw, hbpd, hfpd, hozval, clkval, hclk);
- vclk = (double)(hclk / ((clkval + 1) * 2));
- verboselog( machine(), 3, "LCD - vclk %f\n", vclk);
- framerate = vclk / (((vspw + 1) + (vbpd + 1) + (lineval + 1) + (vfpd + 1)) * ((hspw + 1) + (hbpd + 1) + (hfpd + 1) + (hozval + 1)));
- verboselog( machine(), 3, "LCD - framerate %f\n", framerate);
- visarea.set(0, hozval, 0, lineval);
- verboselog( machine(), 3, "LCD - visarea min_x %d min_y %d max_x %d max_y %d\n", visarea.min_x, visarea.min_y, visarea.max_x, visarea.max_y);
- screen->configure(hozval + 1, lineval + 1, visarea, HZ_TO_ATTOSECONDS( framerate));
-}
-
-void gp32_state::s3c240x_lcd_start()
-{
- screen_device *screen = machine().first_screen();
- verboselog( machine(), 1, "LCD start\n");
- s3c240x_lcd_configure();
- s3c240x_lcd_dma_init();
- m_s3c240x_lcd_timer->adjust( screen->time_until_pos(0, 0));
-}
-
-void gp32_state::s3c240x_lcd_stop()
-{
- verboselog( machine(), 1, "LCD stop\n");
- m_s3c240x_lcd_timer->adjust( attotime::never);
-}
-
-void gp32_state::s3c240x_lcd_recalc()
-{
- if (m_s3c240x_lcd_regs[0] & 1)
- {
- s3c240x_lcd_start();
- }
- else
- {
- s3c240x_lcd_stop();
- }
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_lcd_w)
-{
- UINT32 old_value = m_s3c240x_lcd_regs[offset];
- verboselog( machine(), 9, "(LCD) %08X <- %08X (PC %08X)\n", 0x14A00000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_lcd_regs[offset]);
- switch (offset)
- {
- // LCDCON1
- case 0x00 / 4 :
- {
- if ((old_value & 1) != (data & 1))
- {
- s3c240x_lcd_recalc();
- }
- }
- break;
- }
-}
-
-// LCD PALETTE
-
-
-READ32_MEMBER(gp32_state::s3c240x_lcd_palette_r)
-{
- UINT32 data = m_s3c240x_lcd_palette[offset];
- verboselog( machine(), 9, "(LCD) %08X -> %08X (PC %08X)\n", 0x14A00400 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_lcd_palette_w)
-{
- verboselog( machine(), 9, "(LCD) %08X <- %08X (PC %08X)\n", 0x14A00400 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_lcd_palette[offset]);
- if (mem_mask != 0xffffffff)
- {
- verboselog( machine(), 0, "s3c240x_lcd_palette_w: unknown mask %08x\n", mem_mask);
- }
- m_palette->set_pen_color( offset, s3c240x_get_color_5551( data & 0xFFFF));
-}
-
-// CLOCK & POWER MANAGEMENT
-
-
-UINT32 gp32_state::s3c240x_get_fclk(int reg)
-{
- UINT32 data, mdiv, pdiv, sdiv;
- data = m_s3c240x_clkpow_regs[reg]; // MPLLCON or UPLLCON
- mdiv = BITS( data, 19, 12);
- pdiv = BITS( data, 9, 4);
- sdiv = BITS( data, 1, 0);
- return (UINT32)((double)((mdiv + 8) * 12000000) / (double)((pdiv + 2) * (1 << sdiv)));
-}
-
-UINT32 gp32_state::s3c240x_get_hclk(int reg)
-{
- switch (m_s3c240x_clkpow_regs[5] & 0x3) // CLKDIVN
- {
- case 0 : return s3c240x_get_fclk(reg) / 1;
- case 1 : return s3c240x_get_fclk(reg) / 1;
- case 2 : return s3c240x_get_fclk(reg) / 2;
- case 3 : return s3c240x_get_fclk(reg) / 2;
- }
- return 0;
-}
-
-UINT32 gp32_state::s3c240x_get_pclk(int reg)
-{
- switch (m_s3c240x_clkpow_regs[5] & 0x3) // CLKDIVN
- {
- case 0 : return s3c240x_get_fclk(reg) / 1;
- case 1 : return s3c240x_get_fclk(reg) / 2;
- case 2 : return s3c240x_get_fclk(reg) / 2;
- case 3 : return s3c240x_get_fclk(reg) / 4;
- }
- return 0;
-}
-
-READ32_MEMBER(gp32_state::s3c240x_clkpow_r)
-{
- UINT32 data = m_s3c240x_clkpow_regs[offset];
- verboselog( machine(), 9, "(CLKPOW) %08X -> %08X (PC %08X)\n", 0x14800000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_clkpow_w)
-{
- verboselog( machine(), 9, "(CLKPOW) %08X <- %08X (PC %08X)\n", 0x14800000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_clkpow_regs[offset]);
- switch (offset)
- {
- // MPLLCON
- case 0x04 / 4 :
- {
- m_maincpu->set_unscaled_clock(s3c240x_get_fclk(MPLLCON) * CLOCK_MULTIPLIER);
- }
- break;
- }
-}
-
-// INTERRUPT CONTROLLER
-
-
-void gp32_state::s3c240x_check_pending_irq()
-{
- if (m_s3c240x_irq_regs[0] != 0)
- {
- UINT32 int_type = 0, temp;
- temp = m_s3c240x_irq_regs[0];
- while (!(temp & 1))
- {
- int_type++;
- temp = temp >> 1;
- }
- m_s3c240x_irq_regs[4] |= (1 << int_type); // INTPND
- m_s3c240x_irq_regs[5] = int_type; // INTOFFSET
- m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE);
- }
- else
- {
- m_maincpu->set_input_line(ARM7_IRQ_LINE, CLEAR_LINE);
- }
-}
-
-void gp32_state::s3c240x_request_irq(UINT32 int_type)
-{
- verboselog( machine(), 5, "request irq %d\n", int_type);
- if (m_s3c240x_irq_regs[0] == 0)
- {
- m_s3c240x_irq_regs[0] |= (1 << int_type); // SRCPND
- m_s3c240x_irq_regs[4] |= (1 << int_type); // INTPND
- m_s3c240x_irq_regs[5] = int_type; // INTOFFSET
- m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE);
- }
- else
- {
- m_s3c240x_irq_regs[0] |= (1 << int_type); // SRCPND
- s3c240x_check_pending_irq();
- }
-}
-
-
-READ32_MEMBER(gp32_state::s3c240x_irq_r)
-{
- UINT32 data = m_s3c240x_irq_regs[offset];
- verboselog( machine(), 9, "(IRQ) %08X -> %08X (PC %08X)\n", 0x14400000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_irq_w)
-{
- UINT32 old_value = m_s3c240x_irq_regs[offset];
- verboselog( machine(), 9, "(IRQ) %08X <- %08X (PC %08X)\n", 0x14400000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_irq_regs[offset]);
- switch (offset)
- {
- // SRCPND
- case 0x00 / 4 :
- {
- m_s3c240x_irq_regs[0] = (old_value & ~data); // clear only the bit positions of SRCPND corresponding to those set to one in the data
- s3c240x_check_pending_irq();
- }
- break;
- // INTPND
- case 0x10 / 4 :
- {
- m_s3c240x_irq_regs[4] = (old_value & ~data); // clear only the bit positions of INTPND corresponding to those set to one in the data
- }
- break;
- }
-}
-
-// PWM TIMER
-
-#if 0
-static const char *const timer_reg_names[] =
-{
- "Timer config 0",
- "Timer config 1",
- "Timer control",
- "Timer count buffer 0",
- "Timer compare buffer 0",
- "Timer count observation 0",
- "Timer count buffer 1",
- "Timer compare buffer 1",
- "Timer count observation 1",
- "Timer count buffer 2",
- "Timer compare buffer 2",
- "Timer count observation 2",
- "Timer count buffer 3",
- "Timer compare buffer 3",
- "Timer count observation 3",
- "Timer count buffer 4",
- "Timer compare buffer 4",
- "Timer count observation 4",
-};
-#endif
-
-
-READ32_MEMBER(gp32_state::s3c240x_pwm_r)
-{
- UINT32 data = m_s3c240x_pwm_regs[offset];
- verboselog( machine(), 9, "(PWM) %08X -> %08X (PC %08X)\n", 0x15100000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-void gp32_state::s3c240x_pwm_start(int timer)
-{
- static const int mux_table[] = { 2, 4, 8, 16 };
- static const int prescaler_shift[] = { 0, 0, 8, 8, 8 };
- static const int mux_shift[] = { 0, 4, 8, 12, 16 };
- static const int tcon_shift[] = { 0, 8, 12, 16, 20 };
- const UINT32 *regs = &m_s3c240x_pwm_regs[3+timer*3];
- UINT32 prescaler, mux, cnt, cmp, auto_reload;
- double freq, hz;
- verboselog( machine(), 1, "PWM %d start\n", timer);
- prescaler = (m_s3c240x_pwm_regs[0] >> prescaler_shift[timer]) & 0xFF;
- mux = (m_s3c240x_pwm_regs[1] >> mux_shift[timer]) & 0x0F;
- freq = s3c240x_get_pclk(MPLLCON) / (prescaler + 1) / mux_table[mux];
- cnt = BITS( regs[0], 15, 0);
- if (timer != 4)
- {
- cmp = BITS( regs[1], 15, 0);
- auto_reload = BIT( m_s3c240x_pwm_regs[2], tcon_shift[timer] + 3);
- }
- else
- {
- cmp = 0;
- auto_reload = BIT( m_s3c240x_pwm_regs[2], tcon_shift[timer] + 2);
- }
- hz = freq / (cnt - cmp + 1);
- verboselog( machine(), 5, "PWM %d - FCLK=%d HCLK=%d PCLK=%d prescaler=%d div=%d freq=%f cnt=%d cmp=%d auto_reload=%d hz=%f\n", timer, s3c240x_get_fclk(MPLLCON), s3c240x_get_hclk(MPLLCON), s3c240x_get_pclk(MPLLCON), prescaler, mux_table[mux], freq, cnt, cmp, auto_reload, hz);
- if (auto_reload)
- {
- m_s3c240x_pwm_timer[timer]->adjust( attotime::from_hz( hz), timer, attotime::from_hz( hz));
- }
- else
- {
- m_s3c240x_pwm_timer[timer]->adjust( attotime::from_hz( hz), timer);
- }
-}
-
-void gp32_state::s3c240x_pwm_stop(int timer)
-{
- verboselog( machine(), 1, "PWM %d stop\n", timer);
- m_s3c240x_pwm_timer[timer]->adjust( attotime::never);
-}
-
-void gp32_state::s3c240x_pwm_recalc(int timer)
-{
- static const int tcon_shift[] = { 0, 8, 12, 16, 20 };
- if (m_s3c240x_pwm_regs[2] & (1 << tcon_shift[timer]))
- {
- s3c240x_pwm_start(timer);
- }
- else
- {
- s3c240x_pwm_stop(timer);
- }
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_pwm_w)
-{
- UINT32 old_value = m_s3c240x_pwm_regs[offset];
- verboselog( machine(), 9, "(PWM) %08X <- %08X (PC %08X)\n", 0x15100000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_pwm_regs[offset]);
- switch (offset)
- {
- // TCON
- case 0x08 / 4 :
- {
- if ((data & 1) != (old_value & 1))
- {
- s3c240x_pwm_recalc(0);
- }
- if ((data & 0x100) != (old_value & 0x100))
- {
- s3c240x_pwm_recalc(1);
- }
- if ((data & 0x1000) != (old_value & 0x1000))
- {
- s3c240x_pwm_recalc(2);
- }
- if ((data & 0x10000) != (old_value & 0x10000))
- {
- s3c240x_pwm_recalc(3);
- }
- if ((data & 0x100000) != (old_value & 0x100000))
- {
- s3c240x_pwm_recalc(4);
- }
- }
- }
-}
-
-TIMER_CALLBACK_MEMBER(gp32_state::s3c240x_pwm_timer_exp)
-{
- int ch = param;
- static const int ch_int[] = { INT_TIMER0, INT_TIMER1, INT_TIMER2, INT_TIMER3, INT_TIMER4 };
- verboselog( machine(), 2, "PWM %d timer callback\n", ch);
- if (BITS( m_s3c240x_pwm_regs[1], 23, 20) == (ch + 1))
- {
- s3c240x_dma_request_pwm();
- }
- else
- {
- s3c240x_request_irq(ch_int[ch]);
- }
-}
-
-// DMA
-
-
-void gp32_state::s3c240x_dma_reload(int dma)
-{
- UINT32 *regs = &m_s3c240x_dma_regs[dma<<3];
- regs[3] = (regs[3] & ~0x000FFFFF) | BITS( regs[2], 19, 0);
- regs[4] = (regs[4] & ~0x1FFFFFFF) | BITS( regs[0], 28, 0);
- regs[5] = (regs[5] & ~0x1FFFFFFF) | BITS( regs[1], 28, 0);
-}
-
-void gp32_state::s3c240x_dma_trigger(int dma)
-{
- UINT32 *regs = &m_s3c240x_dma_regs[dma<<3];
- UINT32 curr_tc, curr_src, curr_dst;
- address_space &space = m_maincpu->space( AS_PROGRAM);
- int dsz, inc_src, inc_dst, servmode;
- static const UINT32 ch_int[] = { INT_DMA0, INT_DMA1, INT_DMA2, INT_DMA3 };
- verboselog( machine(), 5, "DMA %d trigger\n", dma);
- curr_tc = BITS( regs[3], 19, 0);
- curr_src = BITS( regs[4], 28, 0);
- curr_dst = BITS( regs[5], 28, 0);
- dsz = BITS( regs[2], 21, 20);
- servmode = BIT( regs[2], 26);
- inc_src = BIT( regs[0], 29);
- inc_dst = BIT( regs[1], 29);
- verboselog( machine(), 5, "DMA %d - curr_src %08X curr_dst %08X curr_tc %d dsz %d\n", dma, curr_src, curr_dst, curr_tc, dsz);
- while (curr_tc > 0)
- {
- curr_tc--;
- switch (dsz)
- {
- case 0 : space.write_byte( curr_dst, space.read_byte( curr_src)); break;
- case 1 : space.write_word( curr_dst, space.read_word( curr_src)); break;
- case 2 : space.write_dword( curr_dst, space.read_dword( curr_src)); break;
- }
- if (inc_src == 0) curr_src += (1 << dsz);
- if (inc_dst == 0) curr_dst += (1 << dsz);
- if (servmode == 0) break;
- }
- // update curr_src
- regs[4] = (regs[4] & ~0x1FFFFFFF) | curr_src;
- // update curr_dst
- regs[5] = (regs[5] & ~0x1FFFFFFF) | curr_dst;
- // update curr_tc
- regs[3] = (regs[3] & ~0x000FFFFF) | curr_tc;
- // ...
- if (curr_tc == 0)
- {
- int _int, reload;
- reload = BIT( regs[2], 22);
- if (!reload)
- {
- s3c240x_dma_reload(dma);
- }
- else
- {
- regs[6] &= ~(1 << 1); // clear on/off
- }
- _int = BIT( regs[2], 28);
- if (_int)
- {
- s3c240x_request_irq(ch_int[dma]);
- }
- }
-}
-
-void gp32_state::s3c240x_dma_request_iis()
-{
- UINT32 *regs = &m_s3c240x_dma_regs[2<<3];
- verboselog( machine(), 5, "s3c240x_dma_request_iis\n");
- if ((BIT( regs[6], 1) != 0) && (BIT( regs[2], 23) != 0) && (BITS( regs[2], 25, 24) == 0))
- {
- s3c240x_dma_trigger(2);
- }
-}
-
-void gp32_state::s3c240x_dma_request_pwm()
-{
- int i;
- verboselog( machine(), 5, "s3c240x_dma_request_pwm\n");
- for (i = 0; i < 4; i++)
- {
- if (i != 1)
- {
- UINT32 *regs = &m_s3c240x_dma_regs[i<<3];
- if ((BIT( regs[6], 1) != 0) && (BIT( regs[2], 23) != 0) && (BITS( regs[2], 25, 24) == 3))
- {
- s3c240x_dma_trigger(i);
- }
- }
- }
-}
-
-void gp32_state::s3c240x_dma_start(int dma)
-{
- UINT32 addr_src, addr_dst, tc;
- UINT32 *regs = &m_s3c240x_dma_regs[dma<<3];
- UINT32 dsz, tsz, reload;
- int inc_src, inc_dst, _int, servmode, swhwsel, hwsrcsel;
- verboselog( machine(), 1, "DMA %d start\n", dma);
- addr_src = BITS( regs[0], 28, 0);
- addr_dst = BITS( regs[1], 28, 0);
- tc = BITS( regs[2], 19, 0);
- inc_src = BIT( regs[0], 29);
- inc_dst = BIT( regs[1], 29);
- tsz = BIT( regs[2], 27);
- _int = BIT( regs[2], 28);
- servmode = BIT( regs[2], 26);
- hwsrcsel = BITS( regs[2], 25, 24);
- swhwsel = BIT( regs[2], 23);
- reload = BIT( regs[2], 22);
- dsz = BITS( regs[2], 21, 20);
- verboselog( machine(), 5, "DMA %d - addr_src %08X inc_src %d addr_dst %08X inc_dst %d int %d tsz %d servmode %d hwsrcsel %d swhwsel %d reload %d dsz %d tc %d\n", dma, addr_src, inc_src, addr_dst, inc_dst, _int, tsz, servmode, hwsrcsel, swhwsel, reload, dsz, tc);
- verboselog( machine(), 5, "DMA %d - copy %08X bytes from %08X (%s) to %08X (%s)\n", dma, tc << dsz, addr_src, inc_src ? "fix" : "inc", addr_dst, inc_dst ? "fix" : "inc");
- s3c240x_dma_reload(dma);
- if (swhwsel == 0)
- {
- s3c240x_dma_trigger(dma);
- }
-}
-
-void gp32_state::s3c240x_dma_stop(int dma)
-{
- verboselog( machine(), 1, "DMA %d stop\n", dma);
-}
-
-void gp32_state::s3c240x_dma_recalc(int dma)
-{
- if (m_s3c240x_dma_regs[(dma<<3)+6] & 2)
- {
- s3c240x_dma_start(dma);
- }
- else
- {
- s3c240x_dma_stop(dma);
- }
-}
-
-READ32_MEMBER(gp32_state::s3c240x_dma_r)
-{
- UINT32 data = m_s3c240x_dma_regs[offset];
- verboselog( machine(), 9, "(DMA) %08X -> %08X (PC %08X)\n", 0x14600000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_dma_w)
-{
- UINT32 old_value = m_s3c240x_dma_regs[offset];
- verboselog( machine(), 9, "(DMA) %08X <- %08X (PC %08X)\n", 0x14600000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_dma_regs[offset]);
- switch (offset)
- {
- // DCON0
- case 0x08 / 4 :
- {
- if (((data >> 22) & 1) != 0) // reload
- {
- m_s3c240x_dma_regs[0x18/4] &= ~(1 << 1); // clear on/off
- }
- }
- break;
- // DMASKTRIG0
- case 0x18 / 4 :
- {
- if ((old_value & 2) != (data & 2)) s3c240x_dma_recalc(0);
- }
- break;
- // DCON1
- case 0x28 / 4 :
- {
- if (((data >> 22) & 1) != 0) // reload
- {
- m_s3c240x_dma_regs[0x38/4] &= ~(1 << 1); // clear on/off
- }
- }
- break;
- // DMASKTRIG1
- case 0x38 / 4 :
- {
- if ((old_value & 2) != (data & 2)) s3c240x_dma_recalc(1);
- }
- break;
- // DCON2
- case 0x48 / 4 :
- {
- if (((data >> 22) & 1) != 0) // reload
- {
- m_s3c240x_dma_regs[0x58/4] &= ~(1 << 1); // clear on/off
- }
- }
- break;
- // DMASKTRIG2
- case 0x58 / 4 :
- {
- if ((old_value & 2) != (data & 2)) s3c240x_dma_recalc(2);
- }
- break;
- // DCON3
- case 0x68 / 4 :
- {
- if (((data >> 22) & 1) != 0) // reload
- {
- m_s3c240x_dma_regs[0x78/4] &= ~(1 << 1); // clear on/off
- }
- }
- break;
- // DMASKTRIG3
- case 0x78 / 4 :
- {
- if ((old_value & 2) != (data & 2)) s3c240x_dma_recalc(3);
- }
- break;
- }
-}
-
-TIMER_CALLBACK_MEMBER(gp32_state::s3c240x_dma_timer_exp)
-{
- int ch = param;
- verboselog( machine(), 2, "DMA %d timer callback\n", ch);
-}
-
-// SMARTMEDIA
-
-void gp32_state::smc_reset()
-{
- verboselog( machine(), 5, "smc_reset\n");
- m_smc.add_latch = 0;
- m_smc.chip = 0;
- m_smc.cmd_latch = 0;
- m_smc.do_read = 0;
- m_smc.do_write = 0;
- m_smc.read = 0;
- m_smc.wp = 0;
- m_smc.busy = 0;
-}
-
-void gp32_state::smc_init()
-{
- verboselog( machine(), 5, "smc_init\n");
- smc_reset();
-}
-
-UINT8 gp32_state::smc_read()
-{
- UINT8 data;
- data = m_smartmedia->data_r();
- verboselog( machine(), 5, "smc_read %08X\n", data);
- return data;
-}
-
-void gp32_state::smc_write(UINT8 data)
-{
- verboselog( machine(), 5, "smc_write %08X\n", data);
- if ((m_smc.chip) && (!m_smc.read))
- {
- if (m_smc.cmd_latch)
- {
- verboselog( machine(), 5, "smartmedia_command_w %08X\n", data);
- m_smartmedia->command_w(data);
- }
- else if (m_smc.add_latch)
- {
- verboselog( machine(), 5, "smartmedia_address_w %08X\n", data);
- m_smartmedia->address_w(data);
- }
- else
- {
- verboselog( machine(), 5, "smartmedia_data_w %08X\n", data);
- m_smartmedia->data_w(data);
- }
- }
-}
-
-void gp32_state::smc_update()
-{
- if (!m_smc.chip)
- {
- smc_reset();
- }
- else
- {
- if ((m_smc.do_write) && (!m_smc.read))
- {
- smc_write(m_smc.datatx);
- }
- else if ((!m_smc.do_write) && (m_smc.do_read) && (m_smc.read) && (!m_smc.cmd_latch) && (!m_smc.add_latch))
- {
- m_smc.datarx = smc_read();
- }
- }
-}
-
-// I2S
-
-#define I2S_L3C ( 1 )
-#define I2S_L3M ( 2 )
-#define I2S_L3D ( 3 )
-
-void gp32_state::i2s_reset()
-{
- verboselog( machine(), 5, "i2s_reset\n");
- m_i2s.l3d = 0;
- m_i2s.l3m = 0;
- m_i2s.l3c = 0;
-}
-
-void gp32_state::i2s_init()
-{
- verboselog( machine(), 5, "i2s_init\n");
- i2s_reset();
-}
-
-void gp32_state::i2s_write(int line, int data)
-{
- switch (line)
- {
- case I2S_L3C :
- {
- if (data != m_i2s.l3c)
- {
- verboselog( machine(), 5, "I2S L3C %d\n", data);
- m_i2s.l3c = data;
- }
- }
- break;
- case I2S_L3M :
- {
- if (data != m_i2s.l3m)
- {
- verboselog( machine(), 5, "I2S L3M %d\n", data);
- m_i2s.l3m = data;
- }
- }
- break;
- case I2S_L3D :
- {
- if (data != m_i2s.l3d)
- {
- verboselog( machine(), 5, "I2S L3D %d\n", data);
- m_i2s.l3d = data;
- }
- }
- break;
- }
-}
-
-// I/O PORT
-
-
-READ32_MEMBER(gp32_state::s3c240x_gpio_r)
-{
- UINT32 data = m_s3c240x_gpio[offset];
- switch (offset)
- {
- // PBCON
- case 0x08 / 4 :
- {
- // smartmedia
- data = (data & ~0x00000001);
- if (!m_smc.read) data = data | 0x00000001;
- }
- break;
- // PBDAT
- case 0x0C / 4 :
- {
- // smartmedia
- data = (data & ~0x000000FF) | (m_smc.datarx & 0xFF);
- // buttons
- data = (data & ~0x0000FF00) | (m_io_in0->read() & 0x0000FF00);
- }
- break;
- // PDDAT
- case 0x24 / 4 :
- {
- // smartmedia
- data = (data & ~0x000003C0);
- if (!m_smc.busy) data = data | 0x00000200;
- if (!m_smc.do_read) data = data | 0x00000100;
- if (!m_smc.chip) data = data | 0x00000080;
- if (!m_smartmedia->is_protected()) data = data | 0x00000040;
- }
- break;
- // PEDAT
- case 0x30 / 4 :
- {
- // smartmedia
- data = (data & ~0x0000003C);
- if (m_smc.cmd_latch) data = data | 0x00000020;
- if (m_smc.add_latch) data = data | 0x00000010;
- if (!m_smc.do_write) data = data | 0x00000008;
- if (!m_smartmedia->is_present()) data = data | 0x00000004;
- // buttons
- data = (data & ~0x000000C0) | (m_io_in1->read() & 0x000000C0);
- }
- break;
- }
- verboselog( machine(), 9, "(GPIO) %08X -> %08X (PC %08X)\n", 0x15600000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_gpio_w)
-{
- COMBINE_DATA(&m_s3c240x_gpio[offset]);
- verboselog( machine(), 9, "(GPIO) %08X <- %08X (PC %08X)\n", 0x15600000 + (offset << 2), data, space.device().safe_pc( ));
- switch (offset)
- {
- // PBCON
- case 0x08 / 4 :
- {
- // smartmedia
- m_smc.read = ((data & 0x00000001) == 0);
- smc_update();
- }
- break;
- // PBDAT
- case 0x0C / 4 :
- {
- // smartmedia
- m_smc.datatx = data & 0xFF;
- }
- break;
- // PDDAT
- case 0x24 / 4 :
- {
- // smartmedia
- m_smc.do_read = ((data & 0x00000100) == 0);
- m_smc.chip = ((data & 0x00000080) == 0);
- m_smc.wp = ((data & 0x00000040) == 0);
- smc_update();
- }
- break;
- // PEDAT
- case 0x30 / 4 :
- {
- // smartmedia
- m_smc.cmd_latch = ((data & 0x00000020) != 0);
- m_smc.add_latch = ((data & 0x00000010) != 0);
- m_smc.do_write = ((data & 0x00000008) == 0);
- smc_update();
- // sound
- i2s_write(I2S_L3D, (data & 0x00000800) ? 1 : 0);
- i2s_write(I2S_L3M, (data & 0x00000400) ? 1 : 0);
- i2s_write(I2S_L3C, (data & 0x00000200) ? 1 : 0);
- }
- break;
-#if 0
- // PGDAT
- case 0x48 / 4 :
- {
- int i2ssdo;
- i2ssdo = BIT( data, 3);
- }
- break;
-#endif
- }
-}
-
-// MEMORY CONTROLLER
-
-
-READ32_MEMBER(gp32_state::s3c240x_memcon_r)
-{
- UINT32 data = m_s3c240x_memcon_regs[offset];
- verboselog( machine(), 9, "(MEMCON) %08X -> %08X (PC %08X)\n", 0x14000000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_memcon_w)
-{
- verboselog( machine(), 9, "(MEMCON) %08X <- %08X (PC %08X)\n", 0x14000000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_memcon_regs[offset]);
-}
-
-// USB HOST CONTROLLER
-
-
-READ32_MEMBER(gp32_state::s3c240x_usb_host_r)
-{
- UINT32 data = m_s3c240x_usb_host_regs[offset];
- verboselog( machine(), 9, "(USB H) %08X -> %08X (PC %08X)\n", 0x14200000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_usb_host_w)
-{
- verboselog( machine(), 9, "(USB H) %08X <- %08X (PC %08X)\n", 0x14200000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_usb_host_regs[offset]);
-}
-
-// UART 0
-
-
-READ32_MEMBER(gp32_state::s3c240x_uart_0_r)
-{
- UINT32 data = m_s3c240x_uart_0_regs[offset];
- switch (offset)
- {
- // UTRSTAT0
- case 0x10 / 4 :
- {
- data = (data & ~0x00000006) | 0x00000004 | 0x00000002; // [bit 2] Transmitter empty / [bit 1] Transmit buffer empty
- }
- break;
- }
- verboselog( machine(), 9, "(UART 0) %08X -> %08X (PC %08X)\n", 0x15000000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_uart_0_w)
-{
- verboselog( machine(), 9, "(UART 0) %08X <- %08X (PC %08X)\n", 0x15000000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_uart_0_regs[offset]);
-}
-
-// UART 1
-
-
-READ32_MEMBER(gp32_state::s3c240x_uart_1_r)
-{
- UINT32 data = m_s3c240x_uart_1_regs[offset];
- switch (offset)
- {
- // UTRSTAT1
- case 0x10 / 4 :
- {
- data = (data & ~0x00000006) | 0x00000004 | 0x00000002; // [bit 2] Transmitter empty / [bit 1] Transmit buffer empty
- }
- break;
- }
- verboselog( machine(), 9, "(UART 1) %08X -> %08X (PC %08X)\n", 0x15004000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_uart_1_w)
-{
- verboselog( machine(), 9, "(UART 1) %08X <- %08X (PC %08X)\n", 0x15004000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_uart_1_regs[offset]);
-}
-
-// USB DEVICE
-
-
-READ32_MEMBER(gp32_state::s3c240x_usb_device_r)
-{
- UINT32 data = m_s3c240x_usb_device_regs[offset];
- verboselog( machine(), 9, "(USB D) %08X -> %08X (PC %08X)\n", 0x15200140 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_usb_device_w)
-{
- verboselog( machine(), 9, "(USB D) %08X <- %08X (PC %08X)\n", 0x15200140 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_usb_device_regs[offset]);
-}
-
-// WATCHDOG TIMER
-
-
-READ32_MEMBER(gp32_state::s3c240x_watchdog_r)
-{
- UINT32 data = m_s3c240x_watchdog_regs[offset];
- verboselog( machine(), 9, "(WDOG) %08X -> %08X (PC %08X)\n", 0x15300000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_watchdog_w)
-{
- verboselog( machine(), 9, "(WDOG) %08X <- %08X (PC %08X)\n", 0x15300000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_watchdog_regs[offset]);
-}
-
-// EEPROM
-
-UINT8 gp32_state::eeprom_read(UINT16 address)
-{
- UINT8 data;
- data = m_eeprom_data[address];
- verboselog( machine(), 5, "EEPROM %04X -> %02X\n", address, data);
- return data;
-}
-
-void gp32_state::eeprom_write(UINT16 address, UINT8 data)
-{
- verboselog( machine(), 5, "EEPROM %04X <- %02X\n", address, data);
- m_eeprom_data[address] = data;
-}
-
-// IIC
-
-#if 0
-UINT8 gp32_state::i2cmem_read_byte( int last)
-{
- UINT8 data = 0;
- int i;
- i2cmem_write( machine, 0, I2CMEM_SDA, 1);
- for (i = 0; i < 8; i++)
- {
- i2cmem_write( machine, 0, I2CMEM_SCL, 1);
- data = (data << 1) + (i2cmem_read( machine, 0, I2CMEM_SDA) ? 1 : 0);
- i2cmem_write( machine, 0, I2CMEM_SCL, 0);
- }
- i2cmem_write( machine, 0, I2CMEM_SDA, last);
- i2cmem_write( machine, 0, I2CMEM_SCL, 1);
- i2cmem_write( machine, 0, I2CMEM_SCL, 0);
- return data;
-}
-#endif
-
-#if 0
-void gp32_state::i2cmem_write_byte( UINT8 data)
-{
- int i;
- for (i = 0; i < 8; i++)
- {
- i2cmem_write( machine, 0, I2CMEM_SDA, (data & 0x80) ? 1 : 0);
- data = data << 1;
- i2cmem_write( machine, 0, I2CMEM_SCL, 1);
- i2cmem_write( machine, 0, I2CMEM_SCL, 0);
- }
- i2cmem_write( machine, 0, I2CMEM_SDA, 1); // ack bit
- i2cmem_write( machine, 0, I2CMEM_SCL, 1);
- i2cmem_write( machine, 0, I2CMEM_SCL, 0);
-}
-#endif
-
-#if 0
-void gp32_state::i2cmem_start( )
-{
- i2cmem_write( machine, 0, I2CMEM_SDA, 1);
- i2cmem_write( machine, 0, I2CMEM_SCL, 1);
- i2cmem_write( machine, 0, I2CMEM_SDA, 0);
- i2cmem_write( machine, 0, I2CMEM_SCL, 0);
-}
-#endif
-
-#if 0
-void gp32_state::i2cmem_stop( )
-{
- i2cmem_write( machine, 0, I2CMEM_SDA, 0);
- i2cmem_write( machine, 0, I2CMEM_SCL, 1);
- i2cmem_write( machine, 0, I2CMEM_SDA, 1);
- i2cmem_write( machine, 0, I2CMEM_SCL, 0);
-}
-#endif
-
-void gp32_state::iic_start()
-{
- verboselog( machine(), 1, "IIC start\n");
- m_s3c240x_iic.data_index = 0;
- m_s3c240x_iic_timer->adjust( attotime::from_msec( 1));
-}
-
-void gp32_state::iic_stop()
-{
- verboselog( machine(), 1, "IIC stop\n");
- m_s3c240x_iic_timer->adjust( attotime::never);
-}
-
-void gp32_state::iic_resume()
-{
- verboselog( machine(), 1, "IIC resume\n");
- m_s3c240x_iic_timer->adjust( attotime::from_msec( 1));
-}
-
-READ32_MEMBER(gp32_state::s3c240x_iic_r)
-{
- UINT32 data = m_s3c240x_iic_regs[offset];
- switch (offset)
- {
- // IICSTAT
- case 0x04 / 4 :
- {
- data = data & ~0x0000000F;
- }
- break;
- }
- verboselog( machine(), 9, "(IIC) %08X -> %08X (PC %08X)\n", 0x15400000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_iic_w)
-{
- verboselog( machine(), 9, "(IIC) %08X <- %08X (PC %08X)\n", 0x15400000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_iic_regs[offset]);
- switch (offset)
- {
- // ADDR_IICCON
- case 0x00 / 4 :
- {
- int interrupt_pending_flag;
-#if 0
- static const int div_table[] = { 16, 512 };
- int enable_interrupt, transmit_clock_value, tx_clock_source_selection
- double clock;
- transmit_clock_value = (data >> 0) & 0xF;
- tx_clock_source_selection = (data >> 6) & 1;
- enable_interrupt = (data >> 5) & 1;
- clock = (double)(s3c240x_get_pclk(MPLLCON) / div_table[tx_clock_source_selection] / (transmit_clock_value + 1));
-#endif
- interrupt_pending_flag = BIT( data, 4);
- if (interrupt_pending_flag == 0)
- {
- int start_stop_condition;
- start_stop_condition = BIT( m_s3c240x_iic_regs[1], 5);
- if (start_stop_condition != 0)
- {
- iic_resume();
- }
- }
- }
- break;
- // IICSTAT
- case 0x04 / 4 :
- {
- int start_stop_condition;
- start_stop_condition = BIT( data, 5);
- if (start_stop_condition != 0)
- {
- iic_start();
- }
- else
- {
- iic_stop();
- }
- }
- break;
- }
-}
-
-TIMER_CALLBACK_MEMBER(gp32_state::s3c240x_iic_timer_exp)
-{
- int enable_interrupt, mode_selection;
- verboselog( machine(), 2, "IIC timer callback\n");
- mode_selection = BITS( m_s3c240x_iic_regs[1], 7, 6);
- switch (mode_selection)
- {
- // master receive mode
- case 2 :
- {
- if (m_s3c240x_iic.data_index == 0)
- {
- UINT8 data_shift = m_s3c240x_iic_regs[3] & 0xFF;
- verboselog( machine(), 5, "IIC write %02X\n", data_shift);
- }
- else
- {
- UINT8 data_shift = eeprom_read(m_s3c240x_iic.address);
- verboselog( machine(), 5, "IIC read %02X\n", data_shift);
- m_s3c240x_iic_regs[3] = (m_s3c240x_iic_regs[3] & ~0xFF) | data_shift;
- }
- m_s3c240x_iic.data_index++;
- }
- break;
- // master transmit mode
- case 3 :
- {
- UINT8 data_shift = m_s3c240x_iic_regs[3] & 0xFF;
- verboselog( machine(), 5, "IIC write %02X\n", data_shift);
- m_s3c240x_iic.data[m_s3c240x_iic.data_index++] = data_shift;
- if (m_s3c240x_iic.data_index == 3)
- {
- m_s3c240x_iic.address = (m_s3c240x_iic.data[1] << 8) | m_s3c240x_iic.data[2];
- }
- if ((m_s3c240x_iic.data_index == 4) && (m_s3c240x_iic.data[0] == 0xA0))
- {
- eeprom_write(m_s3c240x_iic.address, data_shift);
- }
- }
- break;
- }
- enable_interrupt = BIT( m_s3c240x_iic_regs[0], 5);
- if (enable_interrupt)
- {
- s3c240x_request_irq(INT_IIC);
- }
-}
-
-// IIS
-
-void gp32_state::s3c240x_iis_start()
-{
- static const UINT32 codeclk_table[] = { 256, 384 };
- double freq;
- int prescaler_enable, prescaler_control_a, prescaler_control_b, codeclk;
- verboselog( machine(), 1, "IIS start\n");
- prescaler_enable = BIT( m_s3c240x_iis_regs[0], 1);
- prescaler_control_a = BITS( m_s3c240x_iis_regs[2], 9, 5);
- prescaler_control_b = BITS( m_s3c240x_iis_regs[2], 4, 0);
- codeclk = BIT( m_s3c240x_iis_regs[1], 2);
- freq = (double)(s3c240x_get_pclk(MPLLCON) / (prescaler_control_a + 1) / codeclk_table[codeclk]) * 2; // why do I have to multiply by two?
- verboselog( machine(), 5, "IIS - pclk %d psc_enable %d psc_a %d psc_b %d codeclk %d freq %f\n", s3c240x_get_pclk(MPLLCON), prescaler_enable, prescaler_control_a, prescaler_control_b, codeclk_table[codeclk], freq);
- m_s3c240x_iis_timer->adjust( attotime::from_hz( freq), 0, attotime::from_hz( freq));
-}
-
-void gp32_state::s3c240x_iis_stop()
-{
- verboselog( machine(), 1, "IIS stop\n");
- m_s3c240x_iis_timer->adjust( attotime::never);
-}
-
-void gp32_state::s3c240x_iis_recalc()
-{
- if (m_s3c240x_iis_regs[0] & 1)
- {
- s3c240x_iis_start();
- }
- else
- {
- s3c240x_iis_stop();
- }
-}
-
-READ32_MEMBER(gp32_state::s3c240x_iis_r)
-{
- UINT32 data = m_s3c240x_iis_regs[offset];
-#if 0
- switch (offset)
- {
- // IISCON
- case 0x00 / 4 :
- {
- data = data & ~1; // for mp3 player
- }
- break;
- }
-#endif
- verboselog( machine(), 9, "(IIS) %08X -> %08X (PC %08X)\n", 0x15508000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_iis_w)
-{
- UINT32 old_value = m_s3c240x_iis_regs[offset];
- verboselog( machine(), 9, "(IIS) %08X <- %08X (PC %08X)\n", 0x15508000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_iis_regs[offset]);
- switch (offset)
- {
- // IISCON
- case 0x00 / 4 :
- {
- if ((old_value & 1) != (data & 1)) s3c240x_iis_recalc();
- }
- break;
- // IISFIF
- case 0x10 / 4 :
- {
- if (ACCESSING_BITS_16_31)
- {
- m_s3c240x_iis.fifo[m_s3c240x_iis.fifo_index++] = BITS( data, 31, 16);
- }
- if (ACCESSING_BITS_0_15)
- {
- m_s3c240x_iis.fifo[m_s3c240x_iis.fifo_index++] = BITS( data, 15, 0);
- }
- if (m_s3c240x_iis.fifo_index == 2)
- {
- m_s3c240x_iis.fifo_index = 0;
- m_dac1->write_signed16(m_s3c240x_iis.fifo[0] + 0x8000);
- m_dac2->write_signed16(m_s3c240x_iis.fifo[1] + 0x8000);
- }
- }
- break;
- }
-}
-
-TIMER_CALLBACK_MEMBER(gp32_state::s3c240x_iis_timer_exp)
-{
- verboselog( machine(), 2, "IIS timer callback\n");
- s3c240x_dma_request_iis();
-}
-
-// RTC
-
-
-READ32_MEMBER(gp32_state::s3c240x_rtc_r)
-{
- UINT32 data = m_s3c240x_rtc_regs[offset];
- verboselog( machine(), 9, "(RTC) %08X -> %08X (PC %08X)\n", 0x15700040 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_rtc_w)
-{
- verboselog( machine(), 9, "(RTC) %08X <- %08X (PC %08X)\n", 0x15700040 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_rtc_regs[offset]);
-}
-
-// A/D CONVERTER
-
-
-READ32_MEMBER(gp32_state::s3c240x_adc_r)
-{
- UINT32 data = m_s3c240x_adc_regs[offset];
- verboselog( machine(), 9, "(ADC) %08X -> %08X (PC %08X)\n", 0x15800000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_adc_w)
-{
- verboselog( machine(), 9, "(ADC) %08X <- %08X (PC %08X)\n", 0x15800000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_adc_regs[offset]);
-}
-
-// SPI
-
-
-READ32_MEMBER(gp32_state::s3c240x_spi_r)
-{
- UINT32 data = m_s3c240x_spi_regs[offset];
- verboselog( machine(), 9, "(SPI) %08X -> %08X (PC %08X)\n", 0x15900000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_spi_w)
-{
- verboselog( machine(), 9, "(SPI) %08X <- %08X (PC %08X)\n", 0x15900000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_spi_regs[offset]);
-}
-
-// MMC INTERFACE
-
-
-READ32_MEMBER(gp32_state::s3c240x_mmc_r)
-{
- UINT32 data = m_s3c240x_mmc_regs[offset];
- verboselog( machine(), 9, "(MMC) %08X -> %08X (PC %08X)\n", 0x15A00000 + (offset << 2), data, space.device().safe_pc( ));
- return data;
-}
-
-WRITE32_MEMBER(gp32_state::s3c240x_mmc_w)
-{
- verboselog( machine(), 9, "(MMC) %08X <- %08X (PC %08X)\n", 0x15A00000 + (offset << 2), data, space.device().safe_pc( ));
- COMBINE_DATA(&m_s3c240x_mmc_regs[offset]);
-}
-
-// ...
-
-void gp32_state::s3c240x_machine_start()
-{
- m_s3c240x_pwm_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_pwm_timer_exp),this), (void *)(FPTR)0);
- m_s3c240x_pwm_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_pwm_timer_exp),this), (void *)(FPTR)1);
- m_s3c240x_pwm_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_pwm_timer_exp),this), (void *)(FPTR)2);
- m_s3c240x_pwm_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_pwm_timer_exp),this), (void *)(FPTR)3);
- m_s3c240x_pwm_timer[4] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_pwm_timer_exp),this), (void *)(FPTR)4);
- m_s3c240x_dma_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_dma_timer_exp),this), (void *)(FPTR)0);
- m_s3c240x_dma_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_dma_timer_exp),this), (void *)(FPTR)1);
- m_s3c240x_dma_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_dma_timer_exp),this), (void *)(FPTR)2);
- m_s3c240x_dma_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_dma_timer_exp),this), (void *)(FPTR)3);
- m_s3c240x_iic_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_iic_timer_exp),this), (void *)(FPTR)0);
- m_s3c240x_iis_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_iis_timer_exp),this), (void *)(FPTR)0);
- m_s3c240x_lcd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gp32_state::s3c240x_lcd_timer_exp),this), (void *)(FPTR)0);
- m_eeprom_data = auto_alloc_array( machine(), UINT8, 0x2000);
- m_nvram->set_base(m_eeprom_data, 0x2000);
- smc_init();
- i2s_init();
-}
-
-void gp32_state::s3c240x_machine_reset()
-{
- smc_reset();
- i2s_reset();
- m_s3c240x_iis.fifo_index = 0;
- m_s3c240x_iic.data_index = 0;
-}
-
-static ADDRESS_MAP_START( gp32_map, AS_PROGRAM, 32, gp32_state )
- AM_RANGE(0x00000000, 0x0007ffff) AM_ROM
- AM_RANGE(0x0c000000, 0x0c7fffff) AM_RAM AM_SHARE("s3c240x_ram")
- AM_RANGE(0x14000000, 0x1400003b) AM_READWRITE(s3c240x_memcon_r, s3c240x_memcon_w)
- AM_RANGE(0x14200000, 0x1420005b) AM_READWRITE(s3c240x_usb_host_r, s3c240x_usb_host_w)
- AM_RANGE(0x14400000, 0x14400017) AM_READWRITE(s3c240x_irq_r, s3c240x_irq_w)
- AM_RANGE(0x14600000, 0x1460007b) AM_READWRITE(s3c240x_dma_r, s3c240x_dma_w)
- AM_RANGE(0x14800000, 0x14800017) AM_READWRITE(s3c240x_clkpow_r, s3c240x_clkpow_w)
- AM_RANGE(0x14a00000, 0x14a003ff) AM_READWRITE(s3c240x_lcd_r, s3c240x_lcd_w)
- AM_RANGE(0x14a00400, 0x14a007ff) AM_READWRITE(s3c240x_lcd_palette_r, s3c240x_lcd_palette_w)
- AM_RANGE(0x15000000, 0x1500002b) AM_READWRITE(s3c240x_uart_0_r, s3c240x_uart_0_w)
- AM_RANGE(0x15004000, 0x1500402b) AM_READWRITE(s3c240x_uart_1_r, s3c240x_uart_1_w)
- AM_RANGE(0x15100000, 0x15100043) AM_READWRITE(s3c240x_pwm_r, s3c240x_pwm_w)
- AM_RANGE(0x15200140, 0x152001fb) AM_READWRITE(s3c240x_usb_device_r, s3c240x_usb_device_w)
- AM_RANGE(0x15300000, 0x1530000b) AM_READWRITE(s3c240x_watchdog_r, s3c240x_watchdog_w)
- AM_RANGE(0x15400000, 0x1540000f) AM_READWRITE(s3c240x_iic_r, s3c240x_iic_w)
- AM_RANGE(0x15508000, 0x15508013) AM_READWRITE(s3c240x_iis_r, s3c240x_iis_w)
- AM_RANGE(0x15600000, 0x1560005b) AM_READWRITE(s3c240x_gpio_r, s3c240x_gpio_w)
- AM_RANGE(0x15700040, 0x1570008b) AM_READWRITE(s3c240x_rtc_r, s3c240x_rtc_w)
- AM_RANGE(0x15800000, 0x15800007) AM_READWRITE(s3c240x_adc_r, s3c240x_adc_w)
- AM_RANGE(0x15900000, 0x15900017) AM_READWRITE(s3c240x_spi_r, s3c240x_spi_w)
- AM_RANGE(0x15a00000, 0x15a0003f) AM_READWRITE(s3c240x_mmc_r, s3c240x_mmc_w)
-ADDRESS_MAP_END
-
-static INPUT_PORTS_START( gp32 )
- PORT_START("IN0")
- PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("R") PORT_PLAYER(1)
- PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("L") PORT_PLAYER(1)
- PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
- PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
- PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
- PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
- PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("B") PORT_PLAYER(1)
- PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("A") PORT_PLAYER(1)
- PORT_START("IN1")
- PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_SELECT ) PORT_NAME("SELECT") PORT_PLAYER(1)
- PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_START ) PORT_NAME("START") PORT_PLAYER(1)
-INPUT_PORTS_END
-
-void gp32_state::machine_start()
-{
- s3c240x_machine_start();
-}
-
-void gp32_state::machine_reset()
-{
- s3c240x_machine_reset();
-}
-
-static MACHINE_CONFIG_START( gp32, gp32_state )
- MCFG_CPU_ADD("maincpu", ARM9, 40000000)
- MCFG_CPU_PROGRAM_MAP(gp32_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(240, 320)
- MCFG_SCREEN_VISIBLE_AREA(0, 239, 0, 319)
- MCFG_SCREEN_UPDATE_DRIVER(gp32_state, screen_update_gp32)
-
- /* 320x240 is 4:3 but ROT270 causes an aspect ratio of 3:4 by default */
- MCFG_DEFAULT_LAYOUT(layout_lcd_rot)
-
- MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
- MCFG_SOUND_ADD("dac1", DAC, 0)
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
- MCFG_SOUND_ADD("dac2", DAC, 0)
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
-
- MCFG_NVRAM_ADD_1FILL("nvram")
-
- MCFG_DEVICE_ADD("smartmedia", SMARTMEDIA, 0)
-
- MCFG_SOFTWARE_LIST_ADD("memc_list","gp32")
-MACHINE_CONFIG_END
-
-ROM_START( gp32 )
- ROM_REGION( 0x80000, "maincpu", 0 )
- ROM_SYSTEM_BIOS( 0, "157e", "Firmware 1.5.7 (English)" )
- ROMX_LOAD( "gp32157e.bin", 0x000000, 0x080000, CRC(b1e35643) SHA1(1566bc2a27980602e9eb501cf8b2d62939bfd1e5), ROM_BIOS(1) )
- ROM_SYSTEM_BIOS( 1, "100k", "Firmware 1.0.0 (Korean)" )
- ROMX_LOAD( "gp32100k.bin", 0x000000, 0x080000, CRC(d9925ac9) SHA1(3604d0d7210ed72eddd3e3e0c108f1102508423c), ROM_BIOS(2) )
- ROM_SYSTEM_BIOS( 2, "156k", "Firmware 1.5.6 (Korean)" )
- ROMX_LOAD( "gp32156k.bin", 0x000000, 0x080000, CRC(667fb1c8) SHA1(d179ab8e96411272b6a1d683e59da752067f9da8), ROM_BIOS(3) )
- ROM_SYSTEM_BIOS( 3, "166m", "Firmware 1.6.6 (European)" )
- ROMX_LOAD( "gp32166m.bin", 0x000000, 0x080000, CRC(4548a840) SHA1(1ad0cab0af28fb45c182e5e8c87ead2aaa4fffe1), ROM_BIOS(4) )
- ROM_SYSTEM_BIOS( 4, "mfv2", "Mr. Spiv Multi Firmware V2" )
- ROMX_LOAD( "gp32mfv2.bin", 0x000000, 0x080000, CRC(7ddaaaeb) SHA1(5a85278f721beb3b00125db5c912d1dc552c5897), ROM_BIOS(5) )
-#if 0
- ROM_SYSTEM_BIOS( 5, "test", "test" )
- ROMX_LOAD( "test.bin", 0x000000, 0x080000, CRC(00000000) SHA1(0000000000000000000000000000000000000000), ROM_BIOS(6) )
-#endif
-ROM_END
-
-CONS(2001, gp32, 0, 0, gp32, gp32, driver_device, 0, "Game Park Holdings", "GP32", ROT270|MACHINE_NOT_WORKING|MACHINE_NO_SOUND)