2 -- Copyright 2009 Ilari Liusvaara
4 -- Licenced under GNU GPL v2.
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
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
24 -- - bit.any(number...)
25 -- Returns 48-bit number that has those bits set that are set in any of its
27 -- - bit.parity(number...)
28 -- Returns 48-bit number that has those bits set that are set in even number
30 -- - bit.any(number...)
31 -- Returns 48-bit number that has those bits set that are set in all of its
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
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.
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 bitmal with specified foreground color and background color.
95 -- - jpcrr.component_encode(table components)
96 -- Return component encoding for specified components.
97 -- - jpcrr.component_decode(string line)
98 -- Return component decoding for specified line, nil/nil if it doesn't encode
99 -- anything, nil/string if parse error occurs (the error is the second return).
100 -- - jpcrr.save_state(string name)
101 -- Savestate into specified file. Returns name used.
102 -- - jpcrr.save_movie(string name)
103 -- Save movie into specified file. Returns name used.
104 -- - jpcrr.load_state_normal(string name)
105 -- Load specified savestate. Returns name used.
106 -- - jpcrr.load_state_preserve_events(string name)
107 -- Load specified savestate, preserving events. Returns name used.
108 -- - jpcrr.load_state_movie(string name)
109 -- Load specified savestate as movie. Returns name used.
110 -- - jpcrr.assemble()
111 -- Open system settings dialog.
112 -- - jpcrr.change_authors()
113 -- Open change authors dialog.
114 -- - jpcrr.exit = function()
116 -- - jpcrr.ram_dump(string name, boolean binary)
117 -- Dump PC memory to specified file. If binary is true, dump is binary, otherwise
118 -- textual hexadecimal dump.
119 -- - jpcrr.write_byte(number addr, number value)
120 -- Write byte to specified physical address.
121 -- - jpcrr.write_word(number addr, number value)
122 -- Write word to specified physical address (little endian).
123 -- - jpcrr.write_dword(number addr, number value)
124 -- Write dword to specified physical address (little endian).
125 -- - jpcrr.read_byte(number addr)
126 -- Return byte from specified physical address.
127 -- - jpcrr.read_word(number addr)
128 -- Return word from specified physical address (little endian).
129 -- - jpcrr.read_dword(number addr)
130 -- Return dword from specified physical address (little endian).
131 -- - jpcrr.timed_trap(number nsecs)
132 -- Set trap after specified number of nanoseconds. Use nil as nsecs to disable.
133 -- - jpcrr.vretrace_start_trap(boolean is_on)
134 -- Set trap on vretrace start on/off.
135 -- - jpcrr.vretrace_end_trap(boolean is_on)
136 -- Set trap on vretrace end on/off.
137 -- - jpcrr.pc_start()
138 -- Start PC execution.
140 -- Stop PC execution.
141 -- - jpcrr.set_pccontrol_pos(number x, number y)
142 -- Set position of PCControl window.
143 -- - jpcrr.set_luaplugin_pos(number x, number y)
144 -- Set position of LuaPlugin window.
145 -- - jpcrr.set_pcmonitor_pos(number x, number y)
146 -- Set position of PCMonitor window.
147 -- - jpcrr.set_pcstartstoptest_pos(number x, number y)
148 -- Set position of PCStartStopTest window.
149 -- - jpcrr.set_virtualkeyboard_pos(number x, number y)
150 -- Set position of VirtualKeyboard window.
152 -- I/O functions have the following conventions. If function returns any real data, the first
153 -- return value returns this data or is nil. Otherwise first return value is true or false.
154 -- If first return value is nil or false, then the second return value gives textual error
155 -- message for failed operation, or is nil if EOF occured before anything was read.
157 -- Unlink, rename and mkdir don't follow this pattern. They just return true/false to signal
158 -- success or failure.
160 -- Specifying nil as name of file results random filename being used (it even works with unlink,
161 -- mkdir, rename and read-only access, but doesn't make any sense there).
163 -- Class: BinaryFile:
164 -- Binary file for RO or RW access. Methods are as follows:
166 -- Return name of file.
168 -- Return length of file.
169 -- - set_length(number length)
170 -- Truncate file to specified length
171 -- - read(number offset, number length)
172 -- Read up to length bytes from offset.
173 -- - write(number offset, string content)
174 -- Write content to specified offset.
177 -- Class: BinaryInput:
178 -- Binary file for sequential input. Methods are as follows:
180 -- Return name of file.
182 -- Return BinaryInput that is four to five decoding of this stream.
184 -- Return stream as TextInput.
186 -- Return BinaryInput that is inflate of this stream.
187 -- - read(number bytes)
188 -- Read up to bytes bytes from file.
190 -- Read the entiere file at once.
193 -- Character set for binary files is Latin-1.
195 -- Class: BinaryOutput:
196 -- Binary file for sequential output. Methods are as follows:
198 -- Return name of file.
200 -- Return BinaryOutput that writes four to five encoded output to this stream.
202 -- Return stream as TextOutput.
204 -- Return BinaryOutput that writes deflate output to this stream.
205 -- - write(string content)
206 -- Write string to file.
209 -- Character set for binary files is Latin-1.
213 -- Return name of file.
215 -- Read line from file.
216 -- - read_component()
217 -- Read next componented line into array.
219 -- Line iterator function.
222 -- Character set for text files is UTF-8.
224 -- Class: TextOutput:
226 -- Return name of file.
227 -- - write(string line)
228 -- Write line line to file.
229 -- - write_component(table components)
230 -- Write componented line.
233 -- Character set for text files is UTF-8.
236 -- - member(string name)
237 -- Open substream for member name. The methods are the same as for io.opentextin.
238 -- - member_binary(string name)
239 -- Open binary (four to five) substream for member name. The methods are the same as
240 -- for io.openbinaryin.
242 -- Close the file. Any opened substreams are invalidated.
245 -- - member(string name)
246 -- Open substream for member name. The methods are the same as for io.opentextout. Note that
247 -- previous member must be closed before next can open.
248 -- - member_binary(string name)
249 -- Open binary (four to five) substream for member name. The methods are the same as
250 -- for io.openbinaryout. Note that previous substream must be closed before next can open.
252 -- Commit the file. No substream may be open. Closes the file.
254 -- Rollback the file. No substream may be open. Closes the file.
256 -- - io.open(string name, string mode) -> BinaryFile
257 -- Open file named @name in specified mode. The mode can be 'r' (read only) or 'rw' (read and
259 -- - io.open_read(string name) -> BinaryInput
260 -- Open file named @name as binary input stream.
261 -- - io.open_write(string name) -> BinaryOutput
262 -- Open file named @name as binary input stream.
263 -- - io.open_arch_read(string name) -> ArchiveIn
264 -- Open file named @name as input archive.
265 -- - io.open_arch_write(string name) -> ArchiveOut
266 -- Open file named @name as output archive.
267 -- - io.mkdir(string name)
268 -- Create directory name. Returns name created on success, nil on failure.
269 -- - io.unlink(string name)
270 -- Delete file/directory name. Returns name deleted on success, nil on failure.
271 -- - io.rename(string old, string new)
272 -- Rename file old -> new. Returns old, new on success, nil on failure.
281 local handle
, err
, chunk
, indication
, k
, v
;
283 local loadmod
= loadmodule
;
286 local export_module_in
= function(tab
, modname
, prefix
)
287 local fun
= loadmod(modname
);
288 for k
, v
in pairs(fun
) do
289 tab
[(prefix
or "") .. k
] = v
;
298 export_module_in(jpcrr
, "org.jpc.luaextensions.Base");
299 export_module_in(jpcrr
, "org.jpc.luaextensions.ComponentCoding", "component_");
300 export_module_in(bit
, "org.jpc.luaextensions.Bitops");
302 -- Few misc functions.
303 assert = function(val
, err
)
304 if (not val
) and err
then
310 modulus_split
= function(number, ...)
311 local dividers
= {...};
315 for k
, v
in ipairs(dividers
) do
317 table.insert(results
, (number - rem
) / v
);
321 table.insert(results
, number);
322 return unpack(results
);
325 local getmtable
= getmetatable
;
326 local toString
= tostring;
327 local inject_binary_file
;
328 local inject_binary_input
;
329 local inject_binary_output
;
330 local inject_text_input
;
331 local inject_text_output
;
332 local inject_archive_input
;
333 local inject_archive_output
;
335 -- Class member injectors.
336 inject_binary_file
= function(obj
, name
)
338 getmtable(obj
).name
= function(obj
)
341 getmtable(obj
).__index
= function(tab
, name
)
342 local x
= getmtable(obj
)[name
];
346 error("Invalid method " .. name
.. " for BinaryFile");
351 inject_binary_input
= function(obj
, name
)
353 local old_four_to_five
= getmtable(obj
).four_to_five
;
354 local old_inflate
= getmtable(obj
).inflate
;
355 local old_text
= getmtable(obj
).text
;
356 local old_read
= getmtable(obj
).read;
358 getmtable(obj
).name
= function(obj
)
361 getmtable(obj
).four_to_five
= function(obj
)
363 res
, err
= old_four_to_five(obj
);
367 return inject_binary_input(res
, "four-to-five<" .. _name
.. ">");
369 getmtable(obj
).inflate
= function(obj
)
371 res
, err
= old_inflate(obj
);
375 return inject_binary_input(res
, "inflate<" .. _name
.. ">");
377 getmtable(obj
).text
= function(obj
)
379 res
, err
= old_text(obj
);
383 return inject_text_input(res
, "text<" .. _name
.. ">");
385 getmtable(obj
).read = function(obj
, toread
)
387 return old_read(obj
, toread
);
392 ret
, err
= old_read(obj
, 16384);
403 getmtable(obj
).__index
= function(tab
, name
)
404 local x
= getmtable(obj
)[name
];
408 error("Invalid method " .. name
.. " for BinaryInput");
413 inject_binary_output
= function(obj
, name
)
415 local old_four_to_five
= getmtable(obj
).four_to_five
;
416 local old_deflate
= getmtable(obj
).deflate
;
417 local old_text
= getmtable(obj
).text
;
419 getmtable(obj
).name
= function(obj
)
422 getmtable(obj
).four_to_five
= function(obj
)
424 res
, err
= old_four_to_five(obj
);
428 return inject_binary_output(res
, "four-to-five<" .. _name
.. ">");
430 getmtable(obj
).deflate
= function(obj
)
432 res
, err
= old_deflate(obj
);
436 return inject_binary_output(res
, "deflate<" .. _name
.. ">");
438 getmtable(obj
).text
= function(obj
)
440 res
, err
= old_text(obj
);
444 return inject_text_output(res
, "text<" .. _name
.. ">");
446 getmtable(obj
).__index
= function(tab
, name
)
447 local x
= getmtable(obj
)[name
];
451 error("Invalid method " .. name
.. " for BinaryOutput");
456 inject_text_input
= function(obj
, name
)
458 getmtable(obj
).lines
= function(obj
)
459 return function(state
, prevline
)
463 getmtable(obj
).name
= function(obj
)
466 getmtable(obj
).__index
= function(tab
, name
)
467 local x
= getmtable(obj
)[name
];
471 error("Invalid method " .. name
.. " for TextInput");
476 inject_text_output
= function(obj
, name
)
478 getmtable(obj
).name
= function(obj
)
481 getmtable(obj
).__index
= function(tab
, name
)
482 local x
= getmtable(obj
)[name
];
486 error("Invalid method " .. name
.. " for TextOutput");
491 inject_archive_input
= function(obj
, name
)
493 local old_member
= getmtable(obj
).member
;
494 getmtable(obj
).member
= function(obj
, member
)
496 res
, err
= old_member(obj
, member
);
500 return inject_binary_input(res
, _name
.. "[" .. member
.. "]");
502 getmtable(obj
).name
= function(obj
)
505 getmtable(obj
).__index
= function(tab
, name
)
506 local x
= getmtable(obj
)[name
];
510 error("Invalid method " .. name
.. " for ArchiveInput");
515 inject_archive_output
= function(obj
, name
)
517 local old_member
= getmtable(obj
).member
;
518 getmtable(obj
).member
= function(obj
, member
)
520 res
, err
= old_member(obj
, member
);
524 return inject_binary_output(res
, _name
.. "[" .. member
.. "]");
526 getmtable(obj
).name
= function(obj
)
529 getmtable(obj
).__index
= function(tab
, name
)
530 local x
= getmtable(obj
)[name
];
534 error("Invalid method " .. name
.. " for ArchiveOutput");
542 local rprint
= print_console_msg
;
543 print_console_msg
= nil;
544 print = function(...)
550 x
= x
.. "\t" .. toString(y
[i
]);
557 print_console_msg
= nil;
561 local stringfind
= string.find
;
562 local randname
= loadmod("org.jpc.luaextensions.DelayedDelete").random_temp_name
;
563 local path
= args
["luapath"] or ".";
564 local toresourcename
= function(resname
)
566 return randname(path
.. "/", "luatemp-");
569 if not stringfind(resname
, "[%d%l%u_%-]") then
570 error("Bad resource name (case 1): " .. resname
);
572 if stringfind(resname
, "^/") then
573 error("Bad resource name (case 2): " .. resname
);
575 if stringfind(resname
, "%.%.") then
576 error("Bad resource name (case 3): " .. resname
);
578 if stringfind(resname
, "\\") then
579 error("Bad resource name (case 4): " .. resname
);
582 return resname
, path
.. "/" .. resname
;
587 local openbinin
= loadmod("org.jpc.luaextensions.BinaryInFile").open
;
588 local openbinout
= loadmod("org.jpc.luaextensions.BinaryOutFile").open
;
589 local openarchin
= loadmod("org.jpc.luaextensions.ArchiveIn").open
;
590 local openarchout
= loadmod("org.jpc.luaextensions.ArchiveOut").open
;
591 local openbinary
= loadmod("org.jpc.luaextensions.BinaryFile").open
;
593 local baseFS
= loadmod("org.jpc.luaextensions.BaseFSOps");
594 local mkdir
= baseFS
.mkdir
;
595 local unlink
= baseFS
.unlink
;
596 local rename = baseFS
.rename;
598 local getmtable
= getmetatable
;
600 loadfile
= function(_script
)
601 local file
, file2
, err
, content
;
603 x
, y
= toresourcename(_script
);
604 file
, err
= openbinin(y
, "r");
606 return nil, "Can't open " .. _script
.. ": " .. err
;
608 file2
, err
= file
:text();
610 return nil, "Can't transform " .. _script
.. ": " .. err
;
615 content
= content
.. line
.. "\n";
620 return loadstring(content
, _script
);
623 io
.open
= function(name
, mode
)
627 _name
, y
= toresourcename(name
);
628 res
, err
= openbinary(y
, mode
);
632 return inject_binary_file(res
, _name
);
635 io
.open_arch_read
= function(name
)
639 _name
, y
= toresourcename(name
);
640 res
, err
= openarchin(y
);
644 return inject_archive_input(res
, _name
);
647 io
.open_arch_write
= function(name
)
651 _name
, y
= toresourcename(name
);
652 res
, err
= openarchout(y
);
656 return inject_archive_output(res
, _name
);
659 io
.open_read
= function(name
)
663 _name
, y
= toresourcename(name
);
664 res
, err
= openbinin(y
);
668 return inject_binary_input(res
, _name
);
671 io
.open_write
= function(name
)
675 _name
, y
= toresourcename(name
);
676 res
, err
= openbinout(y
);
680 return inject_binary_output(res
, _name
);
683 io
.mkdir
= function(name
)
685 _name
, y
= toresourcename(name
);
693 io
.unlink
= function(name
)
695 _name
, y
= toresourcename(name
);
703 io
.rename = function(name1
, name2
)
706 _name
, y
= toresourcename(name1
);
707 _name2
, y2
= toresourcename(name2
);
708 if rename(y
, y2
) then
709 return _name
, _name2
;
716 jpcrr
.next_frame
= function(name
)
718 if not jpcrr
.pc_connected() then
719 jpcrr
.wait_pc_attach();
721 if jpcrr
.in_frame_hold() then
724 if jpcrr
.wait_vga() then
731 -- Various stuff built on top of ECI.
732 local invoke
= jpcrr
.invoke
;
733 local invokecall
= jpcrr
.call;
734 local invokesync
= jpcrr
.invoke_synchronous
;
736 jpcrr
.save_state
= function(name
)
738 _name
, _fname
= toresourcename(name
);
739 invokesync("state-save", {_fname
});
743 jpcrr
.save_movie
= function(name
)
745 _name
, _fname
= toresourcename(name
);
746 invokesync("movie-save", {_name
});
750 jpcrr
.load_state_normal
= function(name
)
752 _name
, _fname
= toresourcename(name
);
753 invokesync("state-load", {_name
});
757 jpcrr
.load_state_preserve_events
= function(name
)
759 _name
, _fname
= toresourcename(name
);
760 invokesync("state-load-noevents", {_name
});
764 jpcrr
.load_state_movie
= function(name
)
766 _name
, _fname
= toresourcename(name
);
767 invokesync("state-load-movie", {_name
});
771 jpcrr
.assemble
= function()
772 invokesync("pc-assemble");
775 jpcrr
.change_authors
= function()
776 invokesync("change-authors");
779 jpcrr
.ram_dump
= function(name
, binary
)
781 _name
, _fname
= toresourcename(name
);
783 invokesync("ram-dump-binary", {_name
});
785 invokesync("ram-dump-text", {_name
});
790 jpcrr
.hud
.left_gap
= function(f
, g
)
791 invoke("hud-left-gap", {toString(f
), toString(g
)});
794 jpcrr
.hud
.right_gap
= function(f
, g
)
795 invoke("hud-right-gap", {toString(f
), toString(g
)});
798 jpcrr
.hud
.top_gap
= function(f
, g
)
799 invoke("hud-top-gap", {toString(f
), toString(g
)});
802 jpcrr
.hud
.bottom_gap
= function(f
, g
)
803 invoke("hud-bottom-gap", {toString(f
), toString(g
)});
806 jpcrr
.hud
.white_solid_box
= function(f
, x
, y
, w
, h
)
807 invoke("hud-white-solid-box", {toString(f
), toString(x
), toString(y
), toString(w
), toString(h
)});
810 jpcrr
.hud
.box
= function(f
, x
, y
, w
, h
, t
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
)
811 invoke("hud-box", {toString(f
), toString(x
), toString(y
), toString(w
), toString(h
),
812 toString(t
), toString(lr
), toString(lg
), toString(lb
), toString(la
), toString(fr
),
813 toString(fg
), tostring(fb
), toString(fa
)});
816 jpcrr
.hud
.bitmap
= function(f
, x
, y
, bmap
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
)
817 invoke("hud-bitmap", {toString(f
), toString(x
), toString(y
), bmap
, toString(lr
),
818 toString(lg
), toString(lb
), toString(la
), toString(fr
), toString(fg
), tostring(fb
),
822 jpcrr
.set_pccontrol_pos
= function(x
, y
)
823 invokesync("pccontrol-setwinpos", {toString(x
), toString(y
)});
826 jpcrr
.set_luaplugin_pos
= function(x
, y
)
827 invokesync("luaplugin-setwinpos", {toString(x
), toString(y
)});
830 jpcrr
.set_pcmonitor_pos
= function(x
, y
)
831 invokesync("pcmonitor-setwinpos", {toString(x
), toString(y
)});
834 jpcrr
.set_pcstartstoptest_pos
= function(x
, y
)
835 invokesync("pcstartstoptest-setwinpos", {toString(x
), toString(y
)});
838 jpcrr
.set_virtualkeyboard_pos
= function(x
, y
)
839 invokesync("virtualkeyboard-setwinpos", {toString(x
), toString(y
)});
842 jpcrr
.exit = function()
843 invokesync("luaplugin-terminate");
846 jpcrr
.pc_start
= function()
850 jpcrr
.pc_stop
= function()
851 invokesync("pc-stop");
854 jpcrr
.vretrace_start_trap
= function(is_on
)
856 invokesync("trap-vretrace-start-on");
858 invokesync("trap-vretrace-start-off");
862 jpcrr
.vretrace_end_trap
= function(is_on
)
864 invokesync("trap-vretrace-end-on");
866 invokesync("trap-vretrace-end-off");
870 jpcrr
.timed_trap
= function(nsecs
)
872 invokesync("trap-timed", {toString(nsecs
)});
874 invokesync("trap-timed-disable");
878 jpcrr
.write_byte
= function(addr
, value
)
879 invokesync("memory-write", {toString(addr
), toString(value
), "1"});
882 jpcrr
.write_word
= function(addr
, value
)
883 invokesync("memory-write", {toString(addr
), toString(value
), "2"});
886 jpcrr
.write_dword
= function(addr
, value
)
887 invokesync("memory-write", {toString(addr
), toString(value
), "4"});
890 jpcrr
.read_byte
= function(addr
)
891 local t
= {toString(addr
), "1"};
892 t
= invokecall("memory-read", t
);
896 jpcrr
.read_word
= function(addr
)
897 local t
= {toString(addr
), "2"};
898 t
= invokecall("memory-read", t
);
902 jpcrr
.read_dword
= function(addr
)
903 local t
= {toString(addr
), "4"};
904 t
= invokecall("memory-read", t
);
909 jpcrr
.invoke_synchronous
= nil;
913 dofile = function(_script
)
914 local chunk
, err
, indication
915 chunk
, err
= loadfile(_script
);
917 error("Kernel: Can't load subscript " .. _script
.. ": " .. err
);
925 for k
, v
in pairs(args2
) do
926 if (#k
> 2 and string.byte(k
, 1) == 120 and string.byte(k
, 2) == 45) then
927 args
[string.sub(k
, 3)] = v
;
933 chunk
, err
= loadfile(script
);
935 print("Kernel: Can't load script " .. script
.. ": " .. err
);
936 invoke("luaplugin-terminate");
941 indication
, err
= pcall(chunk
);
942 if not indication
then
943 print("Kernel: Unprotected error in script: " .. err
);
944 invoke("luaplugin-terminate");