-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathRamDevice.cs
108 lines (91 loc) · 2.83 KB
/
RamDevice.cs
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
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using M6502.IO;
namespace RAM
{
public class RamDevice : IDevice
{
private PinsState _pinsState;
private ushort _startAddress;
private ushort _endAddress;
private uint Size => (uint)(_endAddress - _startAddress + 1);
private byte[] _memory;
public bool Configure(PinsState pinsState, List<string> parameters)
{
_pinsState = pinsState;
if (parameters.Count < 2)
{
return false;
}
// Parse start address (required)
if (!ushort.TryParse(parameters[0].Replace("0x", ""), NumberStyles.HexNumber, null, out _startAddress))
{
return false;
}
// Parse end address (required)
if (!ushort.TryParse(parameters[1].Replace("0x", ""), NumberStyles.HexNumber, null, out _endAddress))
{
return false;
}
_memory = new byte[Size];
// Parse image file (optional)
if (parameters.Count > 2)
{
var imagePath = parameters[2];
if (!File.Exists(imagePath))
{
return false;
}
var atIndex = 0;
// Parse image start index (optional)
if (parameters.Count > 3)
{
if (!int.TryParse(parameters[3].Replace("0x", ""), NumberStyles.HexNumber, null, out atIndex))
{
return false;
}
}
var imageBytes = File.ReadAllBytes(imagePath);
Array.Copy(imageBytes, 0, _memory, atIndex, imageBytes.Length);
}
return true;
}
public void Process()
{
if (_pinsState.ReadWrite)
{
Read();
}
else
{
Write();
}
}
private void Read()
{
if (IsAddressValid(_pinsState.A))
{
var relativeAddress = GetRelativeAddress(_pinsState.A);
_pinsState.D |= _memory[relativeAddress];
}
}
private void Write()
{
if (IsAddressValid(_pinsState.A))
{
var relativeAddress = GetRelativeAddress(_pinsState.A);
_memory[relativeAddress] = _pinsState.D;
}
}
private bool IsAddressValid(ushort address)
{
return address >= _startAddress && address <= _endAddress;
}
private ushort GetRelativeAddress(ushort address)
{
return (ushort)(address - _startAddress);
}
}
}