49#define DEVICE (MEMCARD_PORT << 4)
50#define BU_PATH(name) (MEMCARD_PORT == 0 ? "bu00:" name : "bu10:" name)
64#define initCard __nugget_bios_initCard
65#define startCard __nugget_bios_startCard
66#define buFormat __nugget_bios_buFormat
67#define firstFile __nugget_bios_firstFile
68#define nextFile __nugget_bios_nextFile
69#define erase __nugget_bios_erase
72#define EVENT_HWCARD 0xf0000011
74static const uint32_t s_specs[
EVENTS] = {0x0004, 0x8000, 0x0100, 0x2000};
75static const char *
const s_names[
EVENTS] = {
"done",
"error",
"timeout",
"new card"};
76static uint32_t s_events[
EVENTS];
78static unsigned s_checks = 0;
79static unsigned s_failures = 0;
81static int check(
int pass,
const char *name) {
83 if (!pass) s_failures++;
88static int same(
const uint8_t *a,
const uint8_t *
b, uint32_t len) {
89 for (uint32_t
i = 0;
i < len;
i++) {
90 if (a[
i] !=
b[
i])
return 0;
95static int streq(
const char *a,
const char *
b) {
96 for (uint32_t
i = 0;;
i++) {
97 if (a[
i] !=
b[
i])
return 0;
98 if (a[
i] == 0)
return 1;
102static void drainEvents() {
103 for (
int i = 0;
i <
EVENTS;
i++) syscall_testEvent(s_events[
i]);
107static int waitCard() {
108 for (uint32_t spin = 0; spin < 0x200000; spin++) {
110 if (syscall_testEvent(s_events[
i]))
return i;
116static const char *eventName(
int e) {
return e < 0 ?
"no event" : s_names[
e]; }
122 for (
int attempt = 0;; attempt++) {
127 syscall_mcAllowNewCard();
131static int cardWrite(
int sector,
const uint8_t *
buffer) {
132 for (
int attempt = 0;; attempt++) {
137 syscall_mcAllowNewCard();
141static uint8_t s_frame[128];
142static uint8_t s_frame2[128];
143static uint8_t s_data[2048];
144static uint8_t s_readback[2048];
146static void fill(uint8_t *
buf, uint32_t len, uint32_t seed) {
147 uint32_t x = seed * 2654435761u + 7;
148 for (uint32_t
i = 0;
i < len;
i++) {
149 x = x * 1103515245u + 12345u;
150 buf[
i] = (uint8_t)(x >> 16);
154static int startsWith(
const uint8_t *
s,
const char *prefix) {
155 for (uint32_t
i = 0; prefix[
i];
i++) {
156 if (
s[
i] != (uint8_t)prefix[
i])
return 0;
163static int cardIsOursToErase() {
164 static const uint8_t titleSjis[] = {0x82, 0x6c, 0x82, 0x73};
165 int e = cardRead(0, s_frame);
167 ramsyscall_printf(
"REFUSE: frame 0 read ended on %s\n",
e == -2 ?
"a refused call" : eventName(
e));
170 int zeros = 1, ones = 1;
171 for (
int i = 0;
i < 128;
i++) {
172 zeros = zeros && s_frame[
i] == 0x00;
173 ones = ones && s_frame[
i] == 0xff;
179 if (s_frame[0] ==
'S' && s_frame[1] ==
'C' && same(s_frame + 4, titleSjis,
sizeof(titleSjis))) {
180 ramsyscall_printf(
"card: frame 0 holds the memcard test's title frame, from an earlier run\n");
183 if (s_frame[0] !=
'M' || s_frame[1] !=
'C') {
187 for (
int s = 1;
s <= 15;
s++) {
188 e = cardRead(
s, s_frame);
193 if (s_frame[0] == 0x51 && !startsWith(s_frame + 0x0a,
"BIMEMTEST")) {
194 s_frame[0x0a + 20] = 0;
196 (
const char *)s_frame + 0x0a);
204static void testSectors() {
206 for (
int s = 64;
s < 67;
s++) {
207 fill(s_frame, 128,
s);
208 int e = cardWrite(
s, s_frame);
211 for (
int s = 64;
s < 67;
s++) {
212 fill(s_frame, 128,
s);
213 int e = cardRead(
s, s_frame2);
214 if (
e !=
DONE || !same(s_frame, s_frame2, 128)) {
219 check(
ok,
"_card_write then _card_read, 3 sectors");
225 int accepted = syscall_mcReadSector(
DEVICE, 1024, s_frame2);
226 int e = accepted ? waitCard() : -2;
227 ramsyscall_printf(
"_card_read 1024: %s, ended on %s\n", accepted ?
"accepted" :
"refused", eventName(
e));
228 check(accepted,
"_card_read passes sector 1024 to the card");
235 accepted = syscall_mcReadSector(
DEVICE, 1023, s_frame2);
236 e = accepted ? waitCard() : -2;
237 check(accepted &&
e ==
DONE,
"_card_read takes sector 1023");
240static void testDevice() {
246 check(
fd >= 0,
"open O_CREAT, 1 block");
247 if (
fd >= 0) syscall_close(
fd);
249 fill(s_data, 2048, 1);
251 int n =
fd >= 0 ? (int)syscall_write(
fd, s_data, 1024) : -1;
252 if (
fd >= 0) syscall_close(
fd);
253 check(n == 1024,
"write 1024 bytes");
256 check(
fd >= 0,
"open O_CREAT, 2 blocks");
257 if (
fd >= 0) syscall_close(
fd);
258 fill(s_data, 2048, 2);
260 n =
fd >= 0 ? (int)syscall_write(
fd, s_data, 2048) : -1;
261 if (
fd >= 0) syscall_close(
fd);
262 check(n == 2048,
"write 2048 bytes");
264 int found = 0, sizes = 1;
268 if (streq(
entry.name,
"BIMEMTEST-BIOS"))
269 sizes = sizes &&
entry.size == 8192;
270 else if (streq(
entry.name,
"BIMEMTEST-BIOS2"))
271 sizes = sizes &&
entry.size == 16384;
274 if (found > 15)
break;
276 check(found == 2 && sizes,
"firstfile/nextfile list both files and their sizes");
278 fill(s_data, 2048, 1);
281 n =
fd >= 0 ? syscall_read(
fd, s_readback, 1024) : -1;
282 if (
fd >= 0) syscall_close(
fd);
283 check(n == 1024 && same(s_data, s_readback, 1024),
"read back the first file");
284 fill(s_data, 2048, 2);
287 n =
fd >= 0 ? syscall_read(
fd, s_readback, 2048) : -1;
288 if (
fd >= 0) syscall_close(
fd);
289 check(n == 2048 && same(s_data, s_readback, 2048),
"read back the second file");
293 check(p && streq(
entry.name,
"BIMEMTEST-BIOS2") &&
nextFile(&entry) == NULL,
"only the second file is left");
298 int e1 = cardRead(1, s_frame);
299 int dir1 = e1 ==
DONE ? s_frame[0] : -1;
300 int e2 = cardRead(2, s_frame);
301 int dir2 = e2 ==
DONE ? s_frame[0] : -1;
302 int named = e2 ==
DONE && startsWith(s_frame + 0x0a,
"BIMEMTEST-BIOS2");
303 int e3 = cardRead(3, s_frame);
304 int dir3 = e3 ==
DONE ? s_frame[0] : -1;
305 ramsyscall_printf(
"directory states: block 1 %02x, block 2 %02x, block 3 %02x\n", dir1, dir2, dir3);
306 check(dir1 == 0xa1 && dir2 == 0x51 && named && dir3 == 0x53,
"directory: a1 / 51 named / 53");
318 s_events[
i] = syscall_openEvent(
EVENT_HWCARD, s_specs[
i], 0x2000, NULL);
319 syscall_enableEvent(s_events[
i]);
322 if (cardIsOursToErase()) {
329 if (s_failures == 0) {
334 return s_failures == 0 ? 0 : 1;
int ok
Definition cdlstop.c:75
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)
__builtin_memset(response, 0xff, 16)
@ PSXF_READ
Definition stdio.h:75
@ PSXF_CREAT
Definition stdio.h:82
@ PSXF_WRITE
Definition stdio.h:76
uint8_t b
Definition gte-depthcue.c:41
int i
Definition gte-regio.c:299
#define erase
Definition memcard-bios.c:69
int __nugget_bios_startCard(void)
#define buFormat
Definition memcard-bios.c:66
int __nugget_bios_erase(const char *name)
#define nextFile
Definition memcard-bios.c:68
#define BU_PATH(name)
Definition memcard-bios.c:50
#define initCard
Definition memcard-bios.c:64
#define DEVICE
Definition memcard-bios.c:49
#define firstFile
Definition memcard-bios.c:67
struct DirEntry * __nugget_bios_nextFile(struct DirEntry *entry)
struct DirEntry * __nugget_bios_firstFile(const char *pattern, struct DirEntry *entry)
@ ERROR
Definition memcard-bios.c:73
@ EVENTS
Definition memcard-bios.c:73
@ DONE
Definition memcard-bios.c:73
@ TIMEOUT
Definition memcard-bios.c:73
@ NEWCARD
Definition memcard-bios.c:73
#define EVENT_HWCARD
Definition memcard-bios.c:72
#define startCard
Definition memcard-bios.c:65
int __nugget_bios_initCard(int padEnable)
#define MEMCARD_PORT
Definition memcard-bios.c:46
int __nugget_bios_buFormat(const char *dev)
int main()
Definition memcard-bios.c:313
n
Definition gentable.py:95
check
Definition mkimage.py:54
entry
Definition mkimage.py:61
int fd
Definition pcdrv-net.c:67
char * s
Definition string.c:48
char e[1]
Definition string.c:119
static void * buffer
Definition syscalls.h:274
#define NUGGET_BIOS_THUNK(name, table, number)
Definition syscalls.h:70
static int sector
Definition syscalls.h:490
static const void * buf
Definition syscalls.h:114