comparison vdp.c @ 2194:01ff005b08f6

Very rudimentary support for Game Gear VDP emulation
author Michael Pavone <pavone@retrodev.com>
date Sun, 21 Aug 2022 22:29:47 -0700
parents c5d0edf1d7e7
children 6f66356af4e2
comparison
equal deleted inserted replaced
2193:d00fb9c6a6a2 2194:01ff005b08f6
144 context->top_offset = border_top - context->border_top; 144 context->top_offset = border_top - context->border_top;
145 } 145 }
146 146
147 static uint8_t color_map_init_done; 147 static uint8_t color_map_init_done;
148 148
149 vdp_context *init_vdp_context(uint8_t region_pal, uint8_t has_max_vsram) 149 vdp_context *init_vdp_context(uint8_t region_pal, uint8_t has_max_vsram, uint8_t type)
150 { 150 {
151 vdp_context *context = calloc(1, sizeof(vdp_context) + VRAM_SIZE); 151 vdp_context *context = calloc(1, sizeof(vdp_context) + VRAM_SIZE);
152 if (headless) { 152 if (headless) {
153 context->fb = malloc(512 * LINEBUF_SIZE * sizeof(uint32_t)); 153 context->fb = malloc(512 * LINEBUF_SIZE * sizeof(uint32_t));
154 context->output_pitch = LINEBUF_SIZE * sizeof(uint32_t); 154 context->output_pitch = LINEBUF_SIZE * sizeof(uint32_t);
159 context->sprite_draws = MAX_SPRITES_LINE; 159 context->sprite_draws = MAX_SPRITES_LINE;
160 context->fifo_write = 0; 160 context->fifo_write = 0;
161 context->fifo_read = -1; 161 context->fifo_read = -1;
162 context->regs[REG_HINT] = context->hint_counter = 0xFF; 162 context->regs[REG_HINT] = context->hint_counter = 0xFF;
163 context->vsram_size = has_max_vsram ? MAX_VSRAM_SIZE : MIN_VSRAM_SIZE; 163 context->vsram_size = has_max_vsram ? MAX_VSRAM_SIZE : MIN_VSRAM_SIZE;
164 context->type = type;
164 165
165 if (!color_map_init_done) { 166 if (!color_map_init_done) {
166 uint8_t b,g,r; 167 uint8_t b,g,r;
167 for (uint16_t color = 0; color < (1 << 12); color++) { 168 for (uint16_t color = 0; color < (1 << 12); color++) {
168 if (color & FBUF_SHADOW) { 169 if (color & FBUF_SHADOW) {
172 } else if(color & FBUF_HILIGHT) { 173 } else if(color & FBUF_HILIGHT) {
173 b = levels[((color >> 9) & 0x7) + 7]; 174 b = levels[((color >> 9) & 0x7) + 7];
174 g = levels[((color >> 5) & 0x7) + 7]; 175 g = levels[((color >> 5) & 0x7) + 7];
175 r = levels[((color >> 1) & 0x7) + 7]; 176 r = levels[((color >> 1) & 0x7) + 7];
176 } else if(color & FBUF_MODE4) { 177 } else if(color & FBUF_MODE4) {
177 b = levels[(color >> 4 & 0xC) | (color >> 6 & 0x2)]; 178 if (type == VDP_GAMEGEAR) {
178 g = levels[(color >> 2 & 0x8) | (color >> 1 & 0x4) | (color >> 4 & 0x2)]; 179 b = (color >> 8 & 0xF) * 0x11;
179 r = levels[(color << 1 & 0xC) | (color >> 1 & 0x2)]; 180 g = (color >> 4 & 0xF) * 0x11;
181 r = (color & 0xF) * 0x11;
182 } else {
183 //TODO: Mode 4 has a separate DAC tap so this isn't quite correct
184 b = levels[(color >> 4 & 0xC) | (color >> 6 & 0x2)];
185 g = levels[(color >> 2 & 0x8) | (color >> 1 & 0x4) | (color >> 4 & 0x2)];
186 r = levels[(color << 1 & 0xC) | (color >> 1 & 0x2)];
187 }
180 } else { 188 } else {
181 b = levels[(color >> 8) & 0xE]; 189 b = levels[(color >> 8) & 0xE];
182 g = levels[(color >> 4) & 0xE]; 190 g = levels[(color >> 4) & 0xE];
183 r = levels[color & 0xE]; 191 r = levels[color & 0xE];
184 } 192 }
803 static void update_color_map(vdp_context *context, uint16_t index, uint16_t value) 811 static void update_color_map(vdp_context *context, uint16_t index, uint16_t value)
804 { 812 {
805 context->colors[index] = color_map[value & CRAM_BITS]; 813 context->colors[index] = color_map[value & CRAM_BITS];
806 context->colors[index + SHADOW_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_SHADOW]; 814 context->colors[index + SHADOW_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_SHADOW];
807 context->colors[index + HIGHLIGHT_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_HILIGHT]; 815 context->colors[index + HIGHLIGHT_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_HILIGHT];
808 context->colors[index + MODE4_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_MODE4]; 816 if (context->type == VDP_GAMEGEAR) {
817 context->colors[index + MODE4_OFFSET] = color_map[(value & 0xFFF) | FBUF_MODE4];
818 } else {
819 context->colors[index + MODE4_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_MODE4];
820 }
809 } 821 }
810 822
811 void write_cram_internal(vdp_context * context, uint16_t addr, uint16_t value) 823 void write_cram_internal(vdp_context * context, uint16_t addr, uint16_t value)
812 { 824 {
813 context->cram[addr] = value; 825 context->cram[addr] = value;
817 static void write_cram(vdp_context * context, uint16_t address, uint16_t value) 829 static void write_cram(vdp_context * context, uint16_t address, uint16_t value)
818 { 830 {
819 uint16_t addr; 831 uint16_t addr;
820 if (context->regs[REG_MODE_2] & BIT_MODE_5) { 832 if (context->regs[REG_MODE_2] & BIT_MODE_5) {
821 addr = (address/2) & (CRAM_SIZE-1); 833 addr = (address/2) & (CRAM_SIZE-1);
834 } else if (context->type == VDP_GAMEGEAR) {
835 addr = (address/2) & 31;
822 } else { 836 } else {
823 addr = address & 0x1F; 837 addr = address & 0x1F;
824 value = (value << 1 & 0xE) | (value << 2 & 0xE0) | (value & 0xE00); 838 value = (value << 1 & 0xE) | (value << 2 & 0xE0) | (value & 0xE00);
825 } 839 }
826 write_cram_internal(context, addr, value); 840 write_cram_internal(context, addr, value);
938 break; 952 break;
939 case CRAM_WRITE: { 953 case CRAM_WRITE: {
940 //printf("CRAM Write | %X to %X\n", start->value, (start->address/2) & (CRAM_SIZE-1)); 954 //printf("CRAM Write | %X to %X\n", start->value, (start->address/2) & (CRAM_SIZE-1));
941 uint16_t val; 955 uint16_t val;
942 if (start->partial == 3) { 956 if (start->partial == 3) {
943 if ((start->address & 1) && (context->regs[REG_MODE_2] & BIT_MODE_5)) { 957 if (context->type == VDP_GAMEGEAR) {
958 if (start->address & 1) {
959 val = start->value << 8 | context->cram_latch;
960 } else {
961 context->cram_latch = start->value;
962 break;
963 }
964 } else if ((start->address & 1) && (context->regs[REG_MODE_2] & BIT_MODE_5)) {
944 val = (context->cram[start->address >> 1 & (CRAM_SIZE-1)] & 0xFF) | start->value << 8; 965 val = (context->cram[start->address >> 1 & (CRAM_SIZE-1)] & 0xFF) | start->value << 8;
945 } else { 966 } else {
946 uint16_t address = (context->regs[REG_MODE_2] & BIT_MODE_5) ? start->address >> 1 & (CRAM_SIZE-1) : start->address & 0x1F; 967 uint16_t address = (context->regs[REG_MODE_2] & BIT_MODE_5) ? start->address >> 1 & (CRAM_SIZE-1) : start->address & 0x1F;
947 val = (context->cram[address] & 0xFF00) | start->value; 968 val = (context->cram[address] & 0xFF00) | start->value;
948 } 969 }