// 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(ulong addr, ulong maxn, char *buf) { ulong orig_maxn = maxn; for (; maxn > 0; buf++, addr++, maxn--) { *buf = readmemzx(addr, 1) & 0xFF; if (*buf == 0) break; } *buf = 0; return orig_maxn - maxn; } ulong writestr(ulong addr, ulong maxn, char *str) { ulong orig_maxn = maxn; for (; *str && maxn > 0; str++, addr++, maxn--) { writemem(*str, addr, 1); } writemem(0, addr, 1); return orig_maxn - maxn; } //----------------------------------------------------------------------------// #define CHK_ALIGN(type) \ if (addr % alignof(type) > 0) { \ _except(E_ALI, \ "Non-aligned memory access: 0x%012lX (0x%012lX) by %lu", \ addr, real, alignof(type)); \ } //----------------------------------------------------------------------------// static ulong readmem8(ulong real, ulong addr) { return (ulong)ctx->mp[real]; } static ulong readmem16(ulong real, ulong addr) { CHK_ALIGN(ushort); return (ulong)*(ushort *)(ctx->mp + real); } static ulong readmem32(ulong real, ulong addr) { CHK_ALIGN(uint); return (ulong)*(uint *)(ctx->mp + real); } static ulong readmem64(ulong real, ulong addr) { CHK_ALIGN(ulong); return (ulong)*(ulong *)(ctx->mp + real); } //----------------------------------------------------------------------------// static void writemem8(ulong val, ulong real, ulong addr) { ctx->mp[real] = val & 0xFF; } static void writemem16(ulong val, ulong real, ulong addr) { *(ushort*)(ctx->mp + real) = val & 0xFFFF; } static void writemem32(ulong val, ulong real, ulong addr) { CHK_ALIGN(uint); *(uint*)(ctx->mp + real) = val & 0xFFFFFFFF; } static void writemem64(ulong val, ulong real, ulong addr) { CHK_ALIGN(ulong); *(ulong*)(ctx->mp + real) = val; } //----------------------------------------------------------------------------// #define CHK_RANGE() \ if (addr < MEMOFF || real >= MEMSIZE) { \ _except(E_ACC, \ "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); \ } #define GETREAL() \ ulong real = addr2real(addr + R(CR1)) //----------------------------------------------------------------------------// ulong readmemzx(ulong addr, uint len) { GETREAL(); CHK_RANGE(); switch (len) { case 1: return readmem8(real, addr); break; case 2: return readmem16(real, addr); break; case 4: return readmem32(real, addr); break; case 8: return readmem64(real, addr); break; default: logerr("readmemzx() bad length %d!\n", len); abort(); } } ulong readmemsx(ulong addr, uint len) { GETREAL(); CHK_RANGE(); ulong val; switch (len) { case 1: val = readmem8(real, addr); val = (ulong)(long)(char)val; break; case 2: val = readmem16(real, addr); val = (ulong)(long)(short)val; break; case 4: val = readmem32(real, addr); val = (ulong)(long)(int)val; break; case 8: return readmem64(real, addr); default: logerr("readmemsx() bad length %d!\n", len); abort(); } return val; } void writemem(ulong val, ulong addr, uint len) { GETREAL(); CHK_RANGE(); switch (len) { case 1: writemem8(val, real, addr); break; case 2: writemem16(val, real, addr); break; case 4: writemem32(val, real, addr); break; case 8: writemem64(val, real, addr); break; default: logerr("writemem() bad length %d!\n", len); abort(); } } //----------------------------------------------------------------------------//