Skip to content

Commit bd3e555

Browse files
committed
Fix GPU commands
1 parent 4787a90 commit bd3e555

3 files changed

Lines changed: 148 additions & 69 deletions

File tree

psx/dev/gpu.c

Lines changed: 118 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,26 @@ uint32_t psx_gpu_read32(psx_gpu_t* gpu, uint32_t offset) {
4040
case 0x00: {
4141
uint32_t data = 0x0;
4242

43-
if (gpu->c0_ysiz) {
44-
data = *((uint32_t*)(&gpu->vram[gpu->c0_xpos + (gpu->c0_ypos * 1024)]));
43+
if (gpu->c0_tsiz) {
44+
data |= gpu->vram[gpu->c0_addr + (gpu->c0_xcnt + (gpu->c0_ycnt * 1024))];
4545

46-
gpu->c0_xsiz -= 2;
47-
gpu->c0_xpos += 2;
46+
gpu->c0_xcnt += 1;
4847

49-
if (gpu->c0_xsiz <= 0) {
50-
gpu->c0_ypos += 1;
51-
gpu->c0_ysiz -= 1;
48+
if (gpu->c0_xcnt == gpu->c0_xsiz) {
49+
gpu->c0_ycnt += 1;
50+
gpu->c0_xcnt = 0;
5251
}
52+
53+
data |= gpu->vram[gpu->c0_addr + (gpu->c0_xcnt + (gpu->c0_ycnt * 1024))] << 16;
54+
55+
gpu->c0_xcnt += 1;
56+
57+
if (gpu->c0_xcnt == gpu->c0_xsiz) {
58+
gpu->c0_ycnt += 1;
59+
gpu->c0_xcnt = 0;
60+
}
61+
62+
gpu->c0_tsiz -= 2;
5363
}
5464

5565
return data;
@@ -94,11 +104,11 @@ int max(int x0, int x1) {
94104

95105
#define EDGE(a, b, c) ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x))
96106

97-
uint16_t gpu_fetch_texel(psx_gpu_t* gpu, uint16_t tx, uint16_t ty, uint32_t tpx, uint32_t tpy) {
107+
uint16_t gpu_fetch_texel(psx_gpu_t* gpu, uint16_t tx, uint16_t ty, uint32_t tpx, uint32_t tpy, int depth) {
98108
tx = (tx & ~gpu->texw_mx) | (gpu->texw_ox & gpu->texw_mx);
99109
ty = (ty & ~gpu->texw_my) | (gpu->texw_oy & gpu->texw_my);
100110

101-
switch (gpu->texp_d) {
111+
switch (depth) {
102112
// 4-bit
103113
case 0: {
104114
uint16_t texel = gpu->vram[(tpx + (tx >> 2)) + ((tpy + ty) * 1024)];
@@ -124,20 +134,82 @@ uint16_t gpu_fetch_texel(psx_gpu_t* gpu, uint16_t tx, uint16_t ty, uint32_t tpx,
124134
}
125135
}
126136

127-
void gpu_render_flat_line(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, uint32_t color) {
128-
double l = 640.0;
137+
void plotLineLow(psx_gpu_t* gpu, int x0, int y0, int x1, int y1, uint16_t color) {
138+
int dx = x1 - x0;
139+
int dy = y1 - y0;
140+
int yi = 1;
141+
if (dy < 0) {
142+
yi = -1;
143+
dy = -dy;
144+
}
145+
int d = (2 * dy) - dx;
146+
int y = y0;
129147

130-
for (double p = 0.0; p < 1.0; p += 1.0 / l) {
131-
unsigned int ax = (v0.x * p) + (v1.x * (1.0f - p));
132-
unsigned int ay = (v0.y * p) + (v1.y * (1.0f - p));
148+
for (int x = x0; x < x1; x++) {
149+
gpu->vram[x + (y * 1024)] = color;
133150

134-
if ((ax > 1024) || (ay > 512))
135-
continue;
151+
if (d > 0) {
152+
y += yi;
153+
d += (2 * (dy - dx));
154+
} else {
155+
d += 2*dy;
156+
}
157+
}
158+
}
136159

137-
gpu->vram[ax + (ay * 1024)] = color;
160+
void plotLineHigh(psx_gpu_t* gpu, int x0, int y0, int x1, int y1, uint16_t color) {
161+
int dx = x1 - x0;
162+
int dy = y1 - y0;
163+
int xi = 1;
164+
if (dx < 0) {
165+
xi = -1;
166+
dx = -dx;
167+
}
168+
int d = (2 * dx) - dy;
169+
int x = x0;
170+
171+
for (int y = y0; y < y1; y++) {
172+
gpu->vram[x + (y * 1024)] = color;
173+
if (d > 0) {
174+
x = x + xi;
175+
d += (2 * (dx - dy));
176+
} else {
177+
d += 2*dx;
178+
}
138179
}
139180
}
140181

182+
void plotLine(psx_gpu_t* gpu, int x0, int y0, int x1, int y1, uint16_t color) {
183+
if (abs(y1 - y0) < abs(x1 - x0)) {
184+
if (x0 > x1) {
185+
plotLineLow(gpu, x1, y1, x0, y0, color);
186+
} else {
187+
plotLineLow(gpu, x0, y0, x1, y1, color);
188+
}
189+
} else {
190+
if (y0 > y1) {
191+
plotLineHigh(gpu, x1, y1, x0, y0, color);
192+
} else {
193+
plotLineHigh(gpu, x0, y0, x1, y1, color);
194+
}
195+
}
196+
}
197+
198+
void gpu_render_flat_line(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, uint32_t color) {
199+
plotLine(gpu, v0.x, v0.y, v1.x, v1.y, color);
200+
// double l = 640.0;
201+
202+
// for (double p = 0.0; p < 1.0; p += 1.0 / l) {
203+
// unsigned int ax = (v0.x * p) + (v1.x * (1.0f - p));
204+
// unsigned int ay = (v0.y * p) + (v1.y * (1.0f - p));
205+
206+
// if ((ax > 1024) || (ay > 512))
207+
// continue;
208+
209+
// gpu->vram[ax + (ay * 1024)] = color;
210+
// }
211+
}
212+
141213
void gpu_render_flat_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint32_t h, uint32_t color) {
142214
/* Offset coordinates */
143215
v.x += gpu->off_x;
@@ -171,7 +243,7 @@ void gpu_render_textured_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint3
171243

172244
for (int y = ymin; y < ymax; y++) {
173245
for (int x = xmin; x < xmax; x++) {
174-
uint16_t color = gpu_fetch_texel(gpu, a.tx + xc, a.ty + yc, tpx, tpy);
246+
uint16_t color = gpu_fetch_texel(gpu, a.tx + xc, a.ty + yc, tpx, tpy, gpu->texp_d);
175247

176248
++xc;
177249

@@ -298,7 +370,7 @@ void gpu_render_shaded_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vertex
298370
}
299371
}
300372

301-
void gpu_render_textured_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vertex_t v2, uint32_t tpx, uint32_t tpy) {
373+
void gpu_render_textured_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vertex_t v2, uint32_t tpx, uint32_t tpy, int depth) {
302374
vertex_t a, b, c;
303375

304376
a = v0;
@@ -341,7 +413,7 @@ void gpu_render_textured_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vert
341413
uint32_t tx = ((z0 * a.tx) + (z1 * b.tx) + (z2 * c.tx)) / area;
342414
uint32_t ty = ((z0 * a.ty) + (z1 * b.ty) + (z2 * c.ty)) / area;
343415

344-
uint16_t color = gpu_fetch_texel(gpu, tx, ty, tpx, tpy);
416+
uint16_t color = gpu_fetch_texel(gpu, tx, ty, tpx, tpy, depth);
345417

346418
if (!color) continue;
347419

@@ -511,9 +583,9 @@ void gpu_cmd_2c(psx_gpu_t* gpu) {
511583
if (!gpu->cmd_args_remaining) {
512584
gpu->state = GPU_STATE_RECV_DATA;
513585

586+
uint32_t texp = gpu->buf[4] >> 16;
514587
gpu->color = gpu->buf[0] & 0xffffff;
515588
gpu->pal = gpu->buf[2] >> 16;
516-
gpu->texp = gpu->buf[4] >> 16;
517589
gpu->v0.tx = gpu->buf[2] & 0xff;
518590
gpu->v0.ty = (gpu->buf[2] >> 8) & 0xff;
519591
gpu->v1.tx = gpu->buf[4] & 0xff;
@@ -534,11 +606,12 @@ void gpu_cmd_2c(psx_gpu_t* gpu) {
534606
gpu->clut_x = (gpu->pal & 0x3f) << 4;
535607
gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
536608

537-
uint32_t tpx = (gpu->texp & 0xf) << 6;
538-
uint32_t tpy = (gpu->texp & 0x10) << 4;
609+
uint32_t tpx = (texp & 0xf) << 6;
610+
uint32_t tpy = (texp & 0x10) << 4;
611+
uint32_t depth = (texp >> 7) & 0x3;
539612

540-
gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy);
541-
gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy);
613+
gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, depth);
614+
gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy, depth);
542615

543616
gpu->state = GPU_STATE_RECV_CMD;
544617
}
@@ -558,9 +631,9 @@ void gpu_cmd_2d(psx_gpu_t* gpu) {
558631
if (!gpu->cmd_args_remaining) {
559632
gpu->state = GPU_STATE_RECV_DATA;
560633

634+
uint32_t texp = gpu->buf[4] >> 16;
561635
gpu->color = gpu->buf[0] & 0xffffff;
562636
gpu->pal = gpu->buf[2] >> 16;
563-
gpu->texp = gpu->buf[4] >> 16;
564637
gpu->v0.tx = gpu->buf[2] & 0xff;
565638
gpu->v0.ty = (gpu->buf[2] >> 8) & 0xff;
566639
gpu->v1.tx = gpu->buf[4] & 0xff;
@@ -581,11 +654,12 @@ void gpu_cmd_2d(psx_gpu_t* gpu) {
581654
gpu->clut_x = (gpu->pal & 0x3f) << 4;
582655
gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
583656

584-
uint32_t tpx = (gpu->texp & 0xf) << 6;
585-
uint32_t tpy = (gpu->texp & 0x10) << 4;
657+
uint32_t tpx = (texp & 0xf) << 6;
658+
uint32_t tpy = (texp & 0x10) << 4;
659+
int depth = (texp >> 7) & 0x3;
586660

587-
gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy);
588-
gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy);
661+
gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, depth);
662+
gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy, depth);
589663

590664
gpu->state = GPU_STATE_RECV_CMD;
591665
}
@@ -687,10 +761,18 @@ void gpu_cmd_c0(psx_gpu_t* gpu) {
687761

688762
case GPU_STATE_RECV_ARGS: {
689763
if (!gpu->cmd_args_remaining) {
690-
gpu->c0_xpos = gpu->buf[1] & 0xffff;
691-
gpu->c0_ypos = gpu->buf[1] >> 16;
764+
gpu->c0_xcnt = 0;
765+
gpu->c0_ycnt = 0;
766+
uint32_t c0_xpos = gpu->buf[1] & 0xffff;
767+
uint32_t c0_ypos = gpu->buf[1] >> 16;
692768
gpu->c0_xsiz = gpu->buf[2] & 0xffff;
693769
gpu->c0_ysiz = gpu->buf[2] >> 16;
770+
c0_xpos = c0_xpos & 0x3ff;
771+
c0_ypos = c0_ypos & 0x1ff;
772+
gpu->c0_xsiz = ((gpu->c0_xsiz - 1) & 0x3ff) + 1;
773+
gpu->c0_ysiz = ((gpu->c0_ysiz - 1) & 0x1ff) + 1;
774+
gpu->c0_tsiz = ((gpu->c0_xsiz * gpu->c0_ysiz) + 1) & 0xfffffffe;
775+
gpu->c0_addr = c0_xpos + (c0_ypos * 1024);
694776

695777
gpu->state = GPU_STATE_RECV_CMD;
696778
}
@@ -720,12 +802,6 @@ void gpu_cmd_02(psx_gpu_t* gpu) {
720802
gpu->xsiz = (((gpu->xsiz & 0x3ff) + 0x0f) & 0xfffffff0);
721803
gpu->ysiz = gpu->ysiz & 0x1ff;
722804

723-
log_fatal("Render flat rectangle pos=(%u, %u) siz=(%u, %u), color=%02x",
724-
gpu->v0.x, gpu->v0.y,
725-
gpu->xsiz, gpu->ysiz,
726-
gpu->color
727-
);
728-
729805
gpu->v0.x += gpu->off_x;
730806
gpu->v0.y += gpu->off_y;
731807

@@ -743,9 +819,12 @@ void psx_gpu_update_cmd(psx_gpu_t* gpu) {
743819
case 0x01: /* Cache clear */ break;
744820
case 0x02: gpu_cmd_02(gpu); break;
745821
case 0x28: gpu_cmd_28(gpu); break;
746-
case 0x2c: gpu_cmd_2c(gpu); break;
822+
case 0x2c: gpu_cmd_2d(gpu); break;
747823
case 0x2d: gpu_cmd_2d(gpu); break;
824+
case 0x2e: gpu_cmd_2d(gpu); break;
825+
case 0x2f: gpu_cmd_2d(gpu); break;
748826
case 0x30: gpu_cmd_30(gpu); break;
827+
case 0x32: gpu_cmd_30(gpu); break;
749828
case 0x38: gpu_cmd_38(gpu); break;
750829
case 0x40: gpu_cmd_40(gpu); break;
751830
case 0x64: gpu_cmd_64(gpu); break;

psx/dev/gpu.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ struct psx_gpu_t {
7070
uint32_t xcnt, ycnt;
7171
vertex_t v0, v1, v2, v3;
7272
uint32_t pal, texp;
73-
uint32_t c0_xpos, c0_ypos;
73+
uint32_t c0_xcnt, c0_ycnt;
74+
uint32_t c0_addr;
7475
int c0_xsiz, c0_ysiz;
76+
int c0_tsiz;
7577

7678
// GPU state
7779
uint32_t state;

psx/dev/pad.c

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,11 @@ void psx_pad_init(psx_pad_t* pad, psx_ic_t* ic) {
6969

7070
uint32_t psx_pad_read32(psx_pad_t* pad, uint32_t offset) {
7171
switch (offset) {
72-
case 0: log_fatal("RX read 32"); return pad_read_rx(pad);
73-
case 4: log_fatal("ST read 32"); return pad_handle_stat_read(pad);
74-
case 8: log_fatal("MD read 32"); return pad->mode;
75-
case 10: log_fatal("CT read 32"); return pad->ctrl;
76-
case 14: log_fatal("BD read 32"); return pad->baud;
72+
case 0: return pad_read_rx(pad);
73+
case 4: return pad_handle_stat_read(pad);
74+
case 8: return pad->mode;
75+
case 10: return pad->ctrl;
76+
case 14: return pad->baud;
7777
}
7878

7979
log_fatal("Unhandled 32-bit PAD read at offset %08x", offset);
@@ -83,11 +83,11 @@ uint32_t psx_pad_read32(psx_pad_t* pad, uint32_t offset) {
8383

8484
uint16_t psx_pad_read16(psx_pad_t* pad, uint32_t offset) {
8585
switch (offset) {
86-
case 0: log_fatal("RX read 16"); return pad_read_rx(pad) & 0xffff;
87-
case 4: log_fatal("ST read 16 %04x", pad_handle_stat_read(pad) & 0xffff); return pad_handle_stat_read(pad) & 0xffff;
88-
case 8: log_fatal("MD read 16"); return pad->mode;
89-
case 10: log_fatal("CT read 16 %04x", pad->ctrl & 0xffff); return pad->ctrl & 0xffff;
90-
case 14: log_fatal("BD read 16"); return pad->baud;
86+
case 0: return pad_read_rx(pad) & 0xffff;
87+
case 4: return pad_handle_stat_read(pad) & 0xffff;
88+
case 8: return pad->mode;
89+
case 10: return pad->ctrl & 0xffff;
90+
case 14: return pad->baud;
9191
}
9292

9393
log_fatal("Unhandled 16-bit PAD read at offset %08x", offset);
@@ -97,11 +97,11 @@ uint16_t psx_pad_read16(psx_pad_t* pad, uint32_t offset) {
9797

9898
uint8_t psx_pad_read8(psx_pad_t* pad, uint32_t offset) {
9999
switch (offset) {
100-
case 0: log_fatal("RX read 8 %02x", pad_read_rx(pad) & 0xff); return pad_read_rx(pad) & 0xff;
101-
case 4: log_fatal("ST read 8"); return pad_handle_stat_read(pad) & 0xff;
102-
case 8: log_fatal("MD read 8"); return pad->mode & 0xff;
103-
case 10: log_fatal("CT read 8"); return pad->ctrl & 0xff;
104-
case 14: log_fatal("BD read 8"); return pad->baud & 0xff;
100+
case 0: return pad_read_rx(pad) & 0xff;
101+
case 4: return pad_handle_stat_read(pad) & 0xff;
102+
case 8: return pad->mode & 0xff;
103+
case 10: return pad->ctrl & 0xff;
104+
case 14: return pad->baud & 0xff;
105105
}
106106

107107
log_fatal("Unhandled 8-bit PAD read at offset %08x", offset);
@@ -111,32 +111,32 @@ uint8_t psx_pad_read8(psx_pad_t* pad, uint32_t offset) {
111111

112112
void psx_pad_write32(psx_pad_t* pad, uint32_t offset, uint32_t value) {
113113
switch (offset) {
114-
case 0: log_fatal("TX write 32 %08x", value); pad_write_tx(pad, value); return;
115-
case 8: log_fatal("MD write 32 %08x", value); pad->mode = value & 0xffff; return;
116-
case 10: log_fatal("CT write 32 %08x", value); pad_handle_ctrl_write(pad, value); return;
117-
case 14: log_fatal("BD write 32 %08x", value); pad->baud = value & 0xffff; return;
114+
case 0: pad_write_tx(pad, value); return;
115+
case 8: pad->mode = value & 0xffff; return;
116+
case 10: pad_handle_ctrl_write(pad, value); return;
117+
case 14: pad->baud = value & 0xffff; return;
118118
}
119119

120120
log_fatal("Unhandled 32-bit PAD write at offset %08x (%08x)", offset, value);
121121
}
122122

123123
void psx_pad_write16(psx_pad_t* pad, uint32_t offset, uint16_t value) {
124124
switch (offset) {
125-
case 0: log_fatal("TX write 16 %04x", value); pad_write_tx(pad, value); return;
126-
case 8: log_fatal("MD write 16 %04x", value); pad->mode = value; return;
127-
case 10: log_fatal("CT write 16 %04x", value); pad_handle_ctrl_write(pad, value); return;
128-
case 14: log_fatal("BD write 16 %04x", value); pad->baud = value; return;
125+
case 0: pad_write_tx(pad, value); return;
126+
case 8: pad->mode = value; return;
127+
case 10: pad_handle_ctrl_write(pad, value); return;
128+
case 14: pad->baud = value; return;
129129
}
130130

131131
log_fatal("Unhandled 16-bit PAD write at offset %08x (%04x)", offset, value);
132132
}
133133

134134
void psx_pad_write8(psx_pad_t* pad, uint32_t offset, uint8_t value) {
135135
switch (offset) {
136-
case 0: log_fatal("TX write 8 %02x", value); pad_write_tx(pad, value); return;
137-
case 8: log_fatal("MD write 8 %02x", value); pad->mode = value; return;
138-
case 10: log_fatal("CT write 8 %02x", value); pad_handle_ctrl_write(pad, value); return;
139-
case 14: log_fatal("BD write 8 %02x", value); pad->baud = value; return;
136+
case 0: pad_write_tx(pad, value); return;
137+
case 8: pad->mode = value; return;
138+
case 10: pad_handle_ctrl_write(pad, value); return;
139+
case 14: pad->baud = value; return;
140140
}
141141

142142
log_fatal("Unhandled 8-bit PAD write at offset %08x (%02x)", offset, value);
@@ -167,8 +167,6 @@ void psx_pad_update(psx_pad_t* pad, int cyc) {
167167
if (pad->cycles_until_irq <= 0) {
168168
psx_ic_irq(pad->ic, IC_JOY);
169169

170-
log_fatal("PAD IRQ");
171-
172170
pad->cycles_until_irq = 0;
173171
}
174172
}

0 commit comments

Comments
 (0)