summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Ivan Vangelista <mesgnet@yahoo.it>2022-08-31 22:31:10 +0200
committer Ivan Vangelista <mesgnet@yahoo.it>2022-08-31 22:31:10 +0200
commit750f28cecdd73b30c9e727afbd7caf20175a9e97 (patch)
tree37cc0ffb8e2c9f09107da9557273833cdac3f791
parent339bfa52d9e7bd2973db24db63d9d8fa7618f6b1 (diff)
taito/galastrm.cpp, taito/gunbustr.cpp, taito/msisaac.cpp: consolidated drivers in single files, minor cleanups
-rw-r--r--src/mame/taito/galastrm.cpp715
-rw-r--r--src/mame/taito/galastrm.h111
-rw-r--r--src/mame/taito/galastrm_v.cpp535
-rw-r--r--src/mame/taito/groundfx.cpp6
-rw-r--r--src/mame/taito/gunbustr.cpp435
-rw-r--r--src/mame/taito/gunbustr.h79
-rw-r--r--src/mame/taito/gunbustr_v.cpp232
-rw-r--r--src/mame/taito/msisaac.cpp507
-rw-r--r--src/mame/taito/msisaac.h116
-rw-r--r--src/mame/taito/msisaac_v.cpp241
10 files changed, 1486 insertions, 1491 deletions
diff --git a/src/mame/taito/galastrm.cpp b/src/mame/taito/galastrm.cpp
index bd09bb323e6..60e91bd3627 100644
--- a/src/mame/taito/galastrm.cpp
+++ b/src/mame/taito/galastrm.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Hau
+// copyright-holders: Hau
+
/*
Galactic Storm
@@ -28,7 +29,7 @@ ENSONIQ 5701,5510,5505
OSC1:16MHz
OSC2:30.47618MHz
----------------------------------------------------------
-based on driver from drivers/gunbustr.cpp by Bryan McPhail & David Graves
+based on driver from taito/gunbustr.cpp by Bryan McPhail & David Graves
Written by Hau
07/03/2008
@@ -44,16 +45,664 @@ TODO:
#include "emu.h"
+
+#include "taito_en.h"
+#include "taitoio.h"
+#include "tc0100scn.h"
+#include "tc0110pcr.h"
+#include "tc0480scp.h"
+
#include "cpu/m68000/m68000.h"
#include "machine/adc0808.h"
#include "machine/eepromser.h"
-#include "taitoio.h"
#include "sound/es5506.h"
-#include "taito_en.h"
+#include "video/poly.h"
+
+#include "emupal.h"
+#include "screen.h"
#include "speaker.h"
-#include "galastrm.h"
+// configurable logging
+#define LOG_BADSPRITES (1U << 1)
+
+//#define VERBOSE (LOG_GENERAL | LOG_BADSPRITES)
+
+#include "logmacro.h"
+
+#define LOGBADSPRITES(...) LOGMASKED(LOG_BADSPRITES, __VA_ARGS__)
+
+
+namespace {
+
+class galastrm_state;
+
+struct gs_poly_data
+{
+ bitmap_ind16* texbase = nullptr;
+};
+
+class galastrm_renderer : public poly_manager<float, gs_poly_data, 2>
+{
+public:
+ galastrm_renderer(galastrm_state &state);
+
+ void tc0610_draw_scanline(s32 scanline, const extent_t& extent, const gs_poly_data& object, int threadid);
+ void tc0610_rotate_draw(bitmap_ind16 &srcbitmap, const rectangle &clip);
+
+ bitmap_ind16 &screenbits() { return m_screenbits; }
+
+private:
+ galastrm_state& m_state;
+ bitmap_ind16 m_screenbits;
+};
+
+
+class galastrm_state : public driver_device
+{
+ friend class galastrm_renderer;
+public:
+ galastrm_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_spriteram(*this,"spriteram"),
+ m_spritemap_rom(*this, "sprmaprom"),
+ m_maincpu(*this, "maincpu"),
+ m_eeprom(*this, "eeprom"),
+ m_tc0100scn(*this, "tc0100scn"),
+ m_tc0110pcr(*this, "tc0110pcr"),
+ m_tc0480scp(*this, "tc0480scp"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_screen(*this, "screen")
+ { }
+
+ void galastrm(machine_config &config);
+ DECLARE_READ_LINE_MEMBER(frame_counter_r);
+
+protected:
+ virtual void video_start() override;
+
+private:
+ required_shared_ptr<u32> m_spriteram;
+
+ required_region_ptr<u16> m_spritemap_rom;
+
+ required_device<cpu_device> m_maincpu;
+ required_device<eeprom_serial_93cxx_device> m_eeprom;
+ required_device<tc0100scn_device> m_tc0100scn;
+ required_device<tc0110pcr_device> m_tc0110pcr;
+ required_device<tc0480scp_device> m_tc0480scp;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<screen_device> m_screen;
+
+ struct gs_tempsprite
+ {
+ u8 gfx = 0U;
+ u32 code = 0U, color = 0U;
+ bool flipx = false, flipy = false;
+ int x = 0, y = 0;
+ int zoomx = 0, zoomy = 0;
+ u32 primask = 0U;
+ };
+
+ u16 m_frame_counter = 0U;
+ u16 m_tc0610_addr[2]{};
+ s16 m_tc0610_ctrl_reg[2][8]{};
+ std::unique_ptr<gs_tempsprite[]> m_spritelist{};
+ struct gs_tempsprite *m_sprite_ptr_pre{};
+ bitmap_ind16 m_tmpbitmaps{};
+ std::unique_ptr<galastrm_renderer> m_poly{};
+
+ s16 m_rsxb = 0;
+ s16 m_rsyb = 0;
+ s32 m_rsxoffs = 0;
+ s32 m_rsyoffs = 0;
+
+ static constexpr u8 X_OFFSET = 96;
+ static constexpr u8 Y_OFFSET = 60;
+
+ template<int Chip> void tc0610_w(offs_t offset, u16 data);
+ void coin_word_w(u8 data);
+ u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ INTERRUPT_GEN_MEMBER(interrupt);
+ void draw_sprites_pre(int x_offs, int y_offs);
+ void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int priority);
+
+ void main_map(address_map &map);
+};
+
+
+// video
+
+galastrm_renderer::galastrm_renderer(galastrm_state& state)
+ : poly_manager<float, gs_poly_data, 2>(state.machine())
+ , m_state(state)
+ , m_screenbits(state.m_screen->width(), state.m_screen->height())
+{
+}
+
+
+/******************************************************************/
+
+void galastrm_state::video_start()
+{
+ m_spritelist = std::make_unique<gs_tempsprite[]>(0x4000);
+
+ m_poly = std::make_unique<galastrm_renderer>(*this);
+
+ m_screen->register_screen_bitmap(m_tmpbitmaps);
+ m_screen->register_screen_bitmap(m_poly->screenbits());
+
+ save_item(NAME(m_rsxb));
+ save_item(NAME(m_rsyb));
+ save_item(NAME(m_rsxoffs));
+ save_item(NAME(m_rsyoffs));
+ save_item(NAME(m_frame_counter));
+ save_item(NAME(m_tc0610_addr));
+ save_item(NAME(m_tc0610_ctrl_reg));
+}
+
+
+/************************************************************
+ SPRITE DRAW ROUTINES
+
+We draw a series of small tiles ("chunks") together to
+create each big sprite. The spritemap ROM provides the lookup
+table for this. The game hardware looks up 16x16 sprite chunks
+from the spritemap ROM, creating a 64x64 sprite like this:
+
+ 0 1 2 3
+ 4 5 6 7
+ 8 9 10 11
+ 12 13 14 15
+
+(where the number is the word offset into the spritemap ROM).
+It can also create 32x32 sprites.
+
+NB: unused portions of the spritemap ROM contain hex FF's.
+It is a useful coding check to warn in the log if these
+are being accessed. [They can be inadvertently while
+spriteram is being tested, take no notice of that.]
+
+Heavy use is made of sprite zooming.
+
+ ***
+
+ Sprite table layout (4 long words per entry)
+
+ ------------------------------------------
+ 0 | ........ x....... ........ ........ | Flip X
+ 0 | ........ .xxxxxxx ........ ........ | ZoomX
+ 0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile
+ | |
+ 2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*]
+ 2 | ........ ......xx xxxxxx.. ........ | Palette bank
+ 2 | ........ ........ ......xx xxxxxxxx | X position
+ | |
+ 3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64)
+ 3 | ........ ......x. ........ ........ | Flip Y
+ 3 | ........ .......x xxxxxx.. ........ | ZoomY
+ 3 | ........ ........ ......xx xxxxxxxx | Y position
+ ------------------------------------------
+
+ [* 00=over BG1; 01=BG2; 10=BG3; 11=over text ???]
+
+********************************************************/
+
+void galastrm_state::draw_sprites_pre(int x_offs, int y_offs)
+{
+ int sprites_flipscreen = 0;
+
+ /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list
+ while processing sprite ram and then draw them all at the end */
+ m_sprite_ptr_pre = m_spritelist.get();
+
+ for (int offs = (m_spriteram.bytes() / 4 - 4); offs >= 0; offs -= 4)
+ {
+ u32 data = m_spriteram[offs + 0];
+ int flipx = (data & 0x00800000) >> 23;
+ int zoomx = (data & 0x007f0000) >> 16;
+ const u32 tilenum = (data & 0x00007fff);
+
+ if (!tilenum) continue;
+
+ data = m_spriteram[offs + 2];
+ const int priority = (data & 0x000c0000) >> 18;
+ int color = (data & 0x0003fc00) >> 10;
+ int x = (data & 0x000003ff);
+
+ data = m_spriteram[offs + 3];
+ const int dblsize = (data & 0x00040000) >> 18;
+ int flipy = (data & 0x00020000) >> 17;
+ int zoomy = (data & 0x0001fc00) >> 10;
+ int y = (data & 0x000003ff);
+
+ int bad_chunks = 0;
+ const int dimension = ((dblsize * 2) + 2); // 2 or 4
+ const int total_chunks = ((dblsize * 3) + 1) << 2; // 4 or 16
+ const u32 map_offset = tilenum << 2;
+
+ zoomx += 1;
+ zoomy += 1;
+
+ if (x > 713) x -= 1024; // 1024 x 512
+ if (y < 117) y += 512;
+
+ y = (-y & 0x3ff);
+ x -= x_offs;
+ y += y_offs;
+ if (flipy) y += (128 - zoomy);
+
+ for (int sprite_chunk = 0; sprite_chunk < total_chunks; sprite_chunk++)
+ {
+ const int j = sprite_chunk / dimension; // rows
+ const int k = sprite_chunk % dimension; // chunks per row
+
+ int px = k;
+ int py = j;
+ // pick tiles back to front for x and y flips
+ if (flipx) px = dimension - 1 - k;
+ if (flipy) py = dimension - 1 - j;
+
+ const u16 code = m_spritemap_rom[map_offset + px + (py << (dblsize + 1))];
+
+ if (code == 0xffff)
+ {
+ bad_chunks += 1;
+ continue;
+ }
+
+ int curx = x + ((k * zoomx) / dimension);
+ int cury = y + ((j * zoomy) / dimension);
+
+ const int zx = x + (((k + 1) * zoomx) / dimension) - curx;
+ const int zy = y + (((j + 1) * zoomy) / dimension) - cury;
+
+ if (sprites_flipscreen)
+ {
+ /* -zx/y is there to fix zoomed sprite coords in screenflip.
+ drawgfxzoom does not know to draw from flip-side of sprites when
+ screen is flipped; so we must correct the coords ourselves. */
+
+ curx = 320 - curx - zx;
+ cury = 256 - cury - zy;
+ flipx = !flipx;
+ flipy = !flipy;
+ }
+
+ m_sprite_ptr_pre->gfx = 0;
+ m_sprite_ptr_pre->code = code;
+ m_sprite_ptr_pre->color = color;
+ m_sprite_ptr_pre->flipx = !flipx;
+ m_sprite_ptr_pre->flipy = flipy;
+ m_sprite_ptr_pre->x = curx;
+ m_sprite_ptr_pre->y = cury;
+ m_sprite_ptr_pre->zoomx = zx << 12;
+ m_sprite_ptr_pre->zoomy = zy << 12;
+ m_sprite_ptr_pre->primask = priority;
+
+ m_sprite_ptr_pre++;
+ }
+ if (bad_chunks)
+ LOGBADSPRITES("Sprite number %04x had %02x invalid chunks\n", tilenum, bad_chunks);
+ }
+}
+
+void galastrm_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int priority)
+{
+ struct gs_tempsprite *sprite_ptr = m_sprite_ptr_pre;
+
+ while (sprite_ptr != m_spritelist.get())
+ {
+ sprite_ptr--;
+
+ if ((priority != 0 && sprite_ptr->primask != 0) ||
+ (priority == 0 && sprite_ptr->primask == 0))
+ {
+ m_gfxdecode->gfx(sprite_ptr->gfx)->prio_zoom_transpen(bitmap, cliprect,
+ sprite_ptr->code,
+ sprite_ptr->color,
+ sprite_ptr->flipx, sprite_ptr->flipy,
+ sprite_ptr->x, sprite_ptr->y,
+ sprite_ptr->zoomx, sprite_ptr->zoomy,
+ screen.priority(), primasks[sprite_ptr->primask], 0);
+ }
+ }
+}
+
+/**************************************************************
+ POLYGON RENDERER
+**************************************************************/
+
+void galastrm_renderer::tc0610_draw_scanline(s32 scanline, const extent_t& extent, const gs_poly_data& object, int threadid)
+{
+ u16 *const framebuffer = &m_screenbits.pix(scanline);
+ const s32 dudx = extent.param[0].dpdx;
+ const s32 dvdx = extent.param[1].dpdx;
+
+ s32 u = extent.param[0].start;
+ s32 v = extent.param[1].start;
+ for (int x = extent.startx; x < extent.stopx; x++)
+ {
+ framebuffer[x] = object.texbase->pix(v >> 16, u >> 16);
+ u += dudx;
+ v += dvdx;
+ }
+}
+
+void galastrm_renderer::tc0610_rotate_draw(bitmap_ind16 &srcbitmap, const rectangle &clip)
+{
+ struct polyVert
+ {
+ float x;
+ float y;
+// float z;
+ } tmpz[4];
+
+ vertex_t vert[4];
+ int rsx = m_state.m_tc0610_ctrl_reg[1][0];
+ int rsy = m_state.m_tc0610_ctrl_reg[1][1];
+ const int rzx = m_state.m_tc0610_ctrl_reg[1][2];
+ const int rzy = m_state.m_tc0610_ctrl_reg[1][3];
+ const int ryx = m_state.m_tc0610_ctrl_reg[1][5];
+ const int ryy = m_state.m_tc0610_ctrl_reg[1][4];
+ const int lx = srcbitmap.width();
+ const int ly = srcbitmap.height();
+
+ int pxx = 0;
+ int pxy = 0;
+ int pyx = 0;
+ int pyy = 0;
+ int zx = 0;
+ int zy = 0;
+
+ if (rzx != 0 || rzy != 0)
+ {
+ while (sqrtf(powf((float)pxx / 4096.0f, 2.0f) + powf((float)pxy / 4096.0f, 2.0f)) < (float)(lx / 2))
+ {
+ pxx += rzx;
+ pxy += rzy;
+ zx++;
+ }
+ while (sqrtf(powf((float)pyy / 4096.0f, 2.0f) + powf((float)pyx / 4096.0f, 2.0f)) < (float)(ly / 2))
+ {
+ pyy += rzx;
+ pyx += -rzy;
+ zy++;
+ }
+ }
+ float zsn = ((float)pyx / 4096.0f) / (float)(ly / 2);
+ float zcs = ((float)pxx / 4096.0f) / (float)(lx / 2);
+
+
+ if ((rsx == -240 && rsy == 1072) || !m_state.m_tc0610_ctrl_reg[1][7])
+ {
+ m_state.m_rsxoffs = 0;
+ m_state.m_rsyoffs = 0;
+ }
+ else
+ {
+ if (rsx > m_state.m_rsxb && m_state.m_rsxb < 0 && rsx-m_state.m_rsxb > 0x8000)
+ {
+ if (m_state.m_rsxoffs == 0)
+ m_state.m_rsxoffs = -0x10000;
+ else
+ m_state.m_rsxoffs = 0;
+ }
+ if (rsx < m_state.m_rsxb && m_state.m_rsxb > 0 && m_state.m_rsxb-rsx > 0x8000)
+ {
+ if (m_state.m_rsxoffs == 0)
+ m_state.m_rsxoffs = 0x10000 - 1;
+ else
+ m_state.m_rsxoffs = 0;
+ }
+ if (rsy > m_state.m_rsyb && m_state.m_rsyb < 0 && rsy-m_state.m_rsyb > 0x8000)
+ {
+ if (m_state.m_rsyoffs == 0)
+ m_state.m_rsyoffs = -0x10000;
+ else
+ m_state.m_rsyoffs = 0;
+ }
+ if (rsy < m_state.m_rsyb && m_state.m_rsyb > 0 && m_state.m_rsyb-rsy > 0x8000)
+ {
+ if (m_state.m_rsyoffs == 0)
+ m_state.m_rsyoffs = 0x10000 - 1;
+ else
+ m_state.m_rsyoffs = 0;
+ }
+ }
+ m_state.m_rsxb = rsx;
+ m_state.m_rsyb = rsy;
+ if (m_state.m_rsxoffs) rsx += m_state.m_rsxoffs;
+ if (m_state.m_rsyoffs) rsy += m_state.m_rsyoffs;
+ if (rsx < -0x14000 || rsx >= 0x14000) m_state.m_rsxoffs = 0;
+ if (rsy < -0x14000 || rsy >= 0x14000) m_state.m_rsyoffs = 0;
+
+
+ pxx = 0;
+ pxy = 0;
+ pyx = 0;
+ pyy = 0;
+ int yx = 0;
+ //int yy = 0;
+ //float ssn = 0.0;
+ //float scs = 0.0;
+ //float ysn = 0.0;
+ //float ycs = 0.0;
+
+ if (m_state.m_tc0610_ctrl_reg[1][7])
+ {
+ if (ryx != 0 || ryy != 0)
+ {
+ while (sqrtf(powf((float)pxx / 4096.0f, 2.0f) + powf((float)pxy / 4096.0f, 2.0f)) < (float)(lx / 2))
+ {
+ pxx += ryx;
+ pxy += ryy;
+ yx++;
+ }
+ while (sqrtf(powf((float)pyy / 4096.0f, 2.0f) + powf((float)pyx / 4096.0f, 2.0f)) < (float)(ly / 2))
+ {
+ pyy += ryx;
+ pyx += -ryy;
+ //yy++;
+ }
+ if (yx >= 0.0)
+ {
+ yx = (int)((8.0 - log((double)yx) / log(2.0)) * 6.0);
+ //ysn = sin(DEGREE_TO_RADIAN(yx));
+ //ycs = 1.0 - ysn*ysn;
+ }
+ }
+
+ pxx = 0;
+ pxy = 0;
+ pyx = 0;
+ pyy = 0;
+
+ if (rsx != 0 || rsy != 0)
+ {
+ while (sqrtf(powf((float)pxx / 65536.0f, 2.0) + powf((float)pxy / 65536.0f, 2.0f)) < (float)(lx / 2))
+ {
+ pxx += rsx;
+ pxy += rsy;
+ }
+ while (sqrtf(powf((float)pyy / 65536.0f, 2.0f) + powf((float)pyx / 65536.0f, 2.0f)) < (float)(ly / 2))
+ {
+ pyy += rsx;
+ pyx += -rsy;
+ }
+ }
+ //ssn = ((float)pxy/65536.0) / (float)(lx / 2);
+ //scs = ((float)pyy/65536.0) / (float)(ly / 2);
+ }
+
+ {
+// polyVert tmpz[4];
+ tmpz[0].x = ((float)(-zx) * zcs) - ((float)(-zy) * zsn);
+ tmpz[0].y = ((float)(-zx) * zsn) + ((float)(-zy) * zcs);
+// tmpz[0].z = 0.0;
+ tmpz[1].x = ((float)(-zx) * zcs) - ((float)(zy - 1) * zsn);
+ tmpz[1].y = ((float)(-zx) * zsn) + ((float)(zy - 1) * zcs);
+// tmpz[1].z = 0.0;
+ tmpz[2].x = ((float)(zx - 1) * zcs) - ((float)(zy - 1) * zsn);
+ tmpz[2].y = ((float)(zx - 1) * zsn) + ((float)(zy - 1) * zcs);
+// tmpz[2].z = 0.0;
+ tmpz[3].x = ((float)(zx - 1) * zcs) - ((float)(-zy) * zsn);
+ tmpz[3].y = ((float)(zx - 1) * zsn) + ((float)(-zy) * zcs);
+// tmpz[3].z = 0.0;
+
+ vert[0].x = tmpz[0].x + (float)(lx / 2);
+ vert[0].y = tmpz[0].y + (float)(ly / 2);
+ vert[1].x = tmpz[1].x + (float)(lx / 2);
+ vert[1].y = tmpz[1].y + (float)(ly / 2);
+ vert[2].x = tmpz[2].x + (float)(lx / 2);
+ vert[2].y = tmpz[2].y + (float)(ly / 2);
+ vert[3].x = tmpz[3].x + (float)(lx / 2);
+ vert[3].y = tmpz[3].y + (float)(ly / 2);
+ }
+
+ vert[0].p[0] = 0.0;
+ vert[0].p[1] = 0.0;
+ vert[1].p[0] = 0.0;
+ vert[1].p[1] = (float)(ly - 1) * 65536.0f;
+ vert[2].p[0] = (float)(lx - 1) * 65536.0f;
+ vert[2].p[1] = (float)(ly - 1) * 65536.0f;
+ vert[3].p[0] = (float)(lx - 1) * 65536.0f;
+ vert[3].p[1] = 0.0;
+
+ gs_poly_data& extra = object_data().next();
+ extra.texbase = &srcbitmap;
+
+ render_polygon<4, 2>(clip, render_delegate(&galastrm_renderer::tc0610_draw_scanline, this), vert);
+ wait();
+}
+
+/**************************************************************
+ SCREEN REFRESH
+**************************************************************/
+
+u32 galastrm_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ u8 layer[5];
+ u8 pivlayer[3];
+ static const u32 primasks[4] = {0xfffc, 0xfff0, 0xff00, 0x0};
+ bitmap_ind8 &priority_bitmap = screen.priority();
+
+ rectangle clip(0, screen.width() -1, 0, screen.height() - 1);
+
+ m_tc0100scn->tilemap_update();
+ m_tc0480scp->tilemap_update();
+
+ const u16 priority = m_tc0480scp->get_bg_priority();
+ layer[0] = (priority & 0xf000) >> 12; // tells us which bg layer is bottom
+ layer[1] = (priority & 0x0f00) >> 8;
+ layer[2] = (priority & 0x00f0) >> 4;
+ layer[3] = (priority & 0x000f) >> 0; // tells us which is top
+ layer[4] = 4; // text layer always over bg layers
+
+ pivlayer[0] = m_tc0100scn->bottomlayer();
+ pivlayer[1] = pivlayer[0] ^ 1;
+ pivlayer[2] = 2;
+
+ bitmap.fill(0, cliprect);
+ priority_bitmap.fill(0, clip);
+ m_tmpbitmaps.fill(0, clip);
+
+ m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[0], 0, 0);
+ m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[1], 0, 0);
+
+#if 0
+ if (layer[0] == 0 && layer[1] == 3 && layer[2] == 2 && layer[3] == 1)
+ {
+ if (!machine().input().code_pressed(KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1);
+ if (!machine().input().code_pressed(KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 4);
+ if (!machine().input().code_pressed(KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4);
+ if (!machine().input().code_pressed(KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 4);
+ }
+ else
+ {
+ if (!machine().input().code_pressed(KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1);
+ if (!machine().input().code_pressed(KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 2);
+ if (!machine().input().code_pressed(KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4);
+ if (!machine().input().code_pressed(KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 8);
+ }
+
+ if (layer[0] == 3 && layer[1] == 0 && layer[2] == 1 && layer[3] == 2)
+ {
+ for (int y = 0; y < priority_bitmap.height; y++)
+ {
+ for (int x = 0; x < priority_bitmap.width; x++)
+ {
+ u8 *pri = &priority_bitmap.pix(y, x);
+ if (!(*pri & 0x02) && m_tmpbitmaps.pix(y, x))
+ *pri |= 0x04;
+ }
+ }
+ }
+
+ draw_sprites_pre(machine(), 42 - X_OFFSET, -571 + Y_OFFSET);
+ draw_sprites(screen, m_tmpbitmaps, clip, primasks, 1);
+
+ copybitmap_trans(bitmap, m_polybitmap, 0, 0, 0, 0, cliprect, 0);
+ m_polybitmap->fill(0, clip);
+ tc0610_rotate_draw(machine(), m_polybitmap, m_tmpbitmaps, cliprect);
+
+ priority_bitmap.fill(0, cliprect);
+ draw_sprites(screen, bitmap, cliprect, primasks, 0);
+
+ if (!machine().input().code_pressed(KEYCODE_B)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0);
+ if (!machine().input().code_pressed(KEYCODE_M)) m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[2], 0, 0);
+
+
+
+#else
+ if (layer[0] == 0 && layer[1] == 3 && layer[2] == 2 && layer[3] == 1)
+ {
+ m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1);
+ m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 4);
+ m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4);
+ m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 4);
+ }
+ else
+ {
+ m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1);
+ m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 2);
+ m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4);
+ m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 8);
+ }
+
+ if (layer[0] == 3 && layer[1] == 0 && layer[2] == 1 && layer[3] == 2)
+ {
+ for (int y=0; y < priority_bitmap.height(); y++)
+ {
+ for (int x=0; x < priority_bitmap.width(); x++)
+ {
+ u8 *pri = &priority_bitmap.pix(y, x);
+ if (!(*pri & 0x02) && m_tmpbitmaps.pix(y, x))
+ *pri |= 0x04;
+ }
+ }
+ }
+
+ draw_sprites_pre(42 - X_OFFSET, -571 + Y_OFFSET);
+ draw_sprites(screen, m_tmpbitmaps, clip, primasks, 1);
+
+ copybitmap_trans(bitmap, m_poly->screenbits(), 0, 0, 0, 0, cliprect, 0);
+ m_poly->screenbits().fill(0, clip);
+ m_poly->tc0610_rotate_draw(m_tmpbitmaps, cliprect);
+
+ priority_bitmap.fill(0, cliprect);
+ draw_sprites(screen, bitmap, cliprect, primasks, 0);
+
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0);
+ m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[2], 0, 0);
+#endif
+
+ return 0;
+}
+
+
+// machine
+
/*********************************************************************/
INTERRUPT_GEN_MEMBER(galastrm_state::interrupt)
@@ -93,18 +742,18 @@ void galastrm_state::coin_word_w(u8 data)
void galastrm_state::main_map(address_map &map)
{
map(0x000000, 0x0fffff).rom();
- map(0x200000, 0x21ffff).ram(); /* main CPU ram */
- map(0x300000, 0x303fff).ram().share("spriteram");
+ map(0x200000, 0x21ffff).ram(); // main RAM
+ map(0x300000, 0x303fff).ram().share(m_spriteram);
map(0x400000, 0x400007).rw("tc0510nio", FUNC(tc0510nio_device::read), FUNC(tc0510nio_device::write));
map(0x40fff0, 0x40fff3).nopw();
map(0x500000, 0x500007).rw("adc", FUNC(adc0808_device::data_r), FUNC(adc0808_device::address_offset_start_w)).umask32(0xffffffff);
- map(0x600000, 0x6007ff).rw("taito_en:dpram", FUNC(mb8421_device::left_r), FUNC(mb8421_device::left_w)); /* Sound shared ram */
- map(0x800000, 0x80ffff).rw(m_tc0480scp, FUNC(tc0480scp_device::ram_r), FUNC(tc0480scp_device::ram_w)); /* tilemaps */
+ map(0x600000, 0x6007ff).rw("taito_en:dpram", FUNC(mb8421_device::left_r), FUNC(mb8421_device::left_w)); // Sound shared RAM
+ map(0x800000, 0x80ffff).rw(m_tc0480scp, FUNC(tc0480scp_device::ram_r), FUNC(tc0480scp_device::ram_w)); // tilemaps
map(0x830000, 0x83002f).rw(m_tc0480scp, FUNC(tc0480scp_device::ctrl_r), FUNC(tc0480scp_device::ctrl_w));
- map(0x900000, 0x900003).rw(m_tc0110pcr, FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_rbswap_word_w)); /* TC0110PCR */
- map(0xb00000, 0xb00003).w(FUNC(galastrm_state::tc0610_w<0>)); /* TC0610 */
+ map(0x900000, 0x900003).rw(m_tc0110pcr, FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_rbswap_word_w));
+ map(0xb00000, 0xb00003).w(FUNC(galastrm_state::tc0610_w<0>));
map(0xc00000, 0xc00003).w(FUNC(galastrm_state::tc0610_w<1>));
- map(0xd00000, 0xd0ffff).rw(m_tc0100scn, FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* piv tilemaps */
+ map(0xd00000, 0xd0ffff).rw(m_tc0100scn, FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); // piv tilemaps
map(0xd20000, 0xd2000f).rw(m_tc0100scn, FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
}
@@ -124,7 +773,7 @@ static INPUT_PORTS_START( galastrm )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN1")
-// PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) /* Freeze input */
+// PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) // Freeze input
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -157,17 +806,17 @@ INPUT_PORTS_END
static const gfx_layout tile16x16_layout =
{
- 16,16, /* 16*16 sprites */
+ 16,16, // 16*16 sprites
RGN_FRAC(1,1),
- 4, /* 4 bits per pixel */
+ 4, // 4 bits per pixel
{ STEP4(0,16) },
{ STEP16(0,1) },
{ STEP16(0,16*4) },
- 64*16 /* every sprite takes 128 consecutive bytes */
+ 64*16 // every sprite takes 128 consecutive bytes
};
static GFXDECODE_START( gfx_galastrm )
- GFXDECODE_ENTRY( "sprites", 0x0, tile16x16_layout, 0, 4096/16 )
+ GFXDECODE_ENTRY( "sprites", 0x0, tile16x16_layout, 0, 4096 / 16 )
GFXDECODE_END
@@ -179,14 +828,14 @@ GFXDECODE_END
void galastrm_state::galastrm(machine_config &config)
{
- /* basic machine hardware */
- M68EC020(config, m_maincpu, 16000000); /* 16 MHz */
+ // basic machine hardware
+ M68EC020(config, m_maincpu, 32_MHz_XTAL / 2); // 16 MHz
m_maincpu->set_addrmap(AS_PROGRAM, &galastrm_state::main_map);
- m_maincpu->set_vblank_int("screen", FUNC(galastrm_state::interrupt)); /* VBL */
+ m_maincpu->set_vblank_int("screen", FUNC(galastrm_state::interrupt)); // VBL
EEPROM_93C46_16BIT(config, "eeprom");
- adc0809_device &adc(ADC0809(config, "adc", 500000)); // unknown clock
+ adc0809_device &adc(ADC0809(config, "adc", 500'000)); // unknown clock
adc.eoc_ff_callback().set_inputline("maincpu", 6);
adc.in_callback<0>().set_ioport("STICKX");
adc.in_callback<1>().set_ioport("STICKY");
@@ -200,7 +849,7 @@ void galastrm_state::galastrm(machine_config &config)
tc0510nio.write_4_callback().set(FUNC(galastrm_state::coin_word_w));
tc0510nio.read_7_callback().set_ioport("IN2");
- /* 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));
@@ -221,7 +870,7 @@ void galastrm_state::galastrm(machine_config &config)
TC0110PCR(config, m_tc0110pcr, 0);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
@@ -233,7 +882,7 @@ void galastrm_state::galastrm(machine_config &config)
/***************************************************************************/
ROM_START( galastrm )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* for 68020 code (CPU A) */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // for 68020 code (CPU A)
ROM_LOAD32_BYTE( "c99_15.ic105", 0x00000, 0x40000, CRC(7eae8efd) SHA1(6bbb3da697dfcd93337b53895678e2a4ff2de457) )
ROM_LOAD32_BYTE( "c99_12.ic102", 0x00001, 0x40000, CRC(e059d1ee) SHA1(560951f95f270f0559b5289dda7f4ba74538cfcb) )
ROM_LOAD32_BYTE( "c99_13.ic103", 0x00002, 0x40000, CRC(885fcb35) SHA1(be10e109c461c1f776e98efa1b2a4d588aa0c41c) )
@@ -243,23 +892,23 @@ ROM_START( galastrm )
ROM_LOAD16_BYTE( "c99_23.ic8", 0x100000, 0x20000, CRC(5718ee92) SHA1(33cfa60c5bceb1525498f27b598067d2dc620431) )
ROM_LOAD16_BYTE( "c99_22.ic7", 0x100001, 0x20000, CRC(b90f7c42) SHA1(e2fa9ee10ad61ae1a672c3357c0072b79ec7fbcb) )
- ROM_REGION( 0x100, "tc0100scn", ROMREGION_ERASE00 ) // no roms for tc0100scn, dummy
+ ROM_REGION( 0x100, "tc0100scn", ROMREGION_ERASE00 ) // no ROMs for tc0100scn, dummy
- ROM_REGION( 0x200000, "tc0480scp", 0 )
- ROM_LOAD32_WORD( "c99-05.ic1", 0x000000, 0x100000, CRC(a91ffba4) SHA1(467af9646ddad5fbb520b6bc13517ed4deacf479) ) /* SCR 16x16 tiles */
+ ROM_REGION( 0x200000, "tc0480scp", 0 ) // SCR 16x16 tiles
+ ROM_LOAD32_WORD( "c99-05.ic1", 0x000000, 0x100000, CRC(a91ffba4) SHA1(467af9646ddad5fbb520b6bc13517ed4deacf479) )
ROM_LOAD32_WORD( "c99-06.ic2", 0x000002, 0x100000, CRC(812ed3ae) SHA1(775904dd42643d0e3a30890590d5f8eac1fe78db) )
- ROM_REGION( 0x400000, "sprites", 0 )
- ROM_LOAD64_WORD_SWAP( "c99-02.ic50", 0x000000, 0x100000, CRC(81e9fc6f) SHA1(4495a7d130b755b5a48eaa814d884d6bb8243bcb) ) /* OBJ 16x16 tiles */
+ ROM_REGION( 0x400000, "sprites", 0 ) // OBJ 16x16 tiles
+ ROM_LOAD64_WORD_SWAP( "c99-02.ic50", 0x000000, 0x100000, CRC(81e9fc6f) SHA1(4495a7d130b755b5a48eaa814d884d6bb8243bcb) )
ROM_LOAD64_WORD_SWAP( "c99-01.ic51", 0x000002, 0x100000, CRC(9dda1267) SHA1(c639ba064496dcadf5f1e55332a12bb442e9dc86) )
ROM_LOAD64_WORD_SWAP( "c99-04.ic66", 0x000004, 0x100000, CRC(a681760f) SHA1(23d4fc7eb778c8a25c4bc7cee1d0c8cdd828a996) )
ROM_LOAD64_WORD_SWAP( "c99-03.ic67", 0x000006, 0x100000, CRC(a2807a27) SHA1(977e395ea2ab2fb82807d3cf5fe5f1dbbde99da0) )
- ROM_REGION16_LE( 0x80000, "sprmaprom", 0 )
- ROM_LOAD16_WORD( "c99-11.ic90", 0x00000, 0x80000, CRC(26a6926c) SHA1(918860e2829131e9ecfe983b2ae3e49e1c9ecd72) ) /* STY, spritemap */
+ ROM_REGION16_LE( 0x80000, "sprmaprom", 0 ) // STY
+ ROM_LOAD16_WORD( "c99-11.ic90", 0x00000, 0x80000, CRC(26a6926c) SHA1(918860e2829131e9ecfe983b2ae3e49e1c9ecd72) )
ROM_REGION16_BE( 0x1000000, "taito_en:ensoniq", ROMREGION_ERASE00 )
- ROM_LOAD16_BYTE( "c99-08.ic3", 0x000000, 0x100000, CRC(fedb4187) SHA1(83563e4af795a0dfeb261a62c31b6fed72f45a4d) ) /* Ensoniq samples */
+ ROM_LOAD16_BYTE( "c99-08.ic3", 0x000000, 0x100000, CRC(fedb4187) SHA1(83563e4af795a0dfeb261a62c31b6fed72f45a4d) )
ROM_LOAD16_BYTE( "c99-09.ic4", 0x200000, 0x100000, CRC(ba70b86b) SHA1(ffbb9547d6b6e47a3ef23206b5f40c57f3ea7619) )
ROM_LOAD16_BYTE( "c99-10.ic5", 0x400000, 0x100000, CRC(da016f1e) SHA1(581ef158c6f6576618dd75429b1d3aa92cd3581d) )
ROM_LOAD16_BYTE( "c99-07.ic2", 0x680000, 0x040000, CRC(4cc3136f) SHA1(d9d7556bbe6af161fa0651b1fbd72e7dbf0a8e82) )
@@ -271,5 +920,7 @@ ROM_START( galastrm )
ROM_LOAD16_WORD( "eeprom-galastrm.bin", 0x0000, 0x0080, CRC(94efa7a6) SHA1(5870b988cb364065e8bd779efbdadca8d3ffc17c) )
ROM_END
+} // anonymous namespace
+
GAME( 1992, galastrm, 0, galastrm, galastrm, galastrm_state, empty_init, ROT0, "Taito Corporation", "Galactic Storm (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/taito/galastrm.h b/src/mame/taito/galastrm.h
deleted file mode 100644
index 7b1813ec975..00000000000
--- a/src/mame/taito/galastrm.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Hau
-#ifndef MAME_INCLUDES_GALASTRM_H
-#define MAME_INCLUDES_GALASTRM_H
-
-#pragma once
-
-#include "machine/eepromser.h"
-
-#include "video/poly.h"
-#include "tc0100scn.h"
-#include "tc0110pcr.h"
-#include "tc0480scp.h"
-
-#include "emupal.h"
-#include "screen.h"
-
-
-class galastrm_state;
-
-struct gs_poly_data
-{
- bitmap_ind16* texbase = nullptr;
-};
-
-class galastrm_renderer : public poly_manager<float, gs_poly_data, 2>
-{
-public:
- galastrm_renderer(galastrm_state &state);
-
- void tc0610_draw_scanline(s32 scanline, const extent_t& extent, const gs_poly_data& object, int threadid);
- void tc0610_rotate_draw(bitmap_ind16 &srcbitmap, const rectangle &clip);
-
- bitmap_ind16 &screenbits() { return m_screenbits; }
-
-private:
- galastrm_state& m_state;
- bitmap_ind16 m_screenbits;
-};
-
-
-class galastrm_state : public driver_device
-{
- friend class galastrm_renderer;
-public:
- galastrm_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_spriteram(*this,"spriteram"),
- m_spritemap_rom(*this, "sprmaprom"),
- m_maincpu(*this, "maincpu"),
- m_eeprom(*this, "eeprom"),
- m_tc0100scn(*this, "tc0100scn"),
- m_tc0110pcr(*this, "tc0110pcr"),
- m_tc0480scp(*this, "tc0480scp"),
- m_gfxdecode(*this, "gfxdecode"),
- m_screen(*this, "screen")
- { }
-
- void galastrm(machine_config &config);
- DECLARE_READ_LINE_MEMBER(frame_counter_r);
-
-protected:
- virtual void video_start() override;
-
-private:
- required_shared_ptr<u32> m_spriteram;
-
- required_region_ptr<u16> m_spritemap_rom;
-
- required_device<cpu_device> m_maincpu;
- required_device<eeprom_serial_93cxx_device> m_eeprom;
- required_device<tc0100scn_device> m_tc0100scn;
- required_device<tc0110pcr_device> m_tc0110pcr;
- required_device<tc0480scp_device> m_tc0480scp;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<screen_device> m_screen;
-
- struct gs_tempsprite
- {
- u8 gfx = 0U;
- u32 code = 0U, color = 0U;
- bool flipx = false, flipy = false;
- int x = 0, y = 0;
- int zoomx = 0, zoomy = 0;
- u32 primask = 0U;
- };
-
- u16 m_frame_counter = 0U;
- int m_tc0610_addr[2]{};
- s16 m_tc0610_ctrl_reg[2][8]{};
- std::unique_ptr<gs_tempsprite[]> m_spritelist{};
- struct gs_tempsprite *m_sprite_ptr_pre{};
- bitmap_ind16 m_tmpbitmaps{};
- std::unique_ptr<galastrm_renderer> m_poly{};
-
- int m_rsxb = 0;
- int m_rsyb = 0;
- int m_rsxoffs = 0;
- int m_rsyoffs = 0;
-
- template<int Chip> void tc0610_w(offs_t offset, u16 data);
- void coin_word_w(u8 data);
- u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- INTERRUPT_GEN_MEMBER(interrupt);
- void draw_sprites_pre(int x_offs, int y_offs);
- void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int priority);
-
- void main_map(address_map &map);
-};
-
-#endif // MAME_INCLUDES_GALASTRM_H
diff --git a/src/mame/taito/galastrm_v.cpp b/src/mame/taito/galastrm_v.cpp
deleted file mode 100644
index 2b8fbfaa9cb..00000000000
--- a/src/mame/taito/galastrm_v.cpp
+++ /dev/null
@@ -1,535 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Hau
-#include "emu.h"
-#include "galastrm.h"
-
-#define X_OFFSET 96
-#define Y_OFFSET 60
-
-
-galastrm_renderer::galastrm_renderer(galastrm_state& state)
- : poly_manager<float, gs_poly_data, 2>(state.machine())
- , m_state(state)
- , m_screenbits(state.m_screen->width(), state.m_screen->height())
-{
-}
-
-
-/******************************************************************/
-
-void galastrm_state::video_start()
-{
- m_spritelist = std::make_unique<gs_tempsprite[]>(0x4000);
-
- m_poly = std::make_unique<galastrm_renderer>(*this);
-
- m_screen->register_screen_bitmap(m_tmpbitmaps);
- m_screen->register_screen_bitmap(m_poly->screenbits());
-
- save_item(NAME(m_rsxb));
- save_item(NAME(m_rsyb));
- save_item(NAME(m_rsxoffs));
- save_item(NAME(m_rsyoffs));
- save_item(NAME(m_frame_counter));
- save_item(NAME(m_tc0610_addr));
- save_item(NAME(m_tc0610_ctrl_reg));
-}
-
-
-/************************************************************
- SPRITE DRAW ROUTINES
-
-We draw a series of small tiles ("chunks") together to
-create each big sprite. The spritemap rom provides the lookup
-table for this. The game hardware looks up 16x16 sprite chunks
-from the spritemap rom, creating a 64x64 sprite like this:
-
- 0 1 2 3
- 4 5 6 7
- 8 9 10 11
- 12 13 14 15
-
-(where the number is the word offset into the spritemap rom).
-It can also create 32x32 sprites.
-
-NB: unused portions of the spritemap rom contain hex FF's.
-It is a useful coding check to warn in the log if these
-are being accessed. [They can be inadvertently while
-spriteram is being tested, take no notice of that.]
-
-Heavy use is made of sprite zooming.
-
- ***
-
- Sprite table layout (4 long words per entry)
-
- ------------------------------------------
- 0 | ........ x....... ........ ........ | Flip X
- 0 | ........ .xxxxxxx ........ ........ | ZoomX
- 0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile
- | |
- 2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*]
- 2 | ........ ......xx xxxxxx.. ........ | Palette bank
- 2 | ........ ........ ......xx xxxxxxxx | X position
- | |
- 3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64)
- 3 | ........ ......x. ........ ........ | Flip Y
- 3 | ........ .......x xxxxxx.. ........ | ZoomY
- 3 | ........ ........ ......xx xxxxxxxx | Y position
- ------------------------------------------
-
- [* 00=over BG1; 01=BG2; 10=BG3; 11=over text ???]
-
-********************************************************/
-
-void galastrm_state::draw_sprites_pre(int x_offs, int y_offs)
-{
- int sprites_flipscreen = 0;
-
- /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list
- while processing sprite ram and then draw them all at the end */
- m_sprite_ptr_pre = m_spritelist.get();
-
- for (int offs = (m_spriteram.bytes()/4-4);offs >= 0;offs -= 4)
- {
- u32 data = m_spriteram[offs+0];
- int flipx = (data & 0x00800000) >> 23;
- int zoomx = (data & 0x007f0000) >> 16;
- const u32 tilenum = (data & 0x00007fff);
-
- if (!tilenum) continue;
-
- data = m_spriteram[offs+2];
- const int priority = (data & 0x000c0000) >> 18;
- int color = (data & 0x0003fc00) >> 10;
- int x = (data & 0x000003ff);
-
- data = m_spriteram[offs+3];
- const int dblsize = (data & 0x00040000) >> 18;
- int flipy = (data & 0x00020000) >> 17;
- int zoomy = (data & 0x0001fc00) >> 10;
- int y = (data & 0x000003ff);
-
- int bad_chunks = 0;
- const int dimension = ((dblsize * 2) + 2); // 2 or 4
- const int total_chunks = ((dblsize * 3) + 1) << 2; // 4 or 16
- const u32 map_offset = tilenum << 2;
-
- zoomx += 1;
- zoomy += 1;
-
- if (x > 713) x -= 1024; /* 1024x512 */
- if (y < 117) y += 512;
-
- y = (-y & 0x3ff);
- x -= x_offs;
- y += y_offs;
- if (flipy) y += (128 - zoomy);
-
- for (int sprite_chunk = 0; sprite_chunk < total_chunks; sprite_chunk++)
- {
- const int j = sprite_chunk / dimension; /* rows */
- const int k = sprite_chunk % dimension; /* chunks per row */
-
- int px = k;
- int py = j;
- /* pick tiles back to front for x and y flips */
- if (flipx) px = dimension - 1 - k;
- if (flipy) py = dimension - 1 - j;
-
- const u16 code = m_spritemap_rom[map_offset + px + (py << (dblsize + 1))];
-
- if (code == 0xffff)
- {
- bad_chunks += 1;
- continue;
- }
-
- int curx = x + ((k * zoomx) / dimension);
- int cury = y + ((j * zoomy) / dimension);
-
- const int zx = x + (((k + 1) * zoomx) / dimension) - curx;
- const int zy = y + (((j + 1) * zoomy) / dimension) - cury;
-
- if (sprites_flipscreen)
- {
- /* -zx/y is there to fix zoomed sprite coords in screenflip.
- drawgfxzoom does not know to draw from flip-side of sprites when
- screen is flipped; so we must correct the coords ourselves. */
-
- curx = 320 - curx - zx;
- cury = 256 - cury - zy;
- flipx = !flipx;
- flipy = !flipy;
- }
-
- m_sprite_ptr_pre->gfx = 0;
- m_sprite_ptr_pre->code = code;
- m_sprite_ptr_pre->color = color;
- m_sprite_ptr_pre->flipx = !flipx;
- m_sprite_ptr_pre->flipy = flipy;
- m_sprite_ptr_pre->x = curx;
- m_sprite_ptr_pre->y = cury;
- m_sprite_ptr_pre->zoomx = zx << 12;
- m_sprite_ptr_pre->zoomy = zy << 12;
- m_sprite_ptr_pre->primask = priority;
-
- m_sprite_ptr_pre++;
- }
- if (bad_chunks)
- logerror("Sprite number %04x had %02x invalid chunks\n",tilenum,bad_chunks);
- }
-}
-
-void galastrm_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int priority)
-{
- struct gs_tempsprite *sprite_ptr = m_sprite_ptr_pre;
-
- while (sprite_ptr != m_spritelist.get())
- {
- sprite_ptr--;
-
- if ((priority != 0 && sprite_ptr->primask != 0) ||
- (priority == 0 && sprite_ptr->primask == 0))
- {
- m_gfxdecode->gfx(sprite_ptr->gfx)->prio_zoom_transpen(bitmap,cliprect,
- sprite_ptr->code,
- sprite_ptr->color,
- sprite_ptr->flipx,sprite_ptr->flipy,
- sprite_ptr->x,sprite_ptr->y,
- sprite_ptr->zoomx,sprite_ptr->zoomy,
- screen.priority(),primasks[sprite_ptr->primask],0);
- }
- }
-}
-
-/**************************************************************
- POLYGON RENDERER
-**************************************************************/
-
-void galastrm_renderer::tc0610_draw_scanline(s32 scanline, const extent_t& extent, const gs_poly_data& object, int threadid)
-{
- u16 *const framebuffer = &m_screenbits.pix(scanline);
- const s32 dudx = extent.param[0].dpdx;
- const s32 dvdx = extent.param[1].dpdx;
-
- s32 u = extent.param[0].start;
- s32 v = extent.param[1].start;
- for (int x = extent.startx; x < extent.stopx; x++)
- {
- framebuffer[x] = object.texbase->pix(v >> 16, u >> 16);
- u += dudx;
- v += dvdx;
- }
-}
-
-void galastrm_renderer::tc0610_rotate_draw(bitmap_ind16 &srcbitmap, const rectangle &clip)
-{
- struct polyVert
- {
- float x;
- float y;
-// float z;
- } tmpz[4];
-
- vertex_t vert[4];
- int rsx = m_state.m_tc0610_ctrl_reg[1][0];
- int rsy = m_state.m_tc0610_ctrl_reg[1][1];
- const int rzx = m_state.m_tc0610_ctrl_reg[1][2];
- const int rzy = m_state.m_tc0610_ctrl_reg[1][3];
- const int ryx = m_state.m_tc0610_ctrl_reg[1][5];
- const int ryy = m_state.m_tc0610_ctrl_reg[1][4];
- const int lx = srcbitmap.width();
- const int ly = srcbitmap.height();
-
- int pxx = 0;
- int pxy = 0;
- int pyx = 0;
- int pyy = 0;
- int zx = 0;
- int zy = 0;
-
- if (rzx != 0 || rzy != 0)
- {
- while (sqrtf(powf((float)pxx / 4096.0f, 2.0f) + powf((float)pxy / 4096.0f, 2.0f)) < (float)(lx / 2))
- {
- pxx += rzx;
- pxy += rzy;
- zx++;
- }
- while (sqrtf(powf((float)pyy / 4096.0f, 2.0f) + powf((float)pyx / 4096.0f, 2.0f)) < (float)(ly / 2))
- {
- pyy += rzx;
- pyx += -rzy;
- zy++;
- }
- }
- float zsn = ((float)pyx / 4096.0f) / (float)(ly / 2);
- float zcs = ((float)pxx / 4096.0f) / (float)(lx / 2);
-
-
- if ((rsx == -240 && rsy == 1072) || !m_state.m_tc0610_ctrl_reg[1][7])
- {
- m_state.m_rsxoffs = 0;
- m_state.m_rsyoffs = 0;
- }
- else
- {
- if (rsx > m_state.m_rsxb && m_state.m_rsxb < 0 && rsx-m_state.m_rsxb > 0x8000)
- {
- if (m_state.m_rsxoffs == 0)
- m_state.m_rsxoffs = -0x10000;
- else
- m_state.m_rsxoffs = 0;
- }
- if (rsx < m_state.m_rsxb && m_state.m_rsxb > 0 && m_state.m_rsxb-rsx > 0x8000)
- {
- if (m_state.m_rsxoffs == 0)
- m_state.m_rsxoffs = 0x10000 - 1;
- else
- m_state.m_rsxoffs = 0;
- }
- if (rsy > m_state.m_rsyb && m_state.m_rsyb < 0 && rsy-m_state.m_rsyb > 0x8000)
- {
- if (m_state.m_rsyoffs == 0)
- m_state.m_rsyoffs = -0x10000;
- else
- m_state.m_rsyoffs = 0;
- }
- if (rsy < m_state.m_rsyb && m_state.m_rsyb > 0 && m_state.m_rsyb-rsy > 0x8000)
- {
- if (m_state.m_rsyoffs == 0)
- m_state.m_rsyoffs = 0x10000 - 1;
- else
- m_state.m_rsyoffs = 0;
- }
- }
- m_state.m_rsxb = rsx;
- m_state.m_rsyb = rsy;
- if (m_state.m_rsxoffs) rsx += m_state.m_rsxoffs;
- if (m_state.m_rsyoffs) rsy += m_state.m_rsyoffs;
- if (rsx < -0x14000 || rsx >= 0x14000) m_state.m_rsxoffs = 0;
- if (rsy < -0x14000 || rsy >= 0x14000) m_state.m_rsyoffs = 0;
-
-
- pxx = 0;
- pxy = 0;
- pyx = 0;
- pyy = 0;
- int yx = 0;
- //int yy = 0;
- //float ssn = 0.0;
- //float scs = 0.0;
- //float ysn = 0.0;
- //float ycs = 0.0;
-
- if (m_state.m_tc0610_ctrl_reg[1][7])
- {
- if (ryx != 0 || ryy != 0)
- {
- while (sqrtf(powf((float)pxx / 4096.0f, 2.0f) + powf((float)pxy / 4096.0f, 2.0f)) < (float)(lx / 2))
- {
- pxx += ryx;
- pxy += ryy;
- yx++;
- }
- while (sqrtf(powf((float)pyy / 4096.0f, 2.0f) + powf((float)pyx / 4096.0f, 2.0f)) < (float)(ly / 2))
- {
- pyy += ryx;
- pyx += -ryy;
- //yy++;
- }
- if (yx >= 0.0)
- {
- yx = (int)((8.0 - log((double)yx) / log(2.0)) * 6.0);
- //ysn = sin(DEGREE_TO_RADIAN(yx));
- //ycs = 1.0 - ysn*ysn;
- }
- }
-
- pxx = 0;
- pxy = 0;
- pyx = 0;
- pyy = 0;
-
- if (rsx != 0 || rsy != 0)
- {
- while (sqrtf(powf((float)pxx / 65536.0f, 2.0) + powf((float)pxy / 65536.0f, 2.0f)) < (float)(lx / 2))
- {
- pxx += rsx;
- pxy += rsy;
- }
- while (sqrtf(powf((float)pyy / 65536.0f, 2.0f) + powf((float)pyx / 65536.0f, 2.0f)) < (float)(ly / 2))
- {
- pyy += rsx;
- pyx += -rsy;
- }
- }
- //ssn = ((float)pxy/65536.0) / (float)(lx / 2);
- //scs = ((float)pyy/65536.0) / (float)(ly / 2);
- }
-
- {
-// polyVert tmpz[4];
- tmpz[0].x = ((float)(-zx) * zcs) - ((float)(-zy) * zsn);
- tmpz[0].y = ((float)(-zx) * zsn) + ((float)(-zy) * zcs);
-// tmpz[0].z = 0.0;
- tmpz[1].x = ((float)(-zx) * zcs) - ((float)(zy - 1) * zsn);
- tmpz[1].y = ((float)(-zx) * zsn) + ((float)(zy - 1) * zcs);
-// tmpz[1].z = 0.0;
- tmpz[2].x = ((float)(zx - 1) * zcs) - ((float)(zy - 1) * zsn);
- tmpz[2].y = ((float)(zx - 1) * zsn) + ((float)(zy - 1) * zcs);
-// tmpz[2].z = 0.0;
- tmpz[3].x = ((float)(zx - 1) * zcs) - ((float)(-zy) * zsn);
- tmpz[3].y = ((float)(zx - 1) * zsn) + ((float)(-zy) * zcs);
-// tmpz[3].z = 0.0;
-
- vert[0].x = tmpz[0].x + (float)(lx / 2);
- vert[0].y = tmpz[0].y + (float)(ly / 2);
- vert[1].x = tmpz[1].x + (float)(lx / 2);
- vert[1].y = tmpz[1].y + (float)(ly / 2);
- vert[2].x = tmpz[2].x + (float)(lx / 2);
- vert[2].y = tmpz[2].y + (float)(ly / 2);
- vert[3].x = tmpz[3].x + (float)(lx / 2);
- vert[3].y = tmpz[3].y + (float)(ly / 2);
- }
-
- vert[0].p[0] = 0.0;
- vert[0].p[1] = 0.0;
- vert[1].p[0] = 0.0;
- vert[1].p[1] = (float)(ly - 1) * 65536.0f;
- vert[2].p[0] = (float)(lx - 1) * 65536.0f;
- vert[2].p[1] = (float)(ly - 1) * 65536.0f;
- vert[3].p[0] = (float)(lx - 1) * 65536.0f;
- vert[3].p[1] = 0.0;
-
- gs_poly_data& extra = object_data().next();
- extra.texbase = &srcbitmap;
-
- render_polygon<4, 2>(clip, render_delegate(&galastrm_renderer::tc0610_draw_scanline, this), vert);
- wait();
-}
-
-/**************************************************************
- SCREEN REFRESH
-**************************************************************/
-
-u32 galastrm_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- u8 layer[5];
- u8 pivlayer[3];
- static const u32 primasks[4] = {0xfffc, 0xfff0, 0xff00, 0x0};
- bitmap_ind8 &priority_bitmap = screen.priority();
-
- rectangle clip(0, screen.width() -1, 0, screen.height() - 1);
-
- m_tc0100scn->tilemap_update();
- m_tc0480scp->tilemap_update();
-
- const u16 priority = m_tc0480scp->get_bg_priority();
- layer[0] = (priority & 0xf000) >> 12; /* tells us which bg layer is bottom */
- layer[1] = (priority & 0x0f00) >> 8;
- layer[2] = (priority & 0x00f0) >> 4;
- layer[3] = (priority & 0x000f) >> 0; /* tells us which is top */
- layer[4] = 4; /* text layer always over bg layers */
-
- pivlayer[0] = m_tc0100scn->bottomlayer();
- pivlayer[1] = pivlayer[0] ^ 1;
- pivlayer[2] = 2;
-
- bitmap.fill(0, cliprect);
- priority_bitmap.fill(0, clip);
- m_tmpbitmaps.fill(0, clip);
-
- m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[0], 0, 0);
- m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[1], 0, 0);
-
-#if 0
- if (layer[0]==0 && layer[1]==3 && layer[2]==2 && layer[3]==1)
- {
- if (!machine().input().code_pressed(KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1);
- if (!machine().input().code_pressed(KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 4);
- if (!machine().input().code_pressed(KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4);
- if (!machine().input().code_pressed(KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 4);
- }
- else
- {
- if (!machine().input().code_pressed(KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1);
- if (!machine().input().code_pressed(KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 2);
- if (!machine().input().code_pressed(KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4);
- if (!machine().input().code_pressed(KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 8);
- }
-
- if (layer[0]==3 && layer[1]==0 && layer[2]==1 && layer[3]==2)
- {
- for (int y = 0; y < priority_bitmap.height; y++)
- {
- for (int x = 0; x < priority_bitmap.width; x++)
- {
- u8 *pri = &priority_bitmap.pix(y, x);
- if (!(*pri & 0x02) && m_tmpbitmaps.pix(y, x))
- *pri |= 0x04;
- }
- }
- }
-
- draw_sprites_pre(machine(), 42-X_OFFSET, -571+Y_OFFSET);
- draw_sprites(screen, m_tmpbitmaps, clip, primasks, 1);
-
- copybitmap_trans(bitmap, m_polybitmap, 0,0, 0,0, cliprect, 0);
- m_polybitmap->fill(0, clip);
- tc0610_rotate_draw(machine(), m_polybitmap, m_tmpbitmaps, cliprect);
-
- priority_bitmap.fill(0, cliprect);
- draw_sprites(screen, bitmap, cliprect, primasks, 0);
-
- if (!machine().input().code_pressed(KEYCODE_B)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0);
- if (!machine().input().code_pressed(KEYCODE_M)) m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[2], 0, 0);
-
-
-
-#else
- if (layer[0] == 0 && layer[1] == 3 && layer[2] == 2 && layer[3] == 1)
- {
- m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1);
- m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 4);
- m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4);
- m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 4);
- }
- else
- {
- m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1);
- m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 2);
- m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4);
- m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 8);
- }
-
- if (layer[0] == 3 && layer[1] == 0 && layer[2] == 1 && layer[3] == 2)
- {
- for (int y=0; y < priority_bitmap.height(); y++)
- {
- for (int x=0; x < priority_bitmap.width(); x++)
- {
- u8 *pri = &priority_bitmap.pix(y, x);
- if (!(*pri & 0x02) && m_tmpbitmaps.pix(y, x))
- *pri |= 0x04;
- }
- }
- }
-
- draw_sprites_pre(42 - X_OFFSET, -571 + Y_OFFSET);
- draw_sprites(screen, m_tmpbitmaps, clip, primasks, 1);
-
- copybitmap_trans(bitmap, m_poly->screenbits(), 0,0, 0,0, cliprect, 0);
- m_poly->screenbits().fill(0, clip);
- m_poly->tc0610_rotate_draw(m_tmpbitmaps, cliprect);
-
- priority_bitmap.fill(0, cliprect);
- draw_sprites(screen, bitmap, cliprect, primasks, 0);
-
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0);
- m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[2], 0, 0);
-#endif
-
- return 0;
-}
diff --git a/src/mame/taito/groundfx.cpp b/src/mame/taito/groundfx.cpp
index 2c0860b91cb..12e226589a7 100644
--- a/src/mame/taito/groundfx.cpp
+++ b/src/mame/taito/groundfx.cpp
@@ -219,17 +219,17 @@ void groundfx_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, c
for (int offs = (m_spriteram.bytes() / 4 - 4); offs >= 0; offs -= 4)
{
- u32 data = m_spriteram[offs+0];
+ u32 data = m_spriteram[offs + 0];
int flipx = (data & 0x00800000) >> 23;
int zoomx = (data & 0x007f0000) >> 16;
const u32 tilenum = (data & 0x00007fff);
- data = m_spriteram[offs+2];
+ data = m_spriteram[offs + 2];
const int priority = (data & 0x000c0000) >> 18;
u32 color = (data & 0x0003fc00) >> 10;
int x = (data & 0x000003ff);
- data = m_spriteram[offs+3];
+ data = m_spriteram[offs + 3];
const int dblsize = (data & 0x00040000) >> 18;
int flipy = (data & 0x00020000) >> 17;
int zoomy = (data & 0x0001fc00) >> 10;
diff --git a/src/mame/taito/gunbustr.cpp b/src/mame/taito/gunbustr.cpp
index 54b47927047..0208f62c392 100644
--- a/src/mame/taito/gunbustr.cpp
+++ b/src/mame/taito/gunbustr.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Bryan McPhail, David Graves
+// copyright-holders: Bryan McPhail, David Graves
+
/****************************************************************************
Gunbuster (c) 1992 Taito
@@ -22,9 +23,9 @@
Gunbuster uses a slightly enhanced sprite system from the one
in Taito Z games.
- The key feature remains the use of a sprite map rom which allows
+ The key feature remains the use of a sprite map ROM which allows
the sprite hardware to create many large zoomed sprites on screen
- while minimizing the main cpu load.
+ while minimizing the main CPU load.
This feature makes the SZ system complementary to the F3 system
which, owing to its F2 sprite hardware, is not very well suited to
@@ -44,19 +45,340 @@
***************************************************************************/
#include "emu.h"
-#include "gunbustr.h"
#include "taito_en.h"
#include "taitoio.h"
+#include "tc0480scp.h"
#include "cpu/m68000/m68000.h"
#include "machine/eepromser.h"
#include "sound/es5506.h"
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+// configurable logging
+#define LOG_BADSPRITES (1U << 1)
+
+//#define VERBOSE (LOG_GENERAL | LOG_BADSPRITES)
+
+#include "logmacro.h"
+
+#define LOGBADSPRITES(...) LOGMASKED(LOG_BADSPRITES, __VA_ARGS__)
+
+
+namespace {
+
+class gunbustr_state : public driver_device
+{
+public:
+ gunbustr_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this,"maincpu"),
+ m_tc0480scp(*this, "tc0480scp"),
+ m_ram(*this,"ram"),
+ m_spriteram(*this,"spriteram"),
+ m_eeprom(*this, "eeprom"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette"),
+ m_spritemap(*this, "spritemap"),
+ m_io_light_x(*this, "LIGHT%u_X", 0U),
+ m_io_light_y(*this, "LIGHT%u_Y", 0U),
+ m_gun_recoil_pl(*this, "Player%u_Gun_Recoil", 1U),
+ m_hit_lamp(*this, "Hit_lamp")
+
+ {
+ m_coin_lockout = true;
+ }
+
+ void gunbustr(machine_config &config);
+
+ void init_gunbustrj();
+ void init_gunbustr();
+
+protected:
+ virtual void video_start() override;
+
+private:
+ void prg_map(address_map &map);
+
+ TIMER_CALLBACK_MEMBER(trigger_irq5);
+
+ void motor_control_w(u32 data);
+ u32 gun_r();
+ void gun_w(u32 data);
+ u32 main_cycle_r();
+ void coin_word_w(u8 data);
+ u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ INTERRUPT_GEN_MEMBER(gunbustr_interrupt);
+ void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int x_offs, int y_offs);
+
+ required_device<cpu_device> m_maincpu;
+ required_device<tc0480scp_device> m_tc0480scp;
+ required_shared_ptr<u32> m_ram;
+ required_shared_ptr<u32> m_spriteram;
+ required_device<eeprom_serial_93cxx_device> m_eeprom;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+ required_region_ptr<u16> m_spritemap;
+
+ required_ioport_array<2> m_io_light_x;
+ required_ioport_array<2> m_io_light_y;
+ output_finder<2> m_gun_recoil_pl;
+ output_finder<> m_hit_lamp;
+
+ struct gb_tempsprite
+ {
+ int gfx = 0;
+ int code = 0, color = 0;
+ int flipx,flipy = 0;
+ int x = 0, y = 0;
+ int zoomx = 0, zoomy = 0;
+ int primask = 0;
+ };
+
+ bool m_coin_lockout;
+ std::unique_ptr<gb_tempsprite[]> m_spritelist{};
+ emu_timer *m_interrupt5_timer = nullptr;
+};
+
+
+// video
+
+/************************************************************/
+
+void gunbustr_state::video_start()
+{
+ m_spritelist = std::make_unique<gb_tempsprite[]>(0x4000);
+
+ m_gun_recoil_pl.resolve();
+ m_hit_lamp.resolve();
+}
+
+/************************************************************
+ SPRITE DRAW ROUTINES
+
+We draw a series of small tiles ("chunks") together to
+create each big sprite. The spritemap ROM provides the lookup
+table for this. The game hardware looks up 16x16 sprite chunks
+from the spritemap ROM, creating a 64x64 sprite like this:
+
+ 0 1 2 3
+ 4 5 6 7
+ 8 9 10 11
+ 12 13 14 15
+
+(where the number is the word offset into the spritemap ROM).
+It can also create 32x32 sprites.
+
+NB: unused portions of the spritemap ROM contain hex FF's.
+It is a useful coding check to warn in the log if these
+are being accessed. [They can be inadvertently while
+spriteram is being tested, take no notice of that.]
+
+Heavy use is made of sprite zooming.
+
+ ***
+
+ Sprite table layout (4 long words per entry)
+
+ ------------------------------------------
+ 0 | ........ x....... ........ ........ | Flip X
+ 0 | ........ .xxxxxxx ........ ........ | ZoomX
+ 0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile
+ | |
+ 2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*]
+ 2 | ........ ......xx xxxxxx.. ........ | Palette bank
+ 2 | ........ ........ ......xx xxxxxxxx | X position
+ | |
+ 3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64)
+ 3 | ........ ......x. ........ ........ | Flip Y
+ 3 | ........ .......x xxxxxx.. ........ | ZoomY
+ 3 | ........ ........ ......xx xxxxxxxx | Y position
+ ------------------------------------------
+
+ [* 00=over BG1; 01=BG2; 10=BG3; 11=over text ???]
+
+********************************************************/
+
+void gunbustr_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int x_offs, int y_offs)
+{
+ int sprites_flipscreen = 0;
+
+ /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list
+ while processing sprite ram and then draw them all at the end */
+ struct gb_tempsprite *sprite_ptr = m_spritelist.get();
+
+ for (int offs = (m_spriteram.bytes() / 4 - 4); offs >= 0; offs -= 4)
+ {
+ u32 data = m_spriteram[offs + 0];
+ int flipx = (data & 0x00800000) >> 23;
+ int zoomx = (data & 0x007f0000) >> 16;
+ const u32 tilenum = (data & 0x00007fff);
+
+ data = m_spriteram[offs + 2];
+ const int priority = (data & 0x000c0000) >> 18;
+ int color = (data & 0x0003fc00) >> 10;
+ int x = (data & 0x000003ff);
+
+ data = m_spriteram[offs + 3];
+ const int dblsize = (data & 0x00040000) >> 18;
+ int flipy = (data & 0x00020000) >> 17;
+ int zoomy = (data & 0x0001fc00) >> 10;
+ int y = (data & 0x000003ff);
+
+ color |= 0x80;
+
+ if (!tilenum) continue;
+
+ flipy = !flipy;
+ zoomx += 1;
+ zoomy += 1;
+
+ y += y_offs;
+
+ // treat coords as signed
+ if (x > 0x340) x -= 0x400;
+ if (y > 0x340) y -= 0x400;
+
+ x -= x_offs;
+
+ int bad_chunks = 0;
+ const int dimension = ((dblsize * 2) + 2); // 2 or 4
+ const int total_chunks = ((dblsize * 3) + 1) << 2; // 4 or 16
+ const int map_offset = tilenum << 2;
+
+ for (int sprite_chunk = 0; sprite_chunk < total_chunks; sprite_chunk++)
+ {
+ const int j = sprite_chunk / dimension; // rows
+ const int k = sprite_chunk % dimension; // chunks per row
+
+ int px = k;
+ int py = j;
+ // pick tiles back to front for x and y flips
+ if (flipx) px = dimension - 1 - k;
+ if (flipy) py = dimension - 1 - j;
+
+ const u32 code = m_spritemap[map_offset + px + (py << (dblsize + 1))];
+
+ if (code == 0xffff)
+ {
+ bad_chunks += 1;
+ continue;
+ }
+
+ int curx = x + ((k * zoomx) / dimension);
+ int cury = y + ((j * zoomy) / dimension);
+
+ const int zx = x + (((k + 1) * zoomx) / dimension) - curx;
+ const int zy = y + (((j + 1) * zoomy) / dimension) - cury;
+
+ if (sprites_flipscreen)
+ {
+ /* -zx/y is there to fix zoomed sprite coords in screenflip.
+ drawgfxzoom does not know to draw from flip-side of sprites when
+ screen is flipped; so we must correct the coords ourselves. */
+
+ curx = 320 - curx - zx;
+ cury = 256 - cury - zy;
+ flipx = !flipx;
+ flipy = !flipy;
+ }
+
+ sprite_ptr->gfx = 0;
+ sprite_ptr->code = code;
+ sprite_ptr->color = color;
+ sprite_ptr->flipx = !flipx;
+ sprite_ptr->flipy = flipy;
+ sprite_ptr->x = curx;
+ sprite_ptr->y = cury;
+ sprite_ptr->zoomx = zx << 12;
+ sprite_ptr->zoomy = zy << 12;
+
+ if (primasks)
+ {
+ sprite_ptr->primask = primasks[priority];
+
+ sprite_ptr++;
+ }
+ else
+ {
+ m_gfxdecode->gfx(sprite_ptr->gfx)->zoom_transpen(bitmap, cliprect,
+ sprite_ptr->code,
+ sprite_ptr->color,
+ sprite_ptr->flipx, sprite_ptr->flipy,
+ sprite_ptr->x, sprite_ptr->y,
+ sprite_ptr->zoomx, sprite_ptr->zoomy, 0);
+ }
+ }
+
+ if (bad_chunks)
+ LOGBADSPRITES("Sprite number %04x had %02x invalid chunks\n", tilenum, bad_chunks);
+ }
+
+ // this happens only if primsks != nullptr
+ while (sprite_ptr != m_spritelist.get())
+ {
+ sprite_ptr--;
+
+ m_gfxdecode->gfx(sprite_ptr->gfx)->prio_zoom_transpen(bitmap, cliprect,
+ sprite_ptr->code,
+ sprite_ptr->color,
+ sprite_ptr->flipx, sprite_ptr->flipy,
+ sprite_ptr->x, sprite_ptr->y,
+ sprite_ptr->zoomx, sprite_ptr->zoomy,
+ screen.priority(), sprite_ptr->primask, 0);
+ }
+}
+
+
+
+/**************************************************************
+ SCREEN REFRESH
+**************************************************************/
+
+u32 gunbustr_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ u8 layer[5];
+ static const u32 primasks[4] = {0xfffc, 0xfff0, 0xff00, 0x0};
+
+ m_tc0480scp->tilemap_update();
+
+ u16 const priority = m_tc0480scp->get_bg_priority();
+ layer[0] = (priority & 0xf000) >> 12; // tells us which bg layer is bottom
+ layer[1] = (priority & 0x0f00) >> 8;
+ layer[2] = (priority & 0x00f0) >> 4;
+ layer[3] = (priority & 0x000f) >> 0; // tells us which is top
+ layer[4] = 4; // text layer always over bg layers
+
+ screen.priority().fill(0, cliprect);
+
+ /* We have to assume 2nd to bottom layer is always underneath
+ sprites as pdrawgfx cannot yet cope with more than 4 layers */
+
+#ifdef MAME_DEBUG
+ if (!machine().input().code_pressed (KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 0);
+ if (!machine().input().code_pressed (KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 1);
+ if (!machine().input().code_pressed (KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 2);
+ if (!machine().input().code_pressed (KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 4);
+ if (!machine().input().code_pressed (KEYCODE_B)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 8);
+ if (!machine().input().code_pressed (KEYCODE_N)) draw_sprites(screen, bitmap, cliprect, primasks, 48, -116);
+#else
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 0);
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 1);
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 2);
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 4);
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 8); // text layer
+ draw_sprites(screen, bitmap, cliprect, primasks, 48, -116);
+#endif
+ return 0;
+}
+
+
+// machine
+
/*********************************************************************/
TIMER_CALLBACK_MEMBER(gunbustr_state::trigger_irq5)
@@ -66,7 +388,7 @@ TIMER_CALLBACK_MEMBER(gunbustr_state::trigger_irq5)
INTERRUPT_GEN_MEMBER(gunbustr_state::gunbustr_interrupt)
{
- m_interrupt5_timer->adjust(m_maincpu->cycles_to_attotime(200000-500));
+ m_interrupt5_timer->adjust(m_maincpu->cycles_to_attotime(200000 - 500));
device.execute().set_input_line(4, HOLD_LINE);
}
@@ -87,9 +409,9 @@ void gunbustr_state::motor_control_w(u32 data)
{
// Standard value poked into MSW is 0x3c00
// (0x2000 and zero are written at startup)
- output().set_value("Player1_Gun_Recoil", BIT(data, 24));
- output().set_value("Player2_Gun_Recoil", BIT(data, 16));
- output().set_value("Hit_lamp", BIT(data, 18));
+ m_gun_recoil_pl[0] = BIT(data, 24);
+ m_gun_recoil_pl[1] = BIT(data, 16);
+ m_hit_lamp = BIT(data, 18);
}
@@ -102,7 +424,7 @@ u32 gunbustr_state::gun_r()
void gunbustr_state::gun_w(u32 data)
{
- /* 10000 cycle delay is arbitrary */
+ // 10000 cycle delay is arbitrary
m_interrupt5_timer->adjust(m_maincpu->cycles_to_attotime(10000));
}
@@ -111,19 +433,19 @@ void gunbustr_state::gun_w(u32 data)
MEMORY STRUCTURES
***********************************************************/
-void gunbustr_state::gunbustr_map(address_map &map)
+void gunbustr_state::prg_map(address_map &map)
{
map(0x000000, 0x0fffff).rom();
- map(0x200000, 0x21ffff).ram().share("ram"); /* main CPUA ram */
- map(0x300000, 0x301fff).ram().share("spriteram"); /* Sprite ram */
- map(0x380000, 0x380003).w(FUNC(gunbustr_state::motor_control_w)); /* motor, lamps etc. */
- map(0x390000, 0x3907ff).rw("taito_en:dpram", FUNC(mb8421_device::left_r), FUNC(mb8421_device::left_w)); /* Sound shared ram */
+ map(0x200000, 0x21ffff).ram().share(m_ram); // main CPUA RAM
+ map(0x300000, 0x301fff).ram().share(m_spriteram);
+ map(0x380000, 0x380003).w(FUNC(gunbustr_state::motor_control_w)); // motor, lamps etc.
+ map(0x390000, 0x3907ff).rw("taito_en:dpram", FUNC(mb8421_device::left_r), FUNC(mb8421_device::left_w)); // Sound shared RAM
map(0x400000, 0x400007).rw("tc0510nio", FUNC(tc0510nio_device::read), FUNC(tc0510nio_device::write));
- map(0x500000, 0x500003).rw(FUNC(gunbustr_state::gun_r), FUNC(gunbustr_state::gun_w)); /* gun coord read */
+ map(0x500000, 0x500003).rw(FUNC(gunbustr_state::gun_r), FUNC(gunbustr_state::gun_w));
map(0x800000, 0x80ffff).rw(m_tc0480scp, FUNC(tc0480scp_device::ram_r), FUNC(tc0480scp_device::ram_w));
map(0x830000, 0x83002f).rw(m_tc0480scp, FUNC(tc0480scp_device::ctrl_r), FUNC(tc0480scp_device::ctrl_w));
map(0x900000, 0x901fff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette");
- map(0xc00000, 0xc03fff).ram(); /* network ram ?? */
+ map(0xc00000, 0xc03fff).ram(); // network RAM ?
}
/***********************************************************
@@ -132,7 +454,7 @@ void gunbustr_state::gunbustr_map(address_map &map)
static INPUT_PORTS_START( gunbustr )
PORT_START("SPECIAL")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) /* Freeze input */
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) // Freeze input
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -171,7 +493,7 @@ static INPUT_PORTS_START( gunbustr )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
- /* Light gun inputs */
+ // Light gun inputs
PORT_START("LIGHT0_X")
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_PLAYER(1)
@@ -193,13 +515,13 @@ INPUT_PORTS_END
static const gfx_layout tile16x16_layout =
{
- 16,16, /* 16*16 sprites */
+ 16,16, // 16*16 sprites
RGN_FRAC(1,1),
- 4, /* 4 bits per pixel */
+ 4, // 4 bits per pixel
{ STEP4(0,16) },
{ STEP16(0,1) },
{ STEP16(0,16*4) },
- 16*16*4 /* every sprite takes 128 consecutive bytes */
+ 16*16*4 // every sprite takes 128 consecutive bytes
};
static GFXDECODE_START( gfx_gunbustr )
@@ -213,10 +535,10 @@ GFXDECODE_END
void gunbustr_state::gunbustr(machine_config &config)
{
- /* basic machine hardware */
+ // basic machine hardware
M68EC020(config, m_maincpu, XTAL(16'000'000));
- m_maincpu->set_addrmap(AS_PROGRAM, &gunbustr_state::gunbustr_map);
- m_maincpu->set_vblank_int("screen", FUNC(gunbustr_state::gunbustr_interrupt)); /* VBL */
+ m_maincpu->set_addrmap(AS_PROGRAM, &gunbustr_state::prg_map);
+ m_maincpu->set_vblank_int("screen", FUNC(gunbustr_state::gunbustr_interrupt)); // VBL
EEPROM_93C46_16BIT(config, "eeprom");
@@ -230,7 +552,7 @@ void gunbustr_state::gunbustr(machine_config &config)
tc0510nio.write_4_callback().set(FUNC(gunbustr_state::coin_word_w));
tc0510nio.read_7_callback().set_ioport("SYSTEM");
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
@@ -248,7 +570,7 @@ void gunbustr_state::gunbustr(machine_config &config)
m_tc0480scp->set_offsets_tx(-1, -1);
m_tc0480scp->set_offsets_flip(-1, 0);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
@@ -260,28 +582,28 @@ void gunbustr_state::gunbustr(machine_config &config)
/***************************************************************************/
ROM_START( gunbustr )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 1024K for 68020 code (CPU A) */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68020 code (CPU A)
ROM_LOAD32_BYTE( "d27-23.bin", 0x00000, 0x40000, CRC(cd1037cc) SHA1(8005a6a84081ce609e7a605ec8e00e740bfc6846) )
ROM_LOAD32_BYTE( "d27-22.bin", 0x00001, 0x40000, CRC(475949fc) SHA1(3d5aa3411d2618004902f9d05dff61d9af01ff35) )
ROM_LOAD32_BYTE( "d27-21.bin", 0x00002, 0x40000, CRC(60950a8a) SHA1(a0336bf6970baa6eaa998a112db840a7fd0452d7) )
ROM_LOAD32_BYTE( "d27-27.bin", 0x00003, 0x40000, CRC(fd7d3d4c) SHA1(df42e135b1e9b7e371971ba7c8a2e161f3623aa3) )
- ROM_REGION( 0x140000, "taito_en:audiocpu", 0 ) /* Sound cpu */
+ ROM_REGION( 0x140000, "taito_en:audiocpu", 0 )
ROM_LOAD16_BYTE( "d27-25.bin", 0x100000, 0x20000, CRC(c88203cf) SHA1(a918d395b471acdce56dacabd7a1e1e023948365) )
ROM_LOAD16_BYTE( "d27-24.bin", 0x100001, 0x20000, CRC(084bd8bd) SHA1(93229bc7de4550ead1bb12f666ddbacbe357488d) )
- ROM_REGION( 0x100000, "tc0480scp", 0 )
- ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) ) /* SCR 16x16 tiles */
+ ROM_REGION( 0x100000, "tc0480scp", 0 ) // SCR 16x16 tiles
+ ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) )
ROM_LOAD32_WORD( "d27-02.bin", 0x00002, 0x80000, CRC(92ab6430) SHA1(28ed80391c732b09d10c74ed6b78ac76cb62e083) )
- ROM_REGION( 0x400000, "sprites", 0 )
- ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) ) /* OBJ 16x16 tiles: each rom has 1 bitplane */
+ ROM_REGION( 0x400000, "sprites", 0 ) // OBJ 16x16 tiles: each ROM has 1 bitplane
+ ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) )
ROM_LOAD64_WORD_SWAP( "d27-05.bin", 0x000004, 0x100000, CRC(96d7c1a5) SHA1(93b6a7aea397280a5a778e736d433a85cb7da52c) )
ROM_LOAD64_WORD_SWAP( "d27-06.bin", 0x000002, 0x100000, CRC(bbb934db) SHA1(9e9b5cf05b9275f1182f5b499b8ee897c4f25b96) )
ROM_LOAD64_WORD_SWAP( "d27-07.bin", 0x000000, 0x100000, CRC(8ab4854e) SHA1(bd2750cdaa2918e56f8aef3732875952a1eeafea) )
- ROM_REGION16_LE( 0x80000, "spritemap", 0 )
- ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) ) /* STY, used to create big sprites on the fly */
+ ROM_REGION16_LE( 0x80000, "spritemap", 0 ) // STY, used to create big sprites on the fly
+ ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) )
ROM_REGION16_BE( 0x800000, "taito_en:ensoniq" , ROMREGION_ERASE00 )
ROM_LOAD16_BYTE( "d27-08.bin", 0x000000, 0x100000, CRC(7c147e30) SHA1(b605045154967050ec06391798da4afe3686a6e1) ) // C8, C9
@@ -294,28 +616,28 @@ ROM_START( gunbustr )
ROM_END
ROM_START( gunbustru )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 1024K for 68020 code (CPU A) */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68020 code (CPU A)
ROM_LOAD32_BYTE( "d27-23.bin", 0x00000, 0x40000, CRC(cd1037cc) SHA1(8005a6a84081ce609e7a605ec8e00e740bfc6846) )
ROM_LOAD32_BYTE( "d27-22.bin", 0x00001, 0x40000, CRC(475949fc) SHA1(3d5aa3411d2618004902f9d05dff61d9af01ff35) )
ROM_LOAD32_BYTE( "d27-21.bin", 0x00002, 0x40000, CRC(60950a8a) SHA1(a0336bf6970baa6eaa998a112db840a7fd0452d7) )
ROM_LOAD32_BYTE( "d27-26.bin", 0x00003, 0x40000, CRC(8a7a0dda) SHA1(59ee7c391c170ab05a3d3d940d833c65e265d9b3) )
- ROM_REGION( 0x140000, "taito_en:audiocpu", 0 ) /* Sound cpu */
+ ROM_REGION( 0x140000, "taito_en:audiocpu", 0 )
ROM_LOAD16_BYTE( "d27-25.bin", 0x100000, 0x20000, CRC(c88203cf) SHA1(a918d395b471acdce56dacabd7a1e1e023948365) )
ROM_LOAD16_BYTE( "d27-24.bin", 0x100001, 0x20000, CRC(084bd8bd) SHA1(93229bc7de4550ead1bb12f666ddbacbe357488d) )
- ROM_REGION( 0x100000, "tc0480scp", 0 )
- ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) ) /* SCR 16x16 tiles */
+ ROM_REGION( 0x100000, "tc0480scp", 0 ) // SCR 16x16 tiles
+ ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) )
ROM_LOAD32_WORD( "d27-02.bin", 0x00002, 0x80000, CRC(92ab6430) SHA1(28ed80391c732b09d10c74ed6b78ac76cb62e083) )
- ROM_REGION( 0x400000, "sprites", 0 )
- ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) ) /* OBJ 16x16 tiles: each rom has 1 bitplane */
+ ROM_REGION( 0x400000, "sprites", 0 ) // OBJ 16x16 tiles: each ROM has 1 bitplane
+ ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) )
ROM_LOAD64_WORD_SWAP( "d27-05.bin", 0x000004, 0x100000, CRC(96d7c1a5) SHA1(93b6a7aea397280a5a778e736d433a85cb7da52c) )
ROM_LOAD64_WORD_SWAP( "d27-06.bin", 0x000002, 0x100000, CRC(bbb934db) SHA1(9e9b5cf05b9275f1182f5b499b8ee897c4f25b96) )
ROM_LOAD64_WORD_SWAP( "d27-07.bin", 0x000000, 0x100000, CRC(8ab4854e) SHA1(bd2750cdaa2918e56f8aef3732875952a1eeafea) )
- ROM_REGION16_LE( 0x80000, "spritemap", 0 )
- ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) ) /* STY, used to create big sprites on the fly */
+ ROM_REGION16_LE( 0x80000, "spritemap", 0 ) // STY, used to create big sprites on the fly
+ ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) )
ROM_REGION16_BE( 0x800000, "taito_en:ensoniq" , ROMREGION_ERASE00 )
ROM_LOAD16_BYTE( "d27-08.bin", 0x000000, 0x100000, CRC(7c147e30) SHA1(b605045154967050ec06391798da4afe3686a6e1) ) // C8, C9
@@ -328,28 +650,28 @@ ROM_START( gunbustru )
ROM_END
ROM_START( gunbustrj )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 1024K for 68020 code (CPU A) */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68020 code (CPU A)
ROM_LOAD32_BYTE( "d27-23.bin", 0x00000, 0x40000, CRC(cd1037cc) SHA1(8005a6a84081ce609e7a605ec8e00e740bfc6846) )
ROM_LOAD32_BYTE( "d27-22.bin", 0x00001, 0x40000, CRC(475949fc) SHA1(3d5aa3411d2618004902f9d05dff61d9af01ff35) )
ROM_LOAD32_BYTE( "d27-21.bin", 0x00002, 0x40000, CRC(60950a8a) SHA1(a0336bf6970baa6eaa998a112db840a7fd0452d7) )
ROM_LOAD32_BYTE( "d27-20.bin", 0x00003, 0x40000, CRC(13735c60) SHA1(65b762b28d51b295f6fe190420af566b1b3d4a82) )
- ROM_REGION( 0x140000, "taito_en:audiocpu", 0 ) /* Sound cpu */
+ ROM_REGION( 0x140000, "taito_en:audiocpu", 0 )
ROM_LOAD16_BYTE( "d27-25.bin", 0x100000, 0x20000, CRC(c88203cf) SHA1(a918d395b471acdce56dacabd7a1e1e023948365) )
ROM_LOAD16_BYTE( "d27-24.bin", 0x100001, 0x20000, CRC(084bd8bd) SHA1(93229bc7de4550ead1bb12f666ddbacbe357488d) )
- ROM_REGION( 0x100000, "tc0480scp", 0 )
- ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) ) /* SCR 16x16 tiles */
+ ROM_REGION( 0x100000, "tc0480scp", 0 ) // SCR 16x16 tiles
+ ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) )
ROM_LOAD32_WORD( "d27-02.bin", 0x00002, 0x80000, CRC(92ab6430) SHA1(28ed80391c732b09d10c74ed6b78ac76cb62e083) )
- ROM_REGION( 0x400000, "sprites", 0 )
- ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) ) /* OBJ 16x16 tiles: each rom has 1 bitplane */
+ ROM_REGION( 0x400000, "sprites", 0 ) // OBJ 16x16 tiles: each ROM has 1 bitplane
+ ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) )
ROM_LOAD64_WORD_SWAP( "d27-05.bin", 0x000004, 0x100000, CRC(96d7c1a5) SHA1(93b6a7aea397280a5a778e736d433a85cb7da52c) )
ROM_LOAD64_WORD_SWAP( "d27-06.bin", 0x000002, 0x100000, CRC(bbb934db) SHA1(9e9b5cf05b9275f1182f5b499b8ee897c4f25b96) )
ROM_LOAD64_WORD_SWAP( "d27-07.bin", 0x000000, 0x100000, CRC(8ab4854e) SHA1(bd2750cdaa2918e56f8aef3732875952a1eeafea) )
- ROM_REGION16_LE( 0x80000, "spritemap", 0 )
- ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) ) /* STY, used to create big sprites on the fly */
+ ROM_REGION16_LE( 0x80000, "spritemap", 0 ) // STY, used to create big sprites on the fly
+ ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) )
ROM_REGION16_BE( 0x800000, "taito_en:ensoniq" , ROMREGION_ERASE00 )
ROM_LOAD16_BYTE( "d27-08.bin", 0x000000, 0x100000, CRC(7c147e30) SHA1(b605045154967050ec06391798da4afe3686a6e1) ) // C8, C9
@@ -363,7 +685,7 @@ ROM_END
u32 gunbustr_state::main_cycle_r()
{
- if (m_maincpu->pc() == 0x55a && (m_ram[0x3acc/4] & 0xff000000) == 0)
+ if (m_maincpu->pc() == 0x55a && (m_ram[0x3acc / 4] & 0xff000000) == 0)
m_maincpu->spin_until_interrupt();
return m_ram[0x3acc/4];
@@ -371,7 +693,7 @@ u32 gunbustr_state::main_cycle_r()
void gunbustr_state::init_gunbustr()
{
- /* Speedup handler */
+ // Speedup handler
m_maincpu->space(AS_PROGRAM).install_read_handler(0x203acc, 0x203acf, read32smo_delegate(*this, FUNC(gunbustr_state::main_cycle_r)));
m_interrupt5_timer = timer_alloc(FUNC(gunbustr_state::trigger_irq5), this);
@@ -385,6 +707,9 @@ void gunbustr_state::init_gunbustrj()
m_coin_lockout = false;
}
-GAME( 1992, gunbustr, 0, gunbustr, gunbustr, gunbustr_state, init_gunbustr, ORIENTATION_FLIP_X, "Taito Corporation Japan", "Gunbuster (World)", MACHINE_NODEVICE_LAN )
-GAME( 1992, gunbustru, gunbustr, gunbustr, gunbustr, gunbustr_state, init_gunbustr, ORIENTATION_FLIP_X, "Taito America Corporation", "Gunbuster (US)", MACHINE_NODEVICE_LAN )
-GAME( 1992, gunbustrj, gunbustr, gunbustr, gunbustr, gunbustr_state, init_gunbustrj,ORIENTATION_FLIP_X, "Taito Corporation", "Gunbuster (Japan)", MACHINE_NODEVICE_LAN )
+} // anonymous namespace
+
+
+GAME( 1992, gunbustr, 0, gunbustr, gunbustr, gunbustr_state, init_gunbustr, ORIENTATION_FLIP_X, "Taito Corporation Japan", "Gunbuster (World)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE )
+GAME( 1992, gunbustru, gunbustr, gunbustr, gunbustr, gunbustr_state, init_gunbustr, ORIENTATION_FLIP_X, "Taito America Corporation", "Gunbuster (US)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE )
+GAME( 1992, gunbustrj, gunbustr, gunbustr, gunbustr, gunbustr_state, init_gunbustrj,ORIENTATION_FLIP_X, "Taito Corporation", "Gunbuster (Japan)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/taito/gunbustr.h b/src/mame/taito/gunbustr.h
deleted file mode 100644
index 21d33e9b788..00000000000
--- a/src/mame/taito/gunbustr.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Bryan McPhail, David Graves
-#ifndef MAME_INCLUDES_GUNBUSTR_H
-#define MAME_INCLUDES_GUNBUSTR_H
-
-#pragma once
-
-#include "machine/eepromser.h"
-#include "tc0480scp.h"
-#include "emupal.h"
-
-struct gb_tempsprite
-{
- int gfx = 0;
- int code = 0, color = 0;
- int flipx,flipy = 0;
- int x = 0, y = 0;
- int zoomx = 0, zoomy = 0;
- int primask = 0;
-};
-
-class gunbustr_state : public driver_device
-{
-public:
- gunbustr_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_maincpu(*this,"maincpu"),
- m_tc0480scp(*this, "tc0480scp"),
- m_ram(*this,"ram"),
- m_spriteram(*this,"spriteram"),
- m_eeprom(*this, "eeprom"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette"),
- m_spritemap(*this, "spritemap"),
- m_io_light_x(*this, "LIGHT%u_X", 0U),
- m_io_light_y(*this, "LIGHT%u_Y", 0U)
- {
- m_coin_lockout = true;
- }
-
- void gunbustr(machine_config &config);
-
- void init_gunbustrj();
- void init_gunbustr();
-
-private:
- virtual void video_start() override;
-
- void gunbustr_map(address_map &map);
-
- TIMER_CALLBACK_MEMBER(trigger_irq5);
-
- void motor_control_w(u32 data);
- u32 gun_r();
- void gun_w(u32 data);
- u32 main_cycle_r();
- void coin_word_w(u8 data);
- u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- INTERRUPT_GEN_MEMBER(gunbustr_interrupt);
- void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,const u32 *primasks,int x_offs,int y_offs);
-
- required_device<cpu_device> m_maincpu;
- required_device<tc0480scp_device> m_tc0480scp;
- required_shared_ptr<u32> m_ram;
- required_shared_ptr<u32> m_spriteram;
- required_device<eeprom_serial_93cxx_device> m_eeprom;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
- required_region_ptr<u16> m_spritemap;
-
- required_ioport_array<2> m_io_light_x;
- required_ioport_array<2> m_io_light_y;
-
- bool m_coin_lockout;
- std::unique_ptr<gb_tempsprite[]> m_spritelist{};
- emu_timer *m_interrupt5_timer = nullptr;
-};
-
-#endif // MAME_INCLUDES_GUNBUSTR_H
diff --git a/src/mame/taito/gunbustr_v.cpp b/src/mame/taito/gunbustr_v.cpp
deleted file mode 100644
index b9520f11daa..00000000000
--- a/src/mame/taito/gunbustr_v.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Bryan McPhail, David Graves
-#include "emu.h"
-#include "gunbustr.h"
-#include "screen.h"
-
-/************************************************************/
-
-void gunbustr_state::video_start()
-{
- m_spritelist = std::make_unique<gb_tempsprite[]>(0x4000);
-}
-
-/************************************************************
- SPRITE DRAW ROUTINES
-
-We draw a series of small tiles ("chunks") together to
-create each big sprite. The spritemap rom provides the lookup
-table for this. The game hardware looks up 16x16 sprite chunks
-from the spritemap rom, creating a 64x64 sprite like this:
-
- 0 1 2 3
- 4 5 6 7
- 8 9 10 11
- 12 13 14 15
-
-(where the number is the word offset into the spritemap rom).
-It can also create 32x32 sprites.
-
-NB: unused portions of the spritemap rom contain hex FF's.
-It is a useful coding check to warn in the log if these
-are being accessed. [They can be inadvertently while
-spriteram is being tested, take no notice of that.]
-
-Heavy use is made of sprite zooming.
-
- ***
-
- Sprite table layout (4 long words per entry)
-
- ------------------------------------------
- 0 | ........ x....... ........ ........ | Flip X
- 0 | ........ .xxxxxxx ........ ........ | ZoomX
- 0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile
- | |
- 2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*]
- 2 | ........ ......xx xxxxxx.. ........ | Palette bank
- 2 | ........ ........ ......xx xxxxxxxx | X position
- | |
- 3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64)
- 3 | ........ ......x. ........ ........ | Flip Y
- 3 | ........ .......x xxxxxx.. ........ | ZoomY
- 3 | ........ ........ ......xx xxxxxxxx | Y position
- ------------------------------------------
-
- [* 00=over BG1; 01=BG2; 10=BG3; 11=over text ???]
-
-********************************************************/
-
-void gunbustr_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,const u32 *primasks,int x_offs,int y_offs)
-{
- int sprites_flipscreen = 0;
-
- /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list
- while processing sprite ram and then draw them all at the end */
- struct gb_tempsprite *sprite_ptr = m_spritelist.get();
-
- for (int offs = (m_spriteram.bytes() / 4 - 4); offs >= 0; offs -= 4)
- {
- u32 data = m_spriteram[offs+0];
- int flipx = (data & 0x00800000) >> 23;
- int zoomx = (data & 0x007f0000) >> 16;
- const u32 tilenum = (data & 0x00007fff);
-
- data = m_spriteram[offs+2];
- const int priority = (data & 0x000c0000) >> 18;
- int color = (data & 0x0003fc00) >> 10;
- int x = (data & 0x000003ff);
-
- data = m_spriteram[offs+3];
- const int dblsize = (data & 0x00040000) >> 18;
- int flipy = (data & 0x00020000) >> 17;
- int zoomy = (data & 0x0001fc00) >> 10;
- int y = (data & 0x000003ff);
-
- color |= 0x80;
-
- if (!tilenum) continue;
-
- flipy = !flipy;
- zoomx += 1;
- zoomy += 1;
-
- y += y_offs;
-
- /* treat coords as signed */
- if (x > 0x340) x -= 0x400;
- if (y > 0x340) y -= 0x400;
-
- x -= x_offs;
-
- int bad_chunks = 0;
- const int dimension = ((dblsize*2) + 2); // 2 or 4
- const int total_chunks = ((dblsize*3) + 1) << 2; // 4 or 16
- const int map_offset = tilenum << 2;
-
- for (int sprite_chunk = 0; sprite_chunk < total_chunks; sprite_chunk++)
- {
- const int j = sprite_chunk / dimension; /* rows */
- const int k = sprite_chunk % dimension; /* chunks per row */
-
- int px = k;
- int py = j;
- /* pick tiles back to front for x and y flips */
- if (flipx) px = dimension - 1 - k;
- if (flipy) py = dimension - 1 - j;
-
- const u32 code = m_spritemap[map_offset + px + (py<<(dblsize+1))];
-
- if (code == 0xffff)
- {
- bad_chunks += 1;
- continue;
- }
-
- int curx = x + ((k * zoomx) / dimension);
- int cury = y + ((j * zoomy) / dimension);
-
- const int zx = x + (((k + 1) * zoomx) / dimension) - curx;
- const int zy = y + (((j + 1) * zoomy) / dimension) - cury;
-
- if (sprites_flipscreen)
- {
- /* -zx/y is there to fix zoomed sprite coords in screenflip.
- drawgfxzoom does not know to draw from flip-side of sprites when
- screen is flipped; so we must correct the coords ourselves. */
-
- curx = 320 - curx - zx;
- cury = 256 - cury - zy;
- flipx = !flipx;
- flipy = !flipy;
- }
-
- sprite_ptr->gfx = 0;
- sprite_ptr->code = code;
- sprite_ptr->color = color;
- sprite_ptr->flipx = !flipx;
- sprite_ptr->flipy = flipy;
- sprite_ptr->x = curx;
- sprite_ptr->y = cury;
- sprite_ptr->zoomx = zx << 12;
- sprite_ptr->zoomy = zy << 12;
-
- if (primasks)
- {
- sprite_ptr->primask = primasks[priority];
-
- sprite_ptr++;
- }
- else
- {
- m_gfxdecode->gfx(sprite_ptr->gfx)->zoom_transpen(bitmap,cliprect,
- sprite_ptr->code,
- sprite_ptr->color,
- sprite_ptr->flipx,sprite_ptr->flipy,
- sprite_ptr->x,sprite_ptr->y,
- sprite_ptr->zoomx,sprite_ptr->zoomy,0);
- }
- }
-
- if (bad_chunks)
-logerror("Sprite number %04x had %02x invalid chunks\n",tilenum,bad_chunks);
- }
-
- /* this happens only if primsks != nullptr */
- while (sprite_ptr != m_spritelist.get())
- {
- sprite_ptr--;
-
- m_gfxdecode->gfx(sprite_ptr->gfx)->prio_zoom_transpen(bitmap,cliprect,
- sprite_ptr->code,
- sprite_ptr->color,
- sprite_ptr->flipx,sprite_ptr->flipy,
- sprite_ptr->x,sprite_ptr->y,
- sprite_ptr->zoomx,sprite_ptr->zoomy,
- screen.priority(),sprite_ptr->primask,0);
- }
-}
-
-
-
-/**************************************************************
- SCREEN REFRESH
-**************************************************************/
-
-u32 gunbustr_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- u8 layer[5];
- u16 priority;
- static const u32 primasks[4] = {0xfffc, 0xfff0, 0xff00, 0x0};
-
- m_tc0480scp->tilemap_update();
-
- priority = m_tc0480scp->get_bg_priority();
- layer[0] = (priority & 0xf000) >> 12; /* tells us which bg layer is bottom */
- layer[1] = (priority & 0x0f00) >> 8;
- layer[2] = (priority & 0x00f0) >> 4;
- layer[3] = (priority & 0x000f) >> 0; /* tells us which is top */
- layer[4] = 4; /* text layer always over bg layers */
-
- screen.priority().fill(0, cliprect);
-
- /* We have to assume 2nd to bottom layer is always underneath
- sprites as pdrawgfx cannot yet cope with more than 4 layers */
-
-#ifdef MAME_DEBUG
- if (!machine().input().code_pressed (KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0],TILEMAP_DRAW_OPAQUE, 0);
- if (!machine().input().code_pressed (KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 1);
- if (!machine().input().code_pressed (KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 2);
- if (!machine().input().code_pressed (KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 4);
- if (!machine().input().code_pressed (KEYCODE_B)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 8);
- if (!machine().input().code_pressed (KEYCODE_N)) draw_sprites(screen, bitmap, cliprect, primasks, 48, -116);
-#else
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 0);
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 1);
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 2);
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 4);
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 8); /* text layer */
- draw_sprites(screen, bitmap, cliprect, primasks, 48, -116);
-#endif
- return 0;
-}
diff --git a/src/mame/taito/msisaac.cpp b/src/mame/taito/msisaac.cpp
index 1a46a5fa95b..f9e789b5bf3 100644
--- a/src/mame/taito/msisaac.cpp
+++ b/src/mame/taito/msisaac.cpp
@@ -1,5 +1,6 @@
// license:GPL-2.0+
-// copyright-holders:Jarek Burczynski
+// copyright-holders: Jarek Burczynski
+
/****************************************************************************
Metal Soldier Isaac II (c) Taito 1985
@@ -15,14 +16,347 @@
****************************************************************************/
#include "emu.h"
-#include "msisaac.h"
+
+#include "taito68705.h"
#include "cpu/z80/z80.h"
#include "cpu/m6805/m6805.h"
+#include "machine/gen_latch.h"
#include "sound/ay8910.h"
+#include "sound/msm5232.h"
+#include "sound/ta7630.h"
+
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
+
+
+// configurable logging
+#define LOG_BG2CTRL (1U << 1)
+#define LOG_UNKWRITE (1U << 2)
+#define LOG_MCU (1U << 3)
+#define LOG_SOUND (1U << 4)
+
+//#define VERBOSE (LOG_GENERAL | LOG_BG2CTRL | LOG_UNKWRITE | LOGMCU | LOGSOUND)
+
+#include "logmacro.h"
+
+#define LOGBG2CTRL(...) LOGMASKED(LOG_BG2CTRL, __VA_ARGS__)
+#define LOGUNKWRITE(...) LOGMASKED(LOG_UNKWRITE, __VA_ARGS__)
+#define LOGMCU(...) LOGMASKED(LOG_MCU, __VA_ARGS__)
+#define LOGSOUND(...) LOGMASKED(LOG_SOUND, __VA_ARGS__)
+
+
+namespace {
+
+// Disabled because the MCU dump is currently unavailable. -AS
+//#define USE_MCU
+
+class msisaac_state : public driver_device
+{
+public:
+ msisaac_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_spriteram(*this, "spriteram"),
+ m_videoram(*this, "videoram%u", 1U),
+ m_audiocpu(*this, "audiocpu"),
+ m_maincpu(*this, "maincpu"),
+ m_bmcu(*this, "bmcu"),
+ m_msm(*this, "msm"),
+ m_ta7630(*this, "ta7630"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette"),
+ m_soundlatch(*this, "soundlatch"),
+ m_in1(*this, "IN1")
+ { }
+
+ void msisaac(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ virtual void video_start() override;
+
+private:
+ // memory pointers
+ required_shared_ptr<uint8_t> m_spriteram;
+ required_shared_ptr_array<uint8_t, 3> m_videoram;
+
+ // video-related
+ bitmap_ind16 *m_tmp_bitmap[2]{};
+ tilemap_t *m_bg_tilemap[2]{};
+ tilemap_t *m_fg_tilemap = nullptr;
+ uint8_t m_bg2_textbank = 0;
+
+ // sound-related
+ uint8_t m_sound_nmi_enable = 0;
+ uint8_t m_pending_nmi = 0;
+
+ // fake MCU
+#ifndef USE_MCU
+ uint8_t m_mcu_val = 0;
+ uint8_t m_direction = 0;
+#endif
+
+ uint8_t m_snd_ctrl[2]{};
+
+ // devices
+ required_device<cpu_device> m_audiocpu;
+ required_device<cpu_device> m_maincpu;
+ optional_device<taito68705_mcu_device> m_bmcu;
+ required_device<msm5232_device> m_msm;
+ required_device<ta7630_device> m_ta7630;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+ required_device<generic_latch_8_device> m_soundlatch;
+
+ required_ioport m_in1;
+
+ void sound_command_w(uint8_t data);
+ void nmi_disable_w(uint8_t data);
+ void nmi_enable_w(uint8_t data);
+ void unknown_w(uint8_t data);
+ uint8_t mcu_r(offs_t offset);
+ uint8_t mcu_status_r(offs_t offset);
+ void mcu_w(offs_t offset, uint8_t data);
+ void fg_scrolly_w(uint8_t data);
+ void fg_scrollx_w(uint8_t data);
+ void bg2_scrollx_w(uint8_t data);
+ template <uint8_t Which> void bg_scrolly_w(uint8_t data);
+ void bg_scrollx_w(uint8_t data);
+ void bg2_textbank_w(uint8_t data);
+ template <uint8_t Which> void bg_videoram_w(offs_t offset, uint8_t data);
+ void fg_videoram_w(offs_t offset, uint8_t data);
+ void sound_control_0_w(uint8_t data);
+ void sound_control_1_w(uint8_t data);
+ TILE_GET_INFO_MEMBER(get_fg_tile_info);
+ TILE_GET_INFO_MEMBER(get_bg_tile_info);
+ TILE_GET_INFO_MEMBER(get_bg2_tile_info);
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ TIMER_CALLBACK_MEMBER(nmi_callback);
+ void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void main_map(address_map &map);
+ void sound_map(address_map &map);
+};
+
+
+// video
+
+/***************************************************************************
+
+ Callbacks for the TileMap code
+
+***************************************************************************/
+
+TILE_GET_INFO_MEMBER(msisaac_state::get_fg_tile_info)
+{
+ int const tile_number = m_videoram[0][tile_index];
+ tileinfo.set(0,
+ tile_number,
+ 0x10,
+ 0);
+}
+
+TILE_GET_INFO_MEMBER(msisaac_state::get_bg_tile_info)
+{
+ int const tile_number = m_videoram[1][tile_index];
+ tileinfo.set(1,
+ 0x100 + tile_number,
+ 0x30,
+ 0);
+}
+
+TILE_GET_INFO_MEMBER(msisaac_state::get_bg2_tile_info)
+{
+ int const tile_number = m_videoram[2][tile_index];
+
+ // graphics 0 or 1
+ int const gfx_b = (m_bg2_textbank >> 3) & 1;
+
+ tileinfo.set(gfx_b,
+ tile_number,
+ 0x20,
+ 0);
+}
+
+/***************************************************************************
+
+ Start the video hardware emulation.
+
+***************************************************************************/
+
+void msisaac_state::video_start()
+{
+ m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
+ m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_bg2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
+ m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
+
+ m_bg_tilemap[1]->set_transparent_pen(0);
+ m_fg_tilemap->set_transparent_pen(0);
+}
+
+
+/***************************************************************************
+
+ Memory handlers
+
+***************************************************************************/
+
+void msisaac_state::fg_scrolly_w(uint8_t data)
+{
+ m_fg_tilemap->set_scrolly(0, data);
+}
+
+void msisaac_state::fg_scrollx_w(uint8_t data)
+{
+ m_fg_tilemap->set_scrollx(0, 9 + data);
+}
+template <uint8_t Which>
+void msisaac_state::bg_scrolly_w(uint8_t data)
+{
+ m_bg_tilemap[Which]->set_scrolly(0, data);
+}
+
+void msisaac_state::bg_scrollx_w(uint8_t data)
+{
+ m_bg_tilemap[0]->set_scrollx(0, 9 + 2 + data);
+}
+
+void msisaac_state::bg2_scrollx_w(uint8_t data)
+{
+ m_bg_tilemap[1]->set_scrollx(0, 9 + 4 + data);
+}
+
+
+void msisaac_state::bg2_textbank_w(uint8_t data)
+{
+ if (m_bg2_textbank != data)
+ {
+ m_bg2_textbank = data;
+ m_bg_tilemap[1]->mark_all_dirty();
+
+ //check if we are correct on this one
+ if ((data != 8) && (data != 0))
+ {
+ LOGBG2CTRL("bg2 control = %2x\n", data);
+ }
+ }
+}
+
+template <uint8_t Which>
+void msisaac_state::bg_videoram_w(offs_t offset, uint8_t data)
+{
+ m_videoram[Which + 1][offset] = data;
+ m_bg_tilemap[Which]->mark_tile_dirty(offset);
+}
+
+void msisaac_state::fg_videoram_w(offs_t offset, uint8_t data)
+{
+ m_videoram[0][offset] = data;
+ m_fg_tilemap->mark_tile_dirty(offset);
+}
+
+
+/***************************************************************************
+
+ Display refresh
+
+***************************************************************************/
+void msisaac_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ const uint8_t *source = m_spriteram + 32 * 4 - 4;
+ const uint8_t *finish = m_spriteram; // ?
+
+ while (source >= finish)
+ {
+ int const sx = source[0];
+ int const sy = 240 - source[1] - 1;
+ int const attributes = source[2];
+ int const sprite_number = source[3];
+
+ int const color = (attributes >> 4) & 0xf;
+ int const flipx = (attributes & 0x1);
+ int const flipy = (attributes & 0x2);
+
+ gfx_element *gfx = m_gfxdecode->gfx(2);
+
+ if (attributes & 4)
+ {
+ //color = machine().rand() & 15;
+ gfx = m_gfxdecode->gfx(3);
+ }
+
+ if (attributes & 8) // double size sprite
+ {
+ switch (attributes & 3)
+ {
+ case 0: // flipx == 0 && flipy == 0
+ gfx->transpen(bitmap, cliprect,
+ sprite_number + 1, color,
+ flipx, flipy,
+ sx, sy - 16, 0);
+ gfx->transpen(bitmap, cliprect,
+ sprite_number, color,
+ flipx, flipy,
+ sx, sy, 0);
+ break;
+ case 1: // flipx == 1 && flipy == 0
+ gfx->transpen(bitmap, cliprect,
+ sprite_number + 1, color,
+ flipx, flipy,
+ sx, sy - 16, 0);
+ gfx->transpen(bitmap, cliprect,
+ sprite_number, color,
+ flipx, flipy,
+ sx, sy, 0);
+ break;
+ case 2: // flipx == 0 && flipy == 1
+ gfx->transpen(bitmap, cliprect,
+ sprite_number, color,
+ flipx, flipy,
+ sx, sy - 16, 0);
+ gfx->transpen(bitmap, cliprect,
+ sprite_number + 1, color,
+ flipx, flipy,
+ sx, sy, 0);
+ break;
+ case 3: // flipx == 1 && flipy == 1
+ gfx->transpen(bitmap, cliprect,
+ sprite_number, color,
+ flipx, flipy,
+ sx, sy - 16, 0);
+ gfx->transpen(bitmap, cliprect,
+ sprite_number + 1, color,
+ flipx, flipy,
+ sx, sy, 0);
+ break;
+ }
+ }
+ else
+ {
+ gfx->transpen(bitmap, cliprect,
+ sprite_number,
+ color,
+ flipx, flipy,
+ sx, sy, 0);
+ }
+ source -= 4;
+ }
+}
+
+uint32_t msisaac_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ m_bg_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
+ m_bg_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
+ draw_sprites(bitmap, cliprect);
+ m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ return 0;
+}
+
+
+// machine
TIMER_CALLBACK_MEMBER(msisaac_state::nmi_callback)
{
@@ -59,16 +393,16 @@ void msisaac_state::flip_screen_w(uint8_t data)
flip_screen_set(data);
}
-void msisaac_state::msisaac_coin_counter_w(offs_t offset, uint8_t data)
+void msisaac_state::coin_counter_w(offs_t offset, uint8_t data)
{
machine().bookkeeping().coin_counter_w(offset,data);
}
#endif
-void msisaac_state::ms_unknown_w(uint8_t data)
+void msisaac_state::unknown_w(uint8_t data)
{
if (data != 0x08)
- popmessage("CPU #0 write to 0xf0a3 data=%2x", data);
+ LOGUNKWRITE("CPU #0 write to 0xf0a3 data = %2x", data);
}
@@ -80,7 +414,7 @@ void msisaac_state::ms_unknown_w(uint8_t data)
-uint8_t msisaac_state::msisaac_mcu_r(offs_t offset)
+uint8_t msisaac_state::mcu_r(offs_t offset)
{
#ifdef USE_MCU
return m_bmcu->buggychl_mcu_r(offset);
@@ -88,23 +422,23 @@ uint8_t msisaac_state::msisaac_mcu_r(offs_t offset)
/*
MCU simulation TODO:
\-Find the command which allows player-2 to play.
-\-Fix some graphics imperfections(*not* confirmed if they are caused by unhandled
+\-Fix some graphics imperfections (*not* confirmed if they are caused by unhandled
commands or imperfect video emulation).
*/
switch (m_mcu_val)
{
- /*Start-up check*/
+ // Start-up check
case 0x5f: return (m_mcu_val + 0x6b);
- /*These interferes with RAM operations(setting them to non-zero you *
- * will have unexpected results,such as infinite lives or score not *
+ /*These interfere with RAM operations (setting them to non-zero you *
+ * will have unexpected results, such as infinite lives or score not *
* incremented properly).*/
case 0x40:
case 0x41:
case 0x42:
return 0;
- /*With this command the MCU controls body direction */
+ // With this command the MCU controls body direction
case 0x02:
{
//direction:
@@ -117,7 +451,7 @@ MCU simulation TODO:
//6-down
//7-leftdwn
- uint8_t val= (ioport("IN1")->read() >> 2) & 0x0f;
+ uint8_t val = (m_in1->read() >> 2) & 0x0f;
/* bit0 = left
bit1 = right
bit2 = down
@@ -141,60 +475,60 @@ MCU simulation TODO:
return m_direction;
}
- /*This controls the arms when they return to the player. */
+ //This controls the arms when they return to the player.
case 0x07:
return 0x45;
default:
- logerror("CPU#0 read from MCU pc=%4x, mcu_val=%2x\n", m_maincpu->pc(), m_mcu_val);
+ LOGMCU("CPU#0 read from MCU pc = %4x, mcu_val = %2x\n", m_maincpu->pc(), m_mcu_val);
return m_mcu_val;
}
#endif
}
-uint8_t msisaac_state::msisaac_mcu_status_r(offs_t offset)
+uint8_t msisaac_state::mcu_status_r(offs_t offset)
{
#ifdef USE_MCU
return m_bmcu->buggychl_mcu_status_r(offset);
#else
- return 3; //mcu ready / cpu data ready
+ return 3; // MCU ready / CPU data ready
#endif
}
-void msisaac_state::msisaac_mcu_w(offs_t offset, uint8_t data)
+void msisaac_state::mcu_w(offs_t offset, uint8_t data)
{
#ifdef USE_MCU
m_bmcu->buggychl_mcu_w(offset,data);
#else
- //if(data != 0x0a && data != 0x42 && data != 0x02)
- // popmessage("PC = %04x %02x", m_maincpu->pc(), data);
+ if(data != 0x0a && data != 0x42 && data != 0x02)
+ LOGMCU("PC = %04x %02x", m_maincpu->pc(), data);
m_mcu_val = data;
#endif
}
-void msisaac_state::msisaac_map(address_map &map)
+void msisaac_state::main_map(address_map &map)
{
map(0x0000, 0xdfff).rom();
map(0xe000, 0xe7ff).ram();
map(0xe800, 0xefff).ram().w(m_palette, FUNC(palette_device::write8)).share("palette");
- map(0xf000, 0xf000).w(FUNC(msisaac_state::msisaac_bg2_textbank_w));
- map(0xf001, 0xf001).nopw(); //???
- map(0xf002, 0xf002).nopw(); //???
+ map(0xf000, 0xf000).w(FUNC(msisaac_state::bg2_textbank_w));
+ map(0xf001, 0xf001).nopw(); // ???
+ map(0xf002, 0xf002).nopw(); // ???
- map(0xf060, 0xf060).w(FUNC(msisaac_state::sound_command_w)); //sound command
- map(0xf061, 0xf061).nopw(); /*sound_reset*/ //????
+ map(0xf060, 0xf060).w(FUNC(msisaac_state::sound_command_w));
+ map(0xf061, 0xf061).nopw(); //sound_reset ????
- map(0xf0a3, 0xf0a3).w(FUNC(msisaac_state::ms_unknown_w)); //???? written in interrupt routine
+ map(0xf0a3, 0xf0a3).w(FUNC(msisaac_state::unknown_w)); // ???? written in interrupt routine
- map(0xf0c0, 0xf0c0).w(FUNC(msisaac_state::msisaac_fg_scrollx_w));
- map(0xf0c1, 0xf0c1).w(FUNC(msisaac_state::msisaac_fg_scrolly_w));
- map(0xf0c2, 0xf0c2).w(FUNC(msisaac_state::msisaac_bg2_scrollx_w));
- map(0xf0c3, 0xf0c3).w(FUNC(msisaac_state::msisaac_bg2_scrolly_w));
- map(0xf0c4, 0xf0c4).w(FUNC(msisaac_state::msisaac_bg_scrollx_w));
- map(0xf0c5, 0xf0c5).w(FUNC(msisaac_state::msisaac_bg_scrolly_w));
+ map(0xf0c0, 0xf0c0).w(FUNC(msisaac_state::fg_scrollx_w));
+ map(0xf0c1, 0xf0c1).w(FUNC(msisaac_state::fg_scrolly_w));
+ map(0xf0c2, 0xf0c2).w(FUNC(msisaac_state::bg2_scrollx_w));
+ map(0xf0c3, 0xf0c3).w(FUNC(msisaac_state::bg_scrolly_w<1>));
+ map(0xf0c4, 0xf0c4).w(FUNC(msisaac_state::bg_scrollx_w));
+ map(0xf0c5, 0xf0c5).w(FUNC(msisaac_state::bg_scrolly_w<0>));
- map(0xf0e0, 0xf0e0).rw(FUNC(msisaac_state::msisaac_mcu_r), FUNC(msisaac_state::msisaac_mcu_w));
- map(0xf0e1, 0xf0e1).r(FUNC(msisaac_state::msisaac_mcu_status_r));
+ map(0xf0e0, 0xf0e0).rw(FUNC(msisaac_state::mcu_r), FUNC(msisaac_state::mcu_w));
+ map(0xf0e1, 0xf0e1).r(FUNC(msisaac_state::mcu_status_r));
map(0xf080, 0xf080).portr("DSW1");
map(0xf081, 0xf081).portr("DSW2");
@@ -203,43 +537,43 @@ void msisaac_state::msisaac_map(address_map &map)
map(0xf084, 0xf084).portr("IN1");
// map(0xf086, 0xf086).portr("IN2");
- map(0xf100, 0xf17f).ram().share("spriteram"); //sprites
- map(0xf400, 0xf7ff).ram().w(FUNC(msisaac_state::msisaac_fg_videoram_w)).share("videoram");
- map(0xf800, 0xfbff).ram().w(FUNC(msisaac_state::msisaac_bg2_videoram_w)).share("videoram3");
- map(0xfc00, 0xffff).ram().w(FUNC(msisaac_state::msisaac_bg_videoram_w)).share("videoram2");
-// map(0xf801, 0xf801).w(FUNC(msisaac_state::msisaac_bgcolor_w));
+ map(0xf100, 0xf17f).ram().share("spriteram");
+ map(0xf400, 0xf7ff).ram().w(FUNC(msisaac_state::fg_videoram_w)).share(m_videoram[0]);
+ map(0xf800, 0xfbff).ram().w(FUNC(msisaac_state::bg_videoram_w<1>)).share(m_videoram[2]);
+ map(0xfc00, 0xffff).ram().w(FUNC(msisaac_state::bg_videoram_w<0>)).share(m_videoram[1]);
+// map(0xf801, 0xf801).w(FUNC(msisaac_state::bgcolor_w));
// map(0xfc00, 0xfc00).w(FUNC(msisaac_state::flip_screen_w));
-// map(0xfc03, 0xfc04).w(FUNC(msisaac_state::msisaac_coin_counter_w));
+// map(0xfc03, 0xfc04).w(FUNC(msisaac_state::coin_counter_w));
}
void msisaac_state::sound_control_0_w(uint8_t data)
{
- m_snd_ctrl0 = data & 0xff;
- //popmessage("SND0 0=%2x 1=%2x", m_snd_ctrl0, m_snd_ctrl1);
+ m_snd_ctrl[0] = data;
+ LOGSOUND("SND0 0 = %2x 1 = %2x", m_snd_ctrl[0], m_snd_ctrl[1]);
- for(int i=0;i<4;i++)
+ for (int i = 0; i < 4; i++)
{
// group1
- m_ta7630->set_channel_volume(m_msm,i, m_snd_ctrl0 & 0xf);
+ m_ta7630->set_channel_volume(m_msm, i, m_snd_ctrl[0] & 0xf);
// group2
- m_ta7630->set_channel_volume(m_msm,i+4, m_snd_ctrl0 >> 4);
+ m_ta7630->set_channel_volume(m_msm, i + 4, m_snd_ctrl[0] >> 4);
}
-// m_msm->set_output_gain(0, m_vol_ctrl[m_snd_ctrl0 & 15] / 100.0); /* group1 from msm5232 */
-// m_msm->set_output_gain(1, m_vol_ctrl[m_snd_ctrl0 & 15] / 100.0); /* group1 from msm5232 */
-// m_msm->set_output_gain(2, m_vol_ctrl[m_snd_ctrl0 & 15] / 100.0); /* group1 from msm5232 */
-// m_msm->set_output_gain(3, m_vol_ctrl[m_snd_ctrl0 & 15] / 100.0); /* group1 from msm5232 */
-// m_msm->set_output_gain(4, m_vol_ctrl[(m_snd_ctrl0 >> 4) & 15] / 100.0); /* group2 from msm5232 */
-// m_msm->set_output_gain(5, m_vol_ctrl[(m_snd_ctrl0 >> 4) & 15] / 100.0); /* group2 from msm5232 */
-// m_msm->set_output_gain(6, m_vol_ctrl[(m_snd_ctrl0 >> 4) & 15] / 100.0); /* group2 from msm5232 */
-// m_msm->set_output_gain(7, m_vol_ctrl[(m_snd_ctrl0 >> 4) & 15] / 100.0); /* group2 from msm5232 */
+// m_msm->set_output_gain(0, m_vol_ctrl[m_snd_ctrl[0] & 15] / 100.0); // group1 from msm5232
+// m_msm->set_output_gain(1, m_vol_ctrl[m_snd_ctrl[0] & 15] / 100.0); // group1 from msm5232
+// m_msm->set_output_gain(2, m_vol_ctrl[m_snd_ctrl[0] & 15] / 100.0); // group1 from msm5232
+// m_msm->set_output_gain(3, m_vol_ctrl[m_snd_ctrl[0] & 15] / 100.0); // group1 from msm5232
+// m_msm->set_output_gain(4, m_vol_ctrl[(m_snd_ctrl[0] >> 4) & 15] / 100.0); // group2 from msm5232
+// m_msm->set_output_gain(5, m_vol_ctrl[(m_snd_ctrl[0] >> 4) & 15] / 100.0); // group2 from msm5232
+// m_msm->set_output_gain(6, m_vol_ctrl[(m_snd_ctrl[0] >> 4) & 15] / 100.0); // group2 from msm5232
+// m_msm->set_output_gain(7, m_vol_ctrl[(m_snd_ctrl[0] >> 4) & 15] / 100.0); // group2 from msm5232
}
void msisaac_state::sound_control_1_w(uint8_t data)
{
- m_snd_ctrl1 = data & 0xff;
- //popmessage("SND1 0=%2x 1=%2x", m_snd_ctrl0, m_snd_ctrl1);
+ m_snd_ctrl[1] = data;
+ LOGSOUND("SND1 0 = %2x 1 = %2x", m_snd_ctrl[0], m_snd_ctrl[1]);
}
-void msisaac_state::msisaac_sound_map(address_map &map)
+void msisaac_state::sound_map(address_map &map)
{
map(0x0000, 0x3fff).rom();
map(0x4000, 0x47ff).ram();
@@ -251,8 +585,8 @@ void msisaac_state::msisaac_sound_map(address_map &map)
map(0xc000, 0xc000).r(m_soundlatch, FUNC(generic_latch_8_device::read));
map(0xc001, 0xc001).w(FUNC(msisaac_state::nmi_enable_w));
map(0xc002, 0xc002).w(FUNC(msisaac_state::nmi_disable_w));
- map(0xc003, 0xc003).nopw(); /*???*/ /* this is NOT mixer_enable */
- map(0xe000, 0xffff).nopr(); /*space for diagnostic ROM (not dumped, not reachable) */
+ map(0xc003, 0xc003).nopw(); // ???, this is NOT mixer_enable
+ map(0xe000, 0xffff).nopr(); // space for diagnostic ROM (not dumped, not reachable)
}
static INPUT_PORTS_START( msisaac )
@@ -409,13 +743,12 @@ GFXDECODE_END
void msisaac_state::machine_start()
{
- /* video */
+ // video
save_item(NAME(m_bg2_textbank));
- /* sound */
+ // sound
save_item(NAME(m_sound_nmi_enable));
save_item(NAME(m_pending_nmi));
- save_item(NAME(m_snd_ctrl0));
- save_item(NAME(m_snd_ctrl1));
+ save_item(NAME(m_snd_ctrl));
#ifdef USE_MCU
#else
@@ -426,15 +759,13 @@ void msisaac_state::machine_start()
void msisaac_state::machine_reset()
{
- //MACHINE_RESET_CALL_MEMBER(ta7630);
-
- /* video */
+ // video
m_bg2_textbank = 0;
- /* sound */
+ // sound
m_sound_nmi_enable = 0;
m_pending_nmi = 0;
- m_snd_ctrl0 = 0;
- m_snd_ctrl1 = 0;
+ m_snd_ctrl[0] = 0;
+ m_snd_ctrl[1] = 0;
#ifdef USE_MCU
m_mcu->set_input_line(0, CLEAR_LINE);
@@ -446,46 +777,46 @@ void msisaac_state::machine_reset()
void msisaac_state::msisaac(machine_config &config)
{
- /* basic machine hardware */
- Z80(config, m_maincpu, 4000000);
- m_maincpu->set_addrmap(AS_PROGRAM, &msisaac_state::msisaac_map);
+ // basic machine hardware
+ Z80(config, m_maincpu, 4'000'000);
+ m_maincpu->set_addrmap(AS_PROGRAM, &msisaac_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(msisaac_state::irq0_line_hold));
- Z80(config, m_audiocpu, 4000000);
- m_audiocpu->set_addrmap(AS_PROGRAM, &msisaac_state::msisaac_sound_map);
- m_audiocpu->set_vblank_int("screen", FUNC(msisaac_state::irq0_line_hold)); /* source of IRQs is unknown */
+ Z80(config, m_audiocpu, 4'000'000);
+ m_audiocpu->set_addrmap(AS_PROGRAM, &msisaac_state::sound_map);
+ m_audiocpu->set_vblank_int("screen", FUNC(msisaac_state::irq0_line_hold)); // source of IRQs is unknown
#ifdef USE_MCU
- M68705(config, "mcu", 8000000/2).set_addrmap(AS_PROGRAM, &msisaac_state::buggychl_mcu_map); /* 4 MHz */
+ M68705(config, "mcu", 8'000'000 / 2).set_addrmap(AS_PROGRAM, &msisaac_state::buggychl_mcu_map); // 4 MHz
BUGGYCHL_MCU(config, m_bmcu, 0);
#endif
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
- screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
+ screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
screen.set_size(32*8, 32*8);
screen.set_visarea(0, 32*8-1, 1*8, 31*8-1);
- screen.set_screen_update(FUNC(msisaac_state::screen_update_msisaac));
+ screen.set_screen_update(FUNC(msisaac_state::screen_update));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_msisaac);
PALETTE(config, m_palette).set_format(palette_device::xRGB_444, 1024);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "mono").front_center();
GENERIC_LATCH_8(config, m_soundlatch);
TA7630(config, m_ta7630);
- AY8910(config, "ay1", 2000000).add_route(ALL_OUTPUTS, "mono", 0.15);
+ AY8910(config, "ay1", 2'000'000).add_route(ALL_OUTPUTS, "mono", 0.15);
// port A/B likely to be TA7630 filters
- AY8910(config, "ay2", 2000000).add_route(ALL_OUTPUTS, "mono", 0.15);
+ AY8910(config, "ay2", 2'000'000).add_route(ALL_OUTPUTS, "mono", 0.15);
// port A/B likely to be TA7630 filters
- MSM5232(config, m_msm, 2000000);
- m_msm->set_capacitors(0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6); /* 0.65 (???) uF capacitors (match the sample, not verified) */
+ MSM5232(config, m_msm, 2'000'000);
+ m_msm->set_capacitors(0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6); // 0.65 (???) uF capacitors (match the sample, not verified)
m_msm->add_route(0, "mono", 1.0); // pin 28 2'-1
m_msm->add_route(1, "mono", 1.0); // pin 29 4'-1
m_msm->add_route(2, "mono", 1.0); // pin 30 8'-1
@@ -503,16 +834,16 @@ void msisaac_state::msisaac(machine_config &config)
/*******************************************************************************/
ROM_START( msisaac )
- ROM_REGION( 0x10000, "maincpu", 0 ) /* Z80 main CPU */
+ ROM_REGION( 0x10000, "maincpu", 0 ) // Z80
ROM_LOAD( "a34_11.bin", 0x0000, 0x4000, CRC(40819334) SHA1(65352607165043909a09e96c07f7060f6ce087e6) )
ROM_LOAD( "a34_12.bin", 0x4000, 0x4000, CRC(4c50b298) SHA1(5962882ad37ba6990ba2a6312b570f214cd4c103) )
ROM_LOAD( "a34_13.bin", 0x8000, 0x4000, CRC(2e2b09b3) SHA1(daa715282ed9ef2e519e252a684ef28085becabd) )
ROM_LOAD( "a34_10.bin", 0xc000, 0x2000, CRC(a2c53dc1) SHA1(14f23511f92bcfc94447dabe2826555d68bc1caa) )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 sound CPU */
+ ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80
ROM_LOAD( "a34_01.bin", 0x0000, 0x4000, CRC(545e45e7) SHA1(18ddb1ec8809bb62ae1c1068cd16cd3c933bf6ba) )
- ROM_REGION( 0x0800, "cpu2", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "mcu", 0 )
ROM_LOAD( "a34_14.mcu", 0x0000, 0x0800, NO_DUMP )
// I tried following MCUs; none of them work with this game:
@@ -534,5 +865,7 @@ ROM_START( msisaac )
ROM_LOAD( "a34_09.bin", 0x6000, 0x2000, CRC(23eb089d) SHA1(fcf48862825bf09ba3718cbade0e163a660e1a68) )
ROM_END
+} // anonymous namespace
+
-GAME( 1985, msisaac, 0, msisaac, msisaac, msisaac_state, empty_init, ROT270, "Taito Corporation", "Metal Soldier Isaac II", MACHINE_UNEMULATED_PROTECTION | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
+GAME( 1985, msisaac, 0, msisaac, msisaac, msisaac_state, empty_init, ROT270, "Taito Corporation", "Metal Soldier Isaac II", MACHINE_UNEMULATED_PROTECTION | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/taito/msisaac.h b/src/mame/taito/msisaac.h
deleted file mode 100644
index d65f9e843b1..00000000000
--- a/src/mame/taito/msisaac.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Jarek Burczynski
-#ifndef MAME_TAITO_MSISAAC_H
-#define MAME_TAITO_MSISAAC_H
-
-#pragma once
-
-#include "taito68705.h"
-
-#include "machine/gen_latch.h"
-#include "sound/msm5232.h"
-#include "sound/ta7630.h"
-
-#include "emupal.h"
-#include "tilemap.h"
-
-
-/* Disabled because the mcu dump is currently unavailable. -AS */
-//#define USE_MCU
-
-class msisaac_state : public driver_device
-{
-public:
- msisaac_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_spriteram(*this, "spriteram"),
- m_videoram(*this, "videoram"),
- m_videoram3(*this, "videoram3"),
- m_videoram2(*this, "videoram2"),
- m_audiocpu(*this, "audiocpu"),
- m_maincpu(*this, "maincpu"),
- m_bmcu(*this, "bmcu"),
- m_msm(*this, "msm"),
- m_ta7630(*this, "ta7630"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette"),
- m_soundlatch(*this, "soundlatch")
- { }
-
- void msisaac(machine_config &config);
-
-protected:
- virtual void machine_start() override;
- virtual void machine_reset() override;
- virtual void video_start() override;
-
-private:
- /* memory pointers */
- required_shared_ptr<uint8_t> m_spriteram;
- required_shared_ptr<uint8_t> m_videoram;
- required_shared_ptr<uint8_t> m_videoram3;
- required_shared_ptr<uint8_t> m_videoram2;
-
- /* video-related */
- bitmap_ind16 *m_tmp_bitmap1 = nullptr;
- bitmap_ind16 *m_tmp_bitmap2 = nullptr;
- tilemap_t *m_bg_tilemap = nullptr;
- tilemap_t *m_fg_tilemap = nullptr;
- tilemap_t *m_bg2_tilemap = nullptr;
- int m_bg2_textbank = 0;
-
- /* sound-related */
- int m_sound_nmi_enable = 0;
- int m_pending_nmi = 0;
-
- /* fake mcu (in msisaac.c) */
-#ifndef USE_MCU
- uint8_t m_mcu_val = 0;
- uint8_t m_direction = 0;
-#endif
-
- uint8_t m_snd_ctrl0 = 0;
- uint8_t m_snd_ctrl1 = 0;
- uint8_t m_snd_ctrl2 = 0;
- uint8_t m_snd_ctrl3 = 0;
-
- /* devices */
- required_device<cpu_device> m_audiocpu;
- required_device<cpu_device> m_maincpu;
- optional_device<taito68705_mcu_device> m_bmcu;
- required_device<msm5232_device> m_msm;
- required_device<ta7630_device> m_ta7630;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
- required_device<generic_latch_8_device> m_soundlatch;
-
- void sound_command_w(uint8_t data);
- void nmi_disable_w(uint8_t data);
- void nmi_enable_w(uint8_t data);
- void ms_unknown_w(uint8_t data);
- uint8_t msisaac_mcu_r(offs_t offset);
- uint8_t msisaac_mcu_status_r(offs_t offset);
- void msisaac_mcu_w(offs_t offset, uint8_t data);
- void sound_control_1_w(uint8_t data);
- void msisaac_fg_scrolly_w(uint8_t data);
- void msisaac_fg_scrollx_w(uint8_t data);
- void msisaac_bg2_scrolly_w(uint8_t data);
- void msisaac_bg2_scrollx_w(uint8_t data);
- void msisaac_bg_scrolly_w(uint8_t data);
- void msisaac_bg_scrollx_w(uint8_t data);
- void msisaac_bg2_textbank_w(uint8_t data);
- void msisaac_bg_videoram_w(offs_t offset, uint8_t data);
- void msisaac_bg2_videoram_w(offs_t offset, uint8_t data);
- void msisaac_fg_videoram_w(offs_t offset, uint8_t data);
- void sound_control_0_w(uint8_t data);
- TILE_GET_INFO_MEMBER(get_fg_tile_info);
- TILE_GET_INFO_MEMBER(get_bg_tile_info);
- TILE_GET_INFO_MEMBER(get_bg2_tile_info);
- uint32_t screen_update_msisaac(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- TIMER_CALLBACK_MEMBER(nmi_callback);
- void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
- void msisaac_map(address_map &map);
- void msisaac_sound_map(address_map &map);
-};
-
-#endif // MAME_TAITO_MSISAAC_H
diff --git a/src/mame/taito/msisaac_v.cpp b/src/mame/taito/msisaac_v.cpp
deleted file mode 100644
index a75a57a3789..00000000000
--- a/src/mame/taito/msisaac_v.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Jarek Burczynski
-/*
-* Video Driver for Metal Soldier Isaac II (1985)
-*/
-
-#include "emu.h"
-#include "msisaac.h"
-
-
-/***************************************************************************
-
- Callbacks for the TileMap code
-
-***************************************************************************/
-
-TILE_GET_INFO_MEMBER(msisaac_state::get_fg_tile_info)
-{
- int tile_number = m_videoram[tile_index];
- tileinfo.set(0,
- tile_number,
- 0x10,
- 0);
-}
-
-TILE_GET_INFO_MEMBER(msisaac_state::get_bg_tile_info)
-{
- int tile_number = m_videoram2[tile_index];
- tileinfo.set(1,
- 0x100 + tile_number,
- 0x30,
- 0);
-}
-
-TILE_GET_INFO_MEMBER(msisaac_state::get_bg2_tile_info)
-{
- int tile_number = m_videoram3[tile_index];
-
- /* graphics 0 or 1 */
- int gfx_b = (m_bg2_textbank >> 3) & 1;
-
- tileinfo.set(gfx_b,
- tile_number,
- 0x20,
- 0);
-}
-
-/***************************************************************************
-
- Start the video hardware emulation.
-
-***************************************************************************/
-
-void msisaac_state::video_start()
-{
- m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
- m_bg2_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_bg2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
- m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
-
- m_bg2_tilemap->set_transparent_pen(0);
- m_fg_tilemap->set_transparent_pen(0);
-}
-
-
-/***************************************************************************
-
- Memory handlers
-
-***************************************************************************/
-
-void msisaac_state::msisaac_fg_scrolly_w(uint8_t data)
-{
- m_fg_tilemap->set_scrolly(0, data);
-}
-
-void msisaac_state::msisaac_fg_scrollx_w(uint8_t data)
-{
- m_fg_tilemap->set_scrollx(0, 9 + data);
-}
-
-void msisaac_state::msisaac_bg2_scrolly_w(uint8_t data)
-{
- m_bg2_tilemap->set_scrolly(0, data);
-}
-
-void msisaac_state::msisaac_bg2_scrollx_w(uint8_t data)
-{
- m_bg2_tilemap->set_scrollx(0, 9 + 2 + data);
-}
-
-void msisaac_state::msisaac_bg_scrolly_w(uint8_t data)
-{
- m_bg_tilemap->set_scrolly(0, data);
-}
-
-void msisaac_state::msisaac_bg_scrollx_w(uint8_t data)
-{
- m_bg_tilemap->set_scrollx(0, 9 + 4 + data);
-}
-
-
-#ifdef UNUSED_FUNCTION
-void msisaac_state::msisaac_textbank1_w(uint8_t data)
-{
- if (textbank1!=data)
- {
- textbank1 = data;
- fg_tilemap->mark_all_dirty();
- }
-}
-#endif
-
-void msisaac_state::msisaac_bg2_textbank_w(uint8_t data)
-{
- if (m_bg2_textbank != data )
- {
- m_bg2_textbank = data;
- m_bg2_tilemap->mark_all_dirty();
-
- //check if we are correct on this one
- if ((data != 8) && (data != 0))
- {
- logerror("bg2 control=%2x\n", data);
- }
- }
-}
-
-void msisaac_state::msisaac_bg_videoram_w(offs_t offset, uint8_t data)
-{
- m_videoram2[offset] = data;
- m_bg_tilemap->mark_tile_dirty(offset);
-}
-
-void msisaac_state::msisaac_bg2_videoram_w(offs_t offset, uint8_t data)
-{
- m_videoram3[offset] = data;
- m_bg2_tilemap->mark_tile_dirty(offset);
-}
-
-void msisaac_state::msisaac_fg_videoram_w(offs_t offset, uint8_t data)
-{
- m_videoram[offset] = data;
- m_fg_tilemap->mark_tile_dirty(offset);
-}
-
-
-/***************************************************************************
-
- Display refresh
-
-***************************************************************************/
-void msisaac_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
-{
- const uint8_t *source = m_spriteram + 32 * 4 - 4;
- const uint8_t *finish = m_spriteram; /* ? */
-
- while (source >= finish)
- {
- int sx = source[0];
- int sy = 240 - source[1] - 1;
- int attributes = source[2];
- int sprite_number = source[3];
-
- int color = (attributes >> 4) & 0xf;
- int flipx = (attributes & 0x1);
- int flipy = (attributes & 0x2);
-
- gfx_element *gfx = m_gfxdecode->gfx(2);
-
- if (attributes & 4)
- {
- //color = machine().rand() & 15;
- gfx = m_gfxdecode->gfx(3);
- }
-
- if (attributes & 8) /* double size sprite */
- {
- switch (attributes & 3)
- {
- case 0: /* flipx==0 && flipy==0 */
- gfx->transpen(bitmap,cliprect,
- sprite_number+1,color,
- flipx,flipy,
- sx,sy-16,0 );
- gfx->transpen(bitmap,cliprect,
- sprite_number,color,
- flipx,flipy,
- sx,sy,0 );
- break;
- case 1: /* flipx==1 && flipy==0 */
- gfx->transpen(bitmap,cliprect,
- sprite_number+1,color,
- flipx,flipy,
- sx,sy-16,0 );
- gfx->transpen(bitmap,cliprect,
- sprite_number,color,
- flipx,flipy,
- sx,sy,0 );
- break;
- case 2: /* flipx==0 && flipy==1 */
- gfx->transpen(bitmap,cliprect,
- sprite_number,color,
- flipx,flipy,
- sx,sy-16,0 );
- gfx->transpen(bitmap,cliprect,
- sprite_number+1,color,
- flipx,flipy,
- sx,sy,0 );
- break;
- case 3: /* flipx==1 && flipy==1 */
- gfx->transpen(bitmap,cliprect,
- sprite_number,color,
- flipx,flipy,
- sx,sy-16,0 );
- gfx->transpen(bitmap,cliprect,
- sprite_number+1,color,
- flipx,flipy,
- sx,sy,0 );
- break;
- }
- }
- else
- {
- gfx->transpen(bitmap,cliprect,
- sprite_number,
- color,
- flipx,flipy,
- sx,sy,0 );
- }
- source -= 4;
- }
-}
-
-uint32_t msisaac_state::screen_update_msisaac(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
- m_bg2_tilemap->draw(screen, bitmap, cliprect, 0, 0);
- draw_sprites(bitmap, cliprect);
- m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
- return 0;
-}