[GPU] First few GP1 commands

This commit is contained in:
liuk7071 2023-07-25 19:46:41 +02:00
parent 395eb8e7e4
commit 72b53dd947
3 changed files with 58 additions and 8 deletions

View file

@ -10,17 +10,56 @@ u32 Gpu::getStat() {
return stat;
}
u32 Gpu::gpuRead() {
// Stubbed
return 0;
}
void Gpu::writeGp0(u32 data) {
if (!hasCommand)
startCommand(data);
}
void Gpu::writeGp1(u32 data) {
const auto cmd = (data >> 24) & 0xff;
switch (cmd) {
case (u32)GP1Command::ResetGpu: {
stat = 0x14802000;
break;
}
case (u32)GP1Command::DMADirection: {
// Bits 0-1 are copied to GPUSTAT.29-30
stat &= ~(3 << 29);
stat |= (data & 3) << 29;
break;
}
case (u32)GP1Command::DisplayMode: {
// Bits 0-5 are copied to GPUSTAT.17-22
stat &= ~(0x3f << 17);
stat |= (data & 0x3f) << 17;
// Bit 6 is copied to GPUSTAT.16
stat &= ~(1 << 16);
stat |= (data & (1 << 6)) << 10;
// Bit 7 is copied to GPUSTAT.17
stat &= ~(1 << 14);
stat |= (data & (1 << 7)) << 7;
break;
}
default:
Helpers::panic("[GPU] Unimplemented gp1 command 0x%02x\n", cmd);
}
}
void Gpu::startCommand(u32 rawCommand) {
// We handle single-word commands (i.e. all the configuration ones) in this function
const auto cmd = (GP0Command)((rawCommand >> 24) & 0xff);
const auto cmd = (rawCommand >> 24) & 0xff;
switch (cmd) {
case GP0Command::DrawModeSetting: {
case (u32)GP0Command::NOP: {
// NOP
break;
}
case (u32)GP0Command::DrawModeSetting: {
// Bits 0-10 are copied into GPUSTAT
stat &= ~0x7ff;
stat |= rawCommand & 0x7ff;
@ -30,6 +69,6 @@ void Gpu::startCommand(u32 rawCommand) {
break;
}
default:
Helpers::panic("[GPU] Unimplemented command 0x%02x\n", (u32)cmd);
Helpers::panic("[GPU] Unimplemented gp0 command 0x%02x\n", (u32)cmd);
}
}

View file

@ -7,19 +7,28 @@ class Gpu {
public:
std::vector<u32> fifo;
u32 getStat();
u32 gpuRead();
// Command processing
void writeGp0(u32 data);
void writeGp1(u32 data);
bool hasCommand = false;
u32 paramsLeft = 0;
enum class GP0Command {
NOP = 0x00,
DrawModeSetting = 0xE1
};
enum class GP1Command {
ResetGpu = 0x00,
DMADirection = 0x04,
DisplayMode = 0x08
};
void startCommand(u32 rawCommand);
private:
u32 stat;
u32 stat = 0x14802000;
};

View file

@ -103,7 +103,8 @@ u32 Memory::read(u32 vaddr) {
u32 paddr = maskAddress(vaddr);
// GPU
if (paddr == 0x1f801814) return gpu->getStat();
if (paddr == 0x1f801810) return gpu->gpuRead();
else if (paddr == 0x1f801814) return gpu->getStat();
// Interrupt
else if (paddr == 0x1f801074) return interrupt->readImask();
// DMA
@ -181,6 +182,7 @@ void Memory::write(u32 vaddr, u32 data) {
// GPU
if (paddr == 0x1f801810) gpu->writeGp0(data);
else if (paddr == 0x1f801814) gpu->writeGp1(data);
// Interrupt
else if (paddr == 0x1f801070) interrupt->writeIstat(data);
else if (paddr == 0x1f801074) interrupt->writeImask(data);
@ -190,9 +192,9 @@ void Memory::write(u32 vaddr, u32 data) {
Helpers::assert(channel < 8, "Tried to access %dth DMA channel", channel); // Should not get triggered
switch (paddr & 0xf) {
case 0x0: dma->channels[channel].madr = data;
case 0x4: dma->channels[channel].bcr.raw = data;
case 0x8: dma->channels[channel].chcr.raw = data;
case 0x0: dma->channels[channel].madr = data; break;
case 0x4: dma->channels[channel].bcr.raw = data; break;
case 0x8: dma->channels[channel].chcr.raw = data; break;
default: Helpers::panic("[FATAL] Unhandled DMA write32 0x%08x <- 0x%08x\n", paddr, data);
}
}