110 lines
3.5 KiB
C
110 lines
3.5 KiB
C
#pragma once
|
|
|
|
#include <stddef.h>
|
|
#include <assert.h>
|
|
|
|
#include "state.h"
|
|
#include "memory_map.h"
|
|
#include "status_bits.h"
|
|
|
|
static inline bool is_delay_slot(struct architectural_state * state)
|
|
{
|
|
return state->is_delay_slot;
|
|
}
|
|
|
|
static inline struct sr_bits _sr_bits(uint32_t sr)
|
|
{
|
|
union {
|
|
struct sr_bits bits;
|
|
uint32_t value;
|
|
} sr_union;
|
|
sr_union.value = sr;
|
|
return sr_union.bits;
|
|
}
|
|
|
|
static inline bool fpu_is_disabled(uint32_t sr)
|
|
{
|
|
return _sr_bits(sr).fd;
|
|
}
|
|
|
|
static inline void sleep(struct architectural_state * state)
|
|
{
|
|
}
|
|
|
|
static inline void ocbp(struct architectural_state * state, uint32_t address)
|
|
{
|
|
}
|
|
|
|
static inline uint8_t read_memory8(struct memory_map * map, uint32_t address)
|
|
{
|
|
struct memory_map_entry * entry = find_entry(map, address);
|
|
if (entry == NULL) return 0;
|
|
uint32_t relative_address = physical_address(address) - entry->start;
|
|
return entry->access.read_memory8(entry->mem, relative_address);
|
|
}
|
|
|
|
static inline uint16_t read_memory16(struct memory_map * map, uint32_t address)
|
|
{
|
|
assert((address & 0b1) == 0);
|
|
struct memory_map_entry * entry = find_entry(map, address);
|
|
if (entry == NULL) return 0;
|
|
uint32_t relative_address = physical_address(address) - entry->start;
|
|
return entry->access.read_memory16(entry->mem, relative_address);
|
|
}
|
|
|
|
static inline uint32_t read_memory32(struct memory_map * map, uint32_t address)
|
|
{
|
|
assert((address & 0b11) == 0);
|
|
struct memory_map_entry * entry = find_entry(map, address);
|
|
if (entry == NULL) return 0;
|
|
uint32_t relative_address = physical_address(address) - entry->start;
|
|
return entry->access.read_memory32(entry->mem, relative_address);
|
|
}
|
|
|
|
static inline uint64_t read_memory_pair32(struct memory_map * map, uint32_t address)
|
|
{
|
|
assert((address & 0b111) == 0);
|
|
struct memory_map_entry * entry = find_entry(map, address);
|
|
if (entry == NULL) return 0;
|
|
uint32_t relative_address = physical_address(address) - entry->start;
|
|
uint64_t low = entry->access.read_memory32(entry->mem, relative_address);
|
|
uint64_t high = entry->access.read_memory32(entry->mem, relative_address+4);
|
|
return (high << 32) | (low << 0);
|
|
}
|
|
|
|
static inline void write_memory8(struct memory_map * map, uint32_t address, uint8_t value)
|
|
{
|
|
struct memory_map_entry * entry = find_entry(map, address);
|
|
if (entry == NULL) return;
|
|
uint32_t relative_address = physical_address(address) - entry->start;
|
|
entry->access.write_memory8(entry->mem, relative_address, value);
|
|
}
|
|
|
|
static inline void write_memory16(struct memory_map * map, uint32_t address, uint16_t value)
|
|
{
|
|
assert((address & 0b1) == 0);
|
|
struct memory_map_entry * entry = find_entry(map, address);
|
|
if (entry == NULL) return;
|
|
uint32_t relative_address = physical_address(address) - entry->start;
|
|
entry->access.write_memory16(entry->mem, relative_address, value);
|
|
}
|
|
|
|
static inline void write_memory32(struct memory_map * map, uint32_t address, uint32_t value)
|
|
{
|
|
assert((address & 0b11) == 0);
|
|
struct memory_map_entry * entry = find_entry(map, address);
|
|
if (entry == NULL) return;
|
|
uint32_t relative_address = physical_address(address) - entry->start;
|
|
entry->access.write_memory32(entry->mem, relative_address, value);
|
|
}
|
|
|
|
static inline void write_memory_pair32(struct memory_map * map, uint32_t address, uint64_t value)
|
|
{
|
|
assert((address & 0b111) == 0);
|
|
struct memory_map_entry * entry = find_entry(map, address);
|
|
if (entry == NULL) return;
|
|
uint32_t relative_address = physical_address(address) - entry->start;
|
|
entry->access.write_memory32(entry->mem, relative_address, (value >> 0 ));
|
|
entry->access.write_memory32(entry->mem, relative_address+4, (value >> 32));
|
|
}
|