diff --git a/src/emu/machine/s3c2400.c b/src/emu/machine/s3c2400.c index a3693004294..8da4a688ea6 100644 --- a/src/emu/machine/s3c2400.c +++ b/src/emu/machine/s3c2400.c @@ -9,7 +9,7 @@ #include "emu.h" #include "cpu/arm7/arm7.h" #include "cpu/arm7/arm7core.h" -#include "s3c2400.h" +#include "machine/s3c2400.h" #include "sound/dac.h" #define VERBOSE_LEVEL ( 0 ) @@ -27,8 +27,6 @@ INLINE void ATTR_PRINTF(3,4) verboselog( running_machine *machine, int n_level, } } -#include "machine/s3c2400.h" - #define DEVICE_S3C2400 #include "machine/s3c24xx.c" #undef DEVICE_S3C2400 @@ -90,3 +88,5 @@ void s3c2400_uart_fifo_w( running_device *device, int uart, UINT8 data) { s3c24xx_uart_fifo_w( device, uart, data); } + +DEFINE_LEGACY_DEVICE(S3C2400, s3c2400); diff --git a/src/emu/machine/s3c2400.h b/src/emu/machine/s3c2400.h index 539e2beb471..1f2080964f8 100644 --- a/src/emu/machine/s3c2400.h +++ b/src/emu/machine/s3c2400.h @@ -1,20 +1,20 @@ /******************************************************************************* - Samsung S3C2400 private data + Samsung S3C2400 *******************************************************************************/ #ifndef __S3C2400_H__ #define __S3C2400_H__ +#include "devlegcy.h" + /******************************************************************************* MACROS / CONSTANTS *******************************************************************************/ #define S3C2400_TAG "s3c2400" -#define S3C2400 DEVICE_GET_INFO_NAME( s3c2400 ) - #define MDRV_S3C2400_ADD(_tag, _clock, _config) \ MDRV_DEVICE_ADD(_tag, S3C2400, _clock) \ MDRV_DEVICE_CONFIG(_config) @@ -33,6 +33,8 @@ enum S3C2400_GPIO_PORT_G }; +DECLARE_LEGACY_DEVICE(S3C2400, s3c2400); + /******************************************************************************* TYPE DEFINITIONS *******************************************************************************/ @@ -67,6 +69,12 @@ struct _s3c2400_interface_i2s write16_device_func data_w; }; +typedef struct _s3c2400_interface_lcd s3c2400_interface_lcd; +struct _s3c2400_interface_lcd +{ + int flags; +}; + typedef struct _s3c2400_interface s3c2400_interface; struct _s3c2400_interface { @@ -74,6 +82,7 @@ struct _s3c2400_interface s3c2400_interface_i2c i2c; s3c2400_interface_adc adc; s3c2400_interface_i2s i2s; + s3c2400_interface_lcd lcd; }; /******************************************************************************* @@ -91,6 +100,10 @@ void s3c2400_uart_fifo_w( running_device *device, int uart, UINT8 data); MACROS & CONSTANTS *******************************************************************************/ +/* Interface */ + +#define S3C24XX_INTERFACE_LCD_REVERSE 1 + /* Memory Controller */ #define S3C24XX_BASE_MEMCON 0x14000000 @@ -583,6 +596,7 @@ typedef struct typedef struct { s3c24xx_irq_regs_t regs; + int line_irq, line_fiq; } s3c24xx_irq_t; typedef struct diff --git a/src/emu/machine/s3c2410.c b/src/emu/machine/s3c2410.c index 750cd4f440d..809171fab3a 100644 --- a/src/emu/machine/s3c2410.c +++ b/src/emu/machine/s3c2410.c @@ -9,7 +9,7 @@ #include "emu.h" #include "cpu/arm7/arm7.h" #include "cpu/arm7/arm7core.h" -#include "s3c2410.h" +#include "machine/s3c2410.h" #include "sound/dac.h" #define VERBOSE_LEVEL ( 0 ) @@ -27,8 +27,6 @@ INLINE void ATTR_PRINTF(3,4) verboselog( running_machine *machine, int n_level, } } -#include "machine/s3c2410.h" - #define DEVICE_S3C2410 #include "machine/s3c24xx.c" #undef DEVICE_S3C2410 @@ -110,4 +108,9 @@ void s3c2410_nand_calculate_mecc( UINT8 *data, UINT32 size, UINT8 *mecc) for (int i = 0; i < size; i++) nand_update_mecc( mecc, i, data[i]); } +void s3c2410_request_eint( running_device *device, UINT32 number) +{ + s3c24xx_request_eint( device, number); +} + DEFINE_LEGACY_DEVICE(S3C2410, s3c2410); diff --git a/src/emu/machine/s3c2410.h b/src/emu/machine/s3c2410.h index 1bfa228097a..622d4de5e91 100644 --- a/src/emu/machine/s3c2410.h +++ b/src/emu/machine/s3c2410.h @@ -1,6 +1,6 @@ /******************************************************************************* - Samsung S3C2410 private data + Samsung S3C2410 *******************************************************************************/ @@ -81,6 +81,12 @@ struct _s3c2410_interface_nand write8_device_func data_w; }; +typedef struct _s3c2410_interface_lcd s3c2410_interface_lcd; +struct _s3c2410_interface_lcd +{ + int flags; +}; + typedef struct _s3c2410_interface s3c2410_interface; struct _s3c2410_interface { @@ -89,6 +95,7 @@ struct _s3c2410_interface s3c2410_interface_adc adc; s3c2410_interface_i2s i2s; s3c2410_interface_nand nand; + s3c2410_interface_lcd lcd; }; /******************************************************************************* @@ -102,6 +109,7 @@ VIDEO_UPDATE( s3c2410 ); void s3c2410_uart_fifo_w( running_device *device, int uart, UINT8 data); void s3c2410_touch_screen( running_device *device, int state); +void s3c2410_request_eint( running_device *device, UINT32 number); WRITE_LINE_DEVICE_HANDLER( s3c2410_pin_frnb_w ); @@ -111,6 +119,10 @@ void s3c2410_nand_calculate_mecc( UINT8 *data, UINT32 size, UINT8 *mecc); MACROS & CONSTANTS *******************************************************************************/ +/* Interface */ + +#define S3C24XX_INTERFACE_LCD_REVERSE 1 + /* Memory Controller */ #define S3C24XX_BASE_MEMCON 0x48000000 @@ -711,6 +723,7 @@ typedef struct typedef struct { s3c24xx_irq_regs_t regs; + int line_irq, line_fiq; } s3c24xx_irq_t; typedef struct @@ -778,6 +791,7 @@ typedef struct { s3c24xx_wdt_regs_t regs; emu_timer *timer; + UINT32 freq, cnt; } s3c24xx_wdt_t; typedef struct diff --git a/src/emu/machine/s3c2440.c b/src/emu/machine/s3c2440.c index 2643046fa74..5c3801a4334 100644 --- a/src/emu/machine/s3c2440.c +++ b/src/emu/machine/s3c2440.c @@ -9,7 +9,7 @@ #include "emu.h" #include "cpu/arm7/arm7.h" #include "cpu/arm7/arm7core.h" -#include "s3c2440.h" +#include "machine/s3c2440.h" #include "sound/dac.h" #define VERBOSE_LEVEL ( 0 ) @@ -27,8 +27,6 @@ INLINE void ATTR_PRINTF(3,4) verboselog( running_machine *machine, int n_level, } } -#include "machine/s3c2440.h" - #define DEVICE_S3C2440 #include "machine/s3c24xx.c" #undef DEVICE_S3C2440 @@ -115,3 +113,5 @@ WRITE_LINE_DEVICE_HANDLER( s3c2440_pin_frnb_w ) { s3c24xx_pin_frnb_w( device, state); } + +DEFINE_LEGACY_DEVICE(S3C2440, s3c2440); diff --git a/src/emu/machine/s3c2440.h b/src/emu/machine/s3c2440.h index 85a44bb4dfe..236883023b5 100644 --- a/src/emu/machine/s3c2440.h +++ b/src/emu/machine/s3c2440.h @@ -1,6 +1,6 @@ /******************************************************************************* - Samsung S3C2440 private data + Samsung S3C2440 *******************************************************************************/ @@ -13,8 +13,6 @@ #define S3C2440_TAG "s3c2440" -#define S3C2440 DEVICE_GET_INFO_NAME( s3c2440 ) - #define MDRV_S3C2440_ADD(_tag, _clock, _config) \ MDRV_DEVICE_ADD(_tag, S3C2440, _clock) \ MDRV_DEVICE_CONFIG(_config) @@ -35,6 +33,8 @@ enum S3C2440_GPIO_PORT_J }; +DECLARE_LEGACY_DEVICE(S3C2440, s3c2440); + /******************************************************************************* TYPE DEFINITIONS *******************************************************************************/ @@ -78,6 +78,12 @@ struct _s3c2440_interface_nand write8_device_func data_w; }; +typedef struct _s3c2440_interface_lcd s3c2440_interface_lcd; +struct _s3c2440_interface_lcd +{ + int flags; +}; + typedef struct _s3c2440_interface s3c2440_interface; struct _s3c2440_interface { @@ -86,6 +92,7 @@ struct _s3c2440_interface s3c2440_interface_adc adc; s3c2440_interface_i2s i2s; s3c2440_interface_nand nand; + s3c2440_interface_lcd lcd; }; /******************************************************************************* @@ -108,6 +115,10 @@ WRITE_LINE_DEVICE_HANDLER( s3c2440_pin_frnb_w ); MACROS & CONSTANTS *******************************************************************************/ +/* Interface */ + +#define S3C24XX_INTERFACE_LCD_REVERSE 1 + /* Memory Controller */ #define S3C24XX_BASE_MEMCON 0x48000000 @@ -770,6 +781,7 @@ typedef struct typedef struct { s3c24xx_irq_regs_t regs; + int line_irq, line_fiq; } s3c24xx_irq_t; typedef struct diff --git a/src/emu/machine/s3c24xx.c b/src/emu/machine/s3c24xx.c index 87041da92e0..88a2a9316b0 100644 --- a/src/emu/machine/s3c24xx.c +++ b/src/emu/machine/s3c24xx.c @@ -243,50 +243,50 @@ static void s3c24xx_lcd_dma_init( running_device *device) s3c24xx->lcd.dma_bits = 0; } -/* +#if 0 static UINT32 s3c24xx_lcd_dma_read( running_device *device) { - s3c24xx_t *s3c24xx = get_token( device); - address_space* space = cputag_get_address_space( device->machine, "maincpu", ADDRESS_SPACE_PROGRAM); - UINT8 *vram, data[4]; - vram = (UINT8 *)space->get_read_ptr( s3c24xx->lcd.vramaddr_cur); - for (int i = 0; i < 2; i++) - { - data[i*2+0] = *vram++; - data[i*2+1] = *vram++; - s3c24xx->lcd.vramaddr_cur += 2; - s3c24xx->lcd.pagewidth_cur++; - if (s3c24xx->lcd.pagewidth_cur >= s3c24xx->lcd.pagewidth_max) - { - s3c24xx->lcd.vramaddr_cur += s3c24xx->lcd.offsize << 1; - s3c24xx->lcd.pagewidth_cur = 0; - vram = (UINT8 *)space->get_read_ptr( s3c24xx->lcd.vramaddr_cur); - } - } - if (s3c24xx->lcd.hwswp == 0) - { - if (s3c24xx->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 (s3c24xx->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); - } - } + s3c24xx_t *s3c24xx = get_token( device); + address_space* space = cputag_get_address_space( device->machine, "maincpu", ADDRESS_SPACE_PROGRAM); + UINT8 *vram, data[4]; + vram = (UINT8 *)space->get_read_ptr( s3c24xx->lcd.vramaddr_cur); + for (int i = 0; i < 2; i++) + { + data[i*2+0] = *vram++; + data[i*2+1] = *vram++; + s3c24xx->lcd.vramaddr_cur += 2; + s3c24xx->lcd.pagewidth_cur++; + if (s3c24xx->lcd.pagewidth_cur >= s3c24xx->lcd.pagewidth_max) + { + s3c24xx->lcd.vramaddr_cur += s3c24xx->lcd.offsize << 1; + s3c24xx->lcd.pagewidth_cur = 0; + vram = (UINT8 *)space->get_read_ptr( s3c24xx->lcd.vramaddr_cur); + } + } + if (s3c24xx->lcd.hwswp == 0) + { + if (s3c24xx->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 (s3c24xx->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); + } + } } -*/ +#endif static UINT32 s3c24xx_lcd_dma_read( running_device *device) { @@ -351,7 +351,14 @@ static UINT32 s3c24xx_lcd_dma_read( running_device *device) vram += 2; } } - return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3] << 0); + if (s3c24xx->iface->lcd.flags & S3C24XX_INTERFACE_LCD_REVERSE) + { + 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); + } } static UINT32 s3c24xx_lcd_dma_read_bits( running_device *device, int count) @@ -416,8 +423,16 @@ static void s3c24xx_lcd_render_stn_01( running_device *device) UINT32 data = s3c24xx_lcd_dma_read( device); for (int j = 0; j < 32; j++) { - *scanline++ = s3c24xx_get_color_stn_01( device, (data >> 31) & 0x01); - data = data << 1; + if (s3c24xx->iface->lcd.flags & S3C24XX_INTERFACE_LCD_REVERSE) + { + *scanline++ = s3c24xx_get_color_stn_01( device, data & 0x01); + data = data >> 1; + } + else + { + *scanline++ = s3c24xx_get_color_stn_01( device, (data >> 31) & 0x01); + data = data << 1; + } s3c24xx->lcd.hpos++; if (s3c24xx->lcd.hpos >= s3c24xx->lcd.hpos_min + (s3c24xx->lcd.pagewidth_max << 4)) { @@ -521,6 +536,30 @@ static void s3c24xx_lcd_render_stn_12_p( running_device *device) } } +static void s3c24xx_lcd_render_stn_12_u( running_device *device) // not tested +{ + s3c24xx_t *s3c24xx = get_token( device); + bitmap_t *bitmap = s3c24xx->lcd.bitmap[0]; + UINT32 *scanline = BITMAP_ADDR32( bitmap, s3c24xx->lcd.vpos, s3c24xx->lcd.hpos); + for (int i = 0; i < 4; i++) + { + UINT32 data = s3c24xx_lcd_dma_read( device); + for (int j = 0; j < 2; j++) + { + *scanline++ = s3c24xx_get_color_stn_12( device, (data >> 16) & 0x0FFF); + data = data << 16; + s3c24xx->lcd.hpos++; + if (s3c24xx->lcd.hpos >= s3c24xx->lcd.hpos_min + (s3c24xx->lcd.pagewidth_max << 0)) + { + s3c24xx->lcd.vpos++; + if (s3c24xx->lcd.vpos > s3c24xx->lcd.vpos_max) s3c24xx->lcd.vpos = s3c24xx->lcd.vpos_min; + s3c24xx->lcd.hpos = s3c24xx->lcd.hpos_min; + scanline = BITMAP_ADDR32( bitmap, s3c24xx->lcd.vpos, s3c24xx->lcd.hpos); + } + } + } +} + static void s3c24xx_lcd_render_tft_01( running_device *device) { s3c24xx_t *s3c24xx = get_token( device); @@ -668,6 +707,7 @@ static TIMER_CALLBACK( s3c24xx_lcd_timer_exp ) case S3C24XX_BPPMODE_STN_04 : s3c24xx_lcd_render_stn_04( device); break; case S3C24XX_BPPMODE_STN_08 : s3c24xx_lcd_render_stn_08( device); break; case S3C24XX_BPPMODE_STN_12_P : s3c24xx_lcd_render_stn_12_p( device); break; + case S3C24XX_BPPMODE_STN_12_U : s3c24xx_lcd_render_stn_12_u( device); break; case S3C24XX_BPPMODE_TFT_01 : s3c24xx_lcd_render_tft_01( device); break; case S3C24XX_BPPMODE_TFT_02 : s3c24xx_lcd_render_tft_02( device); break; case S3C24XX_BPPMODE_TFT_04 : s3c24xx_lcd_render_tft_04( device); break; @@ -765,7 +805,6 @@ READ32_DEVICE_HANDLER( s3c2440_lcd_r ) } break; } -if (offset != S3C24XX_LCDCON5) verboselog( device->machine, 9, "(LCD) %08X -> %08X\n", S3C24XX_BASE_LCD + (offset << 2), data); return data; } @@ -1011,7 +1050,9 @@ static WRITE32_DEVICE_HANDLER( s3c24xx_clkpow_w ) static void s3c24xx_check_pending_irq( running_device *device) { s3c24xx_t *s3c24xx = get_token( device); - UINT32 temp = s3c24xx->irq.regs.srcpnd & ~s3c24xx->irq.regs.intmsk; + UINT32 temp; + // normal irq + temp = (s3c24xx->irq.regs.srcpnd & ~s3c24xx->irq.regs.intmsk) & ~s3c24xx->irq.regs.intmod; if (temp != 0) { UINT32 int_type = 0; @@ -1022,11 +1063,43 @@ static void s3c24xx_check_pending_irq( running_device *device) } s3c24xx->irq.regs.intpnd |= (1 << int_type); s3c24xx->irq.regs.intoffset = int_type; - cputag_set_input_line( device->machine, "maincpu", ARM7_IRQ_LINE, ASSERT_LINE); + if (s3c24xx->irq.line_irq != ASSERT_LINE) + { + cputag_set_input_line( device->machine, "maincpu", ARM7_IRQ_LINE, ASSERT_LINE); + s3c24xx->irq.line_irq = ASSERT_LINE; + } } else { - cputag_set_input_line( device->machine, "maincpu", ARM7_IRQ_LINE, CLEAR_LINE); + if (s3c24xx->irq.line_irq != CLEAR_LINE) + { + cputag_set_input_line( device->machine, "maincpu", ARM7_IRQ_LINE, CLEAR_LINE); + s3c24xx->irq.line_irq = CLEAR_LINE; + } + } + // fast irq + temp = (s3c24xx->irq.regs.srcpnd & ~s3c24xx->irq.regs.intmsk) & s3c24xx->irq.regs.intmod; + if (temp != 0) + { + UINT32 int_type = 0; + while ((temp & 1) == 0) + { + int_type++; + temp = temp >> 1; + } + if (s3c24xx->irq.line_fiq != ASSERT_LINE) + { + cputag_set_input_line( device->machine, "maincpu", ARM7_FIRQ_LINE, ASSERT_LINE); + s3c24xx->irq.line_fiq = ASSERT_LINE; + } + } + else + { + if (s3c24xx->irq.line_fiq != CLEAR_LINE) + { + cputag_set_input_line( device->machine, "maincpu", ARM7_FIRQ_LINE, CLEAR_LINE); + s3c24xx->irq.line_fiq = CLEAR_LINE; + } } } @@ -1530,13 +1603,13 @@ static void s3c24xx_dma_w( running_device *device, UINT32 ch, UINT32 offset, UIN { case S3C24XX_DCON : { - /* --- is this code necessary ??? - if ((data & (1 << 22)) != 0) // reload - { - s3c24xx_dma_regs_t *regs = &s3c24xx->dma[ch].regs; - regs->dmasktrig &= ~(1 << 1); // clear on/off - } - */ + #if 0 // is this code necessary ??? + if ((data & (1 << 22)) != 0) // reload + { + s3c24xx_dma_regs_t *regs = &s3c24xx->dma[ch].regs; + regs->dmasktrig &= ~(1 << 1); // clear on/off + } + #endif } break; case S3C24XX_DMASKTRIG : @@ -1924,6 +1997,32 @@ static WRITE32_DEVICE_HANDLER( s3c24xx_usb_device_w ) /* Watchdog Timer */ +#if defined(DEVICE_S3C2410) + +static UINT16 s3c24xx_wdt_calc_current_count( running_device *device) +{ + s3c24xx_t *s3c24xx = get_token( device); + double timeleft, x1, x2; + UINT32 cnt; + timeleft = attotime_to_double( timer_timeleft( s3c24xx->wdt.timer)); +// printf( "timeleft %f freq %d cnt %d\n", timeleft, s3c24xx->wdt.freq, s3c24xx->wdt.cnt); + x1 = 1 / ((double)s3c24xx->wdt.freq / s3c24xx->wdt.cnt); + x2 = x1 / timeleft; +// printf( "x1 %f\n", x1); + cnt = s3c24xx->wdt.cnt / x2; +// printf( "cnt %d\n", cnt); + return cnt; +} + +#else + +static UINT16 s3c24xx_wdt_calc_current_count( running_device *device) +{ + return 0; +} + +#endif + static READ32_DEVICE_HANDLER( s3c24xx_wdt_r ) { s3c24xx_t *s3c24xx = get_token( device); @@ -1932,7 +2031,11 @@ static READ32_DEVICE_HANDLER( s3c24xx_wdt_r ) { case S3C24XX_WTCNT : { - data = 0; + // is wdt active? + if ((s3c24xx->wdt.regs.wtcon & (1 << 5)) != 0) + { + data = s3c24xx_wdt_calc_current_count( device); + } } break; } @@ -1953,12 +2056,17 @@ static void s3c24xx_wdt_start( running_device *device) hz = freq / s3c24xx->wdt.regs.wtcnt; verboselog( device->machine, 5, "WDT pclk %d prescaler %d clock %d freq %f hz %f\n", pclk, prescaler, clock, freq, hz); timer_adjust_periodic( s3c24xx->wdt.timer, ATTOTIME_IN_HZ( hz), 0, ATTOTIME_IN_HZ( hz)); +#if defined(DEVICE_S3C2410) + s3c24xx->wdt.freq = freq; + s3c24xx->wdt.cnt = s3c24xx->wdt.regs.wtcnt; +#endif } static void s3c24xx_wdt_stop( running_device *device) { s3c24xx_t *s3c24xx = get_token( device); verboselog( device->machine, 1, "WDT stop\n"); + s3c24xx->wdt.regs.wtcnt = s3c24xx_wdt_calc_current_count( device); timer_adjust_oneshot( s3c24xx->wdt.timer, attotime_never, 0); } @@ -3050,6 +3158,10 @@ static DEVICE_RESET( s3c24xx ) s3c24xx_t *s3c24xx = get_token( device); s3c24xx->iis.fifo_index = 0; // s3c24xx->iic.data_index = 0; +#if defined(DEVICE_S3C2410) || defined(DEVICE_S3C2440) + s3c24xx->gpio.regs.gstatus2 = 0x00000001; // Boot is caused by power on reset +#endif + s3c24xx->irq.line_irq = s3c24xx->irq.line_fiq = CLEAR_LINE; } static DEVICE_START( s3c24xx )