Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
cull-thresholds.c
Go to the documentation of this file.
1/*
2
3MIT License
4
5Copyright (c) 2026 PCSX-Redux authors
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26
27// Cull-threshold probes. Naming:
28// CT_<prim>_OK_<dim> -- primitive rendered as expected
29// CT_<prim>_DROP_<dim> -- primitive culled, anchor reads sentinel
30// CT_<prim>_DROPMECH_* -- silent-drop verification
31
32// clang-format off
33
35
36// Probe-anchor pixel for all tests: (5, 3). The 32x32 sentinel-fill
37// region is plenty large for this anchor.
38#define ANCHOR_X 5
39#define ANCHOR_Y 3
40
41// ---- Flat untextured triangle (GP0 0x20) ---------------------------------
42
43static void drawTriOk(void) {
44 rasterReset();
45 rasterClearTestRegion(0, 0, 32, 32);
46 /* In-limit: dx max = 100, dy max = 20. Anchor (5, 3) covered. */
47 rasterFlatTri(RASTER_CMD_RED, 0, 0, 100, 0, 0, 20);
48 rasterFlushPrimitive();
49}
50
51static void drawTriEdgeDx(int16_t dx) {
52 rasterReset();
53 rasterClearTestRegion(0, 0, 32, 32);
54 /* dx = v2.x - v1.x = dx. v1-v3 dx = 0. Worst-edge dx = `dx`. */
55 rasterFlatTri(RASTER_CMD_RED, 0, 0, (int16_t)dx, 0, 0, 20);
56 rasterFlushPrimitive();
57}
58
59static void drawTriEdgeDy(int16_t dy) {
60 rasterReset();
61 rasterClearTestRegion(0, 0, 32, 32);
62 /* dy = v3.y - v1.y = dy. Worst-edge dy = `dy`. */
63 rasterFlatTri(RASTER_CMD_RED, 0, 0, 20, 0, 0, (int16_t)dy);
64 rasterFlushPrimitive();
65}
66
67// ---- Gouraud triangle (GP0 0x30) -----------------------------------------
68
69static void drawGTriOk(void) {
70 rasterReset();
71 rasterClearTestRegion(0, 0, 32, 32);
72 rasterGouraudTri(RASTER_CMD_RED, 0, 0,
73 RASTER_CMD_RED, 100, 0,
74 RASTER_CMD_RED, 0, 20);
75 rasterFlushPrimitive();
76}
77
78static void drawGTriEdgeDx(int16_t dx) {
79 rasterReset();
80 rasterClearTestRegion(0, 0, 32, 32);
81 rasterGouraudTri(RASTER_CMD_RED, 0, 0,
82 RASTER_CMD_RED, dx, 0,
83 RASTER_CMD_RED, 0, 20);
84 rasterFlushPrimitive();
85}
86
87// ---- Flat textured triangle (GP0 0x24) -----------------------------------
88
89static void drawTexTriOk(void) {
90 rasterReset();
91 rasterClearTestRegion(0, 0, 32, 32);
92 setTexpage(TEX15_TX, TEX15_TY, 2);
93 setTextureWindow(0, 0, 0, 0);
94 rasterTexTri(TEX_MOD_NEUTRAL,
95 0, 0, 0, 0,
96 100, 0, 15, 0,
97 0, 20, 0, 15,
99 rasterFlushPrimitive();
100}
101
102static void drawTexTriEdgeDx(int16_t dx) {
103 rasterReset();
104 rasterClearTestRegion(0, 0, 32, 32);
105 setTexpage(TEX15_TX, TEX15_TY, 2);
106 setTextureWindow(0, 0, 0, 0);
107 rasterTexTri(TEX_MOD_NEUTRAL,
108 0, 0, 0, 0,
109 dx, 0, 15, 0,
110 0, 20, 0, 15,
112 rasterFlushPrimitive();
113}
114
115// ---- Flat untextured quad (GP0 0x28) -------------------------------------
116
117static void drawQuadOk(void) {
118 rasterReset();
119 rasterClearTestRegion(0, 0, 32, 32);
120 rasterFlatQuad(RASTER_CMD_GREEN, 0, 0, 100, 0, 0, 20, 100, 20);
121 rasterFlushPrimitive();
122}
123
124static void drawQuadEdgeDx(int16_t dx) {
125 rasterReset();
126 rasterClearTestRegion(0, 0, 32, 32);
127 /* Largest edge dx = `dx`. */
128 rasterFlatQuad(RASTER_CMD_GREEN, 0, 0, dx, 0, 0, 20, dx, 20);
129 rasterFlushPrimitive();
130}
131
132static void drawQuadEdgeDy(int16_t dy) {
133 rasterReset();
134 rasterClearTestRegion(0, 0, 32, 32);
135 rasterFlatQuad(RASTER_CMD_GREEN, 0, 0, 20, 0, 0, dy, 20, dy);
136 rasterFlushPrimitive();
137}
138
139// ---- Flat textured quad (GP0 0x2C) ---------------------------------------
140
141static void drawTexQuadOk(void) {
142 rasterReset();
143 rasterClearTestRegion(0, 0, 32, 32);
144 setTexpage(TEX15_TX, TEX15_TY, 2);
145 setTextureWindow(0, 0, 0, 0);
146 rasterFlatTexQuad(TEX_MOD_NEUTRAL,
147 0, 0, 0, 0,
148 100, 0, 15, 0,
149 0, 20, 0, 15,
150 100, 20, 15, 15,
152 rasterFlushPrimitive();
153}
154
155static void drawTexQuadEdgeDx(int16_t dx) {
156 rasterReset();
157 rasterClearTestRegion(0, 0, 32, 32);
158 setTexpage(TEX15_TX, TEX15_TY, 2);
159 setTextureWindow(0, 0, 0, 0);
160 rasterFlatTexQuad(TEX_MOD_NEUTRAL,
161 0, 0, 0, 0,
162 dx, 0, 15, 0,
163 0, 20, 0, 15,
164 dx, 20, 15, 15,
166 rasterFlushPrimitive();
167}
168
169// ---- Line (GP0 0x40) -----------------------------------------------------
170
171static void drawLineEdgeDx(int16_t dx) {
172 rasterReset();
173 rasterClearTestRegion(0, 0, 32, 32);
174 /* Line at y=ANCHOR_Y crossing x=ANCHOR_X if dx is large enough.
175 Line endpoint at (dx, 3) - if line drops, anchor is sentinel. */
176 rasterFlatLine(RASTER_CMD_BLUE, 0, 3, dx, 3);
177 rasterFlushPrimitive();
178}
179
180// ---- Variable-size rect (GP0 0x60) ---------------------------------------
181
182static void drawRectSize(int16_t w, int16_t h) {
183 rasterReset();
184 rasterClearTestRegion(0, 0, 32, 32);
185 rasterFlatRect(RASTER_CMD_WHITE, 0, 0, w, h);
186 rasterFlushPrimitive();
187}
188
189// ---- Drop-mechanism probe ------------------------------------------------
190//
191// Submit an oversized triangle (suspected to drop) followed by a
192// known-good small triangle at a clearly different anchor (10, 10).
193// If hardware silently drops the first and proceeds with the second,
194// pixel (10, 10) reads RASTER_VRAM_GREEN. If the drop corrupts the
195// command stream, pixel (10, 10) reads sentinel.
196
197static void drawDropMechProbe(void) {
198 rasterReset();
199 rasterClearTestRegion(0, 0, 32, 32);
200 /* Oversized tri (dx=2047 - way over limit). */
201 rasterFlatTri(RASTER_CMD_RED, 0, 0, 2047, 0, 0, 20);
202 /* Small good tri whose interior includes (10, 10). */
203 rasterFlatTri(RASTER_CMD_GREEN, 8, 8, 14, 8, 8, 14);
204 rasterFlushPrimitive();
205}
206
207) // CESTER_BODY
208
209// ============================================================================
210// Baseline + threshold tests per primitive type
211// ============================================================================
212
213// ---- Triangle (GP0 0x20) ----
214
215CESTER_TEST(ct_tri_baseline, gpu_raster_phase14,
216 drawTriOk();
218)
219
220CESTER_TEST(ct_tri_dx_1023_ok, gpu_raster_phase14,
221 drawTriEdgeDx(1023);
222 /* In-limit per psx-spx. Should render. */
224)
225
226CESTER_TEST(ct_tri_dx_1024_drop, gpu_raster_phase14,
227 drawTriEdgeDx(1024);
228 /* Suspected drop boundary. */
230)
231
232CESTER_TEST(ct_tri_dx_1025_drop, gpu_raster_phase14,
233 drawTriEdgeDx(1025);
235)
236
237CESTER_TEST(ct_tri_dx_2047_drop, gpu_raster_phase14,
238 drawTriEdgeDx(2047);
239 /* Way over limit. */
241)
242
243CESTER_TEST(ct_tri_dy_511_ok, gpu_raster_phase14,
244 drawTriEdgeDy(511);
246)
247
248CESTER_TEST(ct_tri_dy_512_drop, gpu_raster_phase14,
249 drawTriEdgeDy(512);
251)
252
253CESTER_TEST(ct_tri_dy_513_drop, gpu_raster_phase14,
254 drawTriEdgeDy(513);
256)
257
258CESTER_TEST(ct_tri_dy_1023_drop, gpu_raster_phase14,
259 drawTriEdgeDy(1023);
261)
262
263// ---- Gouraud triangle (GP0 0x30) ----
264
265CESTER_TEST(ct_gtri_baseline, gpu_raster_phase14,
266 drawGTriOk();
268)
269
270CESTER_TEST(ct_gtri_dx_1023_ok, gpu_raster_phase14,
271 drawGTriEdgeDx(1023);
273)
274
275CESTER_TEST(ct_gtri_dx_1024_drop, gpu_raster_phase14,
276 drawGTriEdgeDx(1024);
278)
279
280CESTER_TEST(ct_gtri_dx_2047_drop, gpu_raster_phase14,
281 drawGTriEdgeDx(2047);
283)
284
285// ---- Textured triangle (GP0 0x24) ----
286
287CESTER_TEST(ct_textri_baseline, gpu_raster_phase14,
288 drawTexTriOk();
289 /* Anchor (5, 3) samples texel u=15*5/100=0 (UV interpolation,
290 roughly). Just verify it's NOT sentinel. */
291 int16_t v = (int16_t)rasterReadPixel(ANCHOR_X, ANCHOR_Y);
292 ramsyscall_printf("OBS x=%d y=%d val=0x%04x expect=NOT-SENTINEL\n",
293 ANCHOR_X, ANCHOR_Y, (unsigned)v);
294 cester_assert_uint_ne((unsigned)RASTER_SENTINEL, (unsigned)v);
295)
296
297CESTER_TEST(ct_textri_dx_1023_ok, gpu_raster_phase14,
298 drawTexTriEdgeDx(1023);
299 int16_t v = (int16_t)rasterReadPixel(ANCHOR_X, ANCHOR_Y);
300 ramsyscall_printf("OBS x=%d y=%d val=0x%04x expect=CT_TEXTRI_DX_1023\n",
301 ANCHOR_X, ANCHOR_Y, (unsigned)v);
302 cester_assert_uint_eq((unsigned)CT_TEXTRI_DX_1023, (unsigned)v);
303)
304
305CESTER_TEST(ct_textri_dx_1024_drop, gpu_raster_phase14,
306 drawTexTriEdgeDx(1024);
308)
309
310CESTER_TEST(ct_textri_dx_2047_drop, gpu_raster_phase14,
311 drawTexTriEdgeDx(2047);
313)
314
315// ---- Quad (GP0 0x28) ----
316
317CESTER_TEST(ct_quad_baseline, gpu_raster_phase14,
318 drawQuadOk();
320)
321
322CESTER_TEST(ct_quad_dx_1023_ok, gpu_raster_phase14,
323 drawQuadEdgeDx(1023);
325)
326
327CESTER_TEST(ct_quad_dx_1024_drop, gpu_raster_phase14,
328 drawQuadEdgeDx(1024);
330)
331
332CESTER_TEST(ct_quad_dx_2047_drop, gpu_raster_phase14,
333 drawQuadEdgeDx(2047);
335)
336
337CESTER_TEST(ct_quad_dy_511_ok, gpu_raster_phase14,
338 drawQuadEdgeDy(511);
340)
341
342CESTER_TEST(ct_quad_dy_512_drop, gpu_raster_phase14,
343 drawQuadEdgeDy(512);
345)
346
347// ---- Textured quad (GP0 0x2C) ----
348
349CESTER_TEST(ct_texquad_baseline, gpu_raster_phase14,
350 drawTexQuadOk();
351 int16_t v = (int16_t)rasterReadPixel(ANCHOR_X, ANCHOR_Y);
352 ramsyscall_printf("OBS x=%d y=%d val=0x%04x expect=NOT-SENTINEL\n",
353 ANCHOR_X, ANCHOR_Y, (unsigned)v);
354 cester_assert_uint_ne((unsigned)RASTER_SENTINEL, (unsigned)v);
355)
356
357CESTER_TEST(ct_texquad_dx_1023_ok, gpu_raster_phase14,
358 drawTexQuadEdgeDx(1023);
359 int16_t v = (int16_t)rasterReadPixel(ANCHOR_X, ANCHOR_Y);
360 ramsyscall_printf("OBS x=%d y=%d val=0x%04x expect=CT_TEXQUAD_DX_1023\n",
361 ANCHOR_X, ANCHOR_Y, (unsigned)v);
362 cester_assert_uint_eq((unsigned)CT_TEXQUAD_DX_1023, (unsigned)v);
363)
364
365CESTER_TEST(ct_texquad_dx_1024_drop, gpu_raster_phase14,
366 drawTexQuadEdgeDx(1024);
368)
369
370CESTER_TEST(ct_texquad_dx_2047_drop, gpu_raster_phase14,
371 drawTexQuadEdgeDx(2047);
373)
374
375// ---- Line (GP0 0x40) ----
376//
377// Lines don't really have "edges" in the polygon sense; the cull
378// concept is about the endpoint delta. Per psx-spx GPU registers the
379// line endpoint delta is limited to ±1023 horizontally / ±511
380// vertically; oversized lines are dropped.
381
382CESTER_TEST(ct_line_dx_100_baseline, gpu_raster_phase14,
383 drawLineEdgeDx(100);
384 /* Line should render through (5, 3). */
386)
387
388CESTER_TEST(ct_line_dx_1023_ok, gpu_raster_phase14,
389 drawLineEdgeDx(1023);
391)
392
393CESTER_TEST(ct_line_dx_1024_drop, gpu_raster_phase14,
394 drawLineEdgeDx(1024);
396)
397
398CESTER_TEST(ct_line_dx_2047_drop, gpu_raster_phase14,
399 drawLineEdgeDx(2047);
401)
402
403// ---- Variable-size rect (GP0 0x60) ----
404//
405// Rectangles have their own "size" command word. psx-spx documents
406// the rectangle width as masked to ((W-1) & 0x3FF) + 1 = max 1024.
407// So w=1024 wraps to 0 (no draw); w=1025 wraps to 1; etc. Verify.
408
409CESTER_TEST(ct_rect_w16_baseline, gpu_raster_phase14,
410 drawRectSize(16, 16);
412)
413
414CESTER_TEST(ct_rect_w1023, gpu_raster_phase14,
415 drawRectSize(1023, 16);
416 /* Hardware should fill - 1023 within mask range. */
418)
419
420CESTER_TEST(ct_rect_w1024, gpu_raster_phase14,
421 drawRectSize(1024, 16);
422 /* psx-spx: ((1024-1)&0x3FF)+1 = 1024. Renders. */
424)
425
426CESTER_TEST(ct_rect_w1025, gpu_raster_phase14,
427 drawRectSize(1025, 16);
428 /* ((1025-1)&0x3FF)+1 = 1. Renders only 1 pixel wide; anchor
429 (5, 3) is outside that single-column rect -> sentinel. */
431)
432
433CESTER_TEST(ct_rect_h511, gpu_raster_phase14,
434 drawRectSize(16, 511);
436)
437
438CESTER_TEST(ct_rect_h512, gpu_raster_phase14,
439 drawRectSize(16, 512);
440 /* ((512-1)&0x1FF)+1 = 512. Renders. */
442)
443
444CESTER_TEST(ct_rect_h513, gpu_raster_phase14,
445 drawRectSize(16, 513);
446 /* ((513-1)&0x1FF)+1 = 1. Wraps to height 1; anchor (5, 3) is
447 outside the single-row rect -> sentinel. */
449)
450
451// ---- Drop-mechanism probe ----
452
453CESTER_TEST(ct_drop_mech_second_renders, gpu_raster_phase14,
454 drawDropMechProbe();
455 /* If the oversized first tri was silently dropped, the second
456 tri rendered and pixel (10, 10) is green. If the drop
457 corrupted the command stream, (10, 10) reads sentinel. */
459)
460
461CESTER_TEST(ct_drop_mech_oversized_not_rendered, gpu_raster_phase14,
462 drawDropMechProbe();
463 /* The first oversized tri at (0, 0)-(2047, 0)-(0, 20) was
464 dropped. Anchor (5, 3) - inside that tri's intended bounds
465 but outside the second tri's bounds - should be sentinel. */
467)
468
469// ---- Per-vertex absolute coordinate test ----
470//
471// Triangle with one vertex at a high absolute X but small edge dx
472// between the other two vertices. Per-edge rule predicts render;
473// per-vertex-abs rule predicts drop.
474
475CESTER_TEST(ct_tri_vertex_abs_just_low_edges, gpu_raster_phase14,
476 rasterReset();
477 rasterClearTestRegion(0, 0, 32, 32);
478 /* v1 = (0, 0), v2 = (1024, 0), v3 = (1024, 20). Edges:
479 v1-v2 dx=1024 (over limit if dx>1023).
480 v2-v3 dx=0.
481 v1-v3 dx=1024 (over limit).
482 So this test triangle has TWO edges over - it's a control
483 confirming over-limit cull, not strictly a per-vertex-abs
484 isolation. */
485 rasterFlatTri(RASTER_CMD_RED, 0, 0, 1024, 0, 1024, 20);
486 rasterFlushPrimitive();
488)
489
490/* Pre-truncation per-vertex absolute coord probes. The GP0 vertex
491 format stores x/y as int16 but the rasterizer interprets only the
492 low 11 bits as signed. We can test whether hardware enforces an
493 independent per-vertex absolute-coord rule BEFORE the 11-bit
494 truncation by sending the same effective post-truncation triangle
495 in two ways: one with all coords in the 11-bit range, one with a
496 vertex coord that has bits set above bit 10 but produces the same
497 low-11-bit result. If both render identically, no pre-truncation
498 rule. If the probe drops (sentinel at anchor), there IS one.
499 Baseline geometry: (0,0)-(20,0)-(0,20). Anchor (5,3) is inside
500 the post-truncation triangle in both cases. */
501CESTER_TEST(ct_tri_pretrunc_baseline, gpu_raster_phase14,
502 rasterReset();
503 rasterClearTestRegion(0, 0, 32, 32);
504 /* All low-11-bit vertices; should render at anchor. */
505 rasterFlatTri(RASTER_CMD_RED, 0, 0, 20, 0, 0, 20);
506 rasterFlushPrimitive();
508)
509CESTER_TEST(ct_tri_pretrunc_bit11, gpu_raster_phase14,
510 rasterReset();
511 rasterClearTestRegion(0, 0, 32, 32);
512 /* Same effective triangle - v2.x = 2068 = 0x814 truncates to
513 low 11 bits = 0x14 = 20. If hardware truncates first then
514 checks per-edge, this renders identically to the baseline.
515 If a pre-truncation per-vertex absolute rule fires on |x| >
516 1023, the polygon drops and anchor is sentinel. */
517 rasterFlatTri(RASTER_CMD_RED, 0, 0, 2068, 0, 0, 20);
518 rasterFlushPrimitive();
520)
521CESTER_TEST(ct_tri_pretrunc_bit15, gpu_raster_phase14,
522 rasterReset();
523 rasterClearTestRegion(0, 0, 32, 32);
524 /* v2.x = -32748 = 0x8014 in 16-bit two's complement. Low 11
525 bits = 0x014 = 20. Maximum bit-pattern divergence from the
526 11-bit truncated value: every high bit set. If any per-vertex
527 rule fires above 11-bit range, this drops. */
528 rasterFlatTri(RASTER_CMD_RED, 0, 0, (int16_t)0x8014, 0, 0, 20);
529 rasterFlushPrimitive();
531)
CESTER_TEST(cddaLevelHalf, test_instances, static const uint8_t atv[4]={0x40, 0x00, 0x40, 0x00};unsigned changes=0;int peak=cddaPeak(atv, 1, &changes);ramsyscall_printf("CD-DA level at half ATV: peak %i, %u sign changes\n", peak, changes);cester_assert_int_ge(peak, 11300);cester_assert_int_le(peak, 11800);cester_assert_uint_ge(changes, 4);) CESTER_TEST(cddaLevelClipped
CESTER_BODY(static uint16_t s_cddaCapture;static int cddaSpuDma(uint32_t spuAddr, void *buf, uint32_t bytes, int isRead) { const uint16_t tsa=spuAddr > > 3;const uint16_t mode=isRead ? 0x30 :0x20;SPU_RAM_DTA=tsa;for(int i=0;i< 0xf01 &&SPU_RAM_DTA !=tsa;i++);SPU_CTRL=(SPU_CTRL &~0x30)|mode;for(volatile int i=0;i< 60;i++);for(int i=0;i< 0xf01 &&(SPU_STATUS &0x30) !=mode;i++);CDDA_SPU_DELAY=(CDDA_SPU_DELAY &0xf0ffffff)|(isRead ? 0x22000000 :0x20000000);DMA_CTRL[DMA_SPU].MADR=(uint32_t) buf &0x1fffffff;DMA_CTRL[DMA_SPU].BCR=((bytes > > 6)<< 16)|0x10;DMA_CTRL[DMA_SPU].CHCR=isRead ? 0x01000200 :0x01000201;int ok=0;for(unsigned t=0;t< 4000000u;t++) { if((DMA_CTRL[DMA_SPU].CHCR &0x01000000)==0) { ok=1;break;} } SPU_CTRL=SPU_CTRL &~0x30;for(volatile int i=0;i< 60;i++);return ok;} static int cddaSimpleCmd(uint8_t cmd) { uint8_t response[16];CDROM_REG0=0;CDROM_REG1=cmd;uint32_t timeout=2000000;int ok=waitCDRomIRQWithTimeout(&timeout);ackCDRomCause();readResponse(response);return ok;} static void cddaWaitPauseComplete() { initializeTime();uint32_t elapsed=0;while(elapsed< 5000000u) { uint32_t budget=200000u;int ok=waitCDRomIRQWithTimeout(&budget);elapsed=budget;if(!ok) continue;uint8_t cause=ackCDRomCause();uint8_t response[16];readResponse(response);if(cause==2) return;} } static int cddaAudioSetup(const uint8_t atv[4], int demute) { if(!resetCDRom()) return 0;DPCR|=0x000b0000;SPU_CTRL=0;for(volatile int i=0;i< 20000;i++);SPU_VOL_MAIN_LEFT=0;SPU_VOL_MAIN_RIGHT=0;SPU_KEY_OFF_LOW=0xffff;SPU_KEY_OFF_HIGH=0xffff;SPU_RAM_DTC=4;SPU_CTRL=0x8001;for(volatile int i=0;i< 20000;i++);for(int i=0;i< 0x400;i++) s_cddaCapture[i]=CDDA_MARKER;if(!cddaSpuDma(0x000, s_cddaCapture, 0x800, 0)) return 0;if(!cddaSimpleCmd(demute ? CDL_DEMUTE :CDL_MUTE)) return 0;CDROM_REG0=2;CDROM_REG2=atv[0];CDROM_REG3=atv[1];CDROM_REG0=3;CDROM_REG1=atv[2];CDROM_REG2=atv[3];CDROM_REG0=3;CDROM_REG3=0x20;CDROM_REG0=0;SPU_VOL_CD_LEFT=0x7fff;SPU_VOL_CD_RIGHT=0x7fff;SPU_CTRL=SPU_CTRL|0x8001;return 1;} static int cddaBufferPeak(unsigned *signChanges) { int peak=0;unsigned changes=0;int prev=0;for(int i=0;i< 0x200;i++) { int v=(int16_t) s_cddaCapture[i];int a=v< 0 ? -v :v;if(a > peak) peak=a;int sign=v >=0 ? 1 :-1;if(i &&sign !=prev) changes++;prev=sign;} *signChanges=changes;return peak;} static int cddaCapturePeak(unsigned *signChanges) { int peak=0;for(unsigned attempt=0;attempt< 8;attempt++) { if(attempt) { initializeTime();while(updateTime()< 250000u);} if(!cddaSpuDma(0x000, s_cddaCapture, 0x800, 1)) return -1;peak=cddaBufferPeak(signChanges);if(peak) { if(attempt) ramsyscall_printf("capture was empty %u time(s) before audio\n", attempt);break;} } return peak;} static int cddaPeak(const uint8_t atv[4], int demute, unsigned *signChanges) { if(!cddaAudioSetup(atv, demute)) return -1;if(!setMode(0)) return -1;CDROM_REG0=0;CDROM_REG2=0x02;if(!cddaSimpleCmd(CDL_PLAY)) return -1;initializeTime();while(updateTime()< 1500000u);int peak=cddaCapturePeak(signChanges);CDROM_REG0=0;CDROM_REG1=CDL_PAUSE;cddaWaitPauseComplete();CDROM_REG0=0;CDROM_REG2=0x00;CDROM_REG2=0x02;CDROM_REG2=0x16;if(cddaSimpleCmd(CDL_SETLOC) &&cddaSimpleCmd(CDL_SEEKL)) cddaWaitPauseComplete();return peak;}[0x400])
Definition cdda.c:37
cester_assert_uint_eq(5, cause1)
ramsyscall_printf("T21 phase=%s t=%u v=%02x cause=%u size=%u stat=%02x\n", phase, t/1000, response[0], cause, size,(nopCause==3 &&nopSize >=1) ? stat[0] :0xff)
#define ANCHOR_Y
#define ANCHOR_X
#define CT_TEXTRI_DX_1023
Definition raster-expected-phase14.h:55
#define CT_RECT_H_512
Definition raster-expected-phase14.h:94
#define CT_TRI_VERTEX_ABS_OVER
Definition raster-expected-phase14.h:98
#define CT_TEXTRI_DX_1024
Definition raster-expected-phase14.h:56
#define CT_TEXTRI_DX_2047
Definition raster-expected-phase14.h:57
#define CT_QUAD_DY_512
Definition raster-expected-phase14.h:64
#define CT_TRI_DX_2047
Definition raster-expected-phase14.h:41
#define CT_TRI_DX_1025
Definition raster-expected-phase14.h:40
#define CT_TRI_DY_513
Definition raster-expected-phase14.h:44
#define CT_RECT_W_1025
Definition raster-expected-phase14.h:92
#define CT_TRI_DX_1023
Definition raster-expected-phase14.h:38
#define CT_RECT_W_1024
Definition raster-expected-phase14.h:91
#define CT_LINE_DX_2047
Definition raster-expected-phase14.h:75
#define CT_TEXQUAD_DX_1023
Definition raster-expected-phase14.h:68
#define CT_TRI_DX_1024
Definition raster-expected-phase14.h:39
#define CT_GTRI_DX_2047
Definition raster-expected-phase14.h:50
#define CT_TRI_PRETRUNC_BIT15
Definition raster-expected-phase14.h:107
#define CT_TRI_PRETRUNC_BIT11
Definition raster-expected-phase14.h:106
#define CT_RECT_H_511
Definition raster-expected-phase14.h:93
#define CT_LINE_DX_1023
Definition raster-expected-phase14.h:73
#define CT_RECT_W_1023
Definition raster-expected-phase14.h:90
#define CT_GTRI_DX_1023
Definition raster-expected-phase14.h:48
#define CT_TRI_DY_512
Definition raster-expected-phase14.h:43
#define CT_TRI_DY_1023
Definition raster-expected-phase14.h:45
#define CT_RECT_H_513
Definition raster-expected-phase14.h:95
#define CT_GTRI_DX_1024
Definition raster-expected-phase14.h:49
#define CT_TEXQUAD_DX_2047
Definition raster-expected-phase14.h:70
#define CT_TEXQUAD_DX_1024
Definition raster-expected-phase14.h:69
#define CT_QUAD_DY_511
Definition raster-expected-phase14.h:63
#define CT_QUAD_DX_2047
Definition raster-expected-phase14.h:62
#define CT_QUAD_DX_1023
Definition raster-expected-phase14.h:60
#define CT_LINE_DX_1024
Definition raster-expected-phase14.h:74
#define CT_TRI_DY_511
Definition raster-expected-phase14.h:42
#define CT_QUAD_DX_1024
Definition raster-expected-phase14.h:61
#define RASTER_VRAM_GREEN
Definition raster-helpers.h:127
#define RASTER_VRAM_BLUE
Definition raster-helpers.h:129
#define RASTER_VRAM_WHITE
Definition raster-helpers.h:131
#define ASSERT_PIXEL_UNTOUCHED(x_, y_)
Definition raster-helpers.h:486
#define RASTER_VRAM_RED
Definition raster-helpers.h:125
#define RASTER_CMD_BLUE
Definition raster-helpers.h:128
#define RASTER_CMD_RED
Definition raster-helpers.h:124
#define RASTER_CMD_WHITE
Definition raster-helpers.h:130
#define RASTER_CMD_GREEN
Definition raster-helpers.h:126
#define ASSERT_PIXEL_EQ(expected, x_, y_)
Definition raster-helpers.h:473
#define RASTER_SENTINEL
Definition raster-helpers.h:95
cester_assert_uint_ne(0, before)
#define TEX15_TY
Definition texture-fixtures.h:66
#define TEX15_TPAGE
Definition texture-fixtures.h:102
#define CLUT15_FIELD
Definition texture-fixtures.h:85
#define TEX15_TX
Definition texture-fixtures.h:65
#define TEX_MOD_NEUTRAL
Definition texture-fixtures.h:308