Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
cdlgetlocp.c
Go to the documentation of this file.
1/*
2
3MIT License
4
5Copyright (c) 2022 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// clang-format off
28
30 int resetDone = resetCDRom();
31 if (!resetDone) {
33 return;
34 }
35
37 CDROM_REG0 = 0;
40 uint8_t cause1 = ackCDRomCause();
41 uint8_t ctrl1 = CDROM_REG0 & ~3;
42 struct LocPResult response;
43 uint8_t responseSize = readResponse((uint8_t*)&response);
44 uint8_t ctrl2 = CDROM_REG0 & ~3;
45 CDROM_REG0 = 1;
46 uint8_t cause1b = CDROM_REG3_UC;
47
52 // Right after reset, the drive will over close to 00:02:00, so
53 // the GetLocP will return values around that. Track will always
54 // be 01, and the oscillation will be of roughly 4 frames. Index
55 // will be 00 or 01 depending if the head is over the pregap,
56 // before or equal to absolute 00:01:74. The absolute time will
57 // be around 00:02:00, and the relative time will be around
58 // 00:00:00. The pregap relative time counts down to 0, so
59 // for an absolute time of 00:01:74, the relative time will be
60 // 00:00:01. For an absolute time of 00:01:73, the relative time
61 // will be 00:00:02, and so on.
62 int inPregap = response.index == 0;
64 uint32_t absolute = MSF2LBA(btoi(response.am), btoi(response.as), btoi(response.af));
66 if (inPregap) {
68 } else {
70 }
79 // Typical value seems to be around 1ms, but has
80 // been seen to spike high from time to time.
83 ramsyscall_printf("Basic getlocP, ack in %ius\n", ackTime);
84 ramsyscall_printf("Full response: track: %02x, index: %02x, relative: %02x:%02x:%02x(%2i), absolute: %02x:%02x:%02x(%2i)\n",
85 response.track, response.index,
88 );
89)
90
91CESTER_TEST(cdlGetLocPafterSeekP, test_instances,
92 int resetDone = resetCDRom();
93 if (!resetDone) {
95 return;
96 }
97
98 int seekDone = seekPTo(0x50, 0, 0);
99 if (!seekDone) {
101 return;
102 }
103
109 uint8_t ctrl1 = CDROM_REG0 & ~3;
110 struct LocPResult response;
111 uint8_t responseSize = readResponse((uint8_t*)&response);
112 uint8_t ctrl2 = CDROM_REG0 & ~3;
113 CDROM_REG0 = 1;
115
120 // After a simple seekP, the head will hover around the seeked
121 // position, so the GetLocP will return values before that. Distance
122 // from the seeked position will be up to 50 frames around this location.
123 int inPregap = response.index == 0;
124 uint32_t relative = MSF2LBA(btoi(response.m), btoi(response.s), btoi(response.f));
125 uint32_t absolute = MSF2LBA(btoi(response.am), btoi(response.as), btoi(response.af));
127 if (inPregap) {
129 } else {
131 }
141 // Typical value seems to be around 1ms, but has
142 // been seen to spike high from time to time.
145 ramsyscall_printf("Basic getlocP after seekP, ack in %ius\n", ackTime);
146 ramsyscall_printf("Full response: track: %02x, index: %02x, relative: %02x:%02x:%02x(%2i), absolute: %02x:%02x:%02x(%2i)\n",
147 response.track, response.index,
150 );
151)
152
153CESTER_TEST(cdlGetLocPafterSeekL, test_instances,
154 int resetDone = resetCDRom();
155 if (!resetDone) {
157 return;
158 }
159
160 int seekDone = seekLTo(0x50, 0, 0);
161 if (!seekDone) {
163 return;
164 }
165
167 CDROM_REG0 = 0;
170 uint8_t cause1 = ackCDRomCause();
171 uint8_t ctrl1 = CDROM_REG0 & ~3;
172 struct LocPResult response;
173 uint8_t responseSize = readResponse((uint8_t*)&response);
174 uint8_t ctrl2 = CDROM_REG0 & ~3;
175 CDROM_REG0 = 1;
176 uint8_t cause1b = CDROM_REG3_UC;
177
182 // After a simple seekL, the head will hover around the seeked
183 // position, so the GetLocP will return values around that. Distance
184 // from the seeked position will be up to 10 frames around this location,
185 // and sometimes a little bit after it too. It will be much more precise
186 // than seekP however, and most of the time, will be exactly at the
187 // seeked position.
188 int inPregap = response.index == 0;
189 uint32_t relative = MSF2LBA(btoi(response.m), btoi(response.s), btoi(response.f));
190 uint32_t absolute = MSF2LBA(btoi(response.am), btoi(response.as), btoi(response.af));
192 if (inPregap) {
194 } else {
196 }
206 // Typical value seems to be around 1ms, but has
207 // been seen to spike high from time to time.
210 ramsyscall_printf("Basic getlocP after seekL, ack in %ius\n", ackTime);
211 ramsyscall_printf("Full response: track: %02x, index: %02x, relative: %02x:%02x:%02x(%2i), absolute: %02x:%02x:%02x(%2i)\n",
212 response.track, response.index,
215 );
216)
217
218
219CESTER_TEST(cdlGetLocPinT5, test_instances,
220 int resetDone = resetCDRom();
221 if (!resetDone) {
223 return;
224 }
225
226 int seekDone = seekPTo(0x70, 0x21, 0);
227 if (!seekDone) {
229 return;
230 }
231
233 CDROM_REG0 = 0;
236 uint8_t cause1 = ackCDRomCause();
237 uint8_t ctrl1 = CDROM_REG0 & ~3;
238 struct LocPResult response;
239 uint8_t responseSize = readResponse((uint8_t*)&response);
240 uint8_t ctrl2 = CDROM_REG0 & ~3;
241 CDROM_REG0 = 1;
242 uint8_t cause1b = CDROM_REG3_UC;
243
248 // Let's go inside of track 5, and see what we get.
249 int inPregap = response.index == 0;
250 uint32_t relative = MSF2LBA(btoi(response.m), btoi(response.s), btoi(response.f));
251 uint32_t absolute = MSF2LBA(btoi(response.am), btoi(response.as), btoi(response.af));
253 if (inPregap) {
255 } else {
257 }
267 // Typical value seems to be around 1ms, but has
268 // been seen to spike high from time to time.
271 ramsyscall_printf("Basic getlocP after seekP in track5's, ack in %ius\n", ackTime);
272 ramsyscall_printf("Full response: track: %02x, index: %02x, relative: %02x:%02x:%02x(%2i), absolute: %02x:%02x:%02x(%2i)\n",
273 response.track, response.index,
276 );
277)
278
279CESTER_TEST(cdlGetLocPinT5Pregap, test_instances,
280 int resetDone = resetCDRom();
281 if (!resetDone) {
283 return;
284 }
285
286 int seekDone = seekPTo(0x70, 0x19, 0x73);
287 if (!seekDone) {
289 return;
290 }
291
293 CDROM_REG0 = 0;
296 uint8_t cause1 = ackCDRomCause();
297 uint8_t ctrl1 = CDROM_REG0 & ~3;
298 struct LocPResult response;
299 uint8_t responseSize = readResponse((uint8_t*)&response);
300 uint8_t ctrl2 = CDROM_REG0 & ~3;
301 CDROM_REG0 = 1;
302 uint8_t cause1b = CDROM_REG3_UC;
303
308 // This time, the head is in the pregap of track 5.
309 int inPregap = response.index == 0;
310 uint32_t relative = MSF2LBA(btoi(response.m), btoi(response.s), btoi(response.f));
311 uint32_t absolute = MSF2LBA(btoi(response.am), btoi(response.as), btoi(response.af));
313 if (inPregap) {
315 } else {
317 }
326 // Typical value seems to be around 1ms, but has
327 // been seen to spike high from time to time.
330 ramsyscall_printf("Basic getlocP after seekP in track5's pregap, ack in %ius\n", ackTime);
331 ramsyscall_printf("Full response: track: %02x, index: %02x, relative: %02x:%02x:%02x(%2i), absolute: %02x:%02x:%02x(%2i)\n",
332 response.track, response.index,
335 );
336)
struct LocPResult response
Definition cdlgetlocp.c:110
cester_assert_uint_eq(3, cause1)
CDROM_REG0
Definition cdlgetlocp.c:105
uint8_t responseSize
Definition cdlgetlocp.c:111
uint32_t ackTime
Definition cdlgetlocp.c:107
cester_assert_uint_ge(onefifty, 150)
CESTER_TEST(cdlGetLocP, test_instances, int resetDone=resetCDRom();if(!resetDone) { cester_assert_true(resetDone);return;} initializeTime();CDROM_REG0=0;CDROM_REG1=CDL_GETLOCP;uint32_t ackTime=waitCDRomIRQ();uint8_t cause1=ackCDRomCause();uint8_t ctrl1=CDROM_REG0 &~3;struct LocPResult response;uint8_t responseSize=readResponse((uint8_t *)&response);uint8_t ctrl2=CDROM_REG0 &~3;CDROM_REG0=1;uint8_t cause1b=CDROM_REG3_UC;cester_assert_uint_eq(3, cause1);cester_assert_uint_eq(0xe0, cause1b);cester_assert_uint_eq(0x38, ctrl1);cester_assert_uint_eq(0x18, ctrl2);int inPregap=response.index==0;uint32_t relative=MSF2LBA(btoi(response.m), btoi(response.s), btoi(response.f));uint32_t absolute=MSF2LBA(btoi(response.am), btoi(response.as), btoi(response.af));uint32_t onefifty=absolute;if(inPregap) { onefifty=absolute+relative;} else { onefifty=absolute - relative;} cester_assert_uint_eq(1, response.track);cester_assert_uint_ge(onefifty, 150);cester_assert_uint_ge(response.index, 0);cester_assert_uint_le(response.index, 1);cester_assert_uint_ge(absolute, 145);cester_assert_uint_lt(absolute, 155);cester_assert_uint_lt(relative, 5);cester_assert_uint_eq(8, responseSize);cester_assert_uint_ge(ackTime, 500);cester_assert_uint_lt(ackTime, 7000);ramsyscall_printf("Basic getlocP, ack in %ius\n", ackTime);ramsyscall_printf("Full response: track: %02x, index: %02x, relative: %02x:%02x:%02x(%2i), absolute: %02x:%02x:%02x(%2i)\n", response.track, response.index, response.m, response.s, response.f, relative, response.am, response.as, response.af, absolute);) CESTER_TEST(cdlGetLocPafterSeekP
uint32_t start
Definition cdlgetlocp.c:252
int resetDone
Definition cdlgetlocp.c:92
uint32_t absolute
Definition cdlgetlocp.c:125
uint32_t onefifty
Definition cdlgetlocp.c:126
test_instances
Definition cdlgetlocp.c:91
cester_assert_uint_lt(absolute, 225000)
uint8_t ctrl2
Definition cdlgetlocp.c:112
uint8_t cause1
Definition cdlgetlocp.c:108
uint8_t cause1b
Definition cdlgetlocp.c:114
int inPregap
Definition cdlgetlocp.c:123
uint8_t ctrl1
Definition cdlgetlocp.c:109
uint32_t relative
Definition cdlgetlocp.c:124
initializeTime()
CDROM_REG1
Definition cdlgetlocp.c:106
int seekDone
Definition cdlgetlocp.c:98
waitCDRomIRQ()
@ CDL_GETLOCP
Definition cdrom.h:59
#define CDROM_REG3_UC
Definition cdrom.h:39
ramsyscall_printf("=== e01_kseg1_reads_no_fill ===\n")
constexpr uint8_t btoi(uint8_t b)
Definition msf.hh:35
ackCDRomCause()
cester_assert_true(seekDone)
readResponse(response)
cester_assert_uint_le(readyCount, 2)
void uint32_t(classId, spec)