-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathvdp.h
199 lines (163 loc) · 4.91 KB
/
vdp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#ifndef VDP_H
#define VDP_H
#include <stddef.h>
#include "clowncommon/clowncommon.h"
#ifdef __cplusplus
extern "C" {
#endif
#define VDP_MAX_SCANLINE_WIDTH 320
#define VDP_MAX_SCANLINES (240 * 2) /* V30 in interlace mode 2 */
typedef struct VDP_Configuration
{
cc_bool sprites_disabled;
cc_bool window_disabled;
cc_bool planes_disabled[2];
} VDP_Configuration;
typedef struct VDP_Constant
{
cc_u8l blit_lookup[1 << (1 + 2)][1 << (1 + 1 + 2 + 4)][1 << 4];
cc_u8l blit_lookup_shadow_highlight[1 << (1 + 2)][1 << (1 + 1 + 2 + 4)][1 << 4];
} VDP_Constant;
typedef enum VDP_Access
{
VDP_ACCESS_VRAM,
VDP_ACCESS_CRAM,
VDP_ACCESS_VSRAM,
VDP_ACCESS_VRAM_8BIT,
VDP_ACCESS_INVALID
} VDP_Access;
typedef enum VDP_DMAMode
{
VDP_DMA_MODE_MEMORY_TO_VRAM, /* TODO: This isn't limited to VRAM. */
VDP_DMA_MODE_FILL,
VDP_DMA_MODE_COPY
} VDP_DMAMode;
typedef enum VDP_HScrollMode
{
VDP_HSCROLL_MODE_FULL,
VDP_HSCROLL_MODE_1CELL,
VDP_HSCROLL_MODE_1LINE
} VDP_HScrollMode;
typedef enum VDP_VScrollMode
{
VDP_VSCROLL_MODE_FULL,
VDP_VSCROLL_MODE_2CELL
} VDP_VScrollMode;
typedef struct VDP_TileMetadata
{
cc_u16f tile_index;
cc_u8f palette_line;
cc_bool x_flip;
cc_bool y_flip;
cc_bool priority;
} VDP_TileMetadata;
typedef struct VDP_CachedSprite
{
cc_u16f y;
cc_u8f width;
cc_u8f height;
cc_u8f link;
} VDP_CachedSprite;
typedef struct VDP_SpriteRowCacheEntry
{
cc_u8l table_index;
cc_u8l y_in_sprite;
cc_u8l width;
cc_u8l height;
} VDP_SpriteRowCacheEntry;
typedef struct VDP_SpriteRowCacheRow
{
cc_u8l total;
VDP_SpriteRowCacheEntry sprites[20];
} VDP_SpriteRowCacheRow;
typedef struct VDP_State
{
struct
{
cc_bool write_pending;
cc_u16l address_register;
cc_u16l code_register;
cc_u16l increment;
VDP_Access selected_buffer;
} access;
struct
{
cc_bool enabled;
VDP_DMAMode mode;
cc_u8l source_address_high;
cc_u16l source_address_low;
cc_u16l length;
} dma;
cc_u16l plane_a_address;
cc_u16l plane_b_address;
cc_u16l window_address;
cc_u16l sprite_table_address;
cc_u16l hscroll_address;
struct
{
cc_bool aligned_right;
cc_bool aligned_bottom;
cc_u16l horizontal_boundary;
cc_u16l vertical_boundary;
} window;
cc_u8l plane_width_bitmask;
cc_u8l plane_height_bitmask;
cc_bool display_enabled;
cc_bool v_int_enabled;
cc_bool h_int_enabled;
cc_bool h40_enabled;
cc_bool v30_enabled;
cc_bool mega_drive_mode_enabled;
cc_bool shadow_highlight_enabled;
cc_bool double_resolution_enabled;
cc_u8l background_colour;
cc_u8l h_int_interval;
cc_bool currently_in_vblank;
cc_bool allow_sprite_masking;
VDP_HScrollMode hscroll_mode;
VDP_VScrollMode vscroll_mode;
cc_bool dma_cycle_delay;
cc_u8l vram[0x10000];
cc_u16l cram[4 * 16];
/* http://gendev.spritesmind.net/forum/viewtopic.php?p=36727#p36727 */
/* According to Mask of Destiny on SpritesMind, later models of Mega Drive (MD2 VA4 and later) have 64 words
of VSRAM, instead of the 40 words that earlier models have. */
/* TODO: Add a toggle for Model 1 and Model 2 behaviour. */
cc_u16l vsram[64];
cc_u8l sprite_table_cache[80][4];
struct
{
cc_bool needs_updating;
VDP_SpriteRowCacheRow rows[VDP_MAX_SCANLINES];
} sprite_row_cache;
/* A placeholder for the FIFO, needed for CRAM/VSRAM DMA fills. */
/* TODO: Implement the actual VDP FIFO. */
cc_u16l previous_data_writes[4];
/* Gens KMod's custom debug register 30. */
cc_u16l kdebug_buffer_index;
char kdebug_buffer[0x100];
} VDP_State;
typedef struct VDP
{
const VDP_Configuration *configuration;
const VDP_Constant *constant;
VDP_State *state;
} VDP;
typedef void (*VDP_ScanlineRenderedCallback)(void *user_data, cc_u16f scanline, const cc_u8l *pixels, cc_u16f screen_width, cc_u16f screen_height);
typedef void (*VDP_ColourUpdatedCallback)(void *user_data, cc_u16f index, cc_u16f colour);
typedef cc_u16f (*VDP_ReadCallback)(void *user_data, cc_u32f address);
typedef void (*VDP_KDebugCallback)(void *user_data, const char *string);
void VDP_Constant_Initialise(VDP_Constant *constant);
void VDP_State_Initialise(VDP_State *state);
void VDP_RenderScanline(const VDP *vdp, cc_u16f scanline, VDP_ScanlineRenderedCallback scanline_rendered_callback, const void *scanline_rendered_callback_user_data);
cc_u16f VDP_ReadData(const VDP *vdp);
cc_u16f VDP_ReadControl(const VDP *vdp);
void VDP_WriteData(const VDP *vdp, cc_u16f value, VDP_ColourUpdatedCallback colour_updated_callback, const void *colour_updated_callback_user_data);
void VDP_WriteControl(const VDP *vdp, cc_u16f value, VDP_ColourUpdatedCallback colour_updated_callback, const void *colour_updated_callback_user_data, VDP_ReadCallback read_callback, const void *read_callback_user_data, VDP_KDebugCallback kdebug_callback, const void *kdebug_callback_user_data);
cc_u16f VDP_ReadVRAMWord(const VDP_State *state, cc_u16f address);
VDP_TileMetadata VDP_DecomposeTileMetadata(cc_u16f packed_tile_metadata);
VDP_CachedSprite VDP_GetCachedSprite(const VDP_State *state, cc_u16f sprite_index);
#ifdef __cplusplus
}
#endif
#endif /* VDP_H */