-
Notifications
You must be signed in to change notification settings - Fork 0
/
execProg.m
110 lines (91 loc) · 3.11 KB
/
execProg.m
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
function execProg(name)
% Initialize registers
cpustate.regs = zeros(32, 1, 'int32');
cpustate.reg_hi = 0;
cpustate.reg_lo = 0;
cpustate.sockets = {};
% Initialize breakpoints
cpustate.breakpoints = [];
%cpustate.breakpoints(1) = hex2dec('40057c');
%cpustate.breakpoints(2) = hex2dec('400594');
%cpustate.breakpoints(3) = hex2dec('400584');
% Load the code page
cpustate.pages{1}.name = 'Code Segment';
cpustate.pages{1}.base_address = hex2dec('00400000');
cpustate.pages{1}.data = loadBinary([name '-code.bin'], '*uint8');
% Load the data page
cpustate.pages{2}.name = 'Data Segment';
cpustate.pages{2}.base_address = hex2dec('10010000');
cpustate.pages{2}.data = loadBinary([name '-data.bin'], '*uint8');
cpustate.pages{2}.data(10000000) = 0;
% Allocate a page for stack
cpustate.pages{3}.name = 'Stack';
cpustate.pages{3}.base_address = hex2dec('40000000');
cpustate.pages{3}.data = zeros(256 * 1024, 1, 'uint8');
% Initialize dynamic memory allocation state
cpustate.next_allocation_address = hex2dec('30000000');
% Begin execution at the start of the code page
cpustate.halted = 0;
cpustate.pc = cpustate.pages{1}.base_address;
cpustate.regs(Register.sp) = cpustate.pages{3}.base_address;
% Initialize callstack tracker
cpustate.callframes = [];
cpustate.loops = 0;
cpustate.dmpdelay = Inf;
start(timer('StartDelay', 0.01, 'TimerFcn', @executeCycle));
function executeCycle(~, ~)
for runs = 1:1000
instr = readMemory(cpustate, cpustate.pc, 4);
for i = 1:length(cpustate.breakpoints)
if cpustate.breakpoints(i) == cpustate.pc
break;
end
end
cpustate.loops = cpustate.loops + 1;
% Execute the next MIPS instruction
cpustate = execInstr(cpustate, instr);
if cpustate.loops >= cpustate.dmpdelay
dumpPageArray(cpustate);
dumpCalls(cpustate);
end
% Check if we're halted
if cpustate.halted
break;
end
end
if ~cpustate.halted
% Check if the GUI has requested us to stop
fid = fopen('shouldistop.txt');
if fid >= 0
% Delete the stop indicator
fclose(fid);
delete('shouldistop.txt');
else
% Start another 1000 cycles
start(timer('StartDelay', 0.01, 'TimerFcn', @executeCycle));
return;
end
end
disp('CPU halted!');
for j = 1:length(cpustate.sockets)
cpustate.sockets{j}.close();
end
cpustate.sockets = {};
end
end
function dumpPageArray(cpustate)
fprintf('Name\t\t\tBase\t\tLimit\t\tLength\n');
for i = 1:length(cpustate.pages)
page = cpustate.pages{i};
fprintf('%s\t0x%08x\t0x%08x\t%d\n', ...
page.name, ...
page.base_address, ...
page.base_address+length(page.data), ...
length(page.data));
end
end
function dumpCalls(cpustate)
for i = length(cpustate.callframes):-1:1
fprintf('0x%08x\n', cpustate.callframes(i));
end
end