gomoku.cpp: added save state support (nw)

This commit is contained in:
Ivan Vangelista 2020-03-03 18:19:03 +01:00
parent 58dc47bd1a
commit e87cc4e169
5 changed files with 136 additions and 136 deletions

View File

@ -4,7 +4,7 @@
Gomoku sound driver (quick hack of the Wiping sound driver)
used by wiping.c
used by gomoku.cpp
***************************************************************************/
@ -48,23 +48,23 @@ gomoku_sound_device::gomoku_sound_device(const machine_config &mconfig, const ch
void gomoku_sound_device::device_start()
{
gomoku_sound_channel *voice;
sound_channel *voice;
int ch;
/* get stream channels */
// get stream channels
m_stream = stream_alloc(0, 1, clock());
/* allocate a pair of buffers to mix into - 1 second's worth should be more than enough */
// allocate a pair of buffers to mix into - 1 second's worth should be more than enough
m_mixer_buffer = std::make_unique<short[]>(2 * clock());
m_mixer_buffer_2 = m_mixer_buffer.get() + clock();
m_mixer_buffer_2 = m_mixer_buffer.get() + clock(); // this is never used?
/* build the mixer table */
// build the mixer table
make_mixer_table(8, DEFGAIN);
/* start with sound enabled, many games don't have a sound enable register */
// start with sound enabled, many games don't have a sound enable register
m_sound_enable = 1;
/* reset all the voices */
// reset all the voices
for (ch = 0, voice = std::begin(m_channel_list); voice < std::end(m_channel_list); ch++, voice++)
{
voice->channel = ch;
@ -73,6 +73,16 @@ void gomoku_sound_device::device_start()
voice->volume = 0;
voice->oneshotplaying = 0;
}
save_item(NAME(m_soundregs1));
save_item(NAME(m_soundregs2));
save_pointer(NAME(m_mixer_buffer), 2 * clock());
// save_item(NAME(m_sound_enable)); // set to 1 at device start and never updated?
save_item(STRUCT_MEMBER(m_channel_list, channel));
save_item(STRUCT_MEMBER(m_channel_list, frequency));
save_item(STRUCT_MEMBER(m_channel_list, counter));
save_item(STRUCT_MEMBER(m_channel_list, volume));
save_item(STRUCT_MEMBER(m_channel_list, oneshotplaying));
}
@ -83,27 +93,27 @@ void gomoku_sound_device::device_start()
void gomoku_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
stream_sample_t *buffer = outputs[0];
gomoku_sound_channel *voice;
sound_channel *voice;
short *mix;
int i, ch;
int ch;
/* if no sound, we're done */
// if no sound, we're done
if (m_sound_enable == 0)
{
memset(buffer, 0, samples * sizeof(*buffer));
return;
}
/* zap the contents of the mixer buffer */
// zap the contents of the mixer buffer
memset(m_mixer_buffer.get(), 0, samples * sizeof(short));
/* loop over each voice and add its contribution */
// loop over each voice and add its contribution
for (ch = 0, voice = std::begin(m_channel_list); voice < std::end(m_channel_list); ch++, voice++)
{
int f = 16 * voice->frequency;
int v = voice->volume;
/* only update if we have non-zero volume and frequency */
// only update if we have non-zero volume and frequency
if (v && f)
{
int w_base;
@ -116,8 +126,8 @@ void gomoku_sound_device::sound_stream_update(sound_stream &stream, stream_sampl
mix = m_mixer_buffer.get();
/* add our contribution */
for (i = 0; i < samples; i++)
// add our contribution
for (int i = 0; i < samples; i++)
{
c += f;
@ -125,7 +135,7 @@ void gomoku_sound_device::sound_stream_update(sound_stream &stream, stream_sampl
{
int offs = w_base | ((c >> 16) & 0x1f);
/* use full byte, first the high 4 bits, then the low 4 bits */
// use full byte, first the high 4 bits, then the low 4 bits
if (c & 0x8000)
*mix++ += ((m_sound_rom[offs] & 0x0f) - 8) * v;
else
@ -142,7 +152,7 @@ void gomoku_sound_device::sound_stream_update(sound_stream &stream, stream_sampl
if (voice->oneshotplaying)
{
/* use full byte, first the high 4 bits, then the low 4 bits */
// use full byte, first the high 4 bits, then the low 4 bits
if (c & 0x8000)
*mix++ += ((m_sound_rom[offs] & 0x0f) - 8) * v;
else
@ -150,33 +160,32 @@ void gomoku_sound_device::sound_stream_update(sound_stream &stream, stream_sampl
}
}
/* update the counter for this voice */
// update the counter for this voice
voice->counter = c;
}
}
}
/* mix it down */
// mix it down
mix = m_mixer_buffer.get();
for (i = 0; i < samples; i++)
for (int i = 0; i < samples; i++)
*buffer++ = m_mixer_lookup[*mix++];
}
/* build a table to divide by the number of voices; gain is specified as gain*16 */
// build a table to divide by the number of voices; gain is specified as gain*16
void gomoku_sound_device::make_mixer_table(int voices, int gain)
{
int count = voices * 128;
int i;
/* allocate memory */
// allocate memory
m_mixer_table = std::make_unique<int16_t[]>(256 * voices);
/* find the middle of the table */
// find the middle of the table
m_mixer_lookup = m_mixer_table.get() + (128 * voices);
/* fill in the table - 16 bit case */
for (i = 0; i < count; i++)
// fill in the table - 16 bit case
for (int i = 0; i < count; i++)
{
int val = i * gain * 16 / voices;
if (val > 32767) val = 32767;
@ -188,19 +197,19 @@ void gomoku_sound_device::make_mixer_table(int voices, int gain)
/********************************************************************************/
WRITE8_MEMBER( gomoku_sound_device::sound1_w )
void gomoku_sound_device::sound1_w(offs_t offset, uint8_t data)
{
gomoku_sound_channel *voice;
sound_channel *voice;
int base;
int ch;
/* update the streams */
// update the streams
m_stream->update();
/* set the register */
// set the register
m_soundregs1[offset] = data;
/* recompute all the voice parameters */
// recompute all the voice parameters
for (ch = 0, base = 0, voice = m_channel_list; voice < m_channel_list + 3; ch++, voice++, base += 8)
{
voice->channel = ch;
@ -210,19 +219,19 @@ WRITE8_MEMBER( gomoku_sound_device::sound1_w )
}
}
WRITE8_MEMBER( gomoku_sound_device::sound2_w )
void gomoku_sound_device::sound2_w(offs_t offset, uint8_t data)
{
gomoku_sound_channel *voice;
sound_channel *voice;
int base;
int ch;
/* update the streams */
// update the streams
m_stream->update();
/* set the register */
// set the register
m_soundregs2[offset] = data;
/* recompute all the voice parameters */
// recompute all the voice parameters
for (ch = 0, base = 0, voice = m_channel_list; voice < m_channel_list + 3; ch++, voice++, base += 8)
{
voice->channel = ch;

View File

@ -15,8 +15,8 @@ class gomoku_sound_device : public device_t,
public:
gomoku_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 48'000);
DECLARE_WRITE8_MEMBER( sound1_w );
DECLARE_WRITE8_MEMBER( sound2_w );
void sound1_w(offs_t offset, uint8_t data);
void sound2_w(offs_t offset, uint8_t data);
protected:
// device-level overrides
@ -28,12 +28,12 @@ protected:
private:
void make_mixer_table(int voices, int gain);
/* 4 voices max */
// 4 voices max
static constexpr unsigned MAX_VOICES = 4;
struct gomoku_sound_channel
struct sound_channel
{
gomoku_sound_channel() { }
sound_channel() { }
int channel = 0;
int frequency = 0;
@ -43,15 +43,15 @@ private:
};
/* data about the sound system */
gomoku_sound_channel m_channel_list[MAX_VOICES];
// data about the sound system
sound_channel m_channel_list[MAX_VOICES];
/* global sound parameters */
// global sound parameters
required_region_ptr<uint8_t> m_sound_rom;
int m_sound_enable;
bool m_sound_enable;
sound_stream *m_stream;
/* mixer tables and internal buffers */
// mixer tables and internal buffers
std::unique_ptr<int16_t[]> m_mixer_table;
int16_t *m_mixer_lookup;
std::unique_ptr<short[]> m_mixer_buffer;

View File

@ -32,26 +32,24 @@ todo:
#include "speaker.h"
/* input ports are rotated 90 degrees */
READ8_MEMBER(gomoku_state::input_port_r)
// input ports are rotated 90 degrees
uint8_t gomoku_state::input_port_r(offs_t offset)
{
int i, res;
res = 0;
for (i = 0; i < 8; i++)
int res = 0;
for (int i = 0; i < 8; i++)
res |= ((m_inputs[i].read_safe(0xff) >> offset) & 1) << i;
return res;
}
void gomoku_state::gomoku_map(address_map &map)
void gomoku_state::prg_map(address_map &map)
{
map(0x0000, 0x47ff).rom();
map(0x4800, 0x4fff).ram();
map(0x5000, 0x53ff).ram().w(FUNC(gomoku_state::gomoku_videoram_w)).share("videoram");
map(0x5400, 0x57ff).ram().w(FUNC(gomoku_state::gomoku_colorram_w)).share("colorram");
map(0x5800, 0x58ff).ram().w(FUNC(gomoku_state::gomoku_bgram_w)).share("bgram");
map(0x5000, 0x53ff).ram().w(FUNC(gomoku_state::videoram_w)).share(m_videoram);
map(0x5400, 0x57ff).ram().w(FUNC(gomoku_state::colorram_w)).share(m_colorram);
map(0x5800, 0x58ff).ram().share(m_bgram);
map(0x6000, 0x601f).w("gomoku", FUNC(gomoku_sound_device::sound1_w));
map(0x6800, 0x681f).w("gomoku", FUNC(gomoku_sound_device::sound2_w));
map(0x7000, 0x7007).w("latch", FUNC(ls259_device::write_d1));
@ -108,25 +106,25 @@ INPUT_PORTS_END
static const gfx_layout charlayout =
{
8, 8, /* 8*8 characters */
256, /* 256 characters */
2, /* 2 bits per pixel */
{ 0, 4 }, /* the two bitplanes are packed in one byte */
8, 8, // 8*8 characters
256, // 256 characters
2, // 2 bits per pixel
{ 0, 4 }, // the two bitplanes are packed in one byte
{ 0, 1, 2, 3, 8+0, 8+1, 8+2, 8+3 },
{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 },
16*8 /* every char takes 16 consecutive bytes */
16*8 // every char takes 16 consecutive bytes
};
static GFXDECODE_START( gfx_gomoku )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 32 )
GFXDECODE_ENTRY( "chars", 0, charlayout, 0, 32 )
GFXDECODE_END
void gomoku_state::gomoku(machine_config &config)
{
/* basic machine hardware */
Z80(config, m_maincpu, XTAL(18'432'000)/12); /* 1.536 MHz ? */
m_maincpu->set_addrmap(AS_PROGRAM, &gomoku_state::gomoku_map);
// basic machine hardware
Z80(config, m_maincpu, XTAL(18'432'000)/12); // 1.536 MHz ?
m_maincpu->set_addrmap(AS_PROGRAM, &gomoku_state::prg_map);
m_maincpu->set_vblank_int("screen", FUNC(gomoku_state::irq0_line_hold));
ls259_device &latch(LS259(config, "latch")); // 7J
@ -134,19 +132,19 @@ void gomoku_state::gomoku(machine_config &config)
latch.q_out_cb<2>().set(FUNC(gomoku_state::bg_dispsw_w));
latch.q_out_cb<7>().set_nop(); // start LED?
/* video hardware */
// video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0));
m_screen->set_size(256, 256);
m_screen->set_visarea(0, 256-1, 16, 256-16-1);
m_screen->set_screen_update(FUNC(gomoku_state::screen_update_gomoku));
m_screen->set_screen_update(FUNC(gomoku_state::screen_update));
m_screen->set_palette("palette");
GFXDECODE(config, m_gfxdecode, "palette", gfx_gomoku);
PALETTE(config, "palette", FUNC(gomoku_state::gomoku_palette), 64);
PALETTE(config, "palette", FUNC(gomoku_state::palette), 64);
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
GOMOKU_SOUND(config, "gomoku").add_route(ALL_OUTPUTS, "mono", 1.0);
@ -154,14 +152,14 @@ void gomoku_state::gomoku(machine_config &config)
ROM_START( gomoku )
ROM_REGION( 0x10000, "maincpu", 0 ) // program
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "rj_1.7a", 0x0000, 0x1000, CRC(ed20d539) SHA1(7cbbc678cbe5c85b914ca44f82bdbd452cf694a0) )
ROM_LOAD( "rj_2.7c", 0x1000, 0x1000, CRC(26a28516) SHA1(53d5d134cd91020fa06e380d355deb1df6b9cb6e) )
ROM_LOAD( "rj_3.7d", 0x2000, 0x1000, CRC(d05db072) SHA1(9697c932c6dcee6f8536c9f0b3c84a719a7d3dee) )
ROM_LOAD( "rj_4.7f", 0x3000, 0x1000, CRC(6e3d1c18) SHA1(e2f7e4c0de3c78d1b8e686152458972f996b023a) )
ROM_LOAD( "rj_5.4e", 0x4000, 0x0800, CRC(eaf541b4) SHA1(bc7e7ec1ba68f71ab9ac86f9ae77971ddb9ce3a4) )
ROM_REGION( 0x1000, "gfx1", 0 ) // text char
ROM_REGION( 0x1000, "chars", 0 )
ROM_LOAD( "rj_6.4r", 0x0000, 0x1000, CRC(ed26ae36) SHA1(61cb73d7f2568e88e1c2981e7af3e9a3b26797d3) )
ROM_REGION( 0x1000, "gomoku", 0 ) // sound
@ -171,19 +169,19 @@ ROM_START( gomoku )
ROM_LOAD( "rj_prom.1m", 0x0000, 0x0020, CRC(5da2f2bd) SHA1(4355ccf06cb09ec3240dc92bda19b1f707a010ef) ) // TEXT color
ROM_LOAD( "rj_prom.1l", 0x0020, 0x0020, CRC(fe4ef393) SHA1(d4c63f8645afeadd13ff82087bcc497d8936d90b) ) // BG color
ROM_REGION( 0x0100, "user1", 0 ) // BG draw data X
ROM_REGION( 0x0100, "bg_x", 0 ) // BG draw data X
ROM_LOAD( "rj_prom.8n", 0x0000, 0x0100, CRC(9ba43222) SHA1(a443df49d7ee9dbfd258b09731d392bf1249cbfa) )
ROM_REGION( 0x0100, "user2", 0 ) // BG draw data Y
ROM_REGION( 0x0100, "bg_y", 0 ) // BG draw data Y
ROM_LOAD( "rj_prom.7p", 0x0000, 0x0100, CRC(5b5464f8) SHA1(b945efb8a7233f501d67f6b1be4e9d4967dc6719) )
ROM_REGION( 0x0100, "user3", 0 ) // BG character data
ROM_REGION( 0x0100, "bg_d", 0 ) // BG character data
ROM_LOAD( "rj_prom.7r", 0x0000, 0x0100, CRC(3004585a) SHA1(711b68140827f0f3dc71f2576fcf9b905c999e8d) )
ROM_REGION( 0x0020, "user4", 0 ) // unknown
ROM_REGION( 0x0020, "unkprom", 0 ) // unknown
ROM_LOAD( "rj_prom.9k", 0x0000, 0x0020, CRC(cff72923) SHA1(4f61375028ab62da46ed119bc81052f5f98c28d4) )
ROM_END
// YEAR, NAME, PARENT, MACHINE, INPUT, STATE INIT, MONITOR, COMPANY, FULLNAME, FLAGS
GAME( 1981, gomoku, 0, gomoku, gomoku, gomoku_state, empty_init, ROT90, "Nichibutsu", "Gomoku Narabe Renju", 0 )
GAME( 1981, gomoku, 0, gomoku, gomoku, gomoku_state, empty_init, ROT90, "Nichibutsu", "Gomoku Narabe Renju", MACHINE_SUPPORTS_SAVE )

View File

@ -20,34 +20,43 @@ public:
m_inputs(*this, {"IN0", "IN1", "DSW", "UNUSED0", "UNUSED1", "UNUSED2", "UNUSED3", "UNUSED4"}),
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen")
m_screen(*this, "screen"),
m_bg_x(*this, "bg_x"),
m_bg_y(*this, "bg_y"),
m_bg_d(*this, "bg_d")
{ }
void gomoku(machine_config &config);
protected:
virtual void video_start() override;
private:
required_shared_ptr<uint8_t> m_videoram;
required_shared_ptr<uint8_t> m_colorram;
required_shared_ptr<uint8_t> m_bgram;
int m_flipscreen;
int m_bg_dispsw;
tilemap_t *m_fg_tilemap;
bitmap_ind16 m_bg_bitmap;
optional_ioport_array<8> m_inputs;
DECLARE_READ8_MEMBER(input_port_r);
DECLARE_WRITE8_MEMBER(gomoku_videoram_w);
DECLARE_WRITE8_MEMBER(gomoku_colorram_w);
DECLARE_WRITE8_MEMBER(gomoku_bgram_w);
DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
DECLARE_WRITE_LINE_MEMBER(bg_dispsw_w);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
virtual void video_start() override;
void gomoku_palette(palette_device &palette) const;
uint32_t screen_update_gomoku(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
void gomoku_map(address_map &map);
required_region_ptr<uint8_t> m_bg_x;
required_region_ptr<uint8_t> m_bg_y;
required_region_ptr<uint8_t> m_bg_d;
bool m_flipscreen;
bool m_bg_dispsw;
tilemap_t *m_fg_tilemap;
bitmap_ind16 m_bg_bitmap;
uint8_t input_port_r(offs_t offset);
void videoram_w(offs_t offset, uint8_t data);
void colorram_w(offs_t offset, uint8_t data);
void flipscreen_w(int state);
void bg_dispsw_w(int state);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
void palette(palette_device &palette) const;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void prg_map(address_map &map);
};
#endif // MAME_INCLUDES_GOMOKU_H

View File

@ -20,7 +20,7 @@
******************************************************************************/
void gomoku_state::gomoku_palette(palette_device &palette) const
void gomoku_state::palette(palette_device &palette) const
{
const uint8_t *color_prom = memregion("proms")->base();
@ -69,29 +69,24 @@ TILE_GET_INFO_MEMBER(gomoku_state::get_fg_tile_info)
TILE_FLIPYX(flipyx));
}
WRITE8_MEMBER(gomoku_state::gomoku_videoram_w)
void gomoku_state::videoram_w(offs_t offset, uint8_t data)
{
m_videoram[offset] = data;
m_fg_tilemap->mark_tile_dirty(offset);
}
WRITE8_MEMBER(gomoku_state::gomoku_colorram_w)
void gomoku_state::colorram_w(offs_t offset, uint8_t data)
{
m_colorram[offset] = data;
m_fg_tilemap->mark_tile_dirty(offset);
}
WRITE8_MEMBER(gomoku_state::gomoku_bgram_w)
{
m_bgram[offset] = data;
}
WRITE_LINE_MEMBER(gomoku_state::flipscreen_w)
void gomoku_state::flipscreen_w(int state)
{
m_flipscreen = state ? 0 : 1;
}
WRITE_LINE_MEMBER(gomoku_state::bg_dispsw_w)
void gomoku_state::bg_dispsw_w(int state)
{
m_bg_dispsw = state ? 0 : 1;
}
@ -105,30 +100,23 @@ WRITE_LINE_MEMBER(gomoku_state::bg_dispsw_w)
void gomoku_state::video_start()
{
uint8_t *GOMOKU_BG_X = memregion( "user1" )->base();
uint8_t *GOMOKU_BG_Y = memregion( "user2" )->base();
uint8_t *GOMOKU_BG_D = memregion( "user3" )->base();
int x, y;
int bgdata;
int color;
m_screen->register_screen_bitmap(m_bg_bitmap);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gomoku_state::get_fg_tile_info)),TILEMAP_SCAN_ROWS,8,8,32, 32);
m_fg_tilemap->set_transparent_pen(0);
/* make background bitmap */
// make background bitmap
m_bg_bitmap.fill(0x20);
// board
for (y = 0; y < 256; y++)
for (int y = 0; y < 256; y++)
{
for (x = 0; x < 256; x++)
for (int x = 0; x < 256; x++)
{
bgdata = GOMOKU_BG_D[ GOMOKU_BG_X[x] + (GOMOKU_BG_Y[y] << 4) ];
int bgdata = m_bg_d[m_bg_x[x] + (m_bg_y[y] << 4)];
color = 0x20; // outside frame (black)
int color = 0x20; // outside frame (black)
if (bgdata & 0x01) color = 0x21; // board (brown)
if (bgdata & 0x02) color = 0x20; // frame line (while)
@ -136,6 +124,9 @@ void gomoku_state::video_start()
m_bg_bitmap.pix16((255 - y - 1) & 0xff, (255 - x + 7) & 0xff) = color;
}
}
save_item(NAME(m_flipscreen)); // set but never used?
save_item(NAME(m_bg_dispsw));
}
@ -145,32 +136,25 @@ void gomoku_state::video_start()
******************************************************************************/
uint32_t gomoku_state::screen_update_gomoku(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
uint32_t gomoku_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
uint8_t *GOMOKU_BG_X = memregion( "user1" )->base();
uint8_t *GOMOKU_BG_Y = memregion( "user2" )->base();
uint8_t *GOMOKU_BG_D = memregion( "user3" )->base();
int x, y;
int bgram;
int bgoffs;
int bgdata;
int color;
/* draw background layer */
// draw background layer
if (m_bg_dispsw)
{
/* copy bg bitmap */
// copy bg bitmap
copybitmap(bitmap, m_bg_bitmap, 0, 0, 0, 0, cliprect);
// stone
for (y = 0; y < 256; y++)
for (int y = 0; y < 256; y++)
{
for (x = 0; x < 256; x++)
for (int x = 0; x < 256; x++)
{
bgoffs = ((((255 - x - 2) / 14) | (((255 - y - 10) / 14) << 4)) & 0xff);
int bgoffs = ((((255 - x - 2) / 14) | (((255 - y - 10) / 14) << 4)) & 0xff);
bgdata = GOMOKU_BG_D[ GOMOKU_BG_X[x] + (GOMOKU_BG_Y[y] << 4) ];
bgram = m_bgram[bgoffs];
int bgdata = m_bg_d[m_bg_x[x] + (m_bg_y[y] << 4) ];
int bgram = m_bgram[bgoffs];
if (bgdata & 0x04)
{
@ -191,20 +175,20 @@ uint32_t gomoku_state::screen_update_gomoku(screen_device &screen, bitmap_ind16
}
// cursor
for (y = 0; y < 256; y++)
for (int y = 0; y < 256; y++)
{
for (x = 0; x < 256; x++)
for (int x = 0; x < 256; x++)
{
bgoffs = ((((255 - x - 2) / 14) | (((255 - y - 10) / 14) << 4)) & 0xff);
int bgoffs = ((((255 - x - 2) / 14) | (((255 - y - 10) / 14) << 4)) & 0xff);
bgdata = GOMOKU_BG_D[ GOMOKU_BG_X[x] + (GOMOKU_BG_Y[y] << 4) ];
bgram = m_bgram[bgoffs];
int bgdata = m_bg_d[m_bg_x[x] + (m_bg_y[y] << 4) ];
int bgram = m_bgram[bgoffs];
if (bgdata & 0x08)
{
if (bgram & 0x04)
{
color = 0x2f; // cursor (black)
color = 0x2f; // cursor (black)
}
else if (bgram & 0x08)
{