kvisc/vm/pc/mem.c

183 lines
4.4 KiB
C
Raw Normal View History

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-08-03 19:01:12 +02:00
ulong readstr(ulong addr, ulong maxn, char *buf)
2019-07-10 17:17:45 +02:00
{
ulong orig_maxn = maxn;
for (; maxn > 0; buf++, addr++, maxn--) {
2019-08-03 19:01:12 +02:00
*buf = readmemzx(addr, 1) & 0xFF;
2019-07-10 17:17:45 +02:00
if (*buf == 0)
break;
}
*buf = 0;
return orig_maxn - maxn;
}
2019-08-03 19:01:12 +02:00
ulong writestr(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--) {
2019-08-03 19:01:12 +02:00
writemem(*str, addr, 1);
2019-06-26 21:25:59 +02:00
}
2019-08-03 19:01:12 +02:00
writemem(0, addr, 1);
2019-06-26 21:25:59 +02:00
return orig_maxn - maxn;
}
//----------------------------------------------------------------------------//
2019-08-21 16:57:32 +02:00
#ifdef _WANT_ALIGN
2019-05-29 19:00:13 +02:00
#define CHK_ALIGN(type) \
if (addr % alignof(type) > 0) { \
2019-08-03 19:01:12 +02:00
_except(E_ALI, \
2019-08-21 16:57:32 +02:00
"Non-aligned memory access: 0x%012lX (0x%012lX) by %lu vs %lu", \
addr, real, alignof(type) - (addr % alignof(type)), \
alignof(type)); \
2019-05-22 18:39:46 +02:00
}
2019-05-29 19:00:13 +02:00
2019-08-21 16:57:32 +02:00
#else
#define CHK_ALIGN(type)
#endif
2019-06-13 15:00:48 +02:00
//----------------------------------------------------------------------------//
2019-05-29 19:00:13 +02:00
2019-08-03 19:01:12 +02:00
static ulong readmem8(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-08-03 19:01:12 +02:00
static ulong readmem16(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-08-03 19:01:12 +02:00
static ulong readmem32(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-08-03 19:01:12 +02:00
static ulong readmem64(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-08-03 19:01:12 +02:00
static void writemem8(ulong val, ulong real, ulong addr)
2019-06-13 15:00:48 +02:00
{
2019-07-24 16:52:26 +02:00
ctx->mp[real] = val & 0xFF;
2019-05-22 18:39:46 +02:00
}
2019-08-03 19:01:12 +02:00
static void writemem16(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-08-03 19:01:12 +02:00
static void writemem32(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-08-03 19:01:12 +02:00
static void writemem64(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) { \
2019-08-03 19:01:12 +02:00
_except(E_ACC, \
2019-06-13 15:00:48 +02:00
"Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); \
}
#define GETREAL() \
2019-08-14 20:23:05 +02:00
ulong real = addr2real(addr + R(CR1))
2019-06-13 15:00:48 +02:00
//----------------------------------------------------------------------------//
2019-08-03 19:01:12 +02:00
ulong readmemzx(ulong addr, uint len)
2019-07-24 16:52:26 +02:00
{
GETREAL();
CHK_RANGE();
switch (len) {
2019-08-03 19:01:12 +02:00
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;
2019-07-24 16:52:26 +02:00
default: logerr("readmemzx() bad length %d!\n", len); abort();
}
}
2019-08-03 19:01:12 +02:00
ulong readmemsx(ulong addr, uint len)
2019-06-13 15:00:48 +02:00
{
GETREAL();
CHK_RANGE();
ulong val;
switch (len) {
case 1:
2019-08-03 19:01:12 +02:00
val = readmem8(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:
2019-08-03 19:01:12 +02:00
val = readmem16(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:
2019-08-03 19:01:12 +02:00
val = readmem32(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:
2019-08-03 19:01:12 +02:00
return readmem64(real, addr);
2019-06-13 15:00:48 +02:00
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;
}
2019-08-03 19:01:12 +02:00
void writemem(ulong val, ulong addr, uint len)
2019-06-13 15:00:48 +02:00
{
GETREAL();
CHK_RANGE();
switch (len) {
2019-08-03 19:01:12 +02:00
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;
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
}
}
//----------------------------------------------------------------------------//