# HG changeset patch # User Michael Pavone # Date 1462055508 25200 # Node ID bf63cbf1d7bb97134b111ffa42a5045dd0b1c84e # Parent 560da2e455c2bedb61c93bff2c448d514015fc20 Implement SAT cache. Causes some graphical corruption in Overdrive due to an unrelated bug. diff -r 560da2e455c2 -r bf63cbf1d7bb vdp.c --- a/vdp.c Sat Apr 30 10:47:29 2016 -0700 +++ b/vdp.c Sat Apr 30 15:31:48 2016 -0700 @@ -210,11 +210,12 @@ uint8_t count = 0; do { uint16_t address = current_index * 8 + sat_address; - uint8_t height = ((context->vdpmem[address+2] & 0x3) + 1) * 8; - uint8_t width = (((context->vdpmem[address+2] >> 2) & 0x3) + 1) * 8; - int16_t y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) & 0x1FF; + uint16_t cache_address = current_index * 4; + uint8_t height = ((context->sat_cache[cache_address+2] & 0x3) + 1) * 8; + uint8_t width = (((context->sat_cache[cache_address+2] >> 2) & 0x3) + 1) * 8; + int16_t y = ((context->sat_cache[cache_address] & 0x3) << 8 | context->sat_cache[cache_address+1]) & 0x1FF; int16_t x = ((context->vdpmem[address+ 6] & 0x3) << 8 | context->vdpmem[address + 7]) & 0x1FF; - uint16_t link = context->vdpmem[address+3] & 0x7F; + uint16_t link = context->sat_cache[cache_address+3] & 0x7F; uint8_t pal = context->vdpmem[address + 4] >> 5 & 0x3; uint8_t pri = context->vdpmem[address + 4] >> 7; uint16_t pattern = ((context->vdpmem[address + 4] << 8 | context->vdpmem[address + 5]) & 0x7FF) << 5; @@ -374,33 +375,40 @@ context->sprite_index = 0; return; } - //TODO: Read from SAT cache rather than from VRAM - uint16_t sat_address = (context->regs[REG_SAT] & 0x7F) << 9; - uint16_t address = context->sprite_index * 8 + sat_address; + uint16_t address = context->sprite_index * 4; line += ymin; - uint16_t y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) & ymask; - uint8_t height = ((context->vdpmem[address+2] & 0x3) + 1) * height_mult; + uint16_t y = ((context->sat_cache[address] & 0x3) << 8 | context->sat_cache[address+1]) & ymask; + uint8_t height = ((context->sat_cache[address+2] & 0x3) + 1) * height_mult; //printf("Sprite %d | y: %d, height: %d\n", context->sprite_index, y, height); if (y <= line && line < (y + height)) { //printf("Sprite %d at y: %d with height %d is on line %d\n", context->sprite_index, y, height, line); - context->sprite_info_list[--(context->slot_counter)].size = context->vdpmem[address+2]; + context->sprite_info_list[--(context->slot_counter)].size = context->sat_cache[address+2]; context->sprite_info_list[context->slot_counter].index = context->sprite_index; context->sprite_info_list[context->slot_counter].y = y-ymin; } - context->sprite_index = context->vdpmem[address+3] & 0x7F; + context->sprite_index = context->sat_cache[address+3] & 0x7F; if (context->sprite_index && context->slot_counter) { - address = context->sprite_index * 8 + sat_address; - y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) & ymask; - height = ((context->vdpmem[address+2] & 0x3) + 1) * height_mult; + if (context->regs[REG_MODE_4] & BIT_H40) { + if (context->sprite_index >= MAX_SPRITES_FRAME) { + context->sprite_index = 0; + return; + } + } else if(context->sprite_index >= MAX_SPRITES_FRAME_H32) { + context->sprite_index = 0; + return; + } + address = context->sprite_index * 4; + y = ((context->sat_cache[address] & 0x3) << 8 | context->sat_cache[address+1]) & ymask; + height = ((context->sat_cache[address+2] & 0x3) + 1) * height_mult; //printf("Sprite %d | y: %d, height: %d\n", context->sprite_index, y, height); if (y <= line && line < (y + height)) { //printf("Sprite %d at y: %d with height %d is on line %d\n", context->sprite_index, y, height, line); - context->sprite_info_list[--(context->slot_counter)].size = context->vdpmem[address+2]; + context->sprite_info_list[--(context->slot_counter)].size = context->sat_cache[address+2]; context->sprite_info_list[context->slot_counter].index = context->sprite_index; context->sprite_info_list[context->slot_counter].y = y-ymin; } - context->sprite_index = context->vdpmem[address+3] & 0x7F; + context->sprite_index = context->sat_cache[address+3] & 0x7F; } } } @@ -509,6 +517,17 @@ } } +void write_vram_byte(vdp_context *context, uint16_t address, uint8_t value) +{ + if (!(address & 4)) { + uint16_t sat_address = (context->regs[REG_SAT] & 0x7F) << 9; + if(address >= sat_address && address <= sat_address + SAT_CACHE_SIZE*2) { + context->sat_cache[(address & 3) | (address >> 1 & 0x1FC)] = value; + } + } + context->vdpmem[address] = value; +} + void external_slot(vdp_context * context) { if ((context->flags & FLAG_DMA_RUN) && (context->regs[REG_DMASRC_H] & 0xC0) == 0x80 && context->fifo_read < 0) { @@ -526,10 +545,10 @@ case VRAM_WRITE: if (start->partial) { //printf("VRAM Write: %X to %X at %d (line %d, slot %d)\n", start->value, start->address ^ 1, context->cycles, context->cycles/MCLKS_LINE, (context->cycles%MCLKS_LINE)/16); - context->vdpmem[start->address ^ 1] = start->partial == 2 ? start->value >> 8 : start->value; + write_vram_byte(context, start->address ^ 1, start->partial == 2 ? start->value >> 8 : start->value); } else { //printf("VRAM Write High: %X to %X at %d (line %d, slot %d)\n", start->value >> 8, start->address, context->cycles, context->cycles/MCLKS_LINE, (context->cycles%MCLKS_LINE)/16); - context->vdpmem[start->address] = start->value >> 8; + write_vram_byte(context, start->address, start->value >> 8); start->partial = 1; //skip auto-increment and removal of entry from fifo return; @@ -557,7 +576,7 @@ } } else if ((context->flags & FLAG_DMA_RUN) && (context->regs[REG_DMASRC_H] & 0xC0) == 0xC0) { if (context->flags & FLAG_READ_FETCHED) { - context->vdpmem[context->address ^ 1] = context->prefetch; + write_vram_byte(context, context->address ^ 1, context->prefetch); //Update DMA state vdp_advance_dma(context); diff -r 560da2e455c2 -r bf63cbf1d7bb vdp.h --- a/vdp.h Sat Apr 30 10:47:29 2016 -0700 +++ b/vdp.h Sat Apr 30 15:31:48 2016 -0700 @@ -21,6 +21,7 @@ #define MAX_SPRITES_LINE_H32 16 #define MAX_SPRITES_FRAME 80 #define MAX_SPRITES_FRAME_H32 64 +#define SAT_CACHE_SIZE (MAX_SPRITES_FRAME * 4) #define FBUF_SHADOW 0x0001 #define FBUF_HILIGHT 0x0010 @@ -158,6 +159,7 @@ int8_t cur_slot; sprite_draw sprite_draw_list[MAX_DRAWS]; sprite_info sprite_info_list[MAX_SPRITES_LINE]; + uint8_t sat_cache[SAT_CACHE_SIZE]; uint16_t col_1; uint16_t col_2; uint16_t hv_latch;