/* read memory */ EXPORT W readMem(UW addr, void *buf, W len, W unit) { W i, n, alen; MP pa, bp; /* address misalignment is reported as error */ if (addr & (unit - 1)) return 0; bp.w = buf; for (alen = 0; alen < len; alen += i) { /* memory address check & conversion to physical address */ n = chkMemAddr(addr + alen, &pa.a, len - alen, 0); if (n < unit) break; /* illegal address */ i = 0; switch(unit) { case 4: for (; i < n; i += 4) *bp.w++ = rd_w(pa.w++); break; case 2: for (; i < n; i += 2) *bp.h++ = rd_h(pa.h++); break; default: for (; i < n; i++) *bp.b++ = rd_b(pa.b++); } } return alen; }
/* write memory unit & 0x10 : fill */ EXPORT W writeMem(UW addr, void *buf, W len, W unit) { W i, n, sz, alen; MP pa, bp; // address misalignment is reported as error sz = unit & 0x0f; if (addr & (sz - 1)) return 0; bp.w = buf; for (alen = 0; alen < len; alen += i) { // memory address check & conversion to physical address n = chkMemAddr(addr + alen, &pa.a, len - alen, 1); if (n < sz) break; // illegal address i = 0; switch(sz) { case 4: if (unit & 0x10) { #if TEF_EM1D for (; i < n; i += 4) wr_w(pa.w++, *bp.w); #endif } else { #if TEF_EM1D for (; i < n; i += 4) wr_w(pa.w++, *bp.w++); #endif } break; case 2: if (unit & 0x10) { #if TEF_EM1D for (; i < n; i += 2) wr_h(pa.h++, *bp.h); #endif } else { #if TEF_EM1D for (; i < n; i += 2) wr_h(pa.h++, *bp.h++); #endif } break; default: if (unit & 0x10) { #if TEF_EM1D for (; i < n; i++) wr_b(pa.b++, *bp.b); #endif } else { #if TEF_EM1D for (; i < n; i++) wr_b(pa.b++, *bp.b++); #endif } } } return alen; }
/* read character string */ EXPORT W readMemStr(UW addr, void *buf, W len) { W i, n, alen; UW pa; for (alen = 0; alen < len; alen += i) { /* memory address check & conversion to physical address */ n = chkMemAddr(addr + alen, &pa, len - alen, 0); if (n == 0) break; /* illegal address */ for (i = 0; i < n; i++, buf++, pa++) { if ((*(UB*)buf = rd_b((UB*)pa)) == 0) return alen + i; } } return -1; }