diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index b2e027cd3..771b95c2a 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -37,7 +37,6 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/pci.h> -#include <86box/video.h> #include <86box/keyboard.h> #define STAT_PARITY 0x80 @@ -2786,18 +2785,14 @@ static void kbc_at_reset(void *priv) { atkbc_t *dev = (atkbc_t *) priv; - uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; dev->status = STAT_UNLOCKED; dev->mem[0x20] = 0x01; dev->mem[0x20] |= CCB_TRANSLATE; dev->command_phase = 0; - /* Set up the correct Video Type bits. */ - if (!is286 || (kbc_ven == KBC_VEN_ACER)) - dev->p1 = video_is_mda() ? 0xb0 : 0xf0; - else - dev->p1 = video_is_mda() ? 0xf0 : 0xb0; + /* Video Type is now handled in the machine P1 handler. */ + dev->p1 = 0xf0; kbc_at_log("ATkbc: P1 = %02x\n", dev->p1); /* Disabled both the keyboard and auxiliary ports. */ @@ -2918,7 +2913,6 @@ kbc_at_init(const device_t *info) dev->is_asic = !!(info->local & KBC_FLAG_IS_ASIC); dev->is_type2 = !!(info->local & KBC_FLAG_IS_TYPE2); - video_reset(gfxcard[0]); kbc_at_reset(dev); dev->handlers[0].read = kbc_at_port_1_read; diff --git a/src/include/86box/vid_voodoo_codegen_x86-64.h b/src/include/86box/vid_voodoo_codegen_x86-64.h index 67a5cae2c..8b1413ad4 100644 --- a/src/include/86box/vid_voodoo_codegen_x86-64.h +++ b/src/include/86box/vid_voodoo_codegen_x86-64.h @@ -653,14 +653,15 @@ codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *pa static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int depthop) { - int block_pos = 0; - int z_skip_pos = 0; - int a_skip_pos = 0; - int amask_skip_pos = 0; - int chroma_skip_pos = 0; - int depth_jump_pos = 0; - int depth_jump_pos2 = 0; - int loop_jump_pos = 0; + int block_pos = 0; + int z_skip_pos = 0; + int a_skip_pos = 0; + int amask_skip_pos = 0; + int stipple_skip_pos = 0; + int chroma_skip_pos = 0; + int depth_jump_pos = 0; + int depth_jump_pos2 = 0; + int loop_jump_pos = 0; #if 0 xmm_01_w = (__m128i)0x0001000100010001ull; xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; @@ -766,6 +767,69 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addquad((uint64_t) (uintptr_t) &i_00_ff_w); loop_jump_pos = block_pos; + if (params->fbzMode & FBZ_STIPPLE) { + /* Stipple enabled. */ + if (params->fbzMode & FBZ_STIPPLE_PATT) { + /* x64's BT instruction is too slow. So use TEST instead. */ + addbyte(0x4c); /* MOV RBX, R14(real_y)*/ + addbyte(0x89); + addbyte(0xf3); + + addbyte(0x83); /* AND EBX, 3 */ + addbyte(0xe3); + addbyte(0x03); + + addbyte(0xc1); /* SHL EBX, 3 */ + addbyte(0xe3); + addbyte(0x03); + + addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, x)); + + addbyte(0xf7); /* NOT EAX */ + addbyte(0xd0); + + addbyte(0x83); /* AND EAX, 7 */ + addbyte(0xe0); + addbyte(0x07); + + addbyte(0x09); /* OR EAX, EBX */ + addbyte(0xc3); + + addbyte(0x88); /* MOV CL, AL */ + addbyte(0xc1); + + addbyte(0xb8); /* MOV EAX, 1*/ + addlong(1); + + addbyte(0xd3); /* SHL EAX, CL */ + addbyte(0xe0); + + addbyte(0x85); /* TEST state->stipple[EDI], EAX */ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, stipple)); + + addbyte(0x0f); /* JZ stipple_skip_pos */ + addbyte(0x84); + stipple_skip_pos = block_pos; + addlong(0); + } else { + addbyte(0xd1); /* ROR state->stipple[EDI], 1*/ + addbyte(0x8f); + addlong(offsetof(voodoo_state_t, stipple)); + + addbyte(0xf7); /* TEST state->stipple[EDI], 0x80000000 */ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, stipple)); + addlong(0x80000000); + + addbyte(0x0f); /* JZ stipple_skip_pos */ + addbyte(0x84); + stipple_skip_pos = block_pos; + addlong(0); + } + } addbyte(0x4c); /*MOV RSI, R15*/ addbyte(0x89); addbyte(0xfe); @@ -3190,6 +3254,8 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, *(uint32_t *) &code_block[chroma_skip_pos] = (block_pos - chroma_skip_pos) - 4; if (amask_skip_pos) *(uint32_t *) &code_block[amask_skip_pos] = (block_pos - amask_skip_pos) - 4; + if (stipple_skip_pos) + *(uint32_t *) &code_block[stipple_skip_pos] = (block_pos - stipple_skip_pos) - 4; addbyte(0x4c); /*MOV RSI, R15*/ addbyte(0x89); diff --git a/src/include/86box/vid_voodoo_regs.h b/src/include/86box/vid_voodoo_regs.h index 3340720a7..9f3260c9f 100644 --- a/src/include/86box/vid_voodoo_regs.h +++ b/src/include/86box/vid_voodoo_regs.h @@ -358,6 +358,7 @@ enum { enum { FBZ_CHROMAKEY = (1 << 1), + FBZ_STIPPLE = (1 << 2), FBZ_W_BUFFER = (1 << 3), FBZ_DEPTH_ENABLE = (1 << 4), @@ -366,6 +367,8 @@ enum { FBZ_DEPTH_WMASK = (1 << 10), FBZ_DITHER_2x2 = (1 << 11), + FBZ_STIPPLE_PATT = (1 << 12), + FBZ_ALPHA_MASK = (1 << 13), FBZ_DRAW_FRONT = 0x0000, diff --git a/src/video/vid_voodoo_display.c b/src/video/vid_voodoo_display.c index 3595d8b89..b126fc165 100644 --- a/src/video/vid_voodoo_display.c +++ b/src/video/vid_voodoo_display.c @@ -645,6 +645,8 @@ skip_draw: if (voodoo->dirty_line_high > voodoo->dirty_line_low || force_blit) svga_doblit(voodoo->h_disp, voodoo->v_disp - 1, voodoo->svga); + else if (voodoo->svga->override) + voodoo->svga->monitor->mon_renderedframes++; if (voodoo->clutData_dirty) { voodoo->clutData_dirty = 0; voodoo_calc_clutData(voodoo); diff --git a/src/video/vid_voodoo_fb.c b/src/video/vid_voodoo_fb.c index 1c140873f..a97ca62a7 100644 --- a/src/video/vid_voodoo_fb.c +++ b/src/video/vid_voodoo_fb.c @@ -254,6 +254,19 @@ voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv) int colbfog_g = 0; int colbfog_b = 0; + if (params->fbzMode & FBZ_STIPPLE) { + if (params->fbzMode & FBZ_STIPPLE_PATT) { + int index = ((y & 3) << 3) | (~x & 7); + if (!(params->stipple & (1 << index))) + goto skip_pixel; + } else { + voodoo->params.stipple = (voodoo->params.stipple << 1) | (voodoo->params.stipple >> 31); + if (!(voodoo->params.stipple & 0x80000000)) { + goto skip_pixel; + } + } + } + if (params->fbzMode & FBZ_DEPTH_ENABLE) { uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); @@ -449,6 +462,19 @@ voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv) int colbfog_g = 0; int colbfog_b = 0; + if (params->fbzMode & FBZ_STIPPLE) { + if (params->fbzMode & FBZ_STIPPLE_PATT) { + int index = ((y & 3) << 3) | (~(x + c) & 7); + if (!(params->stipple & (1 << index))) + goto skip_pixel; + } else { + voodoo->params.stipple = (voodoo->params.stipple << 1) | (voodoo->params.stipple >> 31); + if (!(voodoo->params.stipple & 0x80000000)) { + goto skip_pixel; + } + } + } + if (params->fbzMode & FBZ_DEPTH_ENABLE) { uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); diff --git a/src/video/vid_voodoo_render.c b/src/video/vid_voodoo_render.c index 97186634d..b25f42507 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -88,6 +88,8 @@ typedef struct voodoo_state_t { uint32_t texBaseAddr; int lod_frac[2]; + + int stipple; } voodoo_state_t; #ifdef ENABLE_VOODOO_RENDER_LOG @@ -990,6 +992,20 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t * w_depth = 0xffff; } + if (params->fbzMode & FBZ_STIPPLE) { + if (params->fbzMode & FBZ_STIPPLE_PATT) { + int index = ((real_y & 3) << 3) | (~x & 7); + + if (!(state->stipple & (1 << index))) + goto skip_pixel; + } else { + state->stipple = (state->stipple << 1) | (state->stipple >> 31); + if (!(state->stipple & 0x80000000)) { + goto skip_pixel; + } + } + } + #if 0 w_depth = CLAMP16(w_depth); #endif @@ -1560,6 +1576,7 @@ voodoo_render_log("voodoo_triangle %i %i %i : vA %f, %f vB %f, %f vC %f, %f f if (lodbias & 0x20) lodbias |= ~0x3f; state.tmu[1].lod = LOD + (lodbias << 6); + state.stipple = params->stipple; voodoo_half_triangle(voodoo, params, &state, vertexAy_adjusted, vertexCy_adjusted, odd_even); }