diff --git a/src/sound.c b/src/sound.c index 0bb5f92..b361f35 100644 --- a/src/sound.c +++ b/src/sound.c @@ -213,7 +213,7 @@ void sound_init() outbuffer = malloc(MAXSOUNDBUFLEN * 2 * sizeof(int32_t)); sound_cd_event = thread_create_event(); - sound_cd_thread_h = thread_create(sound_cd_thread, NULL); + //sound_cd_thread_h = thread_create(sound_cd_thread, NULL); } void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 3039969..d6e69e8 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -34,21 +34,6 @@ static int dither[4][4] = {7, 3, 6, 2}, }; -#define RB_SIZE 256 -#define RB_MASK (RB_SIZE - 1) - -#define RB_ENTRIES (virge->s3d_write_idx - virge->s3d_read_idx) -#define RB_FULL (RB_ENTRIES == RB_SIZE) -#define RB_EMPTY (!RB_ENTRIES) - -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) - -#define FIFO_ENTRIES (virge->fifo_write_idx - virge->fifo_read_idx) -#define FIFO_FULL ((virge->fifo_write_idx - virge->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY (virge->fifo_read_idx == virge->fifo_write_idx) - #define FIFO_TYPE 0xff000000 #define FIFO_ADDR 0x00ffffff @@ -60,20 +45,14 @@ enum FIFO_WRITE_DWORD = (0x03 << 24), }; -typedef struct -{ - uint32_t addr_type; - uint32_t val; -} fifo_entry_t; - typedef struct s3d_t { uint32_t cmd_set; int clip_l, clip_r, clip_t, clip_b; - + uint32_t dest_base; uint32_t dest_str; - + uint32_t z_base; uint32_t z_str; @@ -89,14 +68,14 @@ typedef struct s3d_t int32_t TdWdX, TdWdY; uint32_t tws; - + int32_t TdDdX, TdDdY; uint32_t tds; - + int16_t TdGdX, TdBdX, TdRdX, TdAdX; int16_t TdGdY, TdBdY, TdRdY, TdAdY; uint32_t tgs, tbs, trs, tas; - + uint32_t TdXdY12; uint32_t txend12; uint32_t TdXdY01; @@ -106,17 +85,17 @@ typedef struct s3d_t uint32_t tys; int ty01, ty12, tlr; } s3d_t; - + typedef struct virge_t { mem_mapping_t linear_mapping; mem_mapping_t mmio_mapping; mem_mapping_t new_mmio_mapping; - + rom_t bios_rom; - + svga_t svga; - + uint8_t bank; uint8_t ma_ext; @@ -132,17 +111,12 @@ typedef struct virge_t int bilinear_enabled; int dithering_enabled; int memory_size; - + int pixel_count, tri_count; - - thread_t *render_thread; - event_t *wake_render_thread; - event_t *wake_main_thread; - event_t *not_full_event; - + uint32_t hwc_fg_col, hwc_bg_col; int hwc_col_stack_pos; - + struct { uint32_t src_base; @@ -159,21 +133,21 @@ typedef struct virge_t int r_width, r_height; int rsrc_x, rsrc_y; int rdest_x, rdest_y; - + int lxend0, lxend1; int32_t ldx; uint32_t lxstart, lystart; int lycnt; int line_dir; - + int src_x, src_y; int dest_x, dest_y; int w, h; uint8_t rop; - + int data_left_count; uint32_t data_left; - + uint32_t pattern_8[8*8]; uint32_t pattern_16[8*8]; uint32_t pattern_32[8*8]; @@ -186,13 +160,9 @@ typedef struct virge_t uint32_t pycnt; uint32_t dest_l, dest_r; } s3d; - + s3d_t s3d_tri; - s3d_t s3d_buffer[RB_SIZE]; - int s3d_read_idx, s3d_write_idx; - int s3d_busy; - struct { uint32_t pri_ctrl; @@ -218,30 +188,18 @@ typedef struct virge_t uint32_t pri_size; uint32_t sec_start; uint32_t sec_size; - + int sdif; - + int pri_x, pri_y, pri_w, pri_h; int sec_x, sec_y, sec_w, sec_h; } streams; - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; - - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; - int virge_busy; - + uint8_t subsys_stat, subsys_cntl; } virge_t; -static inline void wake_fifo_thread(virge_t *virge) -{ - thread_set_event(virge->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ -} - static void queue_triangle(virge_t *virge); static void s3_virge_recalctimings(svga_t *svga); @@ -260,29 +218,29 @@ enum { CMD_SET_AE = 1, CMD_SET_HC = (1 << 1), - + CMD_SET_FORMAT_MASK = (7 << 2), CMD_SET_FORMAT_8 = (0 << 2), CMD_SET_FORMAT_16 = (1 << 2), CMD_SET_FORMAT_24 = (2 << 2), - + CMD_SET_MS = (1 << 6), CMD_SET_IDS = (1 << 7), CMD_SET_MP = (1 << 8), CMD_SET_TP = (1 << 9), - + CMD_SET_ITA_MASK = (3 << 10), CMD_SET_ITA_BYTE = (0 << 10), CMD_SET_ITA_WORD = (1 << 10), CMD_SET_ITA_DWORD = (2 << 10), - + CMD_SET_ZUP = (1 << 23), - + CMD_SET_ZB_MODE = (3 << 24), CMD_SET_XP = (1 << 25), CMD_SET_YP = (1 << 26), - + CMD_SET_COMMAND_MASK = (15 << 27) }; @@ -320,9 +278,9 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) svga_t *svga = &virge->svga; uint8_t old; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - + // pclog("S3 out %04X %02X %04X:%08X %04X %04X %i\n", addr, val, CS, pc, ES, BX, ins); switch (addr) @@ -340,7 +298,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) else svga->write_bank = svga->read_bank = virge->bank << 14; } break; - + //case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: // pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); //sdac_ramdac_out(addr,val); @@ -355,7 +313,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) + if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) return; if (svga->crtcreg >= 0x80) return; @@ -369,11 +327,11 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) case 0x32: s3_virge_update_irqs(virge); break; - + case 0x69: virge->ma_ext = val & 0x1f; break; - + case 0x35: virge->bank = (virge->bank & 0x70) | (val & 0xf); // pclog("CRTC write R35 %02X\n", val); @@ -392,11 +350,11 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16; else svga->write_bank = svga->read_bank = virge->bank << 14; break; - + case 0x3a: if (val & 0x10) svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ break; - + case 0x45: svga->hwcursor.ena = val & 1; break; @@ -408,7 +366,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.yoff = svga->crtc[0x4f] & 63; svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); break; - + case 0x4a: switch (virge->hwc_col_stack_pos) { @@ -444,7 +402,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) case 0x58: case 0x59: case 0x5a: s3_virge_updatemapping(virge); break; - + case 0x67: switch (val >> 4) { @@ -476,8 +434,8 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; uint8_t ret; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; // if (addr != 0x3da) pclog("S3 in %04X %04X:%08X ", addr, CS, pc); @@ -488,7 +446,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) ret = 0xff; else ret = svga_in(addr, svga); - break; + break; //case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: // pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); //return sdac_ramdac_in(addr); @@ -511,7 +469,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) { case 0x2d: ret = virge->virge_id_high; break; /*Extended chip ID*/ case 0x2e: ret = virge->virge_id_low; break; /*New chip ID*/ - case 0x2f: ret = virge->virge_rev; break; + case 0x2f: ret = virge->virge_rev; break; case 0x30: ret = virge->virge_id; break; /*Chip ID*/ case 0x31: ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); break; case 0x35: ret = (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf); break; @@ -523,10 +481,10 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) default: ret = svga->crtc[svga->crtcreg]; break; } break; - + default: ret = svga_in(addr, svga); - break; + break; } // if (addr != 0x3da) pclog("%02X\n", ret); return ret; @@ -557,24 +515,24 @@ static void s3_virge_recalctimings(svga_t *svga) { switch (svga->bpp) { - case 8: - svga->render = svga_render_8bpp_highres; + case 8: + svga->render = svga_render_8bpp_highres; break; - case 15: - svga->render = svga_render_15bpp_highres; + case 15: + svga->render = svga_render_15bpp_highres; break; - case 16: - svga->render = svga_render_16bpp_highres; + case 16: + svga->render = svga_render_16bpp_highres; break; - case 24: - svga->render = svga_render_24bpp_highres; + case 24: + svga->render = svga_render_24bpp_highres; break; - case 32: - svga->render = svga_render_32bpp_highres; + case 32: + svga->render = svga_render_32bpp_highres; break; } } - + // pclog("svga->rowoffset = %i bpp=%i\n", svga->rowoffset, svga->bpp); if (svga->bpp == 15 || svga->bpp == 16) { @@ -594,11 +552,11 @@ static void s3_virge_recalctimings(svga_t *svga) svga->ma_latch = virge->streams.pri_fb1 >> 2; else svga->ma_latch = virge->streams.pri_fb0 >> 2; - + svga->hdisp = virge->streams.pri_w + 1; if (virge->streams.pri_h < svga->dispend) svga->dispend = virge->streams.pri_h; - + svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x; svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y; svga->overlay.ysize = virge->streams.sec_h; @@ -616,21 +574,21 @@ static void s3_virge_recalctimings(svga_t *svga) switch ((virge->streams.pri_ctrl >> 24) & 0x7) { case 0: /*RGB-8 (CLUT)*/ - svga->render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_highres; break; - case 3: /*KRGB-16 (1.5.5.5)*/ + case 3: /*KRGB-16 (1.5.5.5)*/ svga->htotal >>= 1; - svga->render = svga_render_15bpp_highres; + svga->render = svga_render_15bpp_highres; break; - case 5: /*RGB-16 (5.6.5)*/ + case 5: /*RGB-16 (5.6.5)*/ svga->htotal >>= 1; - svga->render = svga_render_16bpp_highres; + svga->render = svga_render_16bpp_highres; break; - case 6: /*RGB-24 (8.8.8)*/ - svga->render = svga_render_24bpp_highres; + case 6: /*RGB-24 (8.8.8)*/ + svga->render = svga_render_24bpp_highres; break; case 7: /*XRGB-32 (X.8.8.8)*/ - svga->render = svga_render_32bpp_highres; + svga->render = svga_render_32bpp_highres; break; } svga->vram_display_mask = (virge->memory_size << 20) - 1; @@ -661,7 +619,7 @@ static void s3_virge_updatemapping(virge_t *virge) return; } - pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); + pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ { case 0x0: /*128k at A0000*/ @@ -681,9 +639,9 @@ static void s3_virge_updatemapping(virge_t *virge) svga->banked_mask = 0x7fff; break; } - + virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - + pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ { @@ -719,7 +677,7 @@ static void s3_virge_updatemapping(virge_t *virge) mem_mapping_disable(&virge->linear_mapping); svga->fb_only = 0; } - + pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18); if (svga->crtc[0x53] & 0x10) /*Old MMIO*/ { @@ -746,15 +704,6 @@ static void s3_virge_vblank_start(svga_t *svga) s3_virge_update_irqs(virge); } -static void s3_virge_wait_fifo_idle(virge_t *virge) -{ - while (!FIFO_EMPTY) - { - wake_fifo_thread(virge); - thread_wait_event(virge->fifo_not_full_event, 1); - } -} - static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) { virge_t *virge = (virge_t *)p; @@ -765,14 +714,9 @@ static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) switch (addr & 0xffff) { case 0x8505: - if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) - ret = 0x10; - else - ret = 0x10 | (1 << 5); - if (!virge->virge_busy) - wake_fifo_thread(virge); + ret = 0x10 | (1 << 5); return ret; - + case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: @@ -874,78 +818,58 @@ static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) case 0x81fc: ret = virge->streams.sec_size; break; - + case 0x8504: - if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) - ret = (0x10 << 8); - else - ret = (0x10 << 8) | (1 << 13); + ret = (0x10 << 8) | (1 << 13); ret |= virge->subsys_stat; - if (!virge->virge_busy) - wake_fifo_thread(virge); // pclog("Read status %04x %i\n", ret, virge->s3d_busy); break; case 0xa4d4: - s3_virge_wait_fifo_idle(virge); ret = virge->s3d.src_base; break; case 0xa4d8: - s3_virge_wait_fifo_idle(virge); ret = virge->s3d.dest_base; break; case 0xa4dc: - s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r; break; case 0xa4e0: - s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b; break; case 0xa4e4: - s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str; break; case 0xa4e8: case 0xace8: - s3_virge_wait_fifo_idle(virge); ret = virge->s3d.mono_pat_0; break; case 0xa4ec: case 0xacec: - s3_virge_wait_fifo_idle(virge); ret = virge->s3d.mono_pat_1; break; case 0xa4f0: - s3_virge_wait_fifo_idle(virge); ret = virge->s3d.pat_bg_clr; break; case 0xa4f4: - s3_virge_wait_fifo_idle(virge); ret = virge->s3d.pat_fg_clr; break; case 0xa4f8: - s3_virge_wait_fifo_idle(virge); ret = virge->s3d.src_bg_clr; break; case 0xa4fc: - s3_virge_wait_fifo_idle(virge); ret = virge->s3d.src_fg_clr; break; case 0xa500: - s3_virge_wait_fifo_idle(virge); ret = virge->s3d.cmd_set; break; case 0xa504: - s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.r_width << 16) | virge->s3d.r_height; break; case 0xa508: - s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y; break; case 0xa50c: - s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; break; - + default: ret = s3_virge_mmio_read_w(addr, p) | (s3_virge_mmio_read_w(addr + 2, p) << 16); } @@ -953,388 +877,345 @@ static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) return ret; } -static void fifo_thread(void *param) +static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type) { - virge_t *virge = (virge_t *)param; - - while (1) + uint64_t start_time = timer_read(); + uint64_t end_time; + uint32_t addr_type = (addr & FIFO_ADDR) | type; + + switch (addr_type & FIFO_TYPE) { - thread_set_event(virge->fifo_not_full_event); - thread_wait_event(virge->wake_fifo_thread, -1); - thread_reset_event(virge->wake_fifo_thread); - virge->virge_busy = 1; - while (!FIFO_EMPTY) + case FIFO_WRITE_BYTE: + if (((addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) + s3_virge_bitblt(virge, 8, val); + break; + case FIFO_WRITE_WORD: + if (((addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) { - uint64_t start_time = timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK]; - uint32_t val = fifo->val; - - switch (fifo->addr_type & FIFO_TYPE) + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); + else + s3_virge_bitblt(virge, 16, val); + } + break; + case FIFO_WRITE_DWORD: + if (((addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) + { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); + else + s3_virge_bitblt(virge, 32, val); + } + else + { + switch ((addr_type & FIFO_ADDR) & 0xfffc) { - case FIFO_WRITE_BYTE: - if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) - s3_virge_bitblt(virge, 8, val); - break; - case FIFO_WRITE_WORD: - if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) + case 0xa000: case 0xa004: case 0xa008: case 0xa00c: + case 0xa010: case 0xa014: case 0xa018: case 0xa01c: + case 0xa020: case 0xa024: case 0xa028: case 0xa02c: + case 0xa030: case 0xa034: case 0xa038: case 0xa03c: + case 0xa040: case 0xa044: case 0xa048: case 0xa04c: + case 0xa050: case 0xa054: case 0xa058: case 0xa05c: + case 0xa060: case 0xa064: case 0xa068: case 0xa06c: + case 0xa070: case 0xa074: case 0xa078: case 0xa07c: + case 0xa080: case 0xa084: case 0xa088: case 0xa08c: + case 0xa090: case 0xa094: case 0xa098: case 0xa09c: + case 0xa0a0: case 0xa0a4: case 0xa0a8: case 0xa0ac: + case 0xa0b0: case 0xa0b4: case 0xa0b8: case 0xa0bc: + case 0xa0c0: case 0xa0c4: case 0xa0c8: case 0xa0cc: + case 0xa0d0: case 0xa0d4: case 0xa0d8: case 0xa0dc: + case 0xa0e0: case 0xa0e4: case 0xa0e8: case 0xa0ec: + case 0xa0f0: case 0xa0f4: case 0xa0f8: case 0xa0fc: + case 0xa100: case 0xa104: case 0xa108: case 0xa10c: + case 0xa110: case 0xa114: case 0xa118: case 0xa11c: + case 0xa120: case 0xa124: case 0xa128: case 0xa12c: + case 0xa130: case 0xa134: case 0xa138: case 0xa13c: + case 0xa140: case 0xa144: case 0xa148: case 0xa14c: + case 0xa150: case 0xa154: case 0xa158: case 0xa15c: + case 0xa160: case 0xa164: case 0xa168: case 0xa16c: + case 0xa170: case 0xa174: case 0xa178: case 0xa17c: + case 0xa180: case 0xa184: case 0xa188: case 0xa18c: + case 0xa190: case 0xa194: case 0xa198: case 0xa19c: + case 0xa1a0: case 0xa1a4: case 0xa1a8: case 0xa1ac: + case 0xa1b0: case 0xa1b4: case 0xa1b8: case 0xa1bc: + case 0xa1c0: case 0xa1c4: case 0xa1c8: case 0xa1cc: + case 0xa1d0: case 0xa1d4: case 0xa1d8: case 0xa1dc: + case 0xa1e0: case 0xa1e4: case 0xa1e8: case 0xa1ec: + case 0xa1f0: case 0xa1f4: case 0xa1f8: case 0xa1fc: { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); - else - s3_virge_bitblt(virge, 16, val); + int x = (addr_type & FIFO_ADDR) & 4; + int y = ((addr_type & FIFO_ADDR) >> 3) & 7; + virge->s3d.pattern_8[y*8 + x] = val & 0xff; + virge->s3d.pattern_8[y*8 + x + 1] = val >> 8; + virge->s3d.pattern_8[y*8 + x + 2] = val >> 16; + virge->s3d.pattern_8[y*8 + x + 3] = val >> 24; + + x = ((addr_type & FIFO_ADDR) >> 1) & 6; + y = ((addr_type & FIFO_ADDR) >> 4) & 7; + virge->s3d.pattern_16[y*8 + x] = val & 0xffff; + virge->s3d.pattern_16[y*8 + x + 1] = val >> 16; + + x = ((addr_type & FIFO_ADDR) >> 2) & 7; + y = ((addr_type & FIFO_ADDR) >> 5) & 7; + virge->s3d.pattern_32[y*8 + x] = val & 0xffffff; } break; - case FIFO_WRITE_DWORD: - if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) - { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); - else - s3_virge_bitblt(virge, 32, val); - } - else - { - switch ((fifo->addr_type & FIFO_ADDR) & 0xfffc) - { - case 0xa000: case 0xa004: case 0xa008: case 0xa00c: - case 0xa010: case 0xa014: case 0xa018: case 0xa01c: - case 0xa020: case 0xa024: case 0xa028: case 0xa02c: - case 0xa030: case 0xa034: case 0xa038: case 0xa03c: - case 0xa040: case 0xa044: case 0xa048: case 0xa04c: - case 0xa050: case 0xa054: case 0xa058: case 0xa05c: - case 0xa060: case 0xa064: case 0xa068: case 0xa06c: - case 0xa070: case 0xa074: case 0xa078: case 0xa07c: - case 0xa080: case 0xa084: case 0xa088: case 0xa08c: - case 0xa090: case 0xa094: case 0xa098: case 0xa09c: - case 0xa0a0: case 0xa0a4: case 0xa0a8: case 0xa0ac: - case 0xa0b0: case 0xa0b4: case 0xa0b8: case 0xa0bc: - case 0xa0c0: case 0xa0c4: case 0xa0c8: case 0xa0cc: - case 0xa0d0: case 0xa0d4: case 0xa0d8: case 0xa0dc: - case 0xa0e0: case 0xa0e4: case 0xa0e8: case 0xa0ec: - case 0xa0f0: case 0xa0f4: case 0xa0f8: case 0xa0fc: - case 0xa100: case 0xa104: case 0xa108: case 0xa10c: - case 0xa110: case 0xa114: case 0xa118: case 0xa11c: - case 0xa120: case 0xa124: case 0xa128: case 0xa12c: - case 0xa130: case 0xa134: case 0xa138: case 0xa13c: - case 0xa140: case 0xa144: case 0xa148: case 0xa14c: - case 0xa150: case 0xa154: case 0xa158: case 0xa15c: - case 0xa160: case 0xa164: case 0xa168: case 0xa16c: - case 0xa170: case 0xa174: case 0xa178: case 0xa17c: - case 0xa180: case 0xa184: case 0xa188: case 0xa18c: - case 0xa190: case 0xa194: case 0xa198: case 0xa19c: - case 0xa1a0: case 0xa1a4: case 0xa1a8: case 0xa1ac: - case 0xa1b0: case 0xa1b4: case 0xa1b8: case 0xa1bc: - case 0xa1c0: case 0xa1c4: case 0xa1c8: case 0xa1cc: - case 0xa1d0: case 0xa1d4: case 0xa1d8: case 0xa1dc: - case 0xa1e0: case 0xa1e4: case 0xa1e8: case 0xa1ec: - case 0xa1f0: case 0xa1f4: case 0xa1f8: case 0xa1fc: - { - int x = (fifo->addr_type & FIFO_ADDR) & 4; - int y = ((fifo->addr_type & FIFO_ADDR) >> 3) & 7; - virge->s3d.pattern_8[y*8 + x] = val & 0xff; - virge->s3d.pattern_8[y*8 + x + 1] = val >> 8; - virge->s3d.pattern_8[y*8 + x + 2] = val >> 16; - virge->s3d.pattern_8[y*8 + x + 3] = val >> 24; - - x = ((fifo->addr_type & FIFO_ADDR) >> 1) & 6; - y = ((fifo->addr_type & FIFO_ADDR) >> 4) & 7; - virge->s3d.pattern_16[y*8 + x] = val & 0xffff; - virge->s3d.pattern_16[y*8 + x + 1] = val >> 16; - - x = ((fifo->addr_type & FIFO_ADDR) >> 2) & 7; - y = ((fifo->addr_type & FIFO_ADDR) >> 5) & 7; - virge->s3d.pattern_32[y*8 + x] = val & 0xffffff; - } - break; - case 0xa4d4: case 0xa8d4: - virge->s3d.src_base = val & 0x3ffff8; - break; - case 0xa4d8: case 0xa8d8: - virge->s3d.dest_base = val & 0x3ffff8; - break; - case 0xa4dc: case 0xa8dc: - virge->s3d.clip_l = (val >> 16) & 0x7ff; - virge->s3d.clip_r = val & 0x7ff; - break; - case 0xa4e0: case 0xa8e0: - virge->s3d.clip_t = (val >> 16) & 0x7ff; - virge->s3d.clip_b = val & 0x7ff; - break; - case 0xa4e4: case 0xa8e4: - virge->s3d.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xa4e8: case 0xace8: - virge->s3d.mono_pat_0 = val; - break; - case 0xa4ec: case 0xacec: - virge->s3d.mono_pat_1 = val; - break; - case 0xa4f0: case 0xacf0: - virge->s3d.pat_bg_clr = val; - break; - case 0xa4f4: case 0xa8f4: case 0xacf4: - virge->s3d.pat_fg_clr = val; - break; - case 0xa4f8: - virge->s3d.src_bg_clr = val; - break; - case 0xa4fc: - virge->s3d.src_fg_clr = val; - break; - case 0xa500: case 0xa900: - virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xa504: - virge->s3d.r_width = (val >> 16) & 0x7ff; - virge->s3d.r_height = val & 0x7ff; - break; - case 0xa508: - virge->s3d.rsrc_x = (val >> 16) & 0x7ff; - virge->s3d.rsrc_y = val & 0x7ff; - break; - case 0xa50c: - virge->s3d.rdest_x = (val >> 16) & 0x7ff; - virge->s3d.rdest_y = val & 0x7ff; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xa96c: - virge->s3d.lxend0 = (val >> 16) & 0x7ff; - virge->s3d.lxend1 = val & 0x7ff; - break; - case 0xa970: - virge->s3d.ldx = (int32_t)val; - break; - case 0xa974: - virge->s3d.lxstart = val; - break; - case 0xa978: - virge->s3d.lystart = val & 0x7ff; - break; - case 0xa97c: - virge->s3d.lycnt = val & 0x7ff; - virge->s3d.line_dir = val >> 31; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; - - case 0xad00: - virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xad68: - virge->s3d.prdx = val; - break; - case 0xad6c: - virge->s3d.prxstart = val; - break; - case 0xad70: - virge->s3d.pldx = val; - break; - case 0xad74: - virge->s3d.plxstart = val; - break; - case 0xad78: - virge->s3d.pystart = val & 0x7ff; - break; - case 0xad7c: - virge->s3d.pycnt = val & 0x300007ff; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; - - case 0xb4d4: - virge->s3d_tri.z_base = val & 0x3ffff8; - break; - case 0xb4d8: - virge->s3d_tri.dest_base = val & 0x3ffff8; - break; - case 0xb4dc: - virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_r = val & 0x7ff; - break; - case 0xb4e0: - virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_b = val & 0x7ff; - break; - case 0xb4e4: - virge->s3d_tri.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xb4e8: - virge->s3d_tri.z_str = val & 0xff8; - break; - case 0xb4ec: - virge->s3d_tri.tex_base = val & 0x3ffff8; - break; - case 0xb4f0: - virge->s3d_tri.tex_bdr_clr = val & 0xffffff; - break; - case 0xb500: - virge->s3d_tri.cmd_set = val; - if (!(val & CMD_SET_AE)) - queue_triangle(virge); - break; - case 0xb504: - virge->s3d_tri.tbv = val & 0xfffff; - break; - case 0xb508: - virge->s3d_tri.tbu = val & 0xfffff; - break; - case 0xb50c: - virge->s3d_tri.TdWdX = val; - break; - case 0xb510: - virge->s3d_tri.TdWdY = val; - break; - case 0xb514: - virge->s3d_tri.tws = val; - break; - case 0xb518: - virge->s3d_tri.TdDdX = val; - break; - case 0xb51c: - virge->s3d_tri.TdVdX = val; - break; - case 0xb520: - virge->s3d_tri.TdUdX = val; - break; - case 0xb524: - virge->s3d_tri.TdDdY = val; - break; - case 0xb528: - virge->s3d_tri.TdVdY = val; - break; - case 0xb52c: - virge->s3d_tri.TdUdY = val; - break; - case 0xb530: - virge->s3d_tri.tds = val; - break; - case 0xb534: - virge->s3d_tri.tvs = val; - break; - case 0xb538: - virge->s3d_tri.tus = val; - break; - case 0xb53c: - virge->s3d_tri.TdGdX = val >> 16; - virge->s3d_tri.TdBdX = val & 0xffff; - break; - case 0xb540: - virge->s3d_tri.TdAdX = val >> 16; - virge->s3d_tri.TdRdX = val & 0xffff; - break; - case 0xb544: - virge->s3d_tri.TdGdY = val >> 16; - virge->s3d_tri.TdBdY = val & 0xffff; - break; - case 0xb548: - virge->s3d_tri.TdAdY = val >> 16; - virge->s3d_tri.TdRdY = val & 0xffff; - break; - case 0xb54c: - virge->s3d_tri.tgs = (val >> 16) & 0xffff; - virge->s3d_tri.tbs = val & 0xffff; - break; - case 0xb550: - virge->s3d_tri.tas = (val >> 16) & 0xffff; - virge->s3d_tri.trs = val & 0xffff; - break; - - case 0xb554: - virge->s3d_tri.TdZdX = val; - break; - case 0xb558: - virge->s3d_tri.TdZdY = val; - break; - case 0xb55c: - virge->s3d_tri.tzs = val; - break; - case 0xb560: - virge->s3d_tri.TdXdY12 = val; - break; - case 0xb564: - virge->s3d_tri.txend12 = val; - break; - case 0xb568: - virge->s3d_tri.TdXdY01 = val; - break; - case 0xb56c: - virge->s3d_tri.txend01 = val; - break; - case 0xb570: - virge->s3d_tri.TdXdY02 = val; - break; - case 0xb574: - virge->s3d_tri.txs = val; - break; - case 0xb578: - virge->s3d_tri.tys = val; - break; - case 0xb57c: - virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; - virge->s3d_tri.ty12 = val & 0x7ff; - virge->s3d_tri.tlr = val >> 31; - if (virge->s3d_tri.cmd_set & CMD_SET_AE) - queue_triangle(virge); - break; - } - } + case 0xa4d4: case 0xa8d4: + virge->s3d.src_base = val & 0x3ffff8; + break; + case 0xa4d8: case 0xa8d8: + virge->s3d.dest_base = val & 0x3ffff8; + break; + case 0xa4dc: case 0xa8dc: + virge->s3d.clip_l = (val >> 16) & 0x7ff; + virge->s3d.clip_r = val & 0x7ff; + break; + case 0xa4e0: case 0xa8e0: + virge->s3d.clip_t = (val >> 16) & 0x7ff; + virge->s3d.clip_b = val & 0x7ff; + break; + case 0xa4e4: case 0xa8e4: + virge->s3d.dest_str = (val >> 16) & 0xff8; + virge->s3d.src_str = val & 0xff8; + break; + case 0xa4e8: case 0xace8: + virge->s3d.mono_pat_0 = val; + break; + case 0xa4ec: case 0xacec: + virge->s3d.mono_pat_1 = val; + break; + case 0xa4f0: case 0xacf0: + virge->s3d.pat_bg_clr = val; + break; + case 0xa4f4: case 0xa8f4: case 0xacf4: + virge->s3d.pat_fg_clr = val; + break; + case 0xa4f8: + virge->s3d.src_bg_clr = val; + break; + case 0xa4fc: + virge->s3d.src_fg_clr = val; + break; + case 0xa500: case 0xa900: + virge->s3d.cmd_set = val; + if (!(val & CMD_SET_AE)) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xa504: + virge->s3d.r_width = (val >> 16) & 0x7ff; + virge->s3d.r_height = val & 0x7ff; + break; + case 0xa508: + virge->s3d.rsrc_x = (val >> 16) & 0x7ff; + virge->s3d.rsrc_y = val & 0x7ff; + break; + case 0xa50c: + virge->s3d.rdest_x = (val >> 16) & 0x7ff; + virge->s3d.rdest_y = val & 0x7ff; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xa96c: + virge->s3d.lxend0 = (val >> 16) & 0x7ff; + virge->s3d.lxend1 = val & 0x7ff; + break; + case 0xa970: + virge->s3d.ldx = (int32_t)val; + break; + case 0xa974: + virge->s3d.lxstart = val; + break; + case 0xa978: + virge->s3d.lystart = val & 0x7ff; + break; + case 0xa97c: + virge->s3d.lycnt = val & 0x7ff; + virge->s3d.line_dir = val >> 31; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); break; - } - - virge->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(virge->fifo_not_full_event); - end_time = timer_read(); - virge_time += end_time - start_time; - } - virge->virge_busy = 0; - virge->subsys_stat |= INT_FIFO_EMP | INT_3DF_EMP; - s3_virge_update_irqs(virge); - } -} + case 0xad00: + virge->s3d.cmd_set = val; + if (!(val & CMD_SET_AE)) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xad68: + virge->s3d.prdx = val; + break; + case 0xad6c: + virge->s3d.prxstart = val; + break; + case 0xad70: + virge->s3d.pldx = val; + break; + case 0xad74: + virge->s3d.plxstart = val; + break; + case 0xad78: + virge->s3d.pystart = val & 0x7ff; + break; + case 0xad7c: + virge->s3d.pycnt = val & 0x300007ff; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; -static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type) -{ - fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx & FIFO_MASK]; + case 0xb4d4: + virge->s3d_tri.z_base = val & 0x3ffff8; + break; + case 0xb4d8: + virge->s3d_tri.dest_base = val & 0x3ffff8; + break; + case 0xb4dc: + virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; + virge->s3d_tri.clip_r = val & 0x7ff; + break; + case 0xb4e0: + virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; + virge->s3d_tri.clip_b = val & 0x7ff; + break; + case 0xb4e4: + virge->s3d_tri.dest_str = (val >> 16) & 0xff8; + virge->s3d.src_str = val & 0xff8; + break; + case 0xb4e8: + virge->s3d_tri.z_str = val & 0xff8; + break; + case 0xb4ec: + virge->s3d_tri.tex_base = val & 0x3ffff8; + break; + case 0xb4f0: + virge->s3d_tri.tex_bdr_clr = val & 0xffffff; + break; + case 0xb500: + virge->s3d_tri.cmd_set = val; + if (!(val & CMD_SET_AE)) + queue_triangle(virge); + break; + case 0xb504: + virge->s3d_tri.tbv = val & 0xfffff; + break; + case 0xb508: + virge->s3d_tri.tbu = val & 0xfffff; + break; + case 0xb50c: + virge->s3d_tri.TdWdX = val; + break; + case 0xb510: + virge->s3d_tri.TdWdY = val; + break; + case 0xb514: + virge->s3d_tri.tws = val; + break; + case 0xb518: + virge->s3d_tri.TdDdX = val; + break; + case 0xb51c: + virge->s3d_tri.TdVdX = val; + break; + case 0xb520: + virge->s3d_tri.TdUdX = val; + break; + case 0xb524: + virge->s3d_tri.TdDdY = val; + break; + case 0xb528: + virge->s3d_tri.TdVdY = val; + break; + case 0xb52c: + virge->s3d_tri.TdUdY = val; + break; + case 0xb530: + virge->s3d_tri.tds = val; + break; + case 0xb534: + virge->s3d_tri.tvs = val; + break; + case 0xb538: + virge->s3d_tri.tus = val; + break; + case 0xb53c: + virge->s3d_tri.TdGdX = val >> 16; + virge->s3d_tri.TdBdX = val & 0xffff; + break; + case 0xb540: + virge->s3d_tri.TdAdX = val >> 16; + virge->s3d_tri.TdRdX = val & 0xffff; + break; + case 0xb544: + virge->s3d_tri.TdGdY = val >> 16; + virge->s3d_tri.TdBdY = val & 0xffff; + break; + case 0xb548: + virge->s3d_tri.TdAdY = val >> 16; + virge->s3d_tri.TdRdY = val & 0xffff; + break; + case 0xb54c: + virge->s3d_tri.tgs = (val >> 16) & 0xffff; + virge->s3d_tri.tbs = val & 0xffff; + break; + case 0xb550: + virge->s3d_tri.tas = (val >> 16) & 0xffff; + virge->s3d_tri.trs = val & 0xffff; + break; - if (FIFO_FULL) - { - thread_reset_event(virge->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + case 0xb554: + virge->s3d_tri.TdZdX = val; + break; + case 0xb558: + virge->s3d_tri.TdZdY = val; + break; + case 0xb55c: + virge->s3d_tri.tzs = val; + break; + case 0xb560: + virge->s3d_tri.TdXdY12 = val; + break; + case 0xb564: + virge->s3d_tri.txend12 = val; + break; + case 0xb568: + virge->s3d_tri.TdXdY01 = val; + break; + case 0xb56c: + virge->s3d_tri.txend01 = val; + break; + case 0xb570: + virge->s3d_tri.TdXdY02 = val; + break; + case 0xb574: + virge->s3d_tri.txs = val; + break; + case 0xb578: + virge->s3d_tri.tys = val; + break; + case 0xb57c: + virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; + virge->s3d_tri.ty12 = val & 0x7ff; + virge->s3d_tri.tlr = val >> 31; + if (virge->s3d_tri.cmd_set & CMD_SET_AE) + queue_triangle(virge); + break; + } } + break; } - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; + end_time = timer_read(); + virge_time += end_time - start_time; - virge->fifo_write_idx++; - - if (FIFO_ENTRIES > 0xe000) - wake_fifo_thread(virge); - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(virge); + virge->subsys_stat |= INT_FIFO_EMP | INT_3DF_EMP; + s3_virge_update_irqs(virge); } static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) { virge_t *virge = (virge_t *)p; - + // pclog("New MMIO writeb %08X %02X %04x(%08x):%08x\n", addr, val, CS, cs, pc); - reg_writes++; + reg_writes++; if ((addr & 0xfffc) < 0x8000) { s3_virge_queue(virge, addr, val, FIFO_WRITE_BYTE); @@ -1357,7 +1238,7 @@ static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) break; } - + } static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) { @@ -1367,7 +1248,7 @@ static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) if ((addr & 0xfffc) < 0x8000) { s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD); - } + } else switch (addr & 0xfffe) { case 0x83d4: @@ -1486,38 +1367,38 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) case 0x81f0: virge->streams.pri_start = val; virge->streams.pri_x = (val >> 16) & 0x7ff; - virge->streams.pri_y = val & 0x7ff; + virge->streams.pri_y = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81f4: virge->streams.pri_size = val; virge->streams.pri_w = (val >> 16) & 0x7ff; - virge->streams.pri_h = val & 0x7ff; + virge->streams.pri_h = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81f8: virge->streams.sec_start = val; virge->streams.sec_x = (val >> 16) & 0x7ff; - virge->streams.sec_y = val & 0x7ff; + virge->streams.sec_y = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81fc: virge->streams.sec_size = val; virge->streams.sec_w = (val >> 16) & 0x7ff; - virge->streams.sec_h = val & 0x7ff; + virge->streams.sec_h = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; - + case 0x8504: virge->subsys_stat &= ~(val & 0xff); virge->subsys_cntl = (val >> 8); s3_virge_update_irqs(virge); break; - + case 0xa000: case 0xa004: case 0xa008: case 0xa00c: case 0xa010: case 0xa014: case 0xa018: case 0xa01c: case 0xa020: case 0xa024: case 0xa028: case 0xa02c: @@ -1557,7 +1438,7 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) virge->s3d.pattern_8[y*8 + x + 1] = val >> 8; virge->s3d.pattern_8[y*8 + x + 2] = val >> 16; virge->s3d.pattern_8[y*8 + x + 3] = val >> 24; - + x = (addr >> 1) & 6; y = (addr >> 4) & 7; virge->s3d.pattern_16[y*8 + x] = val & 0xffff; @@ -1669,7 +1550,7 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) if (virge->s3d.cmd_set & CMD_SET_AE) s3_virge_bitblt(virge, -1, 0); break; - + case 0xb4d4: virge->s3d_tri.z_base = val & 0x3ffff8; break; @@ -1701,11 +1582,6 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) virge->s3d_tri.cmd_set = val; if (!(val & CMD_SET_AE)) queue_triangle(virge); -/* { - thread_set_event(virge->wake_render_thread); - thread_wait_event(virge->wake_main_thread, -1); - } */ -// s3_virge_triangle(virge); break; case 0xb504: virge->s3d_tri.tbv = val & 0xfffff; @@ -1773,7 +1649,7 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) virge->s3d_tri.tas = (val >> 16) & 0xffff; virge->s3d_tri.trs = val & 0xffff; break; - + case 0xb554: virge->s3d_tri.TdZdX = val; break; @@ -1810,12 +1686,6 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) virge->s3d_tri.tlr = val >> 31; if (virge->s3d_tri.cmd_set & CMD_SET_AE) queue_triangle(virge); -/* { - thread_set_event(virge->wake_render_thread); - thread_wait_event(virge->wake_main_thread, -1); - }*/ - -// s3_virge_triangle(virge); break; } } @@ -1879,7 +1749,7 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) case 7: update = 1; Zzb = Zs; break; \ } \ } while (0) - + #define MIX() \ do \ { \ @@ -1927,7 +1797,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) int cpu_dat_shift; uint32_t *pattern_data; uint32_t src_fg_clr, src_bg_clr; - + switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) { case CMD_SET_FORMAT_8: @@ -1958,7 +1828,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) } if (virge->s3d.cmd_set & CMD_SET_MP) pattern_data = mono_pattern; - + switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK) { case CMD_SET_ITA_BYTE: @@ -1994,7 +1864,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) { case CMD_SET_COMMAND_NOP: break; - + case CMD_SET_COMMAND_BITBLT: if (count == -1) { @@ -2006,7 +1876,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.h = virge->s3d.r_height; virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; virge->s3d.data_left_count = 0; - + /* pclog("BitBlt start %i,%i %i,%i %i,%i %02X %x %x\n", virge->s3d.src_x, virge->s3d.src_y, @@ -2017,7 +1887,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.rop, virge->s3d.src_base, virge->s3d.dest_base);*/ - + if (virge->s3d.cmd_set & CMD_SET_IDS) return; } @@ -2089,7 +1959,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) WRITE(dest_addr, out); } - + virge->s3d.src_x += x_inc; virge->s3d.src_x &= 0x7ff; virge->s3d.dest_x += x_inc; @@ -2103,7 +1973,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.src_y += y_inc; virge->s3d.dest_y += y_inc; virge->s3d.h--; - + switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) { case CMD_SET_IDS: @@ -2123,10 +1993,10 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) } } else - virge->s3d.w--; + virge->s3d.w--; } break; - + case CMD_SET_COMMAND_RECTFILL: /*No source, pattern = pat_fg_clr*/ if (count == -1) @@ -2138,7 +2008,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.w = virge->s3d.r_width; virge->s3d.h = virge->s3d.r_height; virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - + /* pclog("RctFll start %i,%i %i,%i %02X %08x\n", virge->s3d.dest_x, virge->s3d.dest_y, virge->s3d.w, @@ -2183,11 +2053,11 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) } } else - virge->s3d.w--; + virge->s3d.w--; count--; } break; - + case CMD_SET_COMMAND_LINE: if (count == -1) { @@ -2201,7 +2071,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) int x; int new_x; int first_pixel = 1; - + x = virge->s3d.dest_x >> 20; if (virge->s3d.h == virge->s3d.lycnt && @@ -2214,11 +2084,11 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) else new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20; - + if ((virge->s3d.line_dir && x > new_x) || (!virge->s3d.line_dir && x < new_x)) goto skip_line; - + do { uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); @@ -2247,7 +2117,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) WRITE(dest_addr, out); } - + if (x < new_x) x++; else if (x > new_x) @@ -2295,7 +2165,7 @@ skip_line: WRITE(dest_addr, out); } - + x = (x + xdir) & 0x7ff; } while (x != (xend + xdir)); @@ -2344,21 +2214,21 @@ typedef struct s3d_state_t int32_t r, g, b, a, u, v, d, w; int32_t base_r, base_g, base_b, base_a, base_u, base_v, base_d, base_w; - + uint32_t base_z; uint32_t tbu, tbv; uint32_t cmd_set; int max_d; - + uint16_t *texture[10]; - + uint32_t tex_bdr_clr; - + int32_t x1, x2; int y; - + rgba_t dest_rgba; } s3d_state_t; @@ -2366,7 +2236,7 @@ typedef struct s3d_texture_state_t { int level; int texture_shift; - + int32_t u, v; } s3d_texture_state_t; @@ -2462,7 +2332,7 @@ static void tex_ARGB8888_nowrap(s3d_state_t *state, s3d_texture_state_t *texture static void tex_sample_normal(s3d_state_t *state) { s3d_texture_state_t texture_state; - + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); texture_state.u = state->u + state->tbu; @@ -2500,12 +2370,12 @@ static void tex_sample_normal_filter(s3d_state_t *state) texture_state.u = state->u + state->tbu + tex_offset; texture_state.v = state->v + state->tbv + tex_offset; tex_read(state, &texture_state, &tex_samples[3]); - + d[0] = (256 - du) * (256 - dv); d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2539,7 +2409,7 @@ static void tex_sample_mipmap_filter(s3d_state_t *state) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; - + texture_state.u = state->u + state->tbu; texture_state.v = state->v + state->tbv; tex_read(state, &texture_state, &tex_samples[0]); @@ -2562,7 +2432,7 @@ static void tex_sample_mipmap_filter(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2576,9 +2446,9 @@ static void tex_sample_persp_normal(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.texture_shift = 18 + (9 - texture_state.level); texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; @@ -2603,7 +2473,7 @@ static void tex_sample_persp_normal_filter(s3d_state_t *state) texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; - + texture_state.u = u; texture_state.v = v; tex_read(state, &texture_state, &tex_samples[0]); @@ -2626,7 +2496,7 @@ static void tex_sample_persp_normal_filter(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2640,9 +2510,9 @@ static void tex_sample_persp_normal_375(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.texture_shift = 18 + (9 - texture_state.level); texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; @@ -2663,7 +2533,7 @@ static void tex_sample_persp_normal_filter_375(s3d_state_t *state) u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; @@ -2690,7 +2560,7 @@ static void tex_sample_persp_normal_filter_375(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2705,7 +2575,7 @@ static void tex_sample_persp_mipmap(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; @@ -2730,7 +2600,7 @@ static void tex_sample_persp_mipmap_filter(s3d_state_t *state) u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; @@ -2759,7 +2629,7 @@ static void tex_sample_persp_mipmap_filter(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2773,7 +2643,7 @@ static void tex_sample_persp_mipmap_375(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; @@ -2798,13 +2668,13 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; - + texture_state.u = u; texture_state.v = v; tex_read(state, &texture_state, &tex_samples[0]); @@ -2827,7 +2697,7 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2851,7 +2721,7 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) b = ((b) < 0) ? 0 : 0xff; \ if ((a) & ~0xff) \ a = ((a) < 0) ? 0 : 0xff; - + #define CLAMP_RGB(r, g, b) do \ { \ if ((r) < 0) \ @@ -2916,11 +2786,11 @@ static void dest_pixel_lit_texture_reflection(s3d_state_t *state) static void dest_pixel_lit_texture_modulate(s3d_state_t *state) { int r = state->r >> 7, g = state->g >> 7, b = state->b >> 7, a = state->a >> 7; - + tex_sample(state); - + CLAMP_RGBA(r, g, b, a); - + state->dest_rgba.r = ((state->dest_rgba.r) * r) >> 8; state->dest_rgba.g = ((state->dest_rgba.g) * g) >> 8; state->dest_rgba.b = ((state->dest_rgba.b) * b) >> 8; @@ -2935,13 +2805,13 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 uint8_t *vram = virge->svga.vram; int x_dir = s3d_tri->tlr ? 1 : -1; - + int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE); int y_count = yc; - + int bpp = (s3d_tri->cmd_set >> 2) & 7; - + uint32_t dest_offset, z_offset; dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str); @@ -2954,10 +2824,10 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (state->y > s3d_tri->clip_b) { int diff_y = state->y - s3d_tri->clip_b; - + if (diff_y > y_count) diff_y = y_count; - + state->base_u += (s3d_tri->TdUdY * diff_y); state->base_v += (s3d_tri->TdVdY * diff_y); state->base_z += (s3d_tri->TdZdY * diff_y); @@ -2977,7 +2847,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if ((state->y - y_count) < s3d_tri->clip_t) y_count = state->y - s3d_tri->clip_t; } - + for (; y_count > 0; y_count--) { int x = (state->x1 + ((1 << 20) - 1)) >> 20; @@ -3022,7 +2892,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (x < s3d_tri->clip_l) { int diff_x = s3d_tri->clip_l - x; - + z += (s3d_tri->TdZdX * diff_x); state->u += (s3d_tri->TdUdX * diff_x); state->v += (s3d_tri->TdVdX * diff_x); @@ -3032,7 +2902,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 state->a += (s3d_tri->TdAdX * diff_x); state->d += (s3d_tri->TdDdX * diff_x); state->w += (s3d_tri->TdWdX * diff_x); - + x = s3d_tri->clip_l; } } @@ -3047,7 +2917,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (x > s3d_tri->clip_r) { int diff_x = x - s3d_tri->clip_r; - + z += (s3d_tri->TdZdX * diff_x); state->u += (s3d_tri->TdUdX * diff_x); state->v += (s3d_tri->TdVdX * diff_x); @@ -3057,7 +2927,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 state->a += (s3d_tri->TdAdX * diff_x); state->d += (s3d_tri->TdDdX * diff_x); state->w += (s3d_tri->TdWdX * diff_x); - + x = s3d_tri->clip_r; } } @@ -3090,7 +2960,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 { uint32_t src_col; int src_r = 0, src_g = 0, src_b = 0; - + switch (bpp) { case 0: /*8 bpp*/ @@ -3113,7 +2983,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 switch (bpp) { - case 0: /*8 bpp*/ + case 0: /*8 bpp*/ /*Not implemented yet*/ break; case 1: /*16 bpp*/ @@ -3188,11 +3058,11 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) state.tbu = s3d_tri->tbu << 11; state.tbv = s3d_tri->tbv << 11; - + state.max_d = (s3d_tri->cmd_set >> 8) & 15; - + state.tex_bdr_clr = s3d_tri->tex_bdr_clr; - + state.cmd_set = s3d_tri->cmd_set; state.base_u = s3d_tri->tus; @@ -3204,7 +3074,7 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) state.base_a = (int32_t)s3d_tri->tas; state.base_d = s3d_tri->tds; state.base_w = s3d_tri->tws; - + tex_base = s3d_tri->tex_base; for (c = 9; c >= 0; c--) { @@ -3248,8 +3118,8 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) default: pclog("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); return; - } - + } + switch (((s3d_tri->cmd_set >> 12) & 7) | ((s3d_tri->cmd_set & (1 << 29)) ? 8 : 0)) { case 0: case 1: @@ -3297,7 +3167,7 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) // pclog("use tex_sample_persp_normal_filter\n"); break; } - + switch ((s3d_tri->cmd_set >> 5) & 7) { case 0: @@ -3316,7 +3186,7 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; break; } - + // pclog("Triangle %i %i,%i to %i,%i %08x\n", y, x1 >> 20, y, s3d_tri->txend01 >> 20, y - (s3d_tri->ty01 + s3d_tri->ty12), state.cmd_set); state.y = s3d_tri->tys; @@ -3329,47 +3199,15 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) virge->tri_count++; end_time = timer_read(); - - virge_time += end_time - start_time; -} -static void render_thread(void *param) -{ - virge_t *virge = (virge_t *)param; - - while (1) - { - thread_wait_event(virge->wake_render_thread, -1); - thread_reset_event(virge->wake_render_thread); - virge->s3d_busy = 1; - while (!RB_EMPTY) - { - s3_virge_triangle(virge, &virge->s3d_buffer[virge->s3d_read_idx & RB_MASK]); - virge->s3d_read_idx++; - - if (RB_ENTRIES == RB_SIZE - 1) - thread_set_event(virge->not_full_event); - } - virge->s3d_busy = 0; - virge->subsys_stat |= INT_S3D_DONE; - s3_virge_update_irqs(virge); - } + virge_time += end_time - start_time; } static void queue_triangle(virge_t *virge) { -// pclog("queue_triangle: read=%i write=%i RB_ENTRIES=%i RB_FULL=%i\n", virge->s3d_read_idx, virge->s3d_write_idx, RB_ENTRIES, RB_FULL); - if (RB_FULL) - { - thread_reset_event(virge->not_full_event); - if (RB_FULL) - thread_wait_event(virge->not_full_event, -1); /*Wait for room in ringbuffer*/ - } -// pclog(" add at read=%i write=%i %i\n", virge->s3d_read_idx, virge->s3d_write_idx, virge->s3d_write_idx & RB_MASK); - virge->s3d_buffer[virge->s3d_write_idx & RB_MASK] = virge->s3d_tri; - virge->s3d_write_idx++; - if (!virge->s3d_busy) - thread_set_event(virge->wake_render_thread); /*Wake up render thread if moving from idle*/ + s3_virge_triangle(virge, &virge->s3d_tri); + virge->subsys_stat |= INT_S3D_DONE; + s3_virge_update_irqs(virge); } static void s3_virge_hwcursor_draw(svga_t *svga, int displine) @@ -3380,20 +3218,20 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; uint32_t fg, bg; - + // pclog("HWcursor %i %i %08x %08x\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y, virge->hwcursor_col[0],virge->hwcursor_col[1]); switch (svga->bpp) - { + { case 15: fg = video_15to32[virge->hwc_fg_col & 0xffff]; bg = video_15to32[virge->hwc_bg_col & 0xffff]; break; - + case 16: fg = video_16to32[virge->hwc_fg_col & 0xffff]; bg = video_16to32[virge->hwc_bg_col & 0xffff]; break; - + case 24: case 32: fg = virge->hwc_fg_col; bg = virge->hwc_bg_col; @@ -3419,7 +3257,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) if (dat[0] & 0x8000) ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? fg : bg; } - + offset++; dat[0] <<= 1; dat[1] <<= 1; @@ -3438,7 +3276,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; // pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga->hwcursor_on, dat[0], dat[1]); } - + offset++; dat[0] <<= 1; dat[1] <<= 1; @@ -3685,16 +3523,16 @@ static void s3_virge_overlay_draw(svga_t *svga, int displine) int x; uint32_t *p; uint8_t *src = &svga->vram[svga->overlay_latch.addr]; - + p = &((uint32_t *)buffer32->line[displine])[offset + 32]; - + if ((offset + virge->streams.sec_w) > virge->streams.pri_w) x_size = (virge->streams.pri_w - virge->streams.sec_x) + 1; else x_size = virge->streams.sec_w + 1; OVERLAY_SAMPLE(); - + for (x = 0; x < x_size; x++) { *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); @@ -3728,22 +3566,22 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) { case 0x00: ret = 0x33; break; /*'S3'*/ case 0x01: ret = 0x53; break; - + case 0x02: ret = virge->virge_id_low; break; case 0x03: ret = virge->virge_id_high; break; case 0x04: ret = virge->pci_regs[0x04] & 0x27; break; - + case 0x07: ret = virge->pci_regs[0x07] & 0x36; break; - + case 0x08: ret = 0; break; /*Revision ID*/ case 0x09: ret = 0; break; /*Programming interface*/ - + case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ case 0x0b: ret = 0x03; /*output = 3; */break; case 0x0d: ret = virge->pci_regs[0x0d] & 0xf8; break; - + case 0x10: ret = 0x00; break;/*Linear frame buffer address*/ case 0x11: ret = 0x00; break; case 0x12: ret = 0x00; break; @@ -3755,12 +3593,12 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) case 0x33: ret = virge->pci_regs[0x33]; break; case 0x3c: ret = virge->pci_regs[0x3c]; break; - + case 0x3d: ret = 0x01; break; /*INTA*/ - + case 0x3e: ret = 0x04; break; case 0x3f: ret = 0xff; break; - + } // pclog("%02X\n", ret); return ret; @@ -3777,7 +3615,7 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x3d: case 0x3e: case 0x3f: return; - + case PCI_REG_COMMAND: if (val & PCI_COMMAND_IO) { @@ -3787,18 +3625,18 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) else io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; - s3_virge_updatemapping(virge); + s3_virge_updatemapping(virge); return; case 0x07: virge->pci_regs[0x07] = val & 0x3e; return; - case 0x0d: + case 0x0d: virge->pci_regs[0x0d] = val & 0xf8; return; - - case 0x13: - svga->crtc[0x59] = val & 0xfc; - s3_virge_updatemapping(virge); + + case 0x13: + svga->crtc[0x59] = val & 0xfc; + s3_virge_updatemapping(virge); return; case 0x30: case 0x32: case 0x33: @@ -3816,7 +3654,7 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&virge->bios_rom.mapping); } return; - case 0x3c: + case 0x3c: virge->pci_regs[0x3c] = val; return; } @@ -3830,7 +3668,7 @@ static void *s3_virge_init() virge->bilinear_enabled = device_get_config_int("bilinear"); virge->dithering_enabled = device_get_config_int("dithering"); virge->memory_size = device_get_config_int("memory"); - + svga_init(&virge->svga, virge, virge->memory_size << 20, s3_virge_recalctimings, s3_virge_in, s3_virge_out, @@ -3872,14 +3710,14 @@ static void *s3_virge_init() io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); virge->pci_regs[4] = 3; - virge->pci_regs[5] = 0; + virge->pci_regs[5] = 0; virge->pci_regs[6] = 0; virge->pci_regs[7] = 2; virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3d] = 1; virge->pci_regs[0x3e] = 4; virge->pci_regs[0x3f] = 0xff; - + virge->virge_id_high = 0x56; virge->virge_id_low = 0x31; virge->virge_rev = 0; @@ -3895,24 +3733,15 @@ static void *s3_virge_init() virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); break; } - + virge->svga.crtc[0x37] = 1;// | (7 << 5); virge->svga.crtc[0x53] = 1 << 3; virge->svga.crtc[0x59] = 0x70; virge->is_375 = 0; - + pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); - - virge->wake_render_thread = thread_create_event(); - virge->wake_main_thread = thread_create_event(); - virge->not_full_event = thread_create_event(); - virge->render_thread = thread_create(render_thread, virge); - - virge->wake_fifo_thread = thread_create_event(); - virge->fifo_not_full_event = thread_create_event(); - virge->fifo_thread = thread_create(fifo_thread, virge); - + return virge; } @@ -3920,7 +3749,7 @@ static void *s3_virge_375_init() { virge_t *virge = malloc(sizeof(virge_t)); memset(virge, 0, sizeof(virge_t)); - + virge->bilinear_enabled = device_get_config_int("bilinear"); virge->dithering_enabled = device_get_config_int("dithering"); virge->memory_size = device_get_config_int("memory"); @@ -3967,14 +3796,14 @@ static void *s3_virge_375_init() io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); virge->pci_regs[4] = 3; - virge->pci_regs[5] = 0; + virge->pci_regs[5] = 0; virge->pci_regs[6] = 0; virge->pci_regs[7] = 2; virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3d] = 1; virge->pci_regs[0x3e] = 4; virge->pci_regs[0x3f] = 0xff; - + virge->virge_id_high = 0x8a; virge->virge_id_low = 0x01; virge->virge_rev = 0; @@ -3994,22 +3823,13 @@ static void *s3_virge_375_init() virge->svga.crtc[0x37] = 1;// | (7 << 5); virge->svga.crtc[0x53] = 1 << 3; virge->svga.crtc[0x59] = 0x70; - + virge->svga.crtc[0x6c] = 0x01; - + virge->is_375 = 1; - + virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); - - virge->wake_render_thread = thread_create_event(); - virge->wake_main_thread = thread_create_event(); - virge->not_full_event = thread_create_event(); - virge->render_thread = thread_create(render_thread, virge); - - virge->wake_fifo_thread = thread_create_event(); - virge->fifo_not_full_event = thread_create_event(); - virge->fifo_thread = thread_create(fifo_thread, virge); - + return virge; } @@ -4022,17 +3842,8 @@ static void s3_virge_close(void *p) fclose(f); #endif - thread_kill(virge->render_thread); - thread_destroy_event(virge->not_full_event); - thread_destroy_event(virge->wake_main_thread); - thread_destroy_event(virge->wake_render_thread); - - thread_kill(virge->fifo_thread); - thread_destroy_event(virge->wake_fifo_thread); - thread_destroy_event(virge->fifo_not_full_event); - svga_close(&virge->svga); - + free(virge); } @@ -4049,7 +3860,7 @@ static int s3_virge_375_available() static void s3_virge_speed_changed(void *p) { virge_t *virge = (virge_t *)p; - + svga_recalctimings(&virge->svga); } diff --git a/src/video.c b/src/video.c index 34a3789..e36f1cc 100644 --- a/src/video.c +++ b/src/video.c @@ -883,19 +883,19 @@ void loadfont(char *s, int format) fclose(f); } -static struct -{ - int x, y, y1, y2, w, h; - int busy; - int buffer_in_use; - - thread_t *blit_thread; - event_t *wake_blit_thread; - event_t *blit_complete; - event_t *buffer_not_in_use; -} blit_data; - -static void blit_thread(void *param); +// static struct +// { +// int x, y, y1, y2, w, h; +// int busy; +// int buffer_in_use; +// + // thread_t *blit_thread; + // event_t *wake_blit_thread; + // event_t *blit_complete; + // event_t *buffer_not_in_use; +// } blit_data; + +// static void blit_thread(void *param); uint32_t cgapal[16]; @@ -937,18 +937,18 @@ void initvideo() cgapal_rebuild(DISPLAY_RGB, 0); - blit_data.wake_blit_thread = thread_create_event(); - blit_data.blit_complete = thread_create_event(); - blit_data.buffer_not_in_use = thread_create_event(); - blit_data.blit_thread = thread_create(blit_thread, NULL); + // blit_data.wake_blit_thread = thread_create_event(); + // blit_data.blit_complete = thread_create_event(); + // blit_data.buffer_not_in_use = thread_create_event(); + // blit_data.blit_thread = thread_create(blit_thread, NULL); } void closevideo() { - thread_kill(blit_data.blit_thread); - thread_destroy_event(blit_data.buffer_not_in_use); - thread_destroy_event(blit_data.blit_complete); - thread_destroy_event(blit_data.wake_blit_thread); + // thread_kill(blit_data.blit_thread); + // thread_destroy_event(blit_data.buffer_not_in_use); + // thread_destroy_event(blit_data.blit_complete); + // thread_destroy_event(blit_data.wake_blit_thread); free(video_15to32); free(video_16to32); @@ -956,37 +956,37 @@ void closevideo() } -static void blit_thread(void *param) -{ - while (1) - { - thread_wait_event(blit_data.wake_blit_thread, -1); - thread_reset_event(blit_data.wake_blit_thread); - - video_blit_memtoscreen_func(blit_data.x, blit_data.y, blit_data.y1, blit_data.y2, blit_data.w, blit_data.h); - - blit_data.busy = 0; - thread_set_event(blit_data.blit_complete); - } -} +// static void blit_thread(void *param) +// { +// while (1) +// { +// thread_wait_event(blit_data.wake_blit_thread, -1); +// thread_reset_event(blit_data.wake_blit_thread); +// +// video_blit_memtoscreen_func(blit_data.x, blit_data.y, blit_data.y1, blit_data.y2, blit_data.w, blit_data.h); +// +// blit_data.busy = 0; +// thread_set_event(blit_data.blit_complete); +// } +// } void video_blit_complete() { - blit_data.buffer_in_use = 0; - thread_set_event(blit_data.buffer_not_in_use); + // blit_data.buffer_in_use = 0; + // thread_set_event(blit_data.buffer_not_in_use); } void video_wait_for_blit() { - while (blit_data.busy) - thread_wait_event(blit_data.blit_complete, 1); - thread_reset_event(blit_data.blit_complete); + // while (blit_data.busy) + // thread_wait_event(blit_data.blit_complete, 1); + // thread_reset_event(blit_data.blit_complete); } void video_wait_for_buffer() { - while (blit_data.buffer_in_use) - thread_wait_event(blit_data.buffer_not_in_use, 1); - thread_reset_event(blit_data.buffer_not_in_use); + // while (blit_data.buffer_in_use) + // thread_wait_event(blit_data.buffer_not_in_use, 1); + // thread_reset_event(blit_data.buffer_not_in_use); } void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) @@ -994,16 +994,16 @@ void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) video_frames++; if (h <= 0) return; - video_wait_for_blit(); - blit_data.busy = 1; - blit_data.buffer_in_use = 1; - blit_data.x = x; - blit_data.y = y; - blit_data.y1 = y1; - blit_data.y2 = y2; - blit_data.w = w; - blit_data.h = h; - thread_set_event(blit_data.wake_blit_thread); + // video_wait_for_blit(); + // blit_data.busy = 1; + // blit_data.buffer_in_use = 1; + // blit_data.x = x; + // blit_data.y = y; + // blit_data.y1 = y1; + // blit_data.y2 = y2; + // blit_data.w = w; + // blit_data.h = h; + video_blit_memtoscreen_func(x, y, y1, y2, w, h); } void cgapal_rebuild(int display_type, int contrast) diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index cb0fcb8..cbc4dae 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -306,7 +306,7 @@ LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR int display_init() { - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) + if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL could not initialize! Error: %s\n", SDL_GetError()); return 0; diff --git a/src/wx-sdl2-display.c b/src/wx-sdl2-display.c index 239c8e1..7c83c5f 100644 --- a/src/wx-sdl2-display.c +++ b/src/wx-sdl2-display.c @@ -1,5 +1,6 @@ #include #include "video.h" +#include "wx-sdl2.h" #include "wx-sdl2-video.h" #include "wx-utils.h" #include "ibm.h" @@ -85,7 +86,7 @@ void releasemouse() int display_init() { - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) + if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL could not initialize! Error: %s\n", SDL_GetError()); return 0; @@ -690,7 +691,21 @@ int renderer_thread(void* params) if (!render()) internal_rendering = 0; - SDL_Delay(1); + SDL_LockMutex(syncMutex); + syncRender = 0; + SDL_CondSignal(syncCond); + SDL_UnlockMutex(syncMutex); + + if (!rendering || !internal_rendering) + break; + + SDL_LockMutex(syncMutex); + while (!syncRender) { + SDL_CondWait(syncCond, syncMutex); + } + SDL_UnlockMutex(syncMutex); + + // SDL_Delay(1); } window_close(); } @@ -760,7 +775,12 @@ void renderer_stop(int timeout) if (rendering) { SDL_LockMutex(rendererMutex); + SDL_LockMutex(syncMutex); rendering = 0; + syncRender = 1; + SDL_CondSignal(syncCond); + SDL_UnlockMutex(syncMutex); + if (timeout) SDL_CondWaitTimeout(rendererCond, rendererMutex, timeout); else diff --git a/src/wx-sdl2-video-renderer.c b/src/wx-sdl2-video-renderer.c index 7a53092..e109761 100644 --- a/src/wx-sdl2-video-renderer.c +++ b/src/wx-sdl2-video-renderer.c @@ -156,7 +156,7 @@ sdl_renderer_t* sdl2_renderer_create() renderer->close = sdl_video_renderer_close; renderer->update = sdl_video_renderer_update; renderer->present = sdl_video_renderer_present; - renderer->always_update = 0; + renderer->always_update = 1; return renderer; } diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index f926af0..ac9eba5 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -70,6 +70,11 @@ SDL_cond* mainCond; SDL_Thread* mainthreadh = NULL; +SDL_mutex* syncMutex; +SDL_cond* syncCond; +int syncRender = 1; + + SDL_TimerID onesectimer; int running = 0; @@ -188,6 +193,12 @@ int mainthread(void* param) running = 1; while (running) { + SDL_LockMutex(syncMutex); + while (syncRender) { + SDL_CondWait(syncCond, syncMutex); + } + SDL_UnlockMutex(syncMutex); + new_time = SDL_GetTicks(); drawits += new_time - old_time; old_time = new_time; @@ -197,8 +208,6 @@ int mainthread(void* param) uint64_t start_time = timer_read(); uint64_t end_time; drawits -= 10; - if (drawits > 50) - drawits = 0; runpc(); frames++; if (frames >= 200 && nvr_dosave) @@ -212,6 +221,11 @@ int mainthread(void* param) } else SDL_Delay(1); + + SDL_LockMutex(syncMutex); + syncRender = 1; + SDL_CondSignal(syncCond); + SDL_UnlockMutex(syncMutex); } SDL_LockMutex(mainMutex); @@ -624,6 +638,9 @@ int start_emulation(void* params) mainMutex = SDL_CreateMutex(); mainCond = SDL_CreateCond(); + syncMutex = SDL_CreateMutex(); + syncCond = SDL_CreateCond(); + if (!loadbios()) { if (romset != -1) @@ -665,7 +682,7 @@ int start_emulation(void* params) display_start(params); mainthreadh = SDL_CreateThread(mainthread, "Main Thread", NULL); - onesectimer = SDL_AddTimer(1000, timer_onesec, NULL); + // onesectimer = SDL_AddTimer(1000, timer_onesec, NULL); updatewindowsize(640, 480); @@ -697,14 +714,22 @@ int stop_emulation() SDL_DestroyCond(mainCond); SDL_DestroyMutex(mainMutex); + SDL_LockMutex(syncMutex); + syncRender = 0; + SDL_CondSignal(syncCond); + SDL_UnlockMutex(syncMutex); + startblit(); display_stop(); + SDL_DestroyCond(syncCond); + SDL_DestroyMutex(syncMutex); + #if SDL_VERSION_ATLEAST(2, 0, 2) SDL_DetachThread(mainthreadh); #endif mainthreadh = NULL; - SDL_RemoveTimer(onesectimer); + // SDL_RemoveTimer(onesectimer); savenvr(); saveconfig(NULL); diff --git a/src/wx-sdl2.h b/src/wx-sdl2.h index 416ed96..8c16faf 100644 --- a/src/wx-sdl2.h +++ b/src/wx-sdl2.h @@ -1,3 +1,5 @@ +#include + #ifdef __cplusplus extern "C" { #endif @@ -16,3 +18,7 @@ extern char openfilestring[260]; extern int pause; extern int take_screenshot; + +extern SDL_mutex* syncMutex; +extern SDL_cond* syncCond; +extern int syncRender;