rk86 2.0.10 → 2.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/rk86.js +103 -98
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rk86",
3
- "version": "2.0.10",
3
+ "version": "2.0.12",
4
4
  "description": "Эмулятор Радио-86РК (Intel 8080) для терминала",
5
5
  "bin": {
6
6
  "rk86": "rk86.js"
package/rk86.js CHANGED
@@ -1588,11 +1588,11 @@ var init_catalog_data = __esm(() => {
1588
1588
  ];
1589
1589
  });
1590
1590
 
1591
- // src/lib/rk86_terminal.ts
1591
+ // src/lib/terminal/rk86_terminal.ts
1592
1592
  import { existsSync } from "fs";
1593
1593
  import { readFile } from "fs/promises";
1594
1594
 
1595
- // src/lib/hex.ts
1595
+ // src/lib/core/hex.ts
1596
1596
  function hex(v, prefix) {
1597
1597
  return v.toString(16).toUpperCase();
1598
1598
  }
@@ -1612,7 +1612,7 @@ function fromHex(v) {
1612
1612
  return v;
1613
1613
  }
1614
1614
 
1615
- // src/lib/i8080.ts
1615
+ // src/lib/core/i8080.ts
1616
1616
  class I8080 {
1617
1617
  memory;
1618
1618
  io;
@@ -2462,7 +2462,7 @@ class I8080 {
2462
2462
  }
2463
2463
  }
2464
2464
 
2465
- // src/lib/rk86_file_parser.ts
2465
+ // src/lib/core/rk86_file_parser.ts
2466
2466
  var extract_rk86_word = function(v, i) {
2467
2467
  return (v[i] & 255) << 8 | v[i + 1] & 255;
2468
2468
  };
@@ -2542,12 +2542,12 @@ function extact_metadata(text) {
2542
2542
  return [...text.matchAll(/!([^ =\t\n\r]+?)=([^ \t\r\n]+)/g)].map((group) => group.slice(1)).reduce((a, [key, value]) => (a[key] = value, a), initial);
2543
2543
  }
2544
2544
 
2545
- // src/lib/rk86_font.ts
2545
+ // src/lib/core/rk86_font.ts
2546
2546
  function rk86_font_image() {
2547
2547
  return "data:image/bmp;base64," + "Qk0+IAAAAAAAAD4AAAAoAAAACAAAAAAIAAABAAEAAAAAAAAgAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAP///wAAAAAAGAAAABgAAAB+AAAAfgAAABgAAAAYAAAA" + "AAAAAAAAAAABAAAAAQAAAA8AAAAJAAAACQAAAAAAAAAAAAAAAQAAAD8AAAAq" + "AAAAKgAAACoAAAAqAAAAAAAAAAAAAAAAAAAADgAAAAEAAAAHAAAAAQAAAA4A" + "AAAAAAAAAAAAAAAAAAAfAAAAFQAAABUAAAAVAAAAFQAAAAAAAAAAAAAAAAAA" + "AA4AAAABAAAAAgAAAAkAAAAGAAAAAAAAAAAAAAAAAAAAGQAAABUAAAAZAAAA" + "EQAAABEAAAAAAAAAAAAAAAAAAAAOAAAACQAAAA4AAAAIAAAACAAAAAAAAAAA" + "AAAAAAAAAA4AAAAJAAAADgAAAAkAAAAOAAAAAAAAAAAAAAAAAAAAFQAAABUA" + "AAAOAAAAFQAAABUAAAAAAAAAAAAAAAAAAAAOAAAAAQAAAAcAAAAJAAAACQAA" + "AAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAfAAAAAAAAAAAAAAAAAAAA" + "BwAAAAgAAAAIAAAACAAAAAcAAAAAAAAAAAAAAAgAAAAIAAAACAAAAA4AAAAJ" + "AAAADgAAAAAAAAAAAAAAAAAAAAkAAAAFAAAABwAAAAkAAAAHAAAAAAAAAAAA" + "AAAAAAAACQAAAAkAAAAJAAAACQAAAA8AAAAAAAAAAAAAAAAAAAAGAAAACQAA" + "AAkAAAAJAAAABgAAAAAAAAAAAAAAAAAAAAkAAAAJAAAADwAAAAkAAAAJAAAA" + "AAAAAAAAAAAAAAAAEQAAABUAAAAVAAAAGwAAABEAAAAAAAAAAAAAAAAAAAAJ" + "AAAACQAAAAkAAAAFAAAAAwAAAAAAAAAAAAAAAAAAAAkAAAAKAAAADAAAAAoA" + "AAAJAAAAAAAAAAAAAAAAAAAACQAAAA0AAAALAAAACQAAAAkAAAAAAAAABgAA" + "AAAAAAAJAAAADQAAAAsAAAAJAAAACQAAAAAAAAAAAAAAAAAAAAkAAAAJAAAA" + "BgAAAAYAAAAJAAAAAAAAAAAAAAAAAAAACAAAAAgAAAAIAAAACAAAAA8AAAAA" + "AAAAAAAAAAQAAAAEAAAADgAAABUAAAAOAAAABAAAAAAAAAAAAAAAAAAAAAcA" + "AAAIAAAADgAAAAkAAAAGAAAAAAAAAAAAAAAAAAAADwAAAAEAAAAHAAAACQAA" + "AAYAAAAAAAAAAAAAAAEAAAAfAAAAEgAAABIAAAASAAAAEgAAAAAAAAAAAAAA" + "AAAAAA4AAAAJAAAADgAAAAgAAAAHAAAAAAAAAAAAAAAAAAAABgAAAAkAAAAH" + "AAAAAQAAAA4AAAAAAAAAAAAAAAAAAAASAAAAFQAAAB0AAAAVAAAAEgAAAAAA" + "AAAAAAAAAAAAAAQAAAAMAAAAHgAAAD8AAAAeAAAADAAAAAgAAAAAAAAAAQAA" + "AAMAAAAPAAAADAAAAAgAAAAAAAAAAAAAAAAAAAARAAAACAAAAAgAAAAEAAAA" + "CAAAAAgAAAAQAAAAAAAAAAgAAAAIAAAACAAAAAAAAAAIAAAACAAAAAgAAAAA" + "AAAAAQAAAAIAAAACAAAABAAAAAIAAAACAAAAAQAAAAAAAAAPAAAACAAAAAYA" + "AAABAAAADwAAAAAAAAAAAAAAAAAAAA4AAAABAAAABwAAAAkAAAAJAAAAAAAA" + "AAAAAAAAAAAAEQAAAAoAAAACAAAACgAAABEAAAAAAAAAAAAAAAAAAAAKAAAA" + "FQAAABUAAAARAAAAEQAAAAAAAAAAAAAAAAAAAAQAAAAKAAAAEQAAABEAAAAR" + "AAAAAAAAAAAAAAAAAAAADgAAABEAAAARAAAAEQAAABEAAAAAAAAAAAAAAAAA" + "AAAGAAAACQAAAAgAAAAIAAAAHAAAAAgAAAAIAAAAAAAAAA4AAAABAAAABgAA" + "AAgAAAAHAAAAAAAAAAAAAAAAAAAACAAAAAgAAAAIAAAACQAAAA4AAAAAAAAA" + "AAAAAAAAAAABAAAABwAAAAkAAAAJAAAABwAAAAAAAAAAAAAAAAAAAAgAAAAO" + "AAAACQAAAAkAAAAOAAAAAAAAAAAAAAAAAAAABgAAAAkAAAAJAAAACQAAAAYA" + "AAAAAAAAAAAAAAAAAAAJAAAACQAAAAkAAAAJAAAADgAAAAAAAAAAAAAAAAAA" + "ABUAAAAVAAAAFQAAABUAAAAaAAAAAAAAAAAAAAAAAAAABwAAAAIAAAACAAAA" + "AgAAAAIAAAACAAAABgAAAAAAAAAJAAAACgAAAAwAAAAKAAAACQAAAAgAAAAI" + "AAAAAAAAAAYAAAAJAAAAAQAAAAEAAAABAAAAAAAAAAEAAAAAAAAABwAAAAIA" + "AAACAAAAAgAAAAYAAAAAAAAAAgAAAAAAAAAJAAAACQAAAAkAAAAJAAAADgAA" + "AAgAAAAIAAAAAAAAAA4AAAABAAAABwAAAAkAAAAHAAAAAAAAAAAAAAAAAAAA" + "CAAAAAgAAAAIAAAAHAAAAAgAAAAJAAAABgAAAAAAAAAHAAAACAAAAA4AAAAJ" + "AAAABgAAAAAAAAAAAAAAAAAAAAcAAAAJAAAACQAAAAkAAAAHAAAAAQAAAAEA" + "AAAAAAAABwAAAAgAAAAIAAAACAAAAAcAAAAAAAAAAAAAAAAAAAAOAAAACQAA" + "AAkAAAAJAAAADgAAAAgAAAAIAAAAAAAAAA0AAAASAAAAEgAAABIAAAAOAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAEAAAAAAAAAAE" + "AAAAAAAAAAQAAAACAAAAAQAAABEAAAAOAAAAAAAAAAgAAAAEAAAAAgAAAAEA" + "AAACAAAABAAAAAgAAAAAAAAAAAAAAAAAAAAfAAAAAAAAAB8AAAAAAAAAAAAA" + "AAAAAAACAAAABAAAAAgAAAAQAAAACAAAAAQAAAACAAAAAAAAAAgAAAAEAAAA" + "DAAAAAwAAAAAAAAADAAAAAwAAAAAAAAADAAAAAwAAAAAAAAAAAAAAAwAAAAM" + "AAAAAAAAAAAAAAAcAAAAAgAAAAEAAAAPAAAAEQAAABEAAAAOAAAAAAAAAA4A" + "AAARAAAAEQAAAA4AAAARAAAAEQAAAA4AAAAAAAAACAAAAAgAAAAIAAAABAAA" + "AAIAAAABAAAAHwAAAAAAAAAOAAAAEQAAABEAAAAeAAAAEAAAAAgAAAAHAAAA" + "AAAAAA4AAAARAAAAAQAAAAEAAAAeAAAAEAAAAB8AAAAAAAAAAgAAAAIAAAAf" + "AAAAEgAAAAoAAAAGAAAAAgAAAAAAAAAOAAAAEQAAAAEAAAAGAAAAAgAAAAEA" + "AAAfAAAAAAAAAB8AAAAQAAAACAAAAAYAAAABAAAAEQAAAA4AAAAAAAAADgAA" + "AAQAAAAEAAAABAAAAAQAAAAMAAAABAAAAAAAAAAOAAAAEQAAABkAAAAVAAAA" + "EwAAABEAAAAOAAAAAAAAAAAAAAAQAAAACAAAAAQAAAACAAAAAQAAAAAAAAAA" + "AAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAfAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAEAAAADAAAAAwAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAQAAAAEAAAAHwAAAAQAAAAEAAAAAAAAAAAAAAAAAAAA" + "BAAAABUAAAAOAAAAFQAAAAQAAAAAAAAAAAAAAAgAAAAEAAAAAgAAAAIAAAAC" + "AAAABAAAAAgAAAAAAAAAAgAAAAQAAAAIAAAACAAAAAgAAAAEAAAAAgAAAAAA" + "AAAAAAAAAAAAAAAAAAAEAAAAAgAAAAYAAAAGAAAAAAAAAA0AAAASAAAAFQAA" + "AAwAAAAKAAAACgAAAAQAAAAAAAAAAwAAABMAAAAIAAAABAAAAAIAAAAZAAAA" + "GAAAAAAAAAAEAAAAHgAAAAUAAAAOAAAAFAAAAA8AAAAEAAAAAAAAAAoAAAAK" + "AAAAHwAAAAoAAAAfAAAACgAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoA" + "AAAKAAAACgAAAAAAAAAEAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAUAAAAFAAAABQAAAD0AAAAnAAAAIAAAACAAAAA4" + "AAAABAAAAAwAAAAdAAAAPwAAAD8AAAAdAAAADAAAAAQAAAAAAAAAAAAAAAAA" + "AAA/AAAAPwAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAA" + "AAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8A" + "AAA/AAAAPwAAAD8AAAA/AAAABwAAAAcAAAAHAAAABwAAAD8AAAA/AAAAPwAA" + "AD8AAAA4AAAAOAAAADgAAAA4AAAAPwAAAD8AAAA/AAAAPwAAAAAAAAAAAAAA" + "AAAAAAAAAAA4AAAAOAAAADgAAAA4AAAAPwAAAD8AAAA/AAAAPwAAADgAAAA4" + "AAAAOAAAADgAAAAHAAAABwAAAAcAAAAHAAAAOAAAADgAAAA4AAAAOAAAADgA" + "AAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAAAAAAAAAAAAAAAAAAAAA" + "AAwAAAAeAAAAPwAAAAwAAAAMAAAADAAAAAwAAAAMAAAACAAAAAwAAAAuAAAA" + "PwAAAD8AAAAuAAAADAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAwA" + "AAAMAAAADAAAAAwAAAA/AAAAHgAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAACEAAAASAAAADAAAAAwAAAAtAAAAPwAAAAwAAAAMAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAcAAAAH" + "AAAAPwAAAD8AAAA/AAAAPwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcA" + "AAAHAAAABwAAAAcAAAAHAAAABwAAADgAAAA4AAAAOAAAADgAAAAHAAAABwAA" + "AAcAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAA" + "PwAAAD8AAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAHAAAABwAAAAcAAAAA" + "AAAAAAAAAAAAAAAAAAAAOAAAADgAAAA4AAAAOAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAA" + "AD8AAAAAAAAAAQAAAAEAAAABAAAAHwAAABEAAAARAAAAEQAAAAAAAAABAAAA" + "HwAAABUAAAAVAAAAFQAAABUAAAAVAAAAAAAAAA4AAAARAAAAAQAAAAcAAAAB" + "AAAAEQAAAA4AAAAAAAAAHwAAABUAAAAVAAAAFQAAABUAAAAVAAAAEQAAAAAA" + "AAAOAAAAEQAAAAEAAAAGAAAAEQAAABEAAAAOAAAAAAAAABkAAAAVAAAAFQAA" + "ABkAAAARAAAAEQAAABEAAAAAAAAAHgAAABEAAAARAAAAHgAAABAAAAAQAAAA" + "EAAAAAAAAAAeAAAAEQAAABEAAAAeAAAAEQAAABEAAAAeAAAAAAAAABEAAAAV" + "AAAAFQAAAA4AAAAVAAAAFQAAABEAAAAAAAAAEAAAAAgAAAAEAAAACgAAABEA" + "AAARAAAAEQAAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAfAAAAAAAA" + "AA4AAAARAAAAEAAAABAAAAAQAAAAEQAAAA4AAAAAAAAAEAAAABAAAAAQAAAA" + "HgAAABEAAAARAAAAHgAAAAAAAAARAAAACQAAAAUAAAAPAAAAEQAAABEAAAAP" + "AAAAAAAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAAB8AAAAAAAAADgAAABEA" + "AAARAAAAEQAAABEAAAARAAAADgAAAAAAAAARAAAAEQAAABEAAAAfAAAAEQAA" + "ABEAAAARAAAAAAAAABEAAAARAAAAEQAAABUAAAAVAAAAGwAAABEAAAAAAAAA" + "CQAAAAkAAAAJAAAACQAAAAkAAAAJAAAABwAAAAAAAAARAAAAEgAAABQAAAAY" + "AAAAFAAAABIAAAARAAAAAAAAABEAAAARAAAAGQAAABUAAAATAAAAEQAAABUA" + "AAAAAAAAEQAAABEAAAAZAAAAFQAAABMAAAARAAAAEQAAAAAAAAARAAAAEQAA" + "AAoAAAAEAAAACgAAABEAAAARAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAA" + "EQAAAB8AAAAAAAAABAAAAAQAAAAfAAAAFQAAABUAAAAfAAAABAAAAAAAAAAf" + "AAAAEAAAABAAAAAeAAAAEAAAABAAAAAfAAAAAAAAABEAAAAfAAAACgAAAAoA" + "AAAKAAAACgAAAAYAAAAAAAAAAQAAAB8AAAASAAAAEgAAABIAAAASAAAAEgAA" + "AAAAAAAeAAAAEQAAABEAAAAeAAAAEAAAABAAAAAfAAAAAAAAABEAAAARAAAA" + "HwAAABEAAAARAAAACgAAAAQAAAAAAAAAEgAAABUAAAAVAAAAHQAAABUAAAAV" + "AAAAEgAAAAAAAAAfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAEQAAAA4AAAAAAAAADgAAAAIAAAACAAAAAgAA" + "AAIAAAACAAAADgAAAAAAAAAAAAAAAQAAAAIAAAAEAAAACAAAABAAAAAAAAAA" + "AAAAAA4AAAAIAAAACAAAAAgAAAAIAAAACAAAAA4AAAAAAAAAHwAAABAAAAAI" + "AAAADgAAAAIAAAABAAAAHwAAAAAAAAAEAAAABAAAAAQAAAAEAAAACgAAABEA" + "AAARAAAAAAAAABEAAAARAAAACgAAAAQAAAAKAAAAEQAAABEAAAAAAAAACgAA" + "ABUAAAAVAAAAFQAAABEAAAARAAAAEQAAAAAAAAAEAAAABAAAAAoAAAAKAAAA" + "EQAAABEAAAARAAAAAAAAAA4AAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAAA" + "AAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAHwAAAAAAAAAOAAAAEQAAAAEA" + "AAAOAAAAEAAAABEAAAAOAAAAAAAAABEAAAASAAAAFAAAAB4AAAARAAAAEQAA" + "AB4AAAAAAAAADQAAABIAAAAVAAAAEQAAABEAAAARAAAADgAAAAAAAAAQAAAA" + "EAAAABAAAAAeAAAAEQAAABEAAAAeAAAAAAAAAA4AAAARAAAAEQAAABEAAAAR" + "AAAAEQAAAA4AAAAAAAAAEQAAABEAAAATAAAAFQAAABkAAAARAAAAEQAAAAAA" + "AAARAAAAEQAAABEAAAAVAAAAFQAAABsAAAARAAAAAAAAAB8AAAARAAAAEAAA" + "ABAAAAAQAAAAEAAAABAAAAAAAAAAEQAAABIAAAAUAAAAGAAAABQAAAASAAAA" + "EQAAAAAAAAAOAAAAEQAAABEAAAABAAAAAQAAAAEAAAABAAAAAAAAAA4AAAAE" + "AAAABAAAAAQAAAAEAAAABAAAAA4AAAAAAAAAEQAAABEAAAARAAAAHwAAABEA" + "AAARAAAAEQAAAAAAAAAPAAAAEQAAABMAAAAQAAAAEAAAABEAAAAOAAAAAAAA" + "ABAAAAAQAAAAEAAAAB4AAAAQAAAAEAAAAB8AAAAAAAAAHwAAABAAAAAQAAAA" + "HgAAABAAAAAQAAAAHwAAAAAAAAAeAAAACQAAAAkAAAAJAAAACQAAAAkAAAAe" + "AAAAAAAAAA4AAAARAAAAEAAAABAAAAAQAAAAEQAAAA4AAAAAAAAAHgAAABEA" + "AAARAAAAHgAAABEAAAARAAAAHgAAAAAAAAARAAAAEQAAAB8AAAARAAAAEQAA" + "AAoAAAAEAAAAAAAAAA4AAAAQAAAAFwAAABUAAAATAAAAEQAAAA4AAAAAAAAA" + "BAAAAAAAAAAEAAAAAgAAAAEAAAARAAAADgAAAAAAAAAIAAAABAAAAAIAAAAB" + "AAAAAgAAAAQAAAAIAAAAAAAAAAAAAAAAAAAAHwAAAAAAAAAfAAAAAAAAAAAA" + "AAAAAAAAAgAAAAQAAAAIAAAAEAAAAAgAAAAEAAAAAgAAAAAAAAAIAAAABAAA" + "AAwAAAAMAAAAAAAAAAwAAAAMAAAAAAAAAAwAAAAMAAAAAAAAAAAAAAAMAAAA" + "DAAAAAAAAAAAAAAAHAAAAAIAAAABAAAADwAAABEAAAARAAAADgAAAAAAAAAO" + "AAAAEQAAABEAAAAOAAAAEQAAABEAAAAOAAAAAAAAAAgAAAAIAAAACAAAAAQA" + "AAACAAAAAQAAAB8AAAAAAAAADgAAABEAAAARAAAAHgAAABAAAAAIAAAABwAA" + "AAAAAAAOAAAAEQAAAAEAAAABAAAAHgAAABAAAAAfAAAAAAAAAAIAAAACAAAA" + "HwAAABIAAAAKAAAABgAAAAIAAAAAAAAADgAAABEAAAABAAAABgAAAAIAAAAB" + "AAAAHwAAAAAAAAAfAAAAEAAAAAgAAAAGAAAAAQAAABEAAAAOAAAAAAAAAA4A" + "AAAEAAAABAAAAAQAAAAEAAAADAAAAAQAAAAAAAAADgAAABEAAAAZAAAAFQAA" + "ABMAAAARAAAADgAAAAAAAAAAAAAAEAAAAAgAAAAEAAAAAgAAAAEAAAAAAAAA" + "AAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAHwAAAAAAAAAAAAAAAAAAAAAAAAAIAAAABAAAAAwAAAAMAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAEAAAABAAAAB8AAAAEAAAABAAAAAAAAAAAAAAAAAAA" + "AAQAAAAVAAAADgAAABUAAAAEAAAAAAAAAAAAAAAIAAAABAAAAAIAAAACAAAA" + "AgAAAAQAAAAIAAAAAAAAAAIAAAAEAAAACAAAAAgAAAAIAAAABAAAAAIAAAAA" + "AAAAAAAAAAAAAAAAAAAABAAAAAIAAAAGAAAABgAAAAAAAAANAAAAEgAAABUA" + "AAAMAAAACgAAAAoAAAAEAAAAAAAAAAMAAAATAAAACAAAAAQAAAACAAAAGQAA" + "ABgAAAAAAAAABAAAAB4AAAAFAAAADgAAABQAAAAPAAAABAAAAAAAAAAKAAAA" + "CgAAAB8AAAAKAAAAHwAAAAoAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK" + "AAAACgAAAAoAAAAAAAAABAAAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAFAAAABQAAAAUAAAA9AAAAJwAAACAAAAAgAAAA" + "OAAAAAQAAAAMAAAAHQAAAD8AAAA/AAAAHQAAAAwAAAAEAAAAAAAAAAAAAAAA" + "AAAAPwAAAD8AAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwA" + "AAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/" + "AAAAPwAAAD8AAAA/AAAAPwAAAAcAAAAHAAAABwAAAAcAAAA/AAAAPwAAAD8A" + "AAA/AAAAOAAAADgAAAA4AAAAOAAAAD8AAAA/AAAAPwAAAD8AAAAAAAAAAAAA" + "AAAAAAAAAAAAOAAAADgAAAA4AAAAOAAAAD8AAAA/AAAAPwAAAD8AAAA4AAAA" + "OAAAADgAAAA4AAAABwAAAAcAAAAHAAAABwAAADgAAAA4AAAAOAAAADgAAAA4" + "AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAAAAAAAAAAAAAAAAAAAAA" + "AAAMAAAAHgAAAD8AAAAMAAAADAAAAAwAAAAMAAAADAAAAAgAAAAMAAAALgAA" + "AD8AAAA/AAAALgAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAM" + "AAAADAAAAAwAAAAMAAAAPwAAAB4AAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAhAAAAEgAAAAwAAAAMAAAALQAAAD8AAAAMAAAADAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAcAAAAHAAAA" + "BwAAAD8AAAA/AAAAPwAAAD8AAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAH" + "AAAABwAAAAcAAAAHAAAABwAAAAcAAAA4AAAAOAAAADgAAAA4AAAABwAAAAcA" + "AAAHAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPwAA" + "AD8AAAA/AAAAPwAAAAAAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAcAAAAHAAAA" + "AAAAAAAAAAAAAAAAAAAAADgAAAA4AAAAOAAAADgAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAA==";
2548
2548
  }
2549
2549
 
2550
- // src/lib/rk86_keyboard.ts
2550
+ // src/lib/core/rk86_keyboard.ts
2551
2551
  class Keyboard {
2552
2552
  state;
2553
2553
  modifiers;
@@ -2663,7 +2663,7 @@ var SS = 32;
2663
2663
  var US = 64;
2664
2664
  var RL = 128;
2665
2665
 
2666
- // src/lib/hex_map.ts
2666
+ // src/lib/core/hex_map.ts
2667
2667
  function create(array, width = 16) {
2668
2668
  const v = {};
2669
2669
  for (let i = 0;i < array.length; i += width) {
@@ -2683,7 +2683,7 @@ function parse2(hex2) {
2683
2683
  return array;
2684
2684
  }
2685
2685
 
2686
- // src/lib/rk86_memory.ts
2686
+ // src/lib/core/rk86_memory.ts
2687
2687
  class Memory {
2688
2688
  buf = [];
2689
2689
  update_ruslat = () => {};
@@ -2958,63 +2958,7 @@ class Memory {
2958
2958
  }
2959
2959
  }
2960
2960
 
2961
- // src/lib/SoundPlayer.ts
2962
- class SoundPlayer {
2963
- audioCtx;
2964
- gainNode;
2965
- oscillator = null;
2966
- constructor(audioContext) {
2967
- this.audioCtx = audioContext;
2968
- this.gainNode = this.audioCtx.createGain();
2969
- this.gainNode.connect(this.audioCtx.destination);
2970
- }
2971
- play(freq, volume, wave) {
2972
- this.oscillator = this.audioCtx.createOscillator();
2973
- this.oscillator.connect(this.gainNode);
2974
- this.oscillator.frequency.setValueAtTime(freq, this.audioCtx.currentTime);
2975
- if (wave) {
2976
- this.oscillator.type = wave;
2977
- }
2978
- this.gainNode.gain.value = volume;
2979
- this.oscillator.start();
2980
- }
2981
- stop(when) {
2982
- const offset = when || 0.05;
2983
- if (this.oscillator)
2984
- this.oscillator.stop(this.audioCtx.currentTime + offset);
2985
- }
2986
- }
2987
-
2988
- // src/lib/rk86_sound.ts
2989
- class Sound {
2990
- volume = 0.05;
2991
- stop_timer = null;
2992
- previous_tone = null;
2993
- player;
2994
- constructor() {
2995
- const ctx = new AudioContext;
2996
- ctx.resume();
2997
- this.player = new SoundPlayer(ctx);
2998
- }
2999
- set_stop_timer(duration) {
3000
- return setTimeout(() => {
3001
- this.player.stop();
3002
- this.previous_tone = null;
3003
- }, duration * 1000);
3004
- }
3005
- play(tone, duration) {
3006
- clearTimeout(this.stop_timer);
3007
- if (this.previous_tone !== tone) {
3008
- if (this.previous_tone)
3009
- this.player.stop();
3010
- this.player.play(tone, this.volume, "square");
3011
- }
3012
- this.previous_tone = tone;
3013
- this.stop_timer = this.set_stop_timer(duration);
3014
- }
3015
- }
3016
-
3017
- // src/lib/rk86_runner.ts
2961
+ // src/lib/core/rk86_runner.ts
3018
2962
  class Runner {
3019
2963
  paused = false;
3020
2964
  tracer = null;
@@ -3024,6 +2968,7 @@ class Runner {
3024
2968
  last_iff_raise_ticks = 0;
3025
2969
  last_iff = 0;
3026
2970
  sound = null;
2971
+ sound_factory;
3027
2972
  instructions_per_millisecond = 0;
3028
2973
  ticks_per_millisecond = 0;
3029
2974
  FREQ = 1780000;
@@ -3053,15 +2998,16 @@ class Runner {
3053
2998
  this.last_iff = iff;
3054
2999
  }
3055
3000
  init_sound(enabled) {
3056
- if (enabled && this.sound == null) {
3057
- this.sound = new Sound;
3001
+ if (enabled && this.sound == null && this.sound_factory) {
3002
+ this.sound = this.sound_factory();
3058
3003
  console.log("\u0437\u0432\u0443\u043A \u0432\u043A\u043B\u044E\u0447\u0435\u043D");
3059
3004
  } else if (!enabled) {
3060
3005
  this.sound = null;
3061
3006
  console.log("\u0437\u0432\u0443\u043A \u0432\u044B\u043A\u043B\u044E\u0447\u0435\u043D");
3062
3007
  }
3063
3008
  }
3064
- execute() {
3009
+ execute(options = {}) {
3010
+ const { terminate_address, on_terminate, exit_on_halt } = options;
3065
3011
  clearTimeout(this.execute_timer);
3066
3012
  if (!this.paused) {
3067
3013
  let batch_ticks = 0;
@@ -3089,6 +3035,14 @@ class Runner {
3089
3035
  this.machine.ui.on_visualizer_hit(this.machine.memory.read_raw(this.machine.cpu.pc));
3090
3036
  }
3091
3037
  batch_instructions += 1;
3038
+ if (terminate_address !== undefined && this.machine.cpu.pc === terminate_address) {
3039
+ on_terminate?.();
3040
+ return;
3041
+ }
3042
+ if (exit_on_halt && this.machine.memory.read_raw(this.machine.cpu.pc) === 118) {
3043
+ on_terminate?.();
3044
+ return;
3045
+ }
3092
3046
  }
3093
3047
  const now = performance.now();
3094
3048
  const elapsed = now - this.previous_batch_time;
@@ -3096,7 +3050,7 @@ class Runner {
3096
3050
  this.instructions_per_millisecond = batch_instructions / elapsed;
3097
3051
  this.ticks_per_millisecond = batch_ticks / elapsed;
3098
3052
  }
3099
- this.execute_timer = setTimeout(() => this.execute(), 10);
3053
+ this.execute_timer = setTimeout(() => this.execute(options), 10);
3100
3054
  }
3101
3055
  pause() {
3102
3056
  this.paused = true;
@@ -3110,9 +3064,9 @@ class Runner {
3110
3064
  }
3111
3065
  }
3112
3066
 
3113
- // src/lib/rk86_screen.ts
3067
+ // src/lib/core/rk86_screen.ts
3114
3068
  class Screen {
3115
- static #update_rate = 25;
3069
+ static #update_rate = 40;
3116
3070
  machine;
3117
3071
  cursor_rate;
3118
3072
  scale_x;
@@ -3127,6 +3081,7 @@ class Screen {
3127
3081
  light_pen_active;
3128
3082
  video_memory_base = 0;
3129
3083
  video_memory_size = 0;
3084
+ ready = false;
3130
3085
  renderer;
3131
3086
  constructor(machine) {
3132
3087
  this.machine = machine;
@@ -3185,11 +3140,12 @@ class Screen {
3185
3140
  this.render_loop();
3186
3141
  }
3187
3142
  render_loop() {
3188
- this.renderer.update();
3143
+ if (this.ready)
3144
+ this.renderer.update();
3189
3145
  setTimeout(() => this.render_loop(), Screen.#update_rate);
3190
3146
  }
3191
- last_width = 0;
3192
- last_height = 0;
3147
+ last_width = -1;
3148
+ last_height = -1;
3193
3149
  set_geometry(width, height) {
3194
3150
  this.width = width;
3195
3151
  this.height = height;
@@ -3200,8 +3156,10 @@ class Screen {
3200
3156
  console.log(`\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D \u0440\u0430\u0437\u043C\u0435\u0440 \u044D\u043A\u0440\u0430\u043D\u0430: ${width} x ${height}`);
3201
3157
  this.last_width = this.width;
3202
3158
  this.last_height = this.height;
3159
+ if (this.last_video_memory_base !== -1)
3160
+ this.ready = true;
3203
3161
  }
3204
- last_video_memory_base = 0;
3162
+ last_video_memory_base = -1;
3205
3163
  set_video_memory(base) {
3206
3164
  this.video_memory_base = base;
3207
3165
  this.machine.ui.update_video_memory_address(this.video_memory_base);
@@ -3209,6 +3167,8 @@ class Screen {
3209
3167
  return;
3210
3168
  console.log(`\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0430 \u0432\u0438\u0434\u0435\u043E\u043F\u0430\u043C\u044F\u0442\u044C \u0441 \u0430\u0434\u0440\u0435\u0441\u0430`, `${hex16(this.video_memory_base)}`, `\u0440\u0430\u0437\u043C\u0435\u0440\u043E\u043C ${hex16(this.video_memory_size)}`);
3211
3169
  this.last_video_memory_base = this.video_memory_base;
3170
+ if (this.last_width !== -1)
3171
+ this.ready = true;
3212
3172
  }
3213
3173
  set_cursor(x, y) {
3214
3174
  this.cursor_x = x;
@@ -3220,7 +3180,7 @@ class Screen {
3220
3180
  }
3221
3181
  }
3222
3182
 
3223
- // src/lib/rk86_snapshot.ts
3183
+ // src/lib/core/rk86_snapshot.ts
3224
3184
  function rk86_snapshot_restore(snapshot, machine, keys_injector) {
3225
3185
  try {
3226
3186
  const json = typeof snapshot === "string" ? JSON.parse(snapshot) : snapshot;
@@ -3243,7 +3203,7 @@ function rk86_snapshot_restore(snapshot, machine, keys_injector) {
3243
3203
  }
3244
3204
  }
3245
3205
 
3246
- // src/lib/rk86_tape.ts
3206
+ // src/lib/web/tape.ts
3247
3207
  class Tape {
3248
3208
  machine;
3249
3209
  previous_bit_ticks = 0;
@@ -3344,7 +3304,7 @@ class Tape {
3344
3304
  }
3345
3305
  }
3346
3306
 
3347
- // src/lib/rk86_terminal.ts
3307
+ // src/lib/terminal/rk86_terminal.ts
3348
3308
  var charMap = {
3349
3309
  0: " ",
3350
3310
  1: "\u2598",
@@ -3512,6 +3472,8 @@ class IO {
3512
3472
 
3513
3473
  class TerminalRenderer {
3514
3474
  machine;
3475
+ loadInfo = "";
3476
+ loadInfoPrinted = false;
3515
3477
  connect(machine) {
3516
3478
  this.machine = machine;
3517
3479
  }
@@ -3541,6 +3503,11 @@ class TerminalRenderer {
3541
3503
  }
3542
3504
  output += `${dim}\u2514${"\u2500".repeat(w)}\u2518${reset}
3543
3505
  `;
3506
+ if (this.loadInfo && !this.loadInfoPrinted && screen.video_memory_base > 0) {
3507
+ output += this.loadInfo + `
3508
+ `;
3509
+ this.loadInfoPrinted = true;
3510
+ }
3544
3511
  process.stdout.write(output);
3545
3512
  }
3546
3513
  }
@@ -3657,17 +3624,21 @@ function printHelp() {
3657
3624
  \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435: bunx rk86 [\u043E\u043F\u0446\u0438\u0438] [\u0444\u0430\u0439\u043B]
3658
3625
 
3659
3626
  \u041E\u043F\u0446\u0438\u0438:
3660
- -h \u0441\u043F\u0440\u0430\u0432\u043A\u0430
3661
- -l \u0441\u043F\u0438\u0441\u043E\u043A \u0444\u0430\u0439\u043B\u043E\u0432 \u0438\u0437 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430
3662
- -m <\u0444\u0430\u0439\u043B> \u043C\u043E\u043D\u0438\u0442\u043E\u0440 (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E: \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0439 mon32.bin)
3663
- -p \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0444\u0430\u0439\u043B \u0431\u0435\u0437 \u0437\u0430\u043F\u0443\u0441\u043A\u0430
3627
+ -h \u0441\u043F\u0440\u0430\u0432\u043A\u0430
3628
+ -l \u0441\u043F\u0438\u0441\u043E\u043A \u0444\u0430\u0439\u043B\u043E\u0432 \u0438\u0437 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430
3629
+ -m <\u0444\u0430\u0439\u043B> \u043C\u043E\u043D\u0438\u0442\u043E\u0440 (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E: \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0439 mon32.bin)
3630
+ -p \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0444\u0430\u0439\u043B \u0431\u0435\u0437 \u0437\u0430\u043F\u0443\u0441\u043A\u0430
3631
+ --exit-halt \u0432\u044B\u0445\u043E\u0434 \u043F\u0440\u0438 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0438 HLT
3632
+ --exit-address [\u0430\u0434\u0440\u0435\u0441] \u0432\u044B\u0445\u043E\u0434 \u043F\u0440\u0438 \u043F\u0435\u0440\u0435\u0445\u043E\u0434\u0435 \u043D\u0430 \u0430\u0434\u0440\u0435\u0441 (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E: 0xFFFE)
3664
3633
 
3665
3634
  \u041F\u0440\u0438\u043C\u0435\u0440\u044B:
3666
- bunx rk86 \u0437\u0430\u043F\u0443\u0441\u043A \u043C\u043E\u043D\u0438\u0442\u043E\u0440\u0430
3667
- bunx rk86 CHESS.GAM \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0438 \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u0444\u0430\u0439\u043B
3668
- bunx rk86 -p CHESS.GAM \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0444\u0430\u0439\u043B (\u0431\u0435\u0437 \u0437\u0430\u043F\u0443\u0441\u043A\u0430)
3669
- bunx rk86 -m mon16.bin \u0437\u0430\u043F\u0443\u0441\u043A \u0441 \u0434\u0440\u0443\u0433\u0438\u043C \u043C\u043E\u043D\u0438\u0442\u043E\u0440\u043E\u043C
3670
- bunx rk86 -l \u0441\u043F\u0438\u0441\u043E\u043A \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0445 \u0444\u0430\u0439\u043B\u043E\u0432
3635
+ bunx rk86 \u0437\u0430\u043F\u0443\u0441\u043A \u043C\u043E\u043D\u0438\u0442\u043E\u0440\u0430
3636
+ bunx rk86 CHESS.GAM \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0438 \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u0444\u0430\u0439\u043B
3637
+ bunx rk86 -p CHESS.GAM \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0444\u0430\u0439\u043B (\u0431\u0435\u0437 \u0437\u0430\u043F\u0443\u0441\u043A\u0430)
3638
+ bunx rk86 -m mon16.bin \u0437\u0430\u043F\u0443\u0441\u043A \u0441 \u0434\u0440\u0443\u0433\u0438\u043C \u043C\u043E\u043D\u0438\u0442\u043E\u0440\u043E\u043C
3639
+ bunx rk86 --exit-halt prog.bin \u0432\u044B\u0445\u043E\u0434 \u043F\u0440\u0438 HLT
3640
+ bunx rk86 --exit-address prog.bin \u0432\u044B\u0445\u043E\u0434 \u043F\u0440\u0438 JMP FFFEh
3641
+ bunx rk86 -l \u0441\u043F\u0438\u0441\u043E\u043A \u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0445 \u0444\u0430\u0439\u043B\u043E\u0432
3671
3642
 
3672
3643
  \u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435:
3673
3644
  Ctrl+C \u0432\u044B\u0445\u043E\u0434`);
@@ -3683,21 +3654,42 @@ async function listFiles() {
3683
3654
  console.log(`\x1B[33m${entry.name.padEnd(20)}\x1B[0m ${title}${desc}`);
3684
3655
  }
3685
3656
  }
3657
+ function flag(args, name) {
3658
+ const i = args.indexOf(name);
3659
+ if (i == -1)
3660
+ return false;
3661
+ args.splice(i, 1);
3662
+ return true;
3663
+ }
3664
+ function arg(args, name, defaultValue, matcher, convertor) {
3665
+ const convert = (v) => convertor ? convertor(v) : v;
3666
+ const i = args.indexOf(name);
3667
+ if (i == -1)
3668
+ return;
3669
+ if (i + 1 >= args.length || matcher && !matcher.test(args[i + 1])) {
3670
+ args.splice(i, 1);
3671
+ return defaultValue ? convert(defaultValue) : defaultValue;
3672
+ }
3673
+ const value = args[i + 1];
3674
+ args.splice(i, 2);
3675
+ return convert(value);
3676
+ }
3686
3677
  async function main() {
3687
3678
  const args = process.argv.slice(2);
3688
- if (args.includes("-h") || args.includes("--help")) {
3679
+ if (flag(args, "-h") || flag(args, "--help")) {
3689
3680
  printHelp();
3690
3681
  process.exit(0);
3691
3682
  }
3692
- if (args.includes("-l") || args.includes("--list")) {
3683
+ if (flag(args, "-l") || flag(args, "--list")) {
3693
3684
  await listFiles();
3694
3685
  process.exit(0);
3695
3686
  }
3696
- const loadOnly = args.includes("-p");
3697
- const monitorIdx = args.indexOf("-m");
3698
- const monitorFile_ = monitorIdx >= 0 ? args[monitorIdx + 1] : undefined;
3699
- const positional = args.filter((a, i) => !a.startsWith("-") && (monitorIdx < 0 || i !== monitorIdx + 1));
3700
- const programFile = positional[0];
3687
+ const loadOnly = flag(args, "-p");
3688
+ const exitOnHalt = flag(args, "--exit-halt");
3689
+ const exitAddrValue = arg(args, "--exit-address", "0xFFFE", /^0x[0-9a-fA-F]+$/i, (v) => parseInt(v, 16));
3690
+ const exitAddr = exitAddrValue !== undefined;
3691
+ const monitorFile_ = arg(args, "-m");
3692
+ const programFile = args[0];
3701
3693
  const keyboard = new Keyboard;
3702
3694
  const io = new IO;
3703
3695
  const machineBuilder = {
@@ -3717,25 +3709,38 @@ async function main() {
3717
3709
  const monitorFile = parse_rk86_binary(monitorFile_ || "mon32.bin", monitorContent);
3718
3710
  machine.memory.load_file(monitorFile);
3719
3711
  let entryPoint;
3712
+ let loadInfo = "";
3720
3713
  if (programFile) {
3721
3714
  const content = await fetchFile(programFile);
3722
3715
  const { ok, json } = parse(content);
3723
3716
  if (ok) {
3724
3717
  rk86_snapshot_restore(json, machine);
3725
3718
  entryPoint = parseInt(json.cpu.pc);
3726
- console.error(`\u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D \u043E\u0431\u0440\u0430\u0437: ${programFile} (PC=${entryPoint.toString(16)})`);
3719
+ loadInfo = `\u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D: ${programFile} (PC=${hex16(entryPoint)})`;
3727
3720
  } else {
3728
3721
  const file = parse_rk86_binary(programFile, content);
3729
3722
  machine.memory.load_file(file);
3730
3723
  entryPoint = file.entry;
3731
- console.error(`\u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D: ${programFile} (${file.start.toString(16)}-${file.end.toString(16)}, G${file.entry.toString(16)})`);
3724
+ loadInfo = `\u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D: ${programFile} (${hex16(file.start)}-${hex16(file.end)}, G${hex16(file.entry)})`;
3732
3725
  }
3733
3726
  }
3734
3727
  process.stdout.write("\x1B[?25l");
3735
3728
  process.stdout.write("\x1B[2J");
3736
3729
  setupKeyboard(keyboard);
3737
- machine.screen.start(new TerminalRenderer);
3738
- machine.runner.execute();
3730
+ const renderer = new TerminalRenderer;
3731
+ renderer.loadInfo = loadInfo;
3732
+ machine.screen.start(renderer);
3733
+ const onTerminate = exitOnHalt || exitAddr ? () => {
3734
+ renderer.update();
3735
+ console.log();
3736
+ console.log("\u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u0430 \u0440\u0430\u0431\u043E\u0442\u0443 \u043D\u0430", hex16(machine.cpu.pc));
3737
+ process.exit(0);
3738
+ } : undefined;
3739
+ machine.runner.execute({
3740
+ terminate_address: exitAddr ? exitAddrValue : undefined,
3741
+ exit_on_halt: exitOnHalt,
3742
+ on_terminate: onTerminate
3743
+ });
3739
3744
  if (entryPoint !== undefined && !loadOnly) {
3740
3745
  setTimeout(() => machine.cpu.jump(entryPoint), 500);
3741
3746
  }