-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdispatchSyscall.m
151 lines (150 loc) · 5.04 KB
/
dispatchSyscall.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
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
function cpustate = dispatchSyscall(cpustate)
% The syscall code is loaded into $v0
switch (cpustate.regs(Register.v0))
case 1
% print_int
fprintf('%d', cpustate.regs(Register.a0));
case 2
% print_float
disp('print_float is unsupported');
case 3
% print_double
disp('print_double is unsupported');
case 4
% print_string
fprintf('%s', readString(cpustate, cpustate.regs(Register.a0)));
case 5
% read_int
cpustate.regs(Register.v0) = input('');
case 6
% read_float
disp('read_float is unsupported');
case 7
% read_double
disp('read_double is unsupported');
case 8
% read_string
data = input('', 's');
cpustate = writeString(cpustate, cpustate.regs(Register.a0), ...
cpustate.regs(Register.a1), data);
case 9
% sbrk (memory allocation)
pageindex = length(cpustate.pages)+1;
cpustate.pages{pageindex}.name = 'Dynamic Allocation (sbrk)';
cpustate.pages{pageindex}.base_address = cpustate.next_allocation_address;
cpustate.pages{pageindex}.data = zeros(cpustate.regs(Register.a0), 1, 'uint8');
cpustate.next_allocation_address = cpustate.next_allocation_address + cpustate.regs(Register.a0);
cpustate.regs(Register.v0) = cpustate.pages{pageindex}.base_address;
case 10
% exit
exit(0);
case 11
% print_character
fprintf('%c', cpustate.regs(Register.a0));
case 12
% read_character
in = input('', 's');
if ~isempty(in)
cpustate.regs(Register.v0) = in(0);
end
case 13
% open
filename = readString(cpustate, cpustate.regs(Register.a0));
if cpustate.regs(Register.a1) == 0
mode = 'r';
else
mode = 'w';
end
a = fopen(filename, mode);
cpustate.regs(Register.v0) = a;
case 14
% read
readdata = fread(double(cpustate.regs(Register.a0)), cpustate.regs(Register.a2));
cpustate = writeBuffer(cpustate, cpustate.regs(Register.a1), length(readdata), readdata);
cpustate.regs(Register.v0) = length(readdata);
case 15
% write
fwrite(double(cpustate.regs(Register.a0)), ...
readBuffer(cpustate, cpustate.regs(Register.a1), cpustate.regs(Register.a2)));
cpustate.regs(Register.v0) = cpustate.regs(Register.a2);
case 16
% close
fclose(double(cpustate.regs(Register.a0)));
cpustate.regs(Register.v0) = 0;
case 17
% exit2
exit(cpustate.regs(Register.a0));
case 101
% sock_write
% socket fd in $a0
% buffer address in $a1
% max-len in $a2
% bytes written or -1 in $v1
fd = cpustate.regs(Register.a0);
buffAddr = cpustate.regs(Register.a1);
maxLen = cpustate.regs(Register.a2);
socket = cpustate.sockets{fd};
if maxLen > 0
bytes = readBuffer(cpustate, buffAddr, maxLen);
try
socket.getOutputStream().write(bytes);
cpustate.regs(Register.v1) = length(bytes);
catch
cpustate.regs(Register.v1) = -1;
end
else
cpustate.regs(Register.v1) = 0;
end
case 102
% sock_read
% socket fd in $a0
% buffer address in $a1
% max-len in $a2
% bytes read or -1 in $v1
fd = cpustate.regs(Register.a0);
buffAddr = cpustate.regs(Register.a1);
maxLen = cpustate.regs(Register.a2);
socket = cpustate.sockets{fd};
buff = [];
while length(buff) < maxLen && socket.getInputStream().available() > 0
buff = [buff socket.getInputStream().read()];
end
cpustate = writeBuffer(cpustate, buffAddr, length(buff), buff);
cpustate.regs(Register.v1) = length(buff);
case 103
% sock_close
% socket fd in $a0
fd = cpustate.regs(Register.a0);
socket = cpustate.sockets{fd};
socket.close();
case 110
% ssock_open
% put socket fd in $v1
import java.net.ServerSocket;
import java.net.InetSocketAddress;
port = cpustate.regs(Register.a0);
sock = ServerSocket();
sock.setReuseAddress(1);
sock.bind(InetSocketAddress(port));
[cpustate, fd] = addSocket(cpustate, sock);
cpustate.regs(Register.v1) = fd;
case 112
% ssock_accept
% server socket fd in $a0
% put client socket fd in $v1
fd = cpustate.regs(Register.a0);
server = cpustate.sockets{fd};
client = server.accept;
[cpustate, client_fd] = addSocket(cpustate, client);
cpustate.regs(Register.v1) = client_fd;
case 120
% sock_close_all
% close all open server sockets
for i = 1:length(cpustate.sockets)
cpustate.sockets{i}.close();
end
cpustate.sockets = {};
otherwise
fprintf('Invalid syscall index: %d\n', cpustate.regs(Register.v0));
end
end