2019-05-22 18:39:46 +02:00
|
|
|
// The OS/K Team licenses this file to you under the MIT license.
|
|
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
|
2019-06-05 12:53:09 +02:00
|
|
|
#include <pc/arch.h>
|
2019-05-22 18:39:46 +02:00
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
//----------------------------------------------------------------------------//
|
2019-05-22 18:39:46 +02:00
|
|
|
|
2019-07-10 17:17:45 +02:00
|
|
|
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)
|
2019-06-26 21:25:59 +02:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-05-29 19:00:13 +02:00
|
|
|
#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)); \
|
2019-05-22 18:39:46 +02:00
|
|
|
}
|
2019-05-29 19:00:13 +02:00
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
//----------------------------------------------------------------------------//
|
2019-05-29 19:00:13 +02:00
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
static ulong readmem8(ctx_t *ctx, ulong real, ulong addr)
|
2019-05-29 19:00:13 +02:00
|
|
|
{
|
2019-07-24 16:52:26 +02:00
|
|
|
return (ulong)ctx->mp[real];
|
2019-05-22 18:39:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
static ulong readmem16(ctx_t *ctx, ulong real, ulong addr)
|
2019-05-22 18:39:46 +02:00
|
|
|
{
|
2019-05-29 19:00:13 +02:00
|
|
|
CHK_ALIGN(ushort);
|
2019-05-22 18:39:46 +02:00
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
return (ulong)*(ushort *)(ctx->mp + real);
|
2019-05-22 18:39:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
static ulong readmem32(ctx_t *ctx, ulong real, ulong addr)
|
2019-05-22 18:39:46 +02:00
|
|
|
{
|
2019-05-29 19:00:13 +02:00
|
|
|
CHK_ALIGN(uint);
|
2019-05-22 18:39:46 +02:00
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
return (ulong)*(uint *)(ctx->mp + real);
|
2019-05-22 18:39:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
static ulong readmem64(ctx_t *ctx, ulong real, ulong addr)
|
2019-05-22 18:39:46 +02:00
|
|
|
{
|
2019-05-29 19:00:13 +02:00
|
|
|
CHK_ALIGN(ulong);
|
2019-05-22 18:39:46 +02:00
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
return (ulong)*(ulong *)(ctx->mp + real);
|
2019-05-22 18:39:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
//----------------------------------------------------------------------------//
|
2019-05-22 18:39:46 +02:00
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
static void writemem8(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
|
|
|
{
|
2019-07-24 16:52:26 +02:00
|
|
|
ctx->mp[real] = val & 0xFF;
|
2019-05-22 18:39:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
static void writemem16(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
2019-05-22 18:39:46 +02:00
|
|
|
{
|
2019-07-24 16:52:26 +02:00
|
|
|
*(ushort*)(ctx->mp + real) = val & 0xFFFF;
|
2019-05-22 18:39:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
static void writemem32(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
2019-05-22 18:39:46 +02:00
|
|
|
{
|
2019-05-29 19:00:13 +02:00
|
|
|
CHK_ALIGN(uint);
|
2019-05-22 18:39:46 +02:00
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
*(uint*)(ctx->mp + real) = val & 0xFFFFFFFF;
|
2019-05-22 18:39:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
static void writemem64(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
2019-05-22 18:39:46 +02:00
|
|
|
{
|
2019-05-29 19:00:13 +02:00
|
|
|
CHK_ALIGN(ulong);
|
2019-05-22 18:39:46 +02:00
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
*(ulong*)(ctx->mp + real) = val;
|
2019-05-22 18:39:46 +02:00
|
|
|
}
|
2019-05-29 16:57:22 +02:00
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
#define CHK_RANGE() \
|
|
|
|
if (addr < MEMOFF || real >= MEMSIZE) { \
|
|
|
|
_except(ctx, E_ACC, \
|
|
|
|
"Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GETREAL() \
|
2019-07-11 18:34:21 +02:00
|
|
|
ulong real = addr2real(addr + R(CR2))
|
2019-06-13 15:00:48 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
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)
|
2019-06-13 15:00:48 +02:00
|
|
|
{
|
|
|
|
GETREAL();
|
|
|
|
CHK_RANGE();
|
|
|
|
|
|
|
|
ulong val;
|
|
|
|
|
|
|
|
switch (len) {
|
|
|
|
case 1:
|
|
|
|
val = readmem8(ctx, real, addr);
|
2019-07-24 16:52:26 +02:00
|
|
|
val = (ulong)(long)(char)val;
|
2019-06-13 15:00:48 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
val = readmem16(ctx, real, addr);
|
2019-07-24 16:52:26 +02:00
|
|
|
val = (ulong)(long)(short)val;
|
2019-06-13 15:00:48 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
val = readmem32(ctx, real, addr);
|
2019-07-24 16:52:26 +02:00
|
|
|
val = (ulong)(long)(int)val;
|
2019-06-13 15:00:48 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
return readmem64(ctx, real, addr);
|
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
default: logerr("readmemsx() bad length %d!\n", len); abort();
|
2019-06-13 15:00:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
|
|
|
{
|
|
|
|
GETREAL();
|
|
|
|
CHK_RANGE();
|
|
|
|
|
2019-06-19 13:47:10 +02:00
|
|
|
// log("writemem: 0x%lX: 0x%lX (%d)\n", addr, val, len);
|
|
|
|
|
2019-06-13 15:00:48 +02:00
|
|
|
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;
|
2019-06-19 21:41:22 +02:00
|
|
|
default: logerr("writemem() bad length %d!\n", len); abort();
|
2019-06-13 15:00:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|