Add FPU bit hack
[jpcrr.git] / luakernel.lua
blob8edc9179d56842f538b746fbf7ab43c0a1d2b954
1 --
2 -- Copyright 2009 Ilari Liusvaara
3 --
4 -- Licenced under GNU GPL v2.
5 --
7 -- Exported tables:
8 -- - args
9 -- Contains user-level arguments.
11 -- Exported functions:
12 -- - All lua standard functions in tables main, "coroutine", "string" and "table".
13 -- - modulus_split(number num, number...)
14 -- Returns quotents and quotent remainders of number divided by given dividers.
15 -- The number of results returned is equal to number of numbers passed. The
16 -- dividers must be in decreasing order and all dividers must be nonzero and
17 -- should be >1.
18 -- - assert(object ret, object err)
19 -- If ret is considered true, return ret. Otherwise raise err as error. Exception
20 -- if err is nil too, then ret is returned anyway.
21 -- - bit.none(number...)
22 -- Returns 48-bit number that has those bits set that are set in none of its
23 -- arguments.
24 -- - bit.any(number...)
25 -- Returns 48-bit number that has those bits set that are set in any of its
26 -- arguments.
27 -- - bit.parity(number...)
28 -- Returns 48-bit number that has those bits set that are set in even number
29 -- of its arguments.
30 -- - bit.any(number...)
31 -- Returns 48-bit number that has those bits set that are set in all of its
32 -- arguments.
33 -- - bit.lshift(number num, number shift)
34 -- Returns 48 rightmost bits of num shifted by shift places left. Going outside
35 -- shift range 0-47 produces unpredicatable results.
36 -- - bit.rshift(number num, number shift)
37 -- Returns 48 rightmost bits of num shifted by shift places right. Going outside
38 -- shift range 0-47 produces unpredicatable results.
39 -- - bit.arshift(number num, number shift)
40 -- Returns 48 rightmost bits of num shifted by shift places right and bit 47
41 -- value copied to all incoming bits. Going outside shift range 0-47 produces
42 -- unpredicatable results.
43 -- - bit.add(number...)
44 -- Returns sum of all passed numbers modulo 2^48.
45 -- - bit.addneg(number...)
46 -- Returns 0 minus sum of all passed numbers modulo 2^48.
47 -- - bit.addalt(number...)
48 -- Returns sum of odd arguments (first is odd) minus sum of even arguments modulo
49 -- 2^48.
50 -- - bit.tohex(number num)
51 -- Returns hexadecimal string representation of number.
52 -- - jpcrr.pc_running()
53 -- Returns true if PC is running.
54 -- - jpcrr.clock_time()
55 -- Returns current time or nil if no PC.
56 -- - jpcrr.pc_connected()
57 -- Returns true if PC is connected.
58 -- - jpcrr.wait_pc_attach()
59 -- Wait for PC to attach.
60 -- - jpcrr.next_frame()
61 -- Wait for next frame output hold.
62 -- - jpcrr.in_frame_hold()
63 -- Returns true if in frame hold, false otherwise.
64 -- - jpcrr.keypressed(number key)
65 -- Return true if key is pressed, else false.
66 -- - jpcrr.wait_vga()
67 -- Waits for VGA to enter frame hold mode. Frame hold happens once per frame.
68 -- - jpcrr.release_vga()
69 -- Allow VGA to exit frame hold mode. Wait for frame hold first.
70 -- - jpcrr.vga_resolution()
71 -- Return VGA x and y resolutions. -1x-1 or 0x0 is returned if no valid resolution.
72 -- Should only be called during frame hold.
73 -- - jpcrr.hud.left_gap(number flags, number gap)
74 -- Set left gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
75 -- 1 (2) is set, dump to video dump.
76 -- - jpcrr.hud.right_gap(number flags, number gap)
77 -- Set right gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
78 -- 1 (2) is set, dump to video dump.
79 -- - jpcrr.hud.top_gap(number flags, number gap)
80 -- Set top gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
81 -- 1 (2) is set, dump to video dump.
82 -- - jpcrr.hud.bottom_gap(number flags, number gap)
83 -- Set bottom gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
84 -- 1 (2) is set, dump to video dump.
85 -- - jpcrr.hud.white_solid_box(number flags, number x, number y, number w, number h)
86 -- Draw with solid opaque box.
87 -- - jpcrr.hud.box(number flags, number x, number y, number w, number h, number linethick,
88 -- number lineRed, number lineGreen, number lineBlue, number lineAlpha,
89 -- number fillRed, number fillGreen, number fillBlue, number fillAlpha)
90 -- Draw box with specified size, border line thickness, line color and fill color.
91 -- - jpcrr.hud.bitmap(number flags, number x, number y, string bmap,
92 -- number fgRed, number fgGreen, number fgBlue, number fgAlpha,
93 -- number bgRed, number bgGreen, number bgBlue, number bgAlpha)
94 -- Draw bitmap with specified foreground color and background color.
95 -- - jpcrr.hud.bitmap_binary(number flags, number x, number y, string bmap,
96 -- number fgRed, number fgGreen, number fgBlue, number fgAlpha,
97 -- number bgRed, number bgGreen, number bgBlue, number bgAlpha)
98 -- Draw binary bitmap with specified foreground color and background color.
99 -- - jpcrr.joystick_state()
100 -- Returns nil if no joystick. Otherwise returns hold times for all four axis (numeric)
101 -- followed by button states (boolean).
102 -- - jpcrr.component_encode(table components)
103 -- Return component encoding for specified components.
104 -- - jpcrr.component_decode(string line)
105 -- Return component decoding for specified line, nil/nil if it doesn't encode
106 -- anything, nil/string if parse error occurs (the error is the second return).
107 -- - jpcrr.save_state(string name)
108 -- Savestate into specified file. Returns name used.
109 -- - jpcrr.save_movie(string name)
110 -- Save movie into specified file. Returns name used.
111 -- - jpcrr.load_state_normal(string name)
112 -- Load specified savestate. Returns name used.
113 -- - jpcrr.load_state_preserve_events(string name)
114 -- Load specified savestate, preserving events. Returns name used.
115 -- - jpcrr.load_state_movie(string name)
116 -- Load specified savestate as movie. Returns name used.
117 -- - jpcrr.assemble()
118 -- Open system settings dialog.
119 -- - jpcrr.change_authors()
120 -- Open change authors dialog.
121 -- - jpcrr.exit = function()
122 -- Exit the Lua VM.
123 -- - jpcrr.ram_dump(string name, boolean binary)
124 -- Dump PC memory to specified file. If binary is true, dump is binary, otherwise
125 -- textual hexadecimal dump.
126 -- - jpcrr.write_byte(number addr, number value)
127 -- Write byte to specified physical address.
128 -- - jpcrr.write_word(number addr, number value)
129 -- Write word to specified physical address (little endian).
130 -- - jpcrr.write_dword(number addr, number value)
131 -- Write dword to specified physical address (little endian).
132 -- - jpcrr.read_byte(number addr)
133 -- Return byte from specified physical address.
134 -- - jpcrr.read_word(number addr)
135 -- Return word from specified physical address (little endian).
136 -- - jpcrr.read_dword(number addr)
137 -- Return dword from specified physical address (little endian).
138 -- - jpcrr.timed_trap(number nsecs)
139 -- Set trap after specified number of nanoseconds. Use nil as nsecs to disable.
140 -- - jpcrr.vretrace_start_trap(boolean is_on)
141 -- Set trap on vretrace start on/off.
142 -- - jpcrr.vretrace_end_trap(boolean is_on)
143 -- Set trap on vretrace end on/off.
144 -- - jpcrr.pc_start()
145 -- Start PC execution.
146 -- - jpcrr.pc_stop()
147 -- Stop PC execution.
148 -- - jpcrr.set_pccontrol_pos(number x, number y)
149 -- Set position of PCControl window.
150 -- - jpcrr.set_luaplugin_pos(number x, number y)
151 -- Set position of LuaPlugin window.
152 -- - jpcrr.set_pcmonitor_pos(number x, number y)
153 -- Set position of PCMonitor window.
154 -- - jpcrr.set_pcstartstoptest_pos(number x, number y)
155 -- Set position of PCStartStopTest window.
156 -- - jpcrr.set_virtualkeyboard_pos(number x, number y)
157 -- Set position of VirtualKeyboard window.
159 -- I/O functions have the following conventions. If function returns any real data, the first
160 -- return value returns this data or is nil. Otherwise first return value is true or false.
161 -- If first return value is nil or false, then the second return value gives textual error
162 -- message for failed operation, or is nil if EOF occured before anything was read.
164 -- Unlink, rename and mkdir don't follow this pattern. They just return true/false to signal
165 -- success or failure.
167 -- Specifying nil as name of file results random filename being used (it even works with unlink,
168 -- mkdir, rename and read-only access, but doesn't make any sense there).
170 -- Class: BinaryFile:
171 -- Binary file for RO or RW access. Methods are as follows:
172 -- - name()
173 -- Return name of file.
174 -- - length()
175 -- Return length of file.
176 -- - set_length(number length)
177 -- Truncate file to specified length
178 -- - read(number offset, number length)
179 -- Read up to length bytes from offset.
180 -- - write(number offset, string content)
181 -- Write content to specified offset.
182 -- - close()
183 -- Close the file.
184 -- Class: BinaryInput:
185 -- Binary file for sequential input. Methods are as follows:
186 -- - name()
187 -- Return name of file.
188 -- - four_to_five()
189 -- Return BinaryInput that is four to five decoding of this stream.
190 -- - text()
191 -- Return stream as TextInput.
192 -- - inflate()
193 -- Return BinaryInput that is inflate of this stream.
194 -- - read(number bytes)
195 -- Read up to bytes bytes from file.
196 -- - read()
197 -- Read the entiere file at once.
198 -- - close()
199 -- Close the file.
200 -- Character set for binary files is Latin-1.
202 -- Class: BinaryOutput:
203 -- Binary file for sequential output. Methods are as follows:
204 -- - name()
205 -- Return name of file.
206 -- - four_to_five()
207 -- Return BinaryOutput that writes four to five encoded output to this stream.
208 -- - text()
209 -- Return stream as TextOutput.
210 -- - deflate()
211 -- Return BinaryOutput that writes deflate output to this stream.
212 -- - write(string content)
213 -- Write string to file.
214 -- - close()
215 -- Close the file.
216 -- Character set for binary files is Latin-1.
218 -- Class: TextInput:
219 -- - name()
220 -- Return name of file.
221 -- - read()
222 -- Read line from file.
223 -- - read_component()
224 -- Read next componented line into array.
225 -- - lines()
226 -- Line iterator function.
227 -- - close()
228 -- Close the file.
229 -- Character set for text files is UTF-8.
231 -- Class: TextOutput:
232 -- - name()
233 -- Return name of file.
234 -- - write(string line)
235 -- Write line line to file.
236 -- - write_component(table components)
237 -- Write componented line.
238 -- - close()
239 -- Close the file.
240 -- Character set for text files is UTF-8.
242 -- Class ArchiveIn:
243 -- - member(string name)
244 -- Open substream for member name. The methods are the same as for io.opentextin.
245 -- - member_binary(string name)
246 -- Open binary (four to five) substream for member name. The methods are the same as
247 -- for io.openbinaryin.
248 -- - close()
249 -- Close the file. Any opened substreams are invalidated.
251 -- Class ArchiveOut:
252 -- - member(string name)
253 -- Open substream for member name. The methods are the same as for io.opentextout. Note that
254 -- previous member must be closed before next can open.
255 -- - member_binary(string name)
256 -- Open binary (four to five) substream for member name. The methods are the same as
257 -- for io.openbinaryout. Note that previous substream must be closed before next can open.
258 -- - commit()
259 -- Commit the file. No substream may be open. Closes the file.
260 -- - rollback()
261 -- Rollback the file. No substream may be open. Closes the file.
263 -- - io.open(string name, string mode) -> BinaryFile
264 -- Open file named @name in specified mode. The mode can be 'r' (read only) or 'rw' (read and
265 -- write).
266 -- - io.open_read(string name) -> BinaryInput
267 -- Open file named @name as binary input stream.
268 -- - io.open_write(string name) -> BinaryOutput
269 -- Open file named @name as binary input stream.
270 -- - io.open_arch_read(string name) -> ArchiveIn
271 -- Open file named @name as input archive.
272 -- - io.open_arch_write(string name) -> ArchiveOut
273 -- Open file named @name as output archive.
274 -- - io.mkdir(string name)
275 -- Create directory name. Returns name created on success, nil on failure.
276 -- - io.unlink(string name)
277 -- Delete file/directory name. Returns name deleted on success, nil on failure.
278 -- - io.rename(string old, string new)
279 -- Rename file old -> new. Returns old, new on success, nil on failure.
288 local handle, err, chunk, indication, k, v;
290 local loadmod = loadmodule;
291 loadmodule = nil;
293 local export_module_in = function(tab, modname, prefix)
294 local fun = loadmod(modname);
295 for k, v in pairs(fun) do
296 tab[(prefix or "") .. k] = v;
300 jpcrr = {};
301 jpcrr.hud = {};
302 bit = {};
303 io = {};
305 export_module_in(jpcrr, "org.jpc.luaextensions.Base");
306 export_module_in(jpcrr, "org.jpc.luaextensions.InputDevices");
307 export_module_in(jpcrr, "org.jpc.luaextensions.ComponentCoding", "component_");
308 export_module_in(bit, "org.jpc.luaextensions.Bitops");
310 -- Few misc functions.
311 assert = function(val, err)
312 if (not val) and err then
313 error(err);
315 return val;
318 modulus_split = function(number, ...)
319 local dividers = {...};
320 local results = {};
321 local rem;
323 for k, v in ipairs(dividers) do
324 rem = number % v;
325 table.insert(results, (number - rem) / v);
326 number = rem;
329 table.insert(results, number);
330 return unpack(results);
333 local getmtable = getmetatable;
334 local toString = tostring;
335 local inject_binary_file;
336 local inject_binary_input;
337 local inject_binary_output;
338 local inject_text_input;
339 local inject_text_output;
340 local inject_archive_input;
341 local inject_archive_output;
343 -- Class member injectors.
344 inject_binary_file = function(obj, name)
345 local _name = name;
346 getmtable(obj).name = function(obj)
347 return _name;
349 getmtable(obj).__index = function(tab, name)
350 local x = getmtable(obj)[name];
351 if x then
352 return x;
354 error("Invalid method " .. name .. " for BinaryFile");
356 return obj;
359 inject_binary_input = function(obj, name)
360 local _name = name;
361 local old_four_to_five = getmtable(obj).four_to_five;
362 local old_inflate = getmtable(obj).inflate;
363 local old_text = getmtable(obj).text;
364 local old_read = getmtable(obj).read;
366 getmtable(obj).name = function(obj)
367 return _name;
369 getmtable(obj).four_to_five = function(obj)
370 local res, err;
371 res, err = old_four_to_five(obj);
372 if not res then
373 return res, err;
375 return inject_binary_input(res, "four-to-five<" .. _name .. ">");
377 getmtable(obj).inflate = function(obj)
378 local res, err;
379 res, err = old_inflate(obj);
380 if not res then
381 return res, err;
383 return inject_binary_input(res, "inflate<" .. _name .. ">");
385 getmtable(obj).text = function(obj)
386 local res, err;
387 res, err = old_text(obj);
388 if not res then
389 return res, err;
391 return inject_text_input(res, "text<" .. _name .. ">");
393 getmtable(obj).read = function(obj, toread)
394 if toread then
395 return old_read(obj, toread);
396 else
397 local res = "";
398 local ret, err;
399 while true do
400 ret, err = old_read(obj, 16384);
401 if not ret then
402 if not err then
403 return res;
405 return nil, err;
407 res = res .. ret;
411 getmtable(obj).__index = function(tab, name)
412 local x = getmtable(obj)[name];
413 if x then
414 return x;
416 error("Invalid method " .. name .. " for BinaryInput");
418 return obj;
421 inject_binary_output = function(obj, name)
422 local _name = name;
423 local old_four_to_five = getmtable(obj).four_to_five;
424 local old_deflate = getmtable(obj).deflate;
425 local old_text = getmtable(obj).text;
427 getmtable(obj).name = function(obj)
428 return _name;
430 getmtable(obj).four_to_five = function(obj)
431 local res, err;
432 res, err = old_four_to_five(obj);
433 if not res then
434 return res, err;
436 return inject_binary_output(res, "four-to-five<" .. _name .. ">");
438 getmtable(obj).deflate = function(obj)
439 local res, err;
440 res, err = old_deflate(obj);
441 if not res then
442 return res, err;
444 return inject_binary_output(res, "deflate<" .. _name .. ">");
446 getmtable(obj).text = function(obj)
447 local res, err;
448 res, err = old_text(obj);
449 if not res then
450 return res, err;
452 return inject_text_output(res, "text<" .. _name .. ">");
454 getmtable(obj).__index = function(tab, name)
455 local x = getmtable(obj)[name];
456 if x then
457 return x;
459 error("Invalid method " .. name .. " for BinaryOutput");
461 return obj;
464 inject_text_input = function(obj, name)
465 local _name = name;
466 getmtable(obj).lines = function(obj)
467 return function(state, prevline)
468 return state:read();
469 end, obj, nil;
471 getmtable(obj).name = function(obj)
472 return _name;
474 getmtable(obj).__index = function(tab, name)
475 local x = getmtable(obj)[name];
476 if x then
477 return x;
479 error("Invalid method " .. name .. " for TextInput");
481 return obj;
484 inject_text_output = function(obj, name)
485 local _name = name;
486 getmtable(obj).name = function(obj)
487 return _name;
489 getmtable(obj).__index = function(tab, name)
490 local x = getmtable(obj)[name];
491 if x then
492 return x;
494 error("Invalid method " .. name .. " for TextOutput");
496 return obj;
499 inject_archive_input = function(obj, name)
500 local _name = name;
501 local old_member = getmtable(obj).member;
502 getmtable(obj).member = function(obj, member)
503 local res, err;
504 res, err = old_member(obj, member);
505 if not res then
506 return res, err;
508 return inject_binary_input(res, _name .. "[" .. member .. "]");
510 getmtable(obj).name = function(obj)
511 return _name;
513 getmtable(obj).__index = function(tab, name)
514 local x = getmtable(obj)[name];
515 if x then
516 return x;
518 error("Invalid method " .. name .. " for ArchiveInput");
520 return obj;
523 inject_archive_output = function(obj, name)
524 local _name = name;
525 local old_member = getmtable(obj).member;
526 getmtable(obj).member = function(obj, member)
527 local res, err;
528 res, err = old_member(obj, member);
529 if not res then
530 return res, err;
532 return inject_binary_output(res, _name .. "[" .. member .. "]");
534 getmtable(obj).name = function(obj)
535 return _name;
537 getmtable(obj).__index = function(tab, name)
538 local x = getmtable(obj)[name];
539 if x then
540 return x;
542 error("Invalid method " .. name .. " for ArchiveOutput");
544 return obj;
548 -- Redefined print.
550 local rprint = print_console_msg;
551 print_console_msg = nil;
552 print = function(...)
553 local x = "";
554 local y = {...};
555 local i;
556 for i = 1,#y do
557 if i > 1 then
558 x = x .. "\t" .. toString(y[i]);
559 else
560 x = toString(y[i]);
563 rprint(x);
565 print_console_msg = nil;
568 -- I/O routines.
569 local stringfind = string.find;
570 local randname = loadmod("org.jpc.luaextensions.DelayedDelete").random_temp_name;
571 local path = args["luapath"] or ".";
572 local toresourcename = function(resname)
573 if not resname then
574 return randname(path .. "/", "luatemp-");
577 if not stringfind(resname, "[%d%l%u_%-]") then
578 error("Bad resource name (case 1): " .. resname);
580 if stringfind(resname, "^/") then
581 error("Bad resource name (case 2): " .. resname);
583 if stringfind(resname, "%.%.") then
584 error("Bad resource name (case 3): " .. resname);
586 if stringfind(resname, "\\") then
587 error("Bad resource name (case 4): " .. resname);
590 return resname, path .. "/" .. resname;
595 local openbinin = loadmod("org.jpc.luaextensions.BinaryInFile").open;
596 local openbinout = loadmod("org.jpc.luaextensions.BinaryOutFile").open;
597 local openarchin = loadmod("org.jpc.luaextensions.ArchiveIn").open;
598 local openarchout = loadmod("org.jpc.luaextensions.ArchiveOut").open;
599 local openbinary = loadmod("org.jpc.luaextensions.BinaryFile").open;
601 local baseFS = loadmod("org.jpc.luaextensions.BaseFSOps");
602 local mkdir = baseFS.mkdir;
603 local unlink = baseFS.unlink;
604 local rename = baseFS.rename;
606 local getmtable = getmetatable;
608 loadfile = function(_script)
609 local file, file2, err, content;
610 local x, y;
611 x, y = toresourcename(_script);
612 file, err = openbinin(y, "r");
613 if not file then
614 return nil, "Can't open " .. _script .. ": " .. err;
616 file2, err = file:text();
617 if not file2 then
618 return nil, "Can't transform " .. _script .. ": " .. err;
620 content = "";
621 line = file2:read();
622 while line do
623 content = content .. line .. "\n";
624 line = file2:read();
626 file2:close();
627 file:close();
628 return loadstring(content, _script);
631 io.open = function(name, mode)
632 local _name;
633 local res, err;
634 local y;
635 _name, y = toresourcename(name);
636 res, err = openbinary(y, mode);
637 if not res then
638 return res, err;
640 return inject_binary_file(res, _name);
643 io.open_arch_read = function(name)
644 local _name = name;
645 local res, err;
646 local y;
647 _name, y = toresourcename(name);
648 res, err = openarchin(y);
649 if not res then
650 return res, err;
652 return inject_archive_input(res, _name);
655 io.open_arch_write = function(name)
656 local _name = name;
657 local res, err;
658 local y;
659 _name, y = toresourcename(name);
660 res, err = openarchout(y);
661 if not res then
662 return res, err;
664 return inject_archive_output(res, _name);
667 io.open_read = function(name)
668 local _name = name;
669 local res, err;
670 local y;
671 _name, y = toresourcename(name);
672 res, err = openbinin(y);
673 if not res then
674 return res, err;
676 return inject_binary_input(res, _name);
679 io.open_write = function(name)
680 local _name = name;
681 local res, err;
682 local y;
683 _name, y = toresourcename(name);
684 res, err = openbinout(y);
685 if not res then
686 return res, err;
688 return inject_binary_output(res, _name);
691 io.mkdir = function(name)
692 local _name, y;
693 _name, y = toresourcename(name);
694 if mkdir(y) then
695 return _name;
696 else
697 return nil;
701 io.unlink = function(name)
702 local _name, y;
703 _name, y = toresourcename(name);
704 if unlink(y) then
705 return _name;
706 else
707 return nil;
711 io.rename = function(name1, name2)
712 local _name, y;
713 local _name2, y2;
714 _name, y = toresourcename(name1);
715 _name2, y2 = toresourcename(name2);
716 if rename(y, y2) then
717 return _name, _name2;
718 else
719 return nil;
724 jpcrr.next_frame = function(name)
725 while true do
726 if not jpcrr.pc_connected() then
727 jpcrr.wait_pc_attach();
729 if jpcrr.in_frame_hold() then
730 jpcrr.release_vga();
732 if jpcrr.wait_vga() then
733 return;
739 -- Various stuff built on top of ECI.
740 local invoke = jpcrr.invoke;
741 local invokecall = jpcrr.call;
742 local invokesync = jpcrr.invoke_synchronous;
744 jpcrr.save_state = function(name)
745 local _name, _fname;
746 _name, _fname = toresourcename(name);
747 invokesync("state-save", {_fname});
748 return _name;
751 jpcrr.save_movie = function(name)
752 local _name, _fname;
753 _name, _fname = toresourcename(name);
754 invokesync("movie-save", {_name});
755 return _name;
758 jpcrr.load_state_normal = function(name)
759 local _name, _fname;
760 _name, _fname = toresourcename(name);
761 invokesync("state-load", {_name});
762 return _name;
765 jpcrr.load_state_preserve_events = function(name)
766 local _name, _fname;
767 _name, _fname = toresourcename(name);
768 invokesync("state-load-noevents", {_name});
769 return _name;
772 jpcrr.load_state_movie = function(name)
773 local _name, _fname;
774 _name, _fname = toresourcename(name);
775 invokesync("state-load-movie", {_name});
776 return _name;
779 jpcrr.assemble = function()
780 invokesync("pc-assemble");
783 jpcrr.change_authors = function()
784 invokesync("change-authors");
787 jpcrr.ram_dump = function(name, binary)
788 local _name, _fname;
789 _name, _fname = toresourcename(name);
790 if binary then
791 invokesync("ram-dump-binary", {_name});
792 else
793 invokesync("ram-dump-text", {_name});
795 return _name;
798 jpcrr.hud.left_gap = function(f, g)
799 invoke("hud-left-gap", {toString(f), toString(g)});
802 jpcrr.hud.right_gap = function(f, g)
803 invoke("hud-right-gap", {toString(f), toString(g)});
806 jpcrr.hud.top_gap = function(f, g)
807 invoke("hud-top-gap", {toString(f), toString(g)});
810 jpcrr.hud.bottom_gap = function(f, g)
811 invoke("hud-bottom-gap", {toString(f), toString(g)});
814 jpcrr.hud.white_solid_box = function(f, x, y, w, h)
815 invoke("hud-white-solid-box", {toString(f), toString(x), toString(y), toString(w), toString(h)});
818 jpcrr.hud.box = function(f, x, y, w, h, t, lr, lg, lb, la, fr, fg, fb, fa)
819 invoke("hud-box", {toString(f), toString(x), toString(y), toString(w), toString(h),
820 toString(t), toString(lr), toString(lg), toString(lb), toString(la), toString(fr),
821 toString(fg), tostring(fb), toString(fa)});
824 jpcrr.hud.bitmap = function(f, x, y, bmap, lr, lg, lb, la, fr, fg, fb, fa)
825 invoke("hud-bitmap", {toString(f), toString(x), toString(y), bmap, toString(lr),
826 toString(lg), toString(lb), toString(la), toString(fr), toString(fg), tostring(fb),
827 toString(fa)});
830 jpcrr.hud.bitmap_binary = function(f, x, y, bmap, lr, lg, lb, la, fr, fg, fb, fa)
831 invoke("hud-bitmap-binary", {toString(f), toString(x), toString(y), bmap, toString(lr),
832 toString(lg), toString(lb), toString(la), toString(fr), toString(fg), tostring(fb),
833 toString(fa)});
836 jpcrr.set_pccontrol_pos = function(x, y)
837 invokesync("pccontrol-setwinpos", {toString(x), toString(y)});
840 jpcrr.set_luaplugin_pos = function(x, y)
841 invokesync("luaplugin-setwinpos", {toString(x), toString(y)});
844 jpcrr.set_pcmonitor_pos = function(x, y)
845 invokesync("pcmonitor-setwinpos", {toString(x), toString(y)});
848 jpcrr.set_pcstartstoptest_pos = function(x, y)
849 invokesync("pcstartstoptest-setwinpos", {toString(x), toString(y)});
852 jpcrr.set_virtualkeyboard_pos = function(x, y)
853 invokesync("virtualkeyboard-setwinpos", {toString(x), toString(y)});
856 jpcrr.exit = function()
857 invokesync("luaplugin-terminate");
860 jpcrr.pc_start = function()
861 invoke("pc-start");
864 jpcrr.pc_stop = function()
865 invokesync("pc-stop");
868 jpcrr.vretrace_start_trap = function(is_on)
869 if is_on then
870 invokesync("trap-vretrace-start-on");
871 else
872 invokesync("trap-vretrace-start-off");
876 jpcrr.vretrace_end_trap = function(is_on)
877 if is_on then
878 invokesync("trap-vretrace-end-on");
879 else
880 invokesync("trap-vretrace-end-off");
884 jpcrr.timed_trap = function(nsecs)
885 if nsecs then
886 invokesync("trap-timed", {toString(nsecs)});
887 else
888 invokesync("trap-timed-disable");
892 jpcrr.write_byte = function(addr, value)
893 invokesync("memory-write", {toString(addr), toString(value), "1"});
896 jpcrr.write_word = function(addr, value)
897 invokesync("memory-write", {toString(addr), toString(value), "2"});
900 jpcrr.write_dword = function(addr, value)
901 invokesync("memory-write", {toString(addr), toString(value), "4"});
904 jpcrr.read_byte = function(addr)
905 local t = {toString(addr), "1"};
906 t = invokecall("memory-read", t);
907 return (t or {})[1];
910 jpcrr.read_word = function(addr)
911 local t = {toString(addr), "2"};
912 t = invokecall("memory-read", t);
913 return (t or {})[1];
916 jpcrr.read_dword = function(addr)
917 local t = {toString(addr), "4"};
918 t = invokecall("memory-read", t);
919 return (t or {})[1];
922 jpcrr.invoke = nil;
923 jpcrr.invoke_synchronous = nil;
924 jpcrr.call = null
926 -- Dofile.
927 dofile = function(_script)
928 local chunk, err, indication
929 chunk, err = loadfile(_script);
930 if not chunk then
931 error("Kernel: Can't load subscript " .. _script .. ": " .. err);
933 return chunk();
936 local args2 = args;
937 args = null;
938 args = {};
939 for k, v in pairs(args2) do
940 if (#k > 2 and string.byte(k, 1) == 120 and string.byte(k, 2) == 45) then
941 args[string.sub(k, 3)] = v;
944 jpcrr_raw = null;
947 chunk = null;
948 loaded, err = pcall(function()
949 chunk, err = loadfile(script);
950 if not chunk then
951 error(err);
953 end);
954 if not loaded then
955 print("Kernel: Can't load script " .. script .. ": " .. err);
956 invoke("luaplugin-terminate");
957 while true do end
960 script = null;
961 indication, err = pcall(chunk);
962 if not indication then
963 print("Kernel: Unprotected error in script: " .. err);
964 invoke("luaplugin-terminate");
965 while true do end