Some DMA fixes, update README

This commit is contained in:
liuk7071 2022-09-13 19:13:26 +02:00
parent 8658f3cf64
commit 3ac261541a
13 changed files with 101 additions and 39 deletions

View file

@ -850,9 +850,9 @@ int main(int argc, char** argv) {
if(run) Cpu.bus.mem.I_STAT |= 1;
Cpu.bus.Gpu.interlace = !Cpu.bus.Gpu.interlace;
Cpu.bus.mem.I_STAT |= (1 << 9);
if (spuirq) {
//printf("[SPU] IRQ\n");
Cpu.bus.mem.I_STAT |= (1 << 9);
//spuirq = false;
}
if (padirq) {

View file

@ -364,7 +364,7 @@ void cdrom::Stop() {
queued_response_length = 1;
Scheduler.push(&INT3, Scheduler.time + 50401, this);
Scheduler.push(&INT2, Scheduler.time + 35000, this);
Scheduler.push(&INT2, Scheduler.time + 50401 + 35000, this);
status |= 0b00100000; // Set response fifo empty bit (means it's full)
}

22
cpu.cpp
View file

@ -187,15 +187,15 @@ void cpu::do_dma() {
while (words > 0) {
uint32_t current_addr = addr & 0x1ffffc;
uint8_t r = bus.MDEC.output[bus.MDEC.dma_out_index + 0] >> 3;
uint8_t g = bus.MDEC.output[bus.MDEC.dma_out_index + 1] >> 3;
uint8_t b = bus.MDEC.output[bus.MDEC.dma_out_index + 2] >> 3;
uint8_t r = bus.MDEC.output[(bus.MDEC.dma_out_index + 0) & 0x4fffff] >> 3;
uint8_t g = bus.MDEC.output[(bus.MDEC.dma_out_index + 1) & 0x4fffff] >> 3;
uint8_t b = bus.MDEC.output[(bus.MDEC.dma_out_index + 2) & 0x4fffff] >> 3;
uint16_t rgb = ((bus.MDEC.status & (1 << 23)) >> 8) | (b << 10) | (g << 5) | r;
bus.mem.write16(current_addr, rgb);
bus.MDEC.dma_out_index += 3;
r = bus.MDEC.output[bus.MDEC.dma_out_index + 0] >> 3;
g = bus.MDEC.output[bus.MDEC.dma_out_index + 1] >> 3;
b = bus.MDEC.output[bus.MDEC.dma_out_index + 2] >> 3;
r = bus.MDEC.output[(bus.MDEC.dma_out_index + 0) & 0x4fffff] >> 3;
g = bus.MDEC.output[(bus.MDEC.dma_out_index + 1) & 0x4fffff] >> 3;
b = bus.MDEC.output[(bus.MDEC.dma_out_index + 2) & 0x4fffff] >> 3;
rgb = ((bus.MDEC.status & (1 << 23)) >> 8) | (b << 10) | (g << 5) | r;
bus.mem.write16(current_addr + 2, rgb);
if (incrementing) addr += 4; else addr -= 4;
@ -226,12 +226,13 @@ void cpu::do_dma() {
bool incrementing = ((bus.mem.Ch2.CHCR >> 1) & 1) == 0;
auto direction = (bus.mem.Ch2.CHCR) & 1;
uint16_t words = (bus.mem.Ch2.BCR) & 0xffff;
if (words == 0) words = 0x10000;
uint32_t addr = bus.mem.Ch2.MADR & 0x1ffffc;
uint32_t header = bus.mem.read32(addr);
switch (sync_mode) {
case 1: { // Block Copy
words *= (bus.mem.Ch2.BCR >> 16);
words *= ((bus.mem.Ch2.BCR >> 16) != 0) ? (bus.mem.Ch2.BCR >> 16) : 0x10000;
debug_log("[DMA] Start GPU Block Copy\n");
switch (direction) {
case 1:
@ -244,6 +245,7 @@ void cpu::do_dma() {
if (incrementing) addr += 4; else addr -= 4;
words--;
}
bus.mem.Ch2.BCR &= 0xffff; // SyncMode=1 decrements BA to zero
bus.mem.Ch2.CHCR &= ~(1 << 24);
bus.mem.Ch2.CHCR &= ~(1 << 28);
//debug = false;
@ -262,6 +264,7 @@ void cpu::do_dma() {
if (incrementing) addr += 4; else addr -= 4;
words--;
}
bus.mem.Ch2.BCR &= 0xffff; // SyncMode=1 decrements BA to zero
bus.mem.Ch2.CHCR &= ~(1 << 24);
bus.mem.Ch2.CHCR &= ~(1 << 28);
//debug = false;
@ -271,7 +274,6 @@ void cpu::do_dma() {
//should_service_dma_irq = true;
}
return;
return;
default:
printf("[DMA] Unhandled Direction (GPU Block Copy)");
exit(0);
@ -344,8 +346,8 @@ void cpu::do_dma() {
if (incrementing) addr += 4; else addr -= 4;
words--;
}
if (bus.mem.Ch3.CHCR & (1 << 8)) bus.mem.Ch3.BCR &= ~0xffff; // SyncMode=0 with chopping enabled decrements BC to zero
printf("[DMA] CDROM Block Copy completed (pc = 0x%08x)\n", pc);
bus.mem.CDROM.status &= ~(0b10000000); // DRQSTS
bus.mem.Ch3.CHCR &= ~(1 << 24);
bus.mem.Ch3.CHCR &= ~(1 << 28);
//debug = false;
@ -412,6 +414,7 @@ void cpu::do_dma() {
if (((bus.mem.DICR >> 20) & 1) && ((bus.mem.DICR >> 23) & 1)) {
bus.mem.DICR |= (1 << 28);
bus.mem.I_STAT |= 0b1000;
//bus.mem.I_STAT |= (1 << 9);
}
return;
case 0:
@ -439,6 +442,7 @@ void cpu::do_dma() {
if (((bus.mem.DICR >> 20) & 1) && ((bus.mem.DICR >> 23) & 1)) {
bus.mem.DICR |= (1 << 28);
bus.mem.I_STAT |= 0b1000;
//bus.mem.I_STAT |= (1 << 9);
}
return;
default:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 812 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

65
gpu.cpp
View file

@ -277,6 +277,12 @@ void gpu::execute_gp0(uint32_t command) {
cmd_left = 6;
break;
}
case 0x25: { // Textured three-point polygon, opaque, raw-texture
fifo[0] = command;
cmd_length++;
cmd_left = 6;
break;
}
case 0x2B:
case 0x2A: { // Monochrome four-point polygon, semi-transparent
fifo[0] = command;
@ -564,7 +570,8 @@ void gpu::execute_gp0(uint32_t command) {
case 0x23:
case 0x22: SwitchToUntextured(); gpu::draw_untextured_tri(MONOCHROME, SEMI_TRANSPARENT); break;
case 0x26:
case 0x24: SwitchToTextured(); gpu::texture_blending_three_point_opaque_polygon(); break;
case 0x24: SwitchToTextured(); gpu::texture_blending_three_point_opaque_polygon(); break;
case 0x25: SwitchToTextured(); gpu::texture_three_point_opaque_polygon(); break;
case 0x29:
case 0x28: SwitchToUntextured(); gpu::draw_untextured_quad(MONOCHROME, SOLID); break;
case 0x2B:
@ -921,6 +928,58 @@ void gpu::texture_blending_three_point_opaque_polygon() {
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void gpu::texture_three_point_opaque_polygon() {
uint32_t colour = fifo[0] & 0xffffff;
debug_printf("[GP0] Textured three-point polygon, opaque, raw-texture (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;
//printf("\nclut: 0x%x\n", clut);
uint32_t clutX = (clut & 0x3f);
clutX *= 16;
uint32_t clutY = (clut >> 6);
texpage = fifo[4] >> 16;
//printf("texpage: 0x%x\n", texpage);
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;
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, 128, 128, 128, t1.x, t1.y, texpageX, texpageY, clutX, clutY, colourDepth,
v2.x, v2.y, 0.0f, 128, 128, 128, t2.x, t2.y, texpageX, texpageY, clutX, clutY, colourDepth,
v3.x, v3.y, 0.0f, 128, 128, 128, 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
};
glBindTexture(GL_TEXTURE_2D, SampleVramTexture);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
glUniform1i(colourDepthUniform, colourDepth);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void gpu::texture_blending_four_point_opaque_polygon() {
uint32_t colour = fifo[0] & 0xffffff;
debug_printf("[GP0] Textured four-point polygon, opaque, texture blending (colour: 0x%x)\n", colour);
@ -2280,10 +2339,10 @@ void gpu::vram_to_vram() {
auto dest_x = dest_coords & 0x3ff;
auto dest_y = (dest_coords >> 16) & 0x1ff;
//glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ReadBuffer);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ReadBuffer);
glBindTexture(GL_TEXTURE_2D, VramTexture);
//glTexSubImage2D(GL_TEXTURE_2D, 0, dest_x, dest_y, width, height, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ReadBuffer);
glTexSubImage2D(GL_TEXTURE_2D, 0, dest_x, dest_y, width, height, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ReadBuffer);
}
void gpu::cpu_to_vram() {

1
gpu.h
View file

@ -231,6 +231,7 @@ public: // commands
void draw_untextured_quad(int shading, int transparency);
void texture_blending_three_point_opaque_polygon();
void texture_three_point_opaque_polygon();
void monochrome_line_opaque();
void shaded_line_semi_transparent();
void monochrome_polyline_opaque();

View file

@ -609,6 +609,7 @@ void gte::commandSQR() {
}
void gte::commandDPCT() {
//printf("DPCT\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
for (int i = 0; i < 3; i++) {
@ -770,6 +771,7 @@ void gte::commandRTPT() {
}
void gte::commandGPF() {
//printf("GPF\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
@ -781,6 +783,7 @@ void gte::commandGPF() {
}
void gte::commandGPL() {
//printf("GPL\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
MAC1 <<= shift;

View file

@ -4,32 +4,32 @@ Size=400,400
Collapsed=0
[Window][Image]
Pos=2,21
Size=762,575
Pos=1,21
Size=1919,992
Collapsed=0
[Window][Log]
Pos=2,601
Size=667,338
Pos=5,602
Size=667,321
Collapsed=0
[Window][Imagevram]
Pos=765,23
Size=1165,593
Pos=764,23
Size=1166,593
Collapsed=0
[Window][System Settings]
Pos=245,347
Pos=245,348
Size=443,215
Collapsed=0
[Window][Configure Pads]
Pos=59,61
Pos=55,66
Size=124,127
Collapsed=0
[Window][Enabled Interrupts]
Pos=554,600
Pos=675,622
Size=151,261
Collapsed=0

View file

@ -109,6 +109,7 @@ void mdec::decode_macroblock_15bpp() {
yuv_to_rgb(8, 8, y4);
//printf("[MDEC] Decoded macroblock\n");
output_index += 256 * 3;
output_index = (output_index > 0x4fffff) ? (0x4fffff - 3) : output_index; // Quick way to avoiding overflowing... shouldn't ever happen but it does
}
output_index = 0;
status &= ~(1 << 31);

2
mdec.h
View file

@ -27,7 +27,7 @@ public:
int16_t st[64] = { 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 32138, 27245, 18204, 6392, -6393, -18205, -27246, -32139, 30273, 12539, -12540, -30274, -30274, -12540, 12539, 30273, 27245, -6393, -32139, -18205, 18204, 32138, 6392, -27246, 23170, -23171, -23171, 23170, 23170, -23171, -23171, 23170, 18204, -32139, 6392, 27245, -27246, -6393, 32138, -18205, 12539, -30274, 30273, -12540, -12540, 30273, -30274, 12539, 6392, -18205, 27245, -32139, 32138, -27246, 18204, -6393 };
std::vector<uint16_t> input;
uint8_t* output = new uint8_t[0x50000];
uint8_t* output = new uint8_t[0x500000];
int16_t cr[64] = { 0 };
int16_t cb[64] = { 0 };
int16_t y1[64] = { 0 };

Binary file not shown.

View file

@ -106,20 +106,10 @@ uint8_t memory::read(uint32_t addr) {
uint32_t bytes;
uint32_t masked_addr = mask_address(addr);
if (masked_addr == 0x1f8010f6) return 0;
// SPU
if (masked_addr >= 0x1f801c00 && (masked_addr <= 0x1f801d7f)) return 0;
if (masked_addr == 0xf1000001) {
return 0;
}
if (masked_addr == 0xf1000002) {
return 0;
}
if (masked_addr == 0xf1000003) {
return 0;
}
if (masked_addr >= 0xf1000004 && masked_addr <= 0xf10000ff) {
return 0;
}
if (masked_addr == 0x1f8010f6) return 0;
if (masked_addr == 0x1F801070) { // I_STAT
debug_log("[IRQ] Status 8bit read\n");
@ -234,6 +224,7 @@ uint16_t memory::read16(uint32_t addr) {
if (masked_addr == 0x1f7fffd0) return 0; // This shouldn't happen
// SPU stuff
if (masked_addr >= 0x1f801c00 && (masked_addr <= 0x1f801d7f)) return 0;
if (masked_addr == 0x1f801d08) return 0;
if (masked_addr == 0x1f801d0a) return 0;
if (masked_addr == 0x1f801d18) return 0;
@ -361,8 +352,8 @@ uint32_t memory::read32(uint32_t addr) {
uint32_t bytes;
uint32_t masked_addr = mask_address(addr);
if (masked_addr == 0x02000008) return 0;
if (masked_addr == 0x02000004) return 0;
// SPU
if (masked_addr >= 0x1f801c00 && (masked_addr <= 0x1f801d7f)) return 0;
// Timer 1 counter mode
if (masked_addr == 0x1f801114) {
@ -932,6 +923,9 @@ void memory::write16(uint32_t addr, uint16_t data) {
uint32_t masked_addr = mask_address(addr);
// SPU stuff
if (masked_addr >= 0x1f801c00 && (masked_addr <= 0x1f801d7f)) return;
// SIO
if (masked_addr == 0x1f801050) return;
if (masked_addr == 0x1f801058) return;