diff --git a/src/mame/drivers/galaxia.c b/src/mame/drivers/galaxia.c index 612968d4e7d..02180bff047 100644 --- a/src/mame/drivers/galaxia.c +++ b/src/mame/drivers/galaxia.c @@ -20,7 +20,7 @@ Quick PCB sketch: | | | 13l 13i 13h | | | - | PROM 11l 11i 11h S2636 XTAL | + | PROM 11l 11i 11h S2636 S2621 XTAL | |6-| ?MHz | | 10i 10h S2636 | |5-| | @@ -43,6 +43,8 @@ Quick PCB sketch: | |--| ------------------------------------------------------------------------------ +XTAL label is not readable on any PCB? + Astro Wars (port of Astro Fighter) is on a stripped down board of Galaxia, using only one 2636 chip, less RAM, and no PROM. @@ -51,8 +53,7 @@ using only one 2636 chip, less RAM, and no PROM. HW has many similarities with quasar.c / cvs.c / zac2650.c TODO: -- fix colors -- starfield hardware? +- fix colors, there's no color prom?! - improve bullets - accurate astrowar sprite/bg sync - XTAL @@ -69,6 +70,7 @@ TODO: static INTERRUPT_GEN( galaxia_interrupt ) { device_set_input_line_and_vector(device, 0, HOLD_LINE, 0x03); + cvs_scroll_stars(device->machine()); } @@ -83,21 +85,7 @@ static WRITE8_HANDLER(galaxia_video_w) galaxia_state *state = space->machine().driver_data(); // space->machine().primary_screen->update_partial(space->machine().primary_screen->vpos()); state->m_bg_tilemap->mark_tile_dirty(offset); - - if (*state->m_fo_state) - state->m_video[offset] = data; - else - state->m_color[offset] = data; -} - -static READ8_HANDLER(galaxia_video_r) -{ - galaxia_state *state = space->machine().driver_data(); - - if (*state->m_fo_state) - return state->m_video[offset]; - else - return state->m_color[offset]; + cvs_video_or_color_ram_w(space, offset, data); } static WRITE8_HANDLER(galaxia_scroll_w) @@ -125,24 +113,24 @@ static READ8_HANDLER(galaxia_collision_r) { galaxia_state *state = space->machine().driver_data(); space->machine().primary_screen->update_partial(space->machine().primary_screen->vpos()); - return state->m_collision; + return state->m_collision_register; } static READ8_HANDLER(galaxia_collision_clear) { galaxia_state *state = space->machine().driver_data(); space->machine().primary_screen->update_partial(space->machine().primary_screen->vpos()); - state->m_collision = 0; + state->m_collision_register = 0; return 0xff; } static ADDRESS_MAP_START( galaxia_mem_map, AS_PROGRAM, 8 ) AM_RANGE(0x0000, 0x13ff) AM_ROM - AM_RANGE(0x1400, 0x14ff) AM_MIRROR(0x6000) AM_RAM AM_BASE_MEMBER(galaxia_state, m_bullet) + AM_RANGE(0x1400, 0x14ff) AM_MIRROR(0x6000) AM_RAM AM_BASE_MEMBER(galaxia_state, m_bullet_ram) AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_0", s2636_work_ram_r, s2636_work_ram_w) AM_RANGE(0x1600, 0x16ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_1", s2636_work_ram_r, s2636_work_ram_w) AM_RANGE(0x1700, 0x17ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_2", s2636_work_ram_r, s2636_work_ram_w) - AM_RANGE(0x1800, 0x1bff) AM_MIRROR(0x6000) AM_READWRITE(galaxia_video_r, galaxia_video_w) AM_BASE_MEMBER(galaxia_state, m_video) + AM_RANGE(0x1800, 0x1bff) AM_MIRROR(0x6000) AM_READWRITE(cvs_video_or_color_ram_r, galaxia_video_w) AM_BASE_MEMBER(galaxia_state, m_video_ram) AM_RANGE(0x1c00, 0x1fff) AM_MIRROR(0x6000) AM_RAM AM_RANGE(0x2000, 0x33ff) AM_ROM AM_RANGE(0x7214, 0x7214) AM_READ_PORT("IN0") @@ -152,8 +140,8 @@ static ADDRESS_MAP_START( astrowar_mem_map, AS_PROGRAM, 8 ) AM_RANGE(0x0000, 0x13ff) AM_ROM AM_RANGE(0x1400, 0x14ff) AM_MIRROR(0x6000) AM_RAM AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_0", s2636_work_ram_r, s2636_work_ram_w) - AM_RANGE(0x1800, 0x1bff) AM_MIRROR(0x6000) AM_READWRITE(galaxia_video_r, galaxia_video_w) AM_BASE_MEMBER(galaxia_state, m_video) - AM_RANGE(0x1c00, 0x1cff) AM_MIRROR(0x6000) AM_RAM AM_BASE_MEMBER(galaxia_state, m_bullet) + AM_RANGE(0x1800, 0x1bff) AM_MIRROR(0x6000) AM_READWRITE(cvs_video_or_color_ram_r, galaxia_video_w) AM_BASE_MEMBER(galaxia_state, m_video_ram) + AM_RANGE(0x1c00, 0x1cff) AM_MIRROR(0x6000) AM_RAM AM_BASE_MEMBER(galaxia_state, m_bullet_ram) AM_RANGE(0x2000, 0x33ff) AM_ROM ADDRESS_MAP_END @@ -283,19 +271,19 @@ static const gfx_layout tiles8x8x2_layout = }; static GFXDECODE_START( galaxia ) - GFXDECODE_ENTRY( "gfx1", 0, tiles8x8x2_layout, 0, 16 ) + GFXDECODE_ENTRY( "gfx1", 0, tiles8x8x2_layout, 0, 4 ) GFXDECODE_END static GFXDECODE_START( astrowar ) - GFXDECODE_ENTRY( "gfx1", 0, tiles8x8x1_layout, 0, 16 ) + GFXDECODE_ENTRY( "gfx1", 0, tiles8x8x1_layout, 0, 8 ) GFXDECODE_END static const s2636_interface galaxia_s2636_config[3] = { - { "screen", 0x100, 3, -27, "s2636snd_0" }, - { "screen", 0x100, 3, -27, "s2636snd_1" }, - { "screen", 0x100, 3, -27, "s2636snd_2" } + { "screen", 0x100, 3, -26, "s2636snd_0" }, + { "screen", 0x100, 3, -26, "s2636snd_1" }, + { "screen", 0x100, 3, -26, "s2636snd_2" } }; static const s2636_interface astrowar_s2636_config = @@ -324,7 +312,7 @@ static MACHINE_CONFIG_START( galaxia, galaxia_state ) MCFG_SCREEN_UPDATE_STATIC(galaxia) MCFG_GFXDECODE(galaxia) - MCFG_PALETTE_LENGTH(0x100) + MCFG_PALETTE_LENGTH(0x18+2) MCFG_PALETTE_INIT(galaxia) MCFG_VIDEO_START(galaxia) @@ -360,14 +348,14 @@ static MACHINE_CONFIG_START( astrowar, galaxia_state ) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) MCFG_SCREEN_SIZE(256, 256) - MCFG_SCREEN_VISIBLE_AREA(0*8, 30*8-1, 2*8, 32*8-1) + MCFG_SCREEN_VISIBLE_AREA(1*8, 31*8-1, 2*8, 32*8-1) MCFG_SCREEN_UPDATE_STATIC(astrowar) MCFG_GFXDECODE(astrowar) - MCFG_PALETTE_LENGTH(0x100) + MCFG_PALETTE_LENGTH(0x18+2) - MCFG_PALETTE_INIT(galaxia) - MCFG_VIDEO_START(galaxia) + MCFG_PALETTE_INIT(astrowar) + MCFG_VIDEO_START(astrowar) MCFG_S2636_ADD("s2636_0", astrowar_s2636_config) @@ -425,5 +413,5 @@ ROM_START( astrowar ) ROM_END -GAME( 1979, galaxia, 0, galaxia, galaxia, 0, ROT90, "Zaccaria / Zelco", "Galaxia", GAME_WRONG_COLORS | GAME_IMPERFECT_GRAPHICS ) -GAME( 1980, astrowar, 0, astrowar, galaxia, 0, ROT90, "Zaccaria / Zelco", "Astro Wars", GAME_WRONG_COLORS | GAME_IMPERFECT_GRAPHICS ) +GAME( 1979, galaxia, 0, galaxia, galaxia, 0, ROT90, "Zaccaria / Zelco", "Galaxia", GAME_IMPERFECT_COLORS | GAME_IMPERFECT_GRAPHICS ) +GAME( 1980, astrowar, 0, astrowar, galaxia, 0, ROT90, "Zaccaria / Zelco", "Astro Wars", GAME_IMPERFECT_COLORS | GAME_IMPERFECT_GRAPHICS ) diff --git a/src/mame/includes/galaxia.h b/src/mame/includes/galaxia.h index ac15271be62..67ca09ae5e7 100644 --- a/src/mame/includes/galaxia.h +++ b/src/mame/includes/galaxia.h @@ -4,28 +4,26 @@ ****************************************************************************/ -class galaxia_state : public driver_device +#include "includes/cvs.h" + +class galaxia_state : public cvs_state { public: galaxia_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) { } - - UINT8 *m_video; - UINT8 *m_color; - UINT8 *m_bullet; - - UINT8 *m_fo_state; + : cvs_state(mconfig, type, tag) { } tilemap_t *m_bg_tilemap; + bitmap_ind16 m_stars_bitmap; bitmap_ind16 m_temp_bitmap; - - UINT8 m_collision; }; /*----------- defined in video/galaxia.c -----------*/ PALETTE_INIT( galaxia ); +PALETTE_INIT( astrowar ); VIDEO_START( galaxia ); +VIDEO_START( astrowar ); + SCREEN_UPDATE_IND16( galaxia ); SCREEN_UPDATE_IND16( astrowar ); diff --git a/src/mame/mame.mak b/src/mame/mame.mak index a8812978a79..302f23099b7 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -573,6 +573,7 @@ $(MAMEOBJ)/comad.a: \ $(MAMEOBJ)/cvs.a: \ $(DRIVERS)/cvs.o $(VIDEO)/cvs.o \ + $(DRIVERS)/galaxia.o $(VIDEO)/galaxia.o \ $(DRIVERS)/quasar.o $(VIDEO)/quasar.o \ $(MAMEOBJ)/dataeast.a: \ @@ -1570,7 +1571,6 @@ $(MAMEOBJ)/yunsung.a: \ $(DRIVERS)/yunsun16.o $(VIDEO)/yunsun16.o \ $(MAMEOBJ)/zaccaria.a: \ - $(DRIVERS)/galaxia.o $(VIDEO)/galaxia.o \ $(DRIVERS)/laserbat.o $(AUDIO)/laserbat.o \ $(DRIVERS)/zac2650.o $(VIDEO)/zac2650.o \ $(DRIVERS)/zaccaria.o $(VIDEO)/zaccaria.o \ diff --git a/src/mame/video/galaxia.c b/src/mame/video/galaxia.c index 03a0cf59c52..a002d32c882 100644 --- a/src/mame/video/galaxia.c +++ b/src/mame/video/galaxia.c @@ -10,22 +10,61 @@ #include "video/s2636.h" #include "includes/galaxia.h" +#define SPRITE_PEN_BASE (0x10) +#define STAR_PEN (0x18) +#define BULLET_PEN (0x19) + + +// Colors are 1bpp, but how they are generated is a mystery +// there's no color prom on the pcb, nor palette ram PALETTE_INIT( galaxia ) { - for (int i = 0; i < 0x100 ; i++) + // estimated with video/photo references + const int lut_clr[0x18] = { + // background + 0, 1, 4, 5, + 0, 3, 6, 2, + 0, 1, 4, 5, // unused? + 0, 3, 1, 7, + + // sprites + 0, 4, 3, 6, 1, 5, 2, 7 + }; + + for (int i = 0; i < 0x18; i++) + palette_set_color_rgb(machine, i, pal1bit(lut_clr[i] >> 0), pal1bit(lut_clr[i] >> 1), pal1bit(lut_clr[i] >> 2)); + + // stars/bullets + palette_set_color_rgb(machine, STAR_PEN, pal1bit(1), pal1bit(1), pal1bit(1)); + palette_set_color_rgb(machine, BULLET_PEN, pal1bit(1), pal1bit(1), pal1bit(0)); +} + +PALETTE_INIT( astrowar ) +{ + // no reference material available(?), except for Data East astrof + const int lut_clr[8] = { 7, 3, 5, 1, 4, 2, 6, 7 }; + + for (int i = 0; i < 8; i++) { - // 1bpp is correct, but there should be more permutations - palette_set_color_rgb(machine, i, pal1bit(i >> 0), pal1bit(i >> 1), pal1bit(i >> 2)); + // background + palette_set_color_rgb(machine, i*2, 0, 0, 0); + palette_set_color_rgb(machine, i*2 + 1, pal1bit(lut_clr[i] >> 0), pal1bit(lut_clr[i] >> 1), pal1bit(lut_clr[i] >> 2)); + + // sprites + palette_set_color_rgb(machine, i | SPRITE_PEN_BASE, pal1bit(i >> 0), pal1bit(i >> 1), pal1bit(i >> 2)); } + + // stars/bullets + palette_set_color_rgb(machine, STAR_PEN, pal1bit(1), pal1bit(1), pal1bit(1)); + palette_set_color_rgb(machine, BULLET_PEN, pal1bit(1), pal1bit(1), pal1bit(0)); } static TILE_GET_INFO( get_bg_tile_info ) { galaxia_state *state = machine.driver_data(); - UINT8 code = state->m_video[tile_index]; - UINT8 attr = state->m_color[tile_index]; - UINT8 color = attr; + UINT8 code = state->m_video_ram[tile_index]; + UINT8 color = state->m_color_ram[tile_index]; // highest bits unused SET_TILE_INFO(0, code, color, 0); } @@ -33,12 +72,22 @@ static TILE_GET_INFO( get_bg_tile_info ) VIDEO_START( galaxia ) { galaxia_state *state = machine.driver_data(); - state->m_color = auto_alloc_array(machine, UINT8, 0x400); state->m_bg_tilemap = tilemap_create(machine, get_bg_tile_info, tilemap_scan_rows, 8, 8, 32, 32); state->m_bg_tilemap->set_transparent_pen(0); state->m_bg_tilemap->set_scroll_cols(8); + + machine.primary_screen->register_screen_bitmap(state->m_stars_bitmap); + cvs_init_stars(machine); +} +VIDEO_START( astrowar ) +{ + VIDEO_START_CALL(galaxia); + + galaxia_state *state = machine.driver_data(); + + state->m_bg_tilemap->set_scrolldx(8, 8); machine.primary_screen->register_screen_bitmap(state->m_temp_bitmap); } @@ -61,18 +110,18 @@ SCREEN_UPDATE_IND16( galaxia ) { for (x = cliprect.min_x; x <= cliprect.max_x; x++) { - bool bullet = state->m_bullet[y] && x == (state->m_bullet[y] ^ 0xff); - bool background = (bitmap.pix16(y, x) & 7) != 0; + bool bullet = state->m_bullet_ram[y] && x == (state->m_bullet_ram[y] ^ 0xff); + bool background = (bitmap.pix16(y, x) & 3) != 0; // draw bullets (guesswork) if (bullet) { // background vs. bullet collision detection - if (background) state->m_collision |= 0x80; + if (background) state->m_collision_register |= 0x80; // bullet size/color/priority is guessed - bitmap.pix16(y, x) = 7; - if (x) bitmap.pix16(y, x-1) = 7; + bitmap.pix16(y, x) = BULLET_PEN; + if (x) bitmap.pix16(y, x-1) = BULLET_PEN; } // copy the S2636 images into the main bitmap and check collision @@ -85,27 +134,32 @@ SCREEN_UPDATE_IND16( galaxia ) if (S2636_IS_PIXEL_DRAWN(pixel)) { // S2636 vs. S2636 collision detection - if (S2636_IS_PIXEL_DRAWN(pixel0) && S2636_IS_PIXEL_DRAWN(pixel1)) state->m_collision |= 0x01; - if (S2636_IS_PIXEL_DRAWN(pixel1) && S2636_IS_PIXEL_DRAWN(pixel2)) state->m_collision |= 0x02; - if (S2636_IS_PIXEL_DRAWN(pixel2) && S2636_IS_PIXEL_DRAWN(pixel0)) state->m_collision |= 0x04; + if (S2636_IS_PIXEL_DRAWN(pixel0) && S2636_IS_PIXEL_DRAWN(pixel1)) state->m_collision_register |= 0x01; + if (S2636_IS_PIXEL_DRAWN(pixel1) && S2636_IS_PIXEL_DRAWN(pixel2)) state->m_collision_register |= 0x02; + if (S2636_IS_PIXEL_DRAWN(pixel2) && S2636_IS_PIXEL_DRAWN(pixel0)) state->m_collision_register |= 0x04; // S2636 vs. bullet collision detection - if (bullet) state->m_collision |= 0x08; + if (bullet) state->m_collision_register |= 0x08; // S2636 vs. background collision detection if (background) { /* bit4 causes problems on 2nd level - if (S2636_IS_PIXEL_DRAWN(pixel0)) state->m_collision |= 0x10; */ - if (S2636_IS_PIXEL_DRAWN(pixel1)) state->m_collision |= 0x20; - if (S2636_IS_PIXEL_DRAWN(pixel2)) state->m_collision |= 0x40; + if (S2636_IS_PIXEL_DRAWN(pixel0)) state->m_collision_register |= 0x10; */ + if (S2636_IS_PIXEL_DRAWN(pixel1)) state->m_collision_register |= 0x20; + if (S2636_IS_PIXEL_DRAWN(pixel2)) state->m_collision_register |= 0x40; } - bitmap.pix16(y, x) = S2636_PIXEL_COLOR(pixel); + bitmap.pix16(y, x) = S2636_PIXEL_COLOR(pixel) | SPRITE_PEN_BASE; } } } + // cvs stars circuit + state->m_stars_bitmap.fill(0, cliprect); + cvs_update_stars(screen.machine(), state->m_stars_bitmap, cliprect, STAR_PEN, 1); + copybitmap_trans(bitmap, state->m_stars_bitmap, 0, 0, 0, 0, cliprect, 0); + return 0; } @@ -125,24 +179,23 @@ SCREEN_UPDATE_IND16( astrowar ) for (y = cliprect.min_y; y <= cliprect.max_y; y++) { // draw bullets (guesswork) - if (state->m_bullet[y]) + if (state->m_bullet_ram[y]) { - UINT8 pos = (state->m_bullet[y] ^ 0xff) - 8; + UINT8 pos = state->m_bullet_ram[y] ^ 0xff; // background vs. bullet collision detection - if (state->m_temp_bitmap.pix16(y, pos) & 7) - state->m_collision |= 0x02; + if (state->m_temp_bitmap.pix16(y, pos) & 1) + state->m_collision_register |= 0x02; // bullet size/color/priority is guessed - bitmap.pix16(y, pos) = 7; - if (pos) bitmap.pix16(y, pos-1) = 7; + bitmap.pix16(y, pos) = BULLET_PEN; + if (pos) bitmap.pix16(y, pos-1) = BULLET_PEN; } for (x = cliprect.min_x; x <= cliprect.max_x; x++) { // NOTE: similar to zac2650.c, the sprite chip runs at a different frequency than the background generator - // the exact timing is unknown, so we'll have to do with guesswork (s_offset and s_ratio) - int s_offset = 7; + // the exact timing ratio is unknown, so we'll have to do with guesswork float s_ratio = 256.0 / 196.0; float sx = x * s_ratio; @@ -150,19 +203,24 @@ SCREEN_UPDATE_IND16( astrowar ) break; // copy the S2636 bitmap into the main bitmap and check collision - int pixel = s2636_0_bitmap.pix16(y, x + s_offset); + int pixel = s2636_0_bitmap.pix16(y, x); if (S2636_IS_PIXEL_DRAWN(pixel)) { // S2636 vs. background collision detection - if ((state->m_temp_bitmap.pix16(y, (int)(sx)) | state->m_temp_bitmap.pix16(y, (int)(sx + 0.5))) & 7) - state->m_collision |= 0x01; + if ((state->m_temp_bitmap.pix16(y, (int)(sx)) | state->m_temp_bitmap.pix16(y, (int)(sx + 0.5))) & 1) + state->m_collision_register |= 0x01; - bitmap.pix16(y, (int)(sx)) = S2636_PIXEL_COLOR(pixel); - bitmap.pix16(y, (int)(sx + 0.5)) = S2636_PIXEL_COLOR(pixel); + bitmap.pix16(y, (int)(sx)) = S2636_PIXEL_COLOR(pixel) | SPRITE_PEN_BASE; + bitmap.pix16(y, (int)(sx + 0.5)) = S2636_PIXEL_COLOR(pixel) | SPRITE_PEN_BASE; } } } + // cvs stars circuit + state->m_stars_bitmap.fill(0, cliprect); + cvs_update_stars(screen.machine(), state->m_stars_bitmap, cliprect, STAR_PEN, 1); + copybitmap_trans(bitmap, state->m_stars_bitmap, 0, 0, 0, 0, cliprect, 0); + return 0; }