flower.cpp: Replace hardcoded tags to region pointers, Fix some sound/cocktail mode behaviors (#8944)

* flower.cpp: Replace hardcoded tags to region pointers, Fix some sound/cocktail mode behaviors
- Use tilemap_t for text layer
- Add hardware notes
- Add notes for unknown sound register writes
- Add sound io register value for debug purpose
- Fix initializing behavior
- Use shorter/correct type values, Fix spacings
- Fix GFX ROM naming

* audio/flower.cpp: Reduce unnecessary values/pointers
- Use STRUCT_MEMBER for save values
This commit is contained in:
cam900 2021-12-15 00:29:56 +09:00 committed by GitHub
parent edcfe24353
commit 7eac6c8acc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 231 additions and 225 deletions

View File

@ -9,6 +9,8 @@
TODO: TODO:
- several unknown registers (effects and unknown register tied to repeat port); - several unknown registers (effects and unknown register tied to repeat port);
- repeat certainly needs a cutoff, which is unknown about how it works; - repeat certainly needs a cutoff, which is unknown about how it works;
- keyon/off behavior is not verified
- PCM output is incorrect/unverified
***************************************************************************/ ***************************************************************************/
@ -42,14 +44,15 @@ void flower_sound_device::regs_map(address_map &map)
// flower_sound_device - constructor // flower_sound_device - constructor
//------------------------------------------------- //-------------------------------------------------
flower_sound_device::flower_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) flower_sound_device::flower_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, FLOWER_CUSTOM, tag, owner, clock), : device_t(mconfig, FLOWER_CUSTOM, tag, owner, clock),
device_sound_interface(mconfig, *this), device_sound_interface(mconfig, *this),
device_memory_interface(mconfig, *this), device_memory_interface(mconfig, *this),
m_io_space_config("io", ENDIANNESS_LITTLE, 8, 7, 0, address_map_constructor(FUNC(flower_sound_device::regs_map), this)), m_io_space_config("io", ENDIANNESS_LITTLE, 8, 7, 0, address_map_constructor(FUNC(flower_sound_device::regs_map), this)),
m_stream(nullptr), m_stream(nullptr),
m_mixer_lookup(nullptr), m_mixer_lookup(nullptr),
m_last_channel(nullptr) m_sample_rom(*this, "samples"),
m_volume_rom(*this, "soundvol")
{ {
} }
@ -66,25 +69,18 @@ void flower_sound_device::device_start()
m_mixer_buffer.resize(clock()/50); m_mixer_buffer.resize(clock()/50);
make_mixer_table(MAX_VOICES, defgain); make_mixer_table(MAX_VOICES, defgain);
m_last_channel = m_channel_list + MAX_VOICES; save_item(STRUCT_MEMBER(m_channel_list, start_nibbles));
save_item(STRUCT_MEMBER(m_channel_list, raw_frequency));
save_item(STRUCT_MEMBER(m_channel_list, start_address));
save_item(STRUCT_MEMBER(m_channel_list, position));
save_item(STRUCT_MEMBER(m_channel_list, frequency));
save_item(STRUCT_MEMBER(m_channel_list, volume));
save_item(STRUCT_MEMBER(m_channel_list, volume_bank));
//save_item(STRUCT_MEMBER(m_channel_list, effect));
save_item(STRUCT_MEMBER(m_channel_list, enable));
save_item(STRUCT_MEMBER(m_channel_list, repeat));
m_sample_rom = machine().root_device().memregion("samples")->base(); save_item(NAME(m_io_regs));
m_volume_rom = machine().root_device().memregion("soundvol")->base();
for (int i = 0; i < MAX_VOICES; i++)
{
save_item(NAME(m_channel_list[i].start_address), i);
save_item(NAME(m_channel_list[i].position), i);
save_item(NAME(m_channel_list[i].frequency), i);
save_item(NAME(m_channel_list[i].volume), i);
save_item(NAME(m_channel_list[i].volume_bank), i);
save_item(NAME(m_channel_list[i].effect), i);
save_item(NAME(m_channel_list[i].enable), i);
save_item(NAME(m_channel_list[i].repeat), i);
// assign a channel number (debugger aid)
m_channel_list[i].channel_number = i;
}
} }
@ -115,13 +111,13 @@ void flower_sound_device::make_mixer_table(int voices, int gain)
void flower_sound_device::device_reset() void flower_sound_device::device_reset()
{ {
for (fl_sound_channel *voice = m_channel_list; voice < m_last_channel; voice++) for (auto & voice : m_channel_list)
{ {
voice->start_address = 0; voice.start_address = 0;
voice->position = 0; voice.position = 0;
voice->volume = 0; voice.volume = 0;
voice->enable = false; voice.enable = false;
voice->repeat = false; voice.repeat = false;
} }
} }
@ -129,45 +125,45 @@ void flower_sound_device::sound_stream_update(sound_stream &stream, std::vector<
{ {
auto &buffer = outputs[0]; auto &buffer = outputs[0];
short *mix; short *mix;
uint8_t raw_sample; u8 raw_sample;
std::fill_n(&m_mixer_buffer[0], buffer.samples(), 0); std::fill_n(&m_mixer_buffer[0], buffer.samples(), 0);
for (fl_sound_channel *voice = m_channel_list; voice < m_last_channel; voice++) for (auto & voice : m_channel_list)
{ {
int ch_volume = voice->volume; int ch_volume = voice.volume;
int ch_frequency = voice->frequency; int ch_frequency = voice.frequency;
if (voice->enable == false) if (!voice.enable)
continue; continue;
mix = &m_mixer_buffer[0]; mix = &m_mixer_buffer[0];
for (int i = 0; i < buffer.samples(); i++) for (int i = 0; i < buffer.samples(); i++)
{ {
if (voice->repeat == true) if (voice.repeat)
{ {
raw_sample = m_sample_rom[((voice->start_address >> 7) & 0x7e00) | ((voice->position >> 7) & 0x1ff)]; raw_sample = m_sample_rom[((voice.start_address >> 7) & 0x7e00) | ((voice.position >> 7) & 0x1ff)];
// guess: cut off after a number of repetitions // guess: key on/off bit is lowest bit of volume bank register?
if ((voice->position >> 7) & 0x20000) if ((voice.volume_bank & 0x10) != 0x10)
{ {
voice->enable = false; voice.enable = false;
break; break;
} }
} }
else else
{ {
raw_sample = m_sample_rom[((voice->start_address + voice->position) >> 7) & 0x7fff]; raw_sample = m_sample_rom[((voice.start_address + voice.position) >> 7) & 0x7fff];
if (raw_sample == 0xff) if (raw_sample == 0xff)
{ {
voice->enable = false; voice.enable = false;
break; break;
} }
} }
ch_volume |= voice->volume_bank; ch_volume |= voice.volume_bank;
*mix++ += m_volume_rom[(ch_volume << 8 | raw_sample) & 0x3fff] - 0x80; *mix++ += m_volume_rom[(ch_volume << 8 | raw_sample) & 0x3fff] - 0x80;
voice->position += ch_frequency; voice.position += ch_frequency;
} }
} }
@ -193,80 +189,83 @@ device_memory_interface::space_config_vector flower_sound_device::memory_space_c
// READ/WRITE HANDLERS // READ/WRITE HANDLERS
//************************************************************************** //**************************************************************************
void flower_sound_device::lower_write(offs_t offset, uint8_t data) void flower_sound_device::lower_write(offs_t offset, u8 data)
{ {
m_stream->update(); m_stream->update();
m_io_regs[offset] = data;
m_iospace->write_byte(offset,data); m_iospace->write_byte(offset,data);
} }
void flower_sound_device::upper_write(offs_t offset, uint8_t data) void flower_sound_device::upper_write(offs_t offset, u8 data)
{ {
m_stream->update(); m_stream->update();
m_io_regs[offset|0x40] = data;
m_iospace->write_byte(offset|0x40,data); m_iospace->write_byte(offset|0x40,data);
} }
void flower_sound_device::frequency_w(offs_t offset, uint8_t data) void flower_sound_device::frequency_w(offs_t offset, u8 data)
{ {
uint8_t ch = (offset >> 3) & 0x7; u8 ch = (offset >> 3) & 0x7;
fl_sound_channel *voice; fl_sound_channel &voice = m_channel_list[ch];
voice = &m_channel_list[ch]; // Low nibbles: part of frequency
// High nibbles: unknown
voice.raw_frequency[offset & 3] = data;
voice->raw_frequency[offset & 3] = data & 0xf; voice.frequency = (voice.raw_frequency[2] & 0xf) << 12;
voice.frequency|= (voice.raw_frequency[3] & 0xf) << 8;
voice->frequency = voice->raw_frequency[2] << 12; voice.frequency|= (voice.raw_frequency[0] & 0xf) << 4;
voice->frequency|= voice->raw_frequency[3] << 8; voice.frequency|= (voice.raw_frequency[1] & 0xf) << 0;
voice->frequency|= voice->raw_frequency[0] << 4;
voice->frequency|= voice->raw_frequency[1] << 0;
} }
void flower_sound_device::repeat_w(offs_t offset, uint8_t data) void flower_sound_device::repeat_w(offs_t offset, u8 data)
{ {
uint8_t ch = (offset >> 3) & 0x7; u8 ch = (offset >> 3) & 0x7;
fl_sound_channel *voice; fl_sound_channel &voice = m_channel_list[ch];
voice = &m_channel_list[ch]; voice.repeat = BIT(data, 4); // Bit 4: Repeat flag?
voice->repeat = BIT(data,4);
} }
void flower_sound_device::unk_w(offs_t offset, uint8_t data) void flower_sound_device::unk_w(offs_t offset, u8 data)
{ {
// same as above? // same as above?
} }
void flower_sound_device::volume_w(offs_t offset, uint8_t data) void flower_sound_device::volume_w(offs_t offset, u8 data)
{ {
uint8_t ch = (offset >> 3) & 0x7; u8 ch = (offset >> 3) & 0x7;
fl_sound_channel *voice; fl_sound_channel &voice = m_channel_list[ch];
voice = &m_channel_list[ch]; // Low nibbles: unknown
voice->volume = data >> 4; // High nibbles: volume
voice.volume = data >> 4;
} }
void flower_sound_device::start_address_w(offs_t offset, uint8_t data) void flower_sound_device::start_address_w(offs_t offset, u8 data)
{ {
uint8_t ch = (offset >> 3) & 0x7; u8 ch = (offset >> 3) & 0x7;
fl_sound_channel *voice; fl_sound_channel &voice = m_channel_list[ch];
voice = &m_channel_list[ch]; // Low nibbles: part of start address
voice->start_nibbles[offset & 7] = data & 0xf; // High nibbles: unknown
voice.start_nibbles[offset & 7] = data;
/*
if ((offset & 7) == 4) if ((offset & 7) == 4)
voice->effect = data >> 4; voice.effect = data >> 4;
*/
} }
void flower_sound_device::sample_trigger_w(offs_t offset, uint8_t data) void flower_sound_device::sample_trigger_w(offs_t offset, u8 data)
{ {
uint8_t ch = (offset >> 3) & 0x7; u8 ch = (offset >> 3) & 0x7;
fl_sound_channel *voice; fl_sound_channel &voice = m_channel_list[ch];
voice = &m_channel_list[ch]; voice.enable = true; // BIT(data, 0);
voice.volume_bank = (data & 3) << 4; // Bit 0: Keyon/off?, Bit 1: PCM/Wavetable mode select?
voice->enable = true; voice.start_address = 0;
voice->volume_bank = (data & 3) << 4; voice.position = 0;
voice->start_address = 0;
voice->position = 0;
for (int i = 5; i >= 0; i--) for (int i = 5; i >= 0; i--)
{ {
voice->start_address = (voice->start_address << 4) | voice->start_nibbles[i]; voice.start_address = (voice.start_address << 4) | (voice.start_nibbles[i] & 0xf);
} }
} }

View File

@ -23,11 +23,11 @@ class flower_sound_device : public device_t,
{ {
public: public:
// construction/destruction // construction/destruction
flower_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); flower_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// I/O operations // I/O operations
void lower_write(offs_t offset, uint8_t data); void lower_write(offs_t offset, u8 data);
void upper_write(offs_t offset, uint8_t data); void upper_write(offs_t offset, u8 data);
// virtual void lower_map(address_map &map); // virtual void lower_map(address_map &map);
// virtual void upper_map(address_map &map); // virtual void upper_map(address_map &map);
@ -50,40 +50,40 @@ private:
static constexpr unsigned MAX_VOICES = 8; static constexpr unsigned MAX_VOICES = 8;
static constexpr int defgain = 48; static constexpr int defgain = 48;
std::vector<int16_t> m_mixer_table; u8 m_io_regs[0x80] = {0}; // for debug purpose
int16_t *m_mixer_lookup;
std::vector<s16> m_mixer_table;
s16 *m_mixer_lookup;
std::vector<short> m_mixer_buffer; std::vector<short> m_mixer_buffer;
struct fl_sound_channel struct fl_sound_channel
{ {
uint8_t start_nibbles[6]; u8 start_nibbles[6] = {0};
uint8_t raw_frequency[4]; u8 raw_frequency[4] = {0};
uint32_t start_address; u32 start_address = 0;
uint32_t position; u32 position = 0;
uint16_t frequency; u16 frequency = 0;
uint8_t volume; u8 volume = 0;
uint8_t volume_bank; u8 volume_bank = 0;
uint8_t effect; //u8 effect = 0;
bool enable; bool enable = false;
bool repeat; bool repeat = false;
int channel_number;
}; };
/* data about the sound system */ /* data about the sound system */
fl_sound_channel m_channel_list[MAX_VOICES]; fl_sound_channel m_channel_list[MAX_VOICES];
fl_sound_channel *m_last_channel;
void make_mixer_table(int voices, int gain); void make_mixer_table(int voices, int gain);
const uint8_t *m_sample_rom; required_region_ptr<u8> m_sample_rom;
const uint8_t *m_volume_rom; required_region_ptr<u8> m_volume_rom;
void frequency_w(offs_t offset, uint8_t data); void frequency_w(offs_t offset, u8 data);
void repeat_w(offs_t offset, uint8_t data); void repeat_w(offs_t offset, u8 data);
void unk_w(offs_t offset, uint8_t data); void unk_w(offs_t offset, u8 data);
void volume_w(offs_t offset, uint8_t data); void volume_w(offs_t offset, u8 data);
void start_address_w(offs_t offset, uint8_t data); void start_address_w(offs_t offset, u8 data);
void sample_trigger_w(offs_t offset, uint8_t data); void sample_trigger_w(offs_t offset, u8 data);
}; };

View File

@ -12,6 +12,11 @@
galaxy, planet ship 3rd boss, 2nd boss); galaxy, planet ship 3rd boss, 2nd boss);
- sound chips (similar to Namco custom chips?) - sound chips (similar to Namco custom chips?)
Video reference:
https://youtu.be/ycbJMG09UZ0
https://youtu.be/NolazjlEiAY
https://youtu.be/8JOPTCWu67g
=============================================================================== ===============================================================================
Flower (c)1986 Komax (USA license) Flower (c)1986 Komax (USA license)
@ -114,17 +119,20 @@ public:
DECLARE_INPUT_CHANGED_MEMBER(coin_inserted); DECLARE_INPUT_CHANGED_MEMBER(coin_inserted);
private: private:
void flipscreen_w(uint8_t data); void flipscreen_w(u8 data);
void coin_counter_w(uint8_t data); void coin_counter_w(u8 data);
void sound_command_w(uint8_t data); void sound_command_w(u8 data);
void audio_nmi_mask_w(uint8_t data); void audio_nmi_mask_w(u8 data);
void bgvram_w(offs_t offset, uint8_t data); void bgvram_w(offs_t offset, u8 data);
void fgvram_w(offs_t offset, uint8_t data); void fgvram_w(offs_t offset, u8 data);
void txvram_w(offs_t offset, u8 data);
INTERRUPT_GEN_MEMBER(master_vblank_irq); INTERRUPT_GEN_MEMBER(master_vblank_irq);
INTERRUPT_GEN_MEMBER(slave_vblank_irq); INTERRUPT_GEN_MEMBER(slave_vblank_irq);
TILE_GET_INFO_MEMBER(get_tx_tile_info);
TILE_GET_INFO_MEMBER(get_bg_tile_info); TILE_GET_INFO_MEMBER(get_bg_tile_info);
TILE_GET_INFO_MEMBER(get_fg_tile_info); TILE_GET_INFO_MEMBER(get_fg_tile_info);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); TILEMAP_MAPPER_MEMBER(tilemap_scan);
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void audio_map(address_map &map); void audio_map(address_map &map);
void shared_map(address_map &map); void shared_map(address_map &map);
@ -141,86 +149,74 @@ private:
required_device<screen_device> m_screen; required_device<screen_device> m_screen;
required_device<palette_device> m_palette; required_device<palette_device> m_palette;
required_device<gfxdecode_device> m_gfxdecode; required_device<gfxdecode_device> m_gfxdecode;
required_shared_ptr<uint8_t> m_txvram; required_shared_ptr<u8> m_txvram;
required_shared_ptr<uint8_t> m_bgvram; required_shared_ptr<u8> m_bgvram;
required_shared_ptr<uint8_t> m_fgvram; required_shared_ptr<u8> m_fgvram;
required_shared_ptr<uint8_t> m_workram; required_shared_ptr<u8> m_workram;
required_shared_ptr<uint8_t> m_bgscroll; required_shared_ptr<u8> m_bgscroll;
required_shared_ptr<uint8_t> m_fgscroll; required_shared_ptr<u8> m_fgscroll;
required_device<generic_latch_8_device> m_soundlatch; required_device<generic_latch_8_device> m_soundlatch;
bitmap_ind16 m_temp_bitmap; bitmap_ind16 m_temp_bitmap;
void draw_legacy_text(bitmap_ind16 &bitmap,const rectangle &cliprect);
void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect); void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect);
bool m_audio_nmi_enable; bool m_audio_nmi_enable = false;
bool m_flip_screen; bool m_flip_screen = false;
tilemap_t *m_bg_tilemap; tilemap_t *m_bg_tilemap;
tilemap_t *m_fg_tilemap; tilemap_t *m_fg_tilemap;
tilemap_t *m_tx_tilemap;
}; };
TILE_GET_INFO_MEMBER(flower_state::get_tx_tile_info)
{
const u32 code = m_txvram[tile_index];
const u32 color = (m_txvram[tile_index + 0x400] & 0xfc) >> 2;
tileinfo.set(0, code, color, 0);
}
TILE_GET_INFO_MEMBER(flower_state::get_bg_tile_info) TILE_GET_INFO_MEMBER(flower_state::get_bg_tile_info)
{ {
int code = m_bgvram[tile_index]; const u32 code = m_bgvram[tile_index];
int color = (m_bgvram[tile_index+0x100] & 0xf0) >> 4; const u32 color = (m_bgvram[tile_index + 0x100] & 0xf0) >> 4;
tileinfo.set(1, code, color, 0); tileinfo.set(1, code, color, 0);
} }
TILE_GET_INFO_MEMBER(flower_state::get_fg_tile_info) TILE_GET_INFO_MEMBER(flower_state::get_fg_tile_info)
{ {
int code = m_fgvram[tile_index]; const u32 code = m_fgvram[tile_index];
int color = (m_fgvram[tile_index+0x100] & 0xf0) >> 4; const u32 color = (m_fgvram[tile_index + 0x100] & 0xf0) >> 4;
tileinfo.set(1, code, color, 0); tileinfo.set(1, code, color, 0);
} }
// convert from 32x32 to 36x28, similar as Namco hardware
TILEMAP_MAPPER_MEMBER(flower_state::tilemap_scan)
{
row += 2;
col -= 2;
if (col & 0x20)
return ((col & 0x1f) << 5) + row;
else
return (row << 5) + col;
}
void flower_state::video_start() void flower_state::video_start()
{ {
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(flower_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 16); m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(flower_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 16);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(flower_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 16); m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(flower_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 16);
m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(flower_state::get_tx_tile_info)), tilemap_mapper_delegate(*this, FUNC(flower_state::tilemap_scan)), 8, 8, 36, 28);
m_screen->register_screen_bitmap(m_temp_bitmap); m_screen->register_screen_bitmap(m_temp_bitmap);
m_fg_tilemap->set_transparent_pen(15); m_fg_tilemap->set_transparent_pen(15);
m_tx_tilemap->set_transparent_pen(3);
save_item(NAME(m_flip_screen)); save_item(NAME(m_flip_screen));
m_bg_tilemap->set_scrolldx(16, 0); m_bg_tilemap->set_scrolldx(16, 0);
m_fg_tilemap->set_scrolldx(16, 0); m_fg_tilemap->set_scrolldx(16, 0);
} m_tx_tilemap->set_scrolldy(16, 0);
void flower_state::draw_legacy_text(bitmap_ind16 &bitmap,const rectangle &cliprect)
{
gfx_element *gfx_0 = m_gfxdecode->gfx(0);
int count;
for (count=0;count<32*32;count++)
{
int x = count % 32;
int y = count / 32;
uint8_t tile = m_txvram[count];
uint8_t attr = m_txvram[count+0x400];
if(attr & 0x03) // debug
attr = machine().rand() & 0xfc;
gfx_0->transpen(bitmap,cliprect,tile,attr >> 2,0,0,x*8+16,y*8,3);
}
for (count=0;count<0x40;count++)
{
int x = count / 32;
int y = count % 32;
uint8_t tile = m_txvram[count];
uint8_t attr = m_txvram[count+0x400];
if(attr & 0x03) // debug
attr = machine().rand() & 0xfc;
gfx_0->transpen(bitmap,cliprect,tile,attr >> 2,0,0,x*8+256+16,y*8,3);
}
} }
/* /*
@ -234,106 +230,117 @@ void flower_state::draw_legacy_text(bitmap_ind16 &bitmap,const rectangle &clipre
*/ */
void flower_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect) void flower_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect)
{ {
uint8_t *spr_ptr = &m_workram[0x1e08]; u8 *spr_ptr = &m_workram[0x1e08];
gfx_element *gfx_2 = m_gfxdecode->gfx(2); gfx_element *gfx_2 = m_gfxdecode->gfx(2);
// traverse from top to bottom // traverse from top to bottom
for(int i=0x1f0;i>=0;i-=8) for (int i = 0x1f0; i >= 0; i -= 8)
{ {
uint8_t tile = (spr_ptr[i+1] & 0x3f); u32 tile = (spr_ptr[i + 1] & 0x3f);
uint8_t color = spr_ptr[i+6] >> 4; const u32 color = spr_ptr[i + 6] >> 4;
int x = (spr_ptr[i+4] | (spr_ptr[i+5]<<8))-39; int x = (spr_ptr[i + 4] | (spr_ptr[i + 5] << 8)) - 39;
int y = 241-spr_ptr[i+0]; int y = 241 - spr_ptr[i + 0];
uint8_t attr = spr_ptr[i+2]; const u8 attr = spr_ptr[i + 2];
uint8_t fy = spr_ptr[i+1] & 0x80; const bool fy = spr_ptr[i + 1] & 0x80;
uint8_t fx = spr_ptr[i+1] & 0x40; const bool fx = spr_ptr[i + 1] & 0x40;
uint8_t ysize = ((spr_ptr[i+3] & 0x80) >> 7) + 1; const u8 ysize = ((spr_ptr[i + 3] & 0x80) >> 7) + 1;
uint8_t xsize = ((spr_ptr[i+3] & 0x08) >> 3) + 1; const u8 xsize = ((spr_ptr[i + 3] & 0x08) >> 3) + 1;
uint8_t ydiv = ysize == 2 ? 1 : 2; const u8 ydiv = ysize == 2 ? 1 : 2;
uint8_t xdiv = xsize == 2 ? 1 : 2; const u8 xdiv = xsize == 2 ? 1 : 2;
uint32_t yshrink_zoom = ((spr_ptr[i+3] & 0x70) >> 4) + 1; u32 yshrink_zoom = ((spr_ptr[i + 3] & 0x70) >> 4) + 1;
uint32_t xshrink_zoom = ((spr_ptr[i+3] & 0x07) >> 0) + 1; u32 xshrink_zoom = ((spr_ptr[i + 3] & 0x07) >> 0) + 1;
yshrink_zoom <<= 13; yshrink_zoom <<= 13;
xshrink_zoom <<= 13; xshrink_zoom <<= 13;
int ypixels = (yshrink_zoom*16) >> 16; const int ypixels = (yshrink_zoom * 16) >> 16;
int xpixels = (xshrink_zoom*16) >> 16; const int xpixels = (xshrink_zoom * 16) >> 16;
tile |= (attr & 1) << 6; tile |= (attr & 1) << 6;
tile |= (attr & 8) << 4; tile |= (attr & 8) << 4;
if(flip_screen()) if (m_flip_screen)
{ {
x += xsize*16; x += xsize * 16;
x = 288-x; x = 288 - x;
y -= 2; y -= 2;
} }
if(ysize == 2) if (ysize == 2)
y-=16; y -= 16;
for(int yi=0;yi<ysize;yi++) for (int yi = 0; yi < ysize; yi++)
{ {
int yoffs = (16-ypixels)/ydiv; const int yoffs = (16 - ypixels) / ydiv;
for(int xi=0;xi<xsize;xi++) for (int xi = 0; xi < xsize; xi++)
{ {
int tile_offs; int tile_offs;
int xoffs = (16-xpixels)/xdiv; const int xoffs = (16 - xpixels) / xdiv;
tile_offs = fx ? (xsize-xi-1) * 8 : xi*8; tile_offs = fx ? (xsize - xi - 1) * 8 : xi * 8;
tile_offs+= fy ? (ysize-yi-1) : yi; tile_offs += fy ? (ysize - yi - 1) : yi;
gfx_2->zoom_transpen(bitmap,cliprect, tile+tile_offs, color, fx, fy, x+xi*xpixels+xoffs, y+yi*ypixels+yoffs, xshrink_zoom, yshrink_zoom, 15); gfx_2->zoom_transpen(bitmap, cliprect,
tile + tile_offs, color,
fx, fy,
x + xi * xpixels + xoffs, y + yi * ypixels + yoffs,
xshrink_zoom, yshrink_zoom,
15);
} }
} }
} }
} }
uint32_t flower_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) u32 flower_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
{ {
m_bg_tilemap->set_scrolly(0, m_bgscroll[0]); m_bg_tilemap->set_scrolly(0, m_bgscroll[0]);
m_fg_tilemap->set_scrolly(0, m_fgscroll[0]); m_fg_tilemap->set_scrolly(0, m_fgscroll[0]);
m_temp_bitmap.fill(0,cliprect); m_temp_bitmap.fill(0, cliprect);
m_bg_tilemap->draw(screen, m_temp_bitmap, cliprect, 0, 0); m_bg_tilemap->draw(screen, m_temp_bitmap, cliprect, 0, 0);
m_fg_tilemap->draw(screen, m_temp_bitmap, cliprect, 0, 0); m_fg_tilemap->draw(screen, m_temp_bitmap, cliprect, 0, 0);
draw_sprites(m_temp_bitmap,cliprect); draw_sprites(m_temp_bitmap, cliprect);
draw_legacy_text(m_temp_bitmap,cliprect); m_tx_tilemap->draw(screen, m_temp_bitmap, cliprect, 0, 0);
copybitmap(bitmap,m_temp_bitmap,m_flip_screen,m_flip_screen,m_flip_screen == true ? -154 : 0, m_flip_screen == true ? -7 : 0, cliprect); copybitmap(bitmap, m_temp_bitmap, m_flip_screen, m_flip_screen, m_flip_screen ? -96 : 0, m_flip_screen ? -8 : 0, cliprect);
return 0; return 0;
} }
void flower_state::flipscreen_w(uint8_t data) void flower_state::flipscreen_w(u8 data)
{ {
flip_screen_set(data & 1); m_flip_screen = BIT(data, 0);
m_flip_screen = BIT(data,0); //flip_screen_set(m_flip_screen);
} }
void flower_state::coin_counter_w(uint8_t data) void flower_state::coin_counter_w(u8 data)
{ {
machine().bookkeeping().coin_counter_w(0,data & 1); machine().bookkeeping().coin_counter_w(0, BIT(data, 0));
} }
void flower_state::sound_command_w(uint8_t data) void flower_state::sound_command_w(u8 data)
{ {
m_soundlatch->write(data & 0xff); m_soundlatch->write(data);
if(m_audio_nmi_enable == true) if (m_audio_nmi_enable)
m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
} }
void flower_state::audio_nmi_mask_w(uint8_t data) void flower_state::audio_nmi_mask_w(u8 data)
{ {
m_audio_nmi_enable = BIT(data,0); m_audio_nmi_enable = BIT(data, 0);
} }
void flower_state::bgvram_w(offs_t offset, uint8_t data) void flower_state::txvram_w(offs_t offset, u8 data)
{
m_txvram[offset] = data;
m_tx_tilemap->mark_tile_dirty(offset & 0x3ff);
}
void flower_state::bgvram_w(offs_t offset, u8 data)
{ {
m_bgvram[offset] = data; m_bgvram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset & 0xff); m_bg_tilemap->mark_tile_dirty(offset & 0xff);
} }
void flower_state::fgvram_w(offs_t offset, uint8_t data) void flower_state::fgvram_w(offs_t offset, u8 data)
{ {
m_fgvram[offset] = data; m_fgvram[offset] = data;
m_fg_tilemap->mark_tile_dirty(offset & 0xff); m_fg_tilemap->mark_tile_dirty(offset & 0xff);
@ -354,7 +361,7 @@ void flower_state::shared_map(address_map &map)
map(0xa102, 0xa102).portr("DSW1"); map(0xa102, 0xa102).portr("DSW1");
map(0xa103, 0xa103).portr("DSW2"); map(0xa103, 0xa103).portr("DSW2");
map(0xa400, 0xa400).w(FUNC(flower_state::sound_command_w)); map(0xa400, 0xa400).w(FUNC(flower_state::sound_command_w));
map(0xe000, 0xefff).ram().share("txvram"); map(0xe000, 0xefff).ram().w(FUNC(flower_state::txvram_w)).share("txvram");
map(0xf000, 0xf1ff).ram().w(FUNC(flower_state::fgvram_w)).share("fgvram"); map(0xf000, 0xf1ff).ram().w(FUNC(flower_state::fgvram_w)).share("fgvram");
map(0xf200, 0xf200).ram().share("fgscroll"); map(0xf200, 0xf200).ram().share("fgscroll");
map(0xf800, 0xf9ff).ram().w(FUNC(flower_state::bgvram_w)).share("bgvram"); map(0xf800, 0xf9ff).ram().w(FUNC(flower_state::bgvram_w)).share("bgvram");
@ -399,7 +406,7 @@ static INPUT_PORTS_START( flower )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("DSW1") PORT_START("DSW1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, flower_state,coin_inserted, 0) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, flower_state, coin_inserted, 0)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START2 )
PORT_DIPNAME( 0x08, 0x08, "Energy Decrease" ) PORT_DIPLOCATION("SW2:4") PORT_DIPNAME( 0x08, 0x08, "Energy Decrease" ) PORT_DIPLOCATION("SW2:4")
@ -467,9 +474,9 @@ static const gfx_layout tilelayout =
}; };
static GFXDECODE_START( gfx_flower ) static GFXDECODE_START( gfx_flower )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 64 ) GFXDECODE_ENTRY( "text", 0, charlayout, 0, 64 )
GFXDECODE_ENTRY( "gfx2", 0, tilelayout, 0, 16 ) GFXDECODE_ENTRY( "tiles", 0, tilelayout, 0, 16 )
GFXDECODE_ENTRY( "gfx3", 0, tilelayout, 0, 16 ) GFXDECODE_ENTRY( "sprites", 0, tilelayout, 0, 16 )
GFXDECODE_END GFXDECODE_END
void flower_state::machine_start() void flower_state::machine_start()
@ -484,28 +491,28 @@ void flower_state::machine_reset()
INTERRUPT_GEN_MEMBER(flower_state::master_vblank_irq) INTERRUPT_GEN_MEMBER(flower_state::master_vblank_irq)
{ {
//if(m_master_irq_enable == true) //if (m_master_irq_enable)
device.execute().set_input_line(0, HOLD_LINE); device.execute().set_input_line(0, HOLD_LINE);
} }
INTERRUPT_GEN_MEMBER(flower_state::slave_vblank_irq) INTERRUPT_GEN_MEMBER(flower_state::slave_vblank_irq)
{ {
//if(m_slave_irq_enable == true) //if (m_slave_irq_enable)
device.execute().set_input_line(0, HOLD_LINE); device.execute().set_input_line(0, HOLD_LINE);
} }
void flower_state::flower(machine_config &config) void flower_state::flower(machine_config &config)
{ {
Z80(config, m_mastercpu, MASTER_CLOCK/4); Z80(config, m_mastercpu, MASTER_CLOCK / 4); // divider unknown
m_mastercpu->set_addrmap(AS_PROGRAM, &flower_state::shared_map); m_mastercpu->set_addrmap(AS_PROGRAM, &flower_state::shared_map);
m_mastercpu->set_vblank_int("screen", FUNC(flower_state::master_vblank_irq)); m_mastercpu->set_vblank_int("screen", FUNC(flower_state::master_vblank_irq));
Z80(config, m_slavecpu, MASTER_CLOCK/4); Z80(config, m_slavecpu, MASTER_CLOCK / 4); // divider unknown
m_slavecpu->set_addrmap(AS_PROGRAM, &flower_state::shared_map); m_slavecpu->set_addrmap(AS_PROGRAM, &flower_state::shared_map);
m_slavecpu->set_vblank_int("screen", FUNC(flower_state::slave_vblank_irq)); m_slavecpu->set_vblank_int("screen", FUNC(flower_state::slave_vblank_irq));
Z80(config, m_audiocpu, MASTER_CLOCK/4); Z80(config, m_audiocpu, MASTER_CLOCK / 4); // divider unknown
m_audiocpu->set_addrmap(AS_PROGRAM, &flower_state::audio_map); m_audiocpu->set_addrmap(AS_PROGRAM, &flower_state::audio_map);
m_audiocpu->set_periodic_int(FUNC(flower_state::irq0_line_hold), attotime::from_hz(90)); m_audiocpu->set_periodic_int(FUNC(flower_state::irq0_line_hold), attotime::from_hz(90));
@ -513,7 +520,7 @@ void flower_state::flower(machine_config &config)
SCREEN(config, m_screen, SCREEN_TYPE_RASTER); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_screen_update(FUNC(flower_state::screen_update)); m_screen->set_screen_update(FUNC(flower_state::screen_update));
m_screen->set_raw(MASTER_CLOCK/3,384,0,288,264,16,240); // derived from Galaxian HW, 60.606060 m_screen->set_raw(MASTER_CLOCK / 3, 384, 0, 288, 264, 16, 240); // derived from Galaxian HW, 60.606060
m_screen->set_palette(m_palette); m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_flower); GFXDECODE(config, m_gfxdecode, m_palette, gfx_flower);
@ -537,25 +544,25 @@ ROM_START( flower ) /* Komax version */
ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */ ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
ROM_LOAD( "3.d9", 0x0000, 0x4000, CRC(8866c2b0) SHA1(d00f31994673e8087a1406f98e8832d07cedeb66) ) // 1xxxxxxxxxxxxx = 0xFF ROM_LOAD( "3.d9", 0x0000, 0x4000, CRC(8866c2b0) SHA1(d00f31994673e8087a1406f98e8832d07cedeb66) ) // 1xxxxxxxxxxxxx = 0xFF
ROM_REGION( 0x2000, "gfx1", ROMREGION_INVERT ) /* tx layer */ ROM_REGION( 0x2000, "text", ROMREGION_INVERT ) /* tx layer */
ROM_LOAD( "10.13e", 0x0000, 0x2000, CRC(62f9b28c) SHA1(d57d06b99e72a4f68f197a5b6c042c926cc70ca0) ) // FIRST AND SECOND HALF IDENTICAL ROM_LOAD( "10.13e", 0x0000, 0x2000, CRC(62f9b28c) SHA1(d57d06b99e72a4f68f197a5b6c042c926cc70ca0) ) // FIRST AND SECOND HALF IDENTICAL
ROM_REGION( 0x8000, "gfx2", ROMREGION_INVERT ) /* bg layers */ ROM_REGION( 0x8000, "tiles", ROMREGION_INVERT ) /* bg layers */
ROM_LOAD( "8.10e", 0x0000, 0x2000, CRC(f85eb20f) SHA1(699edc970c359143dee6de2a97cc2a552454785b) ) ROM_LOAD( "8.10e", 0x0000, 0x2000, CRC(f85eb20f) SHA1(699edc970c359143dee6de2a97cc2a552454785b) )
ROM_LOAD( "6.7e", 0x2000, 0x2000, CRC(3e97843f) SHA1(4e4e5625dbf78eca97536b1428b2e49ad58c618f) ) ROM_LOAD( "6.7e", 0x2000, 0x2000, CRC(3e97843f) SHA1(4e4e5625dbf78eca97536b1428b2e49ad58c618f) )
ROM_LOAD( "9.12e", 0x4000, 0x2000, CRC(f1d9915e) SHA1(158e1cc8c402f9ae3906363d99f2b25c94c64212) ) ROM_LOAD( "9.12e", 0x4000, 0x2000, CRC(f1d9915e) SHA1(158e1cc8c402f9ae3906363d99f2b25c94c64212) )
ROM_LOAD( "15.9e", 0x6000, 0x2000, CRC(1cad9f72) SHA1(c38dbea266246ed4d47d12bdd8f9fae22a5f8bb8) ) ROM_LOAD( "15.9e", 0x6000, 0x2000, CRC(1cad9f72) SHA1(c38dbea266246ed4d47d12bdd8f9fae22a5f8bb8) )
ROM_REGION( 0x8000, "gfx3", ROMREGION_INVERT ) /* sprites */ ROM_REGION( 0x8000, "sprites", ROMREGION_INVERT ) /* sprites */
ROM_LOAD( "14.19e", 0x0000, 0x2000, CRC(11b491c5) SHA1(be1c4a0fbe8fd4e124c21e0f700efa0428376691) ) ROM_LOAD( "14.19e", 0x0000, 0x2000, CRC(11b491c5) SHA1(be1c4a0fbe8fd4e124c21e0f700efa0428376691) )
ROM_LOAD( "13.17e", 0x2000, 0x2000, CRC(ea743986) SHA1(bbef4fd0f7d21cc89a52061fa50d7c2ea37287bd) ) ROM_LOAD( "13.17e", 0x2000, 0x2000, CRC(ea743986) SHA1(bbef4fd0f7d21cc89a52061fa50d7c2ea37287bd) )
ROM_LOAD( "12.16e", 0x4000, 0x2000, CRC(e3779f7f) SHA1(8e12d06b3cdc2fcb7b77cc35f8eca45544cc4873) ) ROM_LOAD( "12.16e", 0x4000, 0x2000, CRC(e3779f7f) SHA1(8e12d06b3cdc2fcb7b77cc35f8eca45544cc4873) )
ROM_LOAD( "11.14e", 0x6000, 0x2000, CRC(8801b34f) SHA1(256059fcd16b21e076db1c18fd9669128df1d658) ) ROM_LOAD( "11.14e", 0x6000, 0x2000, CRC(8801b34f) SHA1(256059fcd16b21e076db1c18fd9669128df1d658) )
ROM_REGION( 0x8000, "samples", 0 ) ROM_REGION( 0x8000, "flower:samples", 0 )
ROM_LOAD( "4.12a", 0x0000, 0x8000, CRC(851ed9fd) SHA1(5dc048b612e45da529502bf33d968737a7b0a646) ) /* 8-bit samples */ ROM_LOAD( "4.12a", 0x0000, 0x8000, CRC(851ed9fd) SHA1(5dc048b612e45da529502bf33d968737a7b0a646) ) /* 8-bit samples */
ROM_REGION( 0x4000, "soundvol", 0 ) ROM_REGION( 0x4000, "flower:soundvol", 0 )
ROM_LOAD( "5.16a", 0x0000, 0x4000, CRC(42fa2853) SHA1(cc1e8b8231d6f27f48b05d59390e93ea1c1c0e4c) ) /* volume tables? */ ROM_LOAD( "5.16a", 0x0000, 0x4000, CRC(42fa2853) SHA1(cc1e8b8231d6f27f48b05d59390e93ea1c1c0e4c) ) /* volume tables? */
ROM_REGION( 0x300, "proms", 0 ) /* RGB proms */ ROM_REGION( 0x300, "proms", 0 ) /* RGB proms */
@ -580,25 +587,25 @@ ROM_START( flowerj ) /* Sega/Alpha version. Sega game number 834-5998 */
ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */ ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
ROM_LOAD( "3.d9", 0x0000, 0x4000, CRC(8866c2b0) SHA1(d00f31994673e8087a1406f98e8832d07cedeb66) ) // 1xxxxxxxxxxxxx = 0xFF ROM_LOAD( "3.d9", 0x0000, 0x4000, CRC(8866c2b0) SHA1(d00f31994673e8087a1406f98e8832d07cedeb66) ) // 1xxxxxxxxxxxxx = 0xFF
ROM_REGION( 0x2000, "gfx1", ROMREGION_INVERT ) /* tx layer */ ROM_REGION( 0x2000, "text", ROMREGION_INVERT ) /* tx layer */
ROM_LOAD( "10.13e", 0x0000, 0x2000, CRC(62f9b28c) SHA1(d57d06b99e72a4f68f197a5b6c042c926cc70ca0) ) // FIRST AND SECOND HALF IDENTICAL ROM_LOAD( "10.13e", 0x0000, 0x2000, CRC(62f9b28c) SHA1(d57d06b99e72a4f68f197a5b6c042c926cc70ca0) ) // FIRST AND SECOND HALF IDENTICAL
ROM_REGION( 0x8000, "gfx2", ROMREGION_INVERT ) /* bg layers */ ROM_REGION( 0x8000, "tiles", ROMREGION_INVERT ) /* bg layers */
ROM_LOAD( "8.10e", 0x0000, 0x2000, CRC(f85eb20f) SHA1(699edc970c359143dee6de2a97cc2a552454785b) ) ROM_LOAD( "8.10e", 0x0000, 0x2000, CRC(f85eb20f) SHA1(699edc970c359143dee6de2a97cc2a552454785b) )
ROM_LOAD( "6.7e", 0x2000, 0x2000, CRC(3e97843f) SHA1(4e4e5625dbf78eca97536b1428b2e49ad58c618f) ) ROM_LOAD( "6.7e", 0x2000, 0x2000, CRC(3e97843f) SHA1(4e4e5625dbf78eca97536b1428b2e49ad58c618f) )
ROM_LOAD( "9.12e", 0x4000, 0x2000, CRC(f1d9915e) SHA1(158e1cc8c402f9ae3906363d99f2b25c94c64212) ) ROM_LOAD( "9.12e", 0x4000, 0x2000, CRC(f1d9915e) SHA1(158e1cc8c402f9ae3906363d99f2b25c94c64212) )
ROM_LOAD( "7.9e", 0x6000, 0x2000, CRC(e350f36c) SHA1(f97204dc95b4000c268afc053a2333c1629e07d8) ) ROM_LOAD( "7.9e", 0x6000, 0x2000, CRC(e350f36c) SHA1(f97204dc95b4000c268afc053a2333c1629e07d8) )
ROM_REGION( 0x8000, "gfx3", ROMREGION_INVERT ) /* sprites */ ROM_REGION( 0x8000, "sprites", ROMREGION_INVERT ) /* sprites */
ROM_LOAD( "14.19e", 0x0000, 0x2000, CRC(11b491c5) SHA1(be1c4a0fbe8fd4e124c21e0f700efa0428376691) ) ROM_LOAD( "14.19e", 0x0000, 0x2000, CRC(11b491c5) SHA1(be1c4a0fbe8fd4e124c21e0f700efa0428376691) )
ROM_LOAD( "13.17e", 0x2000, 0x2000, CRC(ea743986) SHA1(bbef4fd0f7d21cc89a52061fa50d7c2ea37287bd) ) ROM_LOAD( "13.17e", 0x2000, 0x2000, CRC(ea743986) SHA1(bbef4fd0f7d21cc89a52061fa50d7c2ea37287bd) )
ROM_LOAD( "12.16e", 0x4000, 0x2000, CRC(e3779f7f) SHA1(8e12d06b3cdc2fcb7b77cc35f8eca45544cc4873) ) ROM_LOAD( "12.16e", 0x4000, 0x2000, CRC(e3779f7f) SHA1(8e12d06b3cdc2fcb7b77cc35f8eca45544cc4873) )
ROM_LOAD( "11.14e", 0x6000, 0x2000, CRC(8801b34f) SHA1(256059fcd16b21e076db1c18fd9669128df1d658) ) ROM_LOAD( "11.14e", 0x6000, 0x2000, CRC(8801b34f) SHA1(256059fcd16b21e076db1c18fd9669128df1d658) )
ROM_REGION( 0x8000, "samples", 0 ) ROM_REGION( 0x8000, "flower:samples", 0 )
ROM_LOAD( "4.12a", 0x0000, 0x8000, CRC(851ed9fd) SHA1(5dc048b612e45da529502bf33d968737a7b0a646) ) /* 8-bit samples */ ROM_LOAD( "4.12a", 0x0000, 0x8000, CRC(851ed9fd) SHA1(5dc048b612e45da529502bf33d968737a7b0a646) ) /* 8-bit samples */
ROM_REGION( 0x4000, "soundvol", 0 ) ROM_REGION( 0x4000, "flower:soundvol", 0 )
ROM_LOAD( "5.16a", 0x0000, 0x4000, CRC(42fa2853) SHA1(cc1e8b8231d6f27f48b05d59390e93ea1c1c0e4c) ) /* volume tables? */ ROM_LOAD( "5.16a", 0x0000, 0x4000, CRC(42fa2853) SHA1(cc1e8b8231d6f27f48b05d59390e93ea1c1c0e4c) ) /* volume tables? */
ROM_REGION( 0x300, "proms", 0 ) /* RGB proms */ ROM_REGION( 0x300, "proms", 0 ) /* RGB proms */