1 win = jpcrr.window.create("Generic watch");
5 fieldpair = function(fname, label)
6 win:create_component({gridx = 0, gridy = y, gridwidth = 1, gridheight = 1, name = fname .. "_LABEL", type = "label", text = label,
7 fill = win:HORIZONTAL(), weightx = 0, weighty = 1});
8 win:create_component({gridx = 1, gridy = y, gridwidth = 1, gridheight = 1, name = fname, type = "label", text = "N/A",
9 fill = win:HORIZONTAL(), weightx = 1, weighty = 1, insets_left = 16});
13 update_field = function(fname, newval)
14 win:set_text(fname, tostring(newval));
21 add_field = function(name, update_fn)
22 fieldpair(name, name);
23 table.insert(fieldnames, name);
24 fieldupdates[name] = update_fn;
27 do_update = function()
28 for k, v in ipairs(fieldnames) do
29 update_field(v, fieldupdates[v]());
34 add_field("System time: ", function()
35 return tostring(jpcrr.clock_time());
38 add_field("Frame number: ", function()
39 return tostring(jpcrr.frame_number());
42 add_field("0x41A: ", function()
43 return tostring(jpcrr.read_word(0x41A) - 30);
46 add_field("0x41C: ", function()
47 return tostring(jpcrr.read_word(0x41C) - 30);
50 add_field("In flight: ", function()
51 return tostring(chars_in_flight);
55 add_field("BUF" .. i .. ": ", function()
56 return string.format("%04X", jpcrr.read_word(0x41E + 2 * i));
65 stopping_flag = false;
66 bios_delay = 100000000; --Assume 20MHz machine with paired IDE drives. (NEW 78ms)
67 first_post_bios_stop = true;
68 keyboard_input_to_feed = {};
69 keyboard_input_pointer = 1;
71 seen_first_char = false;
75 --In case something needs to be done here... VGA unlock is automatically preformed after return.
76 redraw_handler = function()
80 --Handle stop post bios delay. PC is automatically started after this.
81 handle_stop_post_bios_delay = function()
82 local nextchar = jpcrr.read_word(0x41A) - 30;
83 local lastchar = jpcrr.read_word(0x41C) - 30;
84 local olastchar = lastchar;
85 if lastchar < nextchar then
86 lastchar = lastchar + 32;
88 local keyboard_chars = (lastchar-nextchar)/2;
89 if keyboard_chars > 13 then
90 print("WARNING: Keyboard buffer possibly overflowing!");
92 --Character appeared out of flight?
93 if seen_first_char and last_lastchar ~= olastchar then
94 chars_in_flight = chars_in_flight - 1;
97 last_lastchar = olastchar;
98 seen_first_char = true;
99 --Only add more input if nextchar has changed.
100 if last_nextchar == nextchar then
103 last_nextchar = nextchar;
104 while keyboard_chars + chars_in_flight < 10 do
105 --Feed more characters
106 if not keyboard_input_to_feed[keyboard_input_pointer] then
107 -- No more input. Exit.
108 jpcrr.bios_kbd_trap(false);
111 if keyboard_input_to_feed[keyboard_input_pointer] == 54 and not keys_held[54] and keyboard_chars + chars_in_flight > 0 then
114 if keyboard_input_to_feed[keyboard_input_pointer] == 42 and not keys_held[42] and keyboard_chars + chars_in_flight > 0 then
117 if not is_async(keyboard_input_to_feed[keyboard_input_pointer]) then
118 chars_in_flight = chars_in_flight + 1;
121 press_or_release(keyboard_input_to_feed[keyboard_input_pointer]);
122 keyboard_input_pointer = keyboard_input_pointer + 1;
127 async_key_mask[29] = true; -- Left CTRL.
128 async_key_mask[42] = true; -- Left shift.
129 async_key_mask[56] = true; -- Left alt.
130 async_key_mask[58] = true; -- Caps lock.
131 async_key_mask[69] = true; -- Num lock.
132 async_key_mask[70] = true; -- Scroll lock.
133 async_key_mask[54] = true; -- Right shift
134 async_key_mask[95] = true; -- Unknown key (delay);
135 async_key_mask[157] = true; -- Right ctrl.
136 async_key_mask[184] = true; -- Right alt.
137 async_key_mask[255] = true; -- Pause.
139 -- Would this key be asynchronous now?
140 is_async = function(keynum)
141 -- Releases are always asynchronous.
142 if keys_held[keynum] then
145 -- Some keys are always asynchronous.
146 if async_key_mask[keynum] then
149 -- It is synchronous.
153 -- press or release specified key (255 = pause).
154 press_or_release = function(keynum)
155 if keynum == 255 then
156 jpcrr.sendevent("org.jpc.emulator.peripheral.Keyboard", "PAUSE");
158 jpcrr.sendevent("org.jpc.emulator.peripheral.Keyboard", "KEYEDGE", tostring(keynum));
159 keys_held[keynum] = not keys_held[keynum];
164 --This is called after redraw_handler if machine is stopping.
165 stop_handler = function()
166 if jpcrr.clock_time() < bios_delay then
169 if first_post_bios_stop then
170 --Set trap on keyboard and clear timed trap.
171 jpcrr.bios_kbd_trap(true);
172 jpcrr.timed_trap(nil);
173 first_post_bios_stop = false;
175 handle_stop_post_bios_delay();
180 file, err = io.open_read("/select input file");
182 error("Can't open file: " .. err);
184 file2, err = file:text();
186 error("Can't cast file to text: " .. err);
190 line, err = file2:read();
195 error("Can't read line: " .. err);
198 local num = tonumber(line);
200 error("Bad line: " .. line);
202 table.insert(keyboard_input_to_feed, num);
206 --Wait for the initial BIOS delay.
207 jpcrr.timed_trap(bios_delay);
211 event, arg = jpcrr.wait_event();
212 if event == "stop" then
213 stopping_flag = true;
215 if event == "lock" then
219 if stopping_flag then
222 stopping_flag = false;