From 3cad7d88fe679520c535e1c65c4aec5e845b71d6 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 18 Jun 2021 17:45:18 +0200 Subject: [PATCH] The Trio64V2 seems closer to the ViRGE more than I thought and now CRTC regs 0x6B and 0x6C no longer are aliases to 0x59 and 0x5a (only for the trio64v2, the rest is fine as is). --- src/video/vid_s3.c | 110 ++++++++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 1d129e744..ed2d4b648 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -234,7 +234,6 @@ typedef struct s3_t uint32_t dat_buf; int dat_count; int b2e8_pix, temp_cnt; - uint8_t cur_x_bit12, cur_y_bit12; } accel; struct { @@ -542,7 +541,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x8149: case 0x82e9: s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff) | (val << 8); s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x0f) << 8); - s3->accel.cur_y_bit12 = val & 0x10; s3->accel.poly_cy = s3->accel.cur_y; break; case 0x814a: case 0x82ea: @@ -563,7 +561,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x8549: case 0x86e9: s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff) | (val << 8); s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x0f) << 8); - s3->accel.cur_x_bit12 = val & 0x10; s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; s3->accel.poly_x = s3->accel.poly_cx >> 20; break; @@ -2504,18 +2501,24 @@ s3_in(uint16_t addr, void *p) case 0x6a: return s3->bank; /* Phoenix S3 video BIOS'es seem to expect CRTC registers 6B and 6C to be mirrors of 59 and 5A. */ - case 0x6b: - if (svga->crtc[0x53] & 0x08) { - return (s3->chip >= S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); - } else { - return svga->crtc[0x59]; - } + case 0x6b: + if (s3->chip != S3_TRIO64V2) { + if (svga->crtc[0x53] & 0x08) { + return (s3->chip == S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); + } else { + return svga->crtc[0x59]; + } + } else + return svga->crtc[0x6b]; break; - case 0x6c: - if (svga->crtc[0x53] & 0x08) - return 0x00; - else - return (svga->crtc[0x5a] & 0x80); + case 0x6c: + if (s3->chip != S3_TRIO64V2) { + if (svga->crtc[0x53] & 0x08) + return 0x00; + else + return (svga->crtc[0x5a] & 0x80); + } else + return svga->crtc[0x6c]; break; } return svga->crtc[svga->crtcreg]; @@ -4503,9 +4506,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 1: /*Draw line*/ if (!cpu_input) { s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; + if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; + if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; s3->accel.sy = s3->accel.maj_axis_pcnt; @@ -4669,14 +4672,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx = s3->accel.cur_x; s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_x_bit12) { + if (s3->accel.cur_x & 0x1000) { if (s3->accel.cx <= 0x7ff) { s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; } else { s3->accel.cx |= ~0xfff; } } - if (s3->accel.cur_y_bit12) { + if (s3->accel.cur_y & 0x1000) { if (s3->accel.cy <= 0x7ff) { s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; } else { @@ -4912,7 +4915,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.dx >= 0xfffff000) { /* avoid overflow */ s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.cur_x_bit12) { + if (s3->accel.cur_x & 0x1000) { if (s3->accel.cx <= 0x7ff) { s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; } else { @@ -4922,14 +4925,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.cur_y_bitres > 0xfff) s3->accel.cy = s3->accel.cur_y_bitres; } else { - if (s3->accel.cur_x_bit12) { + if (s3->accel.cur_x & 0x1000) { if (s3->accel.cx <= 0x7ff) { /* overlap x */ s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; } else { /* x end is negative */ s3->accel.cx |= ~0xfff; } } - if (s3->accel.cur_y_bit12) { + if (s3->accel.cur_y & 0x1000) { if (s3->accel.cy <= 0x7ff) { /* overlap y */ s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; } else { /* y end is negative */ @@ -5094,9 +5097,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; + if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; + if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; /*Align source with destination*/ s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; @@ -5216,10 +5219,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) + if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) + if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; } @@ -5403,9 +5406,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; + if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; + if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; s3->accel.px = s3->accel.pat_x & 0xfff; if (s3->accel.pat_x & 0x1000) s3->accel.px |= ~0xfff; @@ -5549,7 +5552,7 @@ s3_pci_read(int func, int addr, void *p) return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ break; - case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ + case 0x07: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x07] & 0x36) : (1 << 1); /*Medium DEVSEL timing*/ case 0x08: return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision ID*/ case 0x09: return 0; /*Programming interface*/ @@ -5567,6 +5570,8 @@ s3_pci_read(int func, int addr, void *p) return 0x00; break; + case 0x0d: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x0d] & 0xf8) : 0x00; break; + case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x11: return 0x00; case 0x12: @@ -5591,6 +5596,9 @@ s3_pci_read(int func, int addr, void *p) case 0x3c: return s3->int_line; case 0x3d: return PCI_INTA; + + case 0x3e: return (s3->chip == S3_TRIO64V2) ? 0x04 : 0x00; break; + case 0x3f: return (s3->chip == S3_TRIO64V2) ? 0xff : 0x00; break; } return 0; } @@ -5600,8 +5608,16 @@ s3_pci_write(int func, int addr, uint8_t val, void *p) { s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; + switch (addr) { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x3d: case 0x3e: case 0x3f: + if (s3->chip == S3_TRIO64V2) + return; + break; + case PCI_REG_COMMAND: if (val & PCI_COMMAND_IO) s3_io_set(s3); @@ -5611,6 +5627,20 @@ s3_pci_write(int func, int addr, uint8_t val, void *p) s3_updatemapping(s3); break; + case 0x07: + if (s3->chip == S3_TRIO64V2) { + s3->pci_regs[0x07] = val & 0x3e; + return; + } + break; + + case 0x0d: + if (s3->chip == S3_TRIO64V2) { + s3->pci_regs[0x0d] = val & 0xf8; + return; + } + break; + case 0x12: if (!(svga->crtc[0x53] & 0x08)) { svga->crtc[0x5a] = (svga->crtc[0x5a] & 0x7f) | (val & 0x80); @@ -5946,10 +5976,7 @@ static void *s3_init(const device_t *info) svga->vblank_start = s3_vblank_start; s3_io_set(s3); - - if (s3->pci) { - s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); - } + s3->pci_regs[PCI_REG_COMMAND] = 7; s3->pci_regs[0x30] = 0x00; @@ -5958,10 +5985,6 @@ static void *s3_init(const device_t *info) s3->chip = chip; - s3->wake_fifo_thread = thread_create_event(); - s3->fifo_not_full_event = thread_create_event(); - s3->fifo_thread = thread_create(fifo_thread, s3); - s3->int_line = 0; s3->card_type = info->local; @@ -6154,7 +6177,15 @@ static void *s3_init(const device_t *info) s3->id_ext = s3->id_ext_pci = 0x01; s3->packed_mmio = 1; svga->crtc[0x53] = 0x08; + svga->crtc[0x59] = 0x70; + svga->crtc[0x5a] = 0x00; svga->crtc[0x6c] = 1; + s3->pci_regs[0x05] = 0; + s3->pci_regs[0x06] = 0; + s3->pci_regs[0x07] = 2; + s3->pci_regs[0x3d] = 1; + s3->pci_regs[0x3e] = 4; + s3->pci_regs[0x3f] = 0xff; svga->clock_gen = s3; svga->getclock = s3_trio64_getclock; @@ -6164,10 +6195,17 @@ static void *s3_init(const device_t *info) return NULL; } + if (s3->pci) + s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); + s3->i2c = i2c_gpio_init("ddc_s3"); s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c)); svga->packed_chain4 = 1; + + s3->wake_fifo_thread = thread_create_event(); + s3->fifo_not_full_event = thread_create_event(); + s3->fifo_thread = thread_create(fifo_thread, s3); return s3; }