megadrive_test2

annotate src/vdp.h @ 1:2560a8be8cb8

hblank interrupt test
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 14 Mar 2017 09:02:43 +0200
parents ce1b05082ac4
children 72ab63f262bf
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@0 50 static inline void vdp_setup_access(uint16_t addr, int rw, int memid)
nuclear@0 51 {
nuclear@0 52 uint32_t type;
nuclear@0 53 if(rw == VDP_MEM_WRITE) {
nuclear@0 54 type = (memid & 7) | 1;
nuclear@0 55 } else {
nuclear@0 56 type = memid & 0xc;
nuclear@0 57 }
nuclear@0 58
nuclear@0 59 VDP_PORT_CTL32 = (((uint32_t)addr & 0x3fff) << 16) | ((addr >> 14) & 3) |
nuclear@0 60 ((type << 2) & 0xf0) | (type << 30);
nuclear@0 61 }
nuclear@0 62
nuclear@0 63
nuclear@0 64 /* mode register 1 */
nuclear@0 65 enum {
nuclear@0 66 VDP_MODE1_BASE = 0x4,
nuclear@0 67 VDP_MODE1_HVCNT = 0x2,
nuclear@0 68 VDP_MODE1_HINTR = 0x10
nuclear@0 69 };
nuclear@0 70
nuclear@0 71 /* mode register 2 */
nuclear@0 72 enum {
nuclear@0 73 VDP_MODE2_BASE = 0x4,
nuclear@0 74 VDP_MODE2_V30CELL = 0x8,
nuclear@0 75 VDP_MODE2_DMA = 0x10,
nuclear@0 76 VDP_MODE2_VINTR = 0x20,
nuclear@0 77 VDP_MODE2_DISP = 0x40
nuclear@0 78 };
nuclear@0 79
nuclear@0 80 /* mode register 3 */
nuclear@0 81 enum {
nuclear@0 82 VDP_MODE3_BASE = 0,
nuclear@0 83 VDP_MODE3_HSCROLL_CELL = 2,
nuclear@0 84 VDP_MODE3_HSCROLL_LINE = 3,
nuclear@0 85 VDP_MODE3_VSCROLL_2CELL = 4,
nuclear@0 86 VDP_MODE3_EXTINTR = 8
nuclear@0 87 };
nuclear@0 88
nuclear@0 89 /* mode register 4 */
nuclear@0 90 enum {
nuclear@0 91 VDP_MODE4_BASE = 0,
nuclear@0 92 VDP_MODE4_H40CELL = 0x81,
nuclear@0 93 VDP_MODE4_ILACE = 2,
nuclear@0 94 VDP_MODE4_ILACE_2XRES = 6,
nuclear@0 95 VDP_MODE4_SH = 8 /* shadow/highlight enable */
nuclear@0 96 };
nuclear@0 97
nuclear@0 98 /* scroll size register */
nuclear@0 99 enum {
nuclear@0 100 VDP_SCROLL_H32 = 0,
nuclear@0 101 VDP_SCROLL_H64 = 1,
nuclear@0 102 VDP_SCROLL_H128 = 3,
nuclear@0 103 VDP_SCROLL_V32 = 0,
nuclear@0 104 VDP_SCROLL_V64 = 0x10,
nuclear@0 105 VDP_SCROLL_V128 = 0x30
nuclear@0 106 };
nuclear@0 107
nuclear@0 108 /* window X/Y position register */
nuclear@0 109 enum {
nuclear@0 110 VDP_WIN_LEFT = 0,
nuclear@0 111 VDP_WIN_UP = 0,
nuclear@0 112 VDP_WIN_RIGHT = 0x80,
nuclear@0 113 VDP_WIN_DOWN = 0x80,
nuclear@0 114 VDP_WIN_POSMASK = 0x1f
nuclear@0 115 };
nuclear@0 116
nuclear@0 117 #define VDP_PACK_RGB(r, g, b) \
nuclear@0 118 ((((uint16_t)(r) & 7) << 1) | (((uint16_t)(g) & 7) << 5) | (((uint16_t)(b) & 7) << 9))
nuclear@0 119
nuclear@0 120
nuclear@0 121 static inline void vdp_setreg(int reg, uint8_t value)
nuclear@0 122 {
nuclear@1 123 vdp_reg_shadow[reg] = value;
nuclear@0 124 VDP_PORT_CTL = (uint16_t)value | (reg << 8) | (uint16_t)0x8000;
nuclear@0 125 }
nuclear@0 126
nuclear@0 127 static inline uint16_t vdp_getreg(int reg)
nuclear@0 128 {
nuclear@0 129 return vdp_reg_shadow[reg];
nuclear@0 130 }
nuclear@0 131
nuclear@0 132 static inline uint16_t vdp_status(void)
nuclear@0 133 {
nuclear@0 134 return VDP_PORT_CTL;
nuclear@0 135 }
nuclear@0 136
nuclear@0 137 static inline void vdp_set_bgcolor(int palidx, int colidx)
nuclear@0 138 {
nuclear@0 139 vdp_setreg(VDP_REG_BGCOL, (colidx & 0xf) | (palidx << 4));
nuclear@0 140 }
nuclear@0 141
nuclear@0 142 static inline void vdp_set_autoinc(int stride)
nuclear@0 143 {
nuclear@0 144 vdp_setreg(VDP_REG_AUTOINC, stride);
nuclear@0 145 }
nuclear@0 146
nuclear@0 147 static inline void vdp_set_pal_entry(int pidx, int cidx, int r, int g, int b)
nuclear@0 148 {
nuclear@0 149 uint16_t paddr = (pidx << 5) | (cidx << 1);
nuclear@0 150
nuclear@0 151 vdp_setup_access(paddr, VDP_MEM_WRITE, VDP_MEM_CRAM);
nuclear@0 152 VDP_PORT_DATA = VDP_PACK_RGB(r, g, b);
nuclear@0 153 }
nuclear@0 154
nuclear@1 155 static inline void vdp_enable_vintr(void)
nuclear@1 156 {
nuclear@1 157 vdp_setreg(VDP_REG_MODE2, vdp_getreg(VDP_REG_MODE2) | VDP_MODE2_VINTR);
nuclear@1 158 }
nuclear@1 159
nuclear@1 160 static inline void vdp_disable_vintr(void)
nuclear@1 161 {
nuclear@1 162 vdp_setreg(VDP_REG_MODE2, vdp_getreg(VDP_REG_MODE2) & ~VDP_MODE2_VINTR);
nuclear@1 163 }
nuclear@1 164
nuclear@1 165 static inline void vdp_enable_hintr(int counter)
nuclear@1 166 {
nuclear@1 167 vdp_setreg(VDP_REG_HINTR, counter);
nuclear@1 168 vdp_setreg(VDP_REG_MODE1, vdp_getreg(VDP_REG_MODE1) | VDP_MODE1_HINTR);
nuclear@1 169 }
nuclear@1 170
nuclear@1 171 static inline void vdp_disable_hintr(void)
nuclear@1 172 {
nuclear@1 173 vdp_setreg(VDP_REG_MODE1, vdp_getreg(VDP_REG_MODE1) & ~VDP_MODE1_HINTR);
nuclear@1 174 }
nuclear@1 175
nuclear@0 176 void vdp_init(void);
nuclear@0 177
nuclear@0 178 #endif /* VDP_H_ */