// 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 "arch.h" ulong readmem(ctx_t *ctx, ulong addr, uint len) { switch (len) { case 1: return readmem8(ctx, addr); break; case 2: return readmem16(ctx, addr); break; case 4: return readmem32(ctx, addr); break; case 8: return readmem64(ctx, addr); break; default: log("readmem() bad length!\n"); abort(); } } void writemem(ctx_t *ctx, ulong val, ulong addr, uint len) { addr += ctx->r[CR2].val; switch (len) { case 1: writemem8(ctx, val, addr); break; case 2: writemem16(ctx, val, addr); break; case 4: writemem32(ctx, val, addr); break; case 8: writemem64(ctx, val, addr); break; default: log("writemem() bad length!\n"); abort(); } } #define CHK_RANGE() \ if (addr < MEMOFF || real >= MEMSIZE) { \ _except(ctx, E_ACC, \ "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); \ } #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)); \ } #define GETREAL() \ addr += ctx->r[CR2].val; \ ulong real = addr2real(addr) ulong readmem8(ctx_t *ctx, ulong addr) { GETREAL(); CHK_RANGE(); if (addr % 2 == 0) return (ulong)ctx->mp[real] & 0xFF; else return ((ulong)ctx->mp[real] & 0xFF00) >> 8; } ulong readmem16(ctx_t *ctx, ulong addr) { GETREAL(); CHK_RANGE(); CHK_ALIGN(ushort); return (ulong)ctx->mp[real]; } ulong readmem32(ctx_t *ctx, ulong addr) { GETREAL(); CHK_RANGE(); CHK_ALIGN(uint); ulong val = ctx->mp[real++]; val = val | ((ulong)ctx->mp[real] << 16); return val; } ulong readmem64(ctx_t *ctx, ulong addr) { GETREAL(); CHK_RANGE(); CHK_ALIGN(ulong); ulong val = (ulong)ctx->mp[real++]; val = val | ((ulong)ctx->mp[real++] << 16); val = val | ((ulong)ctx->mp[real++] << 32); val = val | ((ulong)ctx->mp[real] << 48); return val; } void writemem8(ctx_t *ctx, ulong val, ulong addr) { GETREAL(); CHK_RANGE(); ushort v = ctx->mp[real]; if (!(addr % 2)) { ctx->mp[real] = ((v & 0xFF00) << 8) | (val & 0xFF); } else { ctx->mp[real] = (v & 0xFF) | (((val & 0xFF) << 8)); } /* if (addr % 2) { ctx->mp[real] = (v & 0xFF00) | (val & 0xFF); } else { ctx->mp[real] = (v & 0xFF) | (((val & 0xFF) << 8)); } */ } void writemem16(ctx_t *ctx, ulong val, ulong addr) { GETREAL(); CHK_RANGE(); CHK_ALIGN(ushort); ctx->mp[real] = val & 0xFFFF; } void writemem32(ctx_t *ctx, ulong val, ulong addr) { GETREAL(); CHK_RANGE(); CHK_ALIGN(uint); ctx->mp[real++] = val & 0xFFFF; ctx->mp[real] = (val >> 16) & 0xFFFF; } void writemem64(ctx_t *ctx, ulong val, ulong addr) { GETREAL(); CHK_RANGE(); CHK_ALIGN(ulong); ctx->mp[real++] = val; ctx->mp[real++] = (val >> 16) & 0xFFFF; ctx->mp[real++] = (val >> 32) & 0xFFFF; ctx->mp[real] = (val >> 48) & 0xFFFF; }