mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
galaxia: remove partial updates, it was problematic for this driver and unneeded,
quasar: correct cpu speed and improve vblank duration to fix game speed bug on 3rd level, s2636: remove render_first_line, add a start_new_frame instead
This commit is contained in:
parent
27b766f1c3
commit
714c179702
@ -518,7 +518,7 @@ offs_t s2650_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
|
||||
flags = STEP_COND;
|
||||
break;
|
||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
|
||||
util::stream_format(stream, z80 ? "cp r0,%d" : "comz,%d", rv);
|
||||
util::stream_format(stream, z80 ? "cp r0,r%d" : "comz,%d", rv);
|
||||
break;
|
||||
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
||||
util::stream_format(stream, z80 ? "cp r%d,%s" : "comi,%d %s", rv, IMM(pc, params));
|
||||
|
@ -228,17 +228,6 @@ bitmap_ind16 const &s2636_device::update(const rectangle &cliprect)
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// render the first line into the bitmap
|
||||
//-------------------------------------------------
|
||||
|
||||
void s2636_device::render_first_line()
|
||||
{
|
||||
m_screen_line = 0;
|
||||
render_next_line();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// render next line into the bitmap
|
||||
//-------------------------------------------------
|
||||
@ -249,7 +238,7 @@ void s2636_device::render_next_line()
|
||||
|
||||
// pre-clear the line for convenience
|
||||
rectangle const &vis_area = screen().visible_area();
|
||||
uint16_t *const row = &m_bitmap.pix(m_screen_line);
|
||||
uint16_t *const row = &m_bitmap.pix(m_screen_line);
|
||||
m_bitmap.plot_box(0, m_screen_line, m_bitmap.width(), 1, 0);
|
||||
|
||||
if ((vis_area.min_y > m_screen_line) || (vis_area.max_y < m_screen_line))
|
||||
@ -300,8 +289,8 @@ void s2636_device::render_next_line()
|
||||
m_obj_cnt[i] -= obj_inc;
|
||||
|
||||
// fetch appropriate line from object
|
||||
uint8_t const obj_bits = m_registers[OFFS_OBJ[i] + OBJ_HEIGHT - 1 - (m_obj_cnt[i] >> 3)];
|
||||
uint16_t const obj_clr = object_color(i) | 0x08 | (0x10 << i);
|
||||
uint8_t const obj_bits = m_registers[OFFS_OBJ[i] + OBJ_HEIGHT - 1 - (m_obj_cnt[i] >> 3)];
|
||||
uint16_t const obj_clr = object_color(i) | 0x08 | (0x10 << i);
|
||||
|
||||
// blit it to the line ignoring intermediate pixels
|
||||
int const obj_h_cnt = m_registers[OFFS_OBJ[i] + (m_obj_dup[i] ? OFFS_HCB : OFFS_HC)] + m_x_offset;
|
||||
@ -331,15 +320,15 @@ void s2636_device::render_next_line()
|
||||
}
|
||||
|
||||
// let's take a look at the score display
|
||||
uint16_t const bg_clr = m_registers[REG_BG_ENB_CLR] & 0x07;
|
||||
int const score_row = m_vis_line - m_y_offset - SCORE_START_Y[m_registers[REG_SCORE_FMT] & 0x01];
|
||||
uint16_t const bg_clr = m_registers[REG_BG_ENB_CLR] & 0x07;
|
||||
int const score_row = m_vis_line - m_y_offset - SCORE_START_Y[m_registers[REG_SCORE_FMT] & 0x01];
|
||||
if ((0 <= score_row) && (SCORE_HEIGHT > score_row))
|
||||
{
|
||||
int const (&score_start_x)[SCORE_DIGITS] = SCORE_START_X[(m_registers[REG_SCORE_FMT] >> 1) & 0x01];
|
||||
for (int i = 0; i < SCORE_DIGITS; i++)
|
||||
{
|
||||
uint16_t score_bits = SCORE_FONT[score_digit(i)][score_row >> 2];
|
||||
int screen_col = vis_area.min_x + ((score_start_x[i] + m_x_offset) * m_divider);
|
||||
uint16_t score_bits = SCORE_FONT[score_digit(i)][score_row >> 2];
|
||||
int screen_col = vis_area.min_x + ((score_start_x[i] + m_x_offset) * m_divider);
|
||||
while (score_bits && (vis_area.max_x >= screen_col))
|
||||
{
|
||||
if (score_bits & 0x0001) row[screen_col] |= bg_clr | 0x08;
|
||||
@ -350,16 +339,16 @@ void s2636_device::render_next_line()
|
||||
}
|
||||
|
||||
// work out how the background pattern will be drawn
|
||||
bool const bg_enable = bool(m_registers[REG_BG_ENB_CLR] & 0x08);
|
||||
int const bg_row = m_vis_line - m_y_offset - BG_START_Y;
|
||||
bool const bg_draw = bg_enable && (0 <= bg_row) && (BG_HEIGHT > bg_row);
|
||||
int const bg_vbar_offs = OFFS_VBAR_DEF + ((bg_row / 20) << 2) + (((bg_row % 20) >= 2) ? 2 : 0);
|
||||
int const bg_hbar_offs = OFFS_HBAR_DEF + (bg_row / 40);
|
||||
uint16_t const bg_vbar_bits = (uint16_t(m_registers[bg_vbar_offs]) << 8) | uint16_t(m_registers[bg_vbar_offs + 1]);
|
||||
uint8_t const bg_hbar_bits = m_registers[bg_hbar_offs];
|
||||
bool const bg_hbar_stretch = bool(bg_hbar_bits & (1 << ((((bg_row % 40) >= 20) ? 3 : 0) + (((bg_row % 20) >= 11) ? 2 : ((bg_row % 20) >= 2) ? 1 : 0))));
|
||||
int const bg_hbar_width = bg_hbar_stretch ? 8 : (0xc0 == (bg_hbar_bits & 0xc0)) ? 4 : (0x40 == (bg_hbar_bits & 0xc0)) ? 2 : 1;
|
||||
uint16_t const scrn_clr = bg_enable ? ((m_registers[REG_BG_ENB_CLR] >> 4) & 0x07) : 0x00;
|
||||
bool const bg_enable = bool(m_registers[REG_BG_ENB_CLR] & 0x08);
|
||||
int const bg_row = m_vis_line - m_y_offset - BG_START_Y;
|
||||
bool const bg_draw = bg_enable && (0 <= bg_row) && (BG_HEIGHT > bg_row);
|
||||
int const bg_vbar_offs = OFFS_VBAR_DEF + ((bg_row / 20) << 2) + (((bg_row % 20) >= 2) ? 2 : 0);
|
||||
int const bg_hbar_offs = OFFS_HBAR_DEF + (bg_row / 40);
|
||||
uint16_t const bg_vbar_bits = (uint16_t(m_registers[bg_vbar_offs]) << 8) | uint16_t(m_registers[bg_vbar_offs + 1]);
|
||||
uint8_t const bg_hbar_bits = m_registers[bg_hbar_offs];
|
||||
bool const bg_hbar_stretch = bool(bg_hbar_bits & (1 << ((((bg_row % 40) >= 20) ? 3 : 0) + (((bg_row % 20) >= 11) ? 2 : ((bg_row % 20) >= 2) ? 1 : 0))));
|
||||
int const bg_hbar_width = bg_hbar_stretch ? 8 : (0xc0 == (bg_hbar_bits & 0xc0)) ? 4 : (0x40 == (bg_hbar_bits & 0xc0)) ? 2 : 1;
|
||||
uint16_t const scrn_clr = bg_enable ? ((m_registers[REG_BG_ENB_CLR] >> 4) & 0x07) : 0x00;
|
||||
|
||||
for (int screen_col = vis_area.min_x, x = 0; vis_area.max_x >= screen_col; x++)
|
||||
{
|
||||
@ -372,8 +361,8 @@ void s2636_device::render_next_line()
|
||||
if ((row[screen_col] & 0x40) && (row[screen_col] & 0x80)) m_registers[REG_VBL_COL_OBJ] |= 0x01;
|
||||
|
||||
// work out if the background hits this pixel
|
||||
int const bg_col = x - m_x_offset - BG_START_X;
|
||||
bool const bg = bool(bg_vbar_bits & (1U << (15 - (bg_col >> 3))));
|
||||
int const bg_col = x - m_x_offset - BG_START_X;
|
||||
bool const bg = bool(bg_vbar_bits & (1U << (15 - (bg_col >> 3))));
|
||||
if (bg_draw && (0 <= bg_col) && (BG_WIDTH > bg_col) && bg && (bg_hbar_width > (bg_col & 0x07)))
|
||||
{
|
||||
// do object-background collisions
|
||||
@ -452,7 +441,6 @@ void s2636_device::write_intack(int state)
|
||||
// sound_stream_update - generate audio output
|
||||
//-------------------------------------------------
|
||||
|
||||
|
||||
void s2636_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
|
||||
{
|
||||
auto &buffer = outputs[0];
|
||||
|
@ -41,12 +41,13 @@ public:
|
||||
// D3 indicates how the S2636 drew this pixel - 0 = background, 1 = object/score
|
||||
bitmap_ind16 const &bitmap() const { return m_bitmap; }
|
||||
|
||||
// this function is for backwards compatibility and will eventually be removed
|
||||
// use the functions below for per-scanline drawing/collisions
|
||||
// This function is for backwards compatibility and will eventually be removed.
|
||||
// Please note that it is not compatible with partial updates, use the functions
|
||||
// below for per-scanline drawing/collisions.
|
||||
bitmap_ind16 const &update(const rectangle &cliprect);
|
||||
|
||||
// call render_first_line to render the first line of the display and render_next_line for each additional line
|
||||
void render_first_line();
|
||||
// render_next_line will draw one line at a time, call start_new_frame at line 0
|
||||
void start_new_frame() { m_screen_line = 0; }
|
||||
void render_next_line();
|
||||
|
||||
uint8_t read_data(offs_t offset);
|
||||
@ -126,7 +127,7 @@ private:
|
||||
bitmap_ind16 m_bitmap;
|
||||
|
||||
// 256-byte register file (not all of this really exists)
|
||||
uint8_t m_registers[0x100];
|
||||
uint8_t m_registers[0x100];
|
||||
|
||||
// tracking where we're up to in the screen update
|
||||
bool m_vrst;
|
||||
|
@ -715,7 +715,7 @@ void cvs_state::main_cpu_io_map(address_map &map)
|
||||
void cvs_state::main_cpu_data_map(address_map &map)
|
||||
{
|
||||
map(S2650_CTRL_PORT, S2650_CTRL_PORT).rw(FUNC(cvs_state::collision_r), FUNC(cvs_state::audio_command_w));
|
||||
map(S2650_DATA_PORT, S2650_DATA_PORT).rw(FUNC(cvs_state::collision_clear), FUNC(cvs_state::video_fx_w));
|
||||
map(S2650_DATA_PORT, S2650_DATA_PORT).rw(FUNC(cvs_state::collision_clear_r), FUNC(cvs_state::video_fx_w));
|
||||
}
|
||||
|
||||
/*************************************
|
||||
@ -1211,7 +1211,7 @@ void cvs_state::cvs(machine_config &config)
|
||||
m_maincpu->set_addrmap(AS_DATA, &cvs_state::main_cpu_data_map);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(cvs_state::main_cpu_interrupt));
|
||||
m_maincpu->sense_handler().set("screen", FUNC(screen_device::vblank));
|
||||
m_maincpu->flag_handler().set(FUNC(cvs_state::write_s2650_flag));
|
||||
m_maincpu->flag_handler().set([this] (int state) { m_ram_view.select(state); });
|
||||
m_maincpu->intack_handler().set_constant(0x03);
|
||||
|
||||
S2650(config, m_audiocpu, XTAL(14'318'181) / 16);
|
||||
|
@ -21,23 +21,22 @@ void cvs_base_state::machine_reset()
|
||||
m_stars_scroll = 0;
|
||||
}
|
||||
|
||||
void cvs_base_state::write_s2650_flag(int state) // TODO: remove once set_memview is available via devcb
|
||||
{
|
||||
m_ram_view.select(state);
|
||||
}
|
||||
|
||||
// collision register accesors
|
||||
|
||||
uint8_t cvs_base_state::collision_r()
|
||||
{
|
||||
return m_collision_register;
|
||||
}
|
||||
|
||||
uint8_t cvs_base_state::collision_clear()
|
||||
uint8_t cvs_base_state::collision_clear_r()
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
m_collision_register = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// cvs stars hardware
|
||||
|
||||
void cvs_base_state::scroll_start()
|
||||
@ -48,11 +47,9 @@ void cvs_base_state::scroll_start()
|
||||
void cvs_base_state::init_stars()
|
||||
{
|
||||
int generator = 0;
|
||||
|
||||
// precalculate the star background
|
||||
|
||||
m_total_stars = 0;
|
||||
|
||||
// precalculate the star background
|
||||
for (int y = 255; y >= 0; y--)
|
||||
{
|
||||
for (int x = 511; x >= 0; x--)
|
||||
@ -98,7 +95,7 @@ void cvs_base_state::update_stars(bitmap_ind16 &bitmap, const rectangle &cliprec
|
||||
y = ~y;
|
||||
|
||||
if ((y >= cliprect.top()) && (y <= cliprect.bottom()) &&
|
||||
(update_always || (m_palette->pen_indirect(bitmap.pix(y, x)) == 0)))
|
||||
(update_always || (m_palette->pen_indirect(bitmap.pix(y, x)) == 0)))
|
||||
bitmap.pix(y, x) = star_pen;
|
||||
}
|
||||
}
|
||||
|
@ -73,9 +73,8 @@ protected:
|
||||
virtual void machine_start() override ATTR_COLD;
|
||||
virtual void machine_reset() override ATTR_COLD;
|
||||
|
||||
void write_s2650_flag(int state);
|
||||
uint8_t collision_r();
|
||||
uint8_t collision_clear();
|
||||
uint8_t collision_clear_r();
|
||||
void scroll_start();
|
||||
void init_stars() ATTR_COLD;
|
||||
void update_stars(bitmap_ind16 &bitmap, const rectangle &cliprect, const pen_t star_pen, bool update_always);
|
||||
|
@ -60,7 +60,16 @@ http://www.opdenkelder.com/Astrowars_manual.zip
|
||||
|
||||
HW has many similarities with quasar.cpp / cvs.cpp / zac2650.cpp
|
||||
real hardware video of Astro Wars can be seen here: youtu.be/eSrQFBMeDlM
|
||||
---
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
About the 1-bit different 13H ROM in "galaxiab" compared to the one in "galaxia"
|
||||
and "galaxiaa": The change is a RAM address from $1CD5(unknown) to $1CC5(player X
|
||||
position). When an alien is diving down, it reads from there. Set "galaxiac" also
|
||||
reads from $1CC5.
|
||||
|
||||
Also note that "galaxiab" 13H was dumped from 2 boards, so that should take away
|
||||
remaining suspicion that it might be a bad dump.
|
||||
|
||||
TODO:
|
||||
- go through everything in the schematics for astrowar / galaxia
|
||||
@ -109,8 +118,6 @@ private:
|
||||
void scroll_w(uint8_t data);
|
||||
void ctrlport_w(uint8_t data);
|
||||
void dataport_w(uint8_t data);
|
||||
uint8_t collision_r();
|
||||
uint8_t collision_clear();
|
||||
TILE_GET_INFO_MEMBER(get_bg_tile_info);
|
||||
void palette(palette_device &palette) const ATTR_COLD;
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
@ -138,11 +145,11 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*******************************************************************************
|
||||
|
||||
Video
|
||||
|
||||
***************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
static constexpr uint8_t SPRITE_PEN_BASE = 0x10;
|
||||
static constexpr uint8_t STAR_PEN = 0x18;
|
||||
@ -375,11 +382,11 @@ void galaxia_state::vblank_irq(int state)
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*******************************************************************************
|
||||
|
||||
I/O
|
||||
|
||||
***************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
template <uint8_t Which>
|
||||
void galaxia_state::video_w(offs_t offset, uint8_t data)
|
||||
@ -390,8 +397,6 @@ void galaxia_state::video_w(offs_t offset, uint8_t data)
|
||||
|
||||
void galaxia_state::scroll_w(uint8_t data)
|
||||
{
|
||||
m_screen->update_partial(m_screen->vpos());
|
||||
|
||||
// fixed scrolling area
|
||||
for (int i = 1; i < 6; i++)
|
||||
m_bg_tilemap->set_scrolly(i, data);
|
||||
@ -412,19 +417,6 @@ void galaxia_state::dataport_w(uint8_t data)
|
||||
// seems to be related to sound board comms
|
||||
}
|
||||
|
||||
uint8_t galaxia_state::collision_r()
|
||||
{
|
||||
m_screen->update_partial(m_screen->vpos());
|
||||
return m_collision_register;
|
||||
}
|
||||
|
||||
uint8_t galaxia_state::collision_clear()
|
||||
{
|
||||
m_screen->update_partial(m_screen->vpos());
|
||||
m_collision_register = 0;
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void galaxia_state::mem_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x13ff).rom();
|
||||
@ -466,15 +458,15 @@ void galaxia_state::io_map(address_map &map)
|
||||
void galaxia_state::data_map(address_map &map)
|
||||
{
|
||||
map(S2650_CTRL_PORT, S2650_CTRL_PORT).rw(FUNC(galaxia_state::collision_r), FUNC(galaxia_state::ctrlport_w));
|
||||
map(S2650_DATA_PORT, S2650_DATA_PORT).rw(FUNC(galaxia_state::collision_clear), FUNC(galaxia_state::dataport_w));
|
||||
map(S2650_DATA_PORT, S2650_DATA_PORT).rw(FUNC(galaxia_state::collision_clear_r), FUNC(galaxia_state::dataport_w));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*******************************************************************************
|
||||
|
||||
Inputs
|
||||
|
||||
***************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
static INPUT_PORTS_START( galaxia )
|
||||
PORT_START("IN0")
|
||||
@ -549,11 +541,11 @@ static INPUT_PORTS_START( galaxia )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*******************************************************************************
|
||||
|
||||
Machine Configs
|
||||
|
||||
***************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
static const gfx_layout tiles8x8x2_layout =
|
||||
{
|
||||
@ -583,14 +575,14 @@ void galaxia_state::galaxia(machine_config &config)
|
||||
m_maincpu->set_addrmap(AS_IO, &galaxia_state::io_map);
|
||||
m_maincpu->set_addrmap(AS_DATA, &galaxia_state::data_map);
|
||||
m_maincpu->sense_handler().set("screen", FUNC(screen_device::vblank));
|
||||
m_maincpu->flag_handler().set(FUNC(galaxia_state::write_s2650_flag));
|
||||
m_maincpu->flag_handler().set([this] (int state) { m_ram_view.select(state); });
|
||||
m_maincpu->intack_handler().set([this]() { m_maincpu->set_input_line(0, CLEAR_LINE); return 0x03; });
|
||||
|
||||
// video hardware
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_video_attributes(VIDEO_ALWAYS_UPDATE);
|
||||
m_screen->set_refresh_hz(50);
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500));
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(3500));
|
||||
m_screen->set_size(256, 256);
|
||||
m_screen->set_visarea(0*8, 30*8-1, 2*8, 32*8-1);
|
||||
m_screen->set_screen_update(FUNC(galaxia_state::screen_update));
|
||||
@ -624,14 +616,14 @@ void astrowar_state::astrowar(machine_config &config)
|
||||
m_maincpu->set_addrmap(AS_IO, &astrowar_state::io_map);
|
||||
m_maincpu->set_addrmap(AS_DATA, &astrowar_state::data_map);
|
||||
m_maincpu->sense_handler().set("screen", FUNC(screen_device::vblank));
|
||||
m_maincpu->flag_handler().set(FUNC(astrowar_state::write_s2650_flag));
|
||||
m_maincpu->flag_handler().set([this] (int state) { m_ram_view.select(state); });
|
||||
m_maincpu->intack_handler().set([this]() { m_maincpu->set_input_line(0, CLEAR_LINE); return 0x03; });
|
||||
|
||||
// video hardware
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_video_attributes(VIDEO_ALWAYS_UPDATE);
|
||||
m_screen->set_refresh_hz(50);
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500));
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(3500));
|
||||
m_screen->set_size(256, 256);
|
||||
m_screen->set_visarea(1*8, 31*8-1, 2*8, 32*8-1);
|
||||
m_screen->set_screen_update(FUNC(astrowar_state::screen_update));
|
||||
@ -650,11 +642,11 @@ void astrowar_state::astrowar(machine_config &config)
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*******************************************************************************
|
||||
|
||||
Game drivers
|
||||
|
||||
***************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
ROM_START( galaxia )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 )
|
||||
@ -703,7 +695,7 @@ ROM_START( galaxiab )
|
||||
ROM_LOAD( "galaxia.8h", 0x00000, 0x0400, CRC(f3b4ffde) SHA1(15b004e7821bfc145158b1e9435f061c524f6b86) )
|
||||
ROM_LOAD( "galaxia.10h", 0x00400, 0x0400, CRC(6d07fdd4) SHA1(d7d4b345a055275d59951788569db370bccd5195) )
|
||||
ROM_LOAD( "galaxia.11h", 0x00800, 0x0400, CRC(1520eb3d) SHA1(3683174da701e1124af0f9c2ee4a9a84f3fea33a) )
|
||||
ROM_LOAD( "galaxia.13h", 0x00c00, 0x0400, CRC(1d22219b) SHA1(6ab8ea8c78db30d80de98879018726d0420d30fe) ) // sldh - only 1 bit difference compared with set 1/2, however not considered a bad dump since it was found on two boards
|
||||
ROM_LOAD( "galaxia.13h", 0x00c00, 0x0400, CRC(1d22219b) SHA1(6ab8ea8c78db30d80de98879018726d0420d30fe) ) // sldh - only 1 bit difference compared with to galaxiaa, not a bad dump, see notes above
|
||||
ROM_LOAD( "galaxia.8i", 0x01000, 0x0400, CRC(45b88599) SHA1(3b79c21db1aa9d80fac81ac5a554e438805febd1) )
|
||||
ROM_LOAD( "galaxia.10i", 0x02000, 0x0400, CRC(76bd9fe3) SHA1(1abc8e40063aaa9140ea5e0341127eb0a7e86c88) ) // sldh
|
||||
ROM_LOAD( "galaxia.11i", 0x02400, 0x0400, CRC(4456808a) SHA1(f9e8cfdde0e17f13f1be297b2b4503ccc959b33c) )
|
||||
|
@ -10,10 +10,13 @@ Driver by Mike Coates and Pierpaolo Prazzoli
|
||||
TODO:
|
||||
- Missing enemy shooting sound effect, needs netlist?
|
||||
- Where is the flipscreen signal?
|
||||
- Phase 3 seems awfully hard, or is it normal? Even with cheats enabled, it is
|
||||
very hard to complete this level.
|
||||
- Test/service input isn't working?
|
||||
|
||||
It's picky about vblank duration: If it's too short, parts of the game run too
|
||||
slow. Or if it's too long, parts of the game run too fast, and eg. the 3rd level
|
||||
becomes nearly unbeatable. The implemented duration of 3500us approximately
|
||||
matches what was seen on a PCB video.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
Quasar by Zaccaria (1980)
|
||||
@ -310,26 +313,26 @@ void quasar_state::video_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
switch (m_page)
|
||||
{
|
||||
case 0: m_video_ram[offset] = data; break;
|
||||
case 1: m_color_ram[offset] = data & 7; break; // 3 bits of ram only - 3 x 2102
|
||||
case 2: m_effectram[offset] = data; break;
|
||||
case 3: m_effectcontrol = data; break;
|
||||
case 0: m_video_ram[offset] = data; break;
|
||||
case 1: m_color_ram[offset] = data & 7; break; // 3 bits of ram only - 3 x 2102
|
||||
case 2: m_effectram[offset] = data; break;
|
||||
case 3: m_effectcontrol = data; break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t quasar_state::io_r()
|
||||
{
|
||||
uint8_t ans = 0;
|
||||
uint8_t data = 0;
|
||||
|
||||
switch (m_io_page)
|
||||
{
|
||||
case 0: ans = m_in[0]->read(); break;
|
||||
case 1: ans = m_in[1]->read(); break;
|
||||
case 2: ans = m_dsw[0]->read(); break;
|
||||
case 3: ans = m_dsw[1]->read(); break;
|
||||
case 0: data = m_in[0]->read(); break;
|
||||
case 1: data = m_in[1]->read(); break;
|
||||
case 2: data = m_dsw[0]->read(); break;
|
||||
case 3: data = m_dsw[1]->read(); break;
|
||||
}
|
||||
|
||||
return ans;
|
||||
return data;
|
||||
}
|
||||
|
||||
void quasar_state::bullet_w(offs_t offset, uint8_t data)
|
||||
@ -362,7 +365,7 @@ void quasar_state::io(address_map &map)
|
||||
void quasar_state::data(address_map &map)
|
||||
{
|
||||
map(S2650_CTRL_PORT, S2650_CTRL_PORT).r(FUNC(quasar_state::collision_r)).nopw();
|
||||
map(S2650_DATA_PORT, S2650_DATA_PORT).rw(FUNC(quasar_state::collision_clear), FUNC(quasar_state::sh_command_w));
|
||||
map(S2650_DATA_PORT, S2650_DATA_PORT).rw(FUNC(quasar_state::collision_clear_r), FUNC(quasar_state::sh_command_w));
|
||||
}
|
||||
|
||||
|
||||
@ -517,7 +520,7 @@ GFXDECODE_END
|
||||
void quasar_state::quasar(machine_config &config)
|
||||
{
|
||||
// basic machine hardware
|
||||
S2650(config, m_maincpu, 14.318181_MHz_XTAL / 4); // 14.31818 MHz crystal divide by 4 on board
|
||||
S2650(config, m_maincpu, 14.318181_MHz_XTAL / 8);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &quasar_state::program);
|
||||
m_maincpu->set_addrmap(AS_IO, &quasar_state::io);
|
||||
m_maincpu->set_addrmap(AS_DATA, &quasar_state::data);
|
||||
@ -525,7 +528,7 @@ void quasar_state::quasar(machine_config &config)
|
||||
m_maincpu->sense_handler().set("screen", FUNC(screen_device::vblank));
|
||||
m_maincpu->intack_handler().set([this]() { m_maincpu->set_input_line(0, CLEAR_LINE); return 0x0a; });
|
||||
|
||||
i8035_device &audiocpu(I8035(config, "audiocpu", 6_MHz_XTAL)); // 6 MHz crystal divide by 15 in CPU
|
||||
i8035_device &audiocpu(I8035(config, "audiocpu", 6_MHz_XTAL));
|
||||
audiocpu.set_addrmap(AS_PROGRAM, &quasar_state::sound_map);
|
||||
audiocpu.set_addrmap(AS_IO, &quasar_state::sound_portmap);
|
||||
audiocpu.t1_in_cb().set(FUNC(quasar_state::audio_t1_r));
|
||||
@ -534,8 +537,8 @@ void quasar_state::quasar(machine_config &config)
|
||||
// video hardware
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_video_attributes(VIDEO_ALWAYS_UPDATE);
|
||||
m_screen->set_refresh_hz(50); // From dot clock
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
|
||||
m_screen->set_refresh_hz(50); // from dot clock
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(3500));
|
||||
m_screen->set_size(256, 256);
|
||||
m_screen->set_visarea(1*8+1, 29*8-1, 2*8, 32*8-1);
|
||||
m_screen->set_screen_update(FUNC(quasar_state::screen_update));
|
||||
|
@ -29,8 +29,10 @@ horizontal/vertical sync pulse.
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/s2650/s2650.h"
|
||||
#include "machine/s2636.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
@ -206,16 +208,13 @@ TIMER_CALLBACK_MEMBER(subhuntr_state::video_callback)
|
||||
|
||||
if (!y)
|
||||
{
|
||||
m_pvi1_h5->render_first_line();
|
||||
m_pvi2_l5->render_first_line();
|
||||
m_pvi3_n5->render_first_line();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pvi1_h5->render_next_line();
|
||||
m_pvi2_l5->render_next_line();
|
||||
m_pvi3_n5->render_next_line();
|
||||
m_pvi1_h5->start_new_frame();
|
||||
m_pvi2_l5->start_new_frame();
|
||||
m_pvi3_n5->start_new_frame();
|
||||
}
|
||||
m_pvi1_h5->render_next_line();
|
||||
m_pvi2_l5->render_next_line();
|
||||
m_pvi3_n5->render_next_line();
|
||||
|
||||
u16 const *src1 = &m_pvi1_h5->bitmap().pix(y);
|
||||
u16 const *src2 = &m_pvi2_l5->bitmap().pix(y);
|
||||
|
@ -219,16 +219,14 @@ TIMER_CALLBACK_MEMBER(laserbat_state_base::video_line)
|
||||
// update the PVIs
|
||||
if (!y)
|
||||
{
|
||||
m_pvi[0]->render_first_line();
|
||||
m_pvi[1]->render_first_line();
|
||||
m_pvi[2]->render_first_line();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pvi[0]->render_next_line();
|
||||
m_pvi[1]->render_next_line();
|
||||
m_pvi[2]->render_next_line();
|
||||
m_pvi[0]->start_new_frame();
|
||||
m_pvi[1]->start_new_frame();
|
||||
m_pvi[2]->start_new_frame();
|
||||
}
|
||||
m_pvi[0]->render_next_line();
|
||||
m_pvi[1]->render_next_line();
|
||||
m_pvi[2]->render_next_line();
|
||||
|
||||
uint16_t const *const pvi1_row = &m_pvi[0]->bitmap().pix(y);
|
||||
uint16_t const *const pvi2_row = &m_pvi[1]->bitmap().pix(y);
|
||||
uint16_t const *const pvi3_row = &m_pvi[2]->bitmap().pix(y);
|
||||
@ -319,7 +317,7 @@ void laserbat_state::laserbat_palette(palette_device &palette) const
|
||||
for red and green. LSB for blue is always effectively 1. The
|
||||
middle group is the MSB. Yet another crazy thing they did.
|
||||
|
||||
Each colour channel has an emitter follower buffer amlpifier
|
||||
Each colour channel has an emitter follower buffer amplifier
|
||||
biased with a 1k resistor to +5V and a 3k3 resistor to ground.
|
||||
Output is adjusted by connecting additional resistors across the
|
||||
leg to ground using an open collector buffer - 270R, 820R and
|
||||
|
Loading…
Reference in New Issue
Block a user