65816-llvm-mos/tests/memBlock/memPattern.h
2026-10-06 17:01:51 -05:00

75 lines
1.9 KiB
C

// memPattern.h - the byte pattern the memBlock tests fill and check.
//
// The byte at address a is a's low byte xor a mix of its page and bank, so
// a copy off by one byte, one page or one bank reads wrong. Walked a page
// at a time so the per-byte work stays 16-bit.
#ifndef MEM_PATTERN_H
#define MEM_PATTERN_H
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef unsigned long size_t;
#define PAGE_BYTES 256u
static void fill(u32 a, u32 n, u8 seed);
static int holds(u32 a, u32 from, u32 n, u8 seed);
void *memcpy(void *dst, const void *src, size_t n);
void *memmove(void *dst, const void *src, size_t n);
void *memset(void *dst, int c, size_t n);
static u8 mixOf(u32 a, u8 seed);
// [a, a + n) = the pattern of its own addresses.
static void fill(u32 a, u32 n, u8 seed) {
u8 *p = (u8 *)a;
while (n != 0u) {
u8 lo = (u8)a;
u8 m = mixOf(a, seed);
u16 run = (u16)(PAGE_BYTES - lo);
u16 i;
if ((u32)run > n) {
run = (u16)n;
}
for (i = 0; i < run; i++) {
p[i] = (u8)(lo ^ m);
lo++;
}
p += run;
a += run;
n -= run;
}
}
// 1 when [a, a + n) holds the pattern of [from, from + n).
static int holds(u32 a, u32 from, u32 n, u8 seed) {
const u8 *p = (const u8 *)a;
while (n != 0u) {
u8 lo = (u8)from;
u8 m = mixOf(from, seed);
u16 run = (u16)(PAGE_BYTES - lo);
u16 i;
if ((u32)run > n) {
run = (u16)n;
}
for (i = 0; i < run; i++) {
if (p[i] != (u8)(lo ^ m)) {
return 0;
}
lo++;
}
p += run;
from += run;
n -= run;
}
return 1;
}
static u8 mixOf(u32 a, u8 seed) {
return (u8)((u8)((u8)(a >> 8) * 7u) ^ (u8)((u8)(a >> 16) * 13u) ^ seed);
}
#endif