Lots of games now go further thanks to SPU DMA interrupts

This commit is contained in:
liuk7071 2022-07-20 12:47:33 +02:00
parent 8562be5e2c
commit 4c3c6d6e96
9 changed files with 683 additions and 63 deletions

View file

@ -700,16 +700,18 @@ int main(int argc, char** argv) {
while (!glfwWindowShouldClose(window)) {
if (Cpu.frame_cycles >= (33868800 / 60) || !run) {
if (tmr1irq) {
printf("[TIMERS] TMR1 IRQ\n");
tmr1irq = false;
Cpu.bus.mem.I_STAT |= 0b100000;
printf("[TIMERS] TMR2 IRQ\n");
//tmr1irq = false;
//Cpu.bus.mem.I_STAT |= 0b100000;
Cpu.bus.mem.I_STAT |= 0b1000000;
Cpu.bus.mem.tmr1_stub = 0;
}
Cpu.bus.mem.I_STAT |= 0b100000;
//Cpu.bus.mem.I_STAT |= 0b1000000;
if (Cpu.should_service_dma_irq) {
printf("[DMA] IRQ\n");
Cpu.bus.mem.I_STAT |= 0b1000;
Cpu.should_service_dma_irq = false;
//printf("[DMA] IRQ\n");
//Cpu.bus.mem.I_STAT |= 0b1000;
//Cpu.should_service_dma_irq = false;
}
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
if (pad1_source == "Gamepad") {

View file

@ -39,7 +39,9 @@ void cdrom::execute(uint8_t command) {
case 0x09: Pause(); break;
case 0x0A: init(); break;
case 0x0C: Demute(); break;
case 0x0D: SetFilter(); break;
case 0x0E: Setmode(); break;
case 0x10: GetLocL(); break;
case 0x13: GetTN(); break;
case 0x14: GetTD(); break;
case 0x15: SeekL(); break;
@ -82,29 +84,31 @@ uint8_t cdrom::read_fifo() {
void cdrom::queuedRead(void* dataptr) {
cdrom* cdromptr = (cdrom*)(dataptr);
if (cdromptr->reading) {
cdromptr->seekloc++;
cdromptr->cd.read(cdromptr->seekloc);
//cdromptr->seekloc++;
cdromptr->status |= 0b10000000; // DRQSTS
cdromptr->queued_fifo[0] = cdromptr->get_stat();
cdromptr->queued_response_length = 1;
cdromptr->Scheduler.push(&INT1, cdromptr->Scheduler.time + ((33868800 / 100) / (cdromptr->DoubleSpeed ? 2 : 1)), cdromptr);
cdromptr->Scheduler.push(&INT1, cdromptr->Scheduler.time + 5000, cdromptr);
}
}
void cdrom::INT1(void* dataptr) {
cdrom* cdromptr = (cdrom*)(dataptr);
if (cdromptr->reading) {
printf("[IRQ] INT1 dispatched\n");
cdromptr->interrupt_flag &= ~0b111;
cdromptr->interrupt_flag |= 0b001;
cdromptr->cd.read(cdromptr->seekloc++);
if (!cdromptr->xa_adpcm) {
printf("[IRQ] INT1 dispatched\n");
cdromptr->interrupt_flag &= ~0b111;
cdromptr->interrupt_flag |= 0b001;
for (int i = 0; i < 16; i++) {
cdromptr->response_fifo[i] = cdromptr->queued_fifo[i];
for (int i = 0; i < 16; i++) {
cdromptr->response_fifo[i] = cdromptr->queued_fifo[i];
}
cdromptr->response_length = cdromptr->queued_response_length;
cdromptr->status |= 0b00100000;
cdromptr->cd.bytes_read = 0;
}
cdromptr->response_length = cdromptr->queued_response_length;
cdromptr->status |= 0b00100000;
cdromptr->cd.bytes_read = 0;
cdromptr->Scheduler.push(&queuedRead, cdromptr->Scheduler.time + 5000, cdromptr);
cdromptr->Scheduler.push(&queuedRead, cdromptr->Scheduler.time + ((33868800 / 75) / (cdromptr->DoubleSpeed ? 1 : 1)), cdromptr);
}
return;
}
@ -177,7 +181,9 @@ void cdrom::test() {
}
void cdrom::GetStat() { // Return status byte
debug_log("[CDROM] GetStat\n");
response_fifo[0] = get_stat();
//response_fifo[0] = get_stat();
response_fifo[0] = rand() % 0xff;
response_fifo[0] &= ~0b11101;
response_length = 1;
status |= 0b00100000;
Scheduler.push(&INT3, Scheduler.time + 25000, this);
@ -185,17 +191,18 @@ void cdrom::GetStat() { // Return status byte
void cdrom::GetTN() { // Get first track number, and last track number in the TOC of the current Session.
debug_log("[CDROM] GetTN (stubbed)\n");
response_fifo[0] = get_stat();
response_fifo[1] = 0x01;
response_fifo[2] = 0x01;
response_fifo[1] = 0x00;
response_fifo[2] = 0x00;
response_length = 3;
status |= 0b00100000;
Scheduler.push(&INT3, Scheduler.time + 15000, this);
}
void cdrom::GetTD() {
debug_log("[CDROM] GetTD (stubbed)\n");
response_fifo[0] = get_stat();
response_fifo[1] = 0x01;
response_fifo[2] = 0x01;
//response_fifo[0] = get_stat();
response_fifo[0] = 0x00;
response_fifo[1] = 0x00;
response_fifo[2] = 0x00;
response_length = 3;
status |= 0b00100000;
Scheduler.push(&INT3, Scheduler.time + 15000, this);
@ -222,6 +229,20 @@ void cdrom::Setmode() { // Set mode
Scheduler.push(&INT3, Scheduler.time + 4000, this);
//delay = 2;
}
void cdrom::GetLocL() {
debug_log("[CDROM] GetLocL\n");
response_fifo[0] = cd.SectorBuffer[0xc + 0];
response_fifo[1] = cd.SectorBuffer[0xc + 1];
response_fifo[2] = cd.SectorBuffer[0xc + 2];
response_fifo[3] = cd.SectorBuffer[0xc + 3];
response_fifo[4] = cd.SectorBuffer[0x10 + 0];
response_fifo[5] = cd.SectorBuffer[0x10 + 1];
response_fifo[6] = cd.SectorBuffer[0x10 + 2];
response_fifo[7] = cd.SectorBuffer[0x10 + 3];
response_length = 8;
status |= 0b00100000;
Scheduler.push(&INT3, Scheduler.time + 15000, this);
}
void cdrom::GetID() { // Disk info
debug_log("[CDROM] GetID\n");
if (cd.IsCDInserted) {
@ -298,7 +319,7 @@ void cdrom::ReadN() { // Read with retry
status |= 0b00001000; // Set parameter fifo empty bit
debug_log("[CDROM] ReadN\n");
cd.bytes_read = 0;
cd.read(seekloc);
//cd.read(seekloc);
response_fifo[0] = get_stat();
response_length = 1;
//INT3();
@ -309,23 +330,23 @@ void cdrom::ReadN() { // Read with retry
//queued_INT1 = true;
Scheduler.push(&INT3, Scheduler.time + 4, this);
Scheduler.push(&INT1, Scheduler.time + ((33868800 / 100) / (DoubleSpeed ? 2 : 1)), this);
Scheduler.push(&INT1, Scheduler.time + ((33868800 / 75) / (DoubleSpeed ? 1 : 1)), this);
//queued_delay = 33868800 / 75;
status |= 0b00100000; // Set response fifo empty bit (means it's full)
}
void cdrom::ReadS() { // Read without retry
status |= 0b00001000; // Set parameter fifo empty bit
debug_log("[CDROM] ReadS\n");
cd.read(seekloc);
cd.bytes_read = 0;
response_fifo[0] = get_stat();
reading = false; // To not make it retry
reading = true;
response_length = 1;
queued_fifo[0] = 0x22;
queued_response_length = 1;
Scheduler.push(&INT3, Scheduler.time + 4, this);
Scheduler.push(&INT1, Scheduler.time + ((33868800 / 100) / (DoubleSpeed ? 2 : 1)), this);
Scheduler.push(&INT1, Scheduler.time + ((33868800 / 75) / (DoubleSpeed ? 2 : 1)), this);
status |= 0b00100000; // Set response fifo empty bit (means it's full)
}
void cdrom::Pause() {
@ -367,4 +388,11 @@ void cdrom::Demute() {
response_length = 1;
status |= 0b00100000;
Scheduler.push(&INT3, Scheduler.time + 25000, this);
}
void cdrom::SetFilter() {
debug_log("[CDROM] SetFilter\n");
response_fifo[0] = get_stat();
response_length = 1;
status |= 0b00100000;
Scheduler.push(&INT3, Scheduler.time + 25000, this);
}

View file

@ -65,7 +65,9 @@ public:
void Pause();
void init();
void Demute();
void SetFilter();
void Setmode();
void GetLocL();
// setmode
bool DoubleSpeed = false;

17
cpu.cpp
View file

@ -123,11 +123,6 @@ void cpu::exception(exceptions exc) {
delay = false;
}
void DMAIRQ(void* dataptr) {
memory* memoryptr = (memory*)dataptr;
memoryptr->I_STAT |= 0b1000;
}
template<int channel>
void cpu::do_dma() {
//debug = true;
@ -160,7 +155,8 @@ void cpu::do_dma() {
//debug = false;
if (((bus.mem.DICR >> 18) & 1) && ((bus.mem.DICR >> 23) & 1)) {
bus.mem.DICR |= (1 << 26);
should_service_dma_irq = true;
bus.mem.I_STAT |= 0b1000;
//should_service_dma_irq = true;
}
return;
case 0:
@ -195,7 +191,8 @@ void cpu::do_dma() {
}
if (((bus.mem.DICR >> 18) & 1) && ((bus.mem.DICR >> 23) & 1)) {
bus.mem.DICR |= (1 << 26);
should_service_dma_irq = true;
bus.mem.I_STAT |= 0b1000;
//should_service_dma_irq = true;
}
bus.mem.Ch2.CHCR &= ~(1 << 24);
debug_log("[DMA] GPU Linked List transfer complete\n");
@ -243,7 +240,8 @@ void cpu::do_dma() {
//debug = false;
if (((bus.mem.DICR >> 19) & 1) && ((bus.mem.DICR >> 23) & 1)) {
bus.mem.DICR |= (1 << 27);
should_service_dma_irq = true;
bus.mem.I_STAT |= 0b1000;
//should_service_dma_irq = true;
}
//bus.mem.CDROM.queued_read = true;
//bus.mem.CDROM.delay = 2;
@ -300,7 +298,8 @@ void cpu::do_dma() {
//debug = false;
if (((bus.mem.DICR >> 22) & 1) && ((bus.mem.DICR >> 23) & 1)) {
bus.mem.DICR |= (1 << 30);
should_service_dma_irq = true;
bus.mem.I_STAT |= 0b1000;
//should_service_dma_irq = true;
}
return;
}

553
gpu.cpp
View file

@ -233,6 +233,11 @@ void gpu::execute_gp0(uint32_t command) {
cmd_left = 8;
break;
}
case 0x2E: { // Textured four-point polygon, semi-transparent, texture-blending
cmd_length++;
cmd_left = 8;
break;
}
case 0x2F: { // Textured four-point polygon, semi-transparent, raw-texture
fifo[0] = command;
cmd_length++;
@ -313,12 +318,24 @@ void gpu::execute_gp0(uint32_t command) {
cmd_left = 3;
break;
}
case 0x67: { // Textured Rectangle, variable size, semi-transp, raw-texture
fifo[0] = command;
cmd_length++;
cmd_left = 3;
break;
}
case 0x68: { // 1x1 Opaque Monochrome Rectangle
fifo[0] = command;
cmd_length++;
cmd_left = 1;
break;
}
case 0x70: { // Monochrome Rectangle (8x8) (opaque)
fifo[0] = command;
cmd_length++;
cmd_left = 1;
break;
}
case 0x74: { // Textured Rectangle, 8x8, opaque, texture-blending
fifo[0] = command;
cmd_length++;
@ -331,6 +348,12 @@ void gpu::execute_gp0(uint32_t command) {
cmd_left = 2;
break;
}
case 0x7C: { // Textured Rectangle, 16x16, opaque, texture-blending
fifo[0] = command;
cmd_length++;
cmd_left = 2;
break;
}
case 0x80: { // Copy Rectangle (VRAM to VRAM)
fifo[0] = command;
cmd_length++;
@ -344,8 +367,10 @@ void gpu::execute_gp0(uint32_t command) {
break;
}
case 0xC0: { // Copy rectangle VRAM to CPU
// unimplemented
debug_printf("[GP0] Copy Rectangle (VRAM to CPU)\n");
fifo[0] = command;
cmd_length++;
cmd_left = 2;
break;
}
case 0xE1: { // Draw Mode Setting
@ -394,7 +419,7 @@ void gpu::execute_gp0(uint32_t command) {
}
default:
printf("\n[GP0] Unknown GP0 command: 0x%x (0x%x)\n", instr, command);
//abort();
abort();
}
}
else {
@ -407,6 +432,8 @@ void gpu::execute_gp0(uint32_t command) {
glScissor(drawing_topleft_x, drawing_topleft_y, (drawing_bottomright_x - drawing_topleft_x), (drawing_bottomright_y - drawing_topleft_y));
glEnable(GL_SCISSOR_TEST);
//SyncVRAM();
switch ((fifo[0] >> 24) & 0xff) {
case 0x02: gpu::fill_rectangle(); break;
@ -418,6 +445,7 @@ void gpu::execute_gp0(uint32_t command) {
case 0x2A: gpu::monochrome_four_point_semi_transparent_polygon(); break;
case 0x2C: gpu::texture_blending_four_point_opaque_polygon(); break;
case 0x2D: gpu::texture_four_point_opaque_polygon(); break;
case 0x2E: gpu::texture_blending_four_point_polygon_semi_transparent(); break;
case 0x2F: gpu::texture_four_point_semi_transparent_polygon(); break;
case 0x30: gpu::shaded_three_point_opaque_polygon(); break;
case 0x32: gpu::shaded_three_point_semi_transparent_polygon(); break;
@ -431,11 +459,15 @@ void gpu::execute_gp0(uint32_t command) {
case 0x64: gpu::texture_blending_rectangle_variable_size_opaque(); break;
case 0x65: gpu::texture_rectangle_variable_size_opaque(); break;
case 0x66: gpu::texture_blending_rectangle_variable_size_semi_transparent(); break;
case 0x67: gpu::textured_rectangle_variable_size_semi_transparent(); break;
case 0x68: gpu::monochrome_rectangle_dot_opaque(); break;
case 0x70: gpu::monochrome_rectangle_8x8_opaque(); break;
case 0x74: gpu::texture_blending_rectangle_8x8_opaque(); break;
case 0x75: gpu::texture_rectangle_8x8_opaque(); break;
case 0x7C: gpu::texture_blending_rectangle_16x16_opaque(); break;
case 0x80: break;
case 0xA0: gpu::cpu_to_vram(); break;
case 0xC0: gpu::vram_to_cpu(); break;
default: printf("\n%d", fifo[0] >> 24); abort();
}
}
@ -870,6 +902,149 @@ void gpu::texture_four_point_opaque_polygon() {
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
}
void gpu::texture_blending_four_point_polygon_semi_transparent() {
uint32_t colour = fifo[0] & 0xffffff;
debug_printf("[GP0] Textured four-point polygon, semi-transparent, texture-blending (colour: 0x%x)\n", colour);
point v1, v2, v3, v4;
uint16_t texpage = 0;
uint16_t clut = 0;
v1.x = fifo[1] & 0xffff;
v1.y = fifo[1] >> 16;
clut = fifo[2] >> 16;
uint32_t clutX = (clut & 0x3f);
clutX *= 16;
uint32_t clutY = (clut >> 6);
int Clut[256];
for (int i = 0; i < 256; i++) {
Clut[i] = vram_rgb[clutY * 1024 + clutX + i];
}
GLuint ssbo;
GLuint binding = 10;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, 256 * sizeof(int), Clut, GL_STATIC_READ);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, ssbo);
texpage = fifo[4] >> 16;
uint32_t texpageX = ((texpage & 0b1111) * 64);
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
v2.x = fifo[3] & 0xffff;
v2.y = fifo[3] >> 16;
v3.x = fifo[5] & 0xffff;
v3.y = fifo[5] >> 16;
v4.x = fifo[7] & 0xffff;
v4.y = fifo[7] >> 16;
v1.x += xoffset;
v1.y += yoffset;
v2.x += xoffset;
v2.y += yoffset;
v3.x += xoffset;
v3.y += yoffset;
v4.x += xoffset;
v4.y += yoffset;
point t1, t2, t3, t4;
t1.x = (fifo[2] & 0xffff) & 0xff;
t1.y = ((fifo[2] & 0xffff) >> 8) & 0xff;
t2.x = (fifo[4] & 0xffff) & 0xff;
t2.y = ((fifo[4] & 0xffff) >> 8) & 0xff;
t3.x = (fifo[6] & 0xffff) & 0xff;
t3.y = ((fifo[6] & 0xffff) >> 8) & 0xff;
t4.x = (fifo[8] & 0xffff) & 0xff;
t4.y = ((fifo[8] & 0xffff) >> 8) & 0xff;
int colourDepth = (texpage >> 7) & 3;
uint32_t Vertices1[] = {
// positions // colors // texture coords
v1.x, v1.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
v2.x, v2.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
};
glViewport(0, 0, 1024, 512);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
glBindTexture(GL_TEXTURE_2D, VramTexture8);
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
glBindTexture(GL_TEXTURE_2D, VramTexture4);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
glBindVertexArray(VAO);
// Position attribute
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
glEnableVertexAttribArray(0);
// Colour attribute
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
glEnableVertexAttribArray(2);
// texpage attribute
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
glEnableVertexAttribArray(3);
// clut attribute
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
glEnableVertexAttribArray(4);
// colour depth attribute
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
glEnableVertexAttribArray(5);
glUseProgram(TextureShaderProgram);
glUniform1i(colourDepthUniform, colourDepth);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
uint32_t Vertices2[] = {
// positions // colors // texture coords // texpage
v2.x, v2.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y, texpageX, texpageY, clutX, clutY, colourDepth
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
};
glViewport(0, 0, 1024, 512);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
glBindTexture(GL_TEXTURE_2D, VramTexture8);
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
glBindTexture(GL_TEXTURE_2D, VramTexture4);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
glBindVertexArray(VAO);
// Position attribute
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
glEnableVertexAttribArray(0);
// Colour attribute
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
glEnableVertexAttribArray(2);
// texpage attribute
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
glEnableVertexAttribArray(3);
// clut attribute
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
glEnableVertexAttribArray(4);
// colour depth attribute
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
glEnableVertexAttribArray(5);
glUseProgram(TextureShaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
}
void gpu::texture_four_point_semi_transparent_polygon() {
uint32_t colour = fifo[0] & 0xffffff;
debug_printf("[GP0] Textured four-point polygon, semi-transparent, raw-texture\n", colour);
@ -2178,6 +2353,149 @@ void gpu::texture_rectangle_8x8_opaque() {
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
}
void gpu::texture_blending_rectangle_16x16_opaque() {
uint32_t colour = fifo[0] & 0xffffff;
debug_printf("[GP0] Textured Rectangle, 16x16, opaque, texture-blending (colour: 0x%x)\n", colour);
point v1, res, v2, v3, v4;
uint16_t texpage = texpage_raw;
uint16_t clut = 0;
v1.x = fifo[1] & 0xffff;
v1.y = fifo[1] >> 16;
clut = fifo[2] >> 16;
uint32_t clutX = (clut & 0x3f);
clutX *= 16;
uint32_t clutY = (clut >> 6);
int Clut[256];
for (int i = 0; i < 256; i++) {
Clut[i] = vram_rgb[clutY * 1024 + clutX + i];
}
GLuint ssbo;
GLuint binding = 10;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, 256 * sizeof(int), Clut, GL_STATIC_READ);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, ssbo);
//texpage = fifo[4] >> 16;
uint32_t texpageX = ((texpage & 0b1111) * 64);
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
v2.x = v1.x + 8;
v2.y = v1.y;
v3.x = v1.x;
v3.y = v1.y + 8;
v4.x = v1.x + 8;
v4.y = v1.y + 8;
v1.x += xoffset;
v1.y += yoffset;
v2.x += xoffset;
v2.y += yoffset;
v3.x += xoffset;
v3.y += yoffset;
v4.x += xoffset;
v4.y += yoffset;
point t1, t2, t3, t4;
t1.x = (fifo[2] & 0xffff) & 0xff;
t1.y = ((fifo[2] & 0xffff) >> 8) & 0xff;
t2.x = t1.x + 16;
t2.y = t1.y;
t3.x = t1.x;
t3.y = t1.y + 16;
t4.x = t1.x + 16;
t4.y = t1.y + 16;
int colourDepth = (texpage >> 7) & 3;
uint32_t Vertices1[] = {
// positions // colors // texture coords
v1.x, v1.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
v2.x, v2.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
};
glViewport(0, 0, 1024, 512);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
glBindTexture(GL_TEXTURE_2D, VramTexture8);
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
glBindTexture(GL_TEXTURE_2D, VramTexture4);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
glBindVertexArray(VAO);
// Position attribute
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
glEnableVertexAttribArray(0);
// Colour attribute
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
glEnableVertexAttribArray(2);
// texpage attribute
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
glEnableVertexAttribArray(3);
// clut attribute
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
glEnableVertexAttribArray(4);
// colour depth attribute
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
glEnableVertexAttribArray(5);
glUseProgram(TextureShaderProgram);
glUniform1i(colourDepthUniform, colourDepth);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
uint32_t Vertices2[] = {
// positions // colors // texture coords // texpage
v2.x, v2.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y, texpageX, texpageY, clutX, clutY, colourDepth
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
};
glViewport(0, 0, 1024, 512);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
glBindTexture(GL_TEXTURE_2D, VramTexture8);
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
glBindTexture(GL_TEXTURE_2D, VramTexture4);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
glBindVertexArray(VAO);
// Position attribute
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
glEnableVertexAttribArray(0);
// Colour attribute
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
glEnableVertexAttribArray(2);
// texpage attribute
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
glEnableVertexAttribArray(3);
// clut attribute
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
glEnableVertexAttribArray(4);
// colour depth attribute
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
glEnableVertexAttribArray(5);
glUseProgram(TextureShaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
}
void gpu::texture_rectangle_variable_size_opaque() {
uint32_t colour = fifo[0] & 0xffffff;
debug_printf("[GP0] Textured Rectangle, variable size, opaque, raw-texture (colour: 0x%x)\n", colour);
@ -2468,6 +2786,151 @@ void gpu::texture_blending_rectangle_variable_size_semi_transparent() {
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
}
void gpu::textured_rectangle_variable_size_semi_transparent() {
uint32_t colour = fifo[0] & 0xffffff;
debug_printf("[GP0] Textured Rectangle, variable size, semi-transp, raw-texture (colour: 0x%x)\n", colour);
point v1, res, v2, v3, v4;
uint16_t texpage = texpage_raw;
uint16_t clut = 0;
v1.x = fifo[1] & 0xffff;
v1.y = fifo[1] >> 16;
clut = fifo[2] >> 16;
uint32_t clutX = (clut & 0x3f);
clutX *= 16;
uint32_t clutY = (clut >> 6);
int Clut[256];
for (int i = 0; i < 256; i++) {
Clut[i] = vram_rgb[clutY * 1024 + clutX + i];
}
GLuint ssbo;
GLuint binding = 10;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, 256 * sizeof(int), Clut, GL_STATIC_READ);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, ssbo);
//texpage = fifo[4] >> 16;
uint32_t texpageX = ((texpage & 0b1111) * 64);
uint32_t texpageY = (((texpage & 0b10000) >> 4) * 256);
res.x = fifo[3] & 0xffff;
res.y = fifo[3] >> 16;
v2.x = v1.x + res.x;
v2.y = v1.y;
v3.x = v1.x;
v3.y = v1.y + res.y;
v4.x = v1.x + res.x;
v4.y = v1.y + res.y;
v1.x += xoffset;
v1.y += yoffset;
v2.x += xoffset;
v2.y += yoffset;
v3.x += xoffset;
v3.y += yoffset;
v4.x += xoffset;
v4.y += yoffset;
point t1, t2, t3, t4;
t1.x = (fifo[2] & 0xffff) & 0xff;
t1.y = ((fifo[2] & 0xffff) >> 8) & 0xff;
t2.x = t1.x + res.x;
t2.y = t1.y;
t3.x = t1.x;
t3.y = t1.y + res.y;
t4.x = t1.x + res.x;
t4.y = t1.y + res.y;
int colourDepth = (texpage >> 7) & 3;
uint32_t Vertices1[] = {
// positions // colors // texture coords
v1.x, v1.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
v2.x, v2.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
};
glViewport(0, 0, 1024, 512);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
glBindTexture(GL_TEXTURE_2D, VramTexture8);
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
glBindTexture(GL_TEXTURE_2D, VramTexture4);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
glBindVertexArray(VAO);
// Position attribute
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
glEnableVertexAttribArray(0);
// Colour attribute
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
glEnableVertexAttribArray(2);
// texpage attribute
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
glEnableVertexAttribArray(3);
// clut attribute
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
glEnableVertexAttribArray(4);
// colour depth attribute
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
glEnableVertexAttribArray(5);
glUseProgram(TextureShaderProgram);
glUniform1i(colourDepthUniform, colourDepth);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
uint32_t Vertices2[] = {
// positions // colors // texture coords // texpage
v2.x, v2.y, 0, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
v3.x, v3.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t3.x, t3.y, texpageX, texpageY, clutX, clutY, colourDepth,
v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y, texpageX, texpageY, clutX, clutY, colourDepth
//v4.x, v4.y, 0.0f, (((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff), t4.x, t4.y // top left
};
glViewport(0, 0, 1024, 512);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
glBindTexture(GL_TEXTURE_2D, VramTexture8);
glActiveTexture(GL_TEXTURE0 + 2); // Texture unit 2
glBindTexture(GL_TEXTURE_2D, VramTexture4);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
glBindVertexArray(VAO);
// Position attribute
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)0);
glEnableVertexAttribArray(0);
// Colour attribute
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(3 * sizeof(uint32_t)));
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(6 * sizeof(uint32_t)));
glEnableVertexAttribArray(2);
// texpage attribute
glVertexAttribPointer(3, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(8 * sizeof(uint32_t)));
glEnableVertexAttribArray(3);
// clut attribute
glVertexAttribPointer(4, 2, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(10 * sizeof(uint32_t)));
glEnableVertexAttribArray(4);
// colour depth attribute
glVertexAttribPointer(5, 1, GL_UNSIGNED_INT, GL_FALSE, 13 * sizeof(uint32_t), (void*)(12 * sizeof(uint32_t)));
glEnableVertexAttribArray(5);
glUseProgram(TextureShaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
}
void gpu::monochrome_rectangle_dot_opaque() {
uint16_t x = fifo[1] & 0xffff;
uint16_t y = fifo[1] >> 16;
@ -2484,6 +2947,80 @@ void gpu::monochrome_rectangle_dot_opaque() {
return;
}
void gpu::monochrome_rectangle_8x8_opaque() {
uint32_t colour = fifo[0] & 0xffffff;
debug_printf("[GP0] Monochrome Rectangle (8x8) (opaque) (colour: 0x%x)\n", colour);
point v1, res, v2, v3, v4;
v1.x = fifo[1] & 0xffff;
v1.y = fifo[1] >> 16;
v2.x = v1.x + 8;
v2.y = v1.y;
v3.x = v1.x;
v3.y = v1.y + 8;
v4.x = v1.x + 8;
v4.y = v1.y + 8;
v1.x += xoffset;
v1.y += yoffset;
v2.x += xoffset;
v2.y += yoffset;
v3.x += xoffset;
v3.y += yoffset;
v4.x += xoffset;
v4.y += yoffset;
uint32_t Vertices1[]{
v1.x, v1.y, 0,
v2.x, v2.y, 0,
v3.x, v3.y, 0,
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff)
};
glViewport(0, 0, 1024, 512);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
glBindVertexArray(VAO);
glVertexAttribIPointer(0, 3, GL_INT, 3 * sizeof(uint32_t), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 3 * sizeof(uint32_t), (void*)(9 * sizeof(uint32_t)));
glEnableVertexAttribArray(1);
glUseProgram(ShaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
uint32_t Vertices2[]{
v2.x, v2.y, 0.0,
v3.x, v3.y, 0.0,
v4.x, v4.y, 0.0,
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff),
(((colour) >> 0) & 0xff), (((colour) >> 8) & 0xff), (((colour) >> 16) & 0xff)
};
glViewport(0, 0, 1024, 512);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
glBindVertexArray(VAO);
glVertexAttribIPointer(0, 3, GL_INT, 3 * sizeof(uint32_t), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_UNSIGNED_INT, GL_FALSE, 3 * sizeof(uint32_t), (void*)(9 * sizeof(uint32_t)));
glEnableVertexAttribArray(1);
glUseProgram(ShaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
}
void gpu::fill_rectangle() {
debug_printf("[GP0] Fill Rectangle\n");
glViewport(0, 0, 1024, 512);
@ -2518,12 +3055,20 @@ void gpu::cpu_to_vram() {
size &= ~1;
cmd_left = size / 2;
gp0_mode = 1;
return;
}
void gpu::vram_to_cpu() {
uint32_t resolution = fifo[2];
uint32_t coords = fifo[1];
auto width = resolution & 0xffff;
auto height = resolution >> 16;
return;
if (width == 0) width = 1024;
if (height == 0) height = 512;
auto x = coords & 0x3ff;
auto y = (coords >> 16) & 0x1ff;
uint32_t size = width * height;
size += 1;
size &= ~1;
}

17
gpu.h
View file

@ -111,12 +111,22 @@ public: // trongle stuff
return texelFetch(vram, ivec2(clut.x + idx, clut.y), 0);
}
vec4 fetchTexel8Bit(ivec2 coords) {
int texel = sample16(ivec2(coords.x / 2, coords.y) + ivec2(texpageCoords));
int idx = (texel >> ((coords.x % 2) * 8)) & 0xff;
return texelFetch(vram, ivec2(clut.x + idx, clut.y), 0);
}
void main()
{
vec4 colour;
if(colourDepth == 0) {
colour = fetchTexel4Bit(ivec2(TexCoord));
} else if (colourDepth == 2) {
}
else if (colourDepth == 1) {
colour = fetchTexel8Bit(ivec2(TexCoord));
}
else if (colourDepth == 2) {
vec2 TexCoords = vec2(float(TexCoord.x + texpageCoords.x) / 1024.f - 1, -(1 - float(TexCoord.y + texpageCoords.y) / 512.f));
colour = texture(vram, TexCoords);
} else colour = vec4(1.f, 0.f, 0.f, 1.f);
@ -148,6 +158,7 @@ public:
uint16_t* vram = new uint16_t[1024 * 512];
//std::vector<uint32_t> WriteBuffer;
uint32_t* WriteBuffer = new uint32_t[(1024 * 512) / 2];
std::vector<uint32_t> ReadBuffer;
int WriteBufferCnt = 0;
uint32_t* vram8 = new uint32_t[1024 * 512];
uint32_t* vram4 = new uint32_t[1024 * 512];
@ -207,14 +218,18 @@ public: // commands
void shaded_four_point_opaque_polygon();
void shaded_four_point_semi_transparent_polygon();
void shaded_texture_blending_textured_four_point_opaque_polygon();
void texture_blending_four_point_polygon_semi_transparent();
void monochrome_rectangle_variable_size_opaque();
void monochrome_rectangle_variable_size_semi_transparent();
void texture_blending_rectangle_variable_size_opaque();
void texture_rectangle_variable_size_opaque();
void texture_blending_rectangle_variable_size_semi_transparent();
void textured_rectangle_variable_size_semi_transparent();
void texture_blending_rectangle_8x8_opaque();
void texture_rectangle_8x8_opaque();
void texture_blending_rectangle_16x16_opaque();
void monochrome_rectangle_dot_opaque();
void monochrome_rectangle_8x8_opaque();
void fill_rectangle();
void cpu_to_vram();
void vram_to_cpu();

View file

@ -4,17 +4,17 @@ Size=400,400
Collapsed=0
[Window][Image]
Pos=0,22
Size=657,648
Pos=3,20
Size=652,650
Collapsed=0
[Window][System Settings]
Pos=1034,713
Pos=1015,701
Size=578,252
Collapsed=0
[Window][Imagevram]
Pos=663,22
Pos=661,22
Size=1263,645
Collapsed=0

View file

@ -21,12 +21,17 @@ void TMR1IRQ(void* dataptr) {
memory* memoryptr = (memory*)dataptr;
memoryptr->I_STAT |= 0b100000;
memoryptr->CDROM.Scheduler.push(&TMR1IRQ, memoryptr->CDROM.Scheduler.time + 5000, memoryptr);
//printf("[TIMERS] Sending TMR1 IRQ (stub)\n");
////printf("[TIMER]] Sending TMR1 IRQ (stub)\n");
}
void TMR2IRQ(void* dataptr) {
memory* memoryptr = (memory*)dataptr;
memoryptr->I_STAT |= 0b1000000;
}
void DMAIRQ(void* dataptr) {
memory* memoryptr = (memory*)dataptr;
memoryptr->I_STAT |= 0b1000;
memoryptr->DICR |= (1 << 28);
}
memory::memory() {
debug = false;
}
@ -112,8 +117,8 @@ uint8_t memory::read(uint32_t addr) {
}
if (masked_addr == 0x1f801800) { // cdrom status
printf("[CDROM] Status register read\n");
//return rand() % 0xff;
//printf("[CDROM] Status register read\n");
return rand() % 0xff;
return CDROM.status | (CDROM.cd.drqsts << 6);
}
@ -187,7 +192,7 @@ uint16_t memory::read16(uint32_t addr) {
// Timer 0 current value
if (masked_addr == 0x1f801100) {
printf("[TIMER] Read timer 0 current value\n");
//printf("[TIMER] Read timer 0 current value\n");
tmr1_stub += rand() % 4;
return tmr1_stub;
}
@ -205,7 +210,8 @@ uint16_t memory::read16(uint32_t addr) {
if (masked_addr == 0x1f801120) { // timer 2 stuff
//printf("[TIMER] Read timer 2 current value (stubbed)\n");
return tmr1_stub++;
tmr1_stub += rand() % 4;
return tmr1_stub;
}
if (masked_addr == 0x1f801124) {
@ -240,7 +246,7 @@ uint16_t memory::read16(uint32_t addr) {
//}
if (masked_addr >= 0x1F801D80 && masked_addr <= 0x1F801DBC) { // SPUSTAT
printf("[SPU] SPUSTAT read (stubbed)\n");
//printf("[SPU] SPUSTAT read (stubbed)\n");
return rand() % 0xff;
}
@ -299,7 +305,7 @@ uint32_t memory::read32(uint32_t addr) {
// Timer 1 counter mode
if (masked_addr == 0x1f801114) {
//printf("[TIMER] Read timer 1 counter mode (stubbed)\n");
printf("[TIMER] Read timer 1 counter mode (stubbed)\n");
return 0;
}
@ -334,8 +340,9 @@ uint32_t memory::read32(uint32_t addr) {
return 0b01011110100000000000000000000000; // stubbing it
}
if (masked_addr == 0x1f801810) // GPUREAD
if (masked_addr == 0x1f801810) { // GPUREAD
return gpuread;
}
// dma
if (masked_addr == 0x1f8010f0) // DCPR
@ -344,6 +351,22 @@ uint32_t memory::read32(uint32_t addr) {
if (masked_addr == 0x1f8010f4) // DICR
return DICR;
// channel 1 (stubbed)
if (masked_addr == 0x1f801090) { // base address
printf("[DMA] Read DMA1 (mdec -> ram) base address (stubbed)\n");
return 0;
}
if (masked_addr == 0x1f801094) { // block control
printf("[DMA] Read DMA1 (mdec -> ram) block control (stubbed)\n");
return 0;
}
if (masked_addr == 0x1f801098) { // control
printf("[DMA] Read DMA1 (mdec -> ram) control (stubbed)\n");
return 0;
}
// channel 2
if (masked_addr == 0x1f8010a0) // base address
return Ch2.MADR;
@ -396,6 +419,12 @@ uint32_t memory::read32(uint32_t addr) {
}
#endif
// SPU
if (masked_addr == 0x1F801D9C) {
printf("[SPU] Read Voice 0..23 ON/OFF (stubbed)\n");
return 0;
}
// MDEC
if (masked_addr == 0x1f801820) {
printf("[MDEC] Read MDEC Data/Response Register (stubbed)\n");
@ -498,7 +527,7 @@ void memory::write(uint32_t addr, uint8_t data, bool log) {
}
if (masked_addr == 0x1f801104 || masked_addr == 0x1f801108 || masked_addr == 0x1f801100 || masked_addr == 0x1f801114 || masked_addr == 0x1f801118) {
//printf("[TIMERS] Write timer 0/1 regs (0x%08x)\n", masked_addr);
////printf("[TIMER]] Write timer 0/1 regs (0x%08x)\n", masked_addr);
return;
}
@ -658,7 +687,7 @@ void memory::write32(uint32_t addr, uint32_t data) {
return;
}
if (masked_addr == 0x1f8010c8) {
//CDROM.Scheduler.push(&DMAIRQ, CDROM.Scheduler.time + 5000, this);
CDROM.Scheduler.push(&DMAIRQ, CDROM.Scheduler.time + 5000, this);
Ch4.CHCR = data;
return;
}
@ -679,15 +708,15 @@ void memory::write32(uint32_t addr, uint32_t data) {
}
if (masked_addr == 0x1f801114) {
////printf("[TIMERS] Sending TMR1 IRQ (stub)\n");
//printf("[TIMER] Write timer 2 counter mode\n");
//////printf("[TIMER]] Sending TMR1 IRQ (stub)\n");
printf("[TIMER] Write timer 2 counter mode\n");
tmr1_stub = 0;
//CDROM.Scheduler.push(&TMR1IRQ, CDROM.Scheduler.time + 5000, this);
return;
}
if (masked_addr == 0x1f801104 || masked_addr == 0x1f801108 || masked_addr == 0x1f801100 || masked_addr == 0x1f801114 || masked_addr == 0x1f801118) {
//printf("[TIMERS] Write timer 0/1 regs (0x%08x)\n", masked_addr);
////printf("[TIMER]] Write timer 0/1 regs (0x%08x)\n", masked_addr);
return;
}
@ -761,13 +790,13 @@ void memory::write16(uint32_t addr, uint16_t data) {
}
if (masked_addr == 0x1f801110) {
//printf("[TIMER] Write timer 1 current value\n");
printf("[TIMER] Write timer 1 current value\n");
tmr1_stub = data;
return;
}
if (masked_addr == 0x1f801104 || masked_addr == 0x1f801108 || masked_addr == 0x1f801100 || masked_addr == 0x1f801114 || masked_addr == 0x1f801118 || masked_addr == 0x1f801110 || masked_addr == 0x1f801124 || masked_addr == masked_addr == 0x1f801124 || masked_addr == 0x1f801128 || masked_addr == 0x1f801120) {
//printf("[TIMER] Write timer regs\n");
printf("[TIMER] Write timer regs\n");
return;
}

View file

@ -109,7 +109,7 @@ void pad::WriteTXDATA(uint8_t data) {
case 0xff: break;
default:
printf("[PAD] Received unhandled command 0x%x\n", data);
exit(0);
//exit(0);
}
}