mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
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.
This commit is contained in:
parent
380fb5d313
commit
4be4bb12e9
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user