devices: skeleton for ATI Rage emulation.

This commit is contained in:
Maxim Poliakovski 2020-03-31 18:25:58 +02:00
parent 695044cf0e
commit a8c6298545
6 changed files with 108 additions and 37 deletions

View File

@ -22,21 +22,89 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <atirage.h>
#include <cstdint>
#include "endianswap.h"
#include "memreadwrite.h"
#include "pcidevice.h"
#include <thirdparty/loguru/loguru.hpp>
ATIRage::ATIRage() {
ATIRage::ATIRage(uint16_t dev_id) : PCIDevice("ati-rage")
{
WRITE_DWORD_BE_A(&this->pci_cfg[0], (dev_id << 16) | ATI_PCI_VENDOR_ID);
WRITE_DWORD_BE_A(&this->pci_cfg[8], 0x0300005C);
WRITE_DWORD_BE_A(&this->pci_cfg[0x3C], 0x00080100);
}
uint32_t ATIRage::read(int reg, int size) {
LOG_F(INFO, "Reading reg=%X, size %d", reg, (size * 8));
return reg;
uint32_t ATIRage::pci_cfg_read(uint32_t reg_offs, uint32_t size)
{
uint32_t res = 0;
LOG_F(INFO, "Reading ATI Rage config space, offset = 0x%X, size=%d", reg_offs, size);
switch (size) {
case 4:
res = READ_DWORD_LE_U(&this->pci_cfg[reg_offs]);
break;
case 2:
res = READ_WORD_LE_U(&this->pci_cfg[reg_offs]);
break;
case 1:
res = this->pci_cfg[reg_offs];
break;
default:
LOG_F(WARNING, "ATI Rage pci_cfg_read(): invalid size %d", size);
}
LOG_F(INFO, "Return value: 0x%X", res);
return res;
}
void ATIRage::write(int reg, uint32_t value, int size) {
LOG_F(INFO, "Writing reg=%X, value=%X, size %d", reg, value, (size * 8));
void ATIRage::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size)
{
LOG_F(INFO, "Writing into ATI Rage PCI config space, offset = 0x%X, val=0x%X size=%d",
reg_offs, BYTESWAP_32(value), size);
switch (reg_offs) {
case 0x10: /* BAR 0 */
if (value == 0xFFFFFFFFUL) {
WRITE_DWORD_LE_A(&this->pci_cfg[0x10], 0xFF000008);
}
else {
WRITE_DWORD_LE_A(&this->pci_cfg[0x10], value);
}
break;
case 0x14: /* BAR 1: I/O space base, 256 bytes wide */
if (value == 0xFFFFFFFFUL) {
WRITE_DWORD_LE_A(&this->pci_cfg[0x14], 0x0000FFF1);
}
else {
WRITE_DWORD_LE_A(&this->pci_cfg[0x14], value);
}
case 0x18: /* BAR 2 */
if (value == 0xFFFFFFFFUL) {
WRITE_DWORD_LE_A(&this->pci_cfg[0x18], 0xFFFFF000);
}
else {
WRITE_DWORD_LE_A(&this->pci_cfg[0x18], value);
}
break;
case 0x1C: /* BAR 3: unimplemented */
case 0x20: /* BAR 4: unimplemented */
case 0x24: /* BAR 5: unimplemented */
case 0x30: /* Expansion ROM Base Addr: unimplemented */
WRITE_DWORD_LE_A(&this->pci_cfg[reg_offs], 0);
break;
default:
WRITE_DWORD_LE_A(&this->pci_cfg[reg_offs], value);
}
}
void ATIRage::atirage_init() {
}
uint32_t ATIRage::read(uint32_t reg_start, uint32_t offset, int size)
{
LOG_F(INFO, "Reading reg=%X, size %d", offset, size);
return 0;
}
void ATIRage::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size)
{
LOG_F(INFO, "Writing reg=%X, value=%X, size %d", offset, value, size);
}

View File

@ -1,9 +1,18 @@
#ifndef ATIRAGE_H
#define ATIRAGE_H
#ifndef ATI_RAGE_H
#define ATI_RAGE_H
#include <cinttypes>
#include "pcidevice.h"
using namespace std;
/* PCI related definitions. */
enum {
ATI_PCI_VENDOR_ID = 0x1002,
ATI_RAGE_PRO_DEV_ID = 0x4750,
ATI_RAGE_GT_DEV_ID = 0x4754,
};
/** Mach registers offsets. */
enum {
ATI_CTRC_H_TOTAL_DISP = 0x0000,
@ -34,14 +43,22 @@ enum {
ATI_CONTEXT_MASK = 0x0320,
};
class ATIRage
class ATIRage : public PCIDevice
{
public:
ATIRage();
ATIRage(uint16_t dev_id);
~ATIRage() = default;
uint32_t read(int reg, int size);
void write(int reg, uint32_t value, int size);
uint32_t read(uint32_t reg_start, uint32_t offset, int size);
void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size);
bool supports_type(HWCompType type) { return type == HWCompType::MMIO_DEV; };
void set_host(PCIHost* host_instance) { this->host_instance = host_instance; };
/* PCI device methods */
uint32_t pci_cfg_read(uint32_t reg_offs, uint32_t size);
void pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size);
private:
uint32_t atirage_membuf_regs[9]; /* ATI Rage Memory Buffer Registers */
@ -49,14 +66,6 @@ private:
uint32_t atirage_cmdfifo_regs[3]; /* ATI Rage Command FIFO Registers */
uint32_t atirage_datapath_regs[12]; /* ATI Rage Data Path Registers*/
uint8_t atirage_vid_mem[8242880];
uint8_t atirage_cfg[256] = {
0x02, 0x10, //Vendor: ATI Technologies
0x50, 0x47, //Device: 3D Rage Pro PCI
};
void atirage_init();
uint8_t pci_cfg[256] = { 0 }; /* PCI configuration space */
};
#endif /* ATIRAGE_H */
#endif /* ATI_RAGE_H */

View File

@ -26,7 +26,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "viacuda.h"
#include "awacs.h"
#include "dbdma.h"
#include "atirage.h"
#include "machines/machinebase.h"
/** Heathrow Mac I/O device emulation.
@ -43,8 +42,6 @@ HeathrowIC::HeathrowIC() : PCIDevice("mac-io/heathrow")
this->viacuda = new ViaCuda();
gMachineObj->add_subdevice("ViaCuda", this->viacuda);
this->atirage = new ATIRage();
this->screamer = new AWACDevice();
this->snd_out_dma = new DMAChannel(this->screamer);
this->screamer->set_dma_out(this->snd_out_dma);
@ -131,9 +128,6 @@ uint32_t HeathrowIC::read(uint32_t reg_start, uint32_t offset, int size)
case 8:
res = dma_read(offset - 0x8000, size);
break;
case 0x12:
res = this->atirage->read(offset - 0x12000, size);
break;
case 0x14:
res = this->screamer->snd_ctrl_read(offset - 0x14000, size);
break;
@ -166,9 +160,6 @@ void HeathrowIC::write(uint32_t reg_start, uint32_t offset, uint32_t value, int
case 8:
dma_write(offset - 0x8000, value, size);
break;
case 0x12:
this->atirage->write(offset - 0x12000, value, size);
break;
case 0x14:
this->screamer->snd_ctrl_write(offset - 0x14000, value, size);
break;

View File

@ -61,7 +61,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "nvram.h"
#include "awacs.h"
#include "dbdma.h"
#include "atirage.h"
/**
Heathrow ASIC emulation
@ -135,7 +134,6 @@ private:
ViaCuda *viacuda; /* VIA cell with Cuda MCU attached to it */
NVram *nvram; /* NVRAM cell */
AWACDevice *screamer; /* Screamer audio codec instance */
ATIRage *atirage; /* Screamer audio codec instance */
DMAChannel *snd_out_dma;
};

View File

@ -94,7 +94,6 @@ void load_rom(ifstream& rom_file, uint32_t file_size)
int create_machine_for_rom(const char* rom_filepath)
{
ifstream rom_file;
int result;
uint32_t file_size, config_info_offset, rom_id;
char rom_id_str[17];

View File

@ -32,6 +32,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "devices/macio.h"
#include "devices/viacuda.h"
#include "devices/spdram.h"
#include "devices/atirage.h"
static void setup_ram_slot(std::string name, int i2c_addr, int capacity_megs)
{
@ -88,6 +89,11 @@ int create_gossamer()
setup_ram_slot("RAM_DIMM_2", 0x56, 0); /* RAM slot 2 -> empty by default */
setup_ram_slot("RAM_DIMM_3", 0x55, 0); /* RAM slot 3 -> empty by default */
/* register ATI 3D Rage Pro video card with the PCI host bridge */
gMachineObj->add_component("ATIRage", new ATIRage(ATI_RAGE_PRO_DEV_ID));
grackle_obj->pci_register_device(18,
dynamic_cast<PCIDevice *>(gMachineObj->get_comp_by_name("ATIRage")));
/* Init virtual CPU and request MPC750 CPU aka G3 */
ppc_cpu_init(grackle_obj, PPC_VER::MPC750);