Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
row-walk-drift.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// Phase-20 row-walk-drift suite. Five triangles (K in {1, 3, 5, 8, 16})
28// with identical 10x20 screen footprint. Six probes per K at x=7 and
29// y in {5, 8, 11, 14, 17, 20}.
30
31// clang-format off
32
34
35// Triangle T_LONG_K_N: A=(5,5)/(0,0) B=(15,5)/(N,0) C=(5,25)/(0,2N)
36// dU/dx = N/10, dV/dy = N/10. Triangle is 10 wide, 20 tall. Right
37// edge BC has slope -0.5; probes at x=7 are well to the left of BC
38// at every probed y so row-start X stays at 5.
39
40static void drawT_LONG_K01(void) {
41 rasterReset();
42 rasterClearTestRegion(0, 0, 24, 28);
43 setTexpage(TEX17_TX, TEX17_TY, 2);
44 setTextureWindow(0, 0, 0, 0);
45 rasterTexTri(TEX_MOD_NEUTRAL,
46 5, 5, 0, 0,
47 15, 5, 1, 0,
48 5, 25, 0, 2,
50 rasterFlushPrimitive();
51}
52
53static void drawT_LONG_K03(void) {
54 rasterReset();
55 rasterClearTestRegion(0, 0, 24, 28);
56 setTexpage(TEX17_TX, TEX17_TY, 2);
57 setTextureWindow(0, 0, 0, 0);
58 rasterTexTri(TEX_MOD_NEUTRAL,
59 5, 5, 0, 0,
60 15, 5, 3, 0,
61 5, 25, 0, 6,
63 rasterFlushPrimitive();
64}
65
66static void drawT_LONG_K05(void) {
67 rasterReset();
68 rasterClearTestRegion(0, 0, 24, 28);
69 setTexpage(TEX17_TX, TEX17_TY, 2);
70 setTextureWindow(0, 0, 0, 0);
71 rasterTexTri(TEX_MOD_NEUTRAL,
72 5, 5, 0, 0,
73 15, 5, 5, 0,
74 5, 25, 0, 10,
76 rasterFlushPrimitive();
77}
78
79static void drawT_LONG_K08(void) {
80 rasterReset();
81 rasterClearTestRegion(0, 0, 24, 28);
82 setTexpage(TEX17_TX, TEX17_TY, 2);
83 setTextureWindow(0, 0, 0, 0);
84 rasterTexTri(TEX_MOD_NEUTRAL,
85 5, 5, 0, 0,
86 15, 5, 8, 0,
87 5, 25, 0, 16,
89 rasterFlushPrimitive();
90}
91
92static void drawT_LONG_K16(void) {
93 rasterReset();
94 rasterClearTestRegion(0, 0, 24, 28);
95 setTexpage(TEX17_TX, TEX17_TY, 2);
96 setTextureWindow(0, 0, 0, 0);
97 rasterTexTri(TEX_MOD_NEUTRAL,
98 5, 5, 0, 0,
99 15, 5, 16, 0,
100 5, 25, 0, 32, /* 8-bit UV holds 32 cleanly; probes only reach v=24 */
102 rasterFlushPrimitive();
103}
104
105) // CESTER_BODY
106
107// --------------------------------------------------------------------------
108// K=01 probes
109// --------------------------------------------------------------------------
110
111CESTER_TEST(ar_long_k01_y05, gpu_raster_phase20,
112 drawT_LONG_K01();
114)
115
116CESTER_TEST(ar_long_k01_y08, gpu_raster_phase20,
117 drawT_LONG_K01();
119)
120
121CESTER_TEST(ar_long_k01_y11, gpu_raster_phase20,
122 drawT_LONG_K01();
124)
125
126CESTER_TEST(ar_long_k01_y14, gpu_raster_phase20,
127 drawT_LONG_K01();
129)
130
131CESTER_TEST(ar_long_k01_y17, gpu_raster_phase20,
132 drawT_LONG_K01();
134)
135
136CESTER_TEST(ar_long_k01_y20, gpu_raster_phase20,
137 drawT_LONG_K01();
139)
140
141// --------------------------------------------------------------------------
142// K=03 probes
143// --------------------------------------------------------------------------
144
145CESTER_TEST(ar_long_k03_y05, gpu_raster_phase20,
146 drawT_LONG_K03();
148)
149
150CESTER_TEST(ar_long_k03_y08, gpu_raster_phase20,
151 drawT_LONG_K03();
153)
154
155CESTER_TEST(ar_long_k03_y11, gpu_raster_phase20,
156 drawT_LONG_K03();
158)
159
160CESTER_TEST(ar_long_k03_y14, gpu_raster_phase20,
161 drawT_LONG_K03();
163)
164
165CESTER_TEST(ar_long_k03_y17, gpu_raster_phase20,
166 drawT_LONG_K03();
168)
169
170CESTER_TEST(ar_long_k03_y20, gpu_raster_phase20,
171 drawT_LONG_K03();
173)
174
175// --------------------------------------------------------------------------
176// K=05 probes
177// --------------------------------------------------------------------------
178
179CESTER_TEST(ar_long_k05_y05, gpu_raster_phase20,
180 drawT_LONG_K05();
182)
183
184CESTER_TEST(ar_long_k05_y08, gpu_raster_phase20,
185 drawT_LONG_K05();
187)
188
189CESTER_TEST(ar_long_k05_y11, gpu_raster_phase20,
190 drawT_LONG_K05();
192)
193
194CESTER_TEST(ar_long_k05_y14, gpu_raster_phase20,
195 drawT_LONG_K05();
197)
198
199CESTER_TEST(ar_long_k05_y17, gpu_raster_phase20,
200 drawT_LONG_K05();
202)
203
204CESTER_TEST(ar_long_k05_y20, gpu_raster_phase20,
205 drawT_LONG_K05();
207)
208
209// --------------------------------------------------------------------------
210// K=08 probes
211// --------------------------------------------------------------------------
212
213CESTER_TEST(ar_long_k08_y05, gpu_raster_phase20,
214 drawT_LONG_K08();
216)
217
218CESTER_TEST(ar_long_k08_y08, gpu_raster_phase20,
219 drawT_LONG_K08();
221)
222
223CESTER_TEST(ar_long_k08_y11, gpu_raster_phase20,
224 drawT_LONG_K08();
226)
227
228CESTER_TEST(ar_long_k08_y14, gpu_raster_phase20,
229 drawT_LONG_K08();
231)
232
233CESTER_TEST(ar_long_k08_y17, gpu_raster_phase20,
234 drawT_LONG_K08();
236)
237
238CESTER_TEST(ar_long_k08_y20, gpu_raster_phase20,
239 drawT_LONG_K08();
241)
242
243// --------------------------------------------------------------------------
244// K=16 probes
245// --------------------------------------------------------------------------
246
247CESTER_TEST(ar_long_k16_y05, gpu_raster_phase20,
248 drawT_LONG_K16();
250)
251
252CESTER_TEST(ar_long_k16_y08, gpu_raster_phase20,
253 drawT_LONG_K16();
255)
256
257CESTER_TEST(ar_long_k16_y11, gpu_raster_phase20,
258 drawT_LONG_K16();
260)
261
262CESTER_TEST(ar_long_k16_y14, gpu_raster_phase20,
263 drawT_LONG_K16();
265)
266
267CESTER_TEST(ar_long_k16_y17, gpu_raster_phase20,
268 drawT_LONG_K16();
270)
271
272CESTER_TEST(ar_long_k16_y20, gpu_raster_phase20,
273 drawT_LONG_K16();
275)
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
#define EXPECT_LONG_K03_Y05
Definition raster-expected-phase20.h:80
#define EXPECT_LONG_K01_Y17
Definition raster-expected-phase20.h:70
#define EXPECT_LONG_K08_Y17
Definition raster-expected-phase20.h:112
#define EXPECT_LONG_K08_Y20
Definition raster-expected-phase20.h:113
#define EXPECT_LONG_K08_Y08
Definition raster-expected-phase20.h:109
#define EXPECT_LONG_K03_Y20
Definition raster-expected-phase20.h:85
#define EXPECT_LONG_K05_Y11
Definition raster-expected-phase20.h:96
#define EXPECT_LONG_K03_Y17
Definition raster-expected-phase20.h:84
#define EXPECT_LONG_K16_Y14
Definition raster-expected-phase20.h:125
#define EXPECT_LONG_K16_Y08
Definition raster-expected-phase20.h:123
#define EXPECT_LONG_K16_Y17
Definition raster-expected-phase20.h:126
#define EXPECT_LONG_K01_Y14
Definition raster-expected-phase20.h:69
#define EXPECT_LONG_K08_Y11
Definition raster-expected-phase20.h:110
#define EXPECT_LONG_K03_Y08
Definition raster-expected-phase20.h:81
#define EXPECT_LONG_K01_Y20
Definition raster-expected-phase20.h:71
#define EXPECT_LONG_K01_Y05
Definition raster-expected-phase20.h:66
#define EXPECT_LONG_K08_Y14
Definition raster-expected-phase20.h:111
#define EXPECT_LONG_K16_Y11
Definition raster-expected-phase20.h:124
#define EXPECT_LONG_K08_Y05
Definition raster-expected-phase20.h:108
#define EXPECT_LONG_K05_Y14
Definition raster-expected-phase20.h:97
#define EXPECT_LONG_K05_Y20
Definition raster-expected-phase20.h:99
#define EXPECT_LONG_K01_Y11
Definition raster-expected-phase20.h:68
#define EXPECT_LONG_K05_Y05
Definition raster-expected-phase20.h:94
#define EXPECT_LONG_K05_Y17
Definition raster-expected-phase20.h:98
#define EXPECT_LONG_K03_Y11
Definition raster-expected-phase20.h:82
#define EXPECT_LONG_K16_Y05
Definition raster-expected-phase20.h:122
#define EXPECT_LONG_K05_Y08
Definition raster-expected-phase20.h:95
#define EXPECT_LONG_K16_Y20
Definition raster-expected-phase20.h:127
#define EXPECT_LONG_K01_Y08
Definition raster-expected-phase20.h:67
#define EXPECT_LONG_K03_Y14
Definition raster-expected-phase20.h:83
#define TEX17_TY
Definition texture-fixture-phase17.h:58
#define TEX17_TPAGE
Definition texture-fixture-phase17.h:65
#define TEX17_TX
Definition texture-fixture-phase17.h:57
#define PHASE17_ASSERT_PIXEL_EQ(expected, x_, y_)
Definition texture-fixture-phase17.h:102
#define TEX17_CLUT_FIELD
Definition texture-fixture-phase17.h:66
#define TEX_MOD_NEUTRAL
Definition texture-fixtures.h:308