This repository has been archived by the owner on Nov 22, 2023. It is now read-only.
forked from gek169/SISA64
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sisa64.h
134 lines (94 loc) · 3 KB
/
sisa64.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "be_encoder.h"
#include <string.h>
/*
system memory size in BYTES.
configured for 4 gigabytes
*/
#define SYS_MEMORY_SIZE 0x10000000
#define SYS_MEMORY_MASK 0x0FFFFFFF
/*memory for the implementation.
Due to the new mask implementation, we don't need the extra bytes at the end.
*/
extern uint8_t* sisa64_mem;
#ifdef __clang__
#define NOINLINE_THIS __attribute__ ((noinline))
#endif
#ifdef __GNUC__
#define NOINLINE_THIS __attribute__ ((noinline))
#endif
#ifdef __TINYC__
#define NOINLINE_THIS /*a comment*/
#endif
#ifndef NOINLINE_THIS
#define NOINLINE_THIS /*a comment*/
#endif
/*run the emulator*/
NOINLINE_THIS void sisa64_emulate();
/*interact with the device*/
NOINLINE_THIS uint64_t dev_read(uint64_t addr);
NOINLINE_THIS void dev_write(uint64_t addr, uint64_t val);
NOINLINE_THIS int di();
NOINLINE_THIS void dcl();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ISA helper functions to interact with memory.
// Note that in order for the mask to be effective,
// the mask must always be greater than 7.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
#define ADDR_VALIDATOR(l_off)\
addr = (((addr) & ~mask) == 0)*addr;\
if(l_off)addr = (((addr+l_off) & ~mask) == 0)*addr;
*/
/*
#define ADDR_VALIDATOR(l_off)\
if( (addr > mask) || ((addr + l_off) > mask) ) addr = 0;
*/
static inline uint64_t addr_validator(uint64_t addr, const uint64_t l_off, uint64_t max){
if( (addr > max) || ((addr + l_off) > max) ) return 0;
return addr;
}
/*
#define ADDR_VALIDATOR(l_off) (void);
*/
static inline uint8_t mread_u8(uint64_t addr, uint8_t* membase, uint64_t mask){
addr = addr_validator(addr, 0, mask);
return membase[addr];
}
static inline void mwrite_u8(uint64_t addr, uint8_t val, uint8_t* membase, uint64_t mask){
addr = addr_validator(addr, 0, mask);
membase[addr] = val;
}
//multi-byte reads and writes
static inline uint16_t mread_u16(uint64_t addr, uint8_t* membase, uint64_t mask){
uint16_t rv;
addr = addr_validator(addr, 1, mask);
memcpy(&rv, membase + (addr), 2);
return be_to_u16(rv);
}
static inline void mwrite_u16(uint64_t addr, uint16_t val, uint8_t* membase, uint64_t mask){
val = u16_to_be(val);
addr = addr_validator(addr, 1, mask);
memcpy(membase + (addr), &val, 2);
}
static inline uint32_t mread_u32(uint64_t addr, uint8_t* membase, uint64_t mask){
uint32_t rv;
addr = addr_validator(addr, 3, mask);
memcpy(&rv, membase + (addr), 4);
return be_to_u32(rv);
}
static inline void mwrite_u32(uint64_t addr, uint32_t val, uint8_t* membase, uint64_t mask){
val = u32_to_be(val);
addr = addr_validator(addr, 3, mask);
memcpy(membase + (addr), &val, 4);
}
static inline uint64_t mread_u64(uint64_t addr, uint8_t* membase, uint64_t mask){
uint64_t rv;
addr = addr_validator(addr, 7, mask);
memcpy(&rv, membase + (addr), 8);
return be_to_u64(rv);
}
static inline void mwrite_u64(uint64_t addr, uint64_t val, uint8_t* membase, uint64_t mask){
val = u64_to_be(val);
addr = addr_validator(addr, 7, mask);
memcpy(membase + (addr), &val, 8);
}