aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/gpu_neon/gpu.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/plugins/gpu_neon/gpu.c b/plugins/gpu_neon/gpu.c
index f1d8993..d6151cd 100644
--- a/plugins/gpu_neon/gpu.c
+++ b/plugins/gpu_neon/gpu.c
@@ -26,10 +26,26 @@
struct psx_gpu gpu __attribute__((aligned(2048)));
+static noinline int do_cmd_buffer(uint32_t *data, int count);
+
+static noinline void do_cmd_reset(void)
+{
+ if (unlikely(gpu.cmd_len > 0))
+ do_cmd_buffer(gpu.cmd_buffer, gpu.cmd_len);
+
+ gpu.cmd_len = 0;
+ gpu.dma.h = 0;
+}
+
static noinline void do_reset(void)
{
+ int i;
+
+ do_cmd_reset();
+
memset(gpu.regs, 0, sizeof(gpu.regs));
- memset(gpu.ex_regs, 0, sizeof(gpu.ex_regs));
+ for (i = 0; i < sizeof(gpu.ex_regs) / sizeof(gpu.ex_regs[0]); i++)
+ gpu.ex_regs[i] = (0xe0 + i) << 24;
gpu.status.reg = 0x14802000;
gpu.gp0 = 0;
gpu.regs[3] = 1;
@@ -115,7 +131,10 @@ long GPUinit(void)
gpu.state.frame_count = &gpu.zero;
gpu.state.hcnt = &gpu.zero;
+ gpu.frameskip.active = 0;
+ gpu.cmd_len = 0;
do_reset();
+
return ret;
}
@@ -131,7 +150,7 @@ void GPUwriteStatus(uint32_t data)
uint32_t cmd = data >> 24;
if (cmd < ARRAY_SIZE(gpu.regs)) {
- if (cmd != 0 && cmd != 5 && gpu.regs[cmd] == data)
+ if (cmd > 1 && cmd != 5 && gpu.regs[cmd] == data)
return;
gpu.regs[cmd] = data;
}
@@ -142,6 +161,9 @@ void GPUwriteStatus(uint32_t data)
case 0x00:
do_reset();
break;
+ case 0x01:
+ do_cmd_reset();
+ break;
case 0x03:
gpu.status.blanking = data & 1;
break;
@@ -267,8 +289,8 @@ static void start_vram_transfer(uint32_t pos_word, uint32_t size_word, int is_re
gpu.dma.x = pos_word & 0x3ff;
gpu.dma.y = (pos_word >> 16) & 0x1ff;
- gpu.dma.w = size_word & 0x3ff;
- gpu.dma.h = (size_word >> 16) & 0x1ff;
+ gpu.dma.w = ((size_word - 1) & 0x3ff) + 1;
+ gpu.dma.h = (((size_word >> 16) - 1) & 0x1ff) + 1;
gpu.dma.offset = 0;
renderer_flush_queues();
@@ -286,7 +308,7 @@ static void start_vram_transfer(uint32_t pos_word, uint32_t size_word, int is_re
gpu.dma.x, gpu.dma.y, gpu.dma.w, gpu.dma.h);
}
-static int check_cmd(uint32_t *data, int count)
+static noinline int do_cmd_buffer(uint32_t *data, int count)
{
int len, cmd, start, pos;
int vram_dirty = 0;
@@ -366,7 +388,7 @@ static int check_cmd(uint32_t *data, int count)
static void flush_cmd_buffer(void)
{
- int left = check_cmd(gpu.cmd_buffer, gpu.cmd_len);
+ int left = do_cmd_buffer(gpu.cmd_buffer, gpu.cmd_len);
if (left > 0)
memmove(gpu.cmd_buffer, gpu.cmd_buffer + gpu.cmd_len - left, left * 4);
gpu.cmd_len = left;
@@ -381,7 +403,7 @@ void GPUwriteDataMem(uint32_t *mem, int count)
if (unlikely(gpu.cmd_len > 0))
flush_cmd_buffer();
- left = check_cmd(mem, count);
+ left = do_cmd_buffer(mem, count);
if (left)
log_anomaly("GPUwriteDataMem: discarded %d/%d words\n", left, count);
}
@@ -432,7 +454,7 @@ long GPUdmaChain(uint32_t *rambase, uint32_t start_addr)
list[0] |= 0x800000;
if (len) {
- left = check_cmd(list + 1, len);
+ left = do_cmd_buffer(list + 1, len);
if (left)
log_anomaly("GPUdmaChain: discarded %d/%d words\n", left, len);
}