65816-llvm-mos/demos/gnoFdProbe.c
2026-07-07 18:33:48 -05:00

103 lines
2.8 KiB
C

// POSIX fd-layer regression for GNO (punch-list #9): exercise the GS/OS-toolbox
// emulation of creat/write/close/open/read/lseek/unlink over the gsos* wrappers.
// Round-trips a fixed 16-byte payload through a real GS/OS file in the login cwd
// (/home/root) and asserts every stage via bank-2 absolute markers (DBR-
// independent), per the gnoHeapProbe/gnoForkWaitProbe convention.
//
// 0x025000 C0DE reached end (no hang in the fd layer)
// 0x025002 0001 read-back payload matched what was written
// 0x025004 0001 creat() returned a real GS/OS refNum (>= 4)
// 0x025006 0001 write() wrote all 16 bytes
// 0x025008 0001 read() read all 16 bytes back
// 0x02500A 0001 open(O_RDONLY) returned a real refNum (>= 4)
// 0x02500C 0001 lseek(SEEK_SET,4) + 1-byte read landed on payload[4]
// 0x02500E 0001 unlink() removed the file
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#define M(a) (*(volatile uint16_t *)(a))
static const char kPath[] = "fdprobe.tmp";
static const uint8_t kData[16] = {
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50
};
int main(void) {
uint8_t rbuf[16];
uint16_t ok;
int fd;
long n;
long pos;
char one;
uint8_t i;
M(0x025000UL) = 0x0000;
M(0x025002UL) = 0xDEAD;
M(0x025004UL) = 0xDEAD;
M(0x025006UL) = 0xDEAD;
M(0x025008UL) = 0xDEAD;
M(0x02500AUL) = 0xDEAD;
M(0x02500CUL) = 0xDEAD;
M(0x02500EUL) = 0xDEAD;
ok = 1;
// Create + write the payload.
fd = creat(kPath, 0);
if (fd >= 4) {
M(0x025004UL) = 0x0001;
n = write(fd, kData, 16);
if (n == 16) {
M(0x025006UL) = 0x0001;
} else {
ok = 0;
}
close(fd);
} else {
ok = 0;
}
// Reopen read-only and read the payload back.
fd = open(kPath, O_RDONLY);
if (fd >= 4) {
M(0x02500AUL) = 0x0001;
n = read(fd, rbuf, 16);
if (n == 16) {
M(0x025008UL) = 0x0001;
} else {
ok = 0;
}
for (i = 0; i < 16; i++) {
if (rbuf[i] != kData[i]) {
ok = 0;
}
}
// Seek back into the file and confirm the byte at offset 4.
pos = lseek(fd, 4, SEEK_SET);
one = 0;
read(fd, &one, 1);
if (pos == 4 && (uint8_t)one == kData[4]) {
M(0x02500CUL) = 0x0001;
} else {
ok = 0;
}
close(fd);
} else {
ok = 0;
}
// Remove the file.
if (unlink(kPath) == 0) {
M(0x02500EUL) = 0x0001;
} else {
ok = 0;
}
M(0x025002UL) = ok ? 0x0001 : 0xDEAD;
M(0x025000UL) = 0xC0DE;
for (volatile unsigned long j = 0; j < 600000UL; j++) {
}
return 0;
}