2023-01-20 10:23:53 -05:00
do
local orig_require , loaded , retval , source = _G.require , { } , { } , { [ ' chat ' ] = [ = [ local Device = require ( ' device ' )
local system_device
do
local c = Device : new ( )
c.name = ' system '
c : addPort ( 2 , false , function ( self )
return self.cpu . program_stack : len ( )
end )
c : addPort ( 3 , false , function ( self )
return self.cpu . return_stack : len ( )
end )
system_device = c
end
local console_device
do
local c = Device : new ( )
c.name = ' console '
c : addPort ( 8 , false , nil , function ( self , byte )
return table.insert ( self.stdout , byte )
end )
c : addPort ( 9 , false , nil , function ( self , byte )
return table.insert ( self.stderr , byte )
end )
console_device = c
end
local datetime_device
do
local dt = Device : new ( )
dt.name = ' datetime '
dt : addPort ( 0 , true , function ( self )
return tonumber ( os.date ( ' !%Y ' ) )
end )
dt : addPort ( 2 , false , function ( self )
return tonumber ( os.date ( ' !%m ' ) ) - 1
end )
dt : addPort ( 3 , false , function ( self )
return tonumber ( os.date ( ' !%d ' ) )
end )
dt : addPort ( 4 , false , function ( self )
return tonumber ( os.date ( ' !%H ' ) )
end )
dt : addPort ( 5 , false , function ( self )
return tonumber ( os.date ( ' !%M ' ) )
end )
dt : addPort ( 6 , false , function ( self )
return tonumber ( os.date ( ' !%S ' ) )
end )
dt : addPort ( 7 , false , function ( self )
return tonumber ( os.date ( ' !%u ' ) ) % 7
end )
dt : addPort ( 8 , true , function ( self )
return tonumber ( os.date ( ' !%j ' ) ) - 1
end )
dt : addPort ( 10 , true , function ( self )
return 0
end )
datetime_device = dt
end
local Uxn
do
local m = require ( ' uxn ' )
Uxn = function ( )
local u = m.Uxn : new ( )
u : addDevice ( 0x0 , system_device )
u : addDevice ( 0x1 , console_device )
u : addDevice ( 0xb , datetime_device )
return u
end
end
local load_memory
do
local mem_mt = {
__index = function ( self , k )
return 0
end
}
load_memory = function ( u , t )
u.memory = setmetatable ( ( function ( )
local _tbl_0 = { }
for i , v in ipairs ( t ) do
_tbl_0 [ i + 255 ] = v
end
return _tbl_0
end ) ( ) , mem_mt )
end
end
local load_source
load_source = function ( u , s )
for i = 1 , # s do
u.memory [ i + 0xdfff ] = s : byte ( i , i )
end
end
local u = Uxn ( )
local asma_rom = {
2023-12-29 15:48:26 -05:00
160 , 12 , 215 , 160 , 7 , 119 , 53 , 160 , 3 , 177 , 46 , 160 , 7 , 75 , 160 , 5 , 93 , 53 ,
2023-01-20 10:23:53 -05:00
160 , 240 , 0 , 160 , 224 , 0 , 185 , 160 , 4 , 195 , 46 , 34 , 34 , 160 , 5 , 99 , 52 , 29 ,
128 , 48 , 13 , 0 , 160 , 3 , 230 , 46 , 160 , 240 , 0 , 160 , 224 , 0 , 185 , 160 , 4 ,
195 , 46 , 34 , 34 , 160 , 5 , 99 , 52 , 29 , 128 , 22 , 13 , 128 , 79 , 128 , 24 , 23 ,
2023-12-29 15:48:26 -05:00
128 , 75 , 128 , 24 , 23 , 160 , 7 , 73 , 52 , 4 , 128 , 24 , 23 , 128 , 24 , 23 , 0 , 160 ,
2023-01-20 10:23:53 -05:00
5 , 99 , 52 , 160 , 3 , 108 , 46 , 128 , 58 , 128 , 25 , 23 , 128 , 32 , 128 , 25 , 23 ,
160 , 5 , 87 , 52 , 160 , 3 , 108 , 46 , 128 , 46 , 128 , 25 , 23 , 0 , 0 , 128 , 1 , 128 ,
167 , 23 , 38 , 128 , 168 , 55 , 128 , 1 , 128 , 166 , 23 , 160 , 5 , 97 , 53 , 160 , 5 ,
2023-12-29 15:48:26 -05:00
95 , 53 , 160 , 3 , 177 , 46 , 160 , 7 , 75 , 160 , 5 , 93 , 53 , 160 , 5 , 95 , 52 , 160 ,
4 , 57 , 46 , 160 , 5 , 99 , 52 , 29 , 128 , 71 , 13 , 160 , 3 , 230 , 46 , 160 , 7 , 77 ,
160 , 5 , 93 , 53 , 160 , 5 , 97 , 52 , 29 , 128 , 7 , 13 , 160 , 7 , 94 , 160 , 5 , 93 , 53 ,
2023-01-20 10:23:53 -05:00
160 , 5 , 95 , 52 , 160 , 4 , 57 , 46 , 160 , 5 , 99 , 52 , 29 , 128 , 29 , 13 , 160 , 7 ,
2023-12-29 15:48:26 -05:00
73 , 52 , 160 , 240 , 0 , 57 , 160 , 5 , 93 , 52 , 46 , 160 , 5 , 102 , 160 , 3 , 12 , 46 ,
2023-01-20 10:23:53 -05:00
160 , 2 , 65 , 46 , 160 , 2 , 118 , 46 , 108 , 160 , 1 , 245 , 46 , 108 , 128 , 168 , 54 ,
160 , 3 , 108 , 46 , 160 , 2 , 58 , 160 , 3 , 108 , 46 , 160 , 5 , 78 , 52 , 160 , 3 , 123 ,
46 , 128 , 58 , 128 , 25 , 23 , 128 , 32 , 128 , 25 , 23 , 160 , 5 , 99 , 52 , 160 , 3 ,
108 , 46 , 128 , 58 , 128 , 25 , 23 , 128 , 32 , 128 , 25 , 23 , 160 , 5 , 87 , 52 , 160 ,
3 , 108 , 46 , 128 , 46 , 128 , 25 , 23 , 128 , 10 , 128 , 25 , 23 , 108 , 32 , 108 , 105 ,
110 , 101 , 32 , 0 , 160 , 5 , 101 , 20 , 128 , 1 , 28 , 128 , 0 , 8 , 128 , 15 , 13 , 160 ,
5 , 80 , 52 , 160 , 3 , 123 , 46 , 160 , 2 , 94 , 160 , 3 , 108 , 46 , 108 , 32 , 108 , 105 ,
110 , 101 , 115 , 32 , 111 , 102 , 32 , 115 , 111 , 117 , 114 , 99 , 101 , 32 , 99 , 111 ,
100 , 101 , 46 , 10 , 0 , 160 , 5 , 101 , 20 , 128 , 8 , 28 , 128 , 0 , 8 , 128 , 38 , 13 ,
2023-12-29 15:48:26 -05:00
160 , 7 , 119 , 52 , 160 , 12 , 215 , 57 , 160 , 3 , 123 , 46 , 160 , 2 , 170 , 160 , 3 ,
108 , 46 , 160 , 224 , 0 , 160 , 7 , 119 , 52 , 57 , 160 , 3 , 123 , 46 , 160 , 2 , 192 ,
2023-01-20 10:23:53 -05:00
160 , 3 , 108 , 46 , 108 , 32 , 98 , 121 , 116 , 101 , 115 , 32 , 111 , 102 , 32 , 104 ,
101 , 97 , 112 , 32 , 117 , 115 , 101 , 100 , 44 , 32 , 0 , 32 , 98 , 121 , 116 , 101 ,
115 , 32 , 102 , 114 , 101 , 101 , 46 , 10 , 0 , 52 , 157 , 128 , 2 , 13 , 34 , 108 , 38 ,
128 , 245 , 14 , 128 , 9 , 128 , 25 , 23 , 38 , 160 , 0 , 4 , 56 , 38 , 33 , 36 , 20 , 6 ,
128 , 0 , 8 , 128 , 6 , 13 , 128 , 25 , 23 , 128 , 239 , 12 , 2 , 128 , 9 , 128 , 25 , 23 ,
52 , 160 , 3 , 123 , 46 , 128 , 10 , 128 , 25 , 23 , 160 , 0 , 2 , 56 , 128 , 195 , 14 ,
108 , 160 , 5 , 101 , 20 , 128 , 4 , 28 , 128 , 0 , 8 , 128 , 5 , 13 , 52 , 157 , 128 , 2 ,
13 , 34 , 108 , 38 , 128 , 232 , 14 , 38 , 160 , 0 , 4 , 56 , 148 , 128 , 65 , 11 , 128 ,
11 , 13 , 148 , 128 , 90 , 10 , 128 , 4 , 13 , 34 , 128 , 41 , 12 , 38 , 33 , 36 , 20 , 6 ,
128 , 0 , 8 , 128 , 6 , 13 , 128 , 25 , 23 , 128 , 239 , 12 , 2 , 128 , 9 , 128 , 25 , 23 ,
180 , 160 , 3 , 123 , 46 , 128 , 10 , 128 , 25 , 23 , 160 , 0 , 2 , 56 , 160 , 2 , 206 , 46 ,
160 , 0 , 2 , 56 , 128 , 161 , 14 , 108 , 148 , 6 , 128 , 3 , 13 , 2 , 34 , 108 , 128 , 25 ,
23 , 33 , 128 , 241 , 12 , 128 , 48 , 128 , 25 , 23 , 128 , 120 , 128 , 25 , 23 , 7 , 128 ,
4 , 31 , 128 , 20 , 14 , 4 , 128 , 15 , 28 , 128 , 13 , 14 , 6 , 128 , 4 , 31 , 128 , 6 , 14 ,
128 , 15 , 28 , 128 , 0 , 12 , 128 , 48 , 24 , 6 , 128 , 58 , 11 , 128 , 3 , 13 , 128 , 39 ,
2023-12-29 15:48:26 -05:00
24 , 128 , 25 , 23 , 108 , 160 , 34 , 2 , 30 , 160 , 6 , 192 , 21 , 160 , 66 , 2 , 30 , 160 ,
6 , 206 , 21 , 160 , 130 , 2 , 30 , 160 , 6 , 218 , 21 , 128 , 255 , 160 , 5 , 76 , 21 ,
2023-01-20 10:23:53 -05:00
160 , 0 , 0 , 166 , 160 , 5 , 99 , 53 , 160 , 5 , 102 , 53 , 160 , 5 , 104 , 53 , 160 , 11 ,
215 , 160 , 5 , 106 , 53 , 160 , 5 , 76 , 20 , 1 , 160 , 5 , 76 , 21 , 160 , 240 , 0 , 160 ,
2023-12-29 15:48:26 -05:00
7 , 73 , 53 , 160 , 1 , 0 , 38 , 6 , 160 , 5 , 77 , 21 , 160 , 5 , 89 , 53 , 160 , 5 , 91 ,
2023-01-20 10:23:53 -05:00
53 , 160 , 4 , 57 , 160 , 4 , 21 , 185 , 160 , 4 , 195 , 46 , 34 , 34 , 108 , 37 , 66 , 82 ,
75 , 32 , 123 , 32 , 48 , 48 , 32 , 125 , 32 , 37 , 91 , 32 , 123 , 32 , 125 , 32 , 37 , 93 ,
32 , 123 , 32 , 125 , 32 , 64 , 111 , 110 , 45 , 114 , 101 , 115 , 101 , 116 , 32 , 160 ,
4 , 195 , 160 , 0 , 0 , 37 , 160 , 224 , 0 , 38 , 160 , 240 , 0 , 37 , 57 , 37 , 128 , 14 ,
14 , 160 , 5 , 99 , 52 , 29 , 128 , 0 , 13 , 34 , 34 , 34 , 34 , 34 , 108 , 160 , 0 , 0 , 38 ,
37 , 47 , 37 , 239 , 128 , 168 , 55 , 175 , 128 , 50 , 51 , 47 , 175 , 128 , 48 , 51 , 38 ,
128 , 78 , 51 , 128 , 37 , 14 , 36 , 165 , 35 , 39 , 128 , 172 , 55 , 128 , 162 , 54 , 36 ,
46 , 37 , 36 , 185 , 35 , 157 , 128 , 6 , 13 , 34 , 98 , 98 , 111 , 111 , 108 , 111 , 36 ,
171 , 12 , 97 , 57 , 111 , 111 , 128 , 199 , 12 , 160 , 0 , 0 , 160 , 0 , 0 , 170 , 128 ,
15 , 13 , 39 , 128 , 170 , 55 , 128 , 21 , 50 , 128 , 172 , 55 , 39 , 57 , 128 , 237 , 12 ,
128 , 170 , 55 , 128 , 7 , 50 , 128 , 172 , 55 , 128 , 170 , 55 , 108 , 0 , 0 , 37 , 47 ,
39 , 56 , 39 , 160 , 224 , 0 , 40 , 15 , 38 , 160 , 240 , 0 , 41 , 79 , 28 , 160 , 5 , 83 ,
21 , 36 , 175 , 148 , 128 , 33 , 11 , 128 , 4 , 13 , 33 , 128 , 245 , 12 , 170 , 128 , 13 ,
13 , 160 , 5 , 83 , 20 , 128 , 77 , 13 , 34 , 34 , 111 , 111 , 36 , 108 , 148 , 128 , 10 ,
9 , 128 , 0 , 39 , 21 , 111 , 128 , 108 , 14 , 160 , 5 , 99 , 52 , 29 , 128 , 38 , 13 , 128 ,
7 , 13 , 128 , 64 , 50 , 33 , 128 , 60 , 51 , 160 , 5 , 82 , 20 , 128 , 5 , 13 , 33 , 175 ,
128 , 186 , 12 , 160 , 5 , 82 , 20 , 128 , 1 , 25 , 160 , 5 , 82 , 21 , 33 , 35 , 111 , 36 ,
108 , 2 , 34 , 34 , 239 , 160 , 5 , 78 , 53 , 111 , 160 , 224 , 0 , 108 , 34 , 128 , 0 , 5 ,
5 , 21 , 111 , 128 , 39 , 14 , 111 , 160 , 224 , 0 , 108 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
38 , 160 , 5 , 85 , 53 , 38 , 160 , 5 , 87 , 53 , 148 , 128 , 2 , 13 , 34 , 108 , 33 , 175 ,
212 , 175 , 192 , 0 , 47 , 85 , 128 , 0 , 160 , 5 , 77 , 20 , 153 , 28 , 38 , 160 , 5 , 171 ,
2023-12-29 15:48:26 -05:00
56 , 160 , 6 , 66 , 46 , 85 , 128 , 8 , 13 , 111 , 160 , 5 , 85 , 53 , 35 , 52 , 44 , 34 ,
98 , 160 , 5 , 177 , 56 , 52 , 44 , 11 , 127 , 11 , 7 , 11 , 31 , 10 , 18 , 7 , 192 , 8 , 52 ,
6 , 128 , 58 , 11 , 128 , 8 , 13 , 6 , 128 , 96 , 10 , 128 , 5 , 13 , 108 , 128 , 48 , 25 ,
108 , 128 , 87 , 25 , 108 , 15 , 160 , 5 , 85 , 52 , 38 , 128 , 92 , 14 , 6 , 79 , 28 , 128 ,
60 , 13 , 38 , 160 , 0 , 4 , 42 , 128 , 52 , 13 , 157 , 128 , 0 , 8 , 128 , 45 , 13 , 160 ,
0 , 2 , 42 , 5 , 5 , 224 , 0 , 0 , 148 , 6 , 128 , 9 , 13 , 2 , 34 , 111 , 5 , 1 , 134 , 24 ,
24 , 108 , 128 , 177 , 14 , 6 , 128 , 240 , 28 , 128 , 11 , 13 , 192 , 64 , 127 , 192 , 0 ,
15 , 120 , 33 , 128 , 221 , 12 , 98 , 34 , 34 , 128 , 0 , 108 , 47 , 128 , 7 , 12 , 25 ,
128 , 10 , 141 , 34 , 33 , 97 , 148 , 212 , 79 , 157 , 128 , 242 , 13 , 111 , 36 , 108 ,
224 , 0 , 0 , 128 , 2 , 12 , 33 , 97 , 148 , 128 , 250 , 13 , 34 , 111 , 108 , 160 , 5 , 85 ,
52 , 47 , 180 , 29 , 128 , 4 , 13 , 98 , 128 , 1 , 108 , 52 , 38 , 160 , 0 , 4 , 56 , 239 ,
128 , 196 , 14 , 128 , 8 , 13 , 2 , 34 , 33 , 35 , 98 , 128 , 0 , 108 , 128 , 128 , 28 ,
128 , 6 , 31 , 128 , 0 , 4 , 47 , 34 , 34 , 111 , 56 , 128 , 209 , 12 , 160 , 5 , 85 , 52 ,
38 , 128 , 181 , 14 , 160 , 0 , 3 , 43 , 128 , 91 , 13 , 160 , 0 , 3 , 56 , 175 , 212 , 175 ,
192 , 0 , 47 , 85 , 160 , 5 , 106 , 160 , 6 , 66 , 46 , 85 , 128 , 68 , 13 , 160 , 11 , 219 ,
57 , 128 , 3 , 63 , 6 , 128 , 0 , 8 , 128 , 48 , 13 , 212 , 79 , 224 , 0 , 1 , 120 , 6 , 128 ,
4 , 13 , 2 , 98 , 4 , 108 , 6 , 128 , 50 , 9 , 128 , 7 , 13 , 2 , 128 , 0 , 29 , 128 , 228 ,
12 , 6 , 128 , 114 , 9 , 128 , 7 , 13 , 2 , 128 , 0 , 29 , 128 , 214 , 12 , 128 , 107 , 9 ,
128 , 6 , 13 , 128 , 0 , 29 , 128 , 202 , 12 , 98 , 34 , 128 , 1 , 108 , 128 , 128 , 128 ,
17 , 14 , 128 , 14 , 14 , 108 , 160 , 5 , 89 , 180 , 37 , 56 , 36 , 53 , 108 , 4 , 128 , 0 ,
14 , 160 , 5 , 89 , 52 , 160 , 5 , 91 , 52 , 171 , 128 , 13 , 13 , 168 , 128 , 20 , 13 ,
128 , 0 , 128 , 26 , 14 , 33 , 128 , 243 , 12 , 160 , 10 , 222 , 160 , 5 , 99 , 53 , 34 ,
34 , 2 , 108 , 34 , 33 , 38 , 160 , 5 , 89 , 53 , 160 , 5 , 91 , 53 , 128 , 29 , 50 , 38 ,
160 , 255 , 255 , 40 , 128 , 8 , 13 , 175 , 21 , 111 , 33 , 128 , 14 , 51 , 108 , 160 ,
2023-01-20 10:23:53 -05:00
240 , 0 , 185 , 160 , 5 , 93 , 52 , 46 , 35 , 128 , 235 , 12 , 0 , 0 , 34 , 108 , 128 , 170 ,
55 , 160 , 5 , 97 , 52 , 128 , 168 , 55 , 160 , 240 , 0 , 128 , 174 , 55 , 108 , 157 , 128 ,
2 , 13 , 34 , 108 , 160 , 240 , 0 , 38 , 37 , 56 , 36 , 148 , 128 , 24 , 23 , 33 , 170 ,
128 , 247 , 13 , 34 , 34 , 108 , 0 , 0 , 128 , 251 , 50 , 161 , 128 , 247 , 51 , 21 , 108 ,
128 , 242 , 50 , 161 , 33 , 128 , 237 , 51 , 53 , 108 , 47 , 128 , 231 , 50 , 128 , 1 , 12 ,
97 , 212 , 70 , 175 , 85 , 33 , 192 , 247 , 77 , 98 , 128 , 215 , 51 , 108 , 160 , 5 , 85 ,
2023-12-29 15:48:26 -05:00
52 , 160 , 6 , 51 , 46 , 29 , 128 , 19 , 13 , 160 , 5 , 84 , 148 , 1 , 5 , 5 , 21 , 160 , 5 ,
77 , 20 , 128 , 2 , 29 , 160 , 5 , 77 , 21 , 108 , 160 , 5 , 85 , 52 , 160 , 6 , 51 , 46 ,
2023-01-20 10:23:53 -05:00
29 , 128 , 243 , 13 , 160 , 5 , 84 , 148 , 128 , 1 , 25 , 6 , 36 , 21 , 128 , 230 , 13 ,
2023-12-29 15:48:26 -05:00
160 , 5 , 77 , 20 , 128 , 12 , 28 , 160 , 5 , 77 , 21 , 108 , 160 , 5 , 76 , 20 , 128 , 59 ,
13 , 160 , 5 , 104 , 160 , 6 , 66 , 46 , 128 , 9 , 13 , 34 , 160 , 10 , 201 , 160 , 5 , 99 ,
53 , 108 , 160 , 7 , 119 , 52 , 36 , 53 , 160 , 0 , 0 , 160 , 7 , 130 , 46 , 160 , 0 , 0 ,
160 , 7 , 130 , 46 , 160 , 5 , 85 , 52 , 160 , 7 , 140 , 46 , 160 , 5 , 77 , 20 , 128 , 4 ,
29 , 160 , 5 , 77 , 21 , 108 , 160 , 5 , 77 , 20 , 128 , 12 , 29 , 160 , 5 , 77 , 21 , 108 ,
160 , 5 , 77 , 20 , 128 , 8 , 28 , 128 , 8 , 13 , 160 , 5 , 85 , 52 , 160 , 7 , 140 , 46 ,
108 , 128 , 0 , 160 , 7 , 121 , 46 , 160 , 5 , 77 , 20 , 128 , 2 , 28 , 160 , 5 , 77 , 21 ,
108 , 160 , 5 , 102 , 128 , 29 , 14 , 128 , 7 , 13 , 160 , 0 , 0 , 160 , 7 , 130 , 46 , 160 ,
0 , 2 , 56 , 160 , 5 , 108 , 53 , 108 , 160 , 5 , 108 , 52 , 128 , 3 , 14 , 2 , 34 , 108 ,
160 , 6 , 66 , 46 , 128 , 19 , 13 , 180 , 160 , 5 , 89 , 52 , 40 , 128 , 7 , 13 , 160 , 10 ,
239 , 160 , 5 , 99 , 53 , 128 , 1 , 108 , 160 , 7 , 119 , 52 , 36 , 53 , 160 , 0 , 0 , 160 ,
7 , 130 , 46 , 160 , 0 , 0 , 160 , 7 , 130 , 46 , 160 , 5 , 85 , 52 , 160 , 7 , 140 , 46 ,
160 , 7 , 119 , 52 , 160 , 5 , 89 , 52 , 160 , 7 , 130 , 46 , 128 , 0 , 108 , 160 , 0 , 0 ,
160 , 5 , 89 , 53 , 128 , 0 , 160 , 5 , 206 , 46 , 128 , 8 , 13 , 160 , 10 , 118 , 160 , 5 ,
99 , 53 , 108 , 160 , 6 , 237 , 44 , 160 , 5 , 85 , 52 , 148 , 6 , 128 , 3 , 13 , 2 , 34 ,
108 , 160 , 6 , 250 , 46 , 33 , 128 , 240 , 12 , 128 , 160 , 160 , 6 , 250 , 46 , 128 ,
121 , 14 , 160 , 6 , 246 , 44 , 128 , 128 , 160 , 6 , 250 , 46 , 128 , 108 , 14 , 160 , 6 ,
250 , 46 , 128 , 1 , 13 , 108 , 160 , 5 , 76 , 20 , 128 , 0 , 8 , 160 , 5 , 99 , 52 , 29 ,
29 , 128 , 7 , 13 , 160 , 10 , 138 , 160 , 5 , 99 , 53 , 108 , 128 , 32 , 128 , 2 , 12 ,
128 , 64 , 160 , 6 , 250 , 46 , 128 , 62 , 14 , 160 , 5 , 89 , 52 , 57 , 160 , 0 , 2 , 57 ,
160 , 6 , 246 , 44 , 128 , 128 , 160 , 6 , 250 , 46 , 128 , 40 , 14 , 160 , 5 , 89 , 52 ,
57 , 160 , 0 , 2 , 57 , 38 , 160 , 0 , 128 , 43 , 15 , 38 , 160 , 255 , 127 , 42 , 79 , 29 ,
128 , 9 , 13 , 34 , 160 , 10 , 163 , 160 , 5 , 99 , 53 , 108 , 160 , 6 , 250 , 46 , 2 , 108 ,
160 , 5 , 85 , 52 , 148 , 128 , 38 , 9 , 128 , 12 , 13 , 33 , 160 , 5 , 85 , 53 , 160 , 5 ,
108 , 52 , 128 , 57 , 12 , 148 , 6 , 128 , 8 , 13 , 2 , 34 , 160 , 5 , 102 , 128 , 44 , 12 ,
128 , 47 , 8 , 128 , 4 , 13 , 33 , 128 , 233 , 12 , 38 , 128 , 0 , 5 , 5 , 21 , 160 , 5 ,
102 , 160 , 6 , 66 , 46 , 15 , 36 , 38 , 128 , 47 , 5 , 5 , 21 , 79 , 128 , 18 , 13 , 33 ,
160 , 5 , 85 , 53 , 160 , 0 , 2 , 56 , 160 , 6 , 66 , 46 , 128 , 3 , 13 , 52 , 108 , 34 , 34 ,
160 , 5 , 76 , 20 , 128 , 0 , 8 , 128 , 7 , 13 , 160 , 10 , 185 , 160 , 5 , 99 , 53 , 160 ,
2023-01-20 10:23:53 -05:00
5 , 89 , 52 , 108 , 128 , 1 , 160 , 5 , 206 , 46 , 12 , 128 , 6 , 12 , 128 , 11 , 12 , 128 ,
2023-12-29 15:48:26 -05:00
20 , 12 , 160 , 10 , 118 , 160 , 5 , 99 , 53 , 108 , 160 , 6 , 228 , 46 , 2 , 108 , 160 , 6 ,
250 , 46 , 2 , 108 , 128 , 160 , 160 , 6 , 250 , 46 , 160 , 6 , 246 , 44 , 160 , 6 , 118 ,
46 , 128 , 4 , 13 , 160 , 6 , 250 , 44 , 128 , 1 , 160 , 5 , 206 , 46 , 12 , 128 , 6 , 12 ,
128 , 216 , 12 , 128 , 225 , 12 , 160 , 5 , 104 , 160 , 6 , 66 , 46 , 128 , 31 , 13 , 148 ,
128 , 2 , 13 , 34 , 108 , 166 , 160 , 6 , 51 , 46 , 33 , 56 , 36 , 160 , 5 , 110 , 46 , 160 ,
5 , 99 , 52 , 29 , 128 , 3 , 13 , 128 , 227 , 12 , 34 , 108 , 34 , 128 , 96 , 160 , 9 , 46 ,
44 , 160 , 7 , 119 , 52 , 160 , 5 , 85 , 52 , 160 , 7 , 140 , 46 , 160 , 4 , 57 , 46 , 160 ,
5 , 82 , 148 , 1 , 5 , 5 , 21 , 108 , 73 , 110 , 118 , 97 , 108 , 105 , 100 , 32 , 104 ,
101 , 120 , 97 , 100 , 101 , 99 , 105 , 109 , 97 , 108 , 0 , 65 , 100 , 100 , 114 , 101 ,
115 , 115 , 32 , 110 , 111 , 116 , 32 , 105 , 110 , 32 , 122 , 101 , 114 , 111 , 32 , 112 ,
97 , 103 , 101 , 0 , 65 , 100 , 100 , 114 , 101 , 115 , 115 , 32 , 111 , 117 , 116 , 115 ,
105 , 100 , 101 , 32 , 114 , 97 , 110 , 103 , 101 , 0 , 76 , 97 , 98 , 101 , 108 , 32 ,
110 , 111 , 116 , 32 , 102 , 111 , 117 , 110 , 100 , 0 , 77 , 97 , 99 , 114 , 111 , 32 ,
97 , 108 , 114 , 101 , 97 , 100 , 121 , 32 , 101 , 120 , 105 , 115 , 116 , 115 , 0 , 77 ,
101 , 109 , 111 , 114 , 121 , 32 , 111 , 118 , 101 , 114 , 119 , 114 , 105 , 116 , 101 ,
0 , 76 , 97 , 98 , 101 , 108 , 32 , 114 , 101 , 100 , 101 , 102 , 105 , 110 , 101 , 100 ,
0 , 0 , 0 , 0 , 0 , 40 , 0 , 7 , 161 , 10 , 255 , 0 , 0 , 41 , 0 , 7 , 193 , 0 , 0 , 0 , 0 , 40 ,
0 , 7 , 173 , 11 , 15 , 0 , 0 , 41 , 0 , 7 , 218 , 11 , 23 , 11 , 39 , 123 , 0 , 7 , 192 , 0 ,
0 , 0 , 0 , 125 , 0 , 8 , 71 , 0 , 0 , 0 , 0 , 33 , 0 , 9 , 44 , 11 , 47 , 0 , 0 , 34 , 0 , 8 ,
221 , 11 , 55 , 11 , 79 , 35 , 0 , 9 , 228 , 0 , 0 , 0 , 0 , 36 , 0 , 8 , 200 , 11 , 71 , 0 ,
0 , 37 , 0 , 7 , 230 , 11 , 63 , 11 , 111 , 38 , 0 , 8 , 114 , 0 , 0 , 0 , 0 , 40 , 0 , 7 ,
173 , 11 , 95 , 0 , 0 , 41 , 0 , 7 , 218 , 11 , 103 , 11 , 119 , 44 , 0 , 9 , 66 , 0 , 0 , 0 ,
0 , 45 , 0 , 9 , 4 , 11 , 87 , 11 , 175 , 46 , 0 , 8 , 254 , 0 , 0 , 0 , 0 , 58 , 0 , 8 , 247 ,
11 , 135 , 0 , 0 , 59 , 0 , 8 , 241 , 11 , 143 , 11 , 167 , 61 , 0 , 8 , 247 , 0 , 0 , 0 , 0 ,
63 , 0 , 9 , 39 , 11 , 159 , 0 , 0 , 64 , 0 , 8 , 89 , 11 , 151 , 11 , 199 , 95 , 0 , 9 , 72 ,
0 , 0 , 0 , 0 , 123 , 0 , 7 , 192 , 11 , 183 , 0 , 0 , 124 , 0 , 8 , 193 , 11 , 191 , 11 ,
207 , 125 , 0 , 7 , 192 , 0 , 0 , 0 , 0 , 126 , 0 , 10 , 93 , 12 , 39 , 11 , 255 , 76 , 73 ,
84 , 0 , 0 , 0 , 0 , 0 , 73 , 78 , 67 , 0 , 0 , 0 , 0 , 0 , 80 , 79 , 80 , 0 , 12 , 167 , 12 ,
15 , 78 , 73 , 80 , 0 , 0 , 0 , 0 , 0 , 83 , 87 , 80 , 0 , 11 , 239 , 12 , 111 , 82 , 79 , 84 ,
0 , 0 , 0 , 0 , 0 , 68 , 85 , 80 , 0 , 12 , 191 , 11 , 231 , 79 , 86 , 82 , 0 , 0 , 0 , 0 , 0 ,
69 , 81 , 85 , 0 , 0 , 0 , 0 , 0 , 78 , 69 , 81 , 0 , 12 , 175 , 12 , 71 , 71 , 84 , 72 , 0 ,
0 , 0 , 0 , 0 , 76 , 84 , 72 , 0 , 0 , 0 , 0 , 0 , 74 , 77 , 80 , 0 , 11 , 223 , 12 , 55 , 74 ,
67 , 78 , 0 , 12 , 63 , 12 , 103 , 74 , 83 , 82 , 0 , 0 , 0 , 0 , 0 , 83 , 84 , 72 , 0 , 0 , 0 ,
0 , 0 , 76 , 68 , 90 , 0 , 0 , 0 , 0 , 0 , 83 , 84 , 90 , 0 , 12 , 119 , 12 , 87 , 76 , 68 ,
82 , 0 , 12 , 127 , 12 , 159 , 83 , 84 , 82 , 0 , 0 , 0 , 0 , 0 , 76 , 68 , 65 , 0 , 12 , 207 ,
12 , 79 , 83 , 84 , 65 , 0 , 12 , 183 , 12 , 143 , 68 , 69 , 73 , 0 , 0 , 0 , 0 , 0 , 68 , 69 ,
79 , 0 , 0 , 0 , 0 , 0 , 65 , 68 , 68 , 0 , 12 , 95 , 11 , 247 , 83 , 85 , 66 , 0 , 12 , 47 ,
12 , 31 , 77 , 85 , 76 , 0 , 12 , 135 , 12 , 199 , 68 , 73 , 86 , 0 , 12 , 151 , 0 , 0 , 65 ,
78 , 68 , 0 , 0 , 0 , 0 , 0 , 79 , 82 , 65 , 0 , 12 , 7 , 12 , 23 , 69 , 79 , 82 , 0 , 0 , 0 ,
0 , 0 , 83 , 70 , 84 , 0
2023-01-20 10:23:53 -05:00
}
local run
run = function ( u )
console_device.stdout = { }
console_device.stderr = { }
u.program_stack . head = 0
u.return_stack . head = 0
u.ip = 0x100
return u : runUntilBreak ( )
end
local resume
resume = function ( u )
u.ip = u.ip + 1
return u : runUntilBreak ( )
end
local quote
do
local translate
do
local _tbl_0 = { }
for i = 0 , 255 do
_tbl_0 [ i ] = ( ' \\ x%02x ' ) : format ( i )
end
translate = _tbl_0
end
for i = 32 , 126 do
translate [ i ] = string.char ( i )
end
translate [ 0x0d ] = ' \\ r '
translate [ 0x0a ] = ' \\ n '
translate [ 0x22 ] = ' \\ " '
translate [ 0x5c ] = ' \\ \\ '
quote = function ( t )
local out
do
local _tbl_0 = { }
for i , v in ipairs ( t ) do
_tbl_0 [ i + 1 ] = translate [ v ]
end
out = _tbl_0
end
out [ 1 ] = ' " '
out [ # out + 1 ] = ' " '
return table.concat ( out )
end
end
local preamble = [ [ | 10 @ Console $ 8 & write $ 1 & error $ 1
| b0 @ DateTime [ & year $ 2 & month $ 1 & day $ 1 & hour $ 1 & minute $ 1 & second $ 1 & dotw $ 1 & doty $ 2 & isdst $ 1 ]
| 0100 @ reset
] ]
local help_message = [[Hi, I'm uxnbot! Type a line of Uxntal and I'll run it and print out the stacks and Console output. Start the line with "hexdump" and, instead of running it, I'll print a hexdump of the assembled ROM. I also understand the word "help" to print this message. I only support DateTime and the Console/write and Console/error device bytes so far.]]
local chat
chat = function ( command )
local remainder = command : match ( ' ^uxnbot:%s+(.*)$ ' )
if remainder then
command = remainder
end
local help = command : match ( ' ^help(.?) ' )
if help and ( help == ' ' or help : upper ( ) == help : lower ( ) ) then
return help_message
end
local hexdump = command : match ( ' ^hexdump%s+(.*) ' )
if hexdump then
command = hexdump
end
load_memory ( u , asma_rom )
load_source ( u , preamble .. command )
local okay , err = pcall ( run , u )
if not okay then
return ' internal assembly error, pass 1: ' .. ( err : match ( ' ^[^:]*:[^:]*:%s*(.*)$ ' ) or ' unknown error ' )
end
if # console_device.stderr > 0 then
return ' assembly error, pass 1: ' .. table.concat ( ( function ( )
local _accum_0 = { }
local _len_0 = 1
local _list_0 = console_device.stderr
for _index_0 = 1 , # _list_0 do
local c = _list_0 [ _index_0 ]
_accum_0 [ _len_0 ] = string.char ( c )
_len_0 = _len_0 + 1
end
return _accum_0
end ) ( ) )
end
okay , err = pcall ( resume , u )
if not okay then
return ' internal assembly error, pass 2: ' .. ( err : match ( ' ^[^:]*:[^:]*:%s*(.*)$ ' ) or ' unknown error ' )
end
if # console_device.stdout == 4 and console_device.stdout [ 1 ] == 0x4f and console_device.stdout [ 2 ] == 0x4b then
local write_end = console_device.stdout [ 3 ] * 0x100 + console_device.stdout [ 4 ]
local assembled_code
do
local _accum_0 = { }
local _len_0 = 1
for i = 0xf000 , write_end - 1 do
_accum_0 [ _len_0 ] = u.memory [ i ]
_len_0 = _len_0 + 1
end
assembled_code = _accum_0
end
if hexdump then
local out
do
local _tbl_0 = { }
for i , v in ipairs ( assembled_code ) do
_tbl_0 [ i + 1 ] = ( ' %02x ' ) : format ( v )
end
out = _tbl_0
end
out [ 1 ] = ' ROM contents: '
out [ # out ] = out [ # out ] .. ( ' , 0x%x bytes ' ) : format ( # assembled_code )
return table.concat ( out , ' ' )
end
load_memory ( u , assembled_code )
okay , err = pcall ( run , u )
if okay then
local parts = { }
if u.program_stack . head > 0 then
table.insert ( parts , ( ' wst %s ' ) : format ( u.program_stack : debug ( ) ) )
end
if u.return_stack . head > 0 then
table.insert ( parts , ( ' rst %s ' ) : format ( u.return_stack : debug ( ) ) )
end
if # console_device.stdout > 0 then
if # console_device.stdout > 100 then
table.insert ( parts , ( ' %s and more on Console/write ' ) : format ( quote ( ( function ( )
local _accum_0 = { }
local _len_0 = 1
for i = 1 , 100 do
_accum_0 [ _len_0 ] = console_device.stdout [ i ]
_len_0 = _len_0 + 1
end
return _accum_0
end ) ( ) ) ) )
else
table.insert ( parts , ( ' %s on Console/write ' ) : format ( quote ( console_device.stdout ) ) )
end
end
if # console_device.stderr > 0 then
if # console_device.stderr > 100 then
table.insert ( parts , ( ' %s and more on Console/error ' ) : format ( quote ( ( function ( )
local _accum_0 = { }
local _len_0 = 1
for i = 1 , 100 do
_accum_0 [ _len_0 ] = console_device.stderr [ i ]
_len_0 = _len_0 + 1
end
return _accum_0
end ) ( ) ) ) )
else
table.insert ( parts , ( ' %s on Console/error ' ) : format ( quote ( console_device.stderr ) ) )
end
end
if # parts == 0 then
table.insert ( parts , ' wst empty ' )
end
return table.concat ( parts , ' , ' )
else
return ' runtime error: ' .. ( err : match ( ' ^[^:]*:[^:]*:%s*(.*)$ ' ) or ' unknown error ' )
end
else
return ' assembly error, pass 2: ' .. table.concat ( ( function ( )
local _accum_0 = { }
local _len_0 = 1
local _list_0 = console_device.stderr
for _index_0 = 1 , # _list_0 do
local c = _list_0 [ _index_0 ]
_accum_0 [ _len_0 ] = string.char ( c )
_len_0 = _len_0 + 1
end
return _accum_0
end ) ( ) )
end
end
return chat
] = ] ,
[ ' device ' ] = [ [ local Device = { }
Device.DEBUG_NUM_CALLS = { read = { } , write = { } }
Device.__index = function ( self , k )
if type ( k ) == " number " then
Device.DEBUG_NUM_CALLS . read [ self.device_num or self ] = ( Device.DEBUG_NUM_CALLS . read [ self.device_num or self ] or 0 ) + 1
local value = self.portdata [ k ] or 0
local port = self.ports [ k ]
if port then
if port.onread then
value = port.onread ( self )
if port.byte == " high " then
value = bit.rshift ( value , 8 )
end
end
end
return bit.band ( value , 0xff )
elseif Device [ k ] then
return Device [ k ]
end
end
function Device : readShort ( port )
return bit.lshift ( self [ port ] , 8 ) + self [ port + 1 ]
end
function Device : writeShort ( port , short )
-- Write the low byte first since onwrite only triggers on the high byte
self [ port + 1 ] = bit.band ( short , 0xff )
self [ port ] = bit.band ( bit.rshift ( short , 8 ) , 0xff )
end
Device.__newindex = function ( self , k , v )
if type ( k ) == " number " then
--Device.DEBUG_NUM_CALLS.write[self.device_num or self] = (Device.DEBUG_NUM_CALLS.write[self.device_num or self] or 0) + 1
self.portdata [ k ] = v
local port = self.ports [ k ]
if port then
-- Ignore write triggers for the low byte of a short
if port.onwrite and port.byte ~= " low " then
return port.onwrite ( self , v )
end
end
-- If there's no handlers attached to this port, just store the value
if not ( port and ( port.onwrite or port.onread ) ) then
-- Cache the result
rawset ( self , k , v )
end
else
return rawset ( self , k , v )
end
end
function Device : new ( devicenum )
local device = setmetatable ( {
ports = { } ,
portdata = { } ,
} , self )
-- Add vector port by default
device : addPort ( 0 , true , false , function ( self , value )
self.cpu . vectors [ self.device_num ] = self : readShort ( 0 )
end )
return device
end
function Device : addPort ( num , short , read , write )
if short then
self.ports [ num ] = { byte = " high " , onread = read , onwrite = write }
self.ports [ num + 1 ] = { byte = " low " , onread = read , onwrite = write }
else
self.ports [ num ] = { byte = " single " , onread = read , onwrite = write }
end
end
function Device : trigger ( )
self.cpu : triggerDevice ( self.device_num )
end
return Device
] ] ,
[ ' uxn ' ] = [ [ local bit = require " bit "
local math = require " math "
local band , bor , bxor , bnot = bit.band , bit.bor , bit.bxor , bit.bnot
local arshift , rshift , lshift = bit.arshift , bit.rshift , bit.lshift
local function uint8_to_int8 ( byte )
byte = band ( byte , 0xff )
if band ( byte , 0x80 ) ~= 0 then
byte = byte - 0x100
end
return byte
end
local Stack = { }
Stack.__index = Stack
function Stack : new ( limit )
local limit = limit or 256
return setmetatable ( {
limit = limit ,
head = 0 ,
} , self )
end
function Stack : push ( byte )
local head = self.head + 1
self [ head ] = byte
self.head = head
end
function Stack : pop ( )
local head = self.head
local byte = self [ head ]
self.head = head - 1
return byte
end
function Stack : check ( n )
local new = self.head + n
return new >= 0 and new <= self.limit
end
-- 0-indexed non-destructive get
function Stack : getnth ( n )
return self [ self.head - n ]
end
function Stack : len ( )
return self.head
end
function Stack : debug ( )
local t = { }
for i = 1 , self.head do
t [ # t + 1 ] = bit.tohex ( self [ i ] , 2 )
end
return table.concat ( t , " " )
end
local Memory = {
__index = function ( self , k )
if type ( k ) == " number " then
-- Uninitialized memory should be randomized for robust testing
if self.ERROR_ON_UNINITIALIZED_READ then
error ( " READ UNINITIALIZED MEMORY @ " .. bit.tohex ( k ) )
end
return 0 --love.math.random(255)
end
end
}
local Uxn = { }
Uxn.__index = Uxn
function Uxn : new ( mem )
return setmetatable ( {
ip = 1 ,
program_stack = Stack : new ( ) ,
return_stack = Stack : new ( ) ,
memory = setmetatable ( mem or { } , Memory ) ,
devices = { } ,
vectors = { } ,
-- DEBUG TABLES
debug_profile = { } ,
device_triggers = { } , -- Debug
device_reads = { } , -- DEBUG
device_writes = { } , -- DEBUG
} , self )
end
function Uxn : profile ( ... )
local name = table.concat ( { ... } , " _ " )
self.debug_profile [ name ] = ( self.debug_profile [ name ] or 0 ) + 1
end
function Uxn : print_profile ( )
local output = " name \t \t count \n "
for k , v in pairs ( self.debug_profile ) do
output = output .. k .. " \t \t " .. v .. " \n "
end
return output
end
function bytes_to_shorts ( bytes )
local shorts = { }
for i = 1 , # bytes , 2 do
local high_byte = bytes [ i ]
local low_byte = bytes [ i + 1 ]
shorts [ # shorts + 1 ] = band ( lshift ( high_byte , 8 ) + low_byte , 0xffff )
end
return shorts
end
function bytes_to_short ( high , low )
if not low then
low = high [ 2 ]
high = high [ 1 ]
end
return band ( lshift ( high , 8 ) + low , 0xffff )
end
function shorts_to_bytes ( shorts )
local bytes = { }
for i = 1 , # shorts do
local short = shorts [ i ]
local high_byte = rshift ( short , 8 )
-- Mask out the low byte
local low_byte = band ( short , 0xff )
bytes [ # bytes + 1 ] = high_byte
bytes [ # bytes + 1 ] = low_byte
end
return bytes
end
function Uxn : get_n ( n , keep_bit , return_bit , short_bit )
-- Choose which stack to operate on
local stack = return_bit and self.return_stack or self.program_stack
-- Fetch 2 bytes for each number needed
if short_bit then n = n * 2 end
-- Make sure the stack has enough space to fetch n bytes
if not stack : check ( - n ) then
error ( " Stack not big enough to get " .. tostring ( n ) .. " bytes " )
end
local output = { }
for i = 1 , n do
if keep_bit then
output [ ( n - i ) + 1 ] = stack : getnth ( i - 1 )
else
output [ ( n - i ) + 1 ] = stack : pop ( )
end
end
if short_bit then
output = bytes_to_shorts ( output )
end
return output
end
function Uxn : push ( value , k , r , s )
local stack = r and self.return_stack or self.program_stack
--assert(stack:check(1 + (s and 1 or 0)), "Can't push", value, "k", k, "r", r, "s", s)
if stack.head > 0xfe then
error ( r and ' return stack overflow ' or ' working stack overflow ' )
end
if s then
stack : push ( band ( rshift ( value , 8 ) , 0xff ) )
end
stack : push ( band ( value , 0xff ) )
end
function Uxn : pop ( k , r , s )
local stack = r and self.return_stack or self.program_stack
local value
if k then
local offset = self.peek_offset
if s then
local low = stack : getnth ( offset )
local high = stack : getnth ( offset + 1 )
value = low and high and bytes_to_short ( high , low )
offset = offset + 2
else
value = stack : getnth ( offset )
offset = offset + 1
end
self.peek_offset = offset
else
if s then
local low = stack : pop ( )
local high = stack : pop ( )
value = low and high and bytes_to_short ( high , low )
else
value = stack : pop ( )
end
end
if not value then
error ( r and ' return stack underflow ' or ' working stack underflow ' )
end
return value
end
local function extractOpcode ( byte )
local keep_bit = band ( byte , 0x80 ) ~= 0 -- 0b1000 0000
local return_bit = band ( byte , 0x40 ) ~= 0 -- 0b0100 0000
local short_bit = band ( byte , 0x20 ) ~= 0 -- 0b0010 0000
local opcode = band ( byte , 0x1f ) -- 0b0001 1111
return opcode , keep_bit , return_bit , short_bit
end
function Uxn : device_read ( addr , k , r , s )
local device_num = rshift ( addr , 4 )
local device = self.devices [ device_num ]
if device then
self.device_reads [ device_num ] = ( self.device_reads [ device_num ] or 0 ) + 1
local port = band ( addr , 0x0f )
local value
if s then
value = device : readShort ( port )
else
value = band ( device [ port ] , 0xff )
end
return value
else
return 0
end
end
function Uxn : device_write ( addr , value , k , r , s )
local device_num = rshift ( addr , 4 )
local device = self.devices [ device_num ]
local port_num = band ( addr , 0x0f )
if device then
--self:profile("DEO", device_num, port_num)
self.device_writes [ device_num ] = ( self.device_writes [ device_num ] or 0 ) + 1
if self.PRINT then print ( " wrote " , bit.tohex ( value ) , " to " , bit.tohex ( addr ) ) end
if s then
device : writeShort ( port_num , value )
else
device [ port_num ] = value
end
end
end
function Uxn : addDevice ( device_num , device )
if self.devices [ device_num ] then
error ( " Device already exists at " , bit.tohex ( device_num ) )
end
device.cpu = self
device.device_num = device_num
self.devices [ device_num ] = device
return device
end
function Uxn : triggerDevice ( device_num )
local vector = self.vectors [ device_num ]
--local vector = self.devices[device_num]:readShort(0)
if vector then
self.device_triggers [ device_num ] = ( self.device_triggers [ device_num ] or 0 ) + 1
self.ip = vector
return self : runUntilBreak ( )
end
end
local opNames = {
[ 0 ] = " LIT " ,
" INC " ,
" POP " ,
" DUP " ,
" NIP " ,
" SWAP " ,
" OVER " ,
" ROT " ,
" EQU " ,
" NEQ " ,
" GTH " ,
" LTH " ,
" JMP " ,
" JCN " ,
" JSR " ,
" STASH " ,
" LDZ " ,
" STZ " ,
" LDR " ,
" STR " ,
" LDA " ,
" STA " ,
" DEI " ,
" DEO " ,
" ADD " ,
" SUB " ,
" MUL " ,
" DIV " ,
" AND " ,
" OR " ,
" XOR " ,
" SHIFT " ,
}
local opTable = {
-- STACK
--
2023-12-29 15:48:26 -05:00
-- 0x00 JCI/JMI/JSI/LIT
2023-01-20 10:23:53 -05:00
function ( self , k , r , s )
local value
2023-12-29 15:48:26 -05:00
if k then -- LIT2?r?
if s then
value = bytes_to_short ( self.memory [ self.ip ] , self.memory [ self.ip + 1 ] )
else
value = self.memory [ self.ip ]
end
if self.PRINT then print ( " Push " .. ( s and " short " or " byte " ) .. " value = " , bit.tohex ( value ) ) end
self : push ( value , k , r , s )
self.ip = self.ip + ( s and 2 or 1 )
2023-01-20 10:23:53 -05:00
else
2023-12-29 15:48:26 -05:00
value = bytes_to_short ( self.memory [ self.ip ] , self.memory [ self.ip + 1 ] )
self.ip = self.ip + 2
if not r then -- JCI
if self : pop ( false , false , false ) == 0 then return end
elseif r and s then -- JSI
self : push ( self.ip , false , true , true )
end
self.ip = self.ip + value
2023-01-20 10:23:53 -05:00
end
end ,
-- 0x01 INC
function ( self , k , r , s )
local a = self : pop ( k , r , s )
self : push ( a + 1 , k , r , s )
end ,
-- 0x02 POP
function ( self , k , r , s )
self : pop ( k , r , s )
end ,
-- 0x03 NIP
function ( self , k , r , s )
local b = self : pop ( k , r , s )
self : pop ( k , r , s )
self : push ( b , k , r , s )
end ,
-- 0x04 SWAP
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( b , k , r , s )
self : push ( a , k , r , s )
end ,
-- 0x05 ROT
function ( self , k , r , s )
local c = self : pop ( k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( b , k , r , s )
self : push ( c , k , r , s )
self : push ( a , k , r , s )
end ,
-- 0x06 DUP
function ( self , k , r , s )
local a = self : pop ( k , r , s )
self : push ( a , k , r , s )
self : push ( a , k , r , s )
end ,
-- 0x07 OVER
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( a , k , r , s )
self : push ( b , k , r , s )
self : push ( a , k , r , s )
end ,
-- LOGIC
--
-- 0x08 EQU
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
-- Push the flag as a single byte, so short mode is false in Uxn:push
self : push ( a == b and 1 or 0 , k , r , false )
end ,
-- 0x09 NEQ
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( a ~= b and 1 or 0 , k , r , false )
end ,
-- 0x0a GTH
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( a > b and 1 or 0 , k , r , false )
end ,
-- 0x0b LTH
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( a < b and 1 or 0 , k , r , false )
end ,
-- 0x0c JMP
function ( self , k , r , s )
local addr = self : pop ( k , r , s )
if not s then
-- relative jump
addr = uint8_to_int8 ( addr ) + self.ip
end
self.ip = addr
end ,
-- 0x0d JCN
function ( self , k , r , s )
local addr = self : pop ( k , r , s )
local flag = self : pop ( k , r , false )
if flag ~= 0 then
if not s then
addr = self.ip + uint8_to_int8 ( addr )
end
self.ip = addr
end
end ,
-- 0x0e JSR
function ( self , k , r , s )
local addr = self : pop ( k , r , s )
if not s then
addr = uint8_to_int8 ( addr ) + self.ip
end
-- Stash
self : push ( self.ip , k , not r , true )
self.ip = addr
end ,
-- 0x0f STH
function ( self , k , r , s )
local a = self : pop ( k , r , s )
self : push ( a , k , not r , s )
end ,
-- MEMORY
--
-- 0x10 LDZ
function ( self , k , r , s )
local offset = self : pop ( k , r , false )
local value = self.memory [ offset ]
if s then
value = lshift ( value , 8 ) + self.memory [ offset + 1 ]
end
self : push ( value , k , r , s )
end ,
-- 0x11 STZ
function ( self , k , r , s )
local data = self : get_n ( s and 3 or 2 , k , r , false )
local offset = table.remove ( data )
self.memory [ offset ] = data [ 1 ]
if s then
self.memory [ offset + 1 ] = data [ 2 ]
end
end ,
-- 0x12 LDR
function ( self , k , r , s )
local offset = self : pop ( k , r , false )
local addr = uint8_to_int8 ( offset ) + self.ip
local value = self.memory [ addr ]
if s then
value = lshift ( value , 8 ) + self.memory [ addr + 1 ]
end
self : push ( value , k , r , s )
end ,
-- 0x13 STR
function ( self , k , r , s )
local data = self : get_n ( s and 3 or 2 , k , r , false )
local address = uint8_to_int8 ( table.remove ( data ) ) + self.ip
self.memory [ address ] = data [ 1 ]
if s then
self.memory [ address + 1 ] = data [ 2 ]
end
end ,
-- 0x14 LDA
function ( self , k , r , s )
local addr = self : pop ( k , r , true )
local value = self.memory [ addr ]
if s then
value = lshift ( value , 8 ) + self.memory [ addr + 1 ]
end
self : push ( value , k , r , s )
end ,
-- 0x15 STA
function ( self , k , r , s )
local data = self : get_n ( s and 4 or 3 , k , r , false )
local address = bytes_to_short ( data [ # data - 1 ] , data [ # data ] )
self.memory [ address ] = data [ 1 ]
if s then
self.memory [ address + 1 ] = data [ 2 ]
end
end ,
-- 0x16 DEI
function ( self , k , r , s )
local offset = self : pop ( k , r , false )
self : push ( self : device_read ( offset , k , r , s ) , k , r , s )
end ,
-- 0x17 DEO
function ( self , k , r , s )
local address = self : pop ( k , r , false )
local value = self : pop ( k , r , s )
self : device_write ( address , value , k , r , s )
end ,
-- ARITHMETIC
--
-- 0x18 ADD
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( a + b , k , r , s )
end ,
-- 0x19 SUB
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( a - b , k , r , s )
end ,
-- 0x1a MUL
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( a * b , k , r , s )
end ,
-- 0x1b DIV
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
assert ( b ~= 0 , " Can't divide by zero! " )
self : push ( math.floor ( a / b ) , k , r , s )
end ,
-- 0x1c AND
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( band ( a , b ) , k , r , s )
end ,
-- 0x1d OR
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( bor ( a , b ) , k , r , s )
end ,
-- 0x1e EOR
function ( self , k , r , s )
local b = self : pop ( k , r , s )
local a = self : pop ( k , r , s )
self : push ( bxor ( a , b ) , k , r , s )
end ,
-- 0x1f SFT
-- "Shift in short mode expects a single byte"
function ( self , k , r , s )
local amount = self : pop ( k , r , false )
local value = self : pop ( k , r , s )
value = arshift ( value , band ( amount , 0x0f ) )
value = lshift ( value , rshift ( band ( amount , 0xf0 ) , 4 ) )
self : push ( value , k , r , s )
end ,
}
function Uxn : runUntilBreak ( )
local count = 0
local extractOpcode = extractOpcode
local memory = self.memory
while true do
local opline
local opByte = memory [ self.ip ]
if opByte == 0 then break end
if self.PRINT then
opline = bit.tohex ( self.ip )
end
self.ip = self.ip + 1
local opcode , k , r , s = extractOpcode ( opByte )
--self:profile(opNames[opcode])
if self.PRINT then
print ( opline .. " : " .. opNames [ opcode ] .. ( s and " 2 " or " " ) .. ( r and " r " or " " ) .. ( k and " k " or " " ) )
print ( " PS " , self.program_stack : debug ( ) )
print ( " RS " , self.return_stack : debug ( ) )
end
-- Reset the peek offset so consective calls to :pop maintain state
if k then self.peek_offset = 0 end
opTable [ opcode + 1 ] ( self , k , r , s )
2023-12-29 15:48:26 -05:00
self.ip = self.ip % 0x10000
2023-01-20 10:23:53 -05:00
count = count + 1
if count > 1000000 then
error ' uxnbot got bored with all the looping '
end
end
return count
end
return { Uxn = Uxn , uint8_to_int8 = uint8_to_int8 }
] ] ,
}
_G.require = function ( module_name )
if source [ module_name ] then
if not loaded [ module_name ] then
retval [ module_name ] = assert ( loadstring ( source [ module_name ] ) ) ( )
loaded [ module_name ] = true
end
return retval [ module_name ]
else
return orig_require ( module_name )
end
end
end
local chat = require ( ' chat ' )
print ( ' uxnrepl (ctrl-d to quit) ' )
local prompt
prompt = function ( )
io.write ( ' > ' )
return io.flush ( )
end
prompt ( )
for l in io.stdin : lines ( ) do
print ( chat ( l ) )
prompt ( )
end
return print ( ' bye! ' )