From 305d305173a7b041fca1b76e6d98470d6ac2c7c6 Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sun, 22 Jun 2025 17:34:54 +0100 Subject: [PATCH] Basic AGP support. Card is now detected, but can't get to desktop --- src/include/86box/nv/vid_nv.h | 1 + src/include/86box/nv/vid_nv3.h | 59 +++++++++++++++++ src/video/nv/nv3/nv3_core.c | 80 ++++++++++++++++++++++- src/video/nv/nv3/render/nv3_render_blit.c | 11 ++-- 4 files changed, 145 insertions(+), 6 deletions(-) diff --git a/src/include/86box/nv/vid_nv.h b/src/include/86box/nv/vid_nv.h index 84ccf5a15..8a8e2985c 100644 --- a/src/include/86box/nv/vid_nv.h +++ b/src/include/86box/nv/vid_nv.h @@ -131,6 +131,7 @@ typedef struct nv_base_s void* i2c; // I2C for monitor EDID void* ddc; // Display Data Channel for EDID uint32_t last_buffer_address; // Last buffer address. + bool agp_enabled; // AGP Enabled (for debugging) } nv_base_t; #define NV_REG_LIST_END 0xD15EA5E diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index 632ee01fa..80307a5ea 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -140,6 +140,8 @@ extern const device_config_t nv3t_config[]; // Confi #define NV3_PCI_CFG_VBIOS_BASE_L 0x32 #define NV3_PCI_CFG_VBIOS_BASE_H 0x33 +#define NV3_AGP_CAPABILITIES_POINTER 0x34 + #define NV3_PCI_CFG_INT_LINE 0x3C #define NV3_PCI_CFG_INT_PIN 0x3D @@ -151,6 +153,63 @@ extern const device_config_t nv3t_config[]; // Confi #define NV3_PCI_CFG_MAX_LATENCY 0x3F #define NV3_PCI_CFG_MAX_LATENCY_DEFAULT 0x01 +// +// AGP configuration +// + +#define NV3_AGP_START 0x44 + +// stupid stupid pci system +#define NV3_AGP_CAPABILITIES_START 0x44 +#define NV3_AGP_CAPABILITIES_CAP_ID 0x44 +#define NV3_AGP_CAPABILITIES_CAP_ID_AGP 0x02 // "AGP" +#define NV3_AGP_CAPABILITIES_NEXT_PTR 0x45 +#define NV3_AGP_CAPABILITIES_AGP_VERSION 0x46 +#define NV3_AGP_CAPABILITIES_AGP_VERSION_MINOR 0 +#define NV3_AGP_CAPABILITIES_AGP_VERSION_MAJOR 4 +#define NV3_AGP_CAPABILITIES_H 0x47 + +#define NV3_AGP_STATUS_RATE 0x48 +#define NV3_AGP_STATUS_RATE_1X_SUPPORTED 0x1 +#define NV3_AGP_STATUS_RATE_2X_SUPPORTED 0x2 + +#define NV3_AGP_STATUS_BYTE1 0x49 +#define NV3_AGP_STATUS_BYTE1_SBA 1 +#define NV3_AGP_STATUS_SBA_SUPPORTED 0x0 +#define NV3_AGP_STATUS_SBA_UNSUPPORTED 0x1 +#define NV3_AGP_STATUS_MAX_REQUESTS 0x4B +#define NV3_AGP_STATUS_MAX_REQUESTS_AMOUNT 4 + +#define NV3_AGP_COMMAND 0x4C +#define NV3_AGP_COMMAND_DATA_RATE 0 +#define NV3_AGP_COMMAND_DATA_RATE_1X 0x1 +#define NV3_AGP_COMMAND_DATA_RATE_2X 0x2 +#define NV3_AGP_COMMAND_BYTE1 0x4D +#define NV3_AGP_COMMAND_BYTE1_ENABLE 0 +#define NV3_AGP_COMMAND_BYTE1_ENABLE_DISABLED 0x0 +#define NV3_AGP_COMMAND_BYTE1_ENABLE_ENABLED 0x1 +#define NV3_AGP_COMMAND_SBA_ENABLE 1 +#define NV3_AGP_COMMAND_SBA_ENABLE_DISABLED 0x0 +#define NV3_AGP_COMMAND_SBA_ENABLE_ENABLED 0x1 +#define NV3_AGP_COMMAND_REQUEST_DEPTH 0x4F + +#define NV3_AGP_END 0x4F + +// +// ACPI (NV3T only) +// TODO: IMPLEMENT THIS!!!!!! +// +#define NV3_POWER_CAP_ID 0x60 +#define NV3_POWER_NEXT_PTR 0x61 +#define NV3_POWER_VERSION 0x62 + +// "The RIVA128ZX does not physically change its power consumption when +// POWER_STATE is modified." +#define NV3_POWER_STATE 0x64 + +#define NV3_POWER_STATE_D0 0x0 +#define NV3_POWER_STATE_D3HOT 0x3 + // GPU Subsystems // These most likely correspond to functional blocks in the original design diff --git a/src/video/nv/nv3/nv3_core.c b/src/video/nv/nv3/nv3_core.c index 39aa0178d..e97c5fa1f 100644 --- a/src/video/nv/nv3/nv3_core.c +++ b/src/video/nv/nv3/nv3_core.c @@ -235,6 +235,46 @@ void nv3_mmio_write32(uint32_t addr, uint32_t val, void* priv) nv3_mmio_arbitrate_write(addr, val); } +// AGP read function +uint8_t nv3_agp_read(int32_t func, int32_t addr) +{ + uint8_t ret = 0x00; + + switch (addr) + { + case NV3_AGP_CAPABILITIES_CAP_ID: + ret = NV3_AGP_CAPABILITIES_CAP_ID_AGP; // AGP capable device + break; + case NV3_AGP_CAPABILITIES_NEXT_PTR: // Always off + ret = 0x00; + case NV3_AGP_CAPABILITIES_AGP_VERSION: + ret = (0x1 << NV3_AGP_CAPABILITIES_AGP_VERSION_MAJOR) | NV3_AGP_CAPABILITIES_AGP_VERSION_MINOR; + break; + case NV3_AGP_STATUS_RATE: + // NV3T = AGP 2X, NV3 = AGP 1X + if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_C00) + ret = NV3_AGP_STATUS_RATE_1X_SUPPORTED | NV3_AGP_STATUS_RATE_2X_SUPPORTED; + else + ret = NV3_AGP_STATUS_RATE_1X_SUPPORTED; + break; + case NV3_AGP_STATUS_BYTE1: + ret = 0x00; // SBA not supported + break; + case NV3_AGP_STATUS_MAX_REQUESTS: + ret = NV3_AGP_STATUS_MAX_REQUESTS_AMOUNT; + break; + // This is also used for SBA but SBA is always off so we can use a bool + case NV3_AGP_COMMAND_BYTE1: + ret = nv3->nvbase.agp_enabled; + break; + default: + ret = nv3->pci_config.pci_regs[addr]; + break; + } + + return ret; +} + // PCI stuff // BAR0 Pointer to MMIO space // BAR1 Pointer to Linear Framebuffer (NV_USER) @@ -332,7 +372,7 @@ uint8_t nv3_pci_read(int32_t func, int32_t addr, void* priv) case NV3_PCI_CFG_BAR0_L: case NV3_PCI_CFG_BAR1_L: // only bit that matters is bit 3 (prefetch bit) - ret =(NV3_PCI_CFG_BAR_PREFETCHABLE_ENABLED << NV3_PCI_CFG_BAR_PREFETCHABLE); + ret = (NV3_PCI_CFG_BAR_PREFETCHABLE_ENABLED << NV3_PCI_CFG_BAR_PREFETCHABLE); break; // These registers are hardwired to zero per the datasheet @@ -355,6 +395,13 @@ uint8_t nv3_pci_read(int32_t func, int32_t addr, void* priv) ret = nv3->pci_config.vbios_enabled; break; + case NV3_AGP_CAPABILITIES_POINTER: + if (nv3->nvbase.bus_generation >= nv_bus_agp_1x) + ret = NV3_AGP_CAPABILITIES_START; + else + ret = 0x00; + break; + case NV3_PCI_CFG_INT_LINE: ret = nv3->pci_config.int_line; break; @@ -381,6 +428,15 @@ uint8_t nv3_pci_read(int32_t func, int32_t addr, void* priv) ret = nv3->pci_config.pci_regs[NV3_PCI_CFG_SUBSYSTEM_ID + (addr & 0x03)]; break; + case NV3_AGP_START ... NV3_AGP_END: + if (nv3->nvbase.bus_generation < nv_bus_agp_1x) + break; + + ret = nv3_agp_read(func, addr); + + break; + + default: // by default just return pci_config.pci_regs ret = nv3->pci_config.pci_regs[addr]; break; @@ -391,6 +447,20 @@ uint8_t nv3_pci_read(int32_t func, int32_t addr, void* priv) return ret; } +void nv3_agp_write(int32_t func, int32_t addr, uint8_t val) +{ + nv3->pci_config.pci_regs[addr] = val; + + switch (addr) + { + case NV3_AGP_COMMAND_BYTE1: + nv3->nvbase.agp_enabled = val; + break; + default: + break; + } +} + void nv3_pci_write(int32_t func, int32_t addr, uint8_t val, void* priv) { @@ -489,6 +559,14 @@ void nv3_pci_write(int32_t func, int32_t addr, uint8_t val, void* priv) nv3->pci_config.pci_regs[NV3_PCI_CFG_SUBSYSTEM_ID + (addr & 0x03)] = val; break; + case NV3_AGP_START ... NV3_AGP_END: + if (nv3->nvbase.bus_generation < nv_bus_agp_1x) + break; + + nv3_agp_write(func, addr, val); + + break; + default: break; } diff --git a/src/video/nv/nv3/render/nv3_render_blit.c b/src/video/nv/nv3/render/nv3_render_blit.c index 9bf87ec6d..c1b221648 100644 --- a/src/video/nv/nv3/render/nv3_render_blit.c +++ b/src/video/nv/nv3/render/nv3_render_blit.c @@ -140,12 +140,13 @@ void nv3_render_blit_screen2screen(nv3_grobj_t grobj) /* Coordinates for copying an entire line at a time */ uint32_t buf_position = 0, vram_position = 0, size_x = nv3->pgraph.blit.size.x; - /* Read the old pixel into the line buffer - Assumption: All data is sent in an unpacked format. In the case of an NVIDIA GPU this means that all data is sent 32 bits at a time regardless of if - the actual source data is 32 bits in size or not. For pixel data, the upper bits are left as 0 in 8bpp/16bpp mode. For 86box purposes, the data is written - 8/16 bits at a time. + /* + Read the old pixel into the line buffer + Assumption: All data is sent in an unpacked format. In the case of an NVIDIA GPU this means that all data is sent 32 bits at a time regardless of if + the actual source data is 32 bits in size or not. For pixel data, the upper bits are left as 0 in 8bpp/16bpp mode. For 86box purposes, the data is written + 8/16 bits at a time. - TODO: CHECK FOR PACKED FORMAT!!!!! + TODO: CHECK FOR PACKED FORMAT!!!!! */ if (nv3->nvbase.svga.bpp == 15