# HG changeset patch # User Mike Pavone # Date 1371961183 25200 # Node ID 36fbbced25c28c941219603af5960d68dac77028 # Parent 00d5a2b532f4fe73495eaca76ac7cc793d7fec89 Initial work on interlace diff -r 00d5a2b532f4 -r 36fbbced25c2 render_sdl.c --- a/render_sdl.c Wed Jun 19 00:40:13 2013 -0700 +++ b/render_sdl.c Sat Jun 22 21:19:43 2013 -0700 @@ -147,6 +147,8 @@ SDL_PauseAudio(0); } +uint16_t blankbuf[320*240]; + void render_context(vdp_context * context) { uint8_t *buf_8; @@ -166,13 +168,15 @@ } else { repeat_y = repeat_x; } + int othermask = repeat_y >> 1; + uint16_t *otherbuf = (context->regs[REG_MODE_4] & BIT_INTERLACE) ? context->evenbuf : blankbuf; switch (screen->format->BytesPerPixel) { case 2: buf_16 = (uint16_t *)screen->pixels; for (int y = 0; y < 240; y++) { for (int i = 0; i < repeat_y; i++,buf_16 += screen->pitch/2) { uint16_t *line = buf_16; - uint16_t *src_line = context->framebuf + y * 320; + uint16_t *src_line = (i & othermask ? otherbuf : context->oddbuf) + y * 320; for (int x = 0; x < 320; x++) { uint16_t color = color_map[*(src_line++) & 0xFFF]; for (int j = 0; j < repeat_x; j++) { @@ -188,7 +192,7 @@ for (int i = 0; i < repeat_y; i++,buf_8 += screen->pitch) { uint8_t *line = buf_8; for (int x = 0; x < 320; x++) { - uint16_t gen_color = context->framebuf[y * 320 + x]; + uint16_t gen_color = context->oddbuf[y * 320 + x]; b = ((gen_color >> 8) & 0xE) * 18; g = ((gen_color >> 4) & 0xE) * 18; r = (gen_color& 0xE) * 18; @@ -208,7 +212,7 @@ for (int y = 0; y < 240; y++) { for (int i = 0; i < repeat_y; i++,buf_32 += screen->pitch/4) { uint32_t *line = buf_32; - uint16_t *src_line = context->framebuf + y * 320; + uint16_t *src_line = (i & othermask ? otherbuf : context->oddbuf) + y * 320; for (int x = 0; x < 320; x++) { uint32_t color; if (!render_dbg) { @@ -222,7 +226,7 @@ color = color_map[context->cram[ (debug_pal << 4) | (context->vdpmem[(x/8)*32 + (y/8)*32*40 + (x%8)/2 + (y%8)*4] >> 4) ]]; } }else { - uint16_t gen_color = context->framebuf[y * 320 + x]; + uint16_t gen_color = context->oddbuf[y * 320 + x]; r = g = b = 0; switch(gen_color & FBUF_SRC_MASK) { @@ -271,6 +275,10 @@ SDL_UnlockSurface(screen); } SDL_UpdateRect(screen, 0, 0, screen->clip_rect.w, screen->clip_rect.h); + if (context->regs[REG_MODE_4] & BIT_INTERLACE) + { + context->framebuf = context->framebuf == context->oddbuf ? context->evenbuf : context->oddbuf; + } } void render_wait_quit(vdp_context * context) diff -r 00d5a2b532f4 -r 36fbbced25c2 vdp.c --- a/vdp.c Wed Jun 19 00:40:13 2013 -0700 +++ b/vdp.c Sat Jun 22 21:19:43 2013 -0700 @@ -10,27 +10,6 @@ #define MAP_BIT_H_FLIP 0x800 #define MAP_BIT_V_FLIP 0x1000 -//Mode reg 1 -#define BIT_HINT_EN 0x10 -#define BIT_PAL_SEL 0x04 -#define BIT_HVC_LATCH 0x02 -#define BIT_DISP_DIS 0x01 - -//Mode reg 2 -#define BIT_DISP_EN 0x40 -#define BIT_VINT_EN 0x20 -#define BIT_DMA_ENABLE 0x10 -#define BIT_PAL 0x08 -#define BIT_MODE_5 0x04 - -//Mode reg 3 -#define BIT_EINT_EN 0x10 -#define BIT_VSCROLL 0x04 - -//Mode reg 4 -#define BIT_H40 0x01 -#define BIT_HILIGHT 0x8 - #define SCROLL_BUFFER_SIZE 32 #define SCROLL_BUFFER_DRAW 16 @@ -52,8 +31,10 @@ memset(context, 0, sizeof(*context)); context->vdpmem = malloc(VRAM_SIZE); memset(context->vdpmem, 0, VRAM_SIZE); - context->framebuf = malloc(FRAMEBUF_SIZE); + context->oddbuf = context->framebuf = malloc(FRAMEBUF_SIZE); memset(context->framebuf, 0, FRAMEBUF_SIZE); + context->evenbuf = malloc(FRAMEBUF_SIZE); + memset(context->evenbuf, 0, FRAMEBUF_SIZE); context->linebuf = malloc(LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2); memset(context->linebuf, 0, LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2); context->tmp_buf_a = context->linebuf + LINEBUF_SIZE; @@ -158,6 +139,21 @@ if (context->sprite_index && context->slot_counter) { line += 1; line &= 0xFF; + uint16_t ymask, ymin; + uint8_t height_mult; + if (context->double_res) { + line *= 2; + if (context->framebuf != context->oddbuf) { + line++; + } + ymask = 0x3FF; + ymin = 256; + height_mult = 16; + } else { + ymask = 0x1FF; + ymin = 128; + height_mult = 8; + } context->sprite_index &= 0x7F; if (context->latched_mode & BIT_H40) { if (context->sprite_index >= MAX_SPRITES_FRAME) { @@ -171,28 +167,28 @@ //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; - line += 128; + line += ymin; uint16_t y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) & 0x1FF; - uint8_t height = ((context->vdpmem[address+2] & 0x3) + 1) * 8; + uint8_t height = ((context->vdpmem[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].index = context->sprite_index; - context->sprite_info_list[context->slot_counter].y = y-128; + context->sprite_info_list[context->slot_counter].y = y-ymin; } context->sprite_index = context->vdpmem[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]) & 0x1FF; - height = ((context->vdpmem[address+2] & 0x3) + 1) * 8; + height = ((context->vdpmem[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].index = context->sprite_index; - context->sprite_info_list[context->slot_counter].y = y-128; + context->sprite_info_list[context->slot_counter].y = y-ymin; } context->sprite_index = context->vdpmem[address+3] & 0x7F; } @@ -209,6 +205,13 @@ uint8_t width = ((context->sprite_info_list[context->cur_slot].size >> 2) & 0x3) + 1; //in pixels uint8_t height = ((context->sprite_info_list[context->cur_slot].size & 0x3) + 1) * 8; + if (context->double_res) { + line *= 2; + if (context->framebuf != context->oddbuf) { + line++; + } + height *= 2; + } uint16_t att_addr = ((context->regs[REG_SAT] & 0x7F) << 9) + context->sprite_info_list[context->cur_slot].index * 8 + 4; uint16_t tileinfo = (context->vdpmem[att_addr] << 8) | context->vdpmem[att_addr+1]; uint8_t pal_priority = (tileinfo >> 9) & 0x70; @@ -218,7 +221,12 @@ } else { row = line-context->sprite_info_list[context->cur_slot].y; } - uint16_t address = ((tileinfo & 0x7FF) << 5) + row * 4; + uint16_t address; + if (context->double_res) { + address = ((tileinfo & 0x3FF) << 6) + row * 4; + } else { + address = ((tileinfo & 0x7FF) << 5) + row * 4; + } int16_t x = ((context->vdpmem[att_addr+ 2] & 0x3) << 8 | context->vdpmem[att_addr + 3]) & 0x1FF; if (x) { context->flags |= FLAG_CAN_MASK; @@ -432,6 +440,12 @@ void read_map_scroll(uint16_t column, uint16_t vsram_off, uint32_t line, uint16_t address, uint16_t hscroll_val, vdp_context * context) { + /*if (context->double_res) { + line *= 2; + if (context->framebuf != context->oddbuf) { + line++; + } + }*/ if (!vsram_off) { uint16_t left_col, right_col; if (context->regs[REG_WINDOW_H] & WINDOW_RIGHT) { @@ -493,6 +507,10 @@ vscroll = 0x3FF; break; } + /*if (context->double_res) { + vscroll <<= 1; + vscroll |= 1; + }*/ vscroll &= (context->vsram[(context->regs[REG_MODE_3] & BIT_VSCROLL ? column : 0) + vsram_off] + line); context->v_offset = vscroll & 0x7; //printf("%s | line %d, vsram: %d, vscroll: %d, v_offset: %d\n",(vsram_off ? "B" : "A"), line, context->vsram[context->regs[REG_MODE_3] & 0x4 ? column : 0], vscroll, context->v_offset); @@ -545,11 +563,21 @@ void render_map(uint16_t col, uint8_t * tmp_buf, vdp_context * context) { - uint16_t address = ((col & 0x7FF) << 5); + uint16_t address; + uint8_t shift, add; + if (context->double_res) { + address = ((col & 0x3FF) << 6); + shift = 1; + add = context->framebuf != context->oddbuf ? 1 : 0; + } else { + address = ((col & 0x7FF) << 5); + shift = 0; + add = 0; + } if (col & MAP_BIT_V_FLIP) { - address += 28 - 4 * context->v_offset; + address += 28 - 4 * ((context->v_offset << shift) + add); } else { - address += 4 * context->v_offset; + address += 4 * ((context->v_offset << shift) + add); } uint16_t pal_priority = (col >> 9) & 0x70; int32_t dir; @@ -1314,6 +1342,9 @@ if (reg == REG_MODE_2) { //printf("Display is now %s\n", (context->regs[REG_MODE_2] & DISPLAY_ENABLE) ? "enabled" : "disabled"); } + if (reg == REG_MODE_4) { + context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES); + } } } else { context->flags |= FLAG_PENDING; @@ -1362,7 +1393,10 @@ value |= 0x100; } if (context->flags2 & FLAG2_VINT_PENDING) { - value |- 0x80; + value |= 0x80; + } + if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && context->framebuf == context->oddbuf) { + value |= 0x10; } uint32_t line= context->cycles / MCLKS_LINE; uint32_t linecyc = context->cycles % MCLKS_LINE; @@ -1517,6 +1551,12 @@ } } linecyc &= 0xFF; + if (context->double_res) { + line <<= 1; + if (line & 0x100) { + line |= 1; + } + } return (line << 8) | linecyc; } diff -r 00d5a2b532f4 -r 36fbbced25c2 vdp.h --- a/vdp.h Wed Jun 19 00:40:13 2013 -0700 +++ b/vdp.h Sat Jun 22 21:19:43 2013 -0700 @@ -67,6 +67,29 @@ REG_DMASRC_H } vdp_regs; +//Mode reg 1 +#define BIT_HINT_EN 0x10 +#define BIT_PAL_SEL 0x04 +#define BIT_HVC_LATCH 0x02 +#define BIT_DISP_DIS 0x01 + +//Mode reg 2 +#define BIT_DISP_EN 0x40 +#define BIT_VINT_EN 0x20 +#define BIT_DMA_ENABLE 0x10 +#define BIT_PAL 0x08 +#define BIT_MODE_5 0x04 + +//Mode reg 3 +#define BIT_EINT_EN 0x10 +#define BIT_VSCROLL 0x04 + +//Mode reg 4 +#define BIT_H40 0x01 +#define BIT_HILIGHT 0x8 +#define BIT_DOUBLE_RES 0x4 +#define BIT_INTERLACE 0x2 + typedef struct { uint16_t address; int16_t x_pos; @@ -102,6 +125,8 @@ uint8_t *linebuf; //stores 12-bit color + shadow/highlight bits uint16_t *framebuf; + uint16_t *oddbuf; + uint16_t *evenbuf; uint16_t cram[CRAM_SIZE]; uint16_t vsram[VSRAM_SIZE]; uint8_t latched_mode; @@ -120,6 +145,7 @@ uint8_t dma_cd; uint8_t hint_counter; uint8_t flags2; + uint8_t double_res; uint8_t *tmp_buf_a; uint8_t *tmp_buf_b; } vdp_context;