// 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