// The OS/K Team licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #include //----------------------------------------------------------------------------// ulong readstr(ctx_t *ctx, ulong addr, ulong maxn, char *buf) { ulong orig_maxn = maxn; for (; maxn > 0; buf++, addr++, maxn--) { *buf = readmemzx(ctx, addr, 1) & 0xFF; if (*buf == 0) break; } *buf = 0; return orig_maxn - maxn; } ulong writestr(ctx_t *ctx, ulong addr, ulong maxn, char *str) { ulong orig_maxn = maxn; for (; *str && maxn > 0; str++, addr++, maxn--) { writemem(ctx, *str, addr, 1); } writemem(ctx, 0, addr, 1); return orig_maxn - maxn; } //----------------------------------------------------------------------------// #define CHK_ALIGN(type) \ if (addr % alignof(type) > 0) { \ _except(ctx, E_ALI, \ "Non-aligned memory access: 0x%012lX (0x%012lX) by %lu", \ addr, real, alignof(type)); \ } //----------------------------------------------------------------------------// static ulong readmem8(ctx_t *ctx, ulong real, ulong addr) { return (ulong)ctx->mp[real]; } static ulong readmem16(ctx_t *ctx, ulong real, ulong addr) { CHK_ALIGN(ushort); return (ulong)*(ushort *)(ctx->mp + real); } static ulong readmem32(ctx_t *ctx, ulong real, ulong addr) { CHK_ALIGN(uint); return (ulong)*(uint *)(ctx->mp + real); } static ulong readmem64(ctx_t *ctx, ulong real, ulong addr) { CHK_ALIGN(ulong); return (ulong)*(ulong *)(ctx->mp + real); } //----------------------------------------------------------------------------// static void writemem8(ctx_t *ctx, ulong val, ulong real, ulong addr) { ctx->mp[real] = val & 0xFF; } static void writemem16(ctx_t *ctx, ulong val, ulong real, ulong addr) { *(ushort*)(ctx->mp + real) = val & 0xFFFF; } static void writemem32(ctx_t *ctx, ulong val, ulong real, ulong addr) { CHK_ALIGN(uint); *(uint*)(ctx->mp + real) = val & 0xFFFFFFFF; } static void writemem64(ctx_t *ctx, ulong val, ulong real, ulong addr) { CHK_ALIGN(ulong); *(ulong*)(ctx->mp + real) = val; } //----------------------------------------------------------------------------// #define CHK_RANGE() \ if (addr < MEMOFF || real >= MEMSIZE) { \ _except(ctx, E_ACC, \ "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); \ } #define GETREAL() \ ulong real = addr2real(addr + R(CR2)) //----------------------------------------------------------------------------// ulong readmemzx(ctx_t *ctx, ulong addr, uint len) { GETREAL(); CHK_RANGE(); switch (len) { case 1: return readmem8(ctx, real, addr); break; case 2: return readmem16(ctx, real, addr); break; case 4: return readmem32(ctx, real, addr); break; case 8: return readmem64(ctx, real, addr); break; default: logerr("readmemzx() bad length %d!\n", len); abort(); } } ulong readmemsx(ctx_t *ctx, ulong addr, uint len) { GETREAL(); CHK_RANGE(); ulong val; switch (len) { case 1: val = readmem8(ctx, real, addr); val = (ulong)(long)(char)val; break; case 2: val = readmem16(ctx, real, addr); val = (ulong)(long)(short)val; break; case 4: val = readmem32(ctx, real, addr); val = (ulong)(long)(int)val; break; case 8: return readmem64(ctx, real, addr); default: logerr("readmemsx() bad length %d!\n", len); abort(); } return val; } void writemem(ctx_t *ctx, ulong val, ulong addr, uint len) { GETREAL(); CHK_RANGE(); // log("writemem: 0x%lX: 0x%lX (%d)\n", addr, val, len); switch (len) { case 1: writemem8(ctx, val, real, addr); break; case 2: writemem16(ctx, val, real, addr); break; case 4: writemem32(ctx, val, real, addr); break; case 8: writemem64(ctx, val, real, addr); break; default: logerr("writemem() bad length %d!\n", len); abort(); } } //----------------------------------------------------------------------------//