-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBUS.cpp
157 lines (124 loc) · 4.6 KB
/
BUS.cpp
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#ifndef VM_Component_BUS
#define VM_Component_BUS
#ifndef MODE
#define Mode_Release 1
#define Mode_Debug 2
#define MODE Mode_Release
#endif
#if MODE == Mode_Debug
#include <stdio.h>
#endif
#include <stdint.h>
#include "HwError.hpp"
#include "Component.hpp"
#include "Memory.cpp"
namespace Component
{
const uint64_t MaxNumPeripherals = 256;
class Peripheral : public MemoryAccess
{
protected:
uint64_t startLocation;
uint64_t lengthLocation;
bool CheckAddressInRange( uint64_t index )
{
return ( index >= startLocation && ( index - startLocation < lengthLocation ) );
}
uint64_t TranslateAddress( uint64_t Address )
{
return Address - startLocation;
}
public:
bool CheckAccessibility( uint64_t index, uint64_t size ) override
{
return CheckAddressInRange( index ) && CheckAddressInRange( index + size - 1 );
}
void SetRange( uint64_t start, uint64_t length )
{
startLocation = start;
lengthLocation = length;
}
};
class BUS : public MemoryAccess
{
private:
Peripheral * lePeripherals[MaxNumPeripherals];
void ZeroPeripherals()
{
uint64_t iterator;
for( iterator = 0; iterator < MaxNumPeripherals; iterator++ )
{
lePeripherals[iterator] = NULL;
}
}
public:
BUS()
{
ZeroPeripherals();
}
Component_ID GetID() override
{
return Component_ID_Bus;
}
void AddPeripheral( Peripheral * newPeripheral, uint64_t slot )
{
this->SetLastHwError( HwError_NoError );
if( slot < MaxNumPeripherals )
lePeripherals[slot] = newPeripheral;
else
this->SetLastHwError( HwError_PeripheralOutOfRange );
}
uint8_t GetByte( uint64_t index ) override
{
this->SetLastHwError( HwError_NoError );
uint64_t iterator;
for( iterator = 0; iterator < MaxNumPeripherals; iterator++ )
{
if( (lePeripherals[iterator] != NULL) && (lePeripherals[iterator]->CheckAccessibility( index, sizeof(uint8_t) ) ) )
{
#if MODE == Mode_Debug
printf( "Accessed peripheral %ld for get byte at location %ld\n", iterator, index );
#endif
uint8_t result = lePeripherals[iterator]->GetByte(index);
this->SetLastHwError( lePeripherals[iterator]->LastHwError() );
return result;
}
}
SetLastHwError( HwError_UnknownAddress );
return 0;
}
void SetByte( uint64_t index, uint8_t val ) override
{
this->SetLastHwError( HwError_NoError );
uint64_t iterator;
for( iterator = 0; iterator < MaxNumPeripherals; iterator++ )
{
if( lePeripherals[iterator] != NULL )
if( lePeripherals[iterator]->CheckAccessibility( index, sizeof(uint8_t) ) )
{
#if MODE == Mode_Debug
printf( "Accessed peripheral %ld for set byte at location %ld\n", iterator, index );
#endif
lePeripherals[iterator]->SetByte( index, val );
this->SetLastHwError( lePeripherals[iterator]->LastHwError() );
return;
}
}
SetLastHwError( HwError_UnknownAddress );
}
// In this case, accessibility requires that the whole space is owned by a single peripheral.
bool CheckAccessibility( uint64_t index, uint64_t size ) override
{
this->SetLastHwError( HwError_NoError );
uint64_t iterator;
for( iterator = 0; iterator < MaxNumPeripherals; iterator++ )
{
if( lePeripherals[iterator] != nullptr )
if( lePeripherals[iterator]->CheckAccessibility( index, size ) )
return true;
}
return false;
}
};
};
#endif