libsidplayfp 2.15.0
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 <algorithm>
30#include <iterator>
31
32namespace libsidplayfp
33{
34
39{
40private:
41 static constexpr unsigned int SPRITES = 8;
42
43 const uint8_t &enable, &y_expansion;
44
45 uint8_t exp_flop;
46 uint8_t dma;
47 uint8_t mc_base[SPRITES];
48 uint8_t mc[SPRITES];
49
50public:
51 Sprites(uint8_t regs[0x40]) :
52 enable(regs[0x15]),
53 y_expansion(regs[0x17]) {}
54
55 void reset()
56 {
57 exp_flop = 0xff;
58 dma = 0;
59
60 std::fill(std::begin(mc_base), std::end(mc_base), 0);
61 std::fill(std::begin(mc), std::end(mc), 0);
62 }
63
68 void updateMc()
69 {
70 uint8_t mask = 1;
71 for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1)
72 {
73 if (dma & mask)
74 mc[i] = (mc[i] + 3) & 0x3f;
75 }
76 }
77
82 {
83 uint8_t mask = 1;
84 for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1)
85 {
86 if (exp_flop & mask)
87 {
88 mc_base[i] = mc[i];
89 if (mc_base[i] == 0x3f)
90 dma &= ~mask;
91 }
92 }
93 }
94
98 void checkExp()
99 {
100 exp_flop ^= dma & y_expansion;
101 }
102
107 {
108 for (unsigned int i = 0; i < SPRITES; i++)
109 {
110 mc[i] = mc_base[i];
111 }
112 }
113
120 void checkDma(unsigned int rasterY, uint8_t regs[0x40])
121 {
122 const uint8_t y = rasterY & 0xff;
123 uint8_t mask = 1;
124 for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1)
125 {
126 if ((enable & mask) && (y == regs[(i << 1) + 1]) && !(dma & mask))
127 {
128 dma |= mask;
129 mc_base[i] = 0;
130 exp_flop |= mask;
131 }
132 }
133 }
134
141 void lineCrunch(uint8_t data, unsigned int lineCycle)
142 {
143 uint8_t mask = 1;
144 for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1)
145 {
146 if (!(data & mask) && !(exp_flop & mask))
147 {
148 // sprite crunch
149 if (lineCycle == 14)
150 {
151 const uint8_t mc_i = mc[i];
152 const uint8_t mcBase_i = mc_base[i];
153
154 mc[i] = (0x2a & (mcBase_i & mc_i)) | (0x15 & (mcBase_i | mc_i));
155
156 // mcbase will be set from mc on the following clock call
157 }
158
159 exp_flop |= mask;
160 }
161 }
162 }
163
169 inline bool isDma(unsigned int val) const
170 {
171 return dma & val;
172 }
173};
174
175}
176
177#endif
Definition sprites.h:39
void checkExp()
Definition sprites.h:98
void checkDisplay()
Definition sprites.h:106
void updateMcBase()
Definition sprites.h:81
void checkDma(unsigned int rasterY, uint8_t regs[0x40])
Definition sprites.h:120
void updateMc()
Definition sprites.h:68
bool isDma(unsigned int val) const
Definition sprites.h:169
void lineCrunch(uint8_t data, unsigned int lineCycle)
Definition sprites.h:141