diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index bac8157..7b94970 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -6,6 +6,7 @@ #include "mem.h" #include "pci.h" #include "rom.h" +#include "thread.h" #include "video.h" #include "vid_svga.h" #include "vid_ati68860_ramdac.h" @@ -14,6 +15,31 @@ //#define MACH64_DEBUG +#define FIFO_SIZE 65536 +#define FIFO_MASK (FIFO_SIZE - 1) +#define FIFO_ENTRY_SIZE (1 << 31) + +#define FIFO_ENTRIES (mach64->fifo_write_idx - mach64->fifo_read_idx) +#define FIFO_FULL ((mach64->fifo_write_idx - mach64->fifo_read_idx) >= FIFO_SIZE) +#define FIFO_EMPTY (mach64->fifo_read_idx == mach64->fifo_write_idx) + +#define FIFO_TYPE 0xff000000 +#define FIFO_ADDR 0x00ffffff + +enum +{ + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_BYTE = (0x01 << 24), + FIFO_WRITE_WORD = (0x02 << 24), + FIFO_WRITE_DWORD = (0x03 << 24) +}; + +typedef struct +{ + uint32_t addr_type; + uint32_t val; +} fifo_entry_t; + typedef struct mach64_t { mem_mapping_t linear_mapping; @@ -140,6 +166,17 @@ typedef struct mach64_t int err; int poly_draw; } accel; + + 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 blitter_busy; + uint64_t blitter_time; + uint64_t status_time; } mach64_t; enum @@ -206,6 +243,11 @@ enum void mach64_write(uint32_t addr, uint8_t val, void *priv); uint8_t mach64_read(uint32_t addr, void *priv); void mach64_updatemapping(mach64_t *mach64); +void mach64_recalctimings(svga_t *svga); +void mach64_start_fill(mach64_t *mach64); +void mach64_start_line(mach64_t *mach64); +void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64); +void mach64_load_context(mach64_t *mach64); uint8_t mach64_ext_readb(uint32_t addr, void *priv); uint16_t mach64_ext_readw(uint32_t addr, void *priv); @@ -436,6 +478,20 @@ void mach64_updatemapping(mach64_t *mach64) } } +static inline void wake_fifo_thread(mach64_t *mach64) +{ + thread_set_event(mach64->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ +} + +static void mach64_wait_fifo_idle(mach64_t *mach64) +{ + while (!FIFO_EMPTY) + { + wake_fifo_thread(mach64); + thread_wait_event(mach64->fifo_not_full_event, 1); + } +} + #define READ8(addr, var) switch ((addr) & 3) \ { \ case 0: ret = (var) & 0xff; break; \ @@ -452,6 +508,331 @@ void mach64_updatemapping(mach64_t *mach64) case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ } +static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) +{ +// pclog("mach64_accel_write_fifo: addr=%08x val=%02x\n", addr, val); + switch (addr & 0x3ff) + { + case 0x100: case 0x101: case 0x102: case 0x103: + WRITE8(addr, mach64->dst_off_pitch, val); + break; + case 0x104: case 0x105: case 0x11c: case 0x11d: + WRITE8(addr + 2, mach64->dst_y_x, val); + break; + case 0x108: case 0x109: + WRITE8(addr, mach64->dst_y_x, val); + break; + case 0x10c: case 0x10d: case 0x10e: case 0x10f: + WRITE8(addr, mach64->dst_y_x, val); + break; + case 0x110: case 0x111: + WRITE8(addr + 2, mach64->dst_height_width, val); + break; + case 0x114: case 0x115: + case 0x118: case 0x119: case 0x11a: case 0x11b: + case 0x11e: case 0x11f: + WRITE8(addr, mach64->dst_height_width, val); + case 0x113: + if ((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || + ((addr & 0x3ff) == 0x113) && !(val & 0x80)) + { + mach64_start_fill(mach64); +#ifdef MACH64_DEBUG + pclog("%i %i %i %i %i %08x\n", (mach64->dst_height_width & 0x7ff), (mach64->dst_height_width & 0x7ff0000), + ((mach64->dp_src & 7) != SRC_HOST), (((mach64->dp_src >> 8) & 7) != SRC_HOST), + (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST), mach64->dp_src); +#endif + if ((mach64->dst_height_width & 0x7ff) && (mach64->dst_height_width & 0x7ff0000) && + ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && + (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) + mach64_blit(0, -1, mach64); + } + break; + + case 0x120: case 0x121: case 0x122: case 0x123: + WRITE8(addr, mach64->dst_bres_lnth, val); + if ((addr & 0x3ff) == 0x123 && !(val & 0x80)) + { + mach64_start_line(mach64); + + if ((mach64->dst_bres_lnth & 0x7fff) && + ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && + (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) + mach64_blit(0, -1, mach64); + } + break; + case 0x124: case 0x125: case 0x126: case 0x127: + WRITE8(addr, mach64->dst_bres_err, val); + break; + case 0x128: case 0x129: case 0x12a: case 0x12b: + WRITE8(addr, mach64->dst_bres_inc, val); + break; + case 0x12c: case 0x12d: case 0x12e: case 0x12f: + WRITE8(addr, mach64->dst_bres_dec, val); + break; + + case 0x130: case 0x131: case 0x132: case 0x133: + WRITE8(addr, mach64->dst_cntl, val); + break; + + case 0x180: case 0x181: case 0x182: case 0x183: + WRITE8(addr, mach64->src_off_pitch, val); + break; + case 0x184: case 0x185: + WRITE8(addr, mach64->src_y_x, val); + break; + case 0x188: case 0x189: + WRITE8(addr + 2, mach64->src_y_x, val); + break; + case 0x18c: case 0x18d: case 0x18e: case 0x18f: + WRITE8(addr, mach64->src_y_x, val); + break; + case 0x190: case 0x191: + WRITE8(addr + 2, mach64->src_height1_width1, val); + break; + case 0x194: case 0x195: + WRITE8(addr, mach64->src_height1_width1, val); + break; + case 0x198: case 0x199: case 0x19a: case 0x19b: + WRITE8(addr, mach64->src_height1_width1, val); + break; + case 0x19c: case 0x19d: + WRITE8(addr, mach64->src_y_x_start, val); + break; + case 0x1a0: case 0x1a1: + WRITE8(addr + 2, mach64->src_y_x_start, val); + break; + case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7: + WRITE8(addr, mach64->src_y_x_start, val); + break; + case 0x1a8: case 0x1a9: + WRITE8(addr + 2, mach64->src_height2_width2, val); + break; + case 0x1ac: case 0x1ad: + WRITE8(addr, mach64->src_height2_width2, val); + break; + case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3: + WRITE8(addr, mach64->src_height2_width2, val); + break; + + case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: + WRITE8(addr, mach64->src_cntl, val); + break; + + case 0x200: case 0x201: case 0x202: case 0x203: + case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20a: case 0x20b: + case 0x20c: case 0x20d: case 0x20e: case 0x20f: + case 0x210: case 0x211: case 0x212: case 0x213: + case 0x214: case 0x215: case 0x216: case 0x217: + case 0x218: case 0x219: case 0x21a: case 0x21b: + case 0x21c: case 0x21d: case 0x21e: case 0x21f: + case 0x220: case 0x221: case 0x222: case 0x223: + case 0x224: case 0x225: case 0x226: case 0x227: + case 0x228: case 0x229: case 0x22a: case 0x22b: + case 0x22c: case 0x22d: case 0x22e: case 0x22f: + case 0x230: case 0x231: case 0x232: case 0x233: + case 0x234: case 0x235: case 0x236: case 0x237: + case 0x238: case 0x239: case 0x23a: case 0x23b: + case 0x23c: case 0x23d: case 0x23e: case 0x23f: + mach64_blit(val, 8, mach64); + break; + + case 0x280: case 0x281: case 0x282: case 0x283: + WRITE8(addr, mach64->pat_reg0, val); + break; + case 0x284: case 0x285: case 0x286: case 0x287: + WRITE8(addr, mach64->pat_reg1, val); + break; + + case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9: + WRITE8(addr, mach64->sc_left_right, val); + break; + case 0x2a4: case 0x2a5: + addr += 2; + case 0x2aa: case 0x2ab: + WRITE8(addr, mach64->sc_left_right, val); + break; + + case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5: + WRITE8(addr, mach64->sc_top_bottom, val); + break; + case 0x2b0: case 0x2b1: + addr += 2; + case 0x2b6: case 0x2b7: + WRITE8(addr, mach64->sc_top_bottom, val); + break; + + case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: + WRITE8(addr, mach64->dp_bkgd_clr, val); + break; + case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: + WRITE8(addr, mach64->dp_frgd_clr, val); + break; + + case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3: + WRITE8(addr, mach64->dp_pix_width, val); + break; + case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: + WRITE8(addr, mach64->dp_mix, val); + break; + case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: + WRITE8(addr, mach64->dp_src, val); + break; + + case 0x300: case 0x301: case 0x302: case 0x303: + WRITE8(addr, mach64->clr_cmp_clr, val); + break; + case 0x304: case 0x305: case 0x306: case 0x307: + WRITE8(addr, mach64->clr_cmp_mask, val); + break; + case 0x308: case 0x309: case 0x30a: case 0x30b: + WRITE8(addr, mach64->clr_cmp_cntl, val); + break; + + case 0x320: case 0x321: case 0x322: case 0x323: + WRITE8(addr, mach64->context_mask, val); + break; + + case 0x330: case 0x331: + WRITE8(addr, mach64->dst_cntl, val); + break; + case 0x332: + WRITE8(addr - 2, mach64->src_cntl, val); + break; + case 0x333: + WRITE8(addr - 3, mach64->pat_cntl, val & 7); + break; + } +} +static void mach64_accel_write_fifo_w(mach64_t *mach64, uint32_t addr, uint16_t val) +{ +// pclog("mach64_accel_write_fifo_w: addr=%08x val=%04x\n", addr, val); + switch (addr & 0x3fe) + { + case 0x200: case 0x202: case 0x204: case 0x206: + case 0x208: case 0x20a: case 0x20c: case 0x20e: + case 0x210: case 0x212: case 0x214: case 0x216: + case 0x218: case 0x21a: case 0x21c: case 0x21e: + case 0x220: case 0x222: case 0x224: case 0x226: + case 0x228: case 0x22a: case 0x22c: case 0x22e: + case 0x230: case 0x232: case 0x234: case 0x236: + case 0x238: case 0x23a: case 0x23c: case 0x23e: + mach64_blit(val, 16, mach64); + break; + + default: +#ifdef MACH64_DEBUG + pclog(" "); +#endif + mach64_accel_write_fifo(mach64, addr, val); +#ifdef MACH64_DEBUG + pclog(" "); +#endif + mach64_accel_write_fifo(mach64, addr + 1, val >> 8); + break; + } +} +static void mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t val) +{ +// pclog("mach64_accel_write_fifo_l: addr=%08x %02x val=%08x\n", addr, addr >> 2, val); + switch (addr & 0x3fc) + { + case 0x32c: + mach64->context_load_cntl = val; + if (val & 0x30000) + mach64_load_context(mach64); + break; + + case 0x200: case 0x204: case 0x208: case 0x20c: + case 0x210: case 0x214: case 0x218: case 0x21c: + case 0x220: case 0x224: case 0x228: case 0x22c: + case 0x230: case 0x234: case 0x238: case 0x23c: + if (mach64->accel.source_host || (mach64->dp_pix_width & DP_BYTE_PIX_ORDER)) + mach64_blit(val, 32, mach64); + else + mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32, mach64); + break; + + default: +#ifdef MACH64_DEBUG + pclog(" "); +#endif + mach64_accel_write_fifo_w(mach64, addr, val); +#ifdef MACH64_DEBUG + pclog(" "); +#endif + mach64_accel_write_fifo_w(mach64, addr + 2, val >> 16); + break; + } +} + +static void fifo_thread(void *param) +{ + mach64_t *mach64 = (mach64_t *)param; + + while (1) + { + thread_set_event(mach64->fifo_not_full_event); + thread_wait_event(mach64->wake_fifo_thread, -1); + thread_reset_event(mach64->wake_fifo_thread); + mach64->blitter_busy = 1; + while (!FIFO_EMPTY) + { + uint64_t start_time = timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; + uint32_t val = fifo->val; + + switch (fifo->addr_type & FIFO_TYPE) + { + case FIFO_WRITE_BYTE: + mach64_accel_write_fifo(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_WORD: + mach64_accel_write_fifo_w(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_DWORD: + mach64_accel_write_fifo_l(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + } + + mach64->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; + + if (FIFO_ENTRIES > 0xe000) + thread_set_event(mach64->fifo_not_full_event); + + end_time = timer_read(); + mach64->blitter_time += end_time - start_time; + } + mach64->blitter_busy = 0; + } +} + +static void mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t type) +{ + fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_write_idx & FIFO_MASK]; + int c; + + if (FIFO_FULL) + { + thread_reset_event(mach64->fifo_not_full_event); + if (FIFO_FULL) + { + thread_wait_event(mach64->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } + + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; + + mach64->fifo_write_idx++; + + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(mach64); +} + void mach64_cursor_dump(mach64_t *mach64) { svga_t *svga = &mach64->svga; @@ -1084,57 +1465,57 @@ void mach64_load_context(mach64_t *mach64) #endif if (mach64->context_mask & (1 << 2)) - mach64_ext_writel(0x100, *(uint32_t *)&svga->vram[addr + 0x08], mach64); + mach64_accel_write_fifo_l(mach64, 0x100, *(uint32_t *)&svga->vram[addr + 0x08]); if (mach64->context_mask & (1 << 3)) - mach64_ext_writel(0x10c, *(uint32_t *)&svga->vram[addr + 0x0c], mach64); + mach64_accel_write_fifo_l(mach64, 0x10c, *(uint32_t *)&svga->vram[addr + 0x0c]); if (mach64->context_mask & (1 << 4)) - mach64_ext_writel(0x118, *(uint32_t *)&svga->vram[addr + 0x10], mach64); + mach64_accel_write_fifo_l(mach64, 0x118, *(uint32_t *)&svga->vram[addr + 0x10]); if (mach64->context_mask & (1 << 5)) - mach64_ext_writel(0x124, *(uint32_t *)&svga->vram[addr + 0x14], mach64); + mach64_accel_write_fifo_l(mach64, 0x124, *(uint32_t *)&svga->vram[addr + 0x14]); if (mach64->context_mask & (1 << 6)) - mach64_ext_writel(0x128, *(uint32_t *)&svga->vram[addr + 0x18], mach64); + mach64_accel_write_fifo_l(mach64, 0x128, *(uint32_t *)&svga->vram[addr + 0x18]); if (mach64->context_mask & (1 << 7)) - mach64_ext_writel(0x12c, *(uint32_t *)&svga->vram[addr + 0x1c], mach64); + mach64_accel_write_fifo_l(mach64, 0x12c, *(uint32_t *)&svga->vram[addr + 0x1c]); if (mach64->context_mask & (1 << 8)) - mach64_ext_writel(0x180, *(uint32_t *)&svga->vram[addr + 0x20], mach64); + mach64_accel_write_fifo_l(mach64, 0x180, *(uint32_t *)&svga->vram[addr + 0x20]); if (mach64->context_mask & (1 << 9)) - mach64_ext_writel(0x18c, *(uint32_t *)&svga->vram[addr + 0x24], mach64); + mach64_accel_write_fifo_l(mach64, 0x18c, *(uint32_t *)&svga->vram[addr + 0x24]); if (mach64->context_mask & (1 << 10)) - mach64_ext_writel(0x198, *(uint32_t *)&svga->vram[addr + 0x28], mach64); + mach64_accel_write_fifo_l(mach64, 0x198, *(uint32_t *)&svga->vram[addr + 0x28]); if (mach64->context_mask & (1 << 11)) - mach64_ext_writel(0x1a4, *(uint32_t *)&svga->vram[addr + 0x2c], mach64); + mach64_accel_write_fifo_l(mach64, 0x1a4, *(uint32_t *)&svga->vram[addr + 0x2c]); if (mach64->context_mask & (1 << 12)) - mach64_ext_writel(0x1b0, *(uint32_t *)&svga->vram[addr + 0x30], mach64); + mach64_accel_write_fifo_l(mach64, 0x1b0, *(uint32_t *)&svga->vram[addr + 0x30]); if (mach64->context_mask & (1 << 13)) - mach64_ext_writel(0x280, *(uint32_t *)&svga->vram[addr + 0x34], mach64); + mach64_accel_write_fifo_l(mach64, 0x280, *(uint32_t *)&svga->vram[addr + 0x34]); if (mach64->context_mask & (1 << 14)) - mach64_ext_writel(0x284, *(uint32_t *)&svga->vram[addr + 0x38], mach64); + mach64_accel_write_fifo_l(mach64, 0x284, *(uint32_t *)&svga->vram[addr + 0x38]); if (mach64->context_mask & (1 << 15)) - mach64_ext_writel(0x2a8, *(uint32_t *)&svga->vram[addr + 0x3c], mach64); + mach64_accel_write_fifo_l(mach64, 0x2a8, *(uint32_t *)&svga->vram[addr + 0x3c]); if (mach64->context_mask & (1 << 16)) - mach64_ext_writel(0x2b4, *(uint32_t *)&svga->vram[addr + 0x40], mach64); + mach64_accel_write_fifo_l(mach64, 0x2b4, *(uint32_t *)&svga->vram[addr + 0x40]); if (mach64->context_mask & (1 << 17)) - mach64_ext_writel(0x2c0, *(uint32_t *)&svga->vram[addr + 0x44], mach64); + mach64_accel_write_fifo_l(mach64, 0x2c0, *(uint32_t *)&svga->vram[addr + 0x44]); if (mach64->context_mask & (1 << 18)) - mach64_ext_writel(0x2c4, *(uint32_t *)&svga->vram[addr + 0x48], mach64); + mach64_accel_write_fifo_l(mach64, 0x2c4, *(uint32_t *)&svga->vram[addr + 0x48]); if (mach64->context_mask & (1 << 19)) - mach64_ext_writel(0x2c8, *(uint32_t *)&svga->vram[addr + 0x4c], mach64); + mach64_accel_write_fifo_l(mach64, 0x2c8, *(uint32_t *)&svga->vram[addr + 0x4c]); if (mach64->context_mask & (1 << 20)) - mach64_ext_writel(0x2cc, *(uint32_t *)&svga->vram[addr + 0x50], mach64); + mach64_accel_write_fifo_l(mach64, 0x2cc, *(uint32_t *)&svga->vram[addr + 0x50]); if (mach64->context_mask & (1 << 21)) - mach64_ext_writel(0x2d0, *(uint32_t *)&svga->vram[addr + 0x54], mach64); + mach64_accel_write_fifo_l(mach64, 0x2d0, *(uint32_t *)&svga->vram[addr + 0x54]); if (mach64->context_mask & (1 << 22)) - mach64_ext_writel(0x2d4, *(uint32_t *)&svga->vram[addr + 0x58], mach64); + mach64_accel_write_fifo_l(mach64, 0x2d4, *(uint32_t *)&svga->vram[addr + 0x58]); if (mach64->context_mask & (1 << 23)) - mach64_ext_writel(0x2d8, *(uint32_t *)&svga->vram[addr + 0x5c], mach64); + mach64_accel_write_fifo_l(mach64, 0x2d8, *(uint32_t *)&svga->vram[addr + 0x5c]); if (mach64->context_mask & (1 << 24)) - mach64_ext_writel(0x300, *(uint32_t *)&svga->vram[addr + 0x60], mach64); + mach64_accel_write_fifo_l(mach64, 0x300, *(uint32_t *)&svga->vram[addr + 0x60]); if (mach64->context_mask & (1 << 25)) - mach64_ext_writel(0x304, *(uint32_t *)&svga->vram[addr + 0x64], mach64); + mach64_accel_write_fifo_l(mach64, 0x304, *(uint32_t *)&svga->vram[addr + 0x64]); if (mach64->context_mask & (1 << 26)) - mach64_ext_writel(0x308, *(uint32_t *)&svga->vram[addr + 0x68], mach64); + mach64_accel_write_fifo_l(mach64, 0x308, *(uint32_t *)&svga->vram[addr + 0x68]); if (mach64->context_mask & (1 << 27)) - mach64_ext_writel(0x330, *(uint32_t *)&svga->vram[addr + 0x6c], mach64); + mach64_accel_write_fifo_l(mach64, 0x330, *(uint32_t *)&svga->vram[addr + 0x6c]); mach64->context_load_cntl = *(uint32_t *)&svga->vram[addr + 0x70]; } @@ -1225,15 +1606,19 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) break; case 0x100: case 0x101: case 0x102: case 0x103: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_off_pitch); break; case 0x104: case 0x105: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_y_x); break; case 0x108: case 0x109: case 0x11c: case 0x11d: + mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->dst_y_x); break; case 0x10c: case 0x10d: case 0x10e: case 0x10f: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_y_x); break; case 0x110: case 0x111: @@ -1241,135 +1626,187 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) case 0x114: case 0x115: case 0x118: case 0x119: case 0x11a: case 0x11b: case 0x11e: case 0x11f: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_height_width); break; case 0x120: case 0x121: case 0x122: case 0x123: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_lnth); break; case 0x124: case 0x125: case 0x126: case 0x127: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_err); break; case 0x128: case 0x129: case 0x12a: case 0x12b: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_inc); break; case 0x12c: case 0x12d: case 0x12e: case 0x12f: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_dec); break; case 0x130: case 0x131: case 0x132: case 0x133: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_cntl); break; case 0x180: case 0x181: case 0x182: case 0x183: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_off_pitch); break; case 0x184: case 0x185: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x); break; case 0x188: case 0x189: + mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_y_x); break; case 0x18c: case 0x18d: case 0x18e: case 0x18f: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x); break; case 0x190: case 0x191: + mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_height1_width1); break; case 0x194: case 0x195: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height1_width1); break; case 0x198: case 0x199: case 0x19a: case 0x19b: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height1_width1); break; case 0x19c: case 0x19d: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x_start); break; case 0x1a0: case 0x1a1: + mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_y_x_start); break; case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x_start); break; case 0x1a8: case 0x1a9: + mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_height2_width2); break; case 0x1ac: case 0x1ad: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height2_width2); break; case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height2_width2); break; case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_cntl); break; case 0x280: case 0x281: case 0x282: case 0x283: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_reg0); break; case 0x284: case 0x285: case 0x286: case 0x287: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_reg1); break; case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_left_right); break; case 0x2a4: case 0x2a5: addr += 2; case 0x2aa: case 0x2ab: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_left_right); break; case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_top_bottom); break; case 0x2b0: case 0x2b1: addr += 2; case 0x2b6: case 0x2b7: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_top_bottom); break; case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_bkgd_clr); break; case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_frgd_clr); break; case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_pix_width); break; case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_mix); break; case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_src); break; case 0x300: case 0x301: case 0x302: case 0x303: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_clr); break; case 0x304: case 0x305: case 0x306: case 0x307: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_mask); break; case 0x308: case 0x309: case 0x30a: case 0x30b: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_cntl); break; - + + case 0x310: case 0x311: + if (!FIFO_EMPTY) + wake_fifo_thread(mach64); + ret = 0; + if (FIFO_FULL) + ret = 0xff; + break; + case 0x320: case 0x321: case 0x322: case 0x323: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->context_mask); break; case 0x330: case 0x331: + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_cntl); break; case 0x332: + mach64_wait_fifo_idle(mach64); READ8(addr - 2, mach64->src_cntl); break; case 0x333: + mach64_wait_fifo_idle(mach64); READ8(addr - 3, mach64->pat_cntl); break; + + case 0x338: +/* if (!FIFO_EMPTY) + wake_fifo_thread(mach64);*/ + ret = FIFO_EMPTY ? 0 : 1; + break; default: ret = 0; @@ -1445,7 +1882,11 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) #ifdef MACH64_DEBUG pclog("mach64_ext_writeb : addr %08X val %02X\n", addr, val); #endif - switch (addr & 0x3ff) + if (addr & 0x300) + { + mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); + } + else switch (addr & 0x3ff) { case 0x00: case 0x01: case 0x02: case 0x03: WRITE8(addr, mach64->crtc_h_total_disp, val); @@ -1564,197 +2005,6 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) svga->hwcursor.ena = mach64->gen_test_cntl & 0x80; mach64_cursor_dump(mach64); break; - - case 0x100: case 0x101: case 0x102: case 0x103: - WRITE8(addr, mach64->dst_off_pitch, val); - break; - case 0x104: case 0x105: case 0x11c: case 0x11d: - WRITE8(addr + 2, mach64->dst_y_x, val); - break; - case 0x108: case 0x109: - WRITE8(addr, mach64->dst_y_x, val); - break; - case 0x10c: case 0x10d: case 0x10e: case 0x10f: - WRITE8(addr, mach64->dst_y_x, val); - break; - case 0x110: case 0x111: - WRITE8(addr + 2, mach64->dst_height_width, val); - break; - case 0x114: case 0x115: - case 0x118: case 0x119: case 0x11a: case 0x11b: - case 0x11e: case 0x11f: - WRITE8(addr, mach64->dst_height_width, val); - case 0x113: - if ((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || - ((addr & 0x3ff) == 0x113) && !(val & 0x80)) - { - mach64_start_fill(mach64); -#ifdef MACH64_DEBUG - pclog("%i %i %i %i %i\n", (mach64->dst_height_width & 0x7ff), (mach64->dst_height_width & 0x7ff0000), - ((mach64->dp_src & 7) != SRC_HOST), (((mach64->dp_src >> 8) & 7) != SRC_HOST), - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)); -#endif - if ((mach64->dst_height_width & 0x7ff) && (mach64->dst_height_width & 0x7ff0000) && - ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) - mach64_blit(0, -1, mach64); - } - break; - - case 0x120: case 0x121: case 0x122: case 0x123: - WRITE8(addr, mach64->dst_bres_lnth, val); - if ((addr & 0x3ff) == 0x123 && !(val & 0x80)) - { - mach64_start_line(mach64); - - if ((mach64->dst_bres_lnth & 0x7fff) && - ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) - mach64_blit(0, -1, mach64); - } - break; - case 0x124: case 0x125: case 0x126: case 0x127: - WRITE8(addr, mach64->dst_bres_err, val); - break; - case 0x128: case 0x129: case 0x12a: case 0x12b: - WRITE8(addr, mach64->dst_bres_inc, val); - break; - case 0x12c: case 0x12d: case 0x12e: case 0x12f: - WRITE8(addr, mach64->dst_bres_dec, val); - break; - - case 0x130: case 0x131: case 0x132: case 0x133: - WRITE8(addr, mach64->dst_cntl, val); - break; - - case 0x180: case 0x181: case 0x182: case 0x183: - WRITE8(addr, mach64->src_off_pitch, val); - break; - case 0x184: case 0x185: - WRITE8(addr, mach64->src_y_x, val); - break; - case 0x188: case 0x189: - WRITE8(addr + 2, mach64->src_y_x, val); - break; - case 0x18c: case 0x18d: case 0x18e: case 0x18f: - WRITE8(addr, mach64->src_y_x, val); - break; - case 0x190: case 0x191: - WRITE8(addr + 2, mach64->src_height1_width1, val); - break; - case 0x194: case 0x195: - WRITE8(addr, mach64->src_height1_width1, val); - break; - case 0x198: case 0x199: case 0x19a: case 0x19b: - WRITE8(addr, mach64->src_height1_width1, val); - break; - case 0x19c: case 0x19d: - WRITE8(addr, mach64->src_y_x_start, val); - break; - case 0x1a0: case 0x1a1: - WRITE8(addr + 2, mach64->src_y_x_start, val); - break; - case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7: - WRITE8(addr, mach64->src_y_x_start, val); - break; - case 0x1a8: case 0x1a9: - WRITE8(addr + 2, mach64->src_height2_width2, val); - break; - case 0x1ac: case 0x1ad: - WRITE8(addr, mach64->src_height2_width2, val); - break; - case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3: - WRITE8(addr, mach64->src_height2_width2, val); - break; - - case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: - WRITE8(addr, mach64->src_cntl, val); - break; - - case 0x200: case 0x201: case 0x202: case 0x203: - case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20a: case 0x20b: - case 0x20c: case 0x20d: case 0x20e: case 0x20f: - case 0x210: case 0x211: case 0x212: case 0x213: - case 0x214: case 0x215: case 0x216: case 0x217: - case 0x218: case 0x219: case 0x21a: case 0x21b: - case 0x21c: case 0x21d: case 0x21e: case 0x21f: - case 0x220: case 0x221: case 0x222: case 0x223: - case 0x224: case 0x225: case 0x226: case 0x227: - case 0x228: case 0x229: case 0x22a: case 0x22b: - case 0x22c: case 0x22d: case 0x22e: case 0x22f: - case 0x230: case 0x231: case 0x232: case 0x233: - case 0x234: case 0x235: case 0x236: case 0x237: - case 0x238: case 0x239: case 0x23a: case 0x23b: - case 0x23c: case 0x23d: case 0x23e: case 0x23f: - mach64_blit(val, 8, mach64); - break; - - case 0x280: case 0x281: case 0x282: case 0x283: - WRITE8(addr, mach64->pat_reg0, val); - break; - case 0x284: case 0x285: case 0x286: case 0x287: - WRITE8(addr, mach64->pat_reg1, val); - break; - - case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9: - WRITE8(addr, mach64->sc_left_right, val); - break; - case 0x2a4: case 0x2a5: - addr += 2; - case 0x2aa: case 0x2ab: - WRITE8(addr, mach64->sc_left_right, val); - break; - - case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5: - WRITE8(addr, mach64->sc_top_bottom, val); - break; - case 0x2b0: case 0x2b1: - addr += 2; - case 0x2b6: case 0x2b7: - WRITE8(addr, mach64->sc_top_bottom, val); - break; - - case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: - WRITE8(addr, mach64->dp_bkgd_clr, val); - break; - case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: - WRITE8(addr, mach64->dp_frgd_clr, val); - break; - - case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3: - WRITE8(addr, mach64->dp_pix_width, val); - break; - case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: - WRITE8(addr, mach64->dp_mix, val); - break; - case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: - WRITE8(addr, mach64->dp_src, val); - break; - - case 0x300: case 0x301: case 0x302: case 0x303: - WRITE8(addr, mach64->clr_cmp_clr, val); - break; - case 0x304: case 0x305: case 0x306: case 0x307: - WRITE8(addr, mach64->clr_cmp_mask, val); - break; - case 0x308: case 0x309: case 0x30a: case 0x30b: - WRITE8(addr, mach64->clr_cmp_cntl, val); - break; - - case 0x320: case 0x321: case 0x322: case 0x323: - WRITE8(addr, mach64->context_mask, val); - break; - - case 0x330: case 0x331: - WRITE8(addr, mach64->dst_cntl, val); - break; - case 0x332: - WRITE8(addr - 2, mach64->src_cntl, val); - break; - case 0x333: - WRITE8(addr - 3, mach64->pat_cntl, val & 7); - break; } } void mach64_ext_writew(uint32_t addr, uint16_t val, void *p) @@ -1763,19 +2013,12 @@ void mach64_ext_writew(uint32_t addr, uint16_t val, void *p) #ifdef MACH64_DEBUG pclog("mach64_ext_writew : addr %08X val %04X\n", addr, val); #endif - switch (addr & 0x3fe) + if (addr & 0x300) + { + mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); + } + else switch (addr & 0x3fe) { - case 0x200: case 0x202: case 0x204: case 0x206: - case 0x208: case 0x20a: case 0x20c: case 0x20e: - case 0x210: case 0x212: case 0x214: case 0x216: - case 0x218: case 0x21a: case 0x21c: case 0x21e: - case 0x220: case 0x222: case 0x224: case 0x226: - case 0x228: case 0x22a: case 0x22c: case 0x22e: - case 0x230: case 0x232: case 0x234: case 0x236: - case 0x238: case 0x23a: case 0x23c: case 0x23e: - mach64_blit(val, 16, mach64); - break; - default: #ifdef MACH64_DEBUG pclog(" "); @@ -1795,24 +2038,12 @@ void mach64_ext_writel(uint32_t addr, uint32_t val, void *p) if ((addr & 0x3c0) != 0x200) pclog("mach64_ext_writel : addr %08X val %08X\n", addr, val); #endif - switch (addr & 0x3fc) + if (addr & 0x300) + { + mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); + } + else switch (addr & 0x3fc) { - case 0x32c: - mach64->context_load_cntl = val; - if (val & 0x30000) - mach64_load_context(mach64); - break; - - case 0x200: case 0x204: case 0x208: case 0x20c: - case 0x210: case 0x214: case 0x218: case 0x21c: - case 0x220: case 0x224: case 0x228: case 0x22c: - case 0x230: case 0x234: case 0x238: case 0x23c: - if (mach64->accel.source_host || (mach64->dp_pix_width & DP_BYTE_PIX_ORDER)) - mach64_blit(val, 32, mach64); - else - mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32, mach64); - break; - default: #ifdef MACH64_DEBUG pclog(" "); @@ -1940,7 +2171,7 @@ uint8_t mach64_ext_inb(uint16_t port, void *p) break; } #ifdef MACH64_DEBUG - pclog("mach64_ext_inb : port %04X ret %02X %04X:%04X\n", port, ret, CS,pc); + pclog("mach64_ext_inb : port %04X ret %02X %04X:%04X\n", port, ret, CS,cpu_state.pc); #endif return ret; } @@ -2000,7 +2231,7 @@ void mach64_ext_outb(uint16_t port, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG - pclog("mach64_ext_outb : port %04X val %02X %04X:%04X\n", port, val, CS,pc); + pclog("mach64_ext_outb : port %04X val %02X %04X:%04X\n", port, val, CS,cpu_state.pc); #endif switch (port) { @@ -2336,6 +2567,10 @@ void *mach64gx_init() mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ mach64->dst_cntl = 3; + + mach64->wake_fifo_thread = thread_create_event(); + mach64->fifo_not_full_event = thread_create_event(); + mach64->fifo_thread = thread_create(fifo_thread, mach64); return mach64; } @@ -2371,6 +2606,10 @@ void mach64_force_redraw(void *p) void mach64_add_status_info(char *s, int max_len, void *p) { mach64_t *mach64 = (mach64_t *)p; + char temps[256]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - mach64->status_time; + mach64->status_time = new_time; if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { @@ -2405,6 +2644,11 @@ void mach64_add_status_info(char *s, int max_len, void *p) strncat(s, "Mach64 in SVGA mode\n", max_len); svga_add_status_info(s, max_len, &mach64->svga); } + + sprintf(temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)mach64->blitter_time * 100.0) / timer_freq, ((double)mach64->blitter_time * 100.0) / status_diff); + strncat(s, temps, max_len); + + mach64->blitter_time = 0; } static device_config_t mach64gx_config[] =