diff --git a/src/mame/drivers/generalplus_gpl_unknown.cpp b/src/mame/drivers/generalplus_gpl_unknown.cpp index 1420868448a..5e3a38a0917 100644 --- a/src/mame/drivers/generalplus_gpl_unknown.cpp +++ b/src/mame/drivers/generalplus_gpl_unknown.cpp @@ -24,6 +24,7 @@ #include "cpu/unsp/unsp.h" #include "machine/timer.h" +#include "sound/dac.h" #include "emupal.h" #include "screen.h" @@ -42,7 +43,9 @@ public: //m_mainram(*this, "mainram"), m_palette(*this, "palette"), m_screen(*this, "screen"), - m_spirom(*this, "spi") + m_dac(*this, "dac"), + m_spirom(*this, "spi"), + m_testio(*this, "TEST") { } void generalplus_gpl_unknown(machine_config &config); @@ -51,7 +54,7 @@ private: virtual void machine_start() override; virtual void machine_reset() override; - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); required_device m_maincpu; //required_region_ptr m_mainrom; @@ -59,8 +62,11 @@ private: required_device m_palette; required_device m_screen; - required_region_ptr m_spirom; + required_device m_dac; + required_region_ptr m_spirom; + required_ioport m_testio; + uint16_t reg3001_r(offs_t offset); void reg3001_w(offs_t offset, uint16_t data); uint16_t reg3002_r(offs_t offset); @@ -70,49 +76,127 @@ private: uint16_t reg3004_r(offs_t offset); uint16_t reg3005_r(offs_t offset); void reg3005_w(offs_t offset, uint16_t data); + uint16_t reg3006_r(offs_t offset); + uint16_t reg3007_r(offs_t offset); + + uint16_t reg300f_r(offs_t offset); + + uint16_t reg3016_r(offs_t offset); void reg3034_w(offs_t offset, uint16_t data); - void reg3041_w(offs_t offset, uint16_t data); + void reg3041_audiodac_w(offs_t offset, uint16_t data); uint16_t reg3050_r(offs_t offset); void reg3050_w(offs_t offset, uint16_t data); - void reg3051_w(offs_t offset, uint16_t data); - void reg3092_w(offs_t offset, uint16_t data); + uint16_t reg3052_r(offs_t offset); + uint16_t reg3053_r(offs_t offset); + uint16_t reg3090_r(offs_t offset); + uint16_t reg3091_r(offs_t offset); + void reg3092_lcd_w(offs_t offset, uint16_t data); uint16_t reg3094_r(offs_t offset); uint16_t reg3095_r(offs_t offset); + void reg30e0_w(offs_t offset, uint16_t data); + void reg30e1_w(offs_t offset, uint16_t data); + void reg30e2_w(offs_t offset, uint16_t data); + void reg30e3_w(offs_t offset, uint16_t data); uint16_t reg30e4_r(offs_t offset); uint16_t reg30e5_r(offs_t offset); - TIMER_DEVICE_CALLBACK_MEMBER(scanline); + TIMER_DEVICE_CALLBACK_MEMBER(timer); + TIMER_DEVICE_CALLBACK_MEMBER(timer2); + TIMER_DEVICE_CALLBACK_MEMBER(timer3); + + uint16_t m_display[128*2 * 128]; + int m_displayposx; + int m_displayposy; + uint16_t m_3001; + uint16_t m_3003; + uint16_t m_3005; + uint16_t m_3050; void map(address_map &map); }; -uint32_t generalplus_gpl_unknown_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +uint32_t generalplus_gpl_unknown_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { + int count = 0; + for (int y = 0; y < 128; y++) + { + u16* dst = &bitmap.pix(y); + + for (int x = 0; x < 128; x++) + { + uint8_t pix1 = m_display[count++]; + uint8_t pix2 = m_display[count++]; + + uint16_t pal = ((pix1<<8) | pix2); + + dst[x] = pal; + } + } return 0; } static INPUT_PORTS_START( generalplus_gpl_unknown ) + PORT_START("TEST") + PORT_DIPNAME( 0x0001, 0x0000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0002, 0x0000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0002, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0004, 0x0000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0004, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) + PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0100, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0200, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0400, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0800, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) INPUT_PORTS_END uint16_t generalplus_gpl_unknown_state::reg3001_r(offs_t offset) { - return machine().rand(); + return m_3001; } void generalplus_gpl_unknown_state::reg3001_w(offs_t offset, uint16_t data) { - //logerror("%s: reg3001_w %04x\n", machine().describe_context(), data); + m_3001 = data; + logerror("%s: reg3001_w %04x\n", machine().describe_context(), data); } uint16_t generalplus_gpl_unknown_state::reg3002_r(offs_t offset) { - return machine().rand(); + return 0x0000;//machine().rand(); } void generalplus_gpl_unknown_state::reg3002_w(offs_t offset, uint16_t data) @@ -122,59 +206,168 @@ void generalplus_gpl_unknown_state::reg3002_w(offs_t offset, uint16_t data) uint16_t generalplus_gpl_unknown_state::reg3003_r(offs_t offset) { - return machine().rand(); + return m_3003; } void generalplus_gpl_unknown_state::reg3003_w(offs_t offset, uint16_t data) { - //logerror("%s: reg3003_w %04x\n", machine().describe_context(), data); + m_3003 = data; + logerror("%s: reg3003_w %04x\n", machine().describe_context(), data); } uint16_t generalplus_gpl_unknown_state::reg3004_r(offs_t offset) { - return machine().rand(); + return m_testio->read(); } uint16_t generalplus_gpl_unknown_state::reg3005_r(offs_t offset) { - return machine().rand(); + return m_3005; } void generalplus_gpl_unknown_state::reg3005_w(offs_t offset, uint16_t data) { + m_3005 = data; //logerror("%s: reg3005_w %04x\n", machine().describe_context(), data); } +uint16_t generalplus_gpl_unknown_state::reg3006_r(offs_t offset) +{ + return 0x0000;//machine().rand(); +} + +uint16_t generalplus_gpl_unknown_state::reg3007_r(offs_t offset) +{ + return 0x0000;//machine().rand(); +} + +uint16_t generalplus_gpl_unknown_state::reg300f_r(offs_t offset) +{ + return 0x0000;//machine().rand(); +} + +uint16_t generalplus_gpl_unknown_state::reg3016_r(offs_t offset) +{ + return 0x0000;//machine().rand(); +} + + + void generalplus_gpl_unknown_state::reg3034_w(offs_t offset, uint16_t data) { // writes a lot of 0x5555 here in a block - //logerror("%s: reg3034_w %04x\n", machine().describe_context(), data); + logerror("%s: reg3034_w %04x\n", machine().describe_context(), data); } -void generalplus_gpl_unknown_state::reg3041_w(offs_t offset, uint16_t data) +void generalplus_gpl_unknown_state::reg3041_audiodac_w(offs_t offset, uint16_t data) { - //logerror("%s: reg3041_w %04x\n", machine().describe_context(), data); +// logerror("%s: reg3041_audiodac_w %04x\n", machine().describe_context(), data); + + // mapacman only writes 0000 / 7fff / 8000, but is known to have more limited sound than other units + + m_dac->data_w(data); } uint16_t generalplus_gpl_unknown_state::reg3050_r(offs_t offset) { - return machine().rand(); + return m_3050; } void generalplus_gpl_unknown_state::reg3050_w(offs_t offset, uint16_t data) { - //logerror("%s: reg3050_w %04x\n", machine().describe_context(), data); + uint16_t old = m_3050; + m_3050 = data; + + // probably not, but does happen at the end of a line + if ((old & 0x0100) != (m_3050 & 0x0100)) + { + if ((m_3050 & 0x0100) == 0x0000) + { + m_displayposx = 0; + m_displayposy++; + if (m_displayposy == 128) + { + m_displayposy = 0; + } + } + } + + //m_displaypos = 0; + logerror("%s: reg3050_w %04x\n", machine().describe_context(), data); +} + +uint16_t generalplus_gpl_unknown_state::reg3052_r(offs_t offset) +{ + return 0x0000;//machine().rand(); +} + +uint16_t generalplus_gpl_unknown_state::reg3053_r(offs_t offset) +{ + return 0x0000;//machine().rand(); +} + +void generalplus_gpl_unknown_state::reg30e0_w(offs_t offset, uint16_t data) +{ + //logerror("%s: reg30e0_w %04x\n", machine().describe_context(), data); +} + +void generalplus_gpl_unknown_state::reg30e1_w(offs_t offset, uint16_t data) +{ + //logerror("%s: reg30e1_w %04x\n", machine().describe_context(), data); +} + +void generalplus_gpl_unknown_state::reg30e2_w(offs_t offset, uint16_t data) +{ + /* this appears to be querying the SPI Flash, eg. + command 0xab = Read Electonic Signature + command 0x9f = Read ID of the SPI Flash + + [:] ':maincpu' (0075DD): reg3001_w 1c00 + [:] ':maincpu' (00769B): reg3001_w 0c00 + [:] ':maincpu' (00769F): reg30e2_w 00ab (WITHOUT m_3001 & 0x1000) + [:] ':maincpu' (0076A5): reg3001_w 1c00 + [:] ':maincpu' (0076A7): reg30e4_r + [:] ':maincpu' (0076AF): reg3001_w 0c00 + [:] ':maincpu' (0076B3): reg30e2_w 009f (WITHOUT m_3001 & 0x1000) + [:] ':maincpu' (0076B6): reg30e2_w 0000 (WITHOUT m_3001 & 0x1000) + [:] ':maincpu' (0076B8): reg30e2_w 0000 (WITHOUT m_3001 & 0x1000) + [:] ':maincpu' (0076BA): reg30e2_w 0000 (WITHOUT m_3001 & 0x1000) + [:] ':maincpu' (0076C0): reg30e4_r + [:] ':maincpu' (0076C2): reg30e4_r + [:] ':maincpu' (0076C4): reg30e4_r + [:] ':maincpu' (0076C6): reg30e4_r + */ + if (!(m_3001 & 0x1000)) + { + logerror("%s: reg30e2_w %04x (WITHOUT m_3001 & 0x1000)\n", machine().describe_context(), data); + } + else + { + logerror("%s: reg30e2_w %04x (WITH m_3001 & 0x1000)\n", machine().describe_context(), data); + } +} + +void generalplus_gpl_unknown_state::reg30e3_w(offs_t offset, uint16_t data) +{ + //logerror("%s: reg30e3_w %04x\n", machine().describe_context(), data); } uint16_t generalplus_gpl_unknown_state::reg30e4_r(offs_t offset) { - return machine().rand(); + logerror("%s: reg30e4_r\n", machine().describe_context()); + return machine().rand() & 0x01; } uint16_t generalplus_gpl_unknown_state::reg30e5_r(offs_t offset) { - return machine().rand(); + // status flag: loops on bit 0x0010 after writes to 0x30e2 + // and before reading from 0x30e4 + + // clrb [3001],12 is also usually executed before write operations + // to 0x30e2 and setb [3001],12 befoe the result is read back + + return 0x0000; } /* @@ -205,22 +398,64 @@ void generalplus_gpl_unknown_state::reg3051_w(offs_t offset, uint16_t data) m_maincpu->set_input_line(UNSP_IRQ3_LINE, CLEAR_LINE); - logerror("%s: reg3051_w %04x (IRQ Ack?)\n", machine().describe_context(), data); + //logerror("%s: reg3051_w %04x (IRQ Ack?)\n", machine().describe_context(), data); } -void generalplus_gpl_unknown_state::reg3092_w(offs_t offset, uint16_t data) +uint16_t generalplus_gpl_unknown_state::reg3090_r(offs_t offset) { - //logerror("%s: reg3092_w %04x (Video?)\n", machine().describe_context(), data); + return 0x0000;//machine().rand(); +} + +uint16_t generalplus_gpl_unknown_state::reg3091_r(offs_t offset) +{ + return 0x0000;//machine().rand(); +} + +void generalplus_gpl_unknown_state::reg3092_lcd_w(offs_t offset, uint16_t data) +{ + if (m_3005 & 0x1000) + { + //if (m_3005 & 0x0800) // also always set for video writes? + { + //logerror("%s: reg3092_lcd_w %04x (Video?)\n", machine().describe_context(), data); + if ((m_displayposx < 256) && (m_displayposy < 256)) + m_display[(m_displayposy * 256) + m_displayposx] = data; + + if (data & 0xff00) + fatalerror("upper data bits set?\n"); + + m_displayposx++; + + /* + if (m_displayposx == 256) + { + m_displayposy++; + m_displayposx = 0; + } + */ + /* + if (m_displayposy == 128) + { + m_displayposy = 0; + m_displayposx = 0; + } + */ + } + } } uint16_t generalplus_gpl_unknown_state::reg3094_r(offs_t offset) { - return machine().rand(); + return 0x0000; } uint16_t generalplus_gpl_unknown_state::reg3095_r(offs_t offset) { - return machine().rand(); + // loops on bit 0x0010 after writing data to 0x3092 + + // clrb [3005],12 is used before writing non-pixel data to 0x3092 + // setb [3005],12 is used after reading from 0x3094 + return 0x0000; } @@ -233,22 +468,36 @@ void generalplus_gpl_unknown_state::map(address_map &map) map(0x003001, 0x003001).rw(FUNC(generalplus_gpl_unknown_state::reg3001_r), FUNC(generalplus_gpl_unknown_state::reg3001_w)); map(0x003002, 0x003002).rw(FUNC(generalplus_gpl_unknown_state::reg3002_r), FUNC(generalplus_gpl_unknown_state::reg3002_w)); map(0x003003, 0x003003).rw(FUNC(generalplus_gpl_unknown_state::reg3003_r), FUNC(generalplus_gpl_unknown_state::reg3003_w)); - map(0x003004, 0x003004).r(FUNC(generalplus_gpl_unknown_state::reg3004_r)); + map(0x003004, 0x003004).r(FUNC(generalplus_gpl_unknown_state::reg3004_r)); // input from here is acted upon map(0x003005, 0x003005).rw(FUNC(generalplus_gpl_unknown_state::reg3005_r), FUNC(generalplus_gpl_unknown_state::reg3005_w)); + map(0x003006, 0x003006).r(FUNC(generalplus_gpl_unknown_state::reg3006_r)); + map(0x003007, 0x003007).r(FUNC(generalplus_gpl_unknown_state::reg3007_r)); + + map(0x00300f, 0x00300f).r(FUNC(generalplus_gpl_unknown_state::reg300f_r)); + + map(0x003016, 0x003016).r(FUNC(generalplus_gpl_unknown_state::reg3016_r)); map(0x003034, 0x003034).w(FUNC(generalplus_gpl_unknown_state::reg3034_w)); - map(0x003041, 0x003041).w(FUNC(generalplus_gpl_unknown_state::reg3041_w)); + map(0x003041, 0x003041).w(FUNC(generalplus_gpl_unknown_state::reg3041_audiodac_w)); map(0x003050, 0x003050).rw(FUNC(generalplus_gpl_unknown_state::reg3050_r), FUNC(generalplus_gpl_unknown_state::reg3050_w)); map(0x003051, 0x003051).w(FUNC(generalplus_gpl_unknown_state::reg3051_w)); + map(0x003052, 0x003052).r(FUNC(generalplus_gpl_unknown_state::reg3052_r)); + map(0x003053, 0x003053).r(FUNC(generalplus_gpl_unknown_state::reg3053_r)); - map(0x003092, 0x003092).w(FUNC(generalplus_gpl_unknown_state::reg3092_w)); - map(0x003094, 0x003094).r(FUNC(generalplus_gpl_unknown_state::reg3094_r)); - map(0x003095, 0x003095).r(FUNC(generalplus_gpl_unknown_state::reg3095_r)); + map(0x003090, 0x003090).r(FUNC(generalplus_gpl_unknown_state::reg3090_r)); + map(0x003091, 0x003091).r(FUNC(generalplus_gpl_unknown_state::reg3091_r)); + map(0x003092, 0x003092).w(FUNC(generalplus_gpl_unknown_state::reg3092_lcd_w)); + map(0x003094, 0x003094).r(FUNC(generalplus_gpl_unknown_state::reg3094_r)); // potential interesting + map(0x003095, 0x003095).r(FUNC(generalplus_gpl_unknown_state::reg3095_r)); // mostly a status flag - map(0x0030e4, 0x0030e4).r(FUNC(generalplus_gpl_unknown_state::reg30e4_r)); - map(0x0030e5, 0x0030e5).r(FUNC(generalplus_gpl_unknown_state::reg30e5_r)); + map(0x0030e0, 0x0030e0).w(FUNC(generalplus_gpl_unknown_state::reg30e0_w)); + map(0x0030e1, 0x0030e1).w(FUNC(generalplus_gpl_unknown_state::reg30e1_w)); + map(0x0030e2, 0x0030e2).w(FUNC(generalplus_gpl_unknown_state::reg30e2_w)); + map(0x0030e3, 0x0030e3).w(FUNC(generalplus_gpl_unknown_state::reg30e3_w)); + map(0x0030e4, 0x0030e4).r(FUNC(generalplus_gpl_unknown_state::reg30e4_r)); // potentially interesting (must not return 0x0000 or 'flash error') + map(0x0030e5, 0x0030e5).r(FUNC(generalplus_gpl_unknown_state::reg30e5_r)); // potentially interesting (also status flag) map(0x004000, 0x00bfff).rom().region("maincpu", 0x0000); map(0x00c000, 0x00ffff).rom().region("maincpu", 0x0000); @@ -259,39 +508,55 @@ void generalplus_gpl_unknown_state::map(address_map &map) void generalplus_gpl_unknown_state::machine_start() { + for (int color = 0; color < 0x10000; color++) + { + const u8 r = pal5bit(color >> 11); + const u8 g = pal6bit(color >> 5); + const u8 b = pal5bit(color & 0x1f); + m_palette->set_pen_color(color, rgb_t(r, g, b)); + } + + save_item(NAME(m_display)); + save_item(NAME(m_displayposx)); + save_item(NAME(m_displayposy)); + save_item(NAME(m_3001)); + save_item(NAME(m_3003)); + save_item(NAME(m_3005)); + save_item(NAME(m_3050)); } void generalplus_gpl_unknown_state::machine_reset() { + m_displayposx = 0; + m_displayposy = 0; + m_3001 = 0; + m_3003 = 0; + m_3005 = 0; + m_3050 = 0; } -// hack just so we can trigger some IRQs until sources are known -TIMER_DEVICE_CALLBACK_MEMBER(generalplus_gpl_unknown_state::scanline) +TIMER_DEVICE_CALLBACK_MEMBER( generalplus_gpl_unknown_state::timer ) { - int scanline = param; - - if (scanline == 50) - { - m_maincpu->set_input_line(UNSP_IRQ2_LINE, ASSERT_LINE); - } - - if (scanline == 90) - { - m_maincpu->set_input_line(UNSP_IRQ0_LINE, ASSERT_LINE); - } - - if (scanline == 126) - { - m_maincpu->set_input_line(UNSP_IRQ3_LINE, ASSERT_LINE); - } + m_maincpu->set_input_line(UNSP_IRQ3_LINE, ASSERT_LINE); } +TIMER_DEVICE_CALLBACK_MEMBER( generalplus_gpl_unknown_state::timer2 ) +{ + m_maincpu->set_input_line(UNSP_IRQ2_LINE, ASSERT_LINE); +} + +TIMER_DEVICE_CALLBACK_MEMBER( generalplus_gpl_unknown_state::timer3 ) +{ + m_maincpu->set_input_line(UNSP_IRQ0_LINE, ASSERT_LINE); +} + + + void generalplus_gpl_unknown_state::generalplus_gpl_unknown(machine_config &config) { UNSP_20(config, m_maincpu, 96000000); // internal ROM uses unsp2.0 opcodes, unknown clock m_maincpu->set_addrmap(AS_PROGRAM, &generalplus_gpl_unknown_state::map); m_maincpu->set_vectorbase(0x4010); // there is also a set of vectors for what looks to be a burn-in test at 4000, maybe external pin selects? - TIMER(config, "scantimer").configure_scanline(FUNC(generalplus_gpl_unknown_state::scanline), "screen", 0, 1); SCREEN(config, m_screen, SCREEN_TYPE_LCD); m_screen->set_refresh_hz(60); @@ -300,8 +565,16 @@ void generalplus_gpl_unknown_state::generalplus_gpl_unknown(machine_config &conf m_screen->set_visarea(0, 128-1, 0, 128-1); // not the correct resolution m_screen->set_screen_update(FUNC(generalplus_gpl_unknown_state::screen_update)); //m_screen->screen_vblank().set(FUNC(generalplus_gpl_unknown_state::screen_vblank)); + m_screen->set_palette(m_palette); - PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 0x8000); + SPEAKER(config, "speaker").front_center(); + DAC_16BIT_R2R_TWOS_COMPLEMENT(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 1.0); // unknown DAC + + TIMER(config, "timer").configure_periodic(FUNC(generalplus_gpl_unknown_state::timer), attotime::from_hz(200000)); // draw timer (pushes pixels to the display in the IRQ) + TIMER(config, "timer2").configure_periodic(FUNC(generalplus_gpl_unknown_state::timer2), attotime::from_hz(1000)); // game speed? + TIMER(config, "timer3").configure_periodic(FUNC(generalplus_gpl_unknown_state::timer3), attotime::from_hz(20000)); // audio + + PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 0x10000); }