mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
160 lines
4.2 KiB
C
160 lines
4.2 KiB
C
// 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();
|
|
}
|
|
}
|
|
|
|
ulong readmem8(ctx_t *ctx, ulong addr)
|
|
{
|
|
ulong real = addr2real(addr);
|
|
|
|
if (addr < MEMOFF || real >= MEMSIZE) {
|
|
_except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
if (addr % 2) return (ulong)ctx->mp[real] & 0xFF;
|
|
else return ((ulong)ctx->mp[real] & 0xFF00) >> 8;
|
|
}
|
|
|
|
ulong readmem16(ctx_t *ctx, ulong addr)
|
|
{
|
|
ulong real = addr2real(addr);
|
|
|
|
if (addr % alignof(ushort) > 0) {
|
|
_except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
if (addr < MEMOFF || real >= MEMSIZE) {
|
|
_except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
return (ulong)ctx->mp[real];
|
|
}
|
|
|
|
ulong readmem32(ctx_t *ctx, ulong addr)
|
|
{
|
|
ulong real = addr2real(addr);
|
|
|
|
if (addr % alignof(uint) > 0) {
|
|
_except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
if (addr < MEMOFF || real >= MEMSIZE) {
|
|
_except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
ulong val = (ulong)ctx->mp[real++];
|
|
val = (val << 16) | (ulong)ctx->mp[real];
|
|
|
|
return val;
|
|
}
|
|
|
|
ulong readmem64(ctx_t *ctx, ulong addr)
|
|
{
|
|
ulong real = addr2real(addr);
|
|
|
|
if (addr % alignof(ulong) > 0) {
|
|
_except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
if (addr < MEMOFF || real >= MEMSIZE) {
|
|
_except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
ulong val = (ulong)ctx->mp[real++];
|
|
val = (val << 16) | (ulong)ctx->mp[real++];
|
|
val = (val << 16) | (ulong)ctx->mp[real++];
|
|
val = (val << 16) | (ulong)ctx->mp[real];
|
|
|
|
return val;
|
|
}
|
|
|
|
void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
|
{
|
|
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();
|
|
}
|
|
}
|
|
|
|
void writemem8(ctx_t *ctx, ulong val, ulong addr)
|
|
{
|
|
ulong real = addr2real(addr);
|
|
|
|
if (addr < MEMOFF || real >= MEMSIZE) {
|
|
_except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
ushort v = ctx->mp[real];
|
|
|
|
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)
|
|
{
|
|
ulong real = addr2real(addr);
|
|
|
|
if (addr % alignof(ushort) > 0) {
|
|
_except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
if (addr < MEMOFF || real >= MEMSIZE) {
|
|
_except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
ctx->mp[real] = val & 0xFFFF;
|
|
}
|
|
|
|
void writemem32(ctx_t *ctx, ulong val, ulong addr)
|
|
{
|
|
ulong real = addr2real(addr);
|
|
|
|
if (addr % alignof(uint) > 0) {
|
|
_except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
if (addr < MEMOFF || real >= MEMSIZE) {
|
|
_except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
ctx->mp[real++] = (val >> 16) & 0xFFFF;
|
|
ctx->mp[real] = val & 0xFFFF;
|
|
}
|
|
|
|
void writemem64(ctx_t *ctx, ulong val, ulong addr)
|
|
{
|
|
ulong real = addr2real(addr);
|
|
|
|
if (addr % alignof(ulong) > 0) {
|
|
_except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
if (addr < MEMOFF || real >= MEMSIZE) {
|
|
_except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real);
|
|
}
|
|
|
|
ctx->mp[real++] = val >> 48;
|
|
ctx->mp[real++] = (val >> 32) & 0xFFFF;
|
|
ctx->mp[real++] = (val >> 16) & 0xFFFF;
|
|
ctx->mp[real] = val & 0xFFFF;
|
|
}
|