summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2019-05-12 14:07:43 +0200
committer couriersud <couriersud@gmx.org>2019-05-12 14:08:15 +0200
commit4be4bb12e983c6e4effba4e8c5e462fae2c59581 (patch)
treef45d4fff724593f8db86882864c16aa9086c2cb2
parent380fb5d3135e82e02dc6d921cd664a4fcf3a4e05 (diff)
galaga: Manually apply pull request #3532: star field lfsr
implementation Manually applied the lfsr part of #3532 and verifying against static star field. Also added documentation and my findings about the known star field decoding algorithms.
-rw-r--r--src/mame/includes/galaga.h2
-rw-r--r--src/mame/video/galaga.cpp100
2 files changed, 102 insertions, 0 deletions
diff --git a/src/mame/includes/galaga.h b/src/mame/includes/galaga.h
index edc973034df..2a8b3faa780 100644
--- a/src/mame/includes/galaga.h
+++ b/src/mame/includes/galaga.h
@@ -63,6 +63,8 @@ public:
void galaga_mem4(address_map &map);
void gatsbee_main_map(address_map &map);
+ void starfield_init();
+
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
diff --git a/src/mame/video/galaga.cpp b/src/mame/video/galaga.cpp
index e7ed005f62f..58ae9e4533d 100644
--- a/src/mame/video/galaga.cpp
+++ b/src/mame/video/galaga.cpp
@@ -11,6 +11,12 @@
#include "emu.h"
#include "includes/galaga.h"
+#define LOG_DEBUG (1 << 0U)
+#define LOG_ALL (LOG_DEBUG)
+
+#define VERBOSE (LOG_ALL)
+
+#include "logmacro.h"
#define MAX_STARS 252
#define STARS_COLOR_BASE (64*4+64*4)
@@ -376,7 +382,99 @@ void galaga_state::galaga_palette(palette_device &palette) const
palette.set_pen_indirect(64*4 + 64*4 + i, 32 + i);
}
+/***************************************************************************
+
+ Star field documentation
+
+ Couriersud, May 2019:
+
+ The code below was manually applied based on a pull request from
+ Jindřich Makovička. He based his work on information published by
+ Wolfgang Scherr about the 05XX on pin4.at.
+
+ Wolfgang shared is VHDL implementation with the MAME team. I have
+ created a spreadsheet implementation for his decode logic.
+
+ Both implementations use the same Galois type LFSR( tap 15,12,10,5).
+ Using the same seed value, the following holds true:
+
+ Decode_W(lfsr[t-4]) = Decode_J(lfsr[t])
+
+ The two decoding algorithm (Wolfgang, Jindřich) thus deliver the same
+ results but with a 4 clock difference.
+
+ Jindřich's code filters out stars with y<4. This matches the starfield
+ measurements documented above. Wolfgang states that his code matches his
+ measurements and there are stars with y<4.
+ We need to have a closer look at this.
+
+ Both implementations are complex compared to other star field gnerators
+ used in the industry. We thus now have two decoding solutions matching
+ the output. I wonder if there is a simpler one.
+
+***************************************************************************/
+
+void galaga_state::starfield_init()
+{
+ const uint16_t feed = 0x9420;
+ int idx = 0;
+ for (uint16_t sf = 0; sf < 4; ++sf)
+ {
+ // starfield select flags
+ uint16_t sf1 = (sf >> 1) & 1;
+ uint16_t sf2 = sf & 1;
+
+ uint16_t i = 0x70cc;
+ for (int cnt = 0; cnt < 65535; ++cnt)
+ {
+ // output enable lookup
+ uint16_t xor1 = i ^ (i >> 3);
+ uint16_t xor2 = xor1 ^ (i >> 2);
+ uint16_t oe = (sf1 ? 0 : 0x4000) | ((sf1 ^ sf2) ? 0 : 0x1000);
+ if ((i & 0x8007) == 0x8007
+ && (~i & 0x2008) == 0x2008
+ && (xor1 & 0x0100) == (sf1 ? 0 : 0x0100)
+ && (xor2 & 0x0040) == (sf2 ? 0 : 0x0040)
+ && (i & 0x5000) == oe
+ && cnt >= 256 * 4)
+ {
+ // color lookup
+ uint16_t xor3 = (i >> 1) ^ (i >> 6);
+ uint16_t clr =
+ (((i >> 9) & 0x07)
+ | ((xor3 ^ (i >> 4) ^ (i >> 7)) & 0x08)
+ | (~xor3 & 0x10)
+ | (((i >> 2) ^ (i >> 5)) & 0x20))
+ ^ ((i & 0x4000) ? 0 : 0x24)
+ ^ ((((i >> 2) ^ i) & 0x1000) ? 0x21 : 0);
+#if 0
+ m_star_seed_tab[idx].x = cnt % 256;
+ m_star_seed_tab[idx].y = cnt / 256;
+ m_star_seed_tab[idx].col = clr;
+ m_star_seed_tab[idx].set = sf;
+#else
+ int x = cnt % 256;
+ int y = cnt / 256;
+ int col = clr;
+ int set = sf;
+
+ if ((x != s_star_seed_tab[idx].x) || (y != s_star_seed_tab[idx].y)
+ || (col != s_star_seed_tab[idx].col) || (s_star_seed_tab[idx].set != set))
+ LOGMASKED(LOG_DEBUG, "Mismatch: %d %d %d %d %d %d %d %d\n", x, y, col, set, s_star_seed_tab[idx].x,
+ s_star_seed_tab[idx].y, s_star_seed_tab[idx].col, s_star_seed_tab[idx].set);
+#endif
+ ++idx;
+ }
+
+ // update the LFSR
+ if (i & 1)
+ i = (i >> 1) ^ feed;
+ else
+ i = (i >> 1);
+ }
+ }
+}
/***************************************************************************
@@ -433,6 +531,8 @@ VIDEO_START_MEMBER(galaga_state,galaga)
save_item(NAME(m_stars_scrollx));
save_item(NAME(m_stars_scrolly));
save_item(NAME(m_galaga_gfxbank));
+
+ starfield_init();
}