BIOS sends first texture transfer command

This commit is contained in:
liuk7071 2023-07-29 22:31:46 +02:00
parent 2c2e7c3f88
commit b72332bd3a
5 changed files with 98 additions and 12 deletions

View file

@ -27,7 +27,7 @@ uint32_t jump = 0; // jump branch delay slot
bool debug = false;
bool log_kernel = false;
bool exe = false;
bool tty = false;
bool tty = true;
bool delay = false;

View file

@ -1,12 +1,15 @@
#include "gpu.hpp"
MAKE_LOG_FUNCTION(log, gpuLogger)
u32 Gpu::getStat() {
// Stubbed
stat |= 1 << 26; // Ready to receive cmd word
stat |= 1 << 27; // Ready to send VRAM to CPU
stat |= 1 << 28; // Ready to receive DMA block
stat |= 1 << 30; // DMA direction CPU -> GP0
stat ^= 1 << 31; // Fake interlacing
return stat;
}
@ -16,8 +19,15 @@ u32 Gpu::gpuRead() {
}
void Gpu::writeGp0(u32 data) {
if (!hasCommand)
if (!hasCommand) {
startCommand(data);
}
paramsLeft--;
if (paramsLeft == 0) {
// TODO: execute command
hasCommand = false;
}
}
void Gpu::writeGp1(u32 data) {
@ -72,6 +82,11 @@ void Gpu::startCommand(u32 rawCommand) {
// NOP
break;
}
case (u32)GP0Command::ClearCache: {
log("ClearCache\n");
// Stubbed
break;
}
case (u32)GP0Command::DrawModeSetting: {
log("DrawModeSetting\n");
// Bits 0-10 are copied into GPUSTAT
@ -107,7 +122,43 @@ void Gpu::startCommand(u32 rawCommand) {
// TODO: Stubbed for now
break;
}
default:
Helpers::panic("[GPU] Unimplemented gp0 command 0x%02x\n", (u32)cmd);
default: {
DrawCommand drawCommand(rawCommand);
hasCommand = true;
paramsLeft = drawCommand.getCommandSize();
}
}
}
Gpu::DrawCommand::DrawCommand(u32 raw) {
Polygon temp = { .raw = raw };
this->raw = raw;
if (temp.polygonCommand == 1) {
log("Polygon:\n");
log(temp.quad ? " Quad\n" : " Tri\n");
log(temp.shading ? " Shaded\n" : " Monochrome\n");
log(temp.textured ? " Textured\n" : " Untextured\n");
drawType = DrawType::Polygon;
}
else {
Helpers::panic("[GPU] Unimplemented gp0 command 0x%02x (0x%08x)\n", raw >> 24, raw);
}
}
// Returns the amount of words required for the command
u32 Gpu::DrawCommand::getCommandSize() {
u32 size = 1;
if (drawType == DrawType::Polygon) {
// Get number of words required per vertex
Polygon poly = { .raw = this->raw };
if (poly.shading) size++;
if (poly.textured) size++;
// Multiply by number of vertices
size *= poly.quad ? 4 : 3;
}
else {
Helpers::panic("[GPU] Tried to get command size for unimplemented Line command\n");
}
return size;
}

View file

@ -1,6 +1,7 @@
#pragma once
#include <helpers.hpp>
#include <BitField.hpp>
#include <logger.hpp>
@ -14,11 +15,10 @@ public:
void writeGp0(u32 data);
void writeGp1(u32 data);
bool hasCommand = false;
u32 paramsLeft = 0;
enum class GP0Command {
NOP = 0x00,
ClearCache = 0x01,
DrawModeSetting = 0xE1,
TextureWindowSetting = 0xE2,
SetDrawingAreaTopLeft = 0xE3,
@ -36,10 +36,34 @@ public:
DisplayMode = 0x08
};
void startCommand(u32 rawCommand);
private:
u32 stat = 0x14802000;
MAKE_LOG_FUNCTION(log, gpuLogger)
bool hasCommand = false;
u32 paramsLeft = 0; // Parameters needed for command
void startCommand(u32 rawCommand);
class DrawCommand {
public:
DrawCommand(u32 raw);
u32 getCommandSize(); // In words
private:
u32 raw;
enum class DrawType {
Polygon,
Line
} drawType;
union Polygon {
u32 raw;
BitField<0, 24, u32> rgb; // Colour of vertex 0
BitField<24, 1, u32> rawTexture;
BitField<25, 1, u32> semiTransparent;
BitField<26, 1, u32> textured;
BitField<27, 1, u32> quad; // If it's not a quad, it's a tri
BitField<28, 1, u32> shading;
BitField<29, 3, u32> polygonCommand; // Should be 0b001
};
};
};

View file

@ -1,8 +1,9 @@
#include <stdio.h>
#include "playstation.hpp"
#define CLOCK_SPEED (33868800 / 60)
int main(int argc, char** argv) {
if (argc < 2) Helpers::panic("Usage: ChonkyStation [bios path]");
@ -10,8 +11,15 @@ int main(int argc, char** argv) {
PlayStation playstation = PlayStation(argv[1]);
while(true)
playstation.step();
u64 cycles = 0;
while (true) {
cycles = 0;
while (cycles++ < CLOCK_SPEED)
playstation.step();
//printf("pc: 0x%08x\n", playstation.getPC());
//Helpers::dump("ramdump.bin", playstation.getRAM(), 2_MB);
}
return 0;
}

View file

@ -12,7 +12,7 @@ class PlayStation {
public:
PlayStation(const fs::path& biosPath) : interrupt(), gpu(), dma(), mem(&interrupt, &dma, &gpu), cpu(&mem) {
mem.loadBios(biosPath);
//cpu.switchBackend(Cpu::Backend::OldInterpreter);
cpu.switchBackend(Cpu::Backend::OldInterpreter);
}
// Steps the system
@ -20,6 +20,9 @@ public:
cpu.step();
}
u32 getPC() { return cpu.core.pc; }
u8* getRAM() { return mem.ram; }
private:
Cpu cpu;
DMA dma;