diff options
author | couriersud <couriersud@gmx.org> | 2019-05-12 14:07:43 +0200 |
---|---|---|
committer | couriersud <couriersud@gmx.org> | 2019-05-12 14:08:15 +0200 |
commit | 4be4bb12e983c6e4effba4e8c5e462fae2c59581 (patch) | |
tree | f45d4fff724593f8db86882864c16aa9086c2cb2 | |
parent | 380fb5d3135e82e02dc6d921cd664a4fcf3a4e05 (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.h | 2 | ||||
-rw-r--r-- | src/mame/video/galaga.cpp | 100 |
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(); } |