mirror of
https://github.com/holub/mame
synced 2025-06-03 11:26:56 +03:00
-Significant updates to the CD-i driver [Ryan Holtz] (#9102)
-mcd212: Assorted changes. [Ryan Holtz] * Replaced verboselog with logmacro. * Corrected end-of-line region control handling, fixing garbage in The Apprentice. * Fixed screen bitmap handling to be more in line with MAME standards. * Simplified region-control handling. * Removed historical reliance on debug machine switches. * Converted to use a map() function rather than an internal switch. * Converted to use dipalette and rgb_t internally instead of separate CLUT arrays. * Optimized by replacing rgb_t usage with uint32_t values. * Optimized by calculating plane transparency on the fly. * Templatized mix_lines to reduce inner-loop branching. * Fixed a clamping issue with pre-calculated DYUV limits. * Reduce effective color depth back to 6:6:6 to match hardware. -cdrom: Allow recognizing CDI/2352 in cuesheets. [Ryan Holtz] -cdic: Various audio-related changes. [Ryan Holtz] * Attempt to descramble sectors that don't initially appear sensible. * Added support for playing CDDA sectors. * Fixed faulty logic in TOC processing.
This commit is contained in:
parent
6cb03e6627
commit
a3cc6df349
@ -10700,7 +10700,7 @@ license:CC0
|
||||
<publisher>The Vision Factory</publisher>
|
||||
<part name="cdrom" interface="cdi_cdrom">
|
||||
<diskarea name="cdrom">
|
||||
<disk name="the apprentice (cdi-ready)" sha1="7e1f612f1c36dabdc304abf2d17200b5faa4e180" status="baddump"/>
|
||||
<disk name="the apprentice (cdi-ready)" sha1="3a66337c20b9157e64228847ee3d153f80c25e4e"/>
|
||||
</diskarea>
|
||||
</part>
|
||||
</software>
|
||||
|
@ -970,6 +970,11 @@ static void cdrom_get_info_from_type_string(const char *typestring, uint32_t *tr
|
||||
*trktype = CD_TRACK_MODE2_RAW;
|
||||
*datasize = 2352;
|
||||
}
|
||||
else if (!strcmp(typestring, "CDI/2352"))
|
||||
{
|
||||
*trktype = CD_TRACK_MODE2_RAW;
|
||||
*datasize = 2352;
|
||||
}
|
||||
else if (!strcmp(typestring, "AUDIO"))
|
||||
{
|
||||
*trktype = CD_TRACK_AUDIO;
|
||||
|
@ -92,7 +92,7 @@ void cdi_state::cdimono1_mem(address_map &map)
|
||||
map(0x318000, 0x31ffff).noprw();
|
||||
map(0x320000, 0x323fff).rw("mk48t08", FUNC(timekeeper_device::read), FUNC(timekeeper_device::write)).umask16(0xff00); /* nvram (only low bytes used) */
|
||||
map(0x400000, 0x47ffff).rom().region("maincpu", 0);
|
||||
map(0x4fffe0, 0x4fffff).rw(m_mcd212, FUNC(mcd212_device::regs_r), FUNC(mcd212_device::regs_w));
|
||||
map(0x4fffe0, 0x4fffff).m(m_mcd212, FUNC(mcd212_device::map));
|
||||
map(0x500000, 0x57ffff).ram();
|
||||
map(0xd00000, 0xdfffff).ram(); // DVC RAM block 1
|
||||
map(0xe00000, 0xe7ffff).rw(FUNC(cdi_state::dvc_r), FUNC(cdi_state::dvc_w));
|
||||
@ -106,13 +106,9 @@ void cdi_state::cdimono2_mem(address_map &map)
|
||||
#if ENABLE_UART_PRINTING
|
||||
map(0x301400, 0x301403).r(m_maincpu, FUNC(scc68070_device::uart_loopback_enable));
|
||||
#endif
|
||||
//map(0x300000, 0x303bff).rw("cdic", FUNC(cdicdic_device::ram_r), FUNC(cdicdic_device::ram_w));
|
||||
//map(0x303c00, 0x303fff).rw("cdic", FUNC(cdicdic_device::regs_r), FUNC(cdicdic_device::regs_w));
|
||||
//map(0x310000, 0x317fff).rw("slave", FUNC(cdislave_hle_device::slave_r), FUNC(cdislave_hle_device::slave_w));
|
||||
//map(0x318000, 0x31ffff).noprw();
|
||||
map(0x320000, 0x323fff).rw("mk48t08", FUNC(timekeeper_device::read), FUNC(timekeeper_device::write)).umask16(0xff00); /* nvram (only low bytes used) */
|
||||
map(0x400000, 0x47ffff).rom().region("maincpu", 0);
|
||||
map(0x4fffe0, 0x4fffff).rw(m_mcd212, FUNC(mcd212_device::regs_r), FUNC(mcd212_device::regs_w));
|
||||
map(0x4fffe0, 0x4fffff).m(m_mcd212, FUNC(mcd212_device::map));
|
||||
}
|
||||
|
||||
void cdi_state::cdi910_mem(address_map &map)
|
||||
@ -124,15 +120,9 @@ void cdi_state::cdi910_mem(address_map &map)
|
||||
#if ENABLE_UART_PRINTING
|
||||
map(0x301400, 0x301403).r(m_maincpu, FUNC(scc68070_device::uart_loopback_enable));
|
||||
#endif
|
||||
// map(0x300000, 0x303bff).rw("cdic", FUNC(cdicdic_device::ram_r), FUNC(cdicdic_device::ram_w));
|
||||
// map(0x303c00, 0x303fff).rw("cdic", FUNC(cdicdic_device::regs_r), FUNC(cdicdic_device::regs_w));
|
||||
// map(0x310000, 0x317fff).rw("slave_hle", FUNC(cdislave_hle_device::slave_r), FUNC(cdislave_hle_device::slave_w));
|
||||
// map(0x318000, 0x31ffff).noprw();
|
||||
map(0x320000, 0x323fff).rw("mk48t08", FUNC(timekeeper_device::read), FUNC(timekeeper_device::write)).umask16(0xff00); /* nvram (only low bytes used) */
|
||||
map(0x4fffe0, 0x4fffff).rw(m_mcd212, FUNC(mcd212_device::regs_r), FUNC(mcd212_device::regs_w));
|
||||
// map(0x500000, 0x57ffff).ram();
|
||||
map(0x4fffe0, 0x4fffff).m(m_mcd212, FUNC(mcd212_device::map));
|
||||
map(0x500000, 0xffffff).noprw();
|
||||
// map(0xe00000, 0xefffff).ram(); // DVC
|
||||
}
|
||||
|
||||
|
||||
@ -141,69 +131,12 @@ void cdi_state::cdi910_mem(address_map &map)
|
||||
*************************/
|
||||
|
||||
static INPUT_PORTS_START( cdi )
|
||||
PORT_START("DEBUG")
|
||||
PORT_CONFNAME( 0x01, 0x00, "Plane A Disable")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
|
||||
PORT_CONFSETTING( 0x01, DEF_STR( On ) )
|
||||
PORT_CONFNAME( 0x02, 0x00, "Plane B Disable")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
|
||||
PORT_CONFSETTING( 0x02, DEF_STR( On ) )
|
||||
PORT_CONFNAME( 0x04, 0x00, "Force Backdrop Color")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
|
||||
PORT_CONFSETTING( 0x04, DEF_STR( On ) )
|
||||
PORT_CONFNAME( 0xf0, 0x00, "Backdrop Color")
|
||||
PORT_CONFSETTING( 0x00, "Black" )
|
||||
PORT_CONFSETTING( 0x10, "Half-Bright Blue" )
|
||||
PORT_CONFSETTING( 0x20, "Half-Bright Green" )
|
||||
PORT_CONFSETTING( 0x30, "Half-Bright Cyan" )
|
||||
PORT_CONFSETTING( 0x40, "Half-Bright Red" )
|
||||
PORT_CONFSETTING( 0x50, "Half-Bright Magenta" )
|
||||
PORT_CONFSETTING( 0x60, "Half-Bright Yellow" )
|
||||
PORT_CONFSETTING( 0x70, "Half-Bright White" )
|
||||
PORT_CONFSETTING( 0x80, "Black (Alternate)" )
|
||||
PORT_CONFSETTING( 0x90, "Blue" )
|
||||
PORT_CONFSETTING( 0xa0, "Green" )
|
||||
PORT_CONFSETTING( 0xb0, "Cyan" )
|
||||
PORT_CONFSETTING( 0xc0, "Red" )
|
||||
PORT_CONFSETTING( 0xd0, "Magenta" )
|
||||
PORT_CONFSETTING( 0xe0, "Yellow" )
|
||||
PORT_CONFSETTING( 0xf0, "White" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INPUT_PORTS_START( cdimono2 )
|
||||
PORT_START("DEBUG")
|
||||
PORT_CONFNAME( 0x01, 0x00, "Plane A Disable")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
|
||||
PORT_CONFSETTING( 0x01, DEF_STR( On ) )
|
||||
PORT_CONFNAME( 0x02, 0x00, "Plane B Disable")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
|
||||
PORT_CONFSETTING( 0x02, DEF_STR( On ) )
|
||||
PORT_CONFNAME( 0x04, 0x00, "Force Backdrop Color")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
|
||||
PORT_CONFSETTING( 0x04, DEF_STR( On ) )
|
||||
PORT_CONFNAME( 0xf0, 0x00, "Backdrop Color")
|
||||
PORT_CONFSETTING( 0x00, "Black" )
|
||||
PORT_CONFSETTING( 0x10, "Half-Bright Blue" )
|
||||
PORT_CONFSETTING( 0x20, "Half-Bright Green" )
|
||||
PORT_CONFSETTING( 0x30, "Half-Bright Cyan" )
|
||||
PORT_CONFSETTING( 0x40, "Half-Bright Red" )
|
||||
PORT_CONFSETTING( 0x50, "Half-Bright Magenta" )
|
||||
PORT_CONFSETTING( 0x60, "Half-Bright Yellow" )
|
||||
PORT_CONFSETTING( 0x70, "Half-Bright White" )
|
||||
PORT_CONFSETTING( 0x80, "Black (Alternate)" )
|
||||
PORT_CONFSETTING( 0x90, "Blue" )
|
||||
PORT_CONFSETTING( 0xa0, "Green" )
|
||||
PORT_CONFSETTING( 0xb0, "Cyan" )
|
||||
PORT_CONFSETTING( 0xc0, "Red" )
|
||||
PORT_CONFSETTING( 0xd0, "Magenta" )
|
||||
PORT_CONFSETTING( 0xe0, "Yellow" )
|
||||
PORT_CONFSETTING( 0xf0, "White" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
static INPUT_PORTS_START( quizard )
|
||||
PORT_INCLUDE( cdi )
|
||||
|
||||
PORT_START("P0")
|
||||
PORT_DIPNAME( 0x07, 0x05, "Settings" )
|
||||
PORT_DIPSETTING( 0x00, "1 Coin, 0 Bonus Limit, 0 Bonus Number" )
|
||||
@ -419,40 +352,33 @@ static const uint16_t cdi220_lcd_char[20*22] =
|
||||
0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0400, 0x0400, 0x0400, 0x0400
|
||||
};
|
||||
|
||||
void cdi_state::draw_lcd(int y)
|
||||
uint32_t cdi_state::screen_update_cdimono1_lcd(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
if (y >= 22 || !m_slave_hle.found())
|
||||
return;
|
||||
if (!m_slave_hle.found())
|
||||
return 0;
|
||||
|
||||
uint32_t *scanline = &m_lcdbitmap.pix(y);
|
||||
|
||||
for (int lcd = 0; lcd < 8; lcd++)
|
||||
for (int y = 0; y < 22; y++)
|
||||
{
|
||||
uint16_t data = (m_slave_hle->get_lcd_state()[lcd*2] << 8) |
|
||||
m_slave_hle->get_lcd_state()[lcd*2 + 1];
|
||||
for (int x = 0; x < 20; x++)
|
||||
uint32_t *scanline = &bitmap.pix(y);
|
||||
|
||||
for (int lcd = 0; lcd < 8; lcd++)
|
||||
{
|
||||
if (data & cdi220_lcd_char[y*20 + x])
|
||||
uint16_t data = (m_slave_hle->get_lcd_state()[lcd*2] << 8) |
|
||||
m_slave_hle->get_lcd_state()[lcd*2 + 1];
|
||||
for (int x = 0; x < 20; x++)
|
||||
{
|
||||
scanline[(7 - lcd)*24 + x] = rgb_t::white();
|
||||
}
|
||||
else
|
||||
{
|
||||
scanline[(7 - lcd)*24 + x] = rgb_t::black();
|
||||
if (data & cdi220_lcd_char[y*20 + x])
|
||||
{
|
||||
scanline[(7 - lcd)*24 + x] = rgb_t::white();
|
||||
}
|
||||
else
|
||||
{
|
||||
scanline[(7 - lcd)*24 + x] = rgb_t::black();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cdi_state::video_start()
|
||||
{
|
||||
if (m_lcd)
|
||||
m_lcd->register_screen_bitmap(m_lcdbitmap);
|
||||
}
|
||||
|
||||
uint32_t cdi_state::screen_update_cdimono1_lcd(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
copybitmap(bitmap, m_lcdbitmap, 0, 0, 0, 0, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -470,14 +396,15 @@ void cdi_state::cdimono1_base(machine_config &config)
|
||||
MCD212(config, m_mcd212, CLOCK_A);
|
||||
m_mcd212->set_screen("screen");
|
||||
m_mcd212->int_callback().set(m_maincpu, FUNC(scc68070_device::int1_w));
|
||||
m_mcd212->set_scanline_callback(FUNC(cdi_state::draw_lcd));
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(50);
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
|
||||
screen.set_size(384, 302);
|
||||
screen.set_visarea(0, 384-1, 22, 302-1); // TODO: dynamic resolution
|
||||
screen.set_screen_update("mcd212", FUNC(mcd212_device::screen_update));
|
||||
screen.set_video_attributes(VIDEO_UPDATE_SCANLINE);
|
||||
screen.set_size(384, 312);
|
||||
screen.set_visarea(0, 384-1, 0, 312-1); // TODO: dynamic resolution
|
||||
screen.set_screen_update(m_mcd212, FUNC(mcd212_device::screen_update));
|
||||
screen.screen_vblank().set(m_mcd212, FUNC(mcd212_device::screen_vblank));
|
||||
|
||||
SCREEN(config, m_lcd, SCREEN_TYPE_RASTER);
|
||||
m_lcd->set_refresh_hz(50);
|
||||
@ -509,10 +436,6 @@ void cdi_state::cdimono1_base(machine_config &config)
|
||||
DMADAC(config, m_dmadac[1]);
|
||||
m_dmadac[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
|
||||
|
||||
CDDA(config, m_cdda);
|
||||
m_cdda->add_route(ALL_OUTPUTS, "lspeaker", 1.0);
|
||||
m_cdda->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
|
||||
|
||||
MK48T08(config, "mk48t08");
|
||||
}
|
||||
|
||||
@ -525,14 +448,15 @@ void cdi_state::cdimono2(machine_config &config)
|
||||
MCD212(config, m_mcd212, CLOCK_A);
|
||||
m_mcd212->set_screen("screen");
|
||||
m_mcd212->int_callback().set(m_maincpu, FUNC(scc68070_device::int1_w));
|
||||
m_mcd212->set_scanline_callback(FUNC(cdi_state::draw_lcd));
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(60);
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
|
||||
screen.set_size(384, 302);
|
||||
screen.set_visarea(0, 384-1, 22, 302-1); // TODO: dynamic resolution
|
||||
screen.set_screen_update("mcd212", FUNC(mcd212_device::screen_update));
|
||||
screen.set_video_attributes(VIDEO_UPDATE_SCANLINE);
|
||||
screen.set_size(384, 312);
|
||||
screen.set_visarea(0, 384-1, 0, 312-1); // TODO: dynamic resolution
|
||||
screen.set_screen_update(m_mcd212, FUNC(mcd212_device::screen_update));
|
||||
screen.screen_vblank().set(m_mcd212, FUNC(mcd212_device::screen_vblank));
|
||||
|
||||
SCREEN(config, m_lcd, SCREEN_TYPE_RASTER);
|
||||
m_lcd->set_refresh_hz(60);
|
||||
@ -561,10 +485,6 @@ void cdi_state::cdimono2(machine_config &config)
|
||||
DMADAC(config, m_dmadac[1]);
|
||||
m_dmadac[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
|
||||
|
||||
CDDA(config, m_cdda);
|
||||
m_cdda->add_route(ALL_OUTPUTS, "lspeaker", 1.0);
|
||||
m_cdda->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
|
||||
|
||||
MK48T08(config, "mk48t08");
|
||||
}
|
||||
|
||||
@ -576,14 +496,15 @@ void cdi_state::cdi910(machine_config &config)
|
||||
MCD212(config, m_mcd212, CLOCK_A);
|
||||
m_mcd212->set_screen("screen");
|
||||
m_mcd212->int_callback().set(m_maincpu, FUNC(scc68070_device::int1_w));
|
||||
m_mcd212->set_scanline_callback(FUNC(cdi_state::draw_lcd));
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(50);
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
|
||||
screen.set_video_attributes(VIDEO_UPDATE_SCANLINE);
|
||||
screen.set_size(384, 312);
|
||||
screen.set_visarea(0, 384-1, 32, 312-1); // TODO: dynamic resolution
|
||||
screen.set_screen_update("mcd212", FUNC(mcd212_device::screen_update));
|
||||
screen.set_screen_update(m_mcd212, FUNC(mcd212_device::screen_update));
|
||||
screen.screen_vblank().set(m_mcd212, FUNC(mcd212_device::screen_vblank));
|
||||
|
||||
SCREEN(config, m_lcd, SCREEN_TYPE_RASTER);
|
||||
m_lcd->set_refresh_hz(60);
|
||||
@ -612,10 +533,6 @@ void cdi_state::cdi910(machine_config &config)
|
||||
DMADAC(config, m_dmadac[1]);
|
||||
m_dmadac[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
|
||||
|
||||
CDDA(config, m_cdda);
|
||||
m_cdda->add_route(ALL_OUTPUTS, "lspeaker", 1.0);
|
||||
m_cdda->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
|
||||
|
||||
MK48T08(config, "mk48t08");
|
||||
}
|
||||
|
||||
|
@ -21,14 +21,13 @@ public:
|
||||
cdi_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_lcd(*this, "lcd")
|
||||
, m_planea(*this, "mcd212:planea")
|
||||
, m_slave_hle(*this, "slave_hle")
|
||||
, m_servo(*this, "servo")
|
||||
, m_slave(*this, "slave")
|
||||
, m_cdic(*this, "cdic")
|
||||
, m_cdda(*this, "cdda")
|
||||
, m_mcd212(*this, "mcd212")
|
||||
, m_lcd(*this, "lcd")
|
||||
, m_dmadac(*this, "dac%u", 1U)
|
||||
{ }
|
||||
|
||||
@ -43,10 +42,9 @@ protected:
|
||||
void cdimono1_mem(address_map &map);
|
||||
|
||||
required_device<scc68070_device> m_maincpu;
|
||||
optional_device<screen_device> m_lcd;
|
||||
|
||||
private:
|
||||
virtual void video_start() override;
|
||||
|
||||
enum servo_portc_bit_t
|
||||
{
|
||||
INV_JUC_OUT = (1 << 2),
|
||||
@ -54,7 +52,6 @@ private:
|
||||
INV_CADDYSWITCH_IN = (1 << 7)
|
||||
};
|
||||
|
||||
void draw_lcd(int y);
|
||||
uint32_t screen_update_cdimono1_lcd(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void cdi910_mem(address_map &map);
|
||||
@ -72,13 +69,9 @@ private:
|
||||
optional_device<m68hc05c8_device> m_servo;
|
||||
optional_device<m68hc05c8_device> m_slave;
|
||||
optional_device<cdicdic_device> m_cdic;
|
||||
required_device<cdda_device> m_cdda;
|
||||
required_device<mcd212_device> m_mcd212;
|
||||
optional_device<screen_device> m_lcd;
|
||||
|
||||
required_device_array<dmadac_sound_device, 2> m_dmadac;
|
||||
|
||||
bitmap_rgb32 m_lcdbitmap;
|
||||
};
|
||||
|
||||
class quizard_state : public cdi_state
|
||||
|
@ -97,6 +97,162 @@ const uint16_t cdicdic_device::s_crc_ccitt_table[256] =
|
||||
|
||||
#define CRC_CCITT_ROUND(accum, data) (((accum << 8) | data) ^ s_crc_ccitt_table[accum >> 8])
|
||||
|
||||
const uint8_t cdicdic_device::s_sector_scramble[2448] =
|
||||
{
|
||||
// Sector sync area is not scrambled
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
// Remaining data is scrambled
|
||||
0x01, 0x80, 0x00, 0x60, 0x00, 0x28, 0x00, 0x1e, 0x80, 0x08, 0x60, 0x06, 0xa8, 0x02, 0xfe, 0x81,
|
||||
0x80, 0x60, 0x60, 0x28, 0x28, 0x1e, 0x9e, 0x88, 0x68, 0x66, 0xae, 0xaa, 0xfc, 0x7f, 0x01, 0xe0,
|
||||
0x00, 0x48, 0x00, 0x36, 0x80, 0x16, 0xe0, 0x0e, 0xc8, 0x04, 0x56, 0x83, 0x7e, 0xe1, 0xe0, 0x48,
|
||||
0x48, 0x36, 0xb6, 0x96, 0xf6, 0xee, 0xc6, 0xcc, 0x52, 0xd5, 0xfd, 0x9f, 0x01, 0xa8, 0x00, 0x7e,
|
||||
0x80, 0x20, 0x60, 0x18, 0x28, 0x0a, 0x9e, 0x87, 0x28, 0x62, 0x9e, 0xa9, 0xa8, 0x7e, 0xfe, 0xa0,
|
||||
0x40, 0x78, 0x30, 0x22, 0x94, 0x19, 0xaf, 0x4a, 0xfc, 0x37, 0x01, 0xd6, 0x80, 0x5e, 0xe0, 0x38,
|
||||
0x48, 0x12, 0xb6, 0x8d, 0xb6, 0xe5, 0xb6, 0xcb, 0x36, 0xd7, 0x56, 0xde, 0xbe, 0xd8, 0x70, 0x5a,
|
||||
0xa4, 0x3b, 0x3b, 0x53, 0x53, 0x7d, 0xfd, 0xe1, 0x81, 0x88, 0x60, 0x66, 0xa8, 0x2a, 0xfe, 0x9f,
|
||||
0x00, 0x68, 0x00, 0x2e, 0x80, 0x1c, 0x60, 0x09, 0xe8, 0x06, 0xce, 0x82, 0xd4, 0x61, 0x9f, 0x68,
|
||||
0x68, 0x2e, 0xae, 0x9c, 0x7c, 0x69, 0xe1, 0xee, 0xc8, 0x4c, 0x56, 0xb5, 0xfe, 0xf7, 0x00, 0x46,
|
||||
0x80, 0x32, 0xe0, 0x15, 0x88, 0x0f, 0x26, 0x84, 0x1a, 0xe3, 0x4b, 0x09, 0xf7, 0x46, 0xc6, 0xb2,
|
||||
0xd2, 0xf5, 0x9d, 0x87, 0x29, 0xa2, 0x9e, 0xf9, 0xa8, 0x42, 0xfe, 0xb1, 0x80, 0x74, 0x60, 0x27,
|
||||
0x68, 0x1a, 0xae, 0x8b, 0x3c, 0x67, 0x51, 0xea, 0xbc, 0x4f, 0x31, 0xf4, 0x14, 0x47, 0x4f, 0x72,
|
||||
0xb4, 0x25, 0xb7, 0x5b, 0x36, 0xbb, 0x56, 0xf3, 0x7e, 0xc5, 0xe0, 0x53, 0x08, 0x3d, 0xc6, 0x91,
|
||||
0x92, 0xec, 0x6d, 0x8d, 0xed, 0xa5, 0x8d, 0xbb, 0x25, 0xb3, 0x5b, 0x35, 0xfb, 0x57, 0x03, 0x7e,
|
||||
0x81, 0xe0, 0x60, 0x48, 0x28, 0x36, 0x9e, 0x96, 0xe8, 0x6e, 0xce, 0xac, 0x54, 0x7d, 0xff, 0x61,
|
||||
0x80, 0x28, 0x60, 0x1e, 0xa8, 0x08, 0x7e, 0x86, 0xa0, 0x62, 0xf8, 0x29, 0x82, 0x9e, 0xe1, 0xa8,
|
||||
0x48, 0x7e, 0xb6, 0xa0, 0x76, 0xf8, 0x26, 0xc2, 0x9a, 0xd1, 0xab, 0x1c, 0x7f, 0x49, 0xe0, 0x36,
|
||||
0xc8, 0x16, 0xd6, 0x8e, 0xde, 0xe4, 0x58, 0x4b, 0x7a, 0xb7, 0x63, 0x36, 0xa9, 0xd6, 0xfe, 0xde,
|
||||
0xc0, 0x58, 0x50, 0x3a, 0xbc, 0x13, 0x31, 0xcd, 0xd4, 0x55, 0x9f, 0x7f, 0x28, 0x20, 0x1e, 0x98,
|
||||
0x08, 0x6a, 0x86, 0xaf, 0x22, 0xfc, 0x19, 0x81, 0xca, 0xe0, 0x57, 0x08, 0x3e, 0x86, 0x90, 0x62,
|
||||
0xec, 0x29, 0x8d, 0xde, 0xe5, 0x98, 0x4b, 0x2a, 0xb7, 0x5f, 0x36, 0xb8, 0x16, 0xf2, 0x8e, 0xc5,
|
||||
0xa4, 0x53, 0x3b, 0x7d, 0xd3, 0x61, 0x9d, 0xe8, 0x69, 0x8e, 0xae, 0xe4, 0x7c, 0x4b, 0x61, 0xf7,
|
||||
0x68, 0x46, 0xae, 0xb2, 0xfc, 0x75, 0x81, 0xe7, 0x20, 0x4a, 0x98, 0x37, 0x2a, 0x96, 0x9f, 0x2e,
|
||||
0xe8, 0x1c, 0x4e, 0x89, 0xf4, 0x66, 0xc7, 0x6a, 0xd2, 0xaf, 0x1d, 0xbc, 0x09, 0xb1, 0xc6, 0xf4,
|
||||
0x52, 0xc7, 0x7d, 0x92, 0xa1, 0xad, 0xb8, 0x7d, 0xb2, 0xa1, 0xb5, 0xb8, 0x77, 0x32, 0xa6, 0x95,
|
||||
0xba, 0xef, 0x33, 0x0c, 0x15, 0xc5, 0xcf, 0x13, 0x14, 0x0d, 0xcf, 0x45, 0x94, 0x33, 0x2f, 0x55,
|
||||
0xdc, 0x3f, 0x19, 0xd0, 0x0a, 0xdc, 0x07, 0x19, 0xc2, 0x8a, 0xd1, 0xa7, 0x1c, 0x7a, 0x89, 0xe3,
|
||||
0x26, 0xc9, 0xda, 0xd6, 0xdb, 0x1e, 0xdb, 0x48, 0x5b, 0x76, 0xbb, 0x66, 0xf3, 0x6a, 0xc5, 0xef,
|
||||
0x13, 0x0c, 0x0d, 0xc5, 0xc5, 0x93, 0x13, 0x2d, 0xcd, 0xdd, 0x95, 0x99, 0xaf, 0x2a, 0xfc, 0x1f,
|
||||
0x01, 0xc8, 0x00, 0x56, 0x80, 0x3e, 0xe0, 0x10, 0x48, 0x0c, 0x36, 0x85, 0xd6, 0xe3, 0x1e, 0xc9,
|
||||
0xc8, 0x56, 0xd6, 0xbe, 0xde, 0xf0, 0x58, 0x44, 0x3a, 0xb3, 0x53, 0x35, 0xfd, 0xd7, 0x01, 0x9e,
|
||||
0x80, 0x68, 0x60, 0x2e, 0xa8, 0x1c, 0x7e, 0x89, 0xe0, 0x66, 0xc8, 0x2a, 0xd6, 0x9f, 0x1e, 0xe8,
|
||||
0x08, 0x4e, 0x86, 0xb4, 0x62, 0xf7, 0x69, 0x86, 0xae, 0xe2, 0xfc, 0x49, 0x81, 0xf6, 0xe0, 0x46,
|
||||
0xc8, 0x32, 0xd6, 0x95, 0x9e, 0xef, 0x28, 0x4c, 0x1e, 0xb5, 0xc8, 0x77, 0x16, 0xa6, 0x8e, 0xfa,
|
||||
0xe4, 0x43, 0x0b, 0x71, 0xc7, 0x64, 0x52, 0xab, 0x7d, 0xbf, 0x61, 0xb0, 0x28, 0x74, 0x1e, 0xa7,
|
||||
0x48, 0x7a, 0xb6, 0xa3, 0x36, 0xf9, 0xd6, 0xc2, 0xde, 0xd1, 0x98, 0x5c, 0x6a, 0xb9, 0xef, 0x32,
|
||||
0xcc, 0x15, 0x95, 0xcf, 0x2f, 0x14, 0x1c, 0x0f, 0x49, 0xc4, 0x36, 0xd3, 0x56, 0xdd, 0xfe, 0xd9,
|
||||
0x80, 0x5a, 0xe0, 0x3b, 0x08, 0x13, 0x46, 0x8d, 0xf2, 0xe5, 0x85, 0x8b, 0x23, 0x27, 0x59, 0xda,
|
||||
0xba, 0xdb, 0x33, 0x1b, 0x55, 0xcb, 0x7f, 0x17, 0x60, 0x0e, 0xa8, 0x04, 0x7e, 0x83, 0x60, 0x61,
|
||||
0xe8, 0x28, 0x4e, 0x9e, 0xb4, 0x68, 0x77, 0x6e, 0xa6, 0xac, 0x7a, 0xfd, 0xe3, 0x01, 0x89, 0xc0,
|
||||
0x66, 0xd0, 0x2a, 0xdc, 0x1f, 0x19, 0xc8, 0x0a, 0xd6, 0x87, 0x1e, 0xe2, 0x88, 0x49, 0xa6, 0xb6,
|
||||
0xfa, 0xf6, 0xc3, 0x06, 0xd1, 0xc2, 0xdc, 0x51, 0x99, 0xfc, 0x6a, 0xc1, 0xef, 0x10, 0x4c, 0x0c,
|
||||
0x35, 0xc5, 0xd7, 0x13, 0x1e, 0x8d, 0xc8, 0x65, 0x96, 0xab, 0x2e, 0xff, 0x5c, 0x40, 0x39, 0xf0,
|
||||
0x12, 0xc4, 0x0d, 0x93, 0x45, 0xad, 0xf3, 0x3d, 0x85, 0xd1, 0xa3, 0x1c, 0x79, 0xc9, 0xe2, 0xd6,
|
||||
0xc9, 0x9e, 0xd6, 0xe8, 0x5e, 0xce, 0xb8, 0x54, 0x72, 0xbf, 0x65, 0xb0, 0x2b, 0x34, 0x1f, 0x57,
|
||||
0x48, 0x3e, 0xb6, 0x90, 0x76, 0xec, 0x26, 0xcd, 0xda, 0xd5, 0x9b, 0x1f, 0x2b, 0x48, 0x1f, 0x76,
|
||||
0x88, 0x26, 0xe6, 0x9a, 0xca, 0xeb, 0x17, 0x0f, 0x4e, 0x84, 0x34, 0x63, 0x57, 0x69, 0xfe, 0xae,
|
||||
0xc0, 0x7c, 0x50, 0x21, 0xfc, 0x18, 0x41, 0xca, 0xb0, 0x57, 0x34, 0x3e, 0x97, 0x50, 0x6e, 0xbc,
|
||||
0x2c, 0x71, 0xdd, 0xe4, 0x59, 0x8b, 0x7a, 0xe7, 0x63, 0x0a, 0xa9, 0xc7, 0x3e, 0xd2, 0x90, 0x5d,
|
||||
0xac, 0x39, 0xbd, 0xd2, 0xf1, 0x9d, 0x84, 0x69, 0xa3, 0x6e, 0xf9, 0xec, 0x42, 0xcd, 0xf1, 0x95,
|
||||
0x84, 0x6f, 0x23, 0x6c, 0x19, 0xed, 0xca, 0xcd, 0x97, 0x15, 0xae, 0x8f, 0x3c, 0x64, 0x11, 0xeb,
|
||||
0x4c, 0x4f, 0x75, 0xf4, 0x27, 0x07, 0x5a, 0x82, 0xbb, 0x21, 0xb3, 0x58, 0x75, 0xfa, 0xa7, 0x03,
|
||||
0x3a, 0x81, 0xd3, 0x20, 0x5d, 0xd8, 0x39, 0x9a, 0x92, 0xeb, 0x2d, 0x8f, 0x5d, 0xa4, 0x39, 0xbb,
|
||||
0x52, 0xf3, 0x7d, 0x85, 0xe1, 0xa3, 0x08, 0x79, 0xc6, 0xa2, 0xd2, 0xf9, 0x9d, 0x82, 0xe9, 0xa1,
|
||||
0x8e, 0xf8, 0x64, 0x42, 0xab, 0x71, 0xbf, 0x64, 0x70, 0x2b, 0x64, 0x1f, 0x6b, 0x48, 0x2f, 0x76,
|
||||
0x9c, 0x26, 0xe9, 0xda, 0xce, 0xdb, 0x14, 0x5b, 0x4f, 0x7b, 0x74, 0x23, 0x67, 0x59, 0xea, 0xba,
|
||||
0xcf, 0x33, 0x14, 0x15, 0xcf, 0x4f, 0x14, 0x34, 0x0f, 0x57, 0x44, 0x3e, 0xb3, 0x50, 0x75, 0xfc,
|
||||
0x27, 0x01, 0xda, 0x80, 0x5b, 0x20, 0x3b, 0x58, 0x13, 0x7a, 0x8d, 0xe3, 0x25, 0x89, 0xdb, 0x26,
|
||||
0xdb, 0x5a, 0xdb, 0x7b, 0x1b, 0x63, 0x4b, 0x69, 0xf7, 0x6e, 0xc6, 0xac, 0x52, 0xfd, 0xfd, 0x81,
|
||||
0x81, 0xa0, 0x60, 0x78, 0x28, 0x22, 0x9e, 0x99, 0xa8, 0x6a, 0xfe, 0xaf, 0x00, 0x7c, 0x00, 0x21,
|
||||
0xc0, 0x18, 0x50, 0x0a, 0xbc, 0x07, 0x31, 0xc2, 0x94, 0x51, 0xaf, 0x7c, 0x7c, 0x21, 0xe1, 0xd8,
|
||||
0x48, 0x5a, 0xb6, 0xbb, 0x36, 0xf3, 0x56, 0xc5, 0xfe, 0xd3, 0x00, 0x5d, 0xc0, 0x39, 0x90, 0x12,
|
||||
0xec, 0x0d, 0x8d, 0xc5, 0xa5, 0x93, 0x3b, 0x2d, 0xd3, 0x5d, 0x9d, 0xf9, 0xa9, 0x82, 0xfe, 0xe1,
|
||||
0x80, 0x48, 0x60, 0x36, 0xa8, 0x16, 0xfe, 0x8e, 0xc0, 0x64, 0x50, 0x2b, 0x7c, 0x1f, 0x61, 0xc8,
|
||||
0x28, 0x56, 0x9e, 0xbe, 0xe8, 0x70, 0x4e, 0xa4, 0x34, 0x7b, 0x57, 0x63, 0x7e, 0xa9, 0xe0, 0x7e,
|
||||
0xc8, 0x20, 0x56, 0x98, 0x3e, 0xea, 0x90, 0x4f, 0x2c, 0x34, 0x1d, 0xd7, 0x49, 0x9e, 0xb6, 0xe8,
|
||||
0x76, 0xce, 0xa6, 0xd4, 0x7a, 0xdf, 0x63, 0x18, 0x29, 0xca, 0x9e, 0xd7, 0x28, 0x5e, 0x9e, 0xb8,
|
||||
0x68, 0x72, 0xae, 0xa5, 0xbc, 0x7b, 0x31, 0xe3, 0x54, 0x49, 0xff, 0x76, 0xc0, 0x26, 0xd0, 0x1a,
|
||||
0xdc, 0x0b, 0x19, 0xc7, 0x4a, 0xd2, 0xb7, 0x1d, 0xb6, 0x89, 0xb6, 0xe6, 0xf6, 0xca, 0xc6, 0xd7,
|
||||
0x12, 0xde, 0x8d, 0x98, 0x65, 0xaa, 0xab, 0x3f, 0x3f, 0x50, 0x10, 0x3c, 0x0c, 0x11, 0xc5, 0xcc,
|
||||
0x53, 0x15, 0xfd, 0xcf, 0x01, 0x94, 0x00, 0x6f, 0x40, 0x2c, 0x30, 0x1d, 0xd4, 0x09, 0x9f, 0x46,
|
||||
0xe8, 0x32, 0xce, 0x95, 0x94, 0x6f, 0x2f, 0x6c, 0x1c, 0x2d, 0xc9, 0xdd, 0x96, 0xd9, 0xae, 0xda,
|
||||
0xfc, 0x5b, 0x01, 0xfb, 0x40, 0x43, 0x70, 0x31, 0xe4, 0x14, 0x4b, 0x4f, 0x77, 0x74, 0x26, 0xa7,
|
||||
0x5a, 0xfa, 0xbb, 0x03, 0x33, 0x41, 0xd5, 0xf0, 0x5f, 0x04, 0x38, 0x03, 0x52, 0x81, 0xfd, 0xa0,
|
||||
0x41, 0xb8, 0x30, 0x72, 0x94, 0x25, 0xaf, 0x5b, 0x3c, 0x3b, 0x51, 0xd3, 0x7c, 0x5d, 0xe1, 0xf9,
|
||||
0x88, 0x42, 0xe6, 0xb1, 0x8a, 0xf4, 0x67, 0x07, 0x6a, 0x82, 0xaf, 0x21, 0xbc, 0x18, 0x71, 0xca,
|
||||
0xa4, 0x57, 0x3b, 0x7e, 0x93, 0x60, 0x6d, 0xe8, 0x2d, 0x8e, 0x9d, 0xa4, 0x69, 0xbb, 0x6e, 0xf3,
|
||||
0x6c, 0x45, 0xed, 0xf3, 0x0d, 0x85, 0xc5, 0xa3, 0x13, 0x39, 0xcd, 0xd2, 0xd5, 0x9d, 0x9f, 0x29,
|
||||
0xa8, 0x1e, 0xfe, 0x88, 0x40, 0x66, 0xb0, 0x2a, 0xf4, 0x1f, 0x07, 0x48, 0x02, 0xb6, 0x81, 0xb6,
|
||||
0xe0, 0x76, 0xc8, 0x26, 0xd6, 0x9a, 0xde, 0xeb, 0x18, 0x4f, 0x4a, 0xb4, 0x37, 0x37, 0x56, 0x96,
|
||||
0xbe, 0xee, 0xf0, 0x4c, 0x44, 0x35, 0xf3, 0x57, 0x05, 0xfe, 0x83, 0x00, 0x61, 0xc0, 0x28, 0x50,
|
||||
0x1e, 0xbc, 0x08, 0x71, 0xc6, 0xa4, 0x52, 0xfb, 0x7d, 0x83, 0x61, 0xa1, 0xe8, 0x78, 0x4e, 0xa2,
|
||||
0xb4, 0x79, 0xb7, 0x62, 0xf6, 0xa9, 0x86, 0xfe, 0xe2, 0xc0, 0x49, 0x90, 0x36, 0xec, 0x16, 0xcd,
|
||||
0xce, 0xd5, 0x94, 0x5f, 0x2f, 0x78, 0x1c, 0x22, 0x89, 0xd9, 0xa6, 0xda, 0xfa, 0xdb, 0x03, 0x1b,
|
||||
0x41, 0xcb, 0x70, 0x57, 0x64, 0x3e, 0xab, 0x50, 0x7f, 0x7c, 0x20, 0x21, 0xd8, 0x18, 0x5a, 0x8a,
|
||||
0xbb, 0x27, 0x33, 0x5a, 0x95, 0xfb, 0x2f, 0x03, 0x5c, 0x01, 0xf9, 0xc0, 0x42, 0xd0, 0x31, 0x9c,
|
||||
0x14, 0x69, 0xcf, 0x6e, 0xd4, 0x2c, 0x5f, 0x5d, 0xf8, 0x39, 0x82, 0x92, 0xe1, 0xad, 0x88, 0x7d,
|
||||
0xa6, 0xa1, 0xba, 0xf8, 0x73, 0x02, 0xa5, 0xc1, 0xbb, 0x10, 0x73, 0x4c, 0x25, 0xf5, 0xdb, 0x07,
|
||||
0x1b, 0x42, 0x8b, 0x71, 0xa7, 0x64, 0x7a, 0xab, 0x63, 0x3f, 0x69, 0xd0, 0x2e, 0xdc, 0x1c, 0x59,
|
||||
0xc9, 0xfa, 0xd6, 0xc3, 0x1e, 0xd1, 0xc8, 0x5c, 0x56, 0xb9, 0xfe, 0xf2, 0xc0, 0x45, 0x90, 0x33,
|
||||
0x2c, 0x15, 0xdd, 0xcf, 0x19, 0x94, 0x0a, 0xef, 0x47, 0x0c, 0x32, 0x85, 0xd5, 0xa3, 0x1f, 0x39,
|
||||
0xc8, 0x12, 0xd6, 0x8d, 0x9e, 0xe5, 0xa8, 0x4b, 0x3e, 0xb7, 0x50, 0x76, 0xbc, 0x26, 0xf1, 0xda,
|
||||
0xc4, 0x5b, 0x13, 0x7b, 0x4d, 0xe3, 0x75, 0x89, 0xe7, 0x26, 0xca, 0x9a, 0xd7, 0x2b, 0x1e, 0x9f,
|
||||
0x48, 0x68, 0x36, 0xae, 0x96, 0xfc, 0x6e, 0xc1, 0xec, 0x50, 0x4d, 0xfc, 0x35, 0x81, 0xd7, 0x20,
|
||||
0x5e, 0x98, 0x38, 0x6a, 0x92, 0xaf, 0x2d, 0xbc, 0x1d, 0xb1, 0xc9, 0xb4, 0x56, 0xf7, 0x7e, 0xc6,
|
||||
0xa0, 0x52, 0xf8, 0x3d, 0x82, 0x91, 0xa1, 0xac, 0x78, 0x7d, 0xe2, 0xa1, 0x89, 0xb8, 0x66, 0xf2,
|
||||
0xaa, 0xc5, 0xbf, 0x13, 0x30, 0x0d, 0xd4, 0x05, 0x9f, 0x43, 0x28, 0x31, 0xde, 0x94, 0x58, 0x6f,
|
||||
0x7a, 0xac, 0x23, 0x3d, 0xd9, 0xd1, 0x9a, 0xdc, 0x6b, 0x19, 0xef, 0x4a, 0xcc, 0x37, 0x15, 0xd6,
|
||||
0x8f, 0x1e, 0xe4, 0x08, 0x4b, 0x46, 0xb7, 0x72, 0xf6, 0xa5, 0x86, 0xfb, 0x22, 0xc3, 0x59, 0x91,
|
||||
0xfa, 0xec, 0x43, 0x0d, 0xf1, 0xc5, 0x84, 0x53, 0x23, 0x7d, 0xd9, 0xe1, 0x9a, 0xc8, 0x6b, 0x16,
|
||||
0xaf, 0x4e, 0xfc, 0x34, 0x41, 0xd7, 0x70, 0x5e, 0xa4, 0x38, 0x7b, 0x52, 0xa3, 0x7d, 0xb9, 0xe1,
|
||||
0xb2, 0xc8, 0x75, 0x96, 0xa7, 0x2e, 0xfa, 0x9c, 0x43, 0x29, 0xf1, 0xde, 0xc4, 0x58, 0x53, 0x7a,
|
||||
0xbd, 0xe3, 0x31, 0x89, 0xd4, 0x66, 0xdf, 0x6a, 0xd8, 0x2f, 0x1a, 0x9c, 0x0b, 0x29, 0xc7, 0x5e,
|
||||
0xd2, 0xb8, 0x5d, 0xb2, 0xb9, 0xb5, 0xb2, 0xf7, 0x35, 0x86, 0x97, 0x22, 0xee, 0x99, 0x8c, 0x6a,
|
||||
0xe5, 0xef, 0x0b, 0x0c, 0x07, 0x45, 0xc2, 0xb3, 0x11, 0xb5, 0xcc, 0x77, 0x15, 0xe6, 0x8f, 0x0a,
|
||||
0xe4, 0x07, 0x0b, 0x42, 0x87, 0x71, 0xa2, 0xa4, 0x79, 0xbb, 0x62, 0xf3, 0x69, 0x85, 0xee, 0xe3,
|
||||
0x0c, 0x49, 0xc5, 0xf6, 0xd3, 0x06, 0xdd, 0xc2, 0xd9, 0x91, 0x9a, 0xec, 0x6b, 0x0d, 0xef, 0x45,
|
||||
0x8c, 0x33, 0x25, 0xd5, 0xdb, 0x1f, 0x1b, 0x48, 0x0b, 0x76, 0x87, 0x66, 0xe2, 0xaa, 0xc9, 0xbf,
|
||||
0x16, 0xf0, 0x0e, 0xc4, 0x04, 0x53, 0x43, 0x7d, 0xf1, 0xe1, 0x84, 0x48, 0x63, 0x76, 0xa9, 0xe6,
|
||||
0xfe, 0xca, 0xc0, 0x57, 0x10, 0x3e, 0x8c, 0x10, 0x65, 0xcc, 0x2b, 0x15, 0xdf, 0x4f, 0x18, 0x34,
|
||||
0x0a, 0x97, 0x47, 0x2e, 0xb2, 0x9c, 0x75, 0xa9, 0xe7, 0x3e, 0xca, 0x90, 0x57, 0x2c, 0x3e, 0x9d,
|
||||
0xd0, 0x69, 0x9c, 0x2e, 0xe9, 0xdc, 0x4e, 0xd9, 0xf4, 0x5a, 0xc7, 0x7b, 0x12, 0xa3, 0x4d, 0xb9,
|
||||
0xf5, 0xb2, 0xc7, 0x35, 0x92, 0x97, 0x2d, 0xae, 0x9d, 0xbc, 0x69, 0xb1, 0xee, 0xf4, 0x4c, 0x47,
|
||||
0x75, 0xf2, 0xa7, 0x05, 0xba, 0x83, 0x33, 0x21, 0xd5, 0xd8, 0x5f, 0x1a, 0xb8, 0x0b, 0x32, 0x87,
|
||||
0x55, 0xa2, 0xbf, 0x39, 0xb0, 0x12, 0xf4, 0x0d, 0x87, 0x45, 0xa2, 0xb3, 0x39, 0xb5, 0xd2, 0xf7,
|
||||
0x1d, 0x86, 0x89, 0xa2, 0xe6, 0xf9, 0x8a, 0xc2, 0xe7, 0x11, 0x8a, 0x8c, 0x67, 0x25, 0xea, 0x9b,
|
||||
0x0f, 0x2b, 0x44, 0x1f, 0x73, 0x48, 0x25, 0xf6, 0x9b, 0x06, 0xeb, 0x42, 0xcf, 0x71, 0x94, 0x24,
|
||||
0x6f, 0x5b, 0x6c, 0x3b, 0x6d, 0xd3, 0x6d, 0x9d, 0xed, 0xa9, 0x8d, 0xbe, 0xe5, 0xb0, 0x4b, 0x34,
|
||||
0x37, 0x57, 0x56, 0xbe, 0xbe, 0xf0, 0x70, 0x44, 0x24, 0x33, 0x5b, 0x55, 0xfb, 0x7f, 0x03, 0x60,
|
||||
0x01, 0xe8, 0x00, 0x4e, 0x80, 0x34, 0x60, 0x17, 0x68, 0x0e, 0xae, 0x84, 0x7c, 0x63, 0x61, 0xe9,
|
||||
0xe8, 0x4e, 0xce, 0xb4, 0x54, 0x77, 0x7f, 0x66, 0xa0, 0x2a, 0xf8, 0x1f, 0x02, 0x88, 0x01, 0xa6,
|
||||
0x80, 0x7a, 0xe0, 0x23, 0x08, 0x19, 0xc6, 0x8a, 0xd2, 0xe7, 0x1d, 0x8a, 0x89, 0xa7, 0x26, 0xfa,
|
||||
0x9a, 0xc3, 0x2b, 0x11, 0xdf, 0x4c, 0x58, 0x35, 0xfa, 0x97, 0x03, 0x2e, 0x81, 0xdc, 0x60, 0x59,
|
||||
0xe8, 0x3a, 0xce, 0x93, 0x14, 0x6d, 0xcf, 0x6d, 0x94, 0x2d, 0xaf, 0x5d, 0xbc, 0x39, 0xb1, 0xd2,
|
||||
0xf4, 0x5d, 0x87, 0x79, 0xa2, 0xa2, 0xf9, 0xb9, 0x82, 0xf2, 0xe1, 0x85, 0x88, 0x63, 0x26, 0xa9,
|
||||
0xda, 0xfe, 0xdb, 0x00, 0x5b, 0x40, 0x3b, 0x70, 0x13, 0x64, 0x0d, 0xeb, 0x45, 0x8f, 0x73, 0x24,
|
||||
0x25, 0xdb, 0x5b, 0x1b, 0x7b, 0x4b, 0x63, 0x77, 0x69, 0xe6, 0xae, 0xca, 0xfc, 0x57, 0x01, 0xfe,
|
||||
0x80, 0x40, 0x60, 0x30, 0x28, 0x14, 0x1e, 0x8f, 0x48, 0x64, 0x36, 0xab, 0x56, 0xff, 0x7e, 0xc0,
|
||||
0x20, 0x50, 0x18, 0x3c, 0x0a, 0x91, 0xc7, 0x2c, 0x52, 0x9d, 0xfd, 0xa9, 0x81, 0xbe, 0xe0, 0x70,
|
||||
0x48, 0x24, 0x36, 0x9b, 0x56, 0xeb, 0x7e, 0xcf, 0x60, 0x54, 0x28, 0x3f, 0x5e, 0x90, 0x38, 0x6c,
|
||||
0x12, 0xad, 0xcd, 0xbd, 0x95, 0xb1, 0xaf, 0x34, 0x7c, 0x17, 0x61, 0xce, 0xa8, 0x54, 0x7e, 0xbf,
|
||||
0x60, 0x70, 0x28, 0x24, 0x1e, 0x9b, 0x48, 0x6b, 0x76, 0xaf, 0x66, 0xfc, 0x2a, 0xc1, 0xdf, 0x10,
|
||||
0x58, 0x0c, 0x3a, 0x85, 0xd3, 0x23, 0x1d, 0xd9, 0xc9, 0x9a, 0xd6, 0xeb, 0x1e, 0xcf, 0x48, 0x54,
|
||||
0x36, 0xbf, 0x56, 0xf0, 0x3e, 0xc4, 0x10, 0x53, 0x4c, 0x3d, 0xf5, 0xd1, 0x87, 0x1c, 0x62, 0x89,
|
||||
0xe9, 0xa6, 0xce, 0xfa, 0xd4, 0x43, 0x1f, 0x71, 0xc8, 0x24, 0x56, 0x9b, 0x7e, 0xeb, 0x60, 0x4f,
|
||||
0x68, 0x34, 0x2e, 0x97, 0x5c, 0x6e, 0xb9, 0xec, 0x72, 0xcd, 0xe5, 0x95, 0x8b, 0x2f, 0x27, 0x5c,
|
||||
0x1a, 0xb9, 0xcb, 0x32, 0xd7, 0x55, 0x9e, 0xbf, 0x28, 0x70, 0x1e, 0xa4, 0x08, 0x7b, 0x46, 0xa3,
|
||||
0x72, 0xf9, 0xe5, 0x82, 0xcb, 0x21, 0x97, 0x58, 0x6e, 0xba, 0xac, 0x73, 0x3d, 0xe5, 0xd1, 0x8b,
|
||||
0x1c, 0x67, 0x49, 0xea, 0xb6, 0xcf, 0x36, 0xd4, 0x16, 0xdf, 0x4e, 0xd8, 0x34, 0x5a, 0x97, 0x7b,
|
||||
0x2e, 0xa3, 0x5c, 0x79, 0xf9, 0xe2, 0xc2, 0xc9, 0x91, 0x96, 0xec, 0x6e, 0xcd, 0xec, 0x55, 0x8d,
|
||||
0xff, 0x25, 0x80, 0x1b, 0x20, 0x0b, 0x58, 0x07, 0x7a, 0x82, 0xa3, 0x21, 0xb9, 0xd8, 0x72, 0xda,
|
||||
0xa5, 0x9b, 0x3b, 0x2b, 0x53, 0x5f, 0x7d, 0xf8, 0x21, 0x82, 0x98, 0x61, 0xaa, 0xa8, 0x7f, 0x3e,
|
||||
0xa0, 0x10, 0x78, 0x0c, 0x22, 0x85, 0xd9, 0xa3, 0x1a, 0xf9, 0xcb, 0x02, 0xd7, 0x41, 0x9e, 0xb0,
|
||||
0x68, 0x74, 0x2e, 0xa7, 0x5c, 0x7a, 0xb9, 0xe3, 0x32, 0xc9, 0xd5, 0x96, 0xdf, 0x2e, 0xd8, 0x1c,
|
||||
0x5a, 0x89, 0xfb, 0x26, 0xc3, 0x5a, 0xd1, 0xfb, 0x1c, 0x43, 0x49, 0xf1, 0xf6, 0xc4, 0x46, 0xd3,
|
||||
0x72, 0xdd, 0xe5, 0x99
|
||||
};
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MEMBER FUNCTIONS
|
||||
//**************************************************************************
|
||||
@ -406,6 +562,24 @@ void cdicdic_device::play_xa_group(const uint8_t coding, const uint8_t *data)
|
||||
}
|
||||
}
|
||||
|
||||
void cdicdic_device::play_cdda_sector(const uint8_t *data)
|
||||
{
|
||||
m_dmadac[0]->set_frequency(44100);
|
||||
m_dmadac[1]->set_frequency(44100);
|
||||
m_dmadac[0]->set_volume(0x100);
|
||||
m_dmadac[1]->set_volume(0x100);
|
||||
|
||||
int16_t samples[2][2352/4];
|
||||
for (uint16_t i = 0; i < 2352/4; i++)
|
||||
{
|
||||
samples[0][i] = (int16_t)((data[(i * 4) + 1] << 8) | data[(i * 4) + 0]);
|
||||
samples[1][i] = (int16_t)((data[(i * 4) + 3] << 8) | data[(i * 4) + 2]);
|
||||
}
|
||||
|
||||
m_dmadac[0]->transfer(0, 1, 1, SECTOR_SIZE/4, samples[0]);
|
||||
m_dmadac[1]->transfer(0, 1, 1, SECTOR_SIZE/4, samples[1]);
|
||||
}
|
||||
|
||||
void cdicdic_device::play_audio_sector(const uint8_t coding, const uint8_t *data)
|
||||
{
|
||||
if ((coding & CODING_CHAN_MASK) > CODING_STEREO || (coding & CODING_BPS_MASK) == CODING_BPS_MPEG || (coding & CODING_RATE_MASK) == CODING_RATE_RESV)
|
||||
@ -533,6 +707,7 @@ void cdicdic_device::process_audio_map()
|
||||
else
|
||||
{
|
||||
m_decode_addr = 0xffff;
|
||||
m_audio_sector_counter = m_audio_format_sectors;
|
||||
}
|
||||
|
||||
if (was_decoding)
|
||||
@ -550,6 +725,63 @@ void cdicdic_device::update_interrupt_state()
|
||||
m_intreq_callback(interrupt_active ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
void cdicdic_device::descramble_sector(uint8_t *buffer)
|
||||
{
|
||||
for (uint32_t i = 12; i < SECTOR_SIZE; i++)
|
||||
{
|
||||
buffer[i] ^= s_sector_scramble[i];
|
||||
}
|
||||
}
|
||||
|
||||
bool cdicdic_device::is_valid_sector(const uint8_t *buffer)
|
||||
{
|
||||
const uint32_t real_lba = m_curr_lba + 150;
|
||||
const uint8_t mins = real_lba / (60 * 75);
|
||||
const uint8_t secs = (real_lba / 75) % 60;
|
||||
const uint8_t frac = real_lba % 75;
|
||||
const uint8_t mins_bcd = ((mins / 10) << 4) | (mins % 10);
|
||||
const uint8_t secs_bcd = ((secs / 10) << 4) | (secs % 10);
|
||||
const uint8_t frac_bcd = ((frac / 10) << 4) | (frac % 10);
|
||||
|
||||
// Verify MSF
|
||||
if (mins_bcd != buffer[SECTOR_MINUTES] || secs_bcd != buffer[SECTOR_SECONDS] || frac_bcd != buffer[SECTOR_FRACS])
|
||||
{
|
||||
LOGMASKED(LOG_SECTORS, "Not valid sector, MSF (%02x:%02x:%02x vs. %02x:%02x:%02x\n", mins_bcd, secs_bcd, frac_bcd, buffer[SECTOR_MINUTES], buffer[SECTOR_SECONDS], buffer[SECTOR_FRACS]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify mode
|
||||
if (buffer[SECTOR_MODE] != 1 && buffer[SECTOR_MODE] != 2)
|
||||
{
|
||||
LOGMASKED(LOG_SECTORS, "Not valid sector, mode %02x\n", buffer[SECTOR_MODE]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify duplicate info
|
||||
if (buffer[SECTOR_FILE1] != buffer[SECTOR_FILE2])
|
||||
{
|
||||
LOGMASKED(LOG_SECTORS, "Not valid sector, file %02x vs. %02x\n", buffer[SECTOR_FILE1], buffer[SECTOR_FILE2]);
|
||||
return false;
|
||||
}
|
||||
if (buffer[SECTOR_CHAN1] != buffer[SECTOR_CHAN2])
|
||||
{
|
||||
LOGMASKED(LOG_SECTORS, "Not valid sector, channel %02x vs. %02x\n", buffer[SECTOR_CHAN1], buffer[SECTOR_CHAN2]);
|
||||
return false;
|
||||
}
|
||||
if (buffer[SECTOR_SUBMODE1] != buffer[SECTOR_SUBMODE2])
|
||||
{
|
||||
LOGMASKED(LOG_SECTORS, "Not valid sector, channel %02x vs. %02x\n", buffer[SECTOR_SUBMODE1], buffer[SECTOR_SUBMODE2]);
|
||||
return false;
|
||||
}
|
||||
if (buffer[SECTOR_CODING1] != buffer[SECTOR_CODING2])
|
||||
{
|
||||
LOGMASKED(LOG_SECTORS, "Not valid sector, coding %02x vs. %02x\n", buffer[SECTOR_CODING1], buffer[SECTOR_CODING2]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cdicdic_device::is_mode2_sector_selected(const uint8_t *buffer)
|
||||
{
|
||||
if ((buffer[SECTOR_FILE2] << 8) != m_file)
|
||||
@ -701,6 +933,38 @@ void cdicdic_device::process_disc_sector()
|
||||
uint8_t buffer[2560] = { 0 };
|
||||
cdrom_read_data(m_cd, m_curr_lba, buffer, CD_TRACK_RAW_DONTCARE);
|
||||
|
||||
// Detect (badly) if we're dealing with a byteswapped loose-bin image
|
||||
if (buffer[0] == 0xff && buffer[1] == 0x00)
|
||||
{
|
||||
LOGMASKED(LOG_SECTORS, "Byteswapping\n");
|
||||
m_cd_byteswap = true;
|
||||
}
|
||||
|
||||
if (m_cd_byteswap)
|
||||
{
|
||||
for (uint16_t i = 0; i < 2560; i += 2)
|
||||
{
|
||||
std::swap(buffer[i], buffer[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_valid_sector(buffer))
|
||||
{
|
||||
uint8_t descramble_buffer[2560];
|
||||
memcpy(descramble_buffer, buffer, sizeof(descramble_buffer));
|
||||
LOGMASKED(LOG_SECTORS, "Sector seems to be encoded, attempting to apply descrambling\n");
|
||||
descramble_sector(descramble_buffer);
|
||||
|
||||
if (!is_valid_sector(descramble_buffer))
|
||||
{
|
||||
LOGMASKED(LOG_SECTORS, "Sector remains invalid after descrambling, giving up and proceeding as normal\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(buffer, descramble_buffer, sizeof(descramble_buffer));
|
||||
}
|
||||
}
|
||||
|
||||
LOGMASKED(LOG_SECTORS, "Sector header data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
buffer[ 0], buffer[ 1], buffer[ 2], buffer[ 3], buffer[ 4], buffer[ 5], buffer[ 6], buffer[ 7], buffer[ 8], buffer[ 9],
|
||||
buffer[10], buffer[11], buffer[12], buffer[13], buffer[14], buffer[15], buffer[16], buffer[17], buffer[18], buffer[19],
|
||||
@ -724,17 +988,116 @@ void cdicdic_device::process_disc_sector()
|
||||
play_audio_sector(buffer[SECTOR_CODING2], buffer + SECTOR_DATA);
|
||||
}
|
||||
}
|
||||
else if (m_disc_mode == DISC_CDDA)
|
||||
{
|
||||
m_audio_sector_counter = 2;
|
||||
m_decoding_audio_map = false;
|
||||
|
||||
play_cdda_sector(buffer);
|
||||
|
||||
if (frac != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate subcode data
|
||||
uint8_t subcode_buffer[96];
|
||||
memset(subcode_buffer, 0, sizeof(subcode_buffer));
|
||||
|
||||
if (m_disc_command == DISC_TOC)
|
||||
if (m_disc_mode == DISC_TOC)
|
||||
{
|
||||
uint32_t entry_index = 0;
|
||||
for (; buffer[entry_index * 5] != 0; entry_index++);
|
||||
uint8_t *toc_buffer = buffer;
|
||||
const cdrom_toc *toc = cdrom_get_toc(m_cd);
|
||||
uint32_t entry_count = 0;
|
||||
|
||||
uint8_t *toc_data = &buffer[(m_curr_lba % entry_index) * 5];
|
||||
// Determine total frame count for data, and total audio track count
|
||||
uint32_t frames = toc->tracks[0].pregap;
|
||||
int audio_tracks = 0;
|
||||
int other_tracks = 0;
|
||||
uint32_t audio_starts[CD_MAX_TRACKS];
|
||||
for (uint32_t i = 0; i < toc->numtrks; i++)
|
||||
{
|
||||
if (toc->tracks[i].trktype != CD_TRACK_AUDIO)
|
||||
{
|
||||
frames += toc->tracks[i].frames + toc->tracks[i].extraframes;
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_starts[audio_tracks++] = toc->tracks[i].logframeofs;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine last-frame MSF
|
||||
const uint8_t total_mins = frames / (60 * 75);
|
||||
const uint8_t total_secs = (frames / 75) % 60;
|
||||
const uint8_t total_frac = frames % 75;
|
||||
|
||||
// Specify any audio tracks first
|
||||
for (int i = 0; i < audio_tracks; i++)
|
||||
{
|
||||
const uint8_t audio_mins = audio_starts[i] / (60 * 75);
|
||||
const uint8_t audio_secs = (audio_starts[i] / 75) % 60;
|
||||
const uint8_t audio_frac = audio_starts[i] % 75;
|
||||
const uint8_t audio_mins_bcd = ((audio_mins / 10) << 4) | (audio_mins % 10);
|
||||
const uint8_t audio_secs_bcd = ((audio_secs / 10) << 4) | (audio_secs % 10);
|
||||
const uint8_t audio_frac_bcd = ((audio_frac / 10) << 4) | (audio_frac % 10);
|
||||
|
||||
const uint8_t track_bcd = (((i + 1) / 10) << 4) | ((i + 1) % 10);
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
*toc_buffer++ = 0x01; // Track type (CD-DA)
|
||||
*toc_buffer++ = track_bcd; // Track number
|
||||
*toc_buffer++ = audio_mins_bcd;
|
||||
*toc_buffer++ = audio_secs_bcd;
|
||||
*toc_buffer++ = audio_frac_bcd;
|
||||
entry_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// Packet A0 (lead-in)
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
*toc_buffer++ = (other_tracks > 0) ? 0x41 : 0x01;
|
||||
*toc_buffer++ = 0xa0;
|
||||
*toc_buffer++ = 0x01;
|
||||
*toc_buffer++ = (other_tracks > 0) ? 0x10 : 0x00;
|
||||
*toc_buffer++ = 0x00;
|
||||
entry_count++;
|
||||
}
|
||||
|
||||
// Packet A1
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
*toc_buffer++ = (audio_tracks > 0) ? 0x01 : 0x41;
|
||||
*toc_buffer++ = 0xa1;
|
||||
if (audio_tracks > 0)
|
||||
{
|
||||
uint8_t last_audio_track = (uint8_t)(audio_tracks - 1);
|
||||
*toc_buffer++ = ((last_audio_track / 10) << 4) | (last_audio_track % 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
*toc_buffer++ = 0x00;
|
||||
}
|
||||
*toc_buffer++ = 0x00;
|
||||
*toc_buffer++ = 0x00;
|
||||
entry_count++;
|
||||
}
|
||||
|
||||
// Packet A2 (lead-out)
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
*toc_buffer++ = (audio_tracks > 0) ? 0x01 : 0x41;
|
||||
*toc_buffer++ = 0xa2;
|
||||
*toc_buffer++ = ((total_mins / 10) << 4) | (total_mins % 10);
|
||||
*toc_buffer++ = ((total_secs / 10) << 4) | (total_secs % 10);
|
||||
*toc_buffer++ = ((total_frac / 10) << 4) | (total_frac % 10);
|
||||
entry_count++;
|
||||
}
|
||||
|
||||
uint8_t *toc_data = &buffer[(m_curr_lba % entry_count) * 5];
|
||||
|
||||
subcode_buffer[SUBCODE_Q_CONTROL] = toc_data[0];
|
||||
subcode_buffer[SUBCODE_Q_TRACK] = 0x00;
|
||||
@ -751,7 +1114,7 @@ void cdicdic_device::process_disc_sector()
|
||||
}
|
||||
else
|
||||
{
|
||||
subcode_buffer[SUBCODE_Q_CONTROL] = (m_disc_command == DISC_CDDA ? 0x01 : 0x41);
|
||||
subcode_buffer[SUBCODE_Q_CONTROL] = (m_disc_mode == DISC_CDDA ? 0x01 : 0x41);
|
||||
subcode_buffer[SUBCODE_Q_TRACK] = 0x01;
|
||||
subcode_buffer[SUBCODE_Q_INDEX] = 0x01;
|
||||
subcode_buffer[SUBCODE_Q_MODE1_MINS] = mins_bcd;
|
||||
@ -1096,7 +1459,6 @@ cdicdic_device::cdicdic_device(const machine_config &mconfig, const char *tag, d
|
||||
, m_memory_space(*this, ":maincpu", AS_PROGRAM)
|
||||
, m_dmadac(*this, ":dac%u", 1U)
|
||||
, m_scc(*this, ":maincpu")
|
||||
, m_cdda(*this, ":cdda")
|
||||
, m_cdrom_dev(*this, ":cdrom")
|
||||
, m_clock2(clock)
|
||||
{
|
||||
@ -1176,6 +1538,8 @@ void cdicdic_device::device_reset()
|
||||
m_interrupt_vector = 0x0f;
|
||||
m_data_buffer = 0;
|
||||
|
||||
m_cd_byteswap = false;
|
||||
|
||||
m_disc_command = 0;
|
||||
m_disc_mode = 0;
|
||||
m_disc_spinup_counter = 0;
|
||||
@ -1190,13 +1554,11 @@ void cdicdic_device::device_reset()
|
||||
{
|
||||
// Console case (has CDROM device)
|
||||
m_cd = m_cdrom_dev->get_cdrom_file();
|
||||
m_cdda->set_cdrom(m_cd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Arcade case
|
||||
m_cd = cdrom_open(machine().rom_load().get_disk_handle(":cdrom"));
|
||||
m_cdda->set_cdrom(m_cd);
|
||||
}
|
||||
|
||||
m_audio_timer->adjust(attotime::from_hz(75), 0, attotime::from_hz(75));
|
||||
|
@ -86,6 +86,9 @@ private:
|
||||
|
||||
SECTOR_HEADER = 12,
|
||||
|
||||
SECTOR_MINUTES = 12,
|
||||
SECTOR_SECONDS = 13,
|
||||
SECTOR_FRACS = 14,
|
||||
SECTOR_MODE = 15,
|
||||
|
||||
SECTOR_FILE1 = 16,
|
||||
@ -153,7 +156,6 @@ private:
|
||||
required_address_space m_memory_space;
|
||||
required_device_array<dmadac_sound_device, 2> m_dmadac;
|
||||
required_device<scc68070_device> m_scc;
|
||||
required_device<cdda_device> m_cdda;
|
||||
optional_device<cdrom_image_device> m_cdrom_dev;
|
||||
|
||||
uint32_t m_clock2;
|
||||
@ -173,6 +175,7 @@ private:
|
||||
uint16_t m_data_buffer; // CDIC Data Buffer Register (0x303ffe)
|
||||
|
||||
cdrom_file *m_cd;
|
||||
bool m_cd_byteswap;
|
||||
|
||||
emu_timer *m_sector_timer;
|
||||
uint8_t m_disc_command;
|
||||
@ -195,8 +198,11 @@ private:
|
||||
void play_raw_group(const uint8_t *data);
|
||||
void play_xa_group(const uint8_t coding, const uint8_t *data);
|
||||
void play_audio_sector(const uint8_t coding, const uint8_t *data);
|
||||
void play_cdda_sector(const uint8_t *data);
|
||||
void process_audio_map();
|
||||
|
||||
void descramble_sector(uint8_t *buffer);
|
||||
bool is_valid_sector(const uint8_t *buffer);
|
||||
bool is_mode2_sector_selected(const uint8_t *buffer);
|
||||
bool is_mode2_audio_selected(const uint8_t *buffer);
|
||||
|
||||
@ -219,6 +225,7 @@ private:
|
||||
static const int16_t s_xa_filter_coef[4][2];
|
||||
static const int32_t s_samples_per_sector;
|
||||
static const uint16_t s_crc_ccitt_table[256];
|
||||
static const uint8_t s_sector_scramble[2448];
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,178 +27,22 @@ TODO:
|
||||
#pragma once
|
||||
|
||||
|
||||
#define MCD212_CURCNT_COLOR 0x00000f // Cursor color
|
||||
#define MCD212_CURCNT_CUW 0x008000 // Cursor width
|
||||
#define MCD212_CURCNT_COF 0x070000 // Cursor off time
|
||||
#define MCD212_CURCNT_COF_SHIFT 16
|
||||
#define MCD212_CURCNT_CON 0x280000 // Cursor on time
|
||||
#define MCD212_CURCNT_CON_SHIFT 19
|
||||
#define MCD212_CURCNT_BLKC 0x400000 // Blink type
|
||||
#define MCD212_CURCNT_EN 0x800000 // Cursor enable
|
||||
|
||||
#define MCD212_ICM_CS 0x400000 // CLUT select
|
||||
#define MCD212_ICM_NR 0x080000 // Number of region flags
|
||||
#define MCD212_ICM_EV 0x040000 // External video
|
||||
#define MCD212_ICM_MODE2 0x000f00 // Plane 2
|
||||
#define MCD212_ICM_MODE2_SHIFT 8
|
||||
#define MCD212_ICM_MODE1 0x00000f // Plane 1
|
||||
#define MCD212_ICM_MODE1_SHIFT 0
|
||||
|
||||
#define MCD212_TCR_DISABLE_MX 0x800000 // Mix disable
|
||||
#define MCD212_TCR_TB 0x000f00 // Plane B
|
||||
#define MCD212_TCR_TB_SHIFT 8
|
||||
#define MCD212_TCR_TA 0x00000f // Plane A
|
||||
#define MCD212_TCR_COND_1 0x0 // Transparent if: Always (Plane Disabled)
|
||||
#define MCD212_TCR_COND_KEY_1 0x1 // Transparent if: Color Key = True
|
||||
#define MCD212_TCR_COND_XLU_1 0x2 // Transparent if: Transparency Bit = 1
|
||||
#define MCD212_TCR_COND_RF0_1 0x3 // Transparent if: Region Flag 0 = True
|
||||
#define MCD212_TCR_COND_RF1_1 0x4 // Transparent if: Region Flag 1 = True
|
||||
#define MCD212_TCR_COND_RF0KEY_1 0x5 // Transparent if: Region Flag 0 = True || Color Key = True
|
||||
#define MCD212_TCR_COND_RF1KEY_1 0x6 // Transparent if: Region Flag 1 = True || Color Key = True
|
||||
#define MCD212_TCR_COND_UNUSED0 0x7 // Unused
|
||||
#define MCD212_TCR_COND_0 0x8 // Transparent if: Never (No Transparent Area)
|
||||
#define MCD212_TCR_COND_KEY_0 0x9 // Transparent if: Color Key = False
|
||||
#define MCD212_TCR_COND_XLU_0 0xa // Transparent if: Transparency Bit = 0
|
||||
#define MCD212_TCR_COND_RF0_0 0xb // Transparent if: Region Flag 0 = False
|
||||
#define MCD212_TCR_COND_RF1_0 0xc // Transparent if: Region Flag 1 = False
|
||||
#define MCD212_TCR_COND_RF0KEY_0 0xd // Transparent if: Region Flag 0 = False && Color Key = False
|
||||
#define MCD212_TCR_COND_RF1KEY_0 0xe // Transparent if: Region Flag 1 = False && Color Key = False
|
||||
#define MCD212_TCR_COND_UNUSED1 0xf // Unused
|
||||
|
||||
#define MCD212_POR_AB 0 // Plane A in front of Plane B
|
||||
#define MCD212_POR_BA 1 // Plane B in front of Plane A
|
||||
|
||||
#define MCD212_RC_X 0x0003ff // X position
|
||||
#define MCD212_RC_WF 0x00fc00 // Weight position
|
||||
#define MCD212_RC_WF_SHIFT 10
|
||||
#define MCD212_RC_RF 0x010000 // Region flag
|
||||
#define MCD212_RC_RF_SHIFT 16
|
||||
#define MCD212_RC_OP 0xf00000 // Operation
|
||||
#define MCD212_RC_OP_SHIFT 20
|
||||
|
||||
#define MCD212_CSR1W_ST 0x0002 // Standard
|
||||
#define MCD212_CSR1W_BE 0x0001 // Bus Error
|
||||
|
||||
#define MCD212_CSR2R_IT1 0x0004 // Interrupt 1
|
||||
#define MCD212_CSR2R_IT2 0x0002 // Interrupt 2
|
||||
#define MCD212_CSR2R_BE 0x0001 // Bus Error
|
||||
|
||||
#define MCD212_DCR_DE 0x8000 // Display Enable
|
||||
#define MCD212_DCR_CF 0x4000 // Crystal Frequency
|
||||
#define MCD212_DCR_FD 0x2000 // Frame Duration
|
||||
#define MCD212_DCR_SM 0x1000 // Scan Mode
|
||||
#define MCD212_DCR_CM 0x0800 // Color Mode Ch.1/2
|
||||
#define MCD212_DCR_ICA 0x0200 // ICA Enable Ch.1/2
|
||||
#define MCD212_DCR_DCA 0x0100 // DCA Enable Ch.1/2
|
||||
|
||||
#define MCD212_DDR_FT 0x0300 // Display File Type
|
||||
#define MCD212_DDR_FT_BMP 0x0000 // Bitmap
|
||||
#define MCD212_DDR_FT_BMP2 0x0100 // Bitmap (alt.)
|
||||
#define MCD212_DDR_FT_RLE 0x0200 // Run-Length Encoded
|
||||
#define MCD212_DDR_FT_MOSAIC 0x0300 // Mosaic
|
||||
#define MCD212_DDR_MT 0x0c00 // Mosaic File Type
|
||||
#define MCD212_DDR_MT_2 0x0000 // 2x1
|
||||
#define MCD212_DDR_MT_4 0x0400 // 4x1
|
||||
#define MCD212_DDR_MT_8 0x0800 // 8x1
|
||||
#define MCD212_DDR_MT_16 0x0c00 // 16x1
|
||||
#define MCD212_DDR_MT_SHIFT 10
|
||||
|
||||
typedef uint8_t BYTE68K;
|
||||
typedef uint16_t WORD68K;
|
||||
typedef int16_t SWORD68K;
|
||||
|
||||
#define BYTE68K_MAX 255
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> mcd212_device
|
||||
|
||||
class mcd212_device : public device_t,
|
||||
public device_video_interface
|
||||
public device_video_interface
|
||||
{
|
||||
public:
|
||||
typedef device_delegate<void (int)> scanline_callback_delegate;
|
||||
|
||||
// construction/destruction
|
||||
mcd212_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
auto int_callback() { return m_int_callback.bind(); }
|
||||
|
||||
template <typename... T> void set_scanline_callback(T &&... args) { m_scanline_callback.set(std::forward<T>(args)...); }
|
||||
|
||||
// device members
|
||||
uint16_t regs_r(offs_t offset, uint16_t mem_mask = ~0);
|
||||
void regs_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
TIMER_CALLBACK_MEMBER( perform_scan );
|
||||
|
||||
bitmap_rgb32& get_bitmap() { return m_bitmap; }
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
struct channel_t
|
||||
{
|
||||
uint8_t csrr;
|
||||
uint16_t csrw;
|
||||
uint16_t dcr;
|
||||
uint16_t vsr;
|
||||
uint16_t ddr;
|
||||
uint16_t dcp;
|
||||
uint32_t dca;
|
||||
uint8_t clut_r[256];
|
||||
uint8_t clut_g[256];
|
||||
uint8_t clut_b[256];
|
||||
uint32_t image_coding_method;
|
||||
uint32_t transparency_control;
|
||||
uint32_t plane_order;
|
||||
uint32_t clut_bank;
|
||||
uint32_t transparent_color_a;
|
||||
uint32_t reserved0;
|
||||
uint32_t transparent_color_b;
|
||||
uint32_t mask_color_a;
|
||||
uint32_t reserved1;
|
||||
uint32_t mask_color_b;
|
||||
uint32_t dyuv_abs_start_a;
|
||||
uint32_t dyuv_abs_start_b;
|
||||
uint32_t reserved2;
|
||||
uint32_t cursor_position;
|
||||
uint32_t cursor_control;
|
||||
uint32_t cursor_pattern[16];
|
||||
uint32_t region_control[8];
|
||||
uint32_t backdrop_color;
|
||||
uint32_t mosaic_hold_a;
|
||||
uint32_t mosaic_hold_b;
|
||||
uint8_t weight_factor_a[768];
|
||||
uint8_t weight_factor_b[768];
|
||||
};
|
||||
|
||||
struct ab_t
|
||||
{
|
||||
//* Color limit array.
|
||||
BYTE68K limit[3 * BYTE68K_MAX];
|
||||
|
||||
//* Color clamp array.
|
||||
BYTE68K clamp[3 * BYTE68K_MAX];
|
||||
|
||||
//* U-to-B matrix array.
|
||||
SWORD68K matrixUB[BYTE68K_MAX + 1];
|
||||
|
||||
//* U-to-G matrix array.
|
||||
SWORD68K matrixUG[BYTE68K_MAX + 1];
|
||||
|
||||
//* V-to-G matrix array.
|
||||
SWORD68K matrixVG[BYTE68K_MAX + 1];
|
||||
|
||||
//* V-to-R matrix array.
|
||||
SWORD68K matrixVR[BYTE68K_MAX + 1];
|
||||
|
||||
//* Delta-Y decoding array.
|
||||
BYTE68K deltaY[BYTE68K_MAX + 1];
|
||||
|
||||
//* Delta-U/V decoding array.
|
||||
BYTE68K deltaUV[BYTE68K_MAX + 1];
|
||||
};
|
||||
void map(address_map &map);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -206,51 +50,196 @@ protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
uint8_t csr1_r();
|
||||
void csr1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint16_t dcr1_r(offs_t offset, uint16_t mem_mask = ~0);
|
||||
void dcr1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint16_t vsr1_r(offs_t offset, uint16_t mem_mask = ~0);
|
||||
void vsr1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint16_t ddr1_r(offs_t offset, uint16_t mem_mask = ~0);
|
||||
void ddr1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint16_t dca1_r(offs_t offset, uint16_t mem_mask = ~0);
|
||||
void dca1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
|
||||
uint8_t csr2_r();
|
||||
void csr2_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint16_t dcr2_r(offs_t offset, uint16_t mem_mask = ~0);
|
||||
void dcr2_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint16_t vsr2_r(offs_t offset, uint16_t mem_mask = ~0);
|
||||
void vsr2_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint16_t ddr2_r(offs_t offset, uint16_t mem_mask = ~0);
|
||||
void ddr2_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint16_t dca2_r(offs_t offset, uint16_t mem_mask = ~0);
|
||||
void dca2_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
CURCNT_COLOR = 0x00000f, // Cursor color
|
||||
CURCNT_CUW = 0x008000, // Cursor width
|
||||
CURCNT_COF = 0x070000, // Cursor off time
|
||||
CURCNT_COF_SHIFT = 16,
|
||||
CURCNT_CON = 0x280000, // Cursor on time
|
||||
CURCNT_CON_SHIFT = 19,
|
||||
CURCNT_BLKC = 0x400000, // Blink type
|
||||
CURCNT_EN = 0x800000, // Cursor enable
|
||||
|
||||
ICM_CS = 0x400000, // CLUT select
|
||||
ICM_NR = 0x080000, // Number of region flags
|
||||
ICM_NR_BIT = 19,
|
||||
ICM_EV = 0x040000, // External video
|
||||
ICM_MODE2 = 0x000f00, // Plane 2
|
||||
ICM_MODE2_SHIFT = 8,
|
||||
ICM_MODE1 = 0x00000f, // Plane 1
|
||||
ICM_MODE1_SHIFT = 0,
|
||||
|
||||
TCR_DISABLE_MX = 0x800000, // Mix disable
|
||||
TCR_TB = 0x000f00, // Plane B
|
||||
TCR_TB_SHIFT = 8,
|
||||
TCR_TA = 0x00000f, // Plane A
|
||||
TCR_COND_1 = 0x0, // Transparent if: Always (Plane Disabled)
|
||||
TCR_COND_KEY_1 = 0x1, // Transparent if: Color Key = True
|
||||
TCR_COND_XLU_1 = 0x2, // Transparent if: Transparency Bit = 1
|
||||
TCR_COND_RF0_1 = 0x3, // Transparent if: Region Flag 0 = True
|
||||
TCR_COND_RF1_1 = 0x4, // Transparent if: Region Flag 1 = True
|
||||
TCR_COND_RF0KEY_1 = 0x5, // Transparent if: Region Flag 0 = True || Color Key = True
|
||||
TCR_COND_RF1KEY_1 = 0x6, // Transparent if: Region Flag 1 = True || Color Key = True
|
||||
TCR_COND_UNUSED0 = 0x7, // Unused
|
||||
TCR_COND_0 = 0x8, // Transparent if: Never (No Transparent Area)
|
||||
TCR_COND_KEY_0 = 0x9, // Transparent if: Color Key = False
|
||||
TCR_COND_XLU_0 = 0xa, // Transparent if: Transparency Bit = 0
|
||||
TCR_COND_RF0_0 = 0xb, // Transparent if: Region Flag 0 = False
|
||||
TCR_COND_RF1_0 = 0xc, // Transparent if: Region Flag 1 = False
|
||||
TCR_COND_RF0KEY_0 = 0xd, // Transparent if: Region Flag 0 = False && Color Key = False
|
||||
TCR_COND_RF1KEY_0 = 0xe, // Transparent if: Region Flag 1 = False && Color Key = False
|
||||
TCR_COND_UNUSED1 = 0xf, // Unused
|
||||
|
||||
POR_AB = 0, // Plane A in front of Plane B
|
||||
POR_BA = 1, // Plane B in front of Plane A
|
||||
|
||||
RC_X = 0x0003ff, // X position
|
||||
RC_WF = 0x00fc00, // Weight position
|
||||
RC_WF_SHIFT = 10,
|
||||
RC_RF_BIT = 16, // Region flag bit
|
||||
RC_OP = 0xf00000, // Operation
|
||||
RC_OP_SHIFT = 20,
|
||||
|
||||
CSR1W_ST = 0x0002, // Standard
|
||||
CSR1W_BE = 0x0001, // Bus Error
|
||||
|
||||
CSR2R_IT1 = 0x0004, // Interrupt 1
|
||||
CSR2R_IT2 = 0x0002, // Interrupt 2
|
||||
CSR2R_BE = 0x0001, // Bus Error
|
||||
|
||||
DCR_DE = 0x8000, // Display Enable
|
||||
DCR_CF = 0x4000, // Crystal Frequency
|
||||
DCR_FD = 0x2000, // Frame Duration
|
||||
DCR_SM = 0x1000, // Scan Mode
|
||||
DCR_CM = 0x0800, // Color Mode Ch.1/2
|
||||
DCR_ICA = 0x0200, // ICA Enable Ch.1/2
|
||||
DCR_DCA = 0x0100, // DCA Enable Ch.1/2
|
||||
|
||||
DDR_FT = 0x0300, // Display File Type
|
||||
DDR_FT_BMP = 0x0000, // Bitmap
|
||||
DDR_FT_BMP2 = 0x0100, // Bitmap (alt.)
|
||||
DDR_FT_RLE = 0x0200, // Run-Length Encoded
|
||||
DDR_FT_MOSAIC = 0x0300, // Mosaic
|
||||
DDR_MT = 0x0c00, // Mosaic File Type
|
||||
DDR_MT_2 = 0x0000, // 2x1
|
||||
DDR_MT_4 = 0x0400, // 4x1
|
||||
DDR_MT_8 = 0x0800, // 8x1
|
||||
DDR_MT_16 = 0x0c00, // 16x1
|
||||
DDR_MT_SHIFT = 10
|
||||
};
|
||||
|
||||
uint8_t m_csrr[2];
|
||||
uint16_t m_csrw[2];
|
||||
uint16_t m_dcr[2];
|
||||
uint16_t m_vsr[2];
|
||||
uint16_t m_ddr[2];
|
||||
uint16_t m_dcp[2];
|
||||
uint32_t m_dca[2];
|
||||
uint32_t m_clut[256];
|
||||
uint32_t m_image_coding_method;
|
||||
uint32_t m_transparency_control;
|
||||
uint32_t m_plane_order;
|
||||
uint32_t m_clut_bank[2];
|
||||
uint32_t m_transparent_color[2];
|
||||
uint32_t m_mask_color[2];
|
||||
uint32_t m_dyuv_abs_start[2];
|
||||
uint32_t m_cursor_position;
|
||||
uint32_t m_cursor_control;
|
||||
uint32_t m_cursor_pattern[16];
|
||||
uint32_t m_region_control[8];
|
||||
uint32_t m_backdrop_color;
|
||||
uint32_t m_mosaic_hold[2];
|
||||
uint8_t m_weight_factor[2][768];
|
||||
|
||||
// DYUV color limit arrays.
|
||||
uint32_t m_dyuv_limit_r_lut[3 * 0xff];
|
||||
uint32_t m_dyuv_limit_g_lut[3 * 0xff];
|
||||
uint32_t m_dyuv_limit_b_lut[3 * 0xff];
|
||||
|
||||
// DYUV delta-Y decoding array
|
||||
uint8_t m_delta_y_lut[0x100];
|
||||
|
||||
// DYUV delta-UV decoding array
|
||||
uint8_t m_delta_uv_lut[0x100];
|
||||
|
||||
// DYUV U-to-B decoding array
|
||||
int16_t m_dyuv_u_to_b[0x100];
|
||||
|
||||
// U-to-G decoding array
|
||||
int16_t m_dyuv_u_to_g[0x100];
|
||||
|
||||
// V-to-G decoding array
|
||||
int16_t m_dyuv_v_to_g[0x100];
|
||||
|
||||
// V-to-R decoding array
|
||||
int16_t m_dyuv_v_to_r[0x100];
|
||||
|
||||
// interrupt callbacks
|
||||
devcb_write_line m_int_callback;
|
||||
|
||||
scanline_callback_delegate m_scanline_callback;
|
||||
|
||||
required_shared_ptr<uint16_t> m_planea;
|
||||
required_shared_ptr<uint16_t> m_planeb;
|
||||
|
||||
// internal state
|
||||
channel_t m_channel[2];
|
||||
emu_timer *m_scan_timer;
|
||||
uint8_t m_region_flag_0[768];
|
||||
uint8_t m_region_flag_1[768];
|
||||
|
||||
bitmap_rgb32 m_bitmap;
|
||||
bool m_region_flag[2][768];
|
||||
int m_ica_height;
|
||||
int m_total_height;
|
||||
|
||||
static const uint32_t s_4bpp_color[16];
|
||||
|
||||
ab_t m_ab;
|
||||
|
||||
uint8_t get_weight_factor(const uint32_t region_idx);
|
||||
uint8_t get_region_op(const uint32_t region_idx);
|
||||
void update_region_arrays();
|
||||
|
||||
void set_vsr(int channel, uint32_t value);
|
||||
uint32_t get_vsr(int channel);
|
||||
|
||||
void set_dcp(int channel, uint32_t value);
|
||||
uint32_t get_dcp(int channel);
|
||||
|
||||
void set_display_parameters(int channel, uint8_t value);
|
||||
void update_visible_area();
|
||||
uint32_t get_screen_width();
|
||||
|
||||
void process_ica(int channel);
|
||||
void process_dca(int channel);
|
||||
void process_vsr(int channel, uint8_t *pixels_r, uint8_t *pixels_g, uint8_t *pixels_b);
|
||||
template <int Channel> void set_vsr(uint32_t value);
|
||||
template <int Channel> uint32_t get_vsr();
|
||||
|
||||
void set_register(int channel, uint8_t reg, uint32_t value);
|
||||
template <int Channel> void set_dcp(uint32_t value);
|
||||
template <int Channel> uint32_t get_dcp();
|
||||
|
||||
void mix_lines(uint8_t *plane_a_r, uint8_t *plane_a_g, uint8_t *plane_a_b, uint8_t *plane_b_r, uint8_t *plane_b_g, uint8_t *plane_b_b, uint32_t *out);
|
||||
template <int Channel> void set_display_parameters(uint8_t value);
|
||||
|
||||
void draw_cursor(uint32_t *scanline, int y);
|
||||
void draw_scanline(int y);
|
||||
template <int Channel> void process_ica();
|
||||
template <int Channel> void process_dca();
|
||||
|
||||
void ab_init();
|
||||
template <int Channel> uint8_t get_transparency_control();
|
||||
template <int Channel> uint8_t get_icm();
|
||||
template <int Channel> bool get_mosaic_enable();
|
||||
template <int Channel> uint8_t get_mosaic_factor();
|
||||
template <int Channel> void process_vsr(uint32_t *pixels, bool *transparent);
|
||||
|
||||
template <int Channel> void set_register(uint8_t reg, uint32_t value);
|
||||
|
||||
template <bool MosaicA, bool MosaicB, bool OrderAB> void mix_lines(uint32_t *plane_a, bool *transparent_a, uint32_t *plane_b, bool *transparent_b, uint32_t *out);
|
||||
|
||||
void draw_cursor(uint32_t *scanline);
|
||||
void draw_scanline(bitmap_rgb32 &bitmap);
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
Loading…
Reference in New Issue
Block a user