libsidplayfp  1.8.3
sprites.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
5  * Copyright 2009-2014 VICE Project
6  * Copyright 2007-2010 Antti Lankila
7  * Copyright 2001 Simon White
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23 
24 #ifndef SPRITES_H
25 #define SPRITES_H
26 
27 #include <stdint.h>
28 
29 #include <cstring>
30 
31 #define SPRITES 8
32 
33 class Sprites
34 {
35 private:
36  const uint8_t &enable, &y_expansion;
37 
38  uint8_t exp_flop;
39  uint8_t dma;
40  uint8_t mc_base[SPRITES];
41  uint8_t mc[SPRITES];
42 
43 public:
44  Sprites(uint8_t regs[0x40]) :
45  enable(regs[0x15]),
46  y_expansion(regs[0x17]) {}
47 
48  void reset()
49  {
50  exp_flop = 0xff;
51  dma = 0;
52 
53  memset(mc_base, 0, sizeof(mc_base));
54  memset(mc, 0, sizeof(mc));
55  }
56 
61  void updateMc()
62  {
63  uint8_t mask = 1;
64  for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1)
65  {
66  if (dma & mask)
67  mc[i] = (mc[i] + 3) & 0x3f;
68  }
69  }
70 
74  void updateMcBase()
75  {
76  uint8_t mask = 1;
77  for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1)
78  {
79  if (exp_flop & mask)
80  {
81  mc_base[i] = mc[i];
82  if (mc_base[i] == 0x3f)
83  dma &= ~mask;
84  }
85  }
86  }
87 
91  void checkExp()
92  {
93  exp_flop ^= dma & y_expansion;
94  }
95 
99  void checkDisplay()
100  {
101  for (unsigned int i = 0; i < SPRITES; i++)
102  {
103  mc[i] = mc_base[i];
104  }
105  }
106 
110  void checkDma(unsigned int rasterY, uint8_t regs[0x40])
111  {
112  const uint8_t y = rasterY & 0xff;
113  uint8_t mask = 1;
114  for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1)
115  {
116  if ((enable & mask) && (y == regs[(i << 1) + 1]) && !(dma & mask))
117  {
118  dma |= mask;
119  mc_base[i] = 0;
120  exp_flop |= mask;
121  }
122  }
123  }
124 
131  void lineCrunch(uint8_t data, unsigned int lineCycle)
132  {
133  uint8_t mask = 1;
134  for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1)
135  {
136  if (!(data & mask) && !(exp_flop & mask))
137  {
138  // sprite crunch
139  if (lineCycle == 14)
140  {
141  const uint8_t mc_i = mc[i];
142  const uint8_t mcBase_i = mc_base[i];
143 
144  mc[i] = (0x2a & (mcBase_i & mc_i)) | (0x15 & (mcBase_i | mc_i));
145 
146  // mcbase will be set from mc on the following clock call
147  }
148 
149  exp_flop |= mask;
150  }
151  }
152  }
153 
159  bool isDma(unsigned int val) const
160  {
161  return dma & val;
162  }
163 };
164 
165 #endif
bool isDma(unsigned int val) const
Definition: sprites.h:159
void checkDma(unsigned int rasterY, uint8_t regs[0x40])
Definition: sprites.h:110
Definition: sprites.h:33
void checkDisplay()
Definition: sprites.h:99
void lineCrunch(uint8_t data, unsigned int lineCycle)
Definition: sprites.h:131
void checkExp()
Definition: sprites.h:91
void updateMc()
Definition: sprites.h:61
void updateMcBase()
Definition: sprites.h:74