mirror of
https://github.com/StrikerX3/StrikeBox.git
synced 2024-06-23 14:53:22 -04:00
Stub all NV2A engines
This commit is contained in:
parent
c49ed8dffa
commit
170558276b
46
modules/core/include/strikebox/hw/gpu/engine.h
Normal file
46
modules/core/include/strikebox/hw/gpu/engine.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Abstract base class for NV2A engines
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "state.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// Abstract base class of all NV2A engines.
|
||||
class NV2AEngine {
|
||||
public:
|
||||
NV2AEngine(const std::string name, const uint32_t offset, const uint32_t length, const NV2A& nv2a)
|
||||
: m_name(name)
|
||||
, m_offset(offset)
|
||||
, m_length(length)
|
||||
, m_offsetEnd(offset + length)
|
||||
, m_nv2a(nv2a)
|
||||
{}
|
||||
|
||||
virtual uint32_t Read(const uint32_t addr, const uint8_t size) = 0;
|
||||
virtual void Write(const uint32_t addr, const uint32_t value, const uint8_t size) = 0;
|
||||
|
||||
const std::string GetName() const noexcept { return m_name; }
|
||||
const uint32_t GetOffset() const noexcept { return m_offset; }
|
||||
const uint32_t GetLength() const noexcept { return m_length; }
|
||||
|
||||
const bool Contains(uint32_t address) const noexcept { return address >= m_offset && address < m_offsetEnd; }
|
||||
|
||||
private:
|
||||
const std::string m_name;
|
||||
const uint32_t m_offset;
|
||||
const uint32_t m_length;
|
||||
const uint32_t m_offsetEnd; // m_offset + m_length, precomputed for speed
|
||||
const NV2A& m_nv2a;
|
||||
};
|
||||
|
||||
}
|
57
modules/core/include/strikebox/hw/gpu/nv2a.h
Normal file
57
modules/core/include/strikebox/hw/gpu/nv2a.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
// StrikeBox NV2A emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// NV2A is a custom GPU designed by Nvidia for the Original Xbox. Internally,
|
||||
// the chip is split up into different engines that are mapped to distinct
|
||||
// regions of the system memory allocated to the device:
|
||||
//
|
||||
// Engine Offset Length Description
|
||||
// ----------------------------------------------------------------------------
|
||||
// PMC 0x000000 0x1000 Master control
|
||||
// PBUS 0x001000 0x1000 Bus control
|
||||
// PFIFO 0x002000 0x2000 MMIO and DMA FIFO submission to PGRAPH (there's no VPE in NV2A)
|
||||
// PRMA 0x007000 0x1000 Real mode BAR access
|
||||
// PVIDEO 0x008000 0x1000 Video overlay
|
||||
// PTIMER 0x009000 0x1000 Time measurement and time-based alarms
|
||||
// PCOUNTER 0x00A000 0x1000 Performance monitoring counters
|
||||
// PNVIO 0x0C0000 0x1000 VGA sequencer and graph controller registers
|
||||
// PFB 0x100000 0x1000 Memory interface
|
||||
// PSTRAPS 0x101000 0x1000 Straps readout
|
||||
// PROM 0x300000 0x20000 ROM access window
|
||||
// PGRAPH 0x400000 0x2000 2D/3D graphics engine
|
||||
// PCRTC 0x600000 0x1000 CRTC controls
|
||||
// PRMCIO 0x601000 0x1000 VGA CRTC and attribute controller registers
|
||||
// PRAMDAC 0x680000 0x1000 RAMDAC, video overlay, cursor, and PLL control
|
||||
// PRMDIO 0x681000 0x1000 VGA DAC registers
|
||||
// PRAMIN 0x700000 0x100000 RAMIN access
|
||||
// USER 0x800000 0x200000 PFIFO MMIO/DMA submission area
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "state.h"
|
||||
#include "engine.h"
|
||||
|
||||
#include "pmc.h"
|
||||
#include "pbus.h"
|
||||
#include "pfifo.h"
|
||||
#include "prma.h"
|
||||
#include "pvideo.h"
|
||||
#include "ptimer.h"
|
||||
#include "pcounter.h"
|
||||
#include "pnvio.h"
|
||||
#include "pfb.h"
|
||||
#include "pstraps.h"
|
||||
#include "prom.h"
|
||||
#include "pgraph.h"
|
||||
#include "pcrtc.h"
|
||||
#include "prmcio.h"
|
||||
#include "pramdac.h"
|
||||
#include "prmdio.h"
|
||||
#include "pramin.h"
|
||||
#include "user.h"
|
31
modules/core/include/strikebox/hw/gpu/pbus.h
Normal file
31
modules/core/include/strikebox/hw/gpu/pbus.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
// StrikeBox NV2A PBUS (Bus control) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// [https://envytools.readthedocs.io/en/latest/hw/bus/pbus.html]
|
||||
// "PBUS is present on all nvidia cards.
|
||||
// In theory, it deals with "bus control". In practice, it accumulates all sort of junk nobody bothered to create a special area for.
|
||||
// It is unaffected by any PMC.ENABLE bits."
|
||||
//
|
||||
// PBUS engine registers occupy the range 0x001000..0x001FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A bus control engine (PBUS)
|
||||
class PBUS : public NV2AEngine {
|
||||
public:
|
||||
PBUS(const NV2A& nv2a) : NV2AEngine("PBUS", 0x001000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
33
modules/core/include/strikebox/hw/gpu/pcounter.h
Normal file
33
modules/core/include/strikebox/hw/gpu/pcounter.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
// StrikeBox NV2A PCOUNTER (Performance monitoring counters) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// [https://envytools.readthedocs.io/en/latest/hw/pcounter/intro.html]
|
||||
// "PCOUNTER is the card units that contains performance monitoring counters.
|
||||
// [...]
|
||||
// PCOUNTER is actually made of several identical hardware counter units, one for each so-called domain.
|
||||
// Each PCOUNTER domain can potentially run on a different source clock, allowing one to monitor events in various clock domains.
|
||||
// The PCOUNTER domains are mostly independent, but there's some limitted communication and shared circuitry among them."
|
||||
//
|
||||
// PCOUNTER engine registers occupy the range 0x00A000..0x00AFFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A performance monitoring counters engine (PCOUNTER)
|
||||
class PCOUNTER : public NV2AEngine {
|
||||
public:
|
||||
PCOUNTER(const NV2A& nv2a) : NV2AEngine("PCOUNTER", 0x00A000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
26
modules/core/include/strikebox/hw/gpu/pcrtc.h
Normal file
26
modules/core/include/strikebox/hw/gpu/pcrtc.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// StrikeBox NV2A PCRTC (CRTC controls) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// PCRTC engine registers occupy the range 0x600000..0x600FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A CRTC controls engine (PCRTC)
|
||||
class PCRTC : public NV2AEngine {
|
||||
public:
|
||||
PCRTC(const NV2A& nv2a) : NV2AEngine("PCRTC", 0x600000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
26
modules/core/include/strikebox/hw/gpu/pfb.h
Normal file
26
modules/core/include/strikebox/hw/gpu/pfb.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// StrikeBox NV2A PFB (Memory interface) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// PFB engine registers occupy the range 0x100000..0x100FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A memory interface engine (PFB)
|
||||
class PFB : public NV2AEngine {
|
||||
public:
|
||||
PFB(const NV2A& nv2a) : NV2AEngine("PFB", 0x100000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
32
modules/core/include/strikebox/hw/gpu/pfifo.h
Normal file
32
modules/core/include/strikebox/hw/gpu/pfifo.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
// StrikeBox NV2A PFIFO (MMIO and DMA FIFO submission to PGRAPH) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// [https://envytools.readthedocs.io/en/latest/hw/fifo/intro.html]
|
||||
// "Commands to most of the engines are sent through a special engine called PFIFO.
|
||||
// PFIFO maintains multiple fully independent command queues, known as "channels" or "FIFO"s.
|
||||
// Each channel is controlled through a "channel control area", which is a region of MMIO.
|
||||
// PFIFO intercepts all accesses to that area and acts upon them."
|
||||
//
|
||||
// PFIFO engine registers occupy the range 0x002000..0x003FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A MMIO and DMA FIFO submission to PGRAPH engine (PFIFO)
|
||||
class PFIFO : public NV2AEngine {
|
||||
public:
|
||||
PFIFO(const NV2A& nv2a) : NV2AEngine("PFIFO", 0x002000, 0x2000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
28
modules/core/include/strikebox/hw/gpu/pgraph.h
Normal file
28
modules/core/include/strikebox/hw/gpu/pgraph.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
// StrikeBox NV2A PGRAPH (2D/3D graphics engine) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// PGRAPH is the main engine responsible for 2D/3D graphics command processing.
|
||||
//
|
||||
// PGRAPH engine registers occupy the range 0x400000..0x401FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A 2D/3D graphics engine (PGRAPH)
|
||||
class PGRAPH : public NV2AEngine {
|
||||
public:
|
||||
PGRAPH(const NV2A& nv2a) : NV2AEngine("PGRAPH", 0x400000, 0x2000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
30
modules/core/include/strikebox/hw/gpu/pmc.h
Normal file
30
modules/core/include/strikebox/hw/gpu/pmc.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
// StrikeBox NV2A PMC (Master control) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// [https://envytools.readthedocs.io/en/latest/hw/bus/pmc.html]
|
||||
// "PMC is the "master control" engine of the card. Its purpose is to provide card identication,
|
||||
// manage enable/disable bits of other engines, and handle top-level interrupt routing."
|
||||
//
|
||||
// PMC engine registers occupy the range 0x000000..0x000FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A master control engine (PMC)
|
||||
class PMC : public NV2AEngine {
|
||||
public:
|
||||
PMC(const NV2A& nv2a) : NV2AEngine("PMC", 0x000000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
26
modules/core/include/strikebox/hw/gpu/pnvio.h
Normal file
26
modules/core/include/strikebox/hw/gpu/pnvio.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// StrikeBox NV2A PNVIO (VGA sequencer and graph controller registers) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// PNVIO engine registers occupy the range 0x0C0000..0x0C0FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A VGA sequencer and graph controller registers (PNVIO)
|
||||
class PNVIO : public NV2AEngine {
|
||||
public:
|
||||
PNVIO(const NV2A& nv2a) : NV2AEngine("PNVIO", 0x0C0000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
26
modules/core/include/strikebox/hw/gpu/pramdac.h
Normal file
26
modules/core/include/strikebox/hw/gpu/pramdac.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// StrikeBox NV2A PRAMDAC (RAMDAC, video overlay, cursor, and PLL control) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// PRAMDAC engine registers occupy the range 0x680000..0x680FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A RAMDAC, video overlay, cursor, and PLL control engine (PRAMDAC)
|
||||
class PRAMDAC : public NV2AEngine {
|
||||
public:
|
||||
PRAMDAC(const NV2A& nv2a) : NV2AEngine("PRAMDAC", 0x680000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
28
modules/core/include/strikebox/hw/gpu/pramin.h
Normal file
28
modules/core/include/strikebox/hw/gpu/pramin.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
// StrikeBox NV2A PRAMIN (RAMIN access) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// PRAMIN contains a memory area reserved by the kernel used to describe GPU objects.
|
||||
//
|
||||
// PRAMIN engine registers occupy the range 0x700000..0x7FFFFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A RAMIN access engine (PRAMIN)
|
||||
class PRAMIN : public NV2AEngine {
|
||||
public:
|
||||
PRAMIN(const NV2A& nv2a) : NV2AEngine("PRAMIN", 0x700000, 0x100000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
28
modules/core/include/strikebox/hw/gpu/prma.h
Normal file
28
modules/core/include/strikebox/hw/gpu/prma.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
// StrikeBox NV2A PRMA (Real mode BAR access) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// PRMA provides access to BAR registers through real mode.
|
||||
//
|
||||
// PRMA engine registers occupy the range 0x007000..0x007FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A real mode BAR access (PRMA)
|
||||
class PRMA : public NV2AEngine {
|
||||
public:
|
||||
PRMA(const NV2A& nv2a) : NV2AEngine("PRMA", 0x007000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
26
modules/core/include/strikebox/hw/gpu/prmcio.h
Normal file
26
modules/core/include/strikebox/hw/gpu/prmcio.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// StrikeBox NV2A PRMCIO (VGA CRTC and attribute controller registers) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// PRMCIO engine registers occupy the range 0x601000..0x601FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A VGA CRTC and attribute controller registers engine (PRMCIO)
|
||||
class PRMCIO : public NV2AEngine {
|
||||
public:
|
||||
PRMCIO(const NV2A& nv2a) : NV2AEngine("PRMCIO", 0x601000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
26
modules/core/include/strikebox/hw/gpu/prmdio.h
Normal file
26
modules/core/include/strikebox/hw/gpu/prmdio.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// StrikeBox NV2A PRMDIO (VGA DAC registers) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// PRMDIO engine registers occupy the range 0x681000..0x681FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A VGA DAC registers engine (PRMDIO)
|
||||
class PRMDIO : public NV2AEngine {
|
||||
public:
|
||||
PRMDIO(const NV2A& nv2a) : NV2AEngine("PRMDIO", 0x681000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
26
modules/core/include/strikebox/hw/gpu/prom.h
Normal file
26
modules/core/include/strikebox/hw/gpu/prom.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// StrikeBox NV2A PROM (ROM access window) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// PROM engine registers occupy the range 0x300000..0x31FFFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A ROM access window engine (PROM)
|
||||
class PROM : public NV2AEngine {
|
||||
public:
|
||||
PROM(const NV2A& nv2a) : NV2AEngine("PROM", 0x300000, 0x20000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
36
modules/core/include/strikebox/hw/gpu/pstraps.h
Normal file
36
modules/core/include/strikebox/hw/gpu/pstraps.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
// StrikeBox NV2A PSTRAPS (Straps readout) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// [https://envytools.readthedocs.io/en/latest/hw/io/pstraps.html]
|
||||
// "The nvidia GPU chips are used in multiple cards from multiple manufacturers.
|
||||
// Thus, the a single GPU can end up in many different configurations, with varying memory amount, memory type, bus type,
|
||||
// TV norm, crystal frequency, and many other parameters. Since the GPU often needs to know what configuration it is used in,
|
||||
// a "straps" mechanism was invented to tell it this information.
|
||||
// On the first few cycles after reset, the memory bus pins are sampled. Since nothing else is driving them at that point,
|
||||
// their logic state is decided by the pull-up or pull-down resistors placed by board manufacturer.
|
||||
// The value this read is used as the "straps" value and is used to configure many aspects of GPU operation.
|
||||
// Some of the straps are not used by the GPU itself, but are intended for use by the BIOS or the driver."
|
||||
//
|
||||
// PSTRAPS engine registers occupy the range 0x101000..0x101FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A straps readout engine (PSTRAPS)
|
||||
class PSTRAPS : public NV2AEngine {
|
||||
public:
|
||||
PSTRAPS(const NV2A& nv2a) : NV2AEngine("PSTRAPS", 0x101000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
33
modules/core/include/strikebox/hw/gpu/ptimer.h
Normal file
33
modules/core/include/strikebox/hw/gpu/ptimer.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
// StrikeBox NV2A PTIMER (Time measurement and time-based alarms) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// [https://envytools.readthedocs.io/en/latest/hw/bus/ptimer.html]
|
||||
// "PTIMER is a small functional unit used to measure time by the card.
|
||||
// It has a 56-bit tick counter connected to a programmable clock source.
|
||||
// The current value of this counter is used for timestamping by many other units on the GPU.
|
||||
// Two such timestamps can be substracted to get the wall time elapsed between their creation and measure eg. command execution time.
|
||||
// Also, it's possible to set up an interrupt that will be triggered when the low 27 bits of the counter reach a specified value."
|
||||
//
|
||||
// PTIMER engine registers occupy the range 0x009000..0x009FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A time measurement and time-based alarms (PTIMER)
|
||||
class PTIMER : public NV2AEngine {
|
||||
public:
|
||||
PTIMER(const NV2A& nv2a) : NV2AEngine("PTIMER", 0x009000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
26
modules/core/include/strikebox/hw/gpu/pvideo.h
Normal file
26
modules/core/include/strikebox/hw/gpu/pvideo.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// StrikeBox NV2A PVIDEO (Video overlay) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// PVIDEO engine registers occupy the range 0x008000..0x008FFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A video overlay engine (PVIDEO)
|
||||
class PVIDEO : public NV2AEngine {
|
||||
public:
|
||||
PVIDEO(const NV2A& nv2a) : NV2AEngine("PVIDEO", 0x008000, 0x1000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
18
modules/core/include/strikebox/hw/gpu/state.h
Normal file
18
modules/core/include/strikebox/hw/gpu/state.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
// StrikeBox NV2A state class
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#pragma once
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// Represents the state of the NV2A GPU.
|
||||
class NV2A {
|
||||
|
||||
};
|
||||
|
||||
}
|
29
modules/core/include/strikebox/hw/gpu/user.h
Normal file
29
modules/core/include/strikebox/hw/gpu/user.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
// StrikeBox NV2A USER (PFIFO MMIO/DMA submission area) emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
//
|
||||
// The USER area is a portion of shared system memory where FIFO commands are submitted
|
||||
// for processing by the GPU.
|
||||
//
|
||||
// USER engine registers occupy the range 0x800000..0x9FFFFF.
|
||||
#pragma once
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
// NV2A PFIFO MMIO/DMA submission area (USER)
|
||||
class USER : public NV2AEngine {
|
||||
public:
|
||||
USER(const NV2A& nv2a) : NV2AEngine("USER", 0x800000, 0x200000, nv2a) {}
|
||||
|
||||
uint32_t Read(const uint32_t addr, const uint8_t size) override;
|
||||
void Write(const uint32_t addr, const uint32_t value, const uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,7 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
|
||||
#include "pci.h"
|
||||
#include "../basic/irq.h"
|
||||
#include "../gpu/nv2a.h"
|
||||
|
||||
namespace strikebox {
|
||||
|
||||
|
@ -23,6 +28,32 @@ private:
|
|||
uint8_t *m_pSystemRAM;
|
||||
uint32_t m_systemRAMSize;
|
||||
IRQHandler& m_irqHandler;
|
||||
|
||||
// NV2A state and engines
|
||||
nv2a::NV2A m_nv2a;
|
||||
nv2a::PMC m_pmc { m_nv2a };
|
||||
nv2a::PBUS m_pbus { m_nv2a };
|
||||
nv2a::PFIFO m_pfifo { m_nv2a };
|
||||
nv2a::PRMA m_prma { m_nv2a };
|
||||
nv2a::PVIDEO m_pvideo { m_nv2a };
|
||||
nv2a::PTIMER m_ptimer { m_nv2a };
|
||||
nv2a::PCOUNTER m_pcounter{ m_nv2a };
|
||||
nv2a::PNVIO m_pnvio { m_nv2a };
|
||||
nv2a::PFB m_pfb { m_nv2a };
|
||||
nv2a::PSTRAPS m_pstraps { m_nv2a };
|
||||
nv2a::PROM m_prom { m_nv2a };
|
||||
nv2a::PGRAPH m_pgraph { m_nv2a };
|
||||
nv2a::PCRTC m_pcrtc { m_nv2a };
|
||||
nv2a::PRMCIO m_prmcio { m_nv2a };
|
||||
nv2a::PRAMDAC m_pramdac { m_nv2a };
|
||||
nv2a::PRMDIO m_prmdio { m_nv2a };
|
||||
nv2a::PRAMIN m_pramin { m_nv2a };
|
||||
nv2a::USER m_user { m_nv2a };
|
||||
|
||||
// Fast engine lookup
|
||||
std::map<uint32_t, nv2a::NV2AEngine&> engines;
|
||||
void RegisterEngine(nv2a::NV2AEngine& engine);
|
||||
std::optional<std::reference_wrapper<nv2a::NV2AEngine>> FindEngine(const uint32_t address);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
24
modules/core/src/common/strikebox/hw/gpu/pbus.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pbus.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PBUS (Bus control) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pbus.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PBUS::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PBUS::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PBUS::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PBUS::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/pcounter.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pcounter.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PCOUNTER (Performance monitoring counters) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pcounter.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PCOUNTER::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PCOUNTER::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PCOUNTER::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PCOUNTER::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/pcrtc.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pcrtc.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PCRTC (CRTC controls) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pcrtc.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PCRTC::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PCRTC::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PCRTC::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PCRTC::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/pfb.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pfb.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PFB (Memory interface) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pfb.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PFB::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PFB::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PFB::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PFB::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/pfifo.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pfifo.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PFIFO (MMIO and DMA FIFO submission to PGRAPH) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pfifo.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PFIFO::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PFIFO::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PFIFO::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PFIFO::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/pgraph.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pgraph.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PGRAPH (2D/3D graphics engine) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pgraph.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PGRAPH::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PGRAPH::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PGRAPH::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PGRAPH::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/pmc.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pmc.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PMC (Master control) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pmc.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PMC::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PMC::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PMC::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PMC::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/pnvio.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pnvio.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PNVIO (VGA sequencer and graph controller registers) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pnvio.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PNVIO::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PNVIO::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PNVIO::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PNVIO::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/pramdac.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pramdac.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PRAMDAC (RAMDAC, video overlay, cursor, and PLL control) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pramdac.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PRAMDAC::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PRAMDAC::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PRAMDAC::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PRAMDAC::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/pramin.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pramin.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PRAMIN (RAMIN access) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pramin.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PRAMIN::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PRAMIN::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PRAMIN::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PRAMIN::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/prma.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/prma.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PRMA (Real mode BAR access) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/prma.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PRMA::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PRMA::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PRMA::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PRMA::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/prmcio.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/prmcio.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PRMCIO (VGA CRTC and attribute controller registers) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/prmcio.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PRMCIO::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PRMCIO::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PRMCIO::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PRMCIO::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/prmdio.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/prmdio.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PRMDIO (VGA DAC registers) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/prmdio.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PRMDIO::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PRMDIO::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PRMDIO::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PRMDIO::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/prom.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/prom.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PROM (ROM access window) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/prom.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PROM::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PROM::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PROM::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PROM::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/pstraps.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pstraps.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PSTRAPS (Straps readout) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pstraps.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PSTRAPS::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PSTRAPS::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PSTRAPS::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PSTRAPS::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/ptimer.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/ptimer.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PTIMER (Time measurement and time-based alarms) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/ptimer.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PTIMER::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PTIMER::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PTIMER::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PTIMER::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/pvideo.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/pvideo.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A PVIDEO (Video overlay) engine emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/pvideo.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t PVIDEO::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] PVIDEO::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PVIDEO::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] PVIDEO::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
24
modules/core/src/common/strikebox/hw/gpu/user.cpp
Normal file
24
modules/core/src/common/strikebox/hw/gpu/user.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
// StrikeBox NV2A USER (PFIFO MMIO/DMA submission area) emulation
|
||||
// (C) Ivan "StrikerX3" Oliveira
|
||||
//
|
||||
// Based on envytools:
|
||||
// https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// References to particular items in the documentation are denoted between
|
||||
// brackets optionally followed by a quote from the documentation.
|
||||
#include "strikebox/hw/gpu/user.h"
|
||||
|
||||
#include "strikebox/log.h"
|
||||
|
||||
namespace strikebox::nv2a {
|
||||
|
||||
uint32_t USER::Read(const uint32_t addr, const uint8_t size) {
|
||||
log_spew("[NV2A] USER::Read: Unimplemented read! address = 0x%x, size = %u\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USER::Write(const uint32_t addr, const uint32_t value, const uint8_t size) {
|
||||
log_spew("[NV2A] USER::Write: Unimplemented write! address = 0x%x, value = 0x%x, size = %u\n", addr, value, size);
|
||||
}
|
||||
|
||||
}
|
|
@ -4,31 +4,6 @@
|
|||
|
||||
namespace strikebox {
|
||||
|
||||
// TODO: implement engines
|
||||
// Refer to envytools: https://envytools.readthedocs.io/en/latest/index.html
|
||||
//
|
||||
// Engine Offset Length Description
|
||||
// ----------------------------------------------------------------------------
|
||||
// PMC 0x000000 0x1000 Master control
|
||||
// PBUS 0x001000 0x1000 Bus control
|
||||
// PFIFO 0x002000 0x2000 MMIO and DMA FIFO submission to PGRAPH (there's no VPE in NV2A)
|
||||
// PRMA 0x007000 0x1000 Real mode BAR access
|
||||
// PVIDEO 0x008000 0x1000 Video overlay
|
||||
// PTIMER 0x009000 0x1000 Time measurement and time-based alarms
|
||||
// PCOUNTER 0x00A000 0x1000 Performance monitoring counters
|
||||
// PMVIO 0x0C0000 0x1000 VGA sequencer and graph controller registers
|
||||
// PFB 0x100000 0x1000 Memory interface
|
||||
// PSTRAPS 0x101000 0x1000 Straps readout
|
||||
// PROM 0x300000 0x20000 ROM access window
|
||||
// PGRAPH 0x400000 0x2000 2D/3D graphics engine
|
||||
// PCRTC 0x600000 0x1000 CRTC controls
|
||||
// PRMCIO 0x601000 0x1000 VGA CRTC and attribute controller registers
|
||||
// PRAMDAC 0x680000 0x1000 RAMDAC, video overlay, cursor, and PLL control
|
||||
// PRMDIO 0x681000 0x1000 VGA DAC registers
|
||||
// PRAMIN 0x700000 0x100000 RAMIN access
|
||||
// USER 0x800000 0x200000 PFIFO MMIO/DMA submission area
|
||||
//
|
||||
|
||||
NV2ADevice::NV2ADevice(uint8_t *pSystemRAM, uint32_t systemRAMSize, IRQHandler& irqHandler)
|
||||
: PCIDevice(PCI_HEADER_TYPE_NORMAL, PCI_VENDOR_ID_NVIDIA, 0x02A0, 0xA1,
|
||||
0x03, 0x00, 0x00) // VGA-compatible controller
|
||||
|
@ -36,6 +11,24 @@ NV2ADevice::NV2ADevice(uint8_t *pSystemRAM, uint32_t systemRAMSize, IRQHandler&
|
|||
, m_systemRAMSize(systemRAMSize)
|
||||
, m_irqHandler(irqHandler)
|
||||
{
|
||||
RegisterEngine(m_pmc);
|
||||
RegisterEngine(m_pbus);
|
||||
RegisterEngine(m_pfifo);
|
||||
RegisterEngine(m_prma);
|
||||
RegisterEngine(m_pvideo);
|
||||
RegisterEngine(m_ptimer);
|
||||
RegisterEngine(m_pcounter);
|
||||
RegisterEngine(m_pnvio);
|
||||
RegisterEngine(m_pfb);
|
||||
RegisterEngine(m_pstraps);
|
||||
RegisterEngine(m_prom);
|
||||
RegisterEngine(m_pgraph);
|
||||
RegisterEngine(m_pcrtc);
|
||||
RegisterEngine(m_prmcio);
|
||||
RegisterEngine(m_pramdac);
|
||||
RegisterEngine(m_prmdio);
|
||||
RegisterEngine(m_pramin);
|
||||
RegisterEngine(m_user);
|
||||
}
|
||||
|
||||
NV2ADevice::~NV2ADevice() {
|
||||
|
@ -80,21 +73,60 @@ void NV2ADevice::Reset() {
|
|||
}
|
||||
|
||||
void NV2ADevice::PCIIORead(int barIndex, uint32_t port, uint32_t *value, uint8_t size) {
|
||||
log_warning("NV2ADevice::IORead: Unexpected I/O read! bar = %d, port = 0x%x, size = %u\n", barIndex, port, size);
|
||||
log_warning("NV2ADevice::PCIIORead: Unexpected I/O read! bar = %d, port = 0x%x, size = %u\n", barIndex, port, size);
|
||||
*value = 0;
|
||||
}
|
||||
|
||||
void NV2ADevice::PCIIOWrite(int barIndex, uint32_t port, uint32_t value, uint8_t size) {
|
||||
log_warning("NV2ADevice::IOWrite: Unexpected I/O write! bar = %d, port = 0x%x, size = %u, value = 0x%x\n", barIndex, port, size, value);
|
||||
log_warning("NV2ADevice::PCIIOWrite: Unexpected I/O write! bar = %d, port = 0x%x, size = %u, value = 0x%x\n", barIndex, port, size, value);
|
||||
}
|
||||
|
||||
void NV2ADevice::PCIMMIORead(int barIndex, uint32_t addr, uint32_t *value, uint8_t size) {
|
||||
*value = 0;
|
||||
log_spew("NV2ADevice::PCIMMIORead: Unimplemented read! bar = %d, address = 0x%x, size = %u\n", barIndex, addr, size);
|
||||
if (barIndex == 0) {
|
||||
auto opt_eng = FindEngine(addr);
|
||||
if (opt_eng) {
|
||||
auto& eng = opt_eng->get();
|
||||
*value = eng.Read(addr - eng.GetOffset(), size);
|
||||
}
|
||||
else {
|
||||
log_spew("NV2ADevice::PCIMMIORead: Unmapped read! bar = %d, address = 0x%x, size = %u\n", barIndex, addr, size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_spew("NV2ADevice::PCIMMIORead: Unimplemented read! bar = %d, address = 0x%x, size = %u\n", barIndex, addr, size);
|
||||
*value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void NV2ADevice::PCIMMIOWrite(int barIndex, uint32_t addr, uint32_t value, uint8_t size) {
|
||||
log_spew("NV2ADevice::PCIMMIOWrite: Unimplemented write! bar = %d, address = 0x%x, value = 0x%x, size = %u\n", barIndex, addr, value, size);
|
||||
if (barIndex == 0) {
|
||||
auto opt_eng = FindEngine(addr);
|
||||
if (opt_eng) {
|
||||
auto& eng = opt_eng->get();
|
||||
eng.Write(addr - eng.GetOffset(), value, size);
|
||||
}
|
||||
else {
|
||||
log_spew("NV2ADevice::PCIMMIOWrite: Unmapped write! bar = %d, address = 0x%x, value = 0x%x, size = %u\n", barIndex, addr, value, size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_spew("NV2ADevice::PCIMMIOWrite: Unimplemented write! bar = %d, address = 0x%x, value = 0x%x, size = %u\n", barIndex, addr, value, size);
|
||||
}
|
||||
}
|
||||
|
||||
void NV2ADevice::RegisterEngine(nv2a::NV2AEngine& engine) {
|
||||
engines.insert({ engine.GetOffset() + engine.GetLength() - 1, engine });
|
||||
}
|
||||
|
||||
std::optional<std::reference_wrapper<nv2a::NV2AEngine>> NV2ADevice::FindEngine(const uint32_t address) {
|
||||
auto entry = engines.lower_bound(address);
|
||||
if (entry != engines.end()) {
|
||||
auto& engine = entry->second;
|
||||
if (engine.Contains(address)) {
|
||||
return engine;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue