From 03e9544781578259e91ce8edb5d56f6b6385a3a7 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 26 Apr 2018 09:15:36 -0500 Subject: [PATCH 1/4] Fix RIVA 128. TNT and TNT2 still broken --- src/video/vid_nv_riva128.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/video/vid_nv_riva128.c b/src/video/vid_nv_riva128.c index 4dde82a9f..788dcfab5 100644 --- a/src/video/vid_nv_riva128.c +++ b/src/video/vid_nv_riva128.c @@ -2747,15 +2747,16 @@ void riva128_ptimer_tick(void *p) case PCI_REG_COMMAND: riva128->pci_regs[PCI_REG_COMMAND] = val & 0x27; - io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); mem_mapping_disable(&svga->mapping); mem_mapping_disable(&riva128->mmio_mapping); mem_mapping_disable(&riva128->linear_mapping); mem_mapping_disable(&riva128->ramin_mapping); if (val & PCI_COMMAND_IO) { + io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); } + else io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); if (val & PCI_COMMAND_MEM) { uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; @@ -2772,7 +2773,6 @@ void riva128_ptimer_tick(void *p) { mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0xc00000); mem_mapping_set_addr(&riva128->ramin_mapping, linear_addr + 0xc00000, 0x200000); - svga->linear_base = linear_addr; } } return; @@ -2809,7 +2809,6 @@ void riva128_ptimer_tick(void *p) { mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0xc00000); mem_mapping_set_addr(&riva128->ramin_mapping, linear_addr + 0xc00000, 0x200000); - svga->linear_base = linear_addr; } return; } @@ -2862,14 +2861,15 @@ void riva128_ptimer_tick(void *p) case PCI_REG_COMMAND: riva128->pci_regs[PCI_REG_COMMAND] = val & 0x27; - io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); mem_mapping_disable(&svga->mapping); mem_mapping_disable(&riva128->mmio_mapping); mem_mapping_disable(&riva128->linear_mapping); if (val & PCI_COMMAND_IO) { + io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); } + else io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); if (val & PCI_COMMAND_MEM) { uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; @@ -2885,7 +2885,6 @@ void riva128_ptimer_tick(void *p) if (linear_addr) { mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); - svga->linear_base = linear_addr; } } return; @@ -2920,7 +2919,6 @@ void riva128_ptimer_tick(void *p) if (linear_addr) { mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); - svga->linear_base = linear_addr; } return; } @@ -3060,7 +3058,7 @@ void *riva128_init(const device_t *info) riva128_in, riva128_out, NULL, NULL); - riva128->svga.decode_mask = 0x1fffff; + riva128->svga.decode_mask = (riva128->memory_size << 20) - 1; rom_init(&riva128->bios_rom, L"roms/video/nv_riva128/Diamond_V330_rev-e.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) @@ -3304,7 +3302,7 @@ void *rivatnt_init(const device_t *info) riva128_in, riva128_out, NULL, NULL); - riva128->svga.decode_mask = 0x1fffff; + riva128->svga.decode_mask = (riva128->memory_size << 20) - 1; rom_init(&riva128->bios_rom, L"roms/video/nv_riva128/NV4_diamond_revB.rom", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); if (PCI) @@ -3493,7 +3491,7 @@ void *rivatnt2_init(const device_t *info) riva128_in, riva128_out, NULL, NULL); - riva128->svga.decode_mask = 0x1fffff; + riva128->svga.decode_mask = 0x3fffff; switch(model) { From 51299d42492de16e5a82aa8c7981b7b4793232eb Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 26 Apr 2018 09:52:03 -0500 Subject: [PATCH 2/4] Fixed cards with more than 8 MB of VRAM --- src/video/vid_nv_riva128.c | 2 +- src/video/vid_svga.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_nv_riva128.c b/src/video/vid_nv_riva128.c index 788dcfab5..59c16e3aa 100644 --- a/src/video/vid_nv_riva128.c +++ b/src/video/vid_nv_riva128.c @@ -2771,7 +2771,7 @@ void riva128_ptimer_tick(void *p) } if (linear_addr) { - mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0xc00000); + mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); mem_mapping_set_addr(&riva128->ramin_mapping, linear_addr + 0xc00000, 0x200000); } } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 2fca45358..da148849a 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -796,7 +796,7 @@ svga_init(svga_t *svga, void *p, int memsize, svga->vram_max = memsize; svga->vram_display_mask = svga->vram_mask = memsize - 1; svga->decode_mask = 0x7fffff; - svga->changedvram = malloc(0x800000 >> 12); + svga->changedvram = malloc(memsize >> 12); svga->recalctimings_ex = recalctimings_ex; svga->video_in = video_in; svga->video_out = video_out; From f8d0b2de95c38ede5015ccf4bf56ee09fca62ab4 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 26 Apr 2018 10:19:57 -0500 Subject: [PATCH 3/4] Start over on nvidia --- src/video/vid_nvidia.c | 943 +++++++++++++++++++++++++++++++++++++++++ src/video/vid_nvidia.h | 1 + src/video/vid_table.c | 6 +- src/win/Makefile.mingw | 2 +- 4 files changed, 948 insertions(+), 4 deletions(-) create mode 100644 src/video/vid_nvidia.c create mode 100644 src/video/vid_nvidia.h diff --git a/src/video/vid_nvidia.c b/src/video/vid_nvidia.c new file mode 100644 index 000000000..48becc577 --- /dev/null +++ b/src/video/vid_nvidia.c @@ -0,0 +1,943 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * nVidia RIVA 128 emulation. + * + * Version: @(#)vid_nv_riva128.c 1.0.6 2018/04/26 + * + * Author: Melissa Goad + * Miran Grca, + * + * Copyright 2015-2018 Melissa Goad. + * Copyright 2015-2018 Miran Grca. + */ + +#include +#include +#include +#include +#include +#include "../86box.h" +#include "../cpu/cpu.h" +#include "../machine/machine.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../pic.h" +#include "../rom.h" +#include "../timer.h" +#include "../device.h" +#include "../plat.h" +#include "video.h" +#include "vid_nv_riva128.h" +#include "vid_svga.h" +#include "vid_svga_render.h" + +typedef struct riva128_t +{ + mem_mapping_t linear_mapping; + mem_mapping_t mmio_mapping; + + rom_t bios_rom; + + svga_t svga; + + uint8_t card_id; + int pci_card; + int is_nv3t; + + uint16_t vendor_id; + uint16_t device_id; + + uint32_t linear_base, linear_size; + + uint16_t rma_addr; + + uint8_t pci_regs[256]; + + int memory_size; + + uint8_t ext_regs_locked; + + uint8_t read_bank; + uint8_t write_bank; + + struct + { + uint32_t intr; + uint32_t intr_en; + uint32_t intr_line; + uint32_t enable; + } pmc; + + struct + { + uint32_t intr; + uint32_t intr_en; + } pbus; + + struct + { + uint32_t cache_error; + uint32_t intr; + uint32_t intr_en; + + uint32_t ramht; + uint32_t ramht_addr; + uint32_t ramht_size; + + uint32_t ramfc; + uint32_t ramfc_addr; + + uint32_t ramro; + uint32_t ramro_addr; + uint32_t ramro_size; + + uint16_t chan_mode; + uint16_t chan_dma; + uint16_t chan_size; //0 = 1024, 1 = 512 + + uint32_t runout_put, runout_get; + + struct + { + uint32_t dmaput; + uint32_t dmaget; + } channels[16]; + + struct + { + int chanid; + int push_enabled; + int runout; + uint32_t get, put; + uint32_t ctx; + } caches[2]; + + struct + { + int subchan; + uint16_t method; + uint32_t param; + } cache0, cache1[64]; + } pfifo; + + struct + { + uint32_t addr; + uint32_t data; + uint8_t access_reg[4]; + uint8_t mode; + } rma; + + struct + { + uint32_t intr, intr_en; + + uint64_t time; + uint32_t alarm; + + uint16_t clock_mul, clock_div; + } ptimer; + + struct + { + int width; + int bpp; + uint32_t config_0; + } pfb; + + struct + { + uint32_t boot_0; + } pextdev; + + struct + { + int pgraph_speedhack; + + uint32_t obj_handle[8]; + uint16_t obj_class[8]; + + uint32_t debug[5]; + + uint32_t intr; + uint32_t intr_en; + + uint32_t invalid; + uint32_t invalid_en; + + uint32_t ctx_switch[5]; + uint32_t ctx_control; + uint32_t ctx_user; + uint32_t ctx_cache[8][5]; + + uint32_t fifo_enable; + + uint32_t fifo_st2_addr; + uint32_t fifo_st2_data; + + uint32_t uclip_xmin, uclip_ymin, uclip_xmax, uclip_ymax; + uint32_t oclip_xmin, oclip_ymin, oclip_xmax, oclip_ymax; + + uint32_t src_canvas_min, src_canvas_max; + uint32_t dst_canvas_min, dst_canvas_max; + + uint8_t rop; + + uint32_t chroma; + + uint32_t beta; + + uint32_t notify; + + //NV3 + uint32_t surf_offset[4]; + uint32_t surf_pitch[4]; + + uint32_t cliprect_min[2]; + uint32_t cliprect_max[2]; + uint32_t cliprect_ctrl; + + uint32_t instance; + + uint32_t dma_intr, dma_intr_en; + + uint32_t status; + } pgraph; + + struct + { + uint32_t nvpll; + uint32_t nv_m,nv_n,nv_p; + + uint32_t mpll; + uint32_t m_m,m_n,m_p; + + uint32_t vpll; + uint32_t v_m,v_n,v_p; + + uint32_t pll_ctrl; + + uint32_t gen_ctrl; + } pramdac; + + uint32_t channels[16][8][0x2000]; + + struct + { + int scl; + int sda; + } i2c; + + int64_t mtime, mfreq; +} riva128_t; + +uint8_t riva128_rma_in(uint16_t addr, void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + svga_t* svga = &riva128->svga; + uint8_t ret = 0; + + addr &= 0xff; + + //pclog("RIVA 128 RMA read %04X %04X:%08X\n", addr, CS, cpu_state.pc); + + switch(addr) + { + case 0x00: + ret = 0x65; + break; + case 0x01: + ret = 0xd0; + break; + case 0x02: + ret = 0x16; + break; + case 0x03: + ret = 0x2b; + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + if(riva128->rma.addr < 0x1000000) /*ret = riva128_mmio_read((riva128->rma.addr + (addr & 3)) & 0xffffff, riva128);*/pclog("RIVA 128 MMIO write %08x %08x\n", riva128->rma.addr & 0xffffff, riva128->rma.data); + else ret = svga_read_linear((riva128->rma.addr - 0x1000000), svga); + break; + } + + return ret; +} + +void riva128_rma_out(uint16_t addr, uint8_t val, void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + svga_t* svga = &riva128->svga; + + addr &= 0xff; + + //pclog("RIVA 128 RMA write %04X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); + + switch(addr) + { + case 0x04: + riva128->rma.addr &= ~0xff; + riva128->rma.addr |= val; + break; + case 0x05: + riva128->rma.addr &= ~0xff00; + riva128->rma.addr |= (val << 8); + break; + case 0x06: + riva128->rma.addr &= ~0xff0000; + riva128->rma.addr |= (val << 16); + break; + case 0x07: + riva128->rma.addr &= ~0xff000000; + riva128->rma.addr |= (val << 24); + break; + case 0x08: + case 0x0c: + case 0x10: + case 0x14: + riva128->rma.data &= ~0xff; + riva128->rma.data |= val; + break; + case 0x09: + case 0x0d: + case 0x11: + case 0x15: + riva128->rma.data &= ~0xff00; + riva128->rma.data |= (val << 8); + break; + case 0x0a: + case 0x0e: + case 0x12: + case 0x16: + riva128->rma.data &= ~0xff0000; + riva128->rma.data |= (val << 16); + break; + case 0x0b: + case 0x0f: + case 0x13: + case 0x17: + riva128->rma.data &= ~0xff000000; + riva128->rma.data |= (val << 24); + if(riva128->rma.addr < 0x1000000) /*riva128_mmio_write_l(riva128->rma.addr & 0xffffff, riva128->rma.data, riva128);*/pclog("RIVA 128 MMIO write %08x %08x\n", riva128->rma.addr & 0xffffff, riva128->rma.data); + else svga_writel_linear((riva128->rma.addr - 0x1000000), riva128->rma.data, svga); + break; + } + + if(addr & 0x10) riva128->rma.addr+=4; +} + +uint8_t riva128_in(uint16_t addr, void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + svga_t* svga = &riva128->svga; + uint8_t ret = 0; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + // if (addr != 0x3da) pclog("S3 in %04X %04X:%08X ", addr, CS, cpu_state.pc); + switch (addr) + { + case 0x3D4: + ret = svga->crtcreg; + break; + case 0x3D5: + switch(svga->crtcreg) + { + case 0x28: + ret = svga->crtc[0x28] & 0x3f; + break; + case 0x34: + ret = svga->displine & 0xff; + break; + case 0x35: + ret = (svga->displine >> 8) & 7; + break; + case 0x3e: + //DDC status register + ret = (riva128->i2c.sda << 3) | (riva128->i2c.scl << 2); + break; + default: + ret = svga->crtc[svga->crtcreg]; + break; + } + //if(svga->crtcreg > 0x18) + // pclog("RIVA 128 Extended CRTC read %02X %04X:%08X\n", svga->crtcreg, CS, cpu_state.pc); + break; + default: + ret = svga_in(addr, svga); + break; + } + // if (addr != 0x3da) pclog("%02X\n", ret); + return ret; +} + +void riva128_out(uint16_t addr, uint8_t val, void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + + uint8_t old; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch(addr) + { + case 0x3D4: + svga->crtcreg = val; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + switch(svga->crtcreg) + { + case 0x1e: + riva128->read_bank = val; + if (svga->chain4) svga->read_bank = riva128->read_bank << 15; + else svga->read_bank = riva128->read_bank << 13; + break; + case 0x1d: + riva128->write_bank = val; + if (svga->chain4) svga->write_bank = riva128->write_bank << 15; + else svga->write_bank = riva128->write_bank << 13; + break; + case 0x19: + case 0x1a: + case 0x25: + case 0x28: + case 0x2d: + svga_recalctimings(svga); + break; + case 0x38: + riva128->rma.mode = val & 0xf; + break; + case 0x3f: + riva128->i2c.sda = (val >> 4) & 1; + riva128->i2c.scl = (val >> 5) & 1; + break; + } + //if(svga->crtcreg > 0x18) + // pclog("RIVA 128 Extended CRTC write %02X %02x %04X:%08X\n", svga->crtcreg, val, CS, cpu_state.pc); + if (old != val) + { + if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) + { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + return; + } + + svga_out(addr, val, svga); +} + +uint8_t riva128_pci_read(int func, int addr, void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + uint8_t ret = 0; + //pclog("RIVA 128 PCI read %02X %04X:%08X\n", addr, CS, cpu_state.pc); + switch (addr) + { + case 0x00: + ret = riva128->vendor_id & 0xff; + break; + case 0x01: + ret = riva128->vendor_id >> 8; + break; + + case 0x02: + ret = riva128->device_id & 0xff; + break; + case 0x03: + ret = riva128->device_id >> 8; + break; + + case 0x04: + ret = riva128->pci_regs[0x04] & 0x37; + break; + case 0x05: + ret = riva128->pci_regs[0x05] & 0x01; + break; + + case 0x06: + ret = 0x20; + break; + case 0x07: + ret = riva128->pci_regs[0x07] & 0x73; + break; + + case 0x08: + ret = 0x00; + 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 0x0e: + ret = 0x00; + break; /*Header type*/ + + case 0x13: + case 0x17: + ret = riva128->pci_regs[addr]; + break; + + case 0x2c: + case 0x2d: + case 0x2e: + case 0x2f: + ret = riva128->pci_regs[addr]; + //if(CS == 0x0028) output = 3; + break; + + case 0x30: + return riva128->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ + case 0x31: + return 0x00; + case 0x32: + return riva128->pci_regs[0x32]; + case 0x33: + return riva128->pci_regs[0x33]; + + case 0x34: + ret = 0x00; + break; + + case 0x3c: + ret = riva128->pci_regs[0x3c]; + break; + + case 0x3d: + ret = 0x01; + break; /*INTA*/ + + case 0x3e: + ret = 0x03; + break; + case 0x3f: + ret = 0x01; + break; + + } + // pclog("%02X\n", ret); + return ret; +} + +void riva128_reenable_svga_mappings(svga_t *svga) +{ + switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } +} + +void riva128_pci_write(int func, int addr, uint8_t val, void *p) +{ + //pclog("RIVA 128 PCI write %02X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); + riva128_t *riva128 = (riva128_t *)p; + svga_t* svga = &riva128->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: + return; + + case PCI_REG_COMMAND: + riva128->pci_regs[PCI_REG_COMMAND] = val & 0x27; + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&riva128->mmio_mapping); + mem_mapping_disable(&riva128->linear_mapping); + if (val & PCI_COMMAND_IO) + { + io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); + io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); + } + else io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); + if (val & PCI_COMMAND_MEM) + { + uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; + uint32_t linear_addr = riva128->pci_regs[0x17] << 24; + if (!mmio_addr && !linear_addr) + { + riva128_reenable_svga_mappings(svga); + } + if (mmio_addr) + { + mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); + } + if (linear_addr) + { + mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); + } + } + return; + + case 0x05: + riva128->pci_regs[0x05] = val & 0x01; + return; + + case 0x07: + riva128->pci_regs[0x07] = (riva128->pci_regs[0x07] & 0x8f) | (val & 0x70); + return; + + case 0x13: + { + uint32_t mmio_addr; + riva128->pci_regs[addr] = val; + mmio_addr = riva128->pci_regs[0x13] << 24; + mem_mapping_disable(&riva128->mmio_mapping); + if (mmio_addr) + { + mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); + } + return; + } + + case 0x17: + { + uint32_t linear_addr; + riva128->pci_regs[addr] = val; + linear_addr = riva128->pci_regs[0x17] << 24; + mem_mapping_disable(&riva128->linear_mapping); + if (linear_addr) + { + mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); + } + return; + } + + case 0x30: + case 0x32: + case 0x33: + riva128->pci_regs[addr] = val; + mem_mapping_disable(&riva128->bios_rom.mapping); + if (riva128->pci_regs[0x30] & 0x01) + { + uint32_t addr = (riva128->pci_regs[0x32] << 16) | (riva128->pci_regs[0x33] << 24); + // pclog("RIVA 128 bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&riva128->bios_rom.mapping, addr, 0x8000); + } + return; + + case 0x3c: + riva128->pci_regs[0x3c] = val & 0x0f; + return; + + case 0x40: + case 0x41: + case 0x42: + case 0x43: + riva128->pci_regs[addr - 0x14] = val; //0x40-0x43 are ways to write to 0x2c-0x2f + return; + } +} + +void riva128_recalctimings(svga_t *svga) +{ + riva128_t *riva128 = (riva128_t *)svga->p; + + svga->ma_latch += (svga->crtc[0x19] & 0x1f) << 16; + svga->rowoffset += (svga->crtc[0x19] & 0xe0) << 3; + if (svga->crtc[0x25] & 0x01) svga->vtotal += 0x400; + if (svga->crtc[0x25] & 0x02) svga->dispend += 0x400; + if (svga->crtc[0x25] & 0x04) svga->vblankstart += 0x400; + if (svga->crtc[0x25] & 0x08) svga->vsyncstart += 0x400; + if (svga->crtc[0x25] & 0x10) svga->htotal += 0x100; + if (svga->crtc[0x2d] & 0x01) svga->hdisp += 0x100; + //The effects of the large screen bit seem to just be doubling the row offset. + //However, these large modes still don't work. Possibly core SVGA bug? It does report 640x2 res after all. + //if (!(svga->crtc[0x1a] & 0x04)) svga->rowoffset <<= 1; + switch(svga->crtc[0x28] & 3) + { + case 1: + svga->bpp = 8; + svga->lowres = 0; + svga->render = svga_render_8bpp_highres; + break; + case 2: + svga->bpp = 16; + svga->lowres = 0; + svga->render = svga_render_16bpp_highres; + break; + case 3: + svga->bpp = 32; + svga->lowres = 0; + svga->render = svga_render_32bpp_highres; + break; + } + + /*if((svga->crtc[0x28] & 3) != 0) + { + if(svga->crtc[0x1a] & 2) svga_set_ramdac_type(svga, RAMDAC_6BIT); + else svga_set_ramdac_type(svga, RAMDAC_8BIT); + } + else svga_set_ramdac_type(svga, RAMDAC_6BIT);*/ + + double freq; + + if (((svga->miscout >> 2) & 2) == 2) + { + freq = 13500000.0; + + if(riva128->pramdac.v_m == 0) riva128->pramdac.v_m = 1; + else + { + freq = (freq * riva128->pramdac.v_n) / (1 << riva128->pramdac.v_p) / riva128->pramdac.v_m; + //pclog("RIVA 128 Pixel clock is %f Hz\n", freq); + } + + svga->clock = cpuclock / freq; + } + + if(riva128->card_id == 0x03) + { + freq = 13500000.0; + + if(riva128->pramdac.m_m == 0) riva128->pramdac.m_m = 1; + else + { + freq = (freq * riva128->pramdac.m_n) / (1 << riva128->pramdac.m_p) / riva128->pramdac.m_m; + //pclog("RIVA 128 Memory clock is %f Hz\n", freq); + } + + riva128->mfreq = freq; + riva128->mtime = (int64_t)((TIMER_USEC * 100000000.0) / riva128->mfreq); + } +} + + +void *riva128_init(const device_t *info) +{ + riva128_t *riva128 = malloc(sizeof(riva128_t)); + memset(riva128, 0, sizeof(riva128_t)); + + riva128->card_id = 0x03; + riva128->is_nv3t = 0; + + riva128->vendor_id = 0x12d2; + riva128->device_id = 0x0018; + + riva128->memory_size = device_get_config_int("memory"); + + svga_init(&riva128->svga, riva128, riva128->memory_size << 20, + riva128_recalctimings, + riva128_in, riva128_out, + NULL, NULL); + + riva128->svga.decode_mask = (riva128->memory_size << 20) - 1; + + rom_init(&riva128->bios_rom, L"roms/video/nv_riva128/Diamond_V330_rev-e.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (PCI) + mem_mapping_disable(&riva128->bios_rom.mapping); + + /*mem_mapping_add(&riva128->mmio_mapping, 0, 0, + riva128_mmio_read, + riva128_mmio_read_w, + riva128_mmio_read_l, + riva128_mmio_write, + riva128_mmio_write_w, + riva128_mmio_write_l, + NULL, + 0, + riva128);*/ + + mem_mapping_add(&riva128->linear_mapping, 0, 0, + svga_read_linear, + svga_readw_linear, + svga_readl_linear, + svga_write_linear, + svga_writew_linear, + svga_writel_linear, + NULL, + 0, + &riva128->svga); + + io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); + + // riva128->pci_regs[4] = 3; + riva128->pci_regs[4] = 7; + riva128->pci_regs[5] = 0; + riva128->pci_regs[6] = 0; + riva128->pci_regs[7] = 2; + + riva128->pci_regs[0x2c] = 0xd2; + riva128->pci_regs[0x2d] = 0x12; + riva128->pci_regs[0x2e] = 0x00; + riva128->pci_regs[0x2f] = 0x03; + + riva128->pci_regs[0x30] = 0x00; + riva128->pci_regs[0x32] = 0x0c; + riva128->pci_regs[0x33] = 0x00; + + riva128->pmc.intr = 0; + riva128->pbus.intr = 0; + riva128->pfifo.intr = 0; + riva128->pgraph.intr = 0; + riva128->ptimer.intr = 0; + + riva128->pci_card = pci_add_card(PCI_ADD_VIDEO, riva128_pci_read, riva128_pci_write, riva128); + + riva128->ptimer.clock_mul = 1; + riva128->ptimer.clock_div = 1; + + //default values so that the emulator can boot. These'll be overwritten by the video BIOS anyway. + riva128->pramdac.m_m = 0x03; + riva128->pramdac.m_n = 0xc2; + riva128->pramdac.m_p = 0x0d; + + //timer_add(riva128_mclk_poll, &riva128->mtime, &timer_one, riva128); + + return riva128; +} + +void riva128_close(void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + FILE *f = fopen("vram.dmp", "wb"); + fwrite(riva128->svga.vram, 4 << 20, 1, f); + fclose(f); + + svga_close(&riva128->svga); + + free(riva128); +} + +int riva128_available(void) +{ + return rom_present(L"roms/video/nv_riva128/Diamond_V330_rev-e.vbi"); +} + +void riva128_speed_changed(void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + + svga_recalctimings(&riva128->svga); +} + +void riva128_force_redraw(void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + + riva128->svga.fullchange = changeframecount; +} + +const device_config_t riva128_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, + { + { + "1 MB", 1 + }, + { + "2 MB", 2 + }, + { + "4 MB", 4 + }, + { + "" + } + }, + }, + { + "", "", -1 + } +}; + +#if 0 +const device_config_t riva128zx_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "8 MB", + .value = 8 + }, + { + .description = "" + } + }, + .default_int = 4 + }, + { + .type = -1 + } +}; +#endif + +const device_t riva128_device = +{ + "nVidia RIVA 128", + DEVICE_PCI, + 0, + riva128_init, + riva128_close, + NULL, + riva128_available, + riva128_speed_changed, + riva128_force_redraw, + riva128_config +}; \ No newline at end of file diff --git a/src/video/vid_nvidia.h b/src/video/vid_nvidia.h new file mode 100644 index 000000000..c55533d2c --- /dev/null +++ b/src/video/vid_nvidia.h @@ -0,0 +1 @@ +extern const device_t riva128_device; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 84e3a282e..3d69bf92e 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -48,7 +48,7 @@ #include "vid_mda.h" #ifdef DEV_BRANCH # ifdef USE_RIVA -# include "vid_nv_riva128.h" +# include "vid_nvidia.h" # endif #endif #include "vid_oak_oti.h" @@ -143,8 +143,8 @@ video_cards[] = { {"[PCI] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_pci", &s3_diamond_stealth64_pci_device, GFX_STEALTH64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, #if defined(DEV_BRANCH) && defined(USE_RIVA) {"[PCI] nVidia RIVA 128", "riva128", &riva128_device, GFX_RIVA128, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, - {"[PCI] nVidia RIVA TNT", "rivatnt", &rivatnt_device, GFX_RIVATNT, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, - {"[PCI] nVidia RIVA TNT2", "rivatnt2", &rivatnt2_device, GFX_RIVATNT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, + /*{"[PCI] nVidia RIVA TNT", "rivatnt", &rivatnt_device, GFX_RIVATNT, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, + {"[PCI] nVidia RIVA TNT2", "rivatnt2", &rivatnt2_device, GFX_RIVATNT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}},*/ #endif {"[PCI] Number Nine 9FX (S3 Trio64)", "n9_9fx_pci", &s3_9fx_pci_device, GFX_N9_9FX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, {"[PCI] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_pci", &s3_bahamas64_pci_device, GFX_BAHAMAS64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index e8ecbae10..ac37a4f70 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -377,7 +377,7 @@ endif ifeq ($(NV_RIVA), y) OPTS += -DUSE_RIVA -DEVBROBJ += vid_nv_riva128.o +DEVBROBJ += vid_nvidia.o endif ifeq ($(PAS16), y) From b90c64c456c1bdebd8bb49e357ca955a9f8b5db1 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 26 Apr 2018 10:42:05 -0500 Subject: [PATCH 4/4] Remove conflicts --- src/video/vid_svga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index da148849a..2fca45358 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -796,7 +796,7 @@ svga_init(svga_t *svga, void *p, int memsize, svga->vram_max = memsize; svga->vram_display_mask = svga->vram_mask = memsize - 1; svga->decode_mask = 0x7fffff; - svga->changedvram = malloc(memsize >> 12); + svga->changedvram = malloc(0x800000 >> 12); svga->recalctimings_ex = recalctimings_ex; svga->video_in = video_in; svga->video_out = video_out;