-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathMemory.cs
114 lines (96 loc) · 3.67 KB
/
Memory.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
109
110
111
112
113
114
using System;
using System.Runtime.InteropServices;
using System.IO;
using log4net;
using x86CS.Configuration;
namespace x86CS
{
public class Memory
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(Memory));
private static readonly byte[] memory;
public static bool LoggingEnabled = Logger.IsDebugEnabled;
public static bool A20 { get; set; }
public static byte[] MemoryArray { get { return memory; } }
static Memory()
{
memory = new byte[SystemConfig.Machine.MemorySize * 1024 * 1024];
}
public static void SegBlockWrite(ushort segment, ushort offset, byte[] buffer, int length)
{
var virtualPtr = (uint)((segment << 4) + offset);
Memory.BlockWrite(virtualPtr, buffer, length);
}
public static void BlockWrite(uint addr, byte[] buffer, int length)
{
if(LoggingEnabled)
Logger.Debug(String.Format("Block write {0:X} length {1:X} ends {2:X}", addr, length, addr + length));
Buffer.BlockCopy(buffer, 0, memory, (int)addr, length);
}
public static int BlockRead(uint addr, byte[] buffer, int length)
{
Buffer.BlockCopy(memory, (int)addr, buffer, 0, length);
if(LoggingEnabled)
Logger.Debug(String.Format("Block read {0:X} length {1:X} ends {2:X}", addr, length, addr + length));
return buffer.Length;
}
public static uint Read(uint addr, int size)
{
uint ret;
bool passedMem = false;
if (addr > MemoryArray.Length)
passedMem = true;
switch (size)
{
case 8:
if (passedMem)
ret = 0xff;
else
ret = memory[addr];
break;
case 16:
if (passedMem)
ret = 0xffff;
else
ret = (ushort)(memory[addr] | memory[addr + 1] << 8);
break;
default:
if (passedMem)
ret = 0xffffffff;
else
ret = (uint)(memory[addr] | memory[addr + 1] << 8 | memory[addr + 2] << 16 | memory[addr + 3] << 24);
break;
}
if(LoggingEnabled)
Logger.Debug(String.Format("Read {0} address {1:X} value {2:X}{3}", size, addr, ret, passedMem ? " (OverRead)" : ""));
return ret;
}
public static void Write(uint addr, uint value, int size)
{
if (addr > MemoryArray.Length)
{
if(LoggingEnabled)
Logger.Debug(String.Format("Write {0} address {1:X} value {2:X} (OverWrite, ignored)", size, addr, value));
return;
}
if (LoggingEnabled)
Logger.Debug(String.Format("Write {0} address {1:X} value {2:X}", size, addr, value));
switch (size)
{
case 8:
memory[addr] = (byte)value;
break;
case 16:
memory[addr] = (byte)value;
memory[addr + 1] = (byte)((ushort)value).GetHigh();
break;
default:
memory[addr] = (byte)value;
memory[addr + 1] = (byte)(value >> 8);
memory[addr + 2] = (byte)(value >> 16);
memory[addr + 3] = (byte)(value >> 24);
break;
}
}
}
}