rev |
line source |
nuclear@0
|
1 #ifndef VDP_H_
|
nuclear@0
|
2 #define VDP_H_
|
nuclear@0
|
3
|
nuclear@0
|
4 #include <stdint.h>
|
nuclear@0
|
5
|
nuclear@0
|
6 #define VDP_PORT_DATA *((volatile uint16_t*)0xc00000)
|
nuclear@0
|
7 #define VDP_PORT_DATA32 *((volatile uint32_t*)0xc00000)
|
nuclear@0
|
8 #define VDP_PORT_CTL *((volatile uint16_t*)0xc00004)
|
nuclear@0
|
9 #define VDP_PORT_CTL32 *((volatile uint32_t*)0xc00004)
|
nuclear@0
|
10 #define VDP_PORT_HVCNT *((volatile uint16_t*)0xc00008)
|
nuclear@0
|
11 #define VDP_PORT_PSG *((volatile uint16_t*)0xc00010)
|
nuclear@0
|
12
|
nuclear@0
|
13 #define VDP_PORT_STATUS *((volatile uint16_t*)0xc00004)
|
nuclear@0
|
14
|
nuclear@0
|
15 enum {
|
nuclear@0
|
16 VDP_REG_MODE1 = 0,
|
nuclear@0
|
17 VDP_REG_MODE2 = 1,
|
nuclear@0
|
18 VDP_REG_NAMETAB_A = 2,
|
nuclear@0
|
19 VDP_REG_NAMETAB_WIN = 3,
|
nuclear@0
|
20 VDP_REG_NAMETAB_B = 4,
|
nuclear@0
|
21 VDP_REG_SPRITE_TAB = 5,
|
nuclear@0
|
22 VDP_REG_BGCOL = 7,
|
nuclear@1
|
23 VDP_REG_HINTR = 10,
|
nuclear@0
|
24 VDP_REG_MODE3 = 11,
|
nuclear@0
|
25 VDP_REG_MODE4 = 12,
|
nuclear@0
|
26 VDP_REG_SCROLL_TAB = 13,
|
nuclear@0
|
27 VDP_REG_AUTOINC = 15,
|
nuclear@0
|
28 VDP_REG_SCROLL_SIZE = 16,
|
nuclear@0
|
29 VDP_REG_WIN_XPOS = 17,
|
nuclear@0
|
30 VDP_REG_WIN_YPOS = 18,
|
nuclear@0
|
31 VDP_REG_DMA_LEN_LOW = 19,
|
nuclear@0
|
32 VDP_REG_DMA_LEN_HIGH = 20,
|
nuclear@0
|
33 VDP_REG_DMA_SRC_LOW = 21,
|
nuclear@0
|
34 VDP_REG_DMA_SRC_MID = 22,
|
nuclear@0
|
35 VDP_REG_DMA_SRC_HIGH = 23,
|
nuclear@0
|
36
|
nuclear@0
|
37 VDP_NUM_REGS
|
nuclear@0
|
38 };
|
nuclear@0
|
39
|
nuclear@0
|
40 uint16_t vdp_reg_shadow[VDP_NUM_REGS];
|
nuclear@0
|
41
|
nuclear@0
|
42 /* access VDP memory */
|
nuclear@0
|
43 enum { VDP_MEM_READ, VDP_MEM_WRITE };
|
nuclear@0
|
44 enum {
|
nuclear@0
|
45 VDP_MEM_VRAM = 0,
|
nuclear@0
|
46 VDP_MEM_CRAM = 0xa, /* CD5->CD0: 0 0 r 0 w 0 */
|
nuclear@0
|
47 VDP_MEM_VSRAM = 4 /* CD5->CD0: 0 0 0 1 0 0 */
|
nuclear@0
|
48 };
|
nuclear@0
|
49
|
nuclear@4
|
50 enum {
|
nuclear@4
|
51 VDP_PLANE_A,
|
nuclear@4
|
52 VDP_PLANE_B,
|
nuclear@4
|
53 VDP_PLANE_WIN
|
nuclear@4
|
54 };
|
nuclear@4
|
55
|
nuclear@4
|
56 enum {
|
nuclear@4
|
57 VDP_TILE_LOW_PRIO = 0,
|
nuclear@4
|
58 VDP_TILE_HFLIP = 0x0800,
|
nuclear@4
|
59 VDP_TILE_VFLIP = 0x1000,
|
nuclear@4
|
60 VDP_TILE_HIGH_PRIO = 0x8000
|
nuclear@4
|
61 };
|
nuclear@4
|
62
|
nuclear@9
|
63 enum {
|
nuclear@9
|
64 VDP_STAT_PAL = 0x0001,
|
nuclear@9
|
65 VDP_STAT_DMABUSY = 0x0002,
|
nuclear@9
|
66 VDP_STAT_HBLANK = 0x0004,
|
nuclear@9
|
67 VDP_STAT_VBLANK = 0x0008,
|
nuclear@9
|
68 VDP_STAT_ODDFIELD = 0x0010,
|
nuclear@9
|
69 VDP_STAT_SPRITE_COL = 0x0020,
|
nuclear@9
|
70 VDP_STAT_SPRITE_OVF = 0x0040,
|
nuclear@9
|
71 VDP_STAT_VINTR = 0x0080,
|
nuclear@9
|
72 VDP_STAT_FIFO_FULL = 0x0100,
|
nuclear@9
|
73 VDP_STAT_FIFO_EMPTY = 0x0200
|
nuclear@9
|
74 };
|
nuclear@9
|
75
|
nuclear@9
|
76
|
nuclear@0
|
77 static inline void vdp_setup_access(uint16_t addr, int rw, int memid)
|
nuclear@0
|
78 {
|
nuclear@0
|
79 uint32_t type;
|
nuclear@0
|
80 if(rw == VDP_MEM_WRITE) {
|
nuclear@0
|
81 type = (memid & 7) | 1;
|
nuclear@0
|
82 } else {
|
nuclear@0
|
83 type = memid & 0xc;
|
nuclear@0
|
84 }
|
nuclear@0
|
85
|
nuclear@0
|
86 VDP_PORT_CTL32 = (((uint32_t)addr & 0x3fff) << 16) | ((addr >> 14) & 3) |
|
nuclear@0
|
87 ((type << 2) & 0xf0) | (type << 30);
|
nuclear@0
|
88 }
|
nuclear@0
|
89
|
nuclear@0
|
90
|
nuclear@0
|
91 /* mode register 1 */
|
nuclear@0
|
92 enum {
|
nuclear@0
|
93 VDP_MODE1_BASE = 0x4,
|
nuclear@0
|
94 VDP_MODE1_HVCNT = 0x2,
|
nuclear@0
|
95 VDP_MODE1_HINTR = 0x10
|
nuclear@0
|
96 };
|
nuclear@0
|
97
|
nuclear@0
|
98 /* mode register 2 */
|
nuclear@0
|
99 enum {
|
nuclear@0
|
100 VDP_MODE2_BASE = 0x4,
|
nuclear@0
|
101 VDP_MODE2_V30CELL = 0x8,
|
nuclear@0
|
102 VDP_MODE2_DMA = 0x10,
|
nuclear@0
|
103 VDP_MODE2_VINTR = 0x20,
|
nuclear@0
|
104 VDP_MODE2_DISP = 0x40
|
nuclear@0
|
105 };
|
nuclear@0
|
106
|
nuclear@0
|
107 /* mode register 3 */
|
nuclear@0
|
108 enum {
|
nuclear@0
|
109 VDP_MODE3_BASE = 0,
|
nuclear@0
|
110 VDP_MODE3_HSCROLL_CELL = 2,
|
nuclear@0
|
111 VDP_MODE3_HSCROLL_LINE = 3,
|
nuclear@0
|
112 VDP_MODE3_VSCROLL_2CELL = 4,
|
nuclear@0
|
113 VDP_MODE3_EXTINTR = 8
|
nuclear@0
|
114 };
|
nuclear@0
|
115
|
nuclear@0
|
116 /* mode register 4 */
|
nuclear@0
|
117 enum {
|
nuclear@0
|
118 VDP_MODE4_BASE = 0,
|
nuclear@0
|
119 VDP_MODE4_H40CELL = 0x81,
|
nuclear@0
|
120 VDP_MODE4_ILACE = 2,
|
nuclear@0
|
121 VDP_MODE4_ILACE_2XRES = 6,
|
nuclear@0
|
122 VDP_MODE4_SH = 8 /* shadow/highlight enable */
|
nuclear@0
|
123 };
|
nuclear@0
|
124
|
nuclear@0
|
125 /* scroll size register */
|
nuclear@0
|
126 enum {
|
nuclear@0
|
127 VDP_SCROLL_H32 = 0,
|
nuclear@0
|
128 VDP_SCROLL_H64 = 1,
|
nuclear@0
|
129 VDP_SCROLL_H128 = 3,
|
nuclear@0
|
130 VDP_SCROLL_V32 = 0,
|
nuclear@0
|
131 VDP_SCROLL_V64 = 0x10,
|
nuclear@0
|
132 VDP_SCROLL_V128 = 0x30
|
nuclear@0
|
133 };
|
nuclear@0
|
134
|
nuclear@0
|
135 /* window X/Y position register */
|
nuclear@0
|
136 enum {
|
nuclear@0
|
137 VDP_WIN_LEFT = 0,
|
nuclear@0
|
138 VDP_WIN_UP = 0,
|
nuclear@0
|
139 VDP_WIN_RIGHT = 0x80,
|
nuclear@0
|
140 VDP_WIN_DOWN = 0x80,
|
nuclear@0
|
141 VDP_WIN_POSMASK = 0x1f
|
nuclear@0
|
142 };
|
nuclear@0
|
143
|
nuclear@0
|
144 #define VDP_PACK_RGB(r, g, b) \
|
nuclear@0
|
145 ((((uint16_t)(r) & 7) << 1) | (((uint16_t)(g) & 7) << 5) | (((uint16_t)(b) & 7) << 9))
|
nuclear@0
|
146
|
nuclear@0
|
147
|
nuclear@0
|
148 static inline void vdp_setreg(int reg, uint8_t value)
|
nuclear@0
|
149 {
|
nuclear@1
|
150 vdp_reg_shadow[reg] = value;
|
nuclear@0
|
151 VDP_PORT_CTL = (uint16_t)value | (reg << 8) | (uint16_t)0x8000;
|
nuclear@0
|
152 }
|
nuclear@0
|
153
|
nuclear@0
|
154 static inline uint16_t vdp_getreg(int reg)
|
nuclear@0
|
155 {
|
nuclear@0
|
156 return vdp_reg_shadow[reg];
|
nuclear@0
|
157 }
|
nuclear@0
|
158
|
nuclear@0
|
159 static inline uint16_t vdp_status(void)
|
nuclear@0
|
160 {
|
nuclear@0
|
161 return VDP_PORT_CTL;
|
nuclear@0
|
162 }
|
nuclear@0
|
163
|
nuclear@0
|
164 static inline void vdp_set_bgcolor(int palidx, int colidx)
|
nuclear@0
|
165 {
|
nuclear@0
|
166 vdp_setreg(VDP_REG_BGCOL, (colidx & 0xf) | (palidx << 4));
|
nuclear@0
|
167 }
|
nuclear@0
|
168
|
nuclear@0
|
169 static inline void vdp_set_autoinc(int stride)
|
nuclear@0
|
170 {
|
nuclear@0
|
171 vdp_setreg(VDP_REG_AUTOINC, stride);
|
nuclear@0
|
172 }
|
nuclear@0
|
173
|
nuclear@5
|
174 static inline void vdp_begin_palette(int pidx, int cidx)
|
nuclear@5
|
175 {
|
nuclear@5
|
176 uint16_t paddr = (pidx << 5) | (cidx << 1);
|
nuclear@5
|
177 vdp_setup_access(paddr, VDP_MEM_WRITE, VDP_MEM_CRAM);
|
nuclear@5
|
178 }
|
nuclear@5
|
179
|
nuclear@0
|
180 static inline void vdp_set_pal_entry(int pidx, int cidx, int r, int g, int b)
|
nuclear@0
|
181 {
|
nuclear@5
|
182 vdp_begin_palette(pidx, cidx);
|
nuclear@0
|
183 VDP_PORT_DATA = VDP_PACK_RGB(r, g, b);
|
nuclear@0
|
184 }
|
nuclear@0
|
185
|
nuclear@1
|
186 static inline void vdp_enable_vintr(void)
|
nuclear@1
|
187 {
|
nuclear@1
|
188 vdp_setreg(VDP_REG_MODE2, vdp_getreg(VDP_REG_MODE2) | VDP_MODE2_VINTR);
|
nuclear@1
|
189 }
|
nuclear@1
|
190
|
nuclear@1
|
191 static inline void vdp_disable_vintr(void)
|
nuclear@1
|
192 {
|
nuclear@1
|
193 vdp_setreg(VDP_REG_MODE2, vdp_getreg(VDP_REG_MODE2) & ~VDP_MODE2_VINTR);
|
nuclear@1
|
194 }
|
nuclear@1
|
195
|
nuclear@1
|
196 static inline void vdp_enable_hintr(int counter)
|
nuclear@1
|
197 {
|
nuclear@1
|
198 vdp_setreg(VDP_REG_HINTR, counter);
|
nuclear@1
|
199 vdp_setreg(VDP_REG_MODE1, vdp_getreg(VDP_REG_MODE1) | VDP_MODE1_HINTR);
|
nuclear@1
|
200 }
|
nuclear@1
|
201
|
nuclear@1
|
202 static inline void vdp_disable_hintr(void)
|
nuclear@1
|
203 {
|
nuclear@1
|
204 vdp_setreg(VDP_REG_MODE1, vdp_getreg(VDP_REG_MODE1) & ~VDP_MODE1_HINTR);
|
nuclear@1
|
205 }
|
nuclear@1
|
206
|
nuclear@4
|
207 static inline void vdp_set_nametab_addr(int plane, uint16_t addr)
|
nuclear@4
|
208 {
|
nuclear@4
|
209 switch(plane) {
|
nuclear@4
|
210 case VDP_PLANE_A:
|
nuclear@5
|
211 vdp_setreg(VDP_REG_NAMETAB_A, (addr >> 10) & 0x38);
|
nuclear@4
|
212 break;
|
nuclear@4
|
213 case VDP_PLANE_B:
|
nuclear@5
|
214 vdp_setreg(VDP_REG_NAMETAB_B, (addr >> 13) & 7);
|
nuclear@4
|
215 break;
|
nuclear@4
|
216 case VDP_PLANE_WIN:
|
nuclear@5
|
217 vdp_setreg(VDP_REG_NAMETAB_WIN, (addr >> 10) & 0x7e);
|
nuclear@5
|
218 default:
|
nuclear@4
|
219 break;
|
nuclear@4
|
220 }
|
nuclear@4
|
221 }
|
nuclear@4
|
222
|
nuclear@4
|
223 static inline uint16_t vdp_nametab_addr(int idx)
|
nuclear@4
|
224 {
|
nuclear@4
|
225 return (uint16_t)idx << 13;
|
nuclear@4
|
226 }
|
nuclear@4
|
227
|
nuclear@4
|
228 static inline void vdp_set_nametab_idx(int plane, int idx)
|
nuclear@4
|
229 {
|
nuclear@4
|
230 vdp_set_nametab_addr(plane, vdp_nametab_addr(idx));
|
nuclear@4
|
231 }
|
nuclear@4
|
232
|
nuclear@5
|
233 static inline void vdp_disable_layer(int plane)
|
nuclear@5
|
234 {
|
nuclear@5
|
235 switch(plane) {
|
nuclear@5
|
236 case VDP_PLANE_A:
|
nuclear@5
|
237 vdp_setreg(VDP_REG_NAMETAB_A, 0x40);
|
nuclear@5
|
238 break;
|
nuclear@5
|
239 case VDP_PLANE_B:
|
nuclear@5
|
240 vdp_setreg(VDP_REG_NAMETAB_B, 0x08);
|
nuclear@5
|
241 break;
|
nuclear@5
|
242 case VDP_PLANE_WIN:
|
nuclear@5
|
243 vdp_setreg(VDP_REG_NAMETAB_WIN, 0x40);
|
nuclear@5
|
244 default:
|
nuclear@5
|
245 break;
|
nuclear@5
|
246 }
|
nuclear@5
|
247 }
|
nuclear@5
|
248
|
nuclear@4
|
249 static inline uint16_t vdp_nametab_entry(int tileidx, int palidx, uint16_t flags)
|
nuclear@4
|
250 {
|
nuclear@4
|
251 return tileidx | (((uint16_t)palidx & 0x3) << 13) | flags;
|
nuclear@4
|
252 }
|
nuclear@4
|
253
|
nuclear@5
|
254 static inline void vdp_set_sprite_table(uint16_t addr)
|
nuclear@5
|
255 {
|
nuclear@5
|
256 vdp_setreg(VDP_REG_SPRITE_TAB, addr >> 9);
|
nuclear@5
|
257 }
|
nuclear@5
|
258
|
nuclear@5
|
259 static inline void vdp_set_scroll_table(uint16_t addr)
|
nuclear@5
|
260 {
|
nuclear@5
|
261 vdp_setreg(VDP_REG_SCROLL_TAB, addr >> 10);
|
nuclear@5
|
262 }
|
nuclear@5
|
263
|
nuclear@9
|
264 static inline void vdp_wait_vblank_start(void)
|
nuclear@9
|
265 {
|
nuclear@9
|
266 while(!(VDP_PORT_STATUS & VDP_STAT_VBLANK));
|
nuclear@9
|
267 }
|
nuclear@9
|
268
|
nuclear@9
|
269 static inline void vdp_wait_vblank_end(void)
|
nuclear@9
|
270 {
|
nuclear@9
|
271 while(VDP_PORT_STATUS & VDP_STAT_VBLANK);
|
nuclear@9
|
272 }
|
nuclear@9
|
273
|
nuclear@8
|
274 static inline void vdp_wait_vblank(void)
|
nuclear@8
|
275 {
|
nuclear@9
|
276 vdp_wait_vblank_start();
|
nuclear@9
|
277 vdp_wait_vblank_end();
|
nuclear@8
|
278 }
|
nuclear@8
|
279
|
nuclear@0
|
280 void vdp_init(void);
|
nuclear@0
|
281
|
nuclear@0
|
282 #endif /* VDP_H_ */
|