6 #define VDP_PORT_DATA *((volatile uint16_t*)0xc00000)
7 #define VDP_PORT_DATA32 *((volatile uint32_t*)0xc00000)
8 #define VDP_PORT_CTL *((volatile uint16_t*)0xc00004)
9 #define VDP_PORT_CTL32 *((volatile uint32_t*)0xc00004)
10 #define VDP_PORT_HVCNT *((volatile uint16_t*)0xc00008)
11 #define VDP_PORT_PSG *((volatile uint16_t*)0xc00010)
13 #define VDP_PORT_STATUS *((volatile uint16_t*)0xc00004)
18 VDP_REG_NAMETAB_A = 2,
19 VDP_REG_NAMETAB_WIN = 3,
20 VDP_REG_NAMETAB_B = 4,
21 VDP_REG_SPRITE_TAB = 5,
26 VDP_REG_SCROLL_TAB = 13,
28 VDP_REG_SCROLL_SIZE = 16,
29 VDP_REG_WIN_XPOS = 17,
30 VDP_REG_WIN_YPOS = 18,
31 VDP_REG_DMA_LEN_LOW = 19,
32 VDP_REG_DMA_LEN_HIGH = 20,
33 VDP_REG_DMA_SRC_LOW = 21,
34 VDP_REG_DMA_SRC_MID = 22,
35 VDP_REG_DMA_SRC_HIGH = 23,
40 uint16_t vdp_reg_shadow[VDP_NUM_REGS];
42 /* access VDP memory */
43 enum { VDP_MEM_READ, VDP_MEM_WRITE };
46 VDP_MEM_CRAM = 0xa, /* CD5->CD0: 0 0 r 0 w 0 */
47 VDP_MEM_VSRAM = 4 /* CD5->CD0: 0 0 0 1 0 0 */
57 VDP_TILE_LOW_PRIO = 0,
58 VDP_TILE_HFLIP = 0x0800,
59 VDP_TILE_VFLIP = 0x1000,
60 VDP_TILE_HIGH_PRIO = 0x8000
64 VDP_STAT_PAL = 0x0001,
65 VDP_STAT_DMABUSY = 0x0002,
66 VDP_STAT_HBLANK = 0x0004,
67 VDP_STAT_VBLANK = 0x0008,
68 VDP_STAT_ODDFIELD = 0x0010,
69 VDP_STAT_SPRITE_COL = 0x0020,
70 VDP_STAT_SPRITE_OVF = 0x0040,
71 VDP_STAT_VINTR = 0x0080,
72 VDP_STAT_FIFO_FULL = 0x0100,
73 VDP_STAT_FIFO_EMPTY = 0x0200
77 static inline void vdp_setup_access(uint16_t addr, int rw, int memid)
80 if(rw == VDP_MEM_WRITE) {
81 type = (memid & 7) | 1;
86 VDP_PORT_CTL32 = (((uint32_t)addr & 0x3fff) << 16) | ((addr >> 14) & 3) |
87 ((type << 2) & 0xf0) | (type << 30);
94 VDP_MODE1_HVCNT = 0x2,
95 VDP_MODE1_HINTR = 0x10
100 VDP_MODE2_BASE = 0x4,
101 VDP_MODE2_V30CELL = 0x8,
102 VDP_MODE2_DMA = 0x10,
103 VDP_MODE2_VINTR = 0x20,
104 VDP_MODE2_DISP = 0x40
107 /* mode register 3 */
110 VDP_MODE3_HSCROLL_CELL = 2,
111 VDP_MODE3_HSCROLL_LINE = 3,
112 VDP_MODE3_VSCROLL_2CELL = 4,
113 VDP_MODE3_EXTINTR = 8
116 /* mode register 4 */
119 VDP_MODE4_H40CELL = 0x81,
121 VDP_MODE4_ILACE_2XRES = 6,
122 VDP_MODE4_SH = 8 /* shadow/highlight enable */
125 /* scroll size register */
131 VDP_SCROLL_V64 = 0x10,
132 VDP_SCROLL_V128 = 0x30
135 /* window X/Y position register */
139 VDP_WIN_RIGHT = 0x80,
141 VDP_WIN_POSMASK = 0x1f
144 #define VDP_PACK_RGB(r, g, b) \
145 ((((uint16_t)(r) & 7) << 1) | (((uint16_t)(g) & 7) << 5) | (((uint16_t)(b) & 7) << 9))
148 static inline void vdp_setreg(int reg, uint8_t value)
150 vdp_reg_shadow[reg] = value;
151 VDP_PORT_CTL = (uint16_t)value | (reg << 8) | (uint16_t)0x8000;
154 static inline uint16_t vdp_getreg(int reg)
156 return vdp_reg_shadow[reg];
159 static inline uint16_t vdp_status(void)
164 static inline void vdp_set_bgcolor(int palidx, int colidx)
166 vdp_setreg(VDP_REG_BGCOL, (colidx & 0xf) | (palidx << 4));
169 static inline void vdp_set_autoinc(int stride)
171 vdp_setreg(VDP_REG_AUTOINC, stride);
174 static inline void vdp_begin_palette(int pidx, int cidx)
176 uint16_t paddr = (pidx << 5) | (cidx << 1);
177 vdp_setup_access(paddr, VDP_MEM_WRITE, VDP_MEM_CRAM);
180 static inline void vdp_set_pal_entry(int pidx, int cidx, int r, int g, int b)
182 vdp_begin_palette(pidx, cidx);
183 VDP_PORT_DATA = VDP_PACK_RGB(r, g, b);
186 static inline void vdp_enable_vintr(void)
188 vdp_setreg(VDP_REG_MODE2, vdp_getreg(VDP_REG_MODE2) | VDP_MODE2_VINTR);
191 static inline void vdp_disable_vintr(void)
193 vdp_setreg(VDP_REG_MODE2, vdp_getreg(VDP_REG_MODE2) & ~VDP_MODE2_VINTR);
196 static inline void vdp_enable_hintr(int counter)
198 vdp_setreg(VDP_REG_HINTR, counter);
199 vdp_setreg(VDP_REG_MODE1, vdp_getreg(VDP_REG_MODE1) | VDP_MODE1_HINTR);
202 static inline void vdp_disable_hintr(void)
204 vdp_setreg(VDP_REG_MODE1, vdp_getreg(VDP_REG_MODE1) & ~VDP_MODE1_HINTR);
207 static inline void vdp_set_nametab_addr(int plane, uint16_t addr)
211 vdp_setreg(VDP_REG_NAMETAB_A, (addr >> 10) & 0x38);
214 vdp_setreg(VDP_REG_NAMETAB_B, (addr >> 13) & 7);
217 vdp_setreg(VDP_REG_NAMETAB_WIN, (addr >> 10) & 0x7e);
223 static inline uint16_t vdp_nametab_addr(int idx)
225 return (uint16_t)idx << 13;
228 static inline void vdp_set_nametab_idx(int plane, int idx)
230 vdp_set_nametab_addr(plane, vdp_nametab_addr(idx));
233 static inline void vdp_disable_layer(int plane)
237 vdp_setreg(VDP_REG_NAMETAB_A, 0x40);
240 vdp_setreg(VDP_REG_NAMETAB_B, 0x08);
243 vdp_setreg(VDP_REG_NAMETAB_WIN, 0x40);
249 static inline uint16_t vdp_nametab_entry(int tileidx, int palidx, uint16_t flags)
251 return tileidx | (((uint16_t)palidx & 0x3) << 13) | flags;
254 static inline void vdp_set_sprite_table(uint16_t addr)
256 vdp_setreg(VDP_REG_SPRITE_TAB, addr >> 9);
259 static inline void vdp_set_scroll_table(uint16_t addr)
261 vdp_setreg(VDP_REG_SCROLL_TAB, addr >> 10);
264 static inline void vdp_wait_vblank_start(void)
266 while(!(VDP_PORT_STATUS & VDP_STAT_VBLANK));
269 static inline void vdp_wait_vblank_end(void)
271 while(VDP_PORT_STATUS & VDP_STAT_VBLANK);
274 static inline void vdp_wait_vblank(void)
276 vdp_wait_vblank_start();
277 vdp_wait_vblank_end();