@aptre/v86 0.5.0

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 (111) hide show
  1. package/LICENSE +22 -0
  2. package/LICENSE.MIT +22 -0
  3. package/Readme.md +237 -0
  4. package/dist/v86.browser.js +26666 -0
  5. package/dist/v86.browser.js.map +7 -0
  6. package/dist/v86.js +26632 -0
  7. package/dist/v86.js.map +7 -0
  8. package/gen/generate_analyzer.ts +512 -0
  9. package/gen/generate_interpreter.ts +522 -0
  10. package/gen/generate_jit.ts +624 -0
  11. package/gen/rust_ast.ts +107 -0
  12. package/gen/util.ts +35 -0
  13. package/gen/x86_table.ts +1836 -0
  14. package/lib/9p.ts +1547 -0
  15. package/lib/filesystem.ts +1879 -0
  16. package/lib/marshall.ts +168 -0
  17. package/lib/softfloat/softfloat.c +32501 -0
  18. package/lib/zstd/zstddeclib.c +13520 -0
  19. package/package.json +75 -0
  20. package/src/acpi.ts +267 -0
  21. package/src/browser/dummy_screen.ts +106 -0
  22. package/src/browser/fake_network.ts +1771 -0
  23. package/src/browser/fetch_network.ts +361 -0
  24. package/src/browser/filestorage.ts +124 -0
  25. package/src/browser/inbrowser_network.ts +57 -0
  26. package/src/browser/keyboard.ts +564 -0
  27. package/src/browser/main.ts +3415 -0
  28. package/src/browser/mouse.ts +255 -0
  29. package/src/browser/network.ts +142 -0
  30. package/src/browser/print_stats.ts +336 -0
  31. package/src/browser/screen.ts +978 -0
  32. package/src/browser/serial.ts +316 -0
  33. package/src/browser/speaker.ts +1223 -0
  34. package/src/browser/starter.ts +1688 -0
  35. package/src/browser/wisp_network.ts +332 -0
  36. package/src/browser/worker_bus.ts +64 -0
  37. package/src/buffer.ts +652 -0
  38. package/src/bus.ts +78 -0
  39. package/src/const.ts +128 -0
  40. package/src/cpu.ts +2891 -0
  41. package/src/dma.ts +474 -0
  42. package/src/elf.ts +251 -0
  43. package/src/floppy.ts +1778 -0
  44. package/src/ide.ts +3455 -0
  45. package/src/io.ts +504 -0
  46. package/src/iso9660.ts +317 -0
  47. package/src/kernel.ts +250 -0
  48. package/src/lib.ts +645 -0
  49. package/src/log.ts +149 -0
  50. package/src/main.ts +199 -0
  51. package/src/ne2k.ts +1589 -0
  52. package/src/pci.ts +815 -0
  53. package/src/pit.ts +406 -0
  54. package/src/ps2.ts +820 -0
  55. package/src/rtc.ts +537 -0
  56. package/src/rust/analysis.rs +101 -0
  57. package/src/rust/codegen.rs +2660 -0
  58. package/src/rust/config.rs +3 -0
  59. package/src/rust/control_flow.rs +425 -0
  60. package/src/rust/cpu/apic.rs +658 -0
  61. package/src/rust/cpu/arith.rs +1207 -0
  62. package/src/rust/cpu/call_indirect.rs +2 -0
  63. package/src/rust/cpu/cpu.rs +4501 -0
  64. package/src/rust/cpu/fpu.rs +923 -0
  65. package/src/rust/cpu/global_pointers.rs +112 -0
  66. package/src/rust/cpu/instructions.rs +2486 -0
  67. package/src/rust/cpu/instructions_0f.rs +5261 -0
  68. package/src/rust/cpu/ioapic.rs +316 -0
  69. package/src/rust/cpu/memory.rs +351 -0
  70. package/src/rust/cpu/misc_instr.rs +613 -0
  71. package/src/rust/cpu/mod.rs +16 -0
  72. package/src/rust/cpu/modrm.rs +133 -0
  73. package/src/rust/cpu/pic.rs +402 -0
  74. package/src/rust/cpu/sse_instr.rs +361 -0
  75. package/src/rust/cpu/string.rs +701 -0
  76. package/src/rust/cpu/vga.rs +175 -0
  77. package/src/rust/cpu_context.rs +69 -0
  78. package/src/rust/dbg.rs +98 -0
  79. package/src/rust/gen/analyzer.rs +3807 -0
  80. package/src/rust/gen/analyzer0f.rs +3992 -0
  81. package/src/rust/gen/interpreter.rs +4447 -0
  82. package/src/rust/gen/interpreter0f.rs +5404 -0
  83. package/src/rust/gen/jit.rs +5080 -0
  84. package/src/rust/gen/jit0f.rs +5547 -0
  85. package/src/rust/gen/mod.rs +14 -0
  86. package/src/rust/jit.rs +2443 -0
  87. package/src/rust/jit_instructions.rs +7881 -0
  88. package/src/rust/js_api.rs +6 -0
  89. package/src/rust/leb.rs +46 -0
  90. package/src/rust/lib.rs +29 -0
  91. package/src/rust/modrm.rs +330 -0
  92. package/src/rust/opstats.rs +249 -0
  93. package/src/rust/page.rs +15 -0
  94. package/src/rust/paging.rs +25 -0
  95. package/src/rust/prefix.rs +15 -0
  96. package/src/rust/profiler.rs +155 -0
  97. package/src/rust/regs.rs +38 -0
  98. package/src/rust/softfloat.rs +286 -0
  99. package/src/rust/state_flags.rs +27 -0
  100. package/src/rust/wasmgen/mod.rs +2 -0
  101. package/src/rust/wasmgen/wasm_builder.rs +1047 -0
  102. package/src/rust/wasmgen/wasm_opcodes.rs +221 -0
  103. package/src/rust/zstd.rs +105 -0
  104. package/src/sb16.ts +1928 -0
  105. package/src/state.ts +359 -0
  106. package/src/uart.ts +472 -0
  107. package/src/vga.ts +2791 -0
  108. package/src/virtio.ts +1756 -0
  109. package/src/virtio_balloon.ts +273 -0
  110. package/src/virtio_console.ts +372 -0
  111. package/src/virtio_net.ts +326 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/const.ts", "../src/log.ts", "../src/lib.ts", "../src/buffer.ts", "../src/sb16.ts", "../src/acpi.ts", "../src/pit.ts", "../src/dma.ts", "../src/uart.ts", "../src/ne2k.ts", "../src/io.ts", "../src/virtio.ts", "../lib/marshall.ts", "../src/virtio_console.ts", "../src/pci.ts", "../src/ps2.ts", "../src/elf.ts", "../src/rtc.ts", "../src/floppy.ts", "../src/ide.ts", "../src/virtio_net.ts", "../src/vga.ts", "../src/virtio_balloon.ts", "../lib/filesystem.ts", "../lib/9p.ts", "../src/kernel.ts", "../src/cpu.ts", "../src/state.ts", "../src/browser/print_stats.ts", "../src/bus.ts", "../src/browser/speaker.ts", "../src/browser/network.ts", "../src/browser/fake_network.ts", "../src/browser/fetch_network.ts", "../src/browser/wisp_network.ts", "../src/browser/keyboard.ts", "../src/browser/mouse.ts", "../src/browser/screen.ts", "../src/browser/dummy_screen.ts", "../src/browser/serial.ts", "../src/browser/inbrowser_network.ts", "../src/browser/filestorage.ts", "../src/browser/starter.ts", "../src/main.ts"],
4
+ "sourcesContent": ["export const LOG_ALL = -1,\n LOG_NONE = 0,\n LOG_OTHER = 0x0000001,\n LOG_CPU = 0x0000002,\n LOG_FPU = 0x0000004,\n LOG_MEM = 0x0000008,\n LOG_DMA = 0x0000010,\n LOG_IO = 0x0000020,\n LOG_PS2 = 0x0000040,\n LOG_PIC = 0x0000080,\n LOG_VGA = 0x0000100,\n LOG_PIT = 0x0000200,\n LOG_MOUSE = 0x0000400,\n LOG_PCI = 0x0000800,\n LOG_BIOS = 0x0001000,\n LOG_FLOPPY = 0x0002000,\n LOG_SERIAL = 0x0004000,\n LOG_DISK = 0x0008000,\n LOG_RTC = 0x0010000,\n // unused 0x0020000,\n LOG_ACPI = 0x0040000,\n LOG_APIC = 0x0080000,\n LOG_NET = 0x0100000,\n LOG_VIRTIO = 0x0200000,\n LOG_9P = 0x0400000,\n LOG_SB16 = 0x0800000,\n LOG_FETCH = 0x1000000\n\n/**\n * @type {Array<Array<string|number>>}\n */\nexport const LOG_NAMES: ReadonlyArray<readonly [number, string]> = [\n [1, ''],\n [LOG_CPU, 'CPU'],\n [LOG_DISK, 'DISK'],\n [LOG_FPU, 'FPU'],\n [LOG_MEM, 'MEM'],\n [LOG_DMA, 'DMA'],\n [LOG_IO, 'IO'],\n [LOG_PS2, 'PS2'],\n [LOG_PIC, 'PIC'],\n [LOG_VGA, 'VGA'],\n [LOG_PIT, 'PIT'],\n [LOG_MOUSE, 'MOUS'],\n [LOG_PCI, 'PCI'],\n [LOG_BIOS, 'BIOS'],\n [LOG_FLOPPY, 'FLOP'],\n [LOG_SERIAL, 'SERI'],\n [LOG_RTC, 'RTC'],\n [LOG_ACPI, 'ACPI'],\n [LOG_APIC, 'APIC'],\n [LOG_NET, 'NET'],\n [LOG_VIRTIO, 'VIO'],\n [LOG_9P, '9P'],\n [LOG_SB16, 'SB16'],\n [LOG_FETCH, 'FETC'],\n]\n\nexport const // flags register bitflags\n FLAG_CARRY = 1,\n FLAG_PARITY = 4,\n FLAG_ADJUST = 16,\n FLAG_ZERO = 64,\n FLAG_SIGN = 128,\n FLAG_TRAP = 256,\n FLAG_INTERRUPT = 512,\n FLAG_DIRECTION = 1024,\n FLAG_OVERFLOW = 2048,\n FLAG_IOPL = (1 << 12) | (1 << 13),\n FLAG_NT = 1 << 14,\n FLAG_RF = 1 << 16,\n FLAG_VM = 1 << 17,\n FLAG_AC = 1 << 18,\n FLAG_VIF = 1 << 19,\n FLAG_VIP = 1 << 20,\n FLAG_ID = 1 << 21,\n // default values of reserved flags bits\n FLAGS_DEFAULT = 1 << 1,\n REG_EAX = 0,\n REG_ECX = 1,\n REG_EDX = 2,\n REG_EBX = 3,\n REG_ESP = 4,\n REG_EBP = 5,\n REG_ESI = 6,\n REG_EDI = 7,\n REG_ES = 0,\n REG_CS = 1,\n REG_SS = 2,\n REG_DS = 3,\n REG_FS = 4,\n REG_GS = 5,\n REG_LDTR = 7 // local descriptor table register\n\nexport const // The minimum number of bytes that can be memory-mapped by one device.\n MMAP_BLOCK_BITS = 17,\n MMAP_BLOCK_SIZE = 1 << MMAP_BLOCK_BITS,\n MMAP_MAX = 0x100000000\n\nexport const CR0_PG = 1 << 31\nexport const CR4_PAE = 1 << 5\n\n// https://github.com/qemu/seabios/blob/14221cd86eadba82255fdc55ed174d401c7a0a04/src/fw/paravirt.c#L205-L219\n\nexport const FW_CFG_SIGNATURE = 0x00\nexport const FW_CFG_ID = 0x01\nexport const FW_CFG_RAM_SIZE = 0x03\nexport const FW_CFG_NB_CPUS = 0x05\nexport const FW_CFG_MAX_CPUS = 0x0f\nexport const FW_CFG_NUMA = 0x0d\nexport const FW_CFG_FILE_DIR = 0x19\n\nexport const FW_CFG_CUSTOM_START = 0x8000\n// This value is specific to v86, choosen to hopefully not collide with other indexes\nexport const FW_CFG_FILE_START = 0xc000\nexport const FW_CFG_SIGNATURE_QEMU = 0x554d4551\n\n// See same constant in jit.rs\nexport const WASM_TABLE_SIZE = 900\n\nexport const WASM_TABLE_OFFSET = 1024\n\nexport const MIXER_CHANNEL_LEFT = 0\nexport const MIXER_CHANNEL_RIGHT = 1\nexport const MIXER_CHANNEL_BOTH = 2\nexport const MIXER_SRC_MASTER = 0\nexport const MIXER_SRC_PCSPEAKER = 1\nexport const MIXER_SRC_DAC = 2\n", "declare let DEBUG: boolean\n\nif (typeof DEBUG === 'undefined') {\n Object.defineProperty(globalThis, 'DEBUG', {\n value: true,\n writable: true,\n configurable: true,\n })\n}\n\nimport { LOG_NAMES } from './const.js'\nimport { pad0, pads } from './lib.js'\nimport {\n LOG_ALL,\n LOG_PS2,\n LOG_PIT,\n LOG_9P,\n LOG_PIC,\n LOG_DMA,\n LOG_NET,\n LOG_FLOPPY,\n LOG_DISK,\n LOG_SERIAL,\n LOG_VGA,\n LOG_SB16,\n LOG_VIRTIO,\n} from './const.js'\n\nexport const LOG_TO_FILE = false\n\nexport let LOG_LEVEL: number =\n LOG_ALL &\n ~LOG_PS2 &\n ~LOG_PIT &\n ~LOG_VIRTIO &\n ~LOG_9P &\n ~LOG_PIC &\n ~LOG_DMA &\n ~LOG_SERIAL &\n ~LOG_NET &\n ~LOG_FLOPPY &\n ~LOG_DISK &\n ~LOG_VGA &\n ~LOG_SB16\n\nexport function set_log_level(level: number): void {\n LOG_LEVEL = level\n}\n\nexport const log_data: string[] = []\n\nfunction do_the_log(message: string): void {\n if (LOG_TO_FILE) {\n log_data.push(message, '\\n')\n } else {\n console.log(message)\n }\n}\n\nexport const dbg_log: (stuff: string | number, level?: number) => void =\n (function () {\n if (!DEBUG) {\n return function () {}\n }\n\n const init: Record<number, string> = {}\n const dbg_names = LOG_NAMES.reduce(function (a, x) {\n a[x[0]] = x[1]\n return a\n }, init)\n\n let log_last_message = ''\n let log_message_repetitions = 0\n\n function dbg_log_(stuff: string | number, level?: number): void {\n if (!DEBUG) return\n\n level = level || 1\n\n if (level & LOG_LEVEL) {\n const level_name = dbg_names[level] || '',\n message = '[' + pads(level_name, 4) + '] ' + stuff\n\n if (message === log_last_message) {\n log_message_repetitions++\n\n if (log_message_repetitions < 2048) {\n return\n }\n }\n\n const now = new Date()\n const time_str =\n pad0(now.getHours(), 2) +\n ':' +\n pad0(now.getMinutes(), 2) +\n ':' +\n pad0(now.getSeconds(), 2) +\n '+' +\n pad0(now.getMilliseconds(), 3) +\n ' '\n\n if (log_message_repetitions) {\n if (log_message_repetitions === 1) {\n do_the_log(time_str + log_last_message)\n } else {\n do_the_log(\n 'Previous message repeated ' +\n log_message_repetitions +\n ' times',\n )\n }\n\n log_message_repetitions = 0\n }\n\n do_the_log(time_str + message)\n log_last_message = message\n }\n }\n\n return dbg_log_\n })()\n\nexport function dbg_trace(level?: number): void {\n if (!DEBUG) return\n\n dbg_log(Error().stack!, level)\n}\n\nexport function dbg_assert(cond: boolean, msg?: string, _level?: number): void {\n if (!DEBUG) return\n\n if (!cond) {\n dbg_assert_failed(msg)\n }\n}\n\nexport function dbg_assert_failed(msg?: string): never {\n // eslint-disable-next-line no-debugger\n debugger\n console.trace()\n\n if (msg) {\n throw 'Assert failed: ' + msg\n } else {\n throw 'Assert failed'\n }\n}\n", "declare let DEBUG: boolean\n\nimport { dbg_assert } from './log.js'\n\n// pad string with spaces on the right\nexport function pads(\n str: string | number | undefined | null,\n len: number,\n): string {\n const s = str || str === 0 ? str + '' : ''\n return s.padEnd(len, ' ')\n}\n\n// pad string with zeros on the left\nexport function pad0(\n str: string | number | undefined | null,\n len: number,\n): string {\n const s = str || str === 0 ? str + '' : ''\n return s.padStart(len, '0')\n}\n\nexport const view = function (\n constructor: any,\n memory: { buffer: ArrayBuffer },\n offset: number,\n length: number,\n): any {\n dbg_assert(offset >= 0)\n return new Proxy(\n {},\n {\n get: function (_target, property) {\n const b = new constructor(memory.buffer, offset, length)\n const x = b[property]\n if (typeof x === 'function') {\n return x.bind(b)\n }\n dbg_assert(\n /^\\d+$/.test(String(property)) ||\n property === 'buffer' ||\n property === 'length' ||\n property === 'BYTES_PER_ELEMENT' ||\n property === 'byteOffset',\n )\n return x\n },\n set: function (_target, property, value) {\n dbg_assert(/^\\d+$/.test(String(property)))\n new constructor(memory.buffer, offset, length)[property] = value\n return true\n },\n },\n )\n}\n\nexport function h(n: number, len?: number): string {\n let str: string\n if (!n) {\n str = ''\n } else {\n str = n.toString(16)\n }\n\n return '0x' + pad0(str.toUpperCase(), len || 1)\n}\n\nexport function hex_dump(buffer: Uint8Array | number[]): string {\n function hex(n: number, len: number): string {\n return pad0(n.toString(16).toUpperCase(), len)\n }\n\n const result: string[] = []\n let offset = 0\n\n for (; offset + 15 < buffer.length; offset += 16) {\n let line = hex(offset, 5) + ' '\n\n for (let j = 0; j < 0x10; j++) {\n line += hex(buffer[offset + j], 2) + ' '\n }\n\n line += ' '\n\n for (let j = 0; j < 0x10; j++) {\n const x = buffer[offset + j]\n line +=\n x >= 33 && x !== 34 && x !== 92 && x <= 126\n ? String.fromCharCode(x)\n : '.'\n }\n\n result.push(line)\n }\n\n let line = hex(offset, 5) + ' '\n\n for (; offset < buffer.length; offset++) {\n line += hex(buffer[offset], 2) + ' '\n }\n\n const remainder = offset & 0xf\n line += ' '.repeat(0x10 - remainder)\n line += ' '\n\n for (let j = 0; j < remainder; j++) {\n const x = buffer[offset + j]\n line +=\n x >= 33 && x !== 34 && x !== 92 && x <= 126\n ? String.fromCharCode(x)\n : '.'\n }\n\n result.push(line)\n\n return '\\n' + result.join('\\n') + '\\n'\n}\n\n/* global require */\nexport let get_rand_int: () => number\nif (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const rand_data = new Int32Array(1)\n\n get_rand_int = function () {\n crypto.getRandomValues(rand_data)\n return rand_data[0]\n }\n} else if (typeof require !== 'undefined') {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const nodeCrypto = require('crypto')\n\n get_rand_int = function () {\n return nodeCrypto.randomBytes(4).readInt32LE(0)\n }\n} else if (typeof process !== 'undefined') {\n import('node:' + 'crypto').then((nodeCrypto) => {\n get_rand_int = function () {\n return nodeCrypto['randomBytes'](4).readInt32LE(0)\n }\n })\n} else {\n dbg_assert(false, 'Unsupported platform: No cryptographic random values')\n}\n\nexport let int_log2: (x: number) => number\n\nif (\n typeof Math.clz32 === 'function' &&\n Math.clz32(0) === 32 &&\n Math.clz32(0x12345) === 15 &&\n Math.clz32(-1) === 0\n) {\n int_log2 = function (x: number): number {\n dbg_assert(x > 0)\n\n return 31 - Math.clz32(x)\n }\n} else {\n const int_log2_table = new Int8Array(256)\n\n for (let i = 0, b = -2; i < 256; i++) {\n if (!(i & (i - 1))) b++\n\n int_log2_table[i] = b\n }\n\n int_log2 = function (x: number): number {\n x >>>= 0\n dbg_assert(x > 0)\n\n // http://jsperf.com/integer-log2/6\n const tt = x >>> 16\n\n if (tt) {\n const t = tt >>> 8\n if (t) {\n return 24 + int_log2_table[t]\n } else {\n return 16 + int_log2_table[tt]\n }\n } else {\n const t = x >>> 8\n if (t) {\n return 8 + int_log2_table[t]\n } else {\n return int_log2_table[x]\n }\n }\n }\n}\n\nexport const round_up_to_next_power_of_2 = function (x: number): number {\n dbg_assert(x >= 0)\n return x <= 1 ? 1 : 1 << (1 + int_log2(x - 1))\n}\n\nif (typeof DEBUG !== 'undefined' && DEBUG) {\n dbg_assert(int_log2(1) === 0)\n dbg_assert(int_log2(2) === 1)\n dbg_assert(int_log2(7) === 2)\n dbg_assert(int_log2(8) === 3)\n dbg_assert(int_log2(123456789) === 26)\n\n dbg_assert(round_up_to_next_power_of_2(0) === 1)\n dbg_assert(round_up_to_next_power_of_2(1) === 1)\n dbg_assert(round_up_to_next_power_of_2(2) === 2)\n dbg_assert(round_up_to_next_power_of_2(7) === 8)\n dbg_assert(round_up_to_next_power_of_2(8) === 8)\n dbg_assert(round_up_to_next_power_of_2(123456789) === 134217728)\n}\n\nexport class ByteQueue {\n length: number = 0\n private data: Uint8Array\n private start: number = 0\n private end: number = 0\n private size: number\n\n constructor(size: number) {\n this.size = size\n this.data = new Uint8Array(size)\n\n dbg_assert((size & (size - 1)) === 0)\n }\n\n push(item: number): void {\n if (this.length === this.size) {\n // intentional overwrite\n } else {\n this.length++\n }\n\n this.data[this.end] = item\n this.end = (this.end + 1) & (this.size - 1)\n }\n\n shift(): number {\n if (!this.length) {\n return -1\n } else {\n const item = this.data[this.start]\n\n this.start = (this.start + 1) & (this.size - 1)\n this.length--\n\n return item\n }\n }\n\n peek(): number {\n if (!this.length) {\n return -1\n } else {\n return this.data[this.start]\n }\n }\n\n clear(): void {\n this.start = 0\n this.end = 0\n this.length = 0\n }\n}\n\nexport class FloatQueue {\n size: number\n data: Float32Array\n start: number = 0\n end: number = 0\n length: number = 0\n\n constructor(size: number) {\n this.size = size\n this.data = new Float32Array(size)\n\n dbg_assert((size & (size - 1)) === 0)\n }\n\n push(item: number): void {\n if (this.length === this.size) {\n // intentional overwrite\n this.start = (this.start + 1) & (this.size - 1)\n } else {\n this.length++\n }\n\n this.data[this.end] = item\n this.end = (this.end + 1) & (this.size - 1)\n }\n\n shift(): number | undefined {\n if (!this.length) {\n return undefined\n } else {\n const item = this.data[this.start]\n\n this.start = (this.start + 1) & (this.size - 1)\n this.length--\n\n return item\n }\n }\n\n shift_block(count: number): Float32Array {\n const slice = new Float32Array(count)\n\n if (count > this.length) {\n count = this.length\n }\n let slice_end = this.start + count\n\n const partial = this.data.subarray(this.start, slice_end)\n\n slice.set(partial)\n if (slice_end >= this.size) {\n slice_end -= this.size\n slice.set(this.data.subarray(0, slice_end), partial.length)\n }\n this.start = slice_end\n\n this.length -= count\n\n return slice\n }\n\n peek(): number | undefined {\n if (!this.length) {\n return undefined\n } else {\n return this.data[this.start]\n }\n }\n\n clear(): void {\n this.start = 0\n this.end = 0\n this.length = 0\n }\n}\n\nexport function dump_file(ab: BlobPart | BlobPart[], name: string): void {\n if (!Array.isArray(ab)) {\n ab = [ab]\n }\n\n const blob = new Blob(ab)\n download(blob, name)\n}\n\nexport function download(file_or_blob: Blob | File, name: string): void {\n const a = document.createElement('a')\n a['download'] = name\n a.href = window.URL.createObjectURL(file_or_blob)\n a.dataset['downloadurl'] = [\n 'application/octet-stream',\n a['download'],\n a.href,\n ].join(':')\n\n if (document.createEvent) {\n const ev = document.createEvent('MouseEvent')\n ev.initMouseEvent(\n 'click',\n true,\n true,\n window,\n 0,\n 0,\n 0,\n 0,\n 0,\n false,\n false,\n false,\n false,\n 0,\n null,\n )\n a.dispatchEvent(ev)\n } else {\n a.click()\n }\n\n window.URL.revokeObjectURL(a.href)\n}\n\nexport class Bitmap {\n view: Uint8Array\n\n constructor(length_or_buffer: number | ArrayBuffer) {\n if (typeof length_or_buffer === 'number') {\n this.view = new Uint8Array((length_or_buffer + 7) >> 3)\n } else if (length_or_buffer instanceof ArrayBuffer) {\n this.view = new Uint8Array(length_or_buffer)\n } else {\n dbg_assert(false, 'Bitmap: Invalid argument')\n this.view = new Uint8Array(0)\n }\n }\n\n set(index: number, value: number): void {\n const bit_index = index & 7\n const byte_index = index >> 3\n const bit_mask = 1 << bit_index\n\n this.view[byte_index] = value\n ? this.view[byte_index] | bit_mask\n : this.view[byte_index] & ~bit_mask\n }\n\n get(index: number): number {\n const bit_index = index & 7\n const byte_index = index >> 3\n\n return (this.view[byte_index] >> bit_index) & 1\n }\n\n get_buffer(): ArrayBufferLike {\n return this.view.buffer\n }\n}\n\nexport interface LoadFileOptions {\n done?: (result: any, http?: XMLHttpRequest) => void\n progress?: (e: ProgressEvent) => void\n as_json?: boolean\n method?: string\n headers?: Record<string, string>\n range?: { start: number; length: number }\n}\n\nexport let load_file: (\n filename: string,\n options: LoadFileOptions,\n n_tries?: number,\n) => Promise<void>\nexport let get_file_size: (path: string) => Promise<number>\n\nif (\n typeof XMLHttpRequest === 'undefined' ||\n (typeof process !== 'undefined' &&\n process.versions &&\n process.versions.node)\n) {\n let fs: any\n\n load_file = async function (\n filename: string,\n options: LoadFileOptions,\n _n_tries?: number,\n ) {\n if (!fs) {\n // string concat to work around closure compiler 'Invalid module path \"node:fs/promises\" for resolution mode'\n fs = await import('node:' + 'fs/promises')\n }\n\n if (options.range) {\n dbg_assert(!options.as_json)\n\n const fd = await fs['open'](filename, 'r')\n\n const length = options.range.length\n const buffer = Buffer.allocUnsafe(length)\n\n try {\n const result = await fd['read']({\n buffer,\n position: options.range.start,\n })\n dbg_assert(result.bytesRead === length)\n } finally {\n await fd['close']()\n }\n\n if (options.done) {\n options.done(new Uint8Array(buffer))\n }\n } else {\n const o = {\n encoding: options.as_json ? 'utf-8' : null,\n }\n\n const data = await fs['readFile'](filename, o)\n if (options.as_json) {\n options.done!(JSON.parse(data))\n } else {\n options.done!(new Uint8Array(data).buffer)\n }\n }\n }\n\n get_file_size = async function (path: string) {\n if (!fs) {\n // string concat to work around closure compiler 'Invalid module path \"node:fs/promises\" for resolution mode'\n fs = await import('node:' + 'fs/promises')\n }\n const stat = await fs['stat'](path)\n return stat.size\n }\n} else {\n load_file = async function (\n filename: string,\n options: LoadFileOptions,\n n_tries?: number,\n ) {\n const http = new XMLHttpRequest()\n\n http.open(options.method || 'get', filename, true)\n\n if (options.as_json) {\n http.responseType = 'json'\n } else {\n http.responseType = 'arraybuffer'\n }\n\n if (options.headers) {\n const header_names = Object.keys(options.headers)\n\n for (let i = 0; i < header_names.length; i++) {\n const name = header_names[i]\n http.setRequestHeader(name, options.headers[name])\n }\n }\n\n if (options.range) {\n const start = options.range.start\n const end = start + options.range.length - 1\n http.setRequestHeader('Range', 'bytes=' + start + '-' + end)\n http.setRequestHeader('X-Accept-Encoding', 'identity')\n\n // Abort if server responds with complete file in response to range\n // request, to prevent downloading large files from broken http servers\n http.onreadystatechange = function () {\n if (http.status === 200) {\n console.error(\n 'Server sent full file in response to ranged request, aborting',\n { filename },\n )\n http.abort()\n }\n }\n }\n\n http.onload = function (_e) {\n if (http.readyState === 4) {\n if (http.status !== 200 && http.status !== 206) {\n console.error(\n 'Loading the image ' + filename + ' failed (status %d)',\n http.status,\n )\n if (http.status >= 500 && http.status < 600) {\n retry()\n }\n } else if (http.response) {\n if (options.range) {\n const enc = http.getResponseHeader('Content-Encoding')\n if (enc && enc !== 'identity') {\n console.error(\n 'Server sent Content-Encoding in response to ranged request',\n { filename, enc },\n )\n }\n }\n if (options.done) {\n options.done(http.response, http)\n }\n }\n }\n }\n\n http.onerror = function (e) {\n console.error('Loading the image ' + filename + ' failed', e)\n retry()\n }\n\n if (options.progress) {\n http.onprogress = function (e) {\n options.progress!(e)\n }\n }\n\n http.send(null)\n\n function retry() {\n const number_of_tries = n_tries || 0\n const timeout = [1, 1, 2, 3, 5, 8, 13, 21][number_of_tries] || 34\n setTimeout(() => {\n load_file(filename, options, number_of_tries + 1)\n }, 1000 * timeout)\n }\n }\n\n get_file_size = async function (url: string) {\n return new Promise((resolve, reject) => {\n load_file(url, {\n done: (_buffer, http) => {\n const header =\n http!.getResponseHeader('Content-Range') || ''\n const match = header.match(/\\/(\\d+)\\s*$/)\n\n if (match) {\n resolve(+match[1])\n } else {\n const error = new Error(\n '`Range: bytes=...` header not supported (Got `' +\n header +\n '`)',\n )\n reject(error)\n }\n },\n headers: {\n Range: 'bytes=0-0',\n 'X-Accept-Encoding': 'identity',\n },\n })\n })\n }\n}\n\n// Reads len characters at offset from Memory object mem as a JS string\nexport function read_sized_string_from_mem(\n mem: { buffer: ArrayBuffer },\n offset: number,\n len: number,\n): string {\n offset >>>= 0\n len >>>= 0\n return String.fromCharCode(...new Uint8Array(mem.buffer, offset, len))\n}\n\nconst CHARMAPS: Record<string, string> = {\n cp437: ' \\u263A\\u263B\\u2665\\u2666\\u2663\\u2660\\u2022\\u25D8\\u25CB\\u25D9\\u2642\\u2640\\u266A\\u266B\\u263C\\u25BA\\u25C4\\u2195\\u203C\\u00B6\\u00A7\\u25AC\\u21A8\\u2191\\u2193\\u2192\\u2190\\u221F\\u2194\\u25B2\\u25BC !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\u2302\\u00C7\\u00FC\\u00E9\\u00E2\\u00E4\\u00E0\\u00E5\\u00E7\\u00EA\\u00EB\\u00E8\\u00EF\\u00EE\\u00EC\\u00C4\\u00C5\\u00C9\\u00E6\\u00C6\\u00F4\\u00F6\\u00F2\\u00FB\\u00F9\\u00FF\\u00D6\\u00DC\\u00A2\\u00A3\\u00A5\\u20A7\\u0192\\u00E1\\u00ED\\u00F3\\u00FA\\u00F1\\u00D1\\u00AA\\u00BA\\u00BF\\u2310\\u00AC\\u00BD\\u00BC\\u00A1\\u00AB\\u00BB\\u2591\\u2592\\u2593\\u2502\\u2524\\u2561\\u2562\\u2556\\u2555\\u2563\\u2551\\u2557\\u255D\\u255C\\u255B\\u2510\\u2514\\u2534\\u252C\\u251C\\u2500\\u253C\\u255E\\u255F\\u255A\\u2554\\u2569\\u2566\\u2560\\u2550\\u256C\\u2567\\u2568\\u2564\\u2565\\u2559\\u2558\\u2552\\u2553\\u256B\\u256A\\u2518\\u250C\\u2588\\u2584\\u258C\\u2590\\u2580\\u03B1\\u00DF\\u0393\\u03C0\\u03A3\\u03C3\\u00B5\\u03C4\\u03A6\\u0398\\u03A9\\u03B4\\u221E\\u03C6\\u03B5\\u2229\\u2261\\u00B1\\u2265\\u2264\\u2320\\u2321\\u00F7\\u2248\\u00B0\\u2219\\u00B7\\u221A\\u207F\\u00B2\\u25A0 ',\n cp858: '\\u00C7\\u00FC\\u00E9\\u00E2\\u00E4\\u00E0\\u00E5\\u00E7\\u00EA\\u00EB\\u00E8\\u00EF\\u00EE\\u00EC\\u00C4\\u00C5\\u00C9\\u00E6\\u00C6\\u00F4\\u00F6\\u00F2\\u00FB\\u00F9\\u00FF\\u00D6\\u00DC\\u00F8\\u00A3\\u00D8\\u00D7\\u0192\\u00E1\\u00ED\\u00F3\\u00FA\\u00F1\\u00D1\\u00AA\\u00BA\\u00BF\\u00AE\\u00AC\\u00BD\\u00BC\\u00A1\\u00AB\\u00BB\\u2591\\u2592\\u2593\\u2502\\u2524\\u00C1\\u00C2\\u00C0\\u00A9\\u2563\\u2551\\u2557\\u255D\\u00A2\\u00A5\\u2510\\u2514\\u2534\\u252C\\u251C\\u2500\\u253C\\u00E3\\u00C3\\u255A\\u2554\\u2569\\u2566\\u2560\\u2550\\u256C\\u00A4\\u00F0\\u00D0\\u00CA\\u00CB\\u00C8\\u20AC\\u00CD\\u00CE\\u00CF\\u2518\\u250C\\u2588\\u2584\\u00A6\\u00CC\\u2580\\u00D3\\u00DF\\u00D4\\u00D2\\u00F5\\u00D5\\u00B5\\u00FE\\u00DE\\u00DA\\u00DB\\u00D9\\u00FD\\u00DD\\u00AF\\u00B4\\u00AD\\u00B1\\u2017\\u00BE\\u00B6\\u00A7\\u00F7\\u00B8\\u00B0\\u00A8\\u00B7\\u00B9\\u00B3\\u00B2\\u25A0 ',\n}\n\nCHARMAPS.cp858 = CHARMAPS.cp437.slice(0, 128) + CHARMAPS.cp858\nCHARMAPS.ascii = CHARMAPS.cp437\n .split('')\n .map((c, i) => (i > 31 && i < 128 ? c : '.'))\n .join('')\n\nexport function get_charmap(encoding: string): string {\n return encoding && CHARMAPS[encoding] ? CHARMAPS[encoding] : CHARMAPS.cp437\n}\n", "import { load_file, get_file_size } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\n\n// The smallest size the emulated hardware can emit\nconst BLOCK_SIZE = 256\n\nconst ASYNC_SAFE = false\n\nexport class SyncBuffer {\n buffer: ArrayBuffer\n byteLength: number\n onload: ((e: { buffer: ArrayBuffer }) => void) | undefined = undefined\n onprogress:\n | ((e: {\n loaded: number\n total: number\n lengthComputable: boolean\n }) => void)\n | undefined = undefined\n\n constructor(buffer: ArrayBuffer) {\n dbg_assert(buffer instanceof ArrayBuffer)\n\n this.buffer = buffer\n this.byteLength = buffer.byteLength\n }\n\n load(): void {\n if (this.onload) {\n this.onload({ buffer: this.buffer })\n }\n }\n\n get(start: number, len: number, fn: (data: Uint8Array) => void): void {\n dbg_assert(start + len <= this.byteLength)\n fn(new Uint8Array(this.buffer, start, len))\n }\n\n set(start: number, slice: Uint8Array, fn: () => void): void {\n dbg_assert(start + slice.byteLength <= this.byteLength)\n\n new Uint8Array(this.buffer, start, slice.byteLength).set(slice)\n fn()\n }\n\n get_buffer(fn: (buffer: ArrayBuffer) => void): void {\n fn(this.buffer)\n }\n\n get_state(): [number, Uint8Array] {\n return [this.byteLength, new Uint8Array(this.buffer)]\n }\n\n set_state(state: [number, Uint8Array]): void {\n this.byteLength = state[0]\n this.buffer = state[1].slice().buffer\n }\n}\n\nclass AsyncXHRBuffer {\n filename: string\n byteLength: number | undefined\n block_cache: Map<number, Uint8Array> = new Map()\n block_cache_is_write: Set<number> = new Set()\n fixed_chunk_size: number | undefined\n cache_reads: boolean\n onload: ((e: object) => void) | undefined = undefined\n onprogress: ((e: ProgressEvent) => void) | undefined = undefined\n\n constructor(\n filename: string,\n size: number | undefined,\n fixed_chunk_size: number | undefined,\n ) {\n this.filename = filename\n this.byteLength = size\n this.fixed_chunk_size = fixed_chunk_size\n this.cache_reads = !!fixed_chunk_size\n }\n\n async load(): Promise<void> {\n if (this.byteLength !== undefined) {\n if (this.onload) {\n this.onload(Object.create(null))\n }\n return\n }\n\n const size = await get_file_size(this.filename)\n this.byteLength = size\n if (this.onload) {\n this.onload(Object.create(null))\n }\n }\n\n get_from_cache(offset: number, len: number): Uint8Array | undefined {\n const number_of_blocks = len / BLOCK_SIZE\n const block_index = offset / BLOCK_SIZE\n\n for (let i = 0; i < number_of_blocks; i++) {\n const block = this.block_cache.get(block_index + i)\n\n if (!block) {\n return\n }\n }\n\n if (number_of_blocks === 1) {\n return this.block_cache.get(block_index)\n } else {\n const result = new Uint8Array(len)\n for (let i = 0; i < number_of_blocks; i++) {\n result.set(\n this.block_cache.get(block_index + i)!,\n i * BLOCK_SIZE,\n )\n }\n return result\n }\n }\n\n get(offset: number, len: number, fn: (data: Uint8Array) => void): void {\n dbg_assert(offset + len <= this.byteLength!)\n dbg_assert(offset % BLOCK_SIZE === 0)\n dbg_assert(len % BLOCK_SIZE === 0)\n dbg_assert(len > 0)\n\n const block = this.get_from_cache(offset, len)\n if (block) {\n if (ASYNC_SAFE) {\n setTimeout(fn.bind(this, block), 0)\n } else {\n fn(block)\n }\n return\n }\n\n let requested_start = offset\n let requested_length = len\n if (this.fixed_chunk_size) {\n requested_start = offset - (offset % this.fixed_chunk_size)\n requested_length =\n Math.ceil(\n (offset - requested_start + len) / this.fixed_chunk_size,\n ) * this.fixed_chunk_size\n }\n\n load_file(this.filename, {\n done: function (this: AsyncXHRBuffer, buffer: ArrayBuffer) {\n const block = new Uint8Array(buffer)\n this.handle_read(requested_start, requested_length, block)\n if (requested_start === offset && requested_length === len) {\n fn(block)\n } else {\n fn(\n block.subarray(\n offset - requested_start,\n offset - requested_start + len,\n ),\n )\n }\n }.bind(this),\n range: { start: requested_start, length: requested_length },\n })\n }\n\n set(start: number, data: Uint8Array, fn: () => void): void {\n const len = data.length\n dbg_assert(start + data.byteLength <= this.byteLength!)\n dbg_assert(start % BLOCK_SIZE === 0)\n dbg_assert(len % BLOCK_SIZE === 0)\n dbg_assert(len > 0)\n\n const start_block = start / BLOCK_SIZE\n const block_count = len / BLOCK_SIZE\n\n for (let i = 0; i < block_count; i++) {\n const block = this.block_cache.get(start_block + i)\n\n if (block === undefined) {\n const data_slice = data.slice(\n i * BLOCK_SIZE,\n (i + 1) * BLOCK_SIZE,\n )\n this.block_cache.set(start_block + i, data_slice)\n } else {\n const data_slice = data.subarray(\n i * BLOCK_SIZE,\n (i + 1) * BLOCK_SIZE,\n )\n dbg_assert(block.byteLength === data_slice.length)\n block.set(data_slice)\n }\n\n this.block_cache_is_write.add(start_block + i)\n }\n\n fn()\n }\n\n handle_read(offset: number, len: number, block: Uint8Array): void {\n // Used by AsyncXHRBuffer, AsyncXHRPartfileBuffer and AsyncFileBuffer\n // Overwrites blocks from the original source that have been written since\n\n const start_block = offset / BLOCK_SIZE\n const block_count = len / BLOCK_SIZE\n\n for (let i = 0; i < block_count; i++) {\n const cached_block = this.block_cache.get(start_block + i)\n\n if (cached_block) {\n block.set(cached_block, i * BLOCK_SIZE)\n } else if (this.cache_reads) {\n this.block_cache.set(\n start_block + i,\n block.slice(i * BLOCK_SIZE, (i + 1) * BLOCK_SIZE),\n )\n }\n }\n }\n\n get_buffer(fn: (buffer?: ArrayBuffer) => void): void {\n // We must download all parts, unlikely a good idea for big files\n fn()\n }\n\n get_state(): [[number, Uint8Array][]] {\n const block_cache: [number, Uint8Array][] = []\n\n for (const [index, block] of this.block_cache) {\n dbg_assert(isFinite(index))\n if (this.block_cache_is_write.has(index)) {\n block_cache.push([index, block])\n }\n }\n\n return [block_cache]\n }\n\n set_state(state: [[number, Uint8Array][]]): void {\n const block_cache = state[0]\n this.block_cache.clear()\n this.block_cache_is_write.clear()\n\n for (const [index, block] of block_cache) {\n dbg_assert(isFinite(index))\n this.block_cache.set(index, block)\n this.block_cache_is_write.add(index)\n }\n }\n}\n\nexport class AsyncXHRPartfileBuffer {\n extension: string\n basename: string\n is_zstd: boolean\n block_cache: Map<number, Uint8Array> = new Map()\n block_cache_is_write: Set<number> = new Set()\n byteLength: number | undefined\n fixed_chunk_size: number | undefined\n partfile_alt_format: boolean\n\n zstd_decompress:\n | ((size: number, data: Uint8Array) => Promise<any>)\n | undefined\n cache_reads: boolean\n onload: ((e: object) => void) | undefined = undefined\n onprogress: ((e: ProgressEvent) => void) | undefined = undefined\n\n constructor(\n filename: string,\n size: number | undefined,\n fixed_chunk_size: number | undefined,\n partfile_alt_format: boolean | undefined,\n\n zstd_decompress?: (size: number, data: Uint8Array) => Promise<any>,\n ) {\n const parts = filename.match(/\\.[^.]+(\\.zst)?$/)\n\n this.extension = parts ? parts[0] : ''\n this.basename = filename.substring(\n 0,\n filename.length - this.extension.length,\n )\n\n this.is_zstd = this.extension.endsWith('.zst')\n\n if (!this.basename.endsWith('/')) {\n this.basename += '-'\n }\n\n this.byteLength = size\n this.fixed_chunk_size = fixed_chunk_size\n this.partfile_alt_format = !!partfile_alt_format\n this.zstd_decompress = zstd_decompress\n\n this.cache_reads = !!fixed_chunk_size\n }\n\n load(): void {\n if (this.byteLength !== undefined) {\n if (this.onload) {\n this.onload(Object.create(null))\n }\n return\n }\n dbg_assert(false)\n if (this.onload) {\n this.onload(Object.create(null))\n }\n }\n\n get(offset: number, len: number, fn: (data: Uint8Array) => void): void {\n dbg_assert(offset + len <= this.byteLength!)\n dbg_assert(offset % BLOCK_SIZE === 0)\n dbg_assert(len % BLOCK_SIZE === 0)\n dbg_assert(len > 0)\n\n const block = this.get_from_cache(offset, len)\n\n if (block) {\n if (ASYNC_SAFE) {\n setTimeout(fn.bind(this, block), 0)\n } else {\n fn(block)\n }\n return\n }\n\n if (this.fixed_chunk_size) {\n const start_index = Math.floor(offset / this.fixed_chunk_size)\n const m_offset = offset - start_index * this.fixed_chunk_size\n dbg_assert(m_offset >= 0)\n const total_count = Math.ceil(\n (m_offset + len) / this.fixed_chunk_size,\n )\n const blocks = new Uint8Array(total_count * this.fixed_chunk_size)\n let finished = 0\n\n for (let i = 0; i < total_count; i++) {\n const chunk_offset = (start_index + i) * this.fixed_chunk_size\n\n const part_filename = this.partfile_alt_format\n ? // matches output of gnu split:\n // split -b 512 -a8 -d --additional-suffix .img w95.img w95-\n this.basename +\n (start_index + i + '').padStart(8, '0') +\n this.extension\n : this.basename +\n chunk_offset +\n '-' +\n (chunk_offset + this.fixed_chunk_size) +\n this.extension\n\n // XXX: unnecessary allocation\n const cached = this.get_from_cache(\n chunk_offset,\n this.fixed_chunk_size,\n )\n\n if (cached) {\n blocks.set(cached, i * this.fixed_chunk_size)\n finished++\n if (finished === total_count) {\n fn(blocks.subarray(m_offset, m_offset + len))\n }\n } else {\n load_file(part_filename, {\n done: async function (\n this: AsyncXHRPartfileBuffer,\n buffer: ArrayBuffer,\n ) {\n let block = new Uint8Array(buffer)\n\n if (this.is_zstd) {\n const decompressed = await this\n .zstd_decompress!(\n this.fixed_chunk_size!,\n block,\n )\n block = new Uint8Array(decompressed)\n }\n\n blocks.set(block, i * this.fixed_chunk_size!)\n this.handle_read(\n (start_index + i) * this.fixed_chunk_size!,\n this.fixed_chunk_size! | 0,\n block,\n )\n\n finished++\n if (finished === total_count) {\n fn(blocks.subarray(m_offset, m_offset + len))\n }\n }.bind(this),\n })\n }\n }\n } else {\n const part_filename =\n this.basename + offset + '-' + (offset + len) + this.extension\n\n load_file(part_filename, {\n done: function (\n this: AsyncXHRPartfileBuffer,\n buffer: ArrayBuffer,\n ) {\n dbg_assert(buffer.byteLength === len)\n const block = new Uint8Array(buffer)\n this.handle_read(offset, len, block)\n fn(block)\n }.bind(this),\n })\n }\n }\n\n // Shared methods from AsyncXHRBuffer\n get_from_cache = AsyncXHRBuffer.prototype.get_from_cache\n set = AsyncXHRBuffer.prototype.set\n handle_read = AsyncXHRBuffer.prototype.handle_read\n get_state = AsyncXHRBuffer.prototype.get_state\n set_state = AsyncXHRBuffer.prototype.set_state\n}\n\nexport class SyncFileBuffer {\n file: File | undefined\n byteLength: number\n buffer: ArrayBuffer\n onload: ((e: { buffer: ArrayBuffer }) => void) | undefined = undefined\n onprogress:\n | ((e: {\n loaded: number\n total: number\n lengthComputable: boolean\n }) => void)\n | undefined = undefined\n\n constructor(file: File) {\n this.file = file\n this.byteLength = file.size\n\n if (file.size > 1 << 30) {\n console.warn(\n 'SyncFileBuffer: Allocating buffer of ' +\n (file.size >> 20) +\n ' MB ...',\n )\n }\n\n this.buffer = new ArrayBuffer(file.size)\n }\n\n load(): void {\n this.load_next(0)\n }\n\n load_next(start: number): void {\n const PART_SIZE = 4 << 20\n\n const filereader = new FileReader()\n\n filereader.onload = function (\n this: SyncFileBuffer,\n e: ProgressEvent<FileReader>,\n ) {\n const result = e.target!.result\n if (!(result instanceof ArrayBuffer)) return\n const buffer = new Uint8Array(result)\n new Uint8Array(this.buffer, start).set(buffer)\n this.load_next(start + PART_SIZE)\n }.bind(this)\n\n if (this.onprogress) {\n this.onprogress({\n loaded: start,\n total: this.byteLength,\n lengthComputable: true,\n })\n }\n\n if (start < this.byteLength) {\n const end = Math.min(start + PART_SIZE, this.byteLength)\n const slice = this.file!.slice(start, end)\n filereader.readAsArrayBuffer(slice)\n } else {\n this.file = undefined\n if (this.onload) {\n this.onload({ buffer: this.buffer })\n }\n }\n }\n\n get = SyncBuffer.prototype.get\n set = SyncBuffer.prototype.set\n get_buffer = SyncBuffer.prototype.get_buffer\n get_state = SyncBuffer.prototype.get_state\n set_state = SyncBuffer.prototype.set_state\n}\n\nexport class AsyncFileBuffer {\n file: File\n byteLength: number\n block_cache: Map<number, Uint8Array> = new Map()\n block_cache_is_write: Set<number> = new Set()\n onload: ((e: object) => void) | undefined = undefined\n onprogress: ((e: ProgressEvent) => void) | undefined = undefined\n\n constructor(file: File) {\n this.file = file\n this.byteLength = file.size\n }\n\n load(): void {\n if (this.onload) {\n this.onload(Object.create(null))\n }\n }\n\n get(offset: number, len: number, fn: (data: Uint8Array) => void): void {\n dbg_assert(offset % BLOCK_SIZE === 0)\n dbg_assert(len % BLOCK_SIZE === 0)\n dbg_assert(len > 0)\n\n const block = this.get_from_cache(offset, len)\n if (block) {\n fn(block)\n return\n }\n\n const fr = new FileReader()\n\n fr.onload = function (\n this: AsyncFileBuffer,\n e: ProgressEvent<FileReader>,\n ) {\n const result = e.target!.result\n if (!(result instanceof ArrayBuffer)) return\n const block = new Uint8Array(result)\n\n this.handle_read(offset, len, block)\n fn(block)\n }.bind(this)\n\n fr.readAsArrayBuffer(this.file.slice(offset, offset + len))\n }\n\n get_from_cache = AsyncXHRBuffer.prototype.get_from_cache\n set = AsyncXHRBuffer.prototype.set\n handle_read = AsyncXHRBuffer.prototype.handle_read\n get_state = AsyncXHRBuffer.prototype.get_state\n set_state = AsyncXHRBuffer.prototype.set_state\n\n get_buffer(fn: (buffer?: ArrayBuffer) => void): void {\n // We must load all parts, unlikely a good idea for big files\n fn()\n }\n\n get_as_file(name: string): File {\n const parts: BlobPart[] = []\n const existing_blocks = Array.from(this.block_cache.keys()).sort(\n function (x, y) {\n return x - y\n },\n )\n\n let current_offset = 0\n\n for (let i = 0; i < existing_blocks.length; i++) {\n const block_index = existing_blocks[i]\n const block = this.block_cache.get(block_index)!\n const start = block_index * BLOCK_SIZE\n dbg_assert(start >= current_offset)\n\n if (start !== current_offset) {\n parts.push(this.file.slice(current_offset, start))\n current_offset = start\n }\n\n parts.push(new Uint8Array(block))\n current_offset += block.length\n }\n\n if (current_offset !== this.file.size) {\n parts.push(this.file.slice(current_offset))\n }\n\n const file = new File(parts, name)\n dbg_assert(file.size === this.file.size)\n\n return file\n }\n}\n\nexport function buffer_from_object(\n obj: {\n buffer?: ArrayBuffer | File\n url?: string\n size?: number\n fixed_chunk_size?: number\n async?: boolean\n use_parts?: boolean\n },\n\n zstd_decompress_worker?: (size: number, data: Uint8Array) => Promise<any>,\n):\n | SyncBuffer\n | SyncFileBuffer\n | AsyncFileBuffer\n | AsyncXHRBuffer\n | AsyncXHRPartfileBuffer\n | undefined {\n if (obj.buffer instanceof ArrayBuffer) {\n return new SyncBuffer(obj.buffer)\n } else if (typeof File !== 'undefined' && obj.buffer instanceof File) {\n // SyncFileBuffer:\n // - loads the whole disk image into memory, impossible for large files (more than 1GB)\n // - can later serve get/set operations fast and synchronously\n // - takes some time for first load, neglectable for small files (up to 100Mb)\n //\n // AsyncFileBuffer:\n // - loads slices of the file asynchronously as requested\n // - slower get/set\n\n // Heuristics: If file is larger than or equal to 256M, use AsyncFileBuffer\n let is_async = obj.async\n if (is_async === undefined) {\n is_async = obj.buffer.size >= 256 * 1024 * 1024\n }\n\n if (is_async) {\n return new AsyncFileBuffer(obj.buffer)\n } else {\n return new SyncFileBuffer(obj.buffer)\n }\n } else if (obj.url) {\n // Note: Only async for now\n\n if (obj.use_parts) {\n return new AsyncXHRPartfileBuffer(\n obj.url,\n obj.size,\n obj.fixed_chunk_size,\n false,\n zstd_decompress_worker,\n )\n } else {\n return new AsyncXHRBuffer(obj.url, obj.size, obj.fixed_chunk_size)\n }\n } else {\n dbg_log('Ignored file: url=' + obj.url + ' buffer=' + obj.buffer)\n }\n}\n", "import {\n LOG_SB16,\n MIXER_CHANNEL_BOTH,\n MIXER_CHANNEL_LEFT,\n MIXER_CHANNEL_RIGHT,\n MIXER_SRC_PCSPEAKER,\n MIXER_SRC_DAC,\n MIXER_SRC_MASTER,\n} from './const.js'\nimport { h } from './lib.js'\nimport { dbg_log } from './log.js'\nimport { SyncBuffer } from './buffer.js'\n\nimport { DMA } from './dma.js'\nimport { IO } from './io.js'\nimport { BusConnector } from './bus.js'\nimport { ByteQueue, FloatQueue } from './lib.js'\n\n// Minimal interface for the CPU fields SB16 uses.\ninterface SB16Cpu {\n io: IO\n devices: { dma: DMA }\n device_raise_irq(irq: number): void\n device_lower_irq(irq: number): void\n}\n\n// Useful documentation, articles, and source codes for reference:\n// ===============================================================\n//\n// Official Hardware Programming Guide\n// -> https://pdos.csail.mit.edu/6.828/2011/readings/hardware/SoundBlaster.pdf\n//\n// Official Yamaha YMF262 Manual\n// -> http://map.grauw.nl/resources/sound/yamaha_ymf262.pdf\n//\n// OPL3 Programming Guide\n// -> http://www.fit.vutbr.cz/~arnost/opl/opl3.html\n//\n// DOSBox\n// -> https://sourceforge.net/p/dosbox/code-0/HEAD/tree/dosbox/branches/mamesound/src/hardware/sblaster.cpp\n// -> https://github.com/duganchen/dosbox/blob/master/src/hardware/sblaster.cpp\n// -> https://github.com/joncampbell123/dosbox-x/blob/master/src/hardware/sblaster.cpp\n//\n// QEMU\n// -> https://github.com/qemu/qemu/blob/master/hw/audio/sb16.c\n// -> https://github.com/hackndev/qemu/blob/master/hw/sb16.c\n//\n// VirtualBox\n// -> https://www.virtualbox.org/svn/vbox/trunk/src/VBox/Devices/Audio/DevSB16.cpp\n// -> https://github.com/mdaniel/virtualbox-org-svn-vbox-trunk/blob/master/src/VBox/Devices/Audio/DevSB16.cpp\n\nconst // Used for drivers to identify device (DSP command 0xE3).\n DSP_COPYRIGHT = 'COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.',\n // Value of the current DSP command that indicates that the\n // next command/data write in port 2xC should be interpreted\n // as a command number.\n DSP_NO_COMMAND = 0,\n // Size (bytes) of the DSP write/read buffers\n DSP_BUFSIZE = 64,\n // Size (bytes) of the buffers containing floating point linear PCM audio.\n DSP_DACSIZE = 65536,\n // Size (bytes) of the buffer in which DMA transfers are temporarily\n // stored before being processed.\n SB_DMA_BUFSIZE = 65536,\n // Number of samples to attempt to retrieve per transfer.\n SB_DMA_BLOCK_SAMPLES = 1024,\n // Usable DMA channels.\n SB_DMA0 = 0,\n SB_DMA1 = 1,\n SB_DMA3 = 3,\n SB_DMA5 = 5,\n SB_DMA6 = 6,\n SB_DMA7 = 7,\n // Default DMA channels.\n SB_DMA_CHANNEL_8BIT = SB_DMA1,\n SB_DMA_CHANNEL_16BIT = SB_DMA5,\n // Usable IRQ channels.\n SB_IRQ2 = 2,\n SB_IRQ5 = 5,\n SB_IRQ7 = 7,\n SB_IRQ10 = 10,\n // Default IRQ channel.\n SB_IRQ = SB_IRQ5,\n // Indices to the irq_triggered register.\n SB_IRQ_8BIT = 0x1,\n SB_IRQ_16BIT = 0x2,\n _SB_IRQ_MIDI = 0x1,\n _SB_IRQ_MPU = 0x4\n\n// Probably less efficient, but it's more maintainable, instead\n// of having a single large unorganised and decoupled table.\nconst DSP_COMMAND_SIZES = new Uint8Array(256)\nconst DSP_COMMAND_HANDLERS: Array<((this: SB16) => void) | undefined> = []\nconst MIXER_READ_HANDLERS: Array<((this: SB16) => number) | undefined> = []\nconst MIXER_WRITE_HANDLERS: Array<\n ((this: SB16, data: number) => void) | undefined\n> = []\nconst MIXER_REGISTER_IS_LEGACY = new Uint8Array(256)\nconst FM_HANDLERS: Array<\n | ((this: SB16, data: number, register: number, address: number) => void)\n | undefined\n> = []\n\n// Sound Blaster 16 Emulator, or so it seems.\nexport class SB16 {\n cpu: SB16Cpu\n bus: BusConnector\n\n // I/O Buffers.\n write_buffer: ByteQueue\n read_buffer: ByteQueue\n read_buffer_lastvalue: number\n\n // Current DSP command info.\n command: number\n command_size: number\n\n // Mixer.\n mixer_current_address: number\n mixer_registers: Uint8Array\n\n // Dummy status and test registers.\n dummy_speaker_enabled: boolean\n test_register: number\n\n // DSP state.\n dsp_highspeed: boolean\n dsp_stereo: boolean\n dsp_16bit: boolean\n dsp_signed: boolean\n\n // DAC buffer.\n // The final destination for audio data before being sent off\n // to Web Audio APIs.\n // Format:\n // Floating precision linear PCM, nominal between -1 and 1.\n dac_buffers: [FloatQueue, FloatQueue]\n\n // Direct Memory Access transfer info.\n dma: DMA\n dma_sample_count: number\n dma_bytes_count: number\n dma_bytes_left: number\n dma_bytes_block: number\n dma_irq: number\n dma_channel: number\n dma_channel_8bit: number\n dma_channel_16bit: number\n dma_autoinit: boolean\n dma_buffer: ArrayBuffer\n dma_buffer_int8: Int8Array\n dma_buffer_uint8: Uint8Array\n dma_buffer_int16: Int16Array\n dma_buffer_uint16: Uint16Array\n dma_syncbuffer: SyncBuffer\n dma_waiting_transfer: boolean\n dma_paused: boolean\n sampling_rate: number\n bytes_per_sample: number\n\n // DMA identification data.\n e2_value: number\n e2_count: number\n\n // ASP data: not understood by me.\n asp_registers: Uint8Array\n\n // MPU.\n mpu_read_buffer: ByteQueue\n mpu_read_buffer_lastvalue: number\n // Bug-compatible: get_state/set_state reference a different spelling.\n mpu_read_buffer_last_value: number | undefined\n\n // FM Synthesizer.\n fm_current_address0: number\n fm_current_address1: number\n fm_waveform_select_enable: Record<number, number>\n\n // Interrupts.\n irq: number\n irq_triggered: Uint8Array\n\n name: string | undefined\n\n constructor(cpu: SB16Cpu, bus: BusConnector) {\n this.cpu = cpu\n this.bus = bus\n\n // I/O Buffers.\n this.write_buffer = new ByteQueue(DSP_BUFSIZE)\n this.read_buffer = new ByteQueue(DSP_BUFSIZE)\n this.read_buffer_lastvalue = 0\n\n // Current DSP command info.\n this.command = DSP_NO_COMMAND\n this.command_size = 0\n\n // Mixer.\n this.mixer_current_address = 0\n this.mixer_registers = new Uint8Array(256)\n this.mixer_reset()\n\n // Dummy status and test registers.\n this.dummy_speaker_enabled = false\n this.test_register = 0\n\n // DSP state.\n this.dsp_highspeed = false\n this.dsp_stereo = false\n this.dsp_16bit = false\n this.dsp_signed = false\n\n // DAC buffer.\n this.dac_buffers = [\n new FloatQueue(DSP_DACSIZE),\n new FloatQueue(DSP_DACSIZE),\n ]\n\n // Direct Memory Access transfer info.\n this.dma = cpu.devices.dma\n this.dma_sample_count = 0\n this.dma_bytes_count = 0\n this.dma_bytes_left = 0\n this.dma_bytes_block = 0\n this.dma_irq = 0\n this.dma_channel = 0\n this.dma_channel_8bit = SB_DMA_CHANNEL_8BIT\n this.dma_channel_16bit = SB_DMA_CHANNEL_16BIT\n this.dma_autoinit = false\n this.dma_buffer = new ArrayBuffer(SB_DMA_BUFSIZE)\n this.dma_buffer_int8 = new Int8Array(this.dma_buffer)\n this.dma_buffer_uint8 = new Uint8Array(this.dma_buffer)\n this.dma_buffer_int16 = new Int16Array(this.dma_buffer)\n this.dma_buffer_uint16 = new Uint16Array(this.dma_buffer)\n this.dma_syncbuffer = new SyncBuffer(this.dma_buffer)\n this.dma_waiting_transfer = false\n this.dma_paused = false\n this.sampling_rate = 22050\n bus.send('dac-tell-sampling-rate', this.sampling_rate)\n this.bytes_per_sample = 1\n\n // DMA identification data.\n this.e2_value = 0xaa\n this.e2_count = 0\n\n // ASP data: not understood by me.\n this.asp_registers = new Uint8Array(256)\n\n // MPU.\n this.mpu_read_buffer = new ByteQueue(DSP_BUFSIZE)\n this.mpu_read_buffer_lastvalue = 0\n\n // FM Synthesizer.\n this.fm_current_address0 = 0\n this.fm_current_address1 = 0\n this.fm_waveform_select_enable = {}\n\n // Interrupts.\n this.irq = SB_IRQ\n this.irq_triggered = new Uint8Array(0x10)\n\n // IO Ports.\n // http://homepages.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html#DSPPorts\n // https://pdos.csail.mit.edu/6.828/2011/readings/hardware/SoundBlaster.pdf\n\n cpu.io.register_read_consecutive(\n 0x220,\n this,\n this.port2x0_read,\n this.port2x1_read,\n this.port2x2_read,\n this.port2x3_read,\n )\n cpu.io.register_read_consecutive(\n 0x388,\n this,\n this.port2x0_read,\n this.port2x1_read,\n )\n\n cpu.io.register_read_consecutive(\n 0x224,\n this,\n this.port2x4_read,\n this.port2x5_read,\n )\n\n cpu.io.register_read(0x226, this, this.port2x6_read)\n cpu.io.register_read(0x227, this, this.port2x7_read)\n cpu.io.register_read(0x228, this, this.port2x8_read)\n cpu.io.register_read(0x229, this, this.port2x9_read)\n\n cpu.io.register_read(0x22a, this, this.port2xA_read)\n cpu.io.register_read(0x22b, this, this.port2xB_read)\n cpu.io.register_read(0x22c, this, this.port2xC_read)\n cpu.io.register_read(0x22d, this, this.port2xD_read)\n\n cpu.io.register_read_consecutive(\n 0x22e,\n this,\n this.port2xE_read,\n this.port2xF_read,\n )\n\n cpu.io.register_write_consecutive(\n 0x220,\n this,\n this.port2x0_write,\n this.port2x1_write,\n this.port2x2_write,\n this.port2x3_write,\n )\n cpu.io.register_write_consecutive(\n 0x388,\n this,\n this.port2x0_write,\n this.port2x1_write,\n )\n\n cpu.io.register_write_consecutive(\n 0x224,\n this,\n this.port2x4_write,\n this.port2x5_write,\n )\n\n cpu.io.register_write(0x226, this, this.port2x6_write)\n cpu.io.register_write(0x227, this, this.port2x7_write)\n\n cpu.io.register_write_consecutive(\n 0x228,\n this,\n this.port2x8_write,\n this.port2x9_write,\n )\n\n cpu.io.register_write(0x22a, this, this.port2xA_write)\n cpu.io.register_write(0x22b, this, this.port2xB_write)\n cpu.io.register_write(0x22c, this, this.port2xC_write)\n cpu.io.register_write(0x22d, this, this.port2xD_write)\n cpu.io.register_write(0x22e, this, this.port2xE_write)\n cpu.io.register_write(0x22f, this, this.port2xF_write)\n\n cpu.io.register_read_consecutive(\n 0x330,\n this,\n this.port3x0_read,\n this.port3x1_read,\n )\n cpu.io.register_write_consecutive(\n 0x330,\n this,\n this.port3x0_write,\n this.port3x1_write,\n )\n\n this.dma.on_unmask(this.dma_on_unmask, this)\n\n bus.register(\n 'dac-request-data',\n function (this: SB16) {\n this.dac_handle_request()\n },\n this,\n )\n bus.register(\n 'speaker-has-initialized',\n function (this: SB16) {\n this.mixer_reset()\n },\n this,\n )\n bus.send('speaker-confirm-initialized')\n\n this.dsp_reset()\n }\n\n //\n // General\n //\n\n dsp_reset(): void {\n this.write_buffer.clear()\n this.read_buffer.clear()\n\n this.command = DSP_NO_COMMAND\n this.command_size = 0\n\n this.dummy_speaker_enabled = false\n this.test_register = 0\n\n this.dsp_highspeed = false\n this.dsp_stereo = false\n this.dsp_16bit = false\n this.dsp_signed = false\n\n this.dac_buffers[0].clear()\n this.dac_buffers[1].clear()\n\n this.dma_sample_count = 0\n this.dma_bytes_count = 0\n this.dma_bytes_left = 0\n this.dma_bytes_block = 0\n this.dma_irq = 0\n this.dma_channel = 0\n this.dma_autoinit = false\n this.dma_buffer_uint8.fill(0)\n this.dma_waiting_transfer = false\n this.dma_paused = false\n\n this.e2_value = 0xaa\n this.e2_count = 0\n\n this.sampling_rate = 22050\n this.bytes_per_sample = 1\n\n this.lower_irq(SB_IRQ_8BIT)\n this.irq_triggered.fill(0)\n\n this.asp_registers.fill(0)\n this.asp_registers[5] = 0x01\n this.asp_registers[9] = 0xf8\n }\n\n get_state(): unknown[] {\n const state: unknown[] = []\n\n // state[0] = this.write_buffer;\n // state[1] = this.read_buffer;\n state[2] = this.read_buffer_lastvalue\n\n state[3] = this.command\n state[4] = this.command_size\n\n state[5] = this.mixer_current_address\n state[6] = this.mixer_registers\n\n state[7] = this.dummy_speaker_enabled\n state[8] = this.test_register\n\n state[9] = this.dsp_highspeed\n state[10] = this.dsp_stereo\n state[11] = this.dsp_16bit\n state[12] = this.dsp_signed\n\n // state[13] = this.dac_buffers;\n //state[14]\n\n state[15] = this.dma_sample_count\n state[16] = this.dma_bytes_count\n state[17] = this.dma_bytes_left\n state[18] = this.dma_bytes_block\n state[19] = this.dma_irq\n state[20] = this.dma_channel\n state[21] = this.dma_channel_8bit\n state[22] = this.dma_channel_16bit\n state[23] = this.dma_autoinit\n state[24] = this.dma_buffer_uint8\n state[25] = this.dma_waiting_transfer\n state[26] = this.dma_paused\n state[27] = this.sampling_rate\n state[28] = this.bytes_per_sample\n\n state[29] = this.e2_value\n state[30] = this.e2_count\n\n state[31] = this.asp_registers\n\n // state[32] = this.mpu_read_buffer;\n state[33] = this.mpu_read_buffer_last_value\n\n state[34] = this.irq\n state[35] = this.irq_triggered\n //state[36]\n\n return state\n }\n\n set_state(state: any[]): void {\n // this.write_buffer = state[0];\n // this.read_buffer = state[1];\n this.read_buffer_lastvalue = state[2]\n\n this.command = state[3]\n this.command_size = state[4]\n\n this.mixer_current_address = state[5]\n this.mixer_registers = state[6]\n this.mixer_full_update()\n\n this.dummy_speaker_enabled = state[7]\n this.test_register = state[8]\n\n this.dsp_highspeed = state[9]\n this.dsp_stereo = state[10]\n this.dsp_16bit = state[11]\n this.dsp_signed = state[12]\n\n // this.dac_buffers = state[13];\n //state[14]\n\n this.dma_sample_count = state[15]\n this.dma_bytes_count = state[16]\n this.dma_bytes_left = state[17]\n this.dma_bytes_block = state[18]\n this.dma_irq = state[19]\n this.dma_channel = state[20]\n this.dma_channel_8bit = state[21]\n this.dma_channel_16bit = state[22]\n this.dma_autoinit = state[23]\n this.dma_buffer_uint8 = state[24]\n this.dma_waiting_transfer = state[25]\n this.dma_paused = state[26]\n this.sampling_rate = state[27]\n this.bytes_per_sample = state[28]\n\n this.e2_value = state[29]\n this.e2_count = state[30]\n\n this.asp_registers = state[31]\n\n // this.mpu_read_buffer = state[32];\n this.mpu_read_buffer_last_value = state[33]\n\n this.irq = state[34]\n this.irq_triggered = state[35]\n //state[36];\n\n const buf = this.dma_buffer_uint8.buffer\n if (buf instanceof ArrayBuffer) {\n this.dma_buffer = buf\n }\n this.dma_buffer_int8 = new Int8Array(this.dma_buffer)\n this.dma_buffer_int16 = new Int16Array(this.dma_buffer)\n this.dma_buffer_uint16 = new Uint16Array(this.dma_buffer)\n this.dma_syncbuffer = new SyncBuffer(this.dma_buffer)\n\n if (this.dma_paused) {\n this.bus.send('dac-disable')\n } else {\n this.bus.send('dac-enable')\n }\n }\n\n //\n // I/O handlers\n //\n\n port2x0_read(): number {\n dbg_log('220 read: fm music status port (unimplemented)', LOG_SB16)\n return 0xff\n }\n\n port2x1_read(): number {\n dbg_log('221 read: fm music data port (write only)', LOG_SB16)\n return 0xff\n }\n\n port2x2_read(): number {\n dbg_log(\n '222 read: advanced fm music status port (unimplemented)',\n LOG_SB16,\n )\n return 0xff\n }\n\n port2x3_read(): number {\n dbg_log('223 read: advanced music data port (write only)', LOG_SB16)\n return 0xff\n }\n\n // Mixer Address Port.\n port2x4_read(): number {\n dbg_log('224 read: mixer address port', LOG_SB16)\n return this.mixer_current_address\n }\n\n // Mixer Data Port.\n port2x5_read(): number {\n dbg_log('225 read: mixer data port', LOG_SB16)\n return this.mixer_read(this.mixer_current_address)\n }\n\n port2x6_read(): number {\n dbg_log('226 read: (write only)', LOG_SB16)\n return 0xff\n }\n\n port2x7_read(): number {\n dbg_log('227 read: undocumented', LOG_SB16)\n return 0xff\n }\n\n port2x8_read(): number {\n dbg_log('228 read: fm music status port (unimplemented)', LOG_SB16)\n return 0xff\n }\n\n port2x9_read(): number {\n dbg_log('229 read: fm music data port (write only)', LOG_SB16)\n return 0xff\n }\n\n // Read Data.\n // Used to access in-bound DSP data.\n port2xA_read(): number {\n dbg_log('22A read: read data', LOG_SB16)\n if (this.read_buffer.length) {\n this.read_buffer_lastvalue = this.read_buffer.shift()\n }\n dbg_log(\n ' <- ' +\n this.read_buffer_lastvalue +\n ' ' +\n h(this.read_buffer_lastvalue) +\n \" '\" +\n String.fromCharCode(this.read_buffer_lastvalue) +\n \"'\",\n LOG_SB16,\n )\n return this.read_buffer_lastvalue\n }\n\n port2xB_read(): number {\n dbg_log('22B read: undocumented', LOG_SB16)\n return 0xff\n }\n\n // Write-Buffer Status.\n // Indicates whether the DSP is ready to accept commands or data.\n port2xC_read(): number {\n dbg_log('22C read: write-buffer status', LOG_SB16)\n // Always return ready (bit-7 set to low)\n return 0x7f\n }\n\n port2xD_read(): number {\n dbg_log('22D read: undocumented', LOG_SB16)\n return 0xff\n }\n\n // Read-Buffer Status.\n // Indicates whether there is any in-bound data available for reading.\n // Also used to acknowledge DSP 8-bit interrupt.\n port2xE_read(): number {\n dbg_log('22E read: read-buffer status / irq 8bit ack.', LOG_SB16)\n if (this.irq_triggered[SB_IRQ_8BIT]) {\n this.lower_irq(SB_IRQ_8BIT)\n }\n const ready = this.read_buffer.length && !this.dsp_highspeed\n return ((ready ? 1 : 0) << 7) | 0x7f\n }\n\n // DSP 16-bit interrupt acknowledgement.\n port2xF_read(): number {\n dbg_log('22F read: irq 16bit ack', LOG_SB16)\n this.lower_irq(SB_IRQ_16BIT)\n return 0\n }\n\n // FM Address Port - primary register.\n port2x0_write(_value: number): void {\n dbg_log(\n '220 write: (unimplemented) fm register 0 address = ' + h(_value),\n LOG_SB16,\n )\n this.fm_current_address0 = 0\n }\n\n // FM Data Port - primary register.\n port2x1_write(value: number): void {\n dbg_log(\n '221 write: (unimplemented) fm register 0 data = ' + h(value),\n LOG_SB16,\n )\n let handler = FM_HANDLERS[this.fm_current_address0]\n if (!handler) {\n handler = this.fm_default_write\n }\n handler.call(this, value, 0, this.fm_current_address0)\n }\n\n // FM Address Port - secondary register.\n port2x2_write(_value: number): void {\n dbg_log(\n '222 write: (unimplemented) fm register 1 address = ' + h(_value),\n LOG_SB16,\n )\n this.fm_current_address1 = 0\n }\n\n // FM Data Port - secondary register.\n port2x3_write(value: number): void {\n dbg_log(\n '223 write: (unimplemented) fm register 1 data =' + h(value),\n LOG_SB16,\n )\n let handler = FM_HANDLERS[this.fm_current_address1]\n if (!handler) {\n handler = this.fm_default_write\n }\n handler.call(this, value, 1, this.fm_current_address1)\n }\n\n // Mixer Address Port.\n port2x4_write(value: number): void {\n dbg_log('224 write: mixer address = ' + h(value), LOG_SB16)\n this.mixer_current_address = value\n }\n\n // Mixer Data Port.\n port2x5_write(value: number): void {\n dbg_log('225 write: mixer data = ' + h(value), LOG_SB16)\n this.mixer_write(this.mixer_current_address, value)\n }\n\n // Reset.\n // Used to reset the DSP to its default state and to exit highspeed mode.\n port2x6_write(yesplease: number): void {\n dbg_log('226 write: reset = ' + h(yesplease), LOG_SB16)\n\n if (this.dsp_highspeed) {\n dbg_log(' -> exit highspeed', LOG_SB16)\n this.dsp_highspeed = false\n } else if (yesplease) {\n dbg_log(' -> reset', LOG_SB16)\n this.dsp_reset()\n }\n\n // Signal completion.\n this.read_buffer.clear()\n this.read_buffer.push(0xaa)\n }\n\n port2x7_write(_value: number): void {\n dbg_log('227 write: undocumented', LOG_SB16)\n }\n\n port2x8_write(_value: number): void {\n dbg_log('228 write: fm music register port (unimplemented)', LOG_SB16)\n }\n\n port2x9_write(_value: number): void {\n dbg_log('229 write: fm music data port (unimplemented)', LOG_SB16)\n }\n\n port2xA_write(_value: number): void {\n dbg_log('22A write: dsp read data port (read only)', LOG_SB16)\n }\n\n port2xB_write(_value: number): void {\n dbg_log('22B write: undocumented', LOG_SB16)\n }\n\n // Write Command/Data.\n // Used to send commands or data to the DSP.\n port2xC_write(value: number): void {\n dbg_log('22C write: write command/data', LOG_SB16)\n\n if (this.command === DSP_NO_COMMAND) {\n // New command.\n dbg_log('22C write: command = ' + h(value), LOG_SB16)\n this.command = value\n this.write_buffer.clear()\n this.command_size = DSP_COMMAND_SIZES[value]\n } else {\n // More data for current command.\n dbg_log('22C write: data: ' + h(value), LOG_SB16)\n this.write_buffer.push(value)\n }\n\n // Perform command when we have all the needed data.\n if (this.write_buffer.length >= this.command_size) {\n this.command_do()\n }\n }\n\n port2xD_write(_value: number): void {\n dbg_log('22D write: undocumented', LOG_SB16)\n }\n\n port2xE_write(_value: number): void {\n dbg_log('22E write: dsp read buffer status (read only)', LOG_SB16)\n }\n\n port2xF_write(_value: number): void {\n dbg_log('22F write: undocumented', LOG_SB16)\n }\n\n // MPU UART Mode - Data Port\n port3x0_read(): number {\n dbg_log('330 read: mpu data', LOG_SB16)\n\n if (this.mpu_read_buffer.length) {\n this.mpu_read_buffer_lastvalue = this.mpu_read_buffer.shift()\n }\n dbg_log(' <- ' + h(this.mpu_read_buffer_lastvalue), LOG_SB16)\n\n return this.mpu_read_buffer_lastvalue\n }\n port3x0_write(value: number): void {\n dbg_log('330 write: mpu data (unimplemented) : ' + h(value), LOG_SB16)\n }\n\n // MPU UART Mode - Status Port\n port3x1_read(): number {\n dbg_log('331 read: mpu status', LOG_SB16)\n\n let status = 0\n status |= 0x40 * 0 // Output Ready\n status |= 0x80 * +!this.mpu_read_buffer.length // Input Ready\n\n return status\n }\n\n // MPU UART Mode - Command Port\n port3x1_write(value: number): void {\n dbg_log('331 write: mpu command: ' + h(value), LOG_SB16)\n if (value === 0xff) {\n // Command acknowledge.\n this.mpu_read_buffer.clear()\n this.mpu_read_buffer.push(0xfe)\n }\n }\n\n //\n // DSP command handlers\n //\n\n command_do(): void {\n let handler = DSP_COMMAND_HANDLERS[this.command]\n if (!handler) {\n handler = this.dsp_default_handler\n }\n handler.call(this)\n\n // Reset Inputs.\n this.command = DSP_NO_COMMAND\n this.command_size = 0\n this.write_buffer.clear()\n }\n\n dsp_default_handler(): void {\n dbg_log('Unhandled command: ' + h(this.command), LOG_SB16)\n }\n\n //\n // Mixer Handlers (CT1745)\n //\n\n mixer_read(address: number): number {\n const handler = MIXER_READ_HANDLERS[address]\n let data: number\n if (handler) {\n data = handler.call(this)\n } else {\n data = this.mixer_registers[address]\n dbg_log(\n 'unhandled mixer register read. addr:' +\n h(address) +\n ' data:' +\n h(data),\n LOG_SB16,\n )\n }\n return data\n }\n\n mixer_write(address: number, data: number): void {\n const handler = MIXER_WRITE_HANDLERS[address]\n if (handler) {\n handler.call(this, data)\n } else {\n dbg_log(\n 'unhandled mixer register write. addr:' +\n h(address) +\n ' data:' +\n h(data),\n LOG_SB16,\n )\n }\n }\n\n mixer_default_read(): number {\n dbg_log(\n 'mixer register read. addr:' + h(this.mixer_current_address),\n LOG_SB16,\n )\n return this.mixer_registers[this.mixer_current_address]\n }\n\n mixer_default_write(data: number): void {\n dbg_log(\n 'mixer register write. addr:' +\n h(this.mixer_current_address) +\n ' data:' +\n h(data),\n LOG_SB16,\n )\n this.mixer_registers[this.mixer_current_address] = data\n }\n\n mixer_reset(): void {\n // Values intentionally in decimal.\n // Default values available at\n // https://pdos.csail.mit.edu/6.828/2011/readings/hardware/SoundBlaster.pdf\n this.mixer_registers[0x04] = (12 << 4) | 12\n this.mixer_registers[0x22] = (12 << 4) | 12\n this.mixer_registers[0x26] = (12 << 4) | 12\n this.mixer_registers[0x28] = 0\n this.mixer_registers[0x2e] = 0\n this.mixer_registers[0x0a] = 0\n this.mixer_registers[0x30] = 24 << 3\n this.mixer_registers[0x31] = 24 << 3\n this.mixer_registers[0x32] = 24 << 3\n this.mixer_registers[0x33] = 24 << 3\n this.mixer_registers[0x34] = 24 << 3\n this.mixer_registers[0x35] = 24 << 3\n this.mixer_registers[0x36] = 0\n this.mixer_registers[0x37] = 0\n this.mixer_registers[0x38] = 0\n this.mixer_registers[0x39] = 0\n this.mixer_registers[0x3b] = 0\n this.mixer_registers[0x3c] = 0x1f\n this.mixer_registers[0x3d] = 0x15\n this.mixer_registers[0x3e] = 0x0b\n this.mixer_registers[0x3f] = 0\n this.mixer_registers[0x40] = 0\n this.mixer_registers[0x41] = 0\n this.mixer_registers[0x42] = 0\n this.mixer_registers[0x43] = 0\n this.mixer_registers[0x44] = 8 << 4\n this.mixer_registers[0x45] = 8 << 4\n this.mixer_registers[0x46] = 8 << 4\n this.mixer_registers[0x47] = 8 << 4\n\n this.mixer_full_update()\n }\n\n mixer_full_update(): void {\n // Start at 1. Don't re-reset.\n for (let i = 1; i < this.mixer_registers.length; i++) {\n if (MIXER_REGISTER_IS_LEGACY[i]) {\n // Legacy registers are actually mapped to other register locations. Update\n // using the new registers rather than the legacy registers.\n continue\n }\n this.mixer_write(i, this.mixer_registers[i])\n }\n }\n\n //\n // FM Handlers\n //\n\n fm_default_write(data: number, register: number, address: number): void {\n dbg_log(\n 'unhandled fm register write. addr:' +\n register +\n '|' +\n h(address) +\n ' data:' +\n h(data),\n LOG_SB16,\n )\n // No need to save into a dummy register as the registers are write-only.\n }\n\n //\n // FM behaviours\n //\n\n fm_update_waveforms(): void {\n // To be implemented.\n }\n\n //\n // General behaviours\n //\n\n sampling_rate_change(rate: number): void {\n this.sampling_rate = rate\n this.bus.send('dac-tell-sampling-rate', rate)\n }\n\n get_channel_count(): number {\n return this.dsp_stereo ? 2 : 1\n }\n\n dma_transfer_size_set(): void {\n this.dma_sample_count =\n 1 +\n (this.write_buffer.shift() << 0) +\n (this.write_buffer.shift() << 8)\n }\n\n dma_transfer_start(): void {\n dbg_log('begin dma transfer', LOG_SB16)\n\n // (1) Setup appropriate settings.\n\n this.bytes_per_sample = 1\n if (this.dsp_16bit) this.bytes_per_sample *= 2\n\n // Don't count stereo interleaved bits apparently.\n // Disabling this line is needed for sounds to work correctly,\n // especially double buffering autoinit mode.\n // Learnt the hard way.\n // if(this.dsp_stereo) this.bytes_per_sample *= 2;\n\n this.dma_bytes_count = this.dma_sample_count * this.bytes_per_sample\n this.dma_bytes_block = SB_DMA_BLOCK_SAMPLES * this.bytes_per_sample\n\n // Ensure block size is small enough but not too small, and is divisible by 4\n const max_bytes_block = Math.max((this.dma_bytes_count >> 2) & ~0x3, 32)\n this.dma_bytes_block = Math.min(max_bytes_block, this.dma_bytes_block)\n\n // (2) Wait until channel is unmasked (if not already)\n this.dma_waiting_transfer = true\n if (!this.dma.channel_mask[this.dma_channel]) {\n this.dma_on_unmask(this.dma_channel)\n }\n }\n\n dma_on_unmask(channel: number): void {\n if (channel !== this.dma_channel || !this.dma_waiting_transfer) {\n return\n }\n\n // (3) Configure amount of bytes left to transfer and tell speaker adapter\n // to start requesting transfers\n this.dma_waiting_transfer = false\n this.dma_bytes_left = this.dma_bytes_count\n this.dma_paused = false\n this.bus.send('dac-enable')\n }\n\n dma_transfer_next(): void {\n dbg_log('dma transfering next block', LOG_SB16)\n\n const size = Math.min(this.dma_bytes_left, this.dma_bytes_block)\n const samples = Math.floor(size / this.bytes_per_sample)\n\n this.dma.do_write(\n this.dma_syncbuffer,\n 0,\n size,\n this.dma_channel,\n (error: boolean) => {\n dbg_log(\n 'dma block transfer ' +\n (error ? 'unsuccessful' : 'successful'),\n LOG_SB16,\n )\n if (error) return\n\n this.dma_to_dac(samples)\n this.dma_bytes_left -= size\n\n if (!this.dma_bytes_left) {\n // Completed requested transfer of given size.\n this.raise_irq(this.dma_irq)\n\n if (this.dma_autoinit) {\n // Restart the transfer.\n this.dma_bytes_left = this.dma_bytes_count\n }\n }\n },\n )\n }\n\n dma_to_dac(sample_count: number): void {\n const amplitude = this.dsp_16bit ? 32767.5 : 127.5\n const offset = this.dsp_signed ? 0 : -1\n const repeats = this.dsp_stereo ? 1 : 2\n\n let buffer: Int8Array | Uint8Array | Int16Array | Uint16Array\n if (this.dsp_16bit) {\n buffer = this.dsp_signed\n ? this.dma_buffer_int16\n : this.dma_buffer_uint16\n } else {\n buffer = this.dsp_signed\n ? this.dma_buffer_int8\n : this.dma_buffer_uint8\n }\n\n let channel = 0\n for (let i = 0; i < sample_count; i++) {\n const sample = audio_normalize(buffer[i], amplitude, offset)\n for (let j = 0; j < repeats; j++) {\n this.dac_buffers[channel].push(sample)\n channel ^= 1\n }\n }\n\n this.dac_send()\n }\n\n dac_handle_request(): void {\n if (!this.dma_bytes_left || this.dma_paused) {\n // No more data to transfer or is paused. Send whatever is in the buffers.\n this.dac_send()\n } else {\n this.dma_transfer_next()\n }\n }\n\n dac_send(): void {\n if (!this.dac_buffers[0].length) {\n return\n }\n\n const out0 = this.dac_buffers[0].shift_block(this.dac_buffers[0].length)\n const out1 = this.dac_buffers[1].shift_block(this.dac_buffers[1].length)\n this.bus.send('dac-send-data', [out0, out1], [out0.buffer, out1.buffer])\n }\n\n raise_irq(type?: number): void {\n dbg_log('raise irq', LOG_SB16)\n if (type !== undefined) {\n this.irq_triggered[type] = 1\n }\n this.cpu.device_raise_irq(this.irq)\n }\n\n lower_irq(type: number): void {\n dbg_log('lower irq', LOG_SB16)\n this.irq_triggered[type] = 0\n this.cpu.device_lower_irq(this.irq)\n }\n}\n\n//\n// DSP command registration\n//\n\nfunction register_dsp_command(\n commands: number[],\n size: number,\n handler?: (this: SB16) => void,\n): void {\n if (!handler) {\n handler = SB16.prototype.dsp_default_handler\n }\n for (let i = 0; i < commands.length; i++) {\n DSP_COMMAND_SIZES[commands[i]] = size\n DSP_COMMAND_HANDLERS[commands[i]] = handler\n }\n}\n\nfunction any_first_digit(base: number): number[] {\n const commands: number[] = []\n for (let i = 0; i < 16; i++) {\n commands.push(base + i)\n }\n return commands\n}\n\n// ASP set register\nregister_dsp_command([0x0e], 2, function () {\n this.asp_registers[this.write_buffer.shift()] = this.write_buffer.shift()\n})\n\n// ASP get register\nregister_dsp_command([0x0f], 1, function () {\n this.read_buffer.clear()\n this.read_buffer.push(this.asp_registers[this.write_buffer.shift()])\n})\n\n// 8-bit direct mode single byte digitized sound output.\nregister_dsp_command([0x10], 1, function () {\n const value = audio_normalize(this.write_buffer.shift(), 127.5, -1)\n\n this.dac_buffers[0].push(value)\n this.dac_buffers[1].push(value)\n this.bus.send('dac-enable')\n})\n\n// 8-bit single-cycle DMA mode digitized sound output.\nregister_dsp_command([0x14, 0x15], 2, function () {\n this.dma_irq = SB_IRQ_8BIT\n this.dma_channel = this.dma_channel_8bit\n this.dma_autoinit = false\n this.dsp_signed = false\n this.dsp_16bit = false\n this.dsp_highspeed = false\n this.dma_transfer_size_set()\n this.dma_transfer_start()\n})\n\n// Creative 8-bit to 2-bit ADPCM single-cycle DMA mode digitized sound output.\nregister_dsp_command([0x16], 2)\n\n// Creative 8-bit to 2-bit ADPCM single-cycle DMA mode digitzed sound output\n// with reference byte.\nregister_dsp_command([0x17], 2)\n\n// 8-bit auto-init DMA mode digitized sound output.\nregister_dsp_command([0x1c], 0, function () {\n this.dma_irq = SB_IRQ_8BIT\n this.dma_channel = this.dma_channel_8bit\n this.dma_autoinit = true\n this.dsp_signed = false\n this.dsp_16bit = false\n this.dsp_highspeed = false\n this.dma_transfer_start()\n})\n\n// Creative 8-bit to 2-bit ADPCM auto-init DMA mode digitized sound output\n// with reference byte.\nregister_dsp_command([0x1f], 0)\n\n// 8-bit direct mode single byte digitized sound input.\nregister_dsp_command([0x20], 0, function () {\n // Fake silent input.\n this.read_buffer.clear()\n this.read_buffer.push(0x7f)\n})\n\n// 8-bit single-cycle DMA mode digitized sound input.\nregister_dsp_command([0x24], 2)\n\n// 8-bit auto-init DMA mode digitized sound input.\nregister_dsp_command([0x2c], 0)\n\n// Polling mode MIDI input.\nregister_dsp_command([0x30], 0)\n\n// Interrupt mode MIDI input.\nregister_dsp_command([0x31], 0)\n\n// UART polling mode MIDI I/O.\nregister_dsp_command([0x34], 0)\n\n// UART interrupt mode MIDI I/O.\nregister_dsp_command([0x35], 0)\n\n// UART polling mode MIDI I/O with time stamping.\nregister_dsp_command([0x36], 0)\n\n// UART interrupt mode MIDI I/O with time stamping.\nregister_dsp_command([0x37], 0)\n\n// MIDI output.\nregister_dsp_command([0x38], 0)\n\n// Set digitized sound transfer Time Constant.\nregister_dsp_command([0x40], 1, function () {\n // Note: bTimeConstant = 256 * time constant\n this.sampling_rate_change(\n 1000000 / (256 - this.write_buffer.shift()) / this.get_channel_count(),\n )\n})\n\n// Set digitized sound output sampling rate.\n// Set digitized sound input sampling rate.\nregister_dsp_command([0x41, 0x42], 2, function () {\n this.sampling_rate_change(\n (this.write_buffer.shift() << 8) | this.write_buffer.shift(),\n )\n})\n\n// Set DSP block transfer size.\nregister_dsp_command([0x48], 2, function () {\n // TODO: should be in bytes, but if this is only used\n // for 8 bit transfers, then this number is the same\n // as number of samples?\n // Wrong: e.g. stereo requires two bytes per sample.\n this.dma_transfer_size_set()\n})\n\n// Creative 8-bit to 4-bit ADPCM single-cycle DMA mode digitized sound output.\nregister_dsp_command([0x74], 2)\n\n// Creative 8-bit to 4-bit ADPCM single-cycle DMA mode digitized sound output\n// with referene byte.\nregister_dsp_command([0x75], 2)\n\n// Creative 8-bit to 3-bit ADPCM single-cycle DMA mode digitized sound output.\nregister_dsp_command([0x76], 2)\n\n// Creative 8-bit to 3-bit ADPCM single-cycle DMA mode digitized sound output\n// with referene byte.\nregister_dsp_command([0x77], 2)\n\n// Creative 8-bit to 4-bit ADPCM auto-init DMA mode digitized sound output\n// with reference byte.\nregister_dsp_command([0x7d], 0)\n\n// Creative 8-bit to 3-bit ADPCM auto-init DMA mode digitized sound output\n// with reference byte.\nregister_dsp_command([0x7f], 0)\n\n// Pause DAC for a duration.\nregister_dsp_command([0x80], 2)\n\n// 8-bit high-speed auto-init DMA mode digitized sound output.\nregister_dsp_command([0x90], 0, function () {\n this.dma_irq = SB_IRQ_8BIT\n this.dma_channel = this.dma_channel_8bit\n this.dma_autoinit = true\n this.dsp_signed = false\n this.dsp_highspeed = true\n this.dsp_16bit = false\n this.dma_transfer_start()\n})\n\n// 8-bit high-speed single-cycle DMA mode digitized sound input.\nregister_dsp_command([0x91], 0)\n\n// 8-bit high-speed auto-init DMA mode digitized sound input.\nregister_dsp_command([0x98], 0)\n\n// 8-bit high-speed single-cycle DMA mode digitized sound input.\nregister_dsp_command([0x99], 0)\n\n// Set input mode to mono.\nregister_dsp_command([0xa0], 0)\n\n// Set input mode to stereo.\nregister_dsp_command([0xa8], 0)\n\n// Program 16-bit DMA mode digitized sound I/O.\nregister_dsp_command(any_first_digit(0xb0), 3, function () {\n if (this.command & (1 << 3)) {\n // Analogue to digital not implemented.\n this.dsp_default_handler()\n return\n }\n const mode = this.write_buffer.shift()\n this.dma_irq = SB_IRQ_16BIT\n this.dma_channel = this.dma_channel_16bit\n this.dma_autoinit = !!(this.command & (1 << 2))\n this.dsp_signed = !!(mode & (1 << 4))\n this.dsp_stereo = !!(mode & (1 << 5))\n this.dsp_16bit = true\n this.dma_transfer_size_set()\n this.dma_transfer_start()\n})\n\n// Program 8-bit DMA mode digitized sound I/O.\nregister_dsp_command(any_first_digit(0xc0), 3, function () {\n if (this.command & (1 << 3)) {\n // Analogue to digital not implemented.\n this.dsp_default_handler()\n return\n }\n const mode = this.write_buffer.shift()\n this.dma_irq = SB_IRQ_8BIT\n this.dma_channel = this.dma_channel_8bit\n this.dma_autoinit = !!(this.command & (1 << 2))\n this.dsp_signed = !!(mode & (1 << 4))\n this.dsp_stereo = !!(mode & (1 << 5))\n this.dsp_16bit = false\n this.dma_transfer_size_set()\n this.dma_transfer_start()\n})\n\n// Pause 8-bit DMA mode digitized sound I/O.\nregister_dsp_command([0xd0], 0, function () {\n this.dma_paused = true\n this.bus.send('dac-disable')\n})\n\n// Turn on speaker.\n// Documented to have no effect on SB16.\nregister_dsp_command([0xd1], 0, function () {\n this.dummy_speaker_enabled = true\n})\n\n// Turn off speaker.\n// Documented to have no effect on SB16.\nregister_dsp_command([0xd3], 0, function () {\n this.dummy_speaker_enabled = false\n})\n\n// Continue 8-bit DMA mode digitized sound I/O.\nregister_dsp_command([0xd4], 0, function () {\n this.dma_paused = false\n this.bus.send('dac-enable')\n})\n\n// Pause 16-bit DMA mode digitized sound I/O.\nregister_dsp_command([0xd5], 0, function () {\n this.dma_paused = true\n this.bus.send('dac-disable')\n})\n\n// Continue 16-bit DMA mode digitized sound I/O.\nregister_dsp_command([0xd6], 0, function () {\n this.dma_paused = false\n this.bus.send('dac-enable')\n})\n\n// Get speaker status.\nregister_dsp_command([0xd8], 0, function () {\n this.read_buffer.clear()\n this.read_buffer.push(+this.dummy_speaker_enabled * 0xff)\n})\n\n// Exit 16-bit auto-init DMA mode digitized sound I/O.\n// Exit 8-bit auto-init mode digitized sound I/O.\nregister_dsp_command([0xd9, 0xda], 0, function () {\n this.dma_autoinit = false\n})\n\n// DSP identification\nregister_dsp_command([0xe0], 1, function () {\n this.read_buffer.clear()\n this.read_buffer.push(~this.write_buffer.shift())\n})\n\n// Get DSP version number.\nregister_dsp_command([0xe1], 0, function () {\n this.read_buffer.clear()\n this.read_buffer.push(4)\n this.read_buffer.push(5)\n})\n\n// DMA identification.\nregister_dsp_command([0xe2], 1)\n\n// Get DSP copyright.\nregister_dsp_command([0xe3], 0, function () {\n this.read_buffer.clear()\n for (let i = 0; i < DSP_COPYRIGHT.length; i++) {\n this.read_buffer.push(DSP_COPYRIGHT.charCodeAt(i))\n }\n // Null terminator.\n this.read_buffer.push(0)\n})\n\n// Write test register.\nregister_dsp_command([0xe4], 1, function () {\n this.test_register = this.write_buffer.shift()\n})\n\n// Read test register.\nregister_dsp_command([0xe8], 0, function () {\n this.read_buffer.clear()\n this.read_buffer.push(this.test_register)\n})\n\n// Trigger IRQ\nregister_dsp_command([0xf2, 0xf3], 0, function () {\n this.raise_irq()\n})\n\n// ASP - unknown function\nconst SB_F9 = new Uint8Array(256)\nSB_F9[0x0e] = 0xff\nSB_F9[0x0f] = 0x07\nSB_F9[0x37] = 0x38\nregister_dsp_command([0xf9], 1, function () {\n const input = this.write_buffer.shift()\n dbg_log('dsp 0xf9: unknown function. input: ' + input, LOG_SB16)\n\n this.read_buffer.clear()\n this.read_buffer.push(SB_F9[input])\n})\n\n//\n// Mixer registration\n//\n\nfunction register_mixer_read(\n address: number,\n handler?: (this: SB16) => number,\n): void {\n if (!handler) {\n handler = SB16.prototype.mixer_default_read\n }\n MIXER_READ_HANDLERS[address] = handler\n}\n\nfunction register_mixer_write(\n address: number,\n handler?: (this: SB16, data: number) => void,\n): void {\n if (!handler) {\n handler = SB16.prototype.mixer_default_write\n }\n MIXER_WRITE_HANDLERS[address] = handler\n}\n\n// Legacy registers map each nibble to the last 4 bits of the new registers\nfunction register_mixer_legacy(\n address_old: number,\n address_new_left: number,\n address_new_right: number,\n): void {\n MIXER_REGISTER_IS_LEGACY[address_old] = 1\n\n MIXER_READ_HANDLERS[address_old] = function (this: SB16): number {\n const left = this.mixer_registers[address_new_left] & 0xf0\n const right = this.mixer_registers[address_new_right] >>> 4\n return left | right\n }\n\n MIXER_WRITE_HANDLERS[address_old] = function (\n this: SB16,\n data: number,\n ): void {\n this.mixer_registers[address_old] = data\n const prev_left = this.mixer_registers[address_new_left]\n const prev_right = this.mixer_registers[address_new_right]\n const left = (data & 0xf0) | (prev_left & 0x0f)\n const right = ((data << 4) & 0xf0) | (prev_right & 0x0f)\n\n this.mixer_write(address_new_left, left)\n this.mixer_write(address_new_right, right)\n }\n}\n\nfunction register_mixer_volume(\n address: number,\n mixer_source: number,\n channel: number,\n): void {\n MIXER_READ_HANDLERS[address] = SB16.prototype.mixer_default_read\n\n MIXER_WRITE_HANDLERS[address] = function (this: SB16, data: number): void {\n this.mixer_registers[address] = data\n this.bus.send('mixer-volume', [\n mixer_source,\n channel,\n (data >>> 2) - 62,\n ])\n }\n}\n\n// Reset.\nregister_mixer_read(0x00, function () {\n this.mixer_reset()\n return 0\n})\nregister_mixer_write(0x00)\n\n// Legacy Voice Volume Left/Right.\nregister_mixer_legacy(0x04, 0x32, 0x33)\n\n// Legacy Mic Volume. TODO.\n//register_mixer_read(0x0A);\n//register_mixer_write(0x0A, function(data)\n//{\n// this.mixer_registers[0x0A] = data;\n// var prev = this.mixer_registers[0x3A];\n// this.mixer_write(0x3A, data << 5 | (prev & 0x0F));\n//});\n\n// Legacy Master Volume Left/Right.\nregister_mixer_legacy(0x22, 0x30, 0x31)\n// Legacy Midi Volume Left/Right.\nregister_mixer_legacy(0x26, 0x34, 0x35)\n// Legacy CD Volume Left/Right.\nregister_mixer_legacy(0x28, 0x36, 0x37)\n// Legacy Line Volume Left/Right.\nregister_mixer_legacy(0x2e, 0x38, 0x39)\n\n// Master Volume Left.\nregister_mixer_volume(0x30, MIXER_SRC_MASTER, MIXER_CHANNEL_LEFT)\n// Master Volume Right.\nregister_mixer_volume(0x31, MIXER_SRC_MASTER, MIXER_CHANNEL_RIGHT)\n// Voice Volume Left.\nregister_mixer_volume(0x32, MIXER_SRC_DAC, MIXER_CHANNEL_LEFT)\n// Voice Volume Right.\nregister_mixer_volume(0x33, MIXER_SRC_DAC, MIXER_CHANNEL_RIGHT)\n// MIDI Volume Left. TODO.\n//register_mixer_volume(0x34, MIXER_SRC_SYNTH, MIXER_CHANNEL_LEFT);\n// MIDI Volume Right. TODO.\n//register_mixer_volume(0x35, MIXER_SRC_SYNTH, MIXER_CHANNEL_RIGHT);\n// CD Volume Left. TODO.\n//register_mixer_volume(0x36, MIXER_SRC_CD, MIXER_CHANNEL_LEFT);\n// CD Volume Right. TODO.\n//register_mixer_volume(0x37, MIXER_SRC_CD, MIXER_CHANNEL_RIGHT);\n// Line Volume Left. TODO.\n//register_mixer_volume(0x38, MIXER_SRC_LINE, MIXER_CHANNEL_LEFT);\n// Line Volume Right. TODO.\n//register_mixer_volume(0x39, MIXER_SRC_LINE, MIXER_CHANNEL_RIGHT);\n// Mic Volume. TODO.\n//register_mixer_volume(0x3A, MIXER_SRC_MIC, MIXER_CHANNEL_BOTH);\n\n// PC Speaker Volume.\nregister_mixer_read(0x3b)\nregister_mixer_write(0x3b, function (data) {\n this.mixer_registers[0x3b] = data\n this.bus.send('mixer-volume', [\n MIXER_SRC_PCSPEAKER,\n MIXER_CHANNEL_BOTH,\n (data >>> 6) * 6 - 18,\n ])\n})\n\n// Output Mixer Switches. TODO.\n//register_mixer_read(0x3C);\n//register_mixer_write(0x3C, function(data)\n//{\n// this.mixer_registers[0x3C] = data;\n//\n// if(data & 0x01) this.bus.send(\"mixer-connect\", [MIXER_SRC_MIC, MIXER_CHANNEL_BOTH]);\n// else this.bus.send(\"mixer-disconnect\", [MIXER_SRC_MIC, MIXER_CHANNEL_BOTH]);\n//\n// if(data & 0x02) this.bus.send(\"mixer-connect\", [MIXER_SRC_CD, MIXER_CHANNEL_RIGHT]);\n// else this.bus.send(\"mixer-disconnect\", [MIXER_SRC_CD, MIXER_CHANNEL_RIGHT]);\n//\n// if(data & 0x04) this.bus.send(\"mixer-connect\", [MIXER_SRC_CD, MIXER_CHANNEL_LEFT]);\n// else this.bus.send(\"mixer-disconnect\", [MIXER_SRC_CD, MIXER_CHANNEL_LEFT]);\n//\n// if(data & 0x08) this.bus.send(\"mixer-connect\", [MIXER_SRC_LINE, MIXER_CHANNEL_RIGHT]);\n// else this.bus.send(\"mixer-disconnect\", [MIXER_SRC_LINE, MIXER_CHANNEL_RIGHT]);\n//\n// if(data & 0x10) this.bus.send(\"mixer-connect\", [MIXER_SRC_LINE, MIXER_CHANNEL_LEFT]);\n// else this.bus.send(\"mixer-disconnect\", [MIXER_SRC_LINE, MIXER_CHANNEL_LEFT]);\n//});\n\n// Input Mixer Left Switches. TODO.\n//register_mixer_read(0x3D);\n//register_mixer_write(0x3D);\n\n// Input Mixer Right Switches. TODO.\n//register_mixer_read(0x3E);\n//register_mixer_write(0x3E);\n\n// Input Gain Left. TODO.\n//register_mixer_read(0x3F);\n//register_mixer_write(0x3F);\n\n// Input Gain Right. TODO.\n//register_mixer_read(0x40);\n//register_mixer_write(0x40);\n\n// Output Gain Left.\nregister_mixer_read(0x41)\nregister_mixer_write(0x41, function (data) {\n this.mixer_registers[0x41] = data\n this.bus.send('mixer-gain-left', (data >>> 6) * 6)\n})\n\n// Output Gain Right.\nregister_mixer_read(0x42)\nregister_mixer_write(0x42, function (data) {\n this.mixer_registers[0x42] = data\n this.bus.send('mixer-gain-right', (data >>> 6) * 6)\n})\n\n// Mic AGC. TODO.\n//register_mixer_read(0x43);\n//register_mixer_write(0x43);\n\n// Treble Left.\nregister_mixer_read(0x44)\nregister_mixer_write(0x44, function (data) {\n this.mixer_registers[0x44] = data\n data >>>= 3\n this.bus.send('mixer-treble-left', data - (data < 16 ? 14 : 16))\n})\n\n// Treble Right.\nregister_mixer_read(0x45)\nregister_mixer_write(0x45, function (data) {\n this.mixer_registers[0x45] = data\n data >>>= 3\n this.bus.send('mixer-treble-right', data - (data < 16 ? 14 : 16))\n})\n\n// Bass Left.\nregister_mixer_read(0x46)\nregister_mixer_write(0x46, function (data) {\n this.mixer_registers[0x46] = data\n data >>>= 3\n this.bus.send('mixer-bass-right', data - (data < 16 ? 14 : 16))\n})\n\n// Bass Right.\nregister_mixer_read(0x47)\nregister_mixer_write(0x47, function (data) {\n this.mixer_registers[0x47] = data\n data >>>= 3\n this.bus.send('mixer-bass-right', data - (data < 16 ? 14 : 16))\n})\n\n// IRQ Select.\nregister_mixer_read(0x80, function () {\n switch (this.irq) {\n case SB_IRQ2:\n return 0x1\n case SB_IRQ5:\n return 0x2\n case SB_IRQ7:\n return 0x4\n case SB_IRQ10:\n return 0x8\n default:\n return 0x0\n }\n})\nregister_mixer_write(0x80, function (bits) {\n if (bits & 0x1) this.irq = SB_IRQ2\n if (bits & 0x2) this.irq = SB_IRQ5\n if (bits & 0x4) this.irq = SB_IRQ7\n if (bits & 0x8) this.irq = SB_IRQ10\n})\n\n// DMA Select.\nregister_mixer_read(0x81, function () {\n let ret = 0\n switch (this.dma_channel_8bit) {\n case SB_DMA0:\n ret |= 0x1\n break\n case SB_DMA1:\n ret |= 0x2\n break\n // Channel 2 is hardwired to floppy disk.\n case SB_DMA3:\n ret |= 0x8\n break\n }\n switch (this.dma_channel_16bit) {\n // Channel 4 cannot be used.\n case SB_DMA5:\n ret |= 0x20\n break\n case SB_DMA6:\n ret |= 0x40\n break\n case SB_DMA7:\n ret |= 0x80\n break\n }\n return ret\n})\nregister_mixer_write(0x81, function (bits) {\n if (bits & 0x1) this.dma_channel_8bit = SB_DMA0\n if (bits & 0x2) this.dma_channel_8bit = SB_DMA1\n if (bits & 0x8) this.dma_channel_8bit = SB_DMA3\n if (bits & 0x20) this.dma_channel_16bit = SB_DMA5\n if (bits & 0x40) this.dma_channel_16bit = SB_DMA6\n if (bits & 0x80) this.dma_channel_16bit = SB_DMA7\n})\n\n// IRQ Status.\nregister_mixer_read(0x82, function () {\n let ret = 0x20\n for (let i = 0; i < 16; i++) {\n ret |= i * this.irq_triggered[i]\n }\n return ret\n})\n\n//\n// FM registration\n//\n\nfunction register_fm_write(\n addresses: number[],\n handler?: (\n this: SB16,\n data: number,\n register: number,\n address: number,\n ) => void,\n): void {\n if (!handler) {\n handler = SB16.prototype.fm_default_write\n }\n for (let i = 0; i < addresses.length; i++) {\n FM_HANDLERS[addresses[i]] = handler\n }\n}\n\nfunction between(start: number, end: number): number[] {\n const a: number[] = []\n for (let i = start; i <= end; i++) {\n a.push(i)\n }\n return a\n}\n\nconst SB_FM_OPERATORS_BY_OFFSET = new Uint8Array(32)\nSB_FM_OPERATORS_BY_OFFSET[0x00] = 0\nSB_FM_OPERATORS_BY_OFFSET[0x01] = 1\nSB_FM_OPERATORS_BY_OFFSET[0x02] = 2\nSB_FM_OPERATORS_BY_OFFSET[0x03] = 3\nSB_FM_OPERATORS_BY_OFFSET[0x04] = 4\nSB_FM_OPERATORS_BY_OFFSET[0x05] = 5\nSB_FM_OPERATORS_BY_OFFSET[0x08] = 6\nSB_FM_OPERATORS_BY_OFFSET[0x09] = 7\nSB_FM_OPERATORS_BY_OFFSET[0x0a] = 8\nSB_FM_OPERATORS_BY_OFFSET[0x0b] = 9\nSB_FM_OPERATORS_BY_OFFSET[0x0c] = 10\nSB_FM_OPERATORS_BY_OFFSET[0x0d] = 11\nSB_FM_OPERATORS_BY_OFFSET[0x10] = 12\nSB_FM_OPERATORS_BY_OFFSET[0x11] = 13\nSB_FM_OPERATORS_BY_OFFSET[0x12] = 14\nSB_FM_OPERATORS_BY_OFFSET[0x13] = 15\nSB_FM_OPERATORS_BY_OFFSET[0x14] = 16\nSB_FM_OPERATORS_BY_OFFSET[0x15] = 17\n\nfunction get_fm_operator(register: number, offset: number): number {\n return register * 18 + SB_FM_OPERATORS_BY_OFFSET[offset]\n}\n\nregister_fm_write([0x01], function (_bits, register, _address) {\n this.fm_waveform_select_enable[register] = _bits & 1\n this.fm_update_waveforms()\n})\n\n// Timer 1 Count.\nregister_fm_write([0x02])\n\n// Timer 2 Count.\nregister_fm_write([0x03])\n\nregister_fm_write([0x04], function (_bits, register, _address) {\n switch (register) {\n case 0:\n // if(bits & 0x80)\n // {\n // // IQR Reset\n // }\n // else\n // {\n // // Timer masks and on/off\n // }\n break\n case 1:\n // Four-operator enable\n break\n }\n})\n\nregister_fm_write([0x05], function (bits, register, address) {\n if (register === 0) {\n // No registers documented here.\n this.fm_default_write(bits, register, address)\n } else {\n // OPL3 Mode Enable\n }\n})\n\nregister_fm_write([0x08], function (_bits, _register, _address) {\n // Composite sine wave on/off\n // Note select (keyboard split selection method)\n})\n\nregister_fm_write(between(0x20, 0x35), function (_bits, register, address) {\n const _operator = get_fm_operator(register, address - 0x20)\n // Tremolo\n // Vibrato\n // Sustain\n // KSR Envelope Scaling\n // Frequency Multiplication Factor\n})\n\nregister_fm_write(between(0x40, 0x55), function (_bits, register, address) {\n const _operator = get_fm_operator(register, address - 0x40)\n // Key Scale Level\n // Output Level\n})\n\nregister_fm_write(between(0x60, 0x75), function (_bits, register, address) {\n const _operator = get_fm_operator(register, address - 0x60)\n // Attack Rate\n // Decay Rate\n})\n\nregister_fm_write(between(0x80, 0x95), function (_bits, register, address) {\n const _operator = get_fm_operator(register, address - 0x80)\n // Sustain Level\n // Release Rate\n})\n\nregister_fm_write(between(0xa0, 0xa8), function (_bits, _register, address) {\n const _channel = address - 0xa0\n // Frequency Number (Lower 8 bits)\n})\n\nregister_fm_write(between(0xb0, 0xb8), function (_bits, _register, _address) {\n // Key-On\n // Block Number\n // Frequency Number (Higher 2 bits)\n})\n\nregister_fm_write([0xbd], function (_bits, _register, _address) {\n // Tremelo Depth\n // Vibrato Depth\n // Percussion Mode\n // Bass Drum Key-On\n // Snare Drum Key-On\n // Tom-Tom Key-On\n // Cymbal Key-On\n // Hi-Hat Key-On\n})\n\nregister_fm_write(between(0xc0, 0xc8), function (_bits, _register, _address) {\n // Right Speaker Enable\n // Left Speaker Enable\n // Feedback Modulation Factor\n // Synthesis Type\n})\n\nregister_fm_write(between(0xe0, 0xf5), function (_bits, register, address) {\n const _operator = get_fm_operator(register, address - 0xe0)\n // Waveform Select\n})\n\n//\n// Helpers\n//\n\nfunction audio_normalize(\n value: number,\n amplitude: number,\n offset: number,\n): number {\n return audio_clip(value / amplitude + offset, -1, 1)\n}\n\nfunction audio_clip(value: number, low: number, high: number): number {\n return (\n +(value < low) * low +\n +(value > high) * high +\n +(low <= value && value <= high) * value\n )\n}\n", "// http://www.uefi.org/sites/default/files/resources/ACPI_6_1.pdf\n\nimport { v86 } from './main.js'\nimport { LOG_ACPI } from '../src/const.js'\nimport { h } from './lib.js'\nimport { dbg_log, dbg_assert } from './log.js'\nimport { IO } from './io.js'\n\n// Minimal interface for the CPU fields ACPI needs\ninterface ACPICpu {\n io: IO\n devices: {\n pci: {\n register_device(device: any): void\n }\n }\n device_raise_irq(irq: number): void\n device_lower_irq(irq: number): void\n}\n\nconst PMTIMER_FREQ_SECONDS = 3579545\n\nexport class ACPI {\n name: string\n cpu: ACPICpu\n timer_last_value: number\n timer_imprecision_offset: number\n status: number\n pm1_status: number\n pm1_enable: number\n last_timer: number\n gpe: Uint8Array\n\n constructor(cpu: ACPICpu) {\n this.name = 'acpi'\n this.cpu = cpu\n\n const io = cpu.io\n\n const acpi = {\n pci_id: 0x07 << 3,\n pci_space: [\n 0x86, 0x80, 0x13, 0x71, 0x07, 0x00, 0x80, 0x02, 0x08, 0x00,\n 0x80, 0x06, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x09, 0x01, 0x00, 0x00,\n ],\n pci_bars: [],\n name: 'acpi',\n }\n\n // 00:07.0 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08)\n cpu.devices.pci.register_device(acpi)\n\n this.timer_last_value = 0\n this.timer_imprecision_offset = 0\n\n this.status = 1\n this.pm1_status = 0\n this.pm1_enable = 0\n this.last_timer = this.get_timer(v86.microtick())\n\n this.gpe = new Uint8Array(4)\n\n io.register_read(\n 0xb000,\n this,\n undefined,\n function (this: ACPI): number {\n dbg_log('ACPI pm1_status read', LOG_ACPI)\n return this.pm1_status\n },\n )\n io.register_write(\n 0xb000,\n this,\n undefined,\n function (this: ACPI, value: number): void {\n dbg_log('ACPI pm1_status write: ' + h(value, 4), LOG_ACPI)\n this.pm1_status &= ~value\n },\n )\n\n io.register_read(\n 0xb002,\n this,\n undefined,\n function (this: ACPI): number {\n dbg_log('ACPI pm1_enable read', LOG_ACPI)\n return this.pm1_enable\n },\n )\n io.register_write(\n 0xb002,\n this,\n undefined,\n function (this: ACPI, value: number): void {\n dbg_log('ACPI pm1_enable write: ' + h(value), LOG_ACPI)\n this.pm1_enable = value\n },\n )\n\n // ACPI status\n io.register_read(\n 0xb004,\n this,\n function (this: ACPI): number {\n dbg_log('ACPI status read8', LOG_ACPI)\n return this.status & 0xff\n },\n function (this: ACPI): number {\n dbg_log('ACPI status read', LOG_ACPI)\n return this.status\n },\n )\n io.register_write(\n 0xb004,\n this,\n undefined,\n function (this: ACPI, value: number): void {\n dbg_log('ACPI status write: ' + h(value), LOG_ACPI)\n this.status = value\n },\n )\n\n // ACPI, pmtimer\n io.register_read(\n 0xb008,\n this,\n undefined,\n undefined,\n function (this: ACPI): number {\n const value = this.get_timer(v86.microtick()) & 0xffffff\n //dbg_log(\"pmtimer read: \" + h(value >>> 0), LOG_ACPI);\n return value\n },\n )\n\n // ACPI, gpe\n io.register_read(0xafe0, this, function (this: ACPI): number {\n dbg_log('Read gpe#0', LOG_ACPI)\n return this.gpe[0]\n })\n io.register_read(0xafe1, this, function (this: ACPI): number {\n dbg_log('Read gpe#1', LOG_ACPI)\n return this.gpe[1]\n })\n io.register_read(0xafe2, this, function (this: ACPI): number {\n dbg_log('Read gpe#2', LOG_ACPI)\n return this.gpe[2]\n })\n io.register_read(0xafe3, this, function (this: ACPI): number {\n dbg_log('Read gpe#3', LOG_ACPI)\n return this.gpe[3]\n })\n\n io.register_write(\n 0xafe0,\n this,\n function (this: ACPI, value: number): void {\n dbg_log('Write gpe#0: ' + h(value), LOG_ACPI)\n this.gpe[0] = value\n },\n )\n io.register_write(\n 0xafe1,\n this,\n function (this: ACPI, value: number): void {\n dbg_log('Write gpe#1: ' + h(value), LOG_ACPI)\n this.gpe[1] = value\n },\n )\n io.register_write(\n 0xafe2,\n this,\n function (this: ACPI, value: number): void {\n dbg_log('Write gpe#2: ' + h(value), LOG_ACPI)\n this.gpe[2] = value\n },\n )\n io.register_write(\n 0xafe3,\n this,\n function (this: ACPI, value: number): void {\n dbg_log('Write gpe#3: ' + h(value), LOG_ACPI)\n this.gpe[3] = value\n },\n )\n }\n\n timer(now: number): number {\n const timer = this.get_timer(now)\n const highest_bit_changed =\n ((timer ^ this.last_timer) & (1 << 23)) !== 0\n\n if (this.pm1_enable & 1 && highest_bit_changed) {\n dbg_log('ACPI raise irq', LOG_ACPI)\n this.pm1_status |= 1\n this.cpu.device_raise_irq(9)\n } else {\n this.cpu.device_lower_irq(9)\n }\n\n this.last_timer = timer\n return 100 // TODO\n }\n\n get_timer(now: number): number {\n const t = Math.round(now * (PMTIMER_FREQ_SECONDS / 1000))\n\n // Due to the low precision of JavaScript's time functions we increment the\n // returned timer value every time it is read\n\n if (t === this.timer_last_value) {\n // don't go past 1ms\n\n if (this.timer_imprecision_offset < PMTIMER_FREQ_SECONDS / 1000) {\n this.timer_imprecision_offset++\n }\n } else {\n dbg_assert(t > this.timer_last_value)\n\n const previous_timer =\n this.timer_last_value + this.timer_imprecision_offset\n\n // don't go back in time\n\n if (previous_timer <= t) {\n this.timer_imprecision_offset = 0\n this.timer_last_value = t\n } else {\n dbg_log(\n 'Warning: Overshot pmtimer, waiting;' +\n ' current=' +\n t +\n ' last=' +\n this.timer_last_value +\n ' offset=' +\n this.timer_imprecision_offset,\n LOG_ACPI,\n )\n }\n }\n\n return this.timer_last_value + this.timer_imprecision_offset\n }\n\n get_state(): [number, number, number, Uint8Array] {\n const state: [number, number, number, Uint8Array] = [\n this.status,\n this.pm1_status,\n this.pm1_enable,\n this.gpe,\n ]\n return state\n }\n\n set_state(state: [number, number, number, Uint8Array]): void {\n this.status = state[0]\n this.pm1_status = state[1]\n this.pm1_enable = state[2]\n this.gpe = state[3]\n }\n}\n", "import { v86 } from './main.js'\nimport { LOG_PIT } from './const.js'\nimport { h } from './lib.js'\nimport { dbg_log } from './log.js'\nimport { IO } from './io.js'\nimport { BusConnector } from './bus.js'\n\n// In kHz\nexport const OSCILLATOR_FREQ = 1193.1816666 // 1.193182 MHz\n\ninterface PITCpu {\n io: IO\n device_raise_irq(irq: number): void\n device_lower_irq(irq: number): void\n}\n\ntype PITState = [\n Uint8Array,\n Uint8Array,\n Uint8Array,\n Uint8Array,\n Uint8Array,\n Uint16Array,\n Uint16Array,\n Float64Array,\n Uint16Array,\n]\n\n/**\n * PIT is the Programmable Interval Timer.\n */\nexport class PIT {\n name: string\n cpu: PITCpu\n bus: BusConnector\n\n counter_start_time: Float64Array\n counter_start_value: Uint16Array\n\n counter_next_low: Uint8Array\n counter_enabled: Uint8Array\n counter_mode: Uint8Array\n counter_read_mode: Uint8Array\n\n // 2 = latch low, 1 = latch high, 0 = no latch\n counter_latch: Uint8Array\n counter_latch_value: Uint16Array\n\n counter_reload: Uint16Array\n\n constructor(cpu: PITCpu, bus: BusConnector) {\n this.name = 'pit'\n this.cpu = cpu\n this.bus = bus\n\n this.counter_start_time = new Float64Array(3)\n this.counter_start_value = new Uint16Array(3)\n\n this.counter_next_low = new Uint8Array(4)\n this.counter_enabled = new Uint8Array(4)\n this.counter_mode = new Uint8Array(4)\n this.counter_read_mode = new Uint8Array(4)\n\n this.counter_latch = new Uint8Array(4)\n this.counter_latch_value = new Uint16Array(3)\n\n this.counter_reload = new Uint16Array(3)\n\n // TODO:\n // - counter2 can be controlled by an input\n\n cpu.io.register_read(0x61, this, function (this: PIT): number {\n const now = v86.microtick()\n\n const ref_toggle = (now * ((1000 * 1000) / 15000)) & 1\n const counter2_out = this.did_rollover(2, now)\n\n return (ref_toggle << 4) | (counter2_out << 5)\n })\n cpu.io.register_write(\n 0x61,\n this,\n function (this: PIT, data: number): void {\n if (data & 1) {\n this.bus.send('pcspeaker-enable')\n } else {\n this.bus.send('pcspeaker-disable')\n }\n },\n )\n\n cpu.io.register_read(0x40, this, function (this: PIT): number {\n return this.counter_read(0)\n })\n cpu.io.register_read(0x41, this, function (this: PIT): number {\n return this.counter_read(1)\n })\n cpu.io.register_read(0x42, this, function (this: PIT): number {\n return this.counter_read(2)\n })\n\n cpu.io.register_write(\n 0x40,\n this,\n function (this: PIT, data: number): void {\n this.counter_write(0, data)\n },\n )\n cpu.io.register_write(\n 0x41,\n this,\n function (this: PIT, data: number): void {\n this.counter_write(1, data)\n },\n )\n cpu.io.register_write(\n 0x42,\n this,\n function (this: PIT, data: number): void {\n this.counter_write(2, data)\n this.bus.send('pcspeaker-update', [\n this.counter_mode[2],\n this.counter_reload[2],\n ])\n },\n )\n\n cpu.io.register_write(0x43, this, this.port43_write)\n }\n\n get_state(): PITState {\n const state: PITState = [\n this.counter_next_low,\n this.counter_enabled,\n this.counter_mode,\n this.counter_read_mode,\n this.counter_latch,\n this.counter_latch_value,\n this.counter_reload,\n this.counter_start_time,\n this.counter_start_value,\n ]\n\n return state\n }\n\n set_state(state: PITState): void {\n this.counter_next_low = state[0]\n this.counter_enabled = state[1]\n this.counter_mode = state[2]\n this.counter_read_mode = state[3]\n this.counter_latch = state[4]\n this.counter_latch_value = state[5]\n this.counter_reload = state[6]\n this.counter_start_time = state[7]\n this.counter_start_value = state[8]\n }\n\n timer(now: number, no_irq: boolean): number {\n let time_to_next_interrupt = 100\n\n // counter 0 produces interrupts\n if (!no_irq) {\n if (this.counter_enabled[0] && this.did_rollover(0, now)) {\n this.counter_start_value[0] = this.get_counter_value(0, now)\n this.counter_start_time[0] = now\n\n dbg_log(\n 'pit interrupt. new value: ' + this.counter_start_value[0],\n LOG_PIT,\n )\n\n // This isn't strictly correct, but it's necessary since browsers\n // may sleep longer than necessary to trigger the else branch below\n // and clear the irq\n this.cpu.device_lower_irq(0)\n\n this.cpu.device_raise_irq(0)\n const mode = this.counter_mode[0]\n\n if (mode === 0) {\n this.counter_enabled[0] = 0\n }\n } else {\n this.cpu.device_lower_irq(0)\n }\n\n if (this.counter_enabled[0]) {\n const diff = now - this.counter_start_time[0]\n const diff_in_ticks = Math.floor(diff * OSCILLATOR_FREQ)\n const ticks_missing =\n this.counter_start_value[0] - diff_in_ticks // XXX: to simplify\n time_to_next_interrupt = ticks_missing / OSCILLATOR_FREQ\n }\n }\n\n return time_to_next_interrupt\n }\n\n get_counter_value(i: number, now: number): number {\n if (!this.counter_enabled[i]) {\n return 0\n }\n\n const diff = now - this.counter_start_time[i]\n const diff_in_ticks = Math.floor(diff * OSCILLATOR_FREQ)\n\n let value = this.counter_start_value[i] - diff_in_ticks\n\n dbg_log(\n 'diff=' +\n diff +\n ' dticks=' +\n diff_in_ticks +\n ' value=' +\n value +\n ' reload=' +\n this.counter_reload[i],\n LOG_PIT,\n )\n\n const reload = this.counter_reload[i]\n\n if (value >= reload) {\n dbg_log(\n 'Warning: Counter' +\n i +\n ' value ' +\n value +\n ' is larger than reload ' +\n reload,\n LOG_PIT,\n )\n value %= reload\n } else if (value < 0) {\n value = (value % reload) + reload\n }\n\n return value\n }\n\n did_rollover(i: number, now: number): number {\n const diff = now - this.counter_start_time[i]\n\n if (diff < 0) {\n // should only happen after restore_state\n dbg_log(\n 'Warning: PIT timer difference is negative, resetting (timer ' +\n i +\n ')',\n )\n return 1\n }\n const diff_in_ticks = Math.floor(diff * OSCILLATOR_FREQ)\n\n return this.counter_start_value[i] < diff_in_ticks ? 1 : 0\n }\n\n counter_read(i: number): number {\n const latch = this.counter_latch[i]\n\n if (latch) {\n this.counter_latch[i]--\n\n if (latch === 2) {\n return this.counter_latch_value[i] & 0xff\n } else {\n return this.counter_latch_value[i] >> 8\n }\n } else {\n const next_low = this.counter_next_low[i]\n\n if (this.counter_mode[i] === 3) {\n this.counter_next_low[i] ^= 1\n }\n\n const value = this.get_counter_value(i, v86.microtick())\n\n if (next_low) {\n return value & 0xff\n } else {\n return value >> 8\n }\n }\n }\n\n counter_write(i: number, value: number): void {\n if (this.counter_next_low[i]) {\n this.counter_reload[i] = (this.counter_reload[i] & ~0xff) | value\n } else {\n this.counter_reload[i] =\n (this.counter_reload[i] & 0xff) | (value << 8)\n }\n\n if (this.counter_read_mode[i] !== 3 || !this.counter_next_low[i]) {\n if (!this.counter_reload[i]) {\n this.counter_reload[i] = 0xffff\n }\n\n // depends on the mode, should actually\n // happen on the first tick\n this.counter_start_value[i] = this.counter_reload[i]\n\n this.counter_enabled[i] = 1\n\n this.counter_start_time[i] = v86.microtick()\n\n dbg_log(\n 'counter' +\n i +\n ' reload=' +\n h(this.counter_reload[i]) +\n ' tick=' +\n (this.counter_reload[i] || 0x10000) / OSCILLATOR_FREQ +\n 'ms',\n LOG_PIT,\n )\n }\n\n if (this.counter_read_mode[i] === 3) {\n this.counter_next_low[i] ^= 1\n }\n }\n\n port43_write(reg_byte: number): void {\n let mode = (reg_byte >> 1) & 7\n const binary_mode = reg_byte & 1,\n i = (reg_byte >> 6) & 3,\n read_mode = (reg_byte >> 4) & 3\n\n if (i === 1) {\n dbg_log('Unimplemented timer1', LOG_PIT)\n }\n\n if (i === 3) {\n dbg_log('Unimplemented read back', LOG_PIT)\n return\n }\n\n if (read_mode === 0) {\n // latch\n this.counter_latch[i] = 2\n const value = this.get_counter_value(i, v86.microtick())\n dbg_log('latch: ' + value, LOG_PIT)\n this.counter_latch_value[i] = value ? value - 1 : 0\n\n return\n }\n\n if (mode >= 6) {\n // 6 and 7 are aliased to 2 and 3\n mode &= ~4\n }\n\n dbg_log(\n 'Control: mode=' +\n mode +\n ' ctr=' +\n i +\n ' read_mode=' +\n read_mode +\n ' bcd=' +\n binary_mode,\n LOG_PIT,\n )\n\n if (read_mode === 1) {\n // lsb\n this.counter_next_low[i] = 1\n } else if (read_mode === 2) {\n // msb\n this.counter_next_low[i] = 0\n } else {\n // first lsb then msb\n this.counter_next_low[i] = 1\n }\n\n if (i === 0) {\n this.cpu.device_lower_irq(0)\n }\n\n if (mode === 0) {\n // intentionally empty\n } else if (mode === 3 || mode === 2) {\n // what is the difference\n } else {\n dbg_log('Unimplemented counter mode: ' + h(mode), LOG_PIT)\n }\n\n this.counter_mode[i] = mode\n this.counter_read_mode[i] = read_mode\n\n if (i === 2) {\n this.bus.send('pcspeaker-update', [\n this.counter_mode[2],\n this.counter_reload[2],\n ])\n }\n }\n\n dump(): void {\n const reload = this.counter_reload[0]\n const time = (reload || 0x10000) / OSCILLATOR_FREQ\n dbg_log('counter0 ticks every ' + time + 'ms (reload=' + reload + ')')\n }\n}\n", "import { LOG_DMA } from './const.js'\nimport { h } from './lib.js'\nimport { dbg_log } from './log.js'\nimport { IO } from './io.js'\n\ninterface DMACpu {\n io: IO\n mem8: Uint8Array\n write_blob(blob: Uint8Array, offset: number): void\n}\n\ninterface DMABuffer {\n byteLength: number\n get(start: number, len: number, fn: (data: Uint8Array) => void): void\n set(start: number, data: Uint8Array, fn: () => void): void\n}\n\ninterface UnmaskListener {\n fn: (channel: number) => void\n this_value: unknown\n}\n\nexport class DMA {\n name: string\n cpu: DMACpu\n channel_page: Uint8Array\n channel_pagehi: Uint8Array\n channel_addr: Uint16Array\n channel_addr_init: Uint16Array\n channel_count: Uint16Array\n channel_count_init: Uint16Array\n channel_mask: Uint8Array\n channel_mode: Uint8Array\n unmask_listeners: UnmaskListener[]\n lsb_msb_flipflop: number\n\n constructor(cpu: DMACpu) {\n this.name = 'dma'\n this.cpu = cpu\n\n this.channel_page = new Uint8Array(8)\n this.channel_pagehi = new Uint8Array(8)\n this.channel_addr = new Uint16Array(8)\n this.channel_addr_init = new Uint16Array(8)\n this.channel_count = new Uint16Array(8)\n this.channel_count_init = new Uint16Array(8)\n this.channel_mask = new Uint8Array(8)\n this.channel_mode = new Uint8Array(8)\n this.unmask_listeners = []\n\n this.lsb_msb_flipflop = 0\n\n const io = cpu.io\n\n io.register_write(0x00, this, this.port_addr_write.bind(this, 0))\n io.register_write(0x02, this, this.port_addr_write.bind(this, 1))\n io.register_write(0x04, this, this.port_addr_write.bind(this, 2))\n io.register_write(0x06, this, this.port_addr_write.bind(this, 3))\n io.register_write(0x01, this, this.port_count_write.bind(this, 0))\n io.register_write(0x03, this, this.port_count_write.bind(this, 1))\n io.register_write(0x05, this, this.port_count_write.bind(this, 2))\n io.register_write(0x07, this, this.port_count_write.bind(this, 3))\n\n io.register_read(0x00, this, this.port_addr_read.bind(this, 0))\n io.register_read(0x02, this, this.port_addr_read.bind(this, 1))\n io.register_read(0x04, this, this.port_addr_read.bind(this, 2))\n io.register_read(0x06, this, this.port_addr_read.bind(this, 3))\n io.register_read(0x01, this, this.port_count_read.bind(this, 0))\n io.register_read(0x03, this, this.port_count_read.bind(this, 1))\n io.register_read(0x05, this, this.port_count_read.bind(this, 2))\n io.register_read(0x07, this, this.port_count_read.bind(this, 3))\n\n io.register_write(0xc0, this, this.port_addr_write.bind(this, 4))\n io.register_write(0xc4, this, this.port_addr_write.bind(this, 5))\n io.register_write(0xc8, this, this.port_addr_write.bind(this, 6))\n io.register_write(0xcc, this, this.port_addr_write.bind(this, 7))\n io.register_write(0xc2, this, this.port_count_write.bind(this, 4))\n io.register_write(0xc6, this, this.port_count_write.bind(this, 5))\n io.register_write(0xca, this, this.port_count_write.bind(this, 6))\n io.register_write(0xce, this, this.port_count_write.bind(this, 7))\n\n io.register_read(0xc0, this, this.port_addr_read.bind(this, 4))\n io.register_read(0xc4, this, this.port_addr_read.bind(this, 5))\n io.register_read(0xc8, this, this.port_addr_read.bind(this, 6))\n io.register_read(0xcc, this, this.port_addr_read.bind(this, 7))\n io.register_read(0xc2, this, this.port_count_read.bind(this, 4))\n io.register_read(0xc6, this, this.port_count_read.bind(this, 5))\n io.register_read(0xca, this, this.port_count_read.bind(this, 6))\n io.register_read(0xce, this, this.port_count_read.bind(this, 7))\n\n io.register_write(0x87, this, this.port_page_write.bind(this, 0))\n io.register_write(0x83, this, this.port_page_write.bind(this, 1))\n io.register_write(0x81, this, this.port_page_write.bind(this, 2))\n io.register_write(0x82, this, this.port_page_write.bind(this, 3))\n io.register_write(0x8f, this, this.port_page_write.bind(this, 4))\n io.register_write(0x8b, this, this.port_page_write.bind(this, 5))\n io.register_write(0x89, this, this.port_page_write.bind(this, 6))\n io.register_write(0x8a, this, this.port_page_write.bind(this, 7))\n\n io.register_read(0x87, this, this.port_page_read.bind(this, 0))\n io.register_read(0x83, this, this.port_page_read.bind(this, 1))\n io.register_read(0x81, this, this.port_page_read.bind(this, 2))\n io.register_read(0x82, this, this.port_page_read.bind(this, 3))\n io.register_read(0x8f, this, this.port_page_read.bind(this, 4))\n io.register_read(0x8b, this, this.port_page_read.bind(this, 5))\n io.register_read(0x89, this, this.port_page_read.bind(this, 6))\n io.register_read(0x8a, this, this.port_page_read.bind(this, 7))\n\n io.register_write(0x487, this, this.port_pagehi_write.bind(this, 0))\n io.register_write(0x483, this, this.port_pagehi_write.bind(this, 1))\n io.register_write(0x481, this, this.port_pagehi_write.bind(this, 2))\n io.register_write(0x482, this, this.port_pagehi_write.bind(this, 3))\n io.register_write(0x48b, this, this.port_pagehi_write.bind(this, 5))\n io.register_write(0x489, this, this.port_pagehi_write.bind(this, 6))\n io.register_write(0x48a, this, this.port_pagehi_write.bind(this, 7))\n\n io.register_read(0x487, this, this.port_pagehi_read.bind(this, 0))\n io.register_read(0x483, this, this.port_pagehi_read.bind(this, 1))\n io.register_read(0x481, this, this.port_pagehi_read.bind(this, 2))\n io.register_read(0x482, this, this.port_pagehi_read.bind(this, 3))\n io.register_read(0x48b, this, this.port_pagehi_read.bind(this, 5))\n io.register_read(0x489, this, this.port_pagehi_read.bind(this, 6))\n io.register_read(0x48a, this, this.port_pagehi_read.bind(this, 7))\n\n io.register_write(0x0a, this, this.port_singlemask_write.bind(this, 0))\n io.register_write(0xd4, this, this.port_singlemask_write.bind(this, 4))\n io.register_write(0x0f, this, this.port_multimask_write.bind(this, 0))\n io.register_write(0xde, this, this.port_multimask_write.bind(this, 4))\n\n io.register_read(0x0f, this, this.port_multimask_read.bind(this, 0))\n io.register_read(0xde, this, this.port_multimask_read.bind(this, 4))\n\n io.register_write(0x0b, this, this.port_mode_write.bind(this, 0))\n io.register_write(0xd6, this, this.port_mode_write.bind(this, 4))\n\n io.register_write(0x0c, this, this.portC_write)\n io.register_write(0xd8, this, this.portC_write)\n }\n\n get_state(): [\n Uint8Array,\n Uint8Array,\n Uint16Array,\n Uint16Array,\n Uint16Array,\n Uint16Array,\n Uint8Array,\n Uint8Array,\n number,\n ] {\n return [\n this.channel_page,\n this.channel_pagehi,\n this.channel_addr,\n this.channel_addr_init,\n this.channel_count,\n this.channel_count_init,\n this.channel_mask,\n this.channel_mode,\n this.lsb_msb_flipflop,\n ]\n }\n\n set_state(\n state: [\n Uint8Array,\n Uint8Array,\n Uint16Array,\n Uint16Array,\n Uint16Array,\n Uint16Array,\n Uint8Array,\n Uint8Array,\n number,\n ],\n ): void {\n this.channel_page = state[0]\n this.channel_pagehi = state[1]\n this.channel_addr = state[2]\n this.channel_addr_init = state[3]\n this.channel_count = state[4]\n this.channel_count_init = state[5]\n this.channel_mask = state[6]\n this.channel_mode = state[7]\n this.lsb_msb_flipflop = state[8]\n }\n\n port_count_write(channel: number, data_byte: number): void {\n dbg_log('count write [' + channel + '] = ' + h(data_byte), LOG_DMA)\n\n this.channel_count[channel] = this.flipflop_get(\n this.channel_count[channel],\n data_byte,\n false,\n )\n\n this.channel_count_init[channel] = this.flipflop_get(\n this.channel_count_init[channel],\n data_byte,\n true,\n )\n }\n\n port_count_read(channel: number): number {\n dbg_log(\n 'count read [' + channel + '] -> ' + h(this.channel_count[channel]),\n LOG_DMA,\n )\n return this.flipflop_read(this.channel_count[channel])\n }\n\n port_addr_write(channel: number, data_byte: number): void {\n dbg_log('addr write [' + channel + '] = ' + h(data_byte), LOG_DMA)\n\n this.channel_addr[channel] = this.flipflop_get(\n this.channel_addr[channel],\n data_byte,\n false,\n )\n\n this.channel_addr_init[channel] = this.flipflop_get(\n this.channel_addr_init[channel],\n data_byte,\n true,\n )\n }\n\n port_addr_read(channel: number): number {\n dbg_log(\n 'addr read [' + channel + '] -> ' + h(this.channel_addr[channel]),\n LOG_DMA,\n )\n return this.flipflop_read(this.channel_addr[channel])\n }\n\n port_pagehi_write(channel: number, data_byte: number): void {\n dbg_log('pagehi write [' + channel + '] = ' + h(data_byte), LOG_DMA)\n this.channel_pagehi[channel] = data_byte\n }\n\n port_pagehi_read(channel: number): number {\n dbg_log('pagehi read [' + channel + ']', LOG_DMA)\n return this.channel_pagehi[channel]\n }\n\n port_page_write(channel: number, data_byte: number): void {\n dbg_log('page write [' + channel + '] = ' + h(data_byte), LOG_DMA)\n this.channel_page[channel] = data_byte\n }\n\n port_page_read(channel: number): number {\n dbg_log('page read [' + channel + ']', LOG_DMA)\n return this.channel_page[channel]\n }\n\n port_singlemask_write(channel_offset: number, data_byte: number): void {\n const channel = (data_byte & 0x3) + channel_offset\n const value = data_byte & 0x4 ? 1 : 0\n dbg_log(\n 'singlechannel mask write [' + channel + '] = ' + value,\n LOG_DMA,\n )\n this.update_mask(channel, value)\n }\n\n port_multimask_write(channel_offset: number, data_byte: number): void {\n dbg_log('multichannel mask write: ' + h(data_byte), LOG_DMA)\n for (let i = 0; i < 4; i++) {\n this.update_mask(channel_offset + i, data_byte & (1 << i))\n }\n }\n\n port_multimask_read(channel_offset: number): number {\n let value = 0\n value |= this.channel_mask[channel_offset + 0]\n value |= this.channel_mask[channel_offset + 1] << 1\n value |= this.channel_mask[channel_offset + 2] << 2\n value |= this.channel_mask[channel_offset + 3] << 3\n dbg_log('multichannel mask read: ' + h(value), LOG_DMA)\n return value\n }\n\n port_mode_write(channel_offset: number, data_byte: number): void {\n const channel = (data_byte & 0x3) + channel_offset\n dbg_log('mode write [' + channel + '] = ' + h(data_byte), LOG_DMA)\n this.channel_mode[channel] = data_byte\n }\n\n portC_write(_data_byte: number): void {\n dbg_log('flipflop reset', LOG_DMA)\n this.lsb_msb_flipflop = 0\n }\n\n on_unmask(fn: (channel: number) => void, this_value: unknown): void {\n this.unmask_listeners.push({\n fn: fn,\n this_value: this_value,\n })\n }\n\n update_mask(channel: number, value: number): void {\n if (this.channel_mask[channel] !== value) {\n this.channel_mask[channel] = value\n\n if (!value) {\n dbg_log('firing on_unmask(' + channel + ')', LOG_DMA)\n for (let i = 0; i < this.unmask_listeners.length; i++) {\n this.unmask_listeners[i].fn.call(\n this.unmask_listeners[i].this_value,\n channel,\n )\n }\n }\n }\n }\n\n // read data, write to memory\n do_read(\n buffer: DMABuffer,\n start: number,\n len: number,\n channel: number,\n fn: (error: boolean) => void,\n ): void {\n const read_count = this.count_get_8bit(channel),\n addr = this.address_get_8bit(channel)\n\n dbg_log('DMA write channel ' + channel, LOG_DMA)\n dbg_log('to ' + h(addr) + ' len ' + h(read_count), LOG_DMA)\n\n if (len < read_count) {\n dbg_log(\n 'DMA should read more than provided: ' +\n h(len) +\n ' ' +\n h(read_count),\n LOG_DMA,\n )\n }\n\n if (start + read_count > buffer.byteLength) {\n dbg_log('DMA read outside of buffer', LOG_DMA)\n fn(true)\n } else {\n const cpu = this.cpu\n this.channel_addr[channel] += read_count\n\n buffer.get(start, read_count, function (data: Uint8Array) {\n cpu.write_blob(data, addr)\n fn(false)\n })\n }\n }\n\n // write data, read memory\n // start and len in bytes\n do_write(\n buffer: DMABuffer,\n start: number,\n len: number,\n channel: number,\n fn: (error: boolean) => void,\n ): void {\n let read_count = (this.channel_count[channel] + 1) & 0xffff,\n read_bytes = read_count * (channel >= 5 ? 2 : 1),\n unfinished = false,\n want_more = false\n const bytes_per_count = channel >= 5 ? 2 : 1\n const addr = this.address_get_8bit(channel)\n const autoinit = this.channel_mode[channel] & 0x10\n\n dbg_log('DMA write channel ' + channel, LOG_DMA)\n dbg_log('to ' + h(addr) + ' len ' + h(read_bytes), LOG_DMA)\n\n if (len < read_bytes) {\n dbg_log('DMA should read more than provided', LOG_DMA)\n read_count = Math.floor(len / bytes_per_count)\n read_bytes = read_count * bytes_per_count\n unfinished = true\n } else if (len > read_bytes) {\n dbg_log('DMA attempted to read more than provided', LOG_DMA)\n want_more = true\n }\n\n if (start + read_bytes > buffer.byteLength) {\n dbg_log('DMA write outside of buffer', LOG_DMA)\n fn(true)\n } else {\n this.channel_addr[channel] += read_count\n this.channel_count[channel] -= read_count\n // when complete, counter should underflow to 0xFFFF\n\n if (!unfinished && autoinit) {\n dbg_log('DMA autoinit', LOG_DMA)\n this.channel_addr[channel] = this.channel_addr_init[channel]\n this.channel_count[channel] = this.channel_count_init[channel]\n }\n\n buffer.set(\n start,\n this.cpu.mem8.subarray(addr, addr + read_bytes),\n () => {\n if (want_more && autoinit) {\n dbg_log('DMA continuing from start', LOG_DMA)\n this.do_write(\n buffer,\n start + read_bytes,\n len - read_bytes,\n channel,\n fn,\n )\n } else {\n fn(false)\n }\n },\n )\n }\n }\n\n address_get_8bit(channel: number): number {\n let addr = this.channel_addr[channel]\n\n // http://wiki.osdev.org/ISA_DMA#16_bit_issues\n if (channel >= 5) {\n addr = addr << 1\n }\n\n addr &= 0xffff\n addr |= this.channel_page[channel] << 16\n addr |= this.channel_pagehi[channel] << 24\n\n return addr\n }\n\n count_get_8bit(channel: number): number {\n let count = this.channel_count[channel] + 1\n\n if (channel >= 5) {\n count *= 2\n }\n\n return count\n }\n\n flipflop_get(\n old_dword: number,\n new_byte: number,\n continuing: boolean,\n ): number {\n if (!continuing) {\n this.lsb_msb_flipflop ^= 1\n }\n\n if (this.lsb_msb_flipflop) {\n // low byte\n return (old_dword & ~0xff) | new_byte\n } else {\n // high byte\n return (old_dword & ~0xff00) | (new_byte << 8)\n }\n }\n\n flipflop_read(dword: number): number {\n this.lsb_msb_flipflop ^= 1\n\n if (this.lsb_msb_flipflop) {\n // low byte\n return dword & 0xff\n } else {\n // high byte\n return (dword >> 8) & 0xff\n }\n }\n}\n", "declare let DEBUG: boolean\n\nimport { LOG_SERIAL } from './const.js'\nimport { h } from './lib.js'\nimport { dbg_log } from './log.js'\nimport { IO } from './io.js'\nimport { BusConnector } from './bus.js'\n\n/*\n * Serial ports\n * http://wiki.osdev.org/UART\n * https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js\n * https://www.freebsd.org/doc/en/articles/serial-uart/\n */\n\nconst DLAB = 0x80\n\nconst UART_IER_MSI = 0x08 /* Modem Status Changed int. */\nconst UART_IER_THRI = 0x02 /* Enable Transmitter holding register int. */\nconst UART_IER_RDI = 0x01 /* Enable receiver data interrupt */\n\nconst UART_IIR_MSI = 0x00 /* Modem status interrupt (Low priority) */\nconst UART_IIR_NO_INT = 0x01\nconst UART_IIR_THRI = 0x02 /* Transmitter holding register empty */\nconst UART_IIR_RDI = 0x04 /* Receiver data interrupt */\nconst _UART_IIR_RLSI = 0x06 /* Receiver line status interrupt (High p.) */\nconst UART_IIR_CTI = 0x0c /* Character timeout */\n\n// Modem control register\nconst UART_MCR_LOOPBACK = 0x10\n\nconst UART_LSR_DATA_READY = 0x1 // data available\nconst UART_LSR_TX_EMPTY = 0x20 // TX (THR) buffer is empty\nconst UART_LSR_TRANSMITTER_EMPTY = 0x40 // TX empty and line is idle\n\n// Modem status register\nconst UART_MSR_DCD = 0x7 // Data Carrier Detect\nconst UART_MSR_RI = 0x6 // Ring Indicator\nconst UART_MSR_DSR = 0x5 // Data Set Ready\nconst UART_MSR_CTS = 0x4 // Clear To Send\n// Delta bits\nconst UART_MSR_DDCD = 0x3 // Delta DCD\nconst UART_MSR_TERI = 0x2 // Trailing Edge RI\nconst UART_MSR_DDSR = 0x1 // Delta DSR\nconst UART_MSR_DCTS = 0x0 // Delta CTS\n\n// Minimal interface for CPU fields UART uses\ninterface UARTCpu {\n io: IO\n device_raise_irq(irq: number): void\n device_lower_irq(irq: number): void\n}\n\ntype UARTState = [\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n]\n\n/**\n * UART serial port controller.\n */\nexport class UART {\n name: string\n bus: BusConnector\n cpu: UARTCpu\n ints: number\n baud_rate: number\n line_control: number\n lsr: number\n fifo_control: number\n ier: number\n iir: number\n modem_control: number\n modem_status: number\n scratch_register: number\n irq: number\n input: number[]\n current_line: string\n com: number\n\n constructor(cpu: UARTCpu, port: number, bus: BusConnector) {\n this.name = 'uart'\n this.bus = bus\n this.cpu = cpu\n\n this.ints = 1 << UART_IIR_THRI\n\n this.baud_rate = 0\n\n this.line_control = 0\n\n // line status register\n this.lsr = UART_LSR_TRANSMITTER_EMPTY | UART_LSR_TX_EMPTY\n\n this.fifo_control = 0\n\n // interrupts enable\n this.ier = 0\n\n // interrupt identification register\n this.iir = UART_IIR_NO_INT\n\n this.modem_control = 0\n this.modem_status = 0\n\n this.scratch_register = 0\n\n this.irq = 0\n\n this.input = []\n\n this.current_line = ''\n\n switch (port) {\n case 0x3f8:\n this.com = 0\n this.irq = 4\n break\n case 0x2f8:\n this.com = 1\n this.irq = 3\n break\n case 0x3e8:\n this.com = 2\n this.irq = 4\n break\n case 0x2e8:\n this.com = 3\n this.irq = 3\n break\n default:\n dbg_log('Invalid serial port: ' + h(port), LOG_SERIAL)\n this.com = 0\n this.irq = 4\n }\n\n this.bus.register(\n 'serial' + this.com + '-input',\n (data: number): void => {\n this.data_received(data)\n },\n this,\n )\n\n this.bus.register(\n 'serial' + this.com + '-modem-status-input',\n (data: number): void => {\n this.set_modem_status(data)\n },\n this,\n )\n\n // Set individual modem status bits\n\n this.bus.register(\n 'serial' + this.com + '-carrier-detect-input',\n (data: number): void => {\n const status = data\n ? this.modem_status |\n (1 << UART_MSR_DCD) |\n (1 << UART_MSR_DDCD)\n : this.modem_status &\n ~(1 << UART_MSR_DCD) &\n ~(1 << UART_MSR_DDCD)\n this.set_modem_status(status)\n },\n this,\n )\n\n this.bus.register(\n 'serial' + this.com + '-ring-indicator-input',\n (data: number): void => {\n const status = data\n ? this.modem_status |\n (1 << UART_MSR_RI) |\n (1 << UART_MSR_TERI)\n : this.modem_status &\n ~(1 << UART_MSR_RI) &\n ~(1 << UART_MSR_TERI)\n this.set_modem_status(status)\n },\n this,\n )\n\n this.bus.register(\n 'serial' + this.com + '-data-set-ready-input',\n (data: number): void => {\n const status = data\n ? this.modem_status |\n (1 << UART_MSR_DSR) |\n (1 << UART_MSR_DDSR)\n : this.modem_status &\n ~(1 << UART_MSR_DSR) &\n ~(1 << UART_MSR_DDSR)\n this.set_modem_status(status)\n },\n this,\n )\n\n this.bus.register(\n 'serial' + this.com + '-clear-to-send-input',\n (data: number): void => {\n const status = data\n ? this.modem_status |\n (1 << UART_MSR_CTS) |\n (1 << UART_MSR_DCTS)\n : this.modem_status &\n ~(1 << UART_MSR_CTS) &\n ~(1 << UART_MSR_DCTS)\n this.set_modem_status(status)\n },\n this,\n )\n\n const io = cpu.io\n\n io.register_write(\n port,\n this,\n (out_byte: number): void => {\n this.write_data(out_byte)\n },\n (out_word: number): void => {\n this.write_data(out_word & 0xff)\n this.write_data(out_word >> 8)\n },\n )\n\n io.register_write(port | 1, this, (out_byte: number): void => {\n if (this.line_control & DLAB) {\n this.baud_rate = (this.baud_rate & 0xff) | (out_byte << 8)\n dbg_log('baud rate: ' + h(this.baud_rate), LOG_SERIAL)\n } else {\n if (\n (this.ier & UART_IIR_THRI) === 0 &&\n out_byte & UART_IIR_THRI\n ) {\n // re-throw THRI if it was masked\n this.ThrowInterrupt(UART_IIR_THRI)\n }\n\n this.ier = out_byte & 0xf\n dbg_log('interrupt enable: ' + h(out_byte), LOG_SERIAL)\n this.CheckInterrupt()\n }\n })\n\n io.register_read(port, this, (): number => {\n if (this.line_control & DLAB) {\n return this.baud_rate & 0xff\n } else {\n let data = 0\n\n if (this.input.length === 0) {\n dbg_log('Read input empty', LOG_SERIAL)\n } else {\n data = this.input.shift()!\n dbg_log('Read input: ' + h(data), LOG_SERIAL)\n }\n\n if (this.input.length === 0) {\n this.lsr &= ~UART_LSR_DATA_READY\n this.ClearInterrupt(UART_IIR_CTI)\n this.ClearInterrupt(UART_IIR_RDI)\n }\n\n return data\n }\n })\n\n io.register_read(port | 1, this, (): number => {\n if (this.line_control & DLAB) {\n return this.baud_rate >> 8\n } else {\n return this.ier & 0xf\n }\n })\n\n io.register_read(port | 2, this, (): number => {\n let ret = this.iir & 0xf\n dbg_log('read interrupt identification: ' + h(this.iir), LOG_SERIAL)\n\n if (this.iir === UART_IIR_THRI) {\n this.ClearInterrupt(UART_IIR_THRI)\n }\n\n if (this.fifo_control & 1) ret |= 0xc0\n\n return ret\n })\n io.register_write(port | 2, this, (out_byte: number): void => {\n dbg_log('fifo control: ' + h(out_byte), LOG_SERIAL)\n this.fifo_control = out_byte\n })\n\n io.register_read(port | 3, this, (): number => {\n dbg_log('read line control: ' + h(this.line_control), LOG_SERIAL)\n return this.line_control\n })\n io.register_write(port | 3, this, (out_byte: number): void => {\n dbg_log('line control: ' + h(out_byte), LOG_SERIAL)\n this.line_control = out_byte\n })\n\n io.register_read(port | 4, this, (): number => {\n return this.modem_control\n })\n io.register_write(port | 4, this, (out_byte: number): void => {\n dbg_log('modem control: ' + h(out_byte), LOG_SERIAL)\n this.modem_control = out_byte\n })\n\n io.register_read(port | 5, this, (): number => {\n dbg_log('read line status: ' + h(this.lsr), LOG_SERIAL)\n return this.lsr\n })\n io.register_write(port | 5, this, (_out_byte: number): void => {\n dbg_log('Factory test write', LOG_SERIAL)\n })\n\n io.register_read(port | 6, this, (): number => {\n dbg_log('read modem status: ' + h(this.modem_status), LOG_SERIAL)\n // Clear delta bits\n this.modem_status &= 0xf0\n return this.modem_status\n })\n io.register_write(port | 6, this, (out_byte: number): void => {\n dbg_log('write modem status: ' + h(out_byte), LOG_SERIAL)\n this.set_modem_status(out_byte)\n })\n\n io.register_read(port | 7, this, (): number => {\n return this.scratch_register\n })\n io.register_write(port | 7, this, (out_byte: number): void => {\n this.scratch_register = out_byte\n })\n }\n\n get_state(): UARTState {\n const state: UARTState = [\n this.ints,\n this.baud_rate,\n this.line_control,\n this.lsr,\n this.fifo_control,\n this.ier,\n this.iir,\n this.modem_control,\n this.modem_status,\n this.scratch_register,\n this.irq,\n ]\n\n return state\n }\n\n set_state(state: UARTState): void {\n this.ints = state[0]\n this.baud_rate = state[1]\n this.line_control = state[2]\n this.lsr = state[3]\n this.fifo_control = state[4]\n this.ier = state[5]\n this.iir = state[6]\n this.modem_control = state[7]\n this.modem_status = state[8]\n this.scratch_register = state[9]\n this.irq = state[10]\n }\n\n CheckInterrupt(): void {\n if (this.ints & (1 << UART_IIR_CTI) && this.ier & UART_IER_RDI) {\n this.iir = UART_IIR_CTI\n this.cpu.device_raise_irq(this.irq)\n } else if (this.ints & (1 << UART_IIR_RDI) && this.ier & UART_IER_RDI) {\n this.iir = UART_IIR_RDI\n this.cpu.device_raise_irq(this.irq)\n } else if (\n this.ints & (1 << UART_IIR_THRI) &&\n this.ier & UART_IER_THRI\n ) {\n this.iir = UART_IIR_THRI\n this.cpu.device_raise_irq(this.irq)\n } else if (this.ints & (1 << UART_IIR_MSI) && this.ier & UART_IER_MSI) {\n this.iir = UART_IIR_MSI\n this.cpu.device_raise_irq(this.irq)\n } else {\n this.iir = UART_IIR_NO_INT\n this.cpu.device_lower_irq(this.irq)\n }\n }\n\n ThrowInterrupt(line: number): void {\n this.ints |= 1 << line\n this.CheckInterrupt()\n }\n\n ClearInterrupt(line: number): void {\n this.ints &= ~(1 << line)\n this.CheckInterrupt()\n }\n\n data_received(data: number): void {\n dbg_log('input: ' + h(data), LOG_SERIAL)\n this.input.push(data)\n\n this.lsr |= UART_LSR_DATA_READY\n\n if (this.fifo_control & 1) {\n this.ThrowInterrupt(UART_IIR_CTI)\n } else {\n this.ThrowInterrupt(UART_IIR_RDI)\n }\n }\n\n write_data(out_byte: number): void {\n if (this.line_control & DLAB) {\n this.baud_rate = (this.baud_rate & ~0xff) | out_byte\n return\n }\n\n dbg_log('data: ' + h(out_byte), LOG_SERIAL)\n\n this.ThrowInterrupt(UART_IIR_THRI)\n\n if (this.modem_control & UART_MCR_LOOPBACK) {\n this.data_received(out_byte)\n } else {\n this.bus.send('serial' + this.com + '-output-byte', out_byte)\n }\n\n if (DEBUG) {\n const char = String.fromCharCode(out_byte)\n this.current_line += char\n\n if (char === '\\n') {\n const line = this.current_line\n .trimRight()\n // eslint-disable-next-line no-control-regex\n .replace(/[\\x00-\\x08\\x0b-\\x1f\\x7f\\x80-\\xff]/g, '')\n dbg_log('SERIAL: ' + line)\n this.current_line = ''\n }\n }\n }\n\n set_modem_status(status: number): void {\n dbg_log('modem status: ' + h(status), LOG_SERIAL)\n const prev_delta_bits = this.modem_status & 0x0f\n // compare the bits that have changed and shift them into the delta bits\n let delta = (this.modem_status ^ status) >> 4\n // The delta should stay set if they were previously set\n delta |= prev_delta_bits\n\n // update the current modem status\n this.modem_status = status\n // update the delta bits based on the changes and previous\n // values, but also leave the delta bits set if they were\n // passed in as part of the status\n this.modem_status |= delta\n }\n}\n", "import { LOG_NET } from './const.js'\nimport { h, hex_dump } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\n\nimport { PCI } from './pci.js'\nimport { BusConnector } from './bus.js'\nimport { IO } from './io.js'\n\n// http://www.ethernut.de/pdf/8019asds.pdf\n\n// Minimal interface for the CPU fields Ne2k uses.\ninterface Ne2kCpu {\n io: IO\n devices: {\n pci: PCI\n }\n}\n\nconst NE2K_LOG_VERBOSE = false\nconst NE2K_LOG_PACKETS = false\n\nconst E8390_CMD = 0x00 /* The command register (for all pages) */\n\n/* Page 0 register offsets. */\nconst _EN0_CLDALO = 0x01 /* Low byte of current local dma addr RD */\nconst EN0_STARTPG = 0x01 /* Starting page of ring bfr WR */\nconst _EN0_CLDAHI = 0x02 /* High byte of current local dma addr RD */\nconst EN0_STOPPG = 0x02 /* Ending page +1 of ring bfr WR */\nconst EN0_BOUNDARY = 0x03 /* Boundary page of ring bfr RD WR */\nconst EN0_TSR = 0x04 /* Transmit status reg RD */\nconst EN0_TPSR = 0x04 /* Transmit starting page WR */\nconst _EN0_NCR = 0x05 /* Number of collision reg RD */\nconst EN0_TCNTLO = 0x05 /* Low byte of tx byte count WR */\nconst _EN0_FIFO = 0x06 /* FIFO RD */\nconst EN0_TCNTHI = 0x06 /* High byte of tx byte count WR */\nconst EN0_ISR = 0x07 /* Interrupt status reg RD WR */\nconst _EN0_CRDALO = 0x08 /* low byte of current remote dma address RD */\nconst EN0_RSARLO = 0x08 /* Remote start address reg 0 */\nconst _EN0_CRDAHI = 0x09 /* high byte, current remote dma address RD */\nconst EN0_RSARHI = 0x09 /* Remote start address reg 1 */\nconst EN0_RCNTLO = 0x0a /* Remote byte count reg WR */\nconst EN0_RCNTHI = 0x0b /* Remote byte count reg WR */\nconst EN0_RSR = 0x0c /* rx status reg RD */\nconst EN0_RXCR = 0x0c /* RX configuration reg WR */\nconst EN0_TXCR = 0x0d /* TX configuration reg WR */\nconst EN0_COUNTER0 = 0x0d /* Rcv alignment error counter RD */\nconst EN0_DCFG = 0x0e /* Data configuration reg WR */\nconst EN0_COUNTER1 = 0x0e /* Rcv CRC error counter RD */\nconst EN0_IMR = 0x0f /* Interrupt mask reg WR */\nconst EN0_COUNTER2 = 0x0f /* Rcv missed frame error counter RD */\n\nconst NE_DATAPORT = 0x10 /* NatSemi-defined port window offset. */\nconst NE_RESET = 0x1f /* Issue a read to reset, a write to clear. */\n\n/* Bits in EN0_ISR - Interrupt status register */\nconst ENISR_RX = 0x01 /* Receiver, no error */\nconst ENISR_TX = 0x02 /* Transmitter, no error */\nconst _ENISR_RX_ERR = 0x04 /* Receiver, with error */\nconst _ENISR_TX_ERR = 0x08 /* Transmitter, with error */\nconst _ENISR_OVER = 0x10 /* Receiver overwrote the ring */\nconst _ENISR_COUNTERS = 0x20 /* Counters need emptying */\nconst ENISR_RDC = 0x40 /* remote dma complete */\nconst ENISR_RESET = 0x80 /* Reset completed */\nconst _ENISR_ALL = 0x3f /* Interrupts we will enable */\n\nconst ENRSR_RXOK = 0x01 /* Received a good packet */\n\nconst START_PAGE = 0x40\nconst START_RX_PAGE = 0x40 + 12\nconst STOP_PAGE = 0x80\n\n// Search and replace MAC addresses in ethernet, arp and dhcp packets.\n// Used after restoring an OS from memory dump, so that multiple instances of\n// that OS can run at the same time with different external MAC addresses.\n// Crude but seems to work.\nfunction translate_mac_address(\n packet: Uint8Array,\n search_mac: Uint8Array,\n replacement_mac: Uint8Array,\n): void {\n if (\n packet[0] === search_mac[0] &&\n packet[1] === search_mac[1] &&\n packet[2] === search_mac[2] &&\n packet[3] === search_mac[3] &&\n packet[4] === search_mac[4] &&\n packet[5] === search_mac[5]\n ) {\n dbg_log('Replace mac in eth destination field', LOG_NET)\n\n packet[0] = replacement_mac[0]\n packet[1] = replacement_mac[1]\n packet[2] = replacement_mac[2]\n packet[3] = replacement_mac[3]\n packet[4] = replacement_mac[4]\n packet[5] = replacement_mac[5]\n }\n\n if (\n packet[6 + 0] === search_mac[0] &&\n packet[6 + 1] === search_mac[1] &&\n packet[6 + 2] === search_mac[2] &&\n packet[6 + 3] === search_mac[3] &&\n packet[6 + 4] === search_mac[4] &&\n packet[6 + 5] === search_mac[5]\n ) {\n dbg_log('Replace mac in eth source field', LOG_NET)\n\n packet[6 + 0] = replacement_mac[0]\n packet[6 + 1] = replacement_mac[1]\n packet[6 + 2] = replacement_mac[2]\n packet[6 + 3] = replacement_mac[3]\n packet[6 + 4] = replacement_mac[4]\n packet[6 + 5] = replacement_mac[5]\n }\n\n const ethertype = (packet[12] << 8) | packet[13]\n\n if (ethertype === 0x0800) {\n // ipv4\n const ipv4_packet = packet.subarray(14)\n const ipv4_version = ipv4_packet[0] >> 4\n\n if (ipv4_version !== 4) {\n dbg_log(\n 'Expected ipv4.version==4 but got: ' + ipv4_version,\n LOG_NET,\n )\n return\n }\n\n const ipv4_ihl = ipv4_packet[0] & 0xf\n dbg_assert(ipv4_ihl === 5, 'TODO: ihl!=5')\n\n const ipv4_proto = ipv4_packet[9]\n if (ipv4_proto === 0x11) {\n // udp\n const udp_packet = ipv4_packet.subarray(5 * 4)\n const source_port = (udp_packet[0] << 8) | udp_packet[1]\n const destination_port = (udp_packet[2] << 8) | udp_packet[3]\n const checksum = (udp_packet[6] << 8) | udp_packet[7]\n\n dbg_log(\n 'udp srcport=' +\n source_port +\n ' dstport=' +\n destination_port +\n ' checksum=' +\n h(checksum, 4),\n LOG_NET,\n )\n\n if (source_port === 67 || destination_port === 67) {\n // dhcp\n const dhcp_packet = udp_packet.subarray(8)\n const dhcp_magic =\n (dhcp_packet[0xec] << 24) |\n (dhcp_packet[0xed] << 16) |\n (dhcp_packet[0xee] << 8) |\n dhcp_packet[0xef]\n\n if (dhcp_magic !== 0x63825363) {\n dbg_log(\n \"dhcp packet didn't match magic: \" + h(dhcp_magic, 8),\n )\n return\n }\n\n if (\n dhcp_packet[28 + 0] === search_mac[0] &&\n dhcp_packet[28 + 1] === search_mac[1] &&\n dhcp_packet[28 + 2] === search_mac[2] &&\n dhcp_packet[28 + 3] === search_mac[3] &&\n dhcp_packet[28 + 4] === search_mac[4] &&\n dhcp_packet[28 + 5] === search_mac[5]\n ) {\n dbg_log('Replace mac in dhcp.chaddr', LOG_NET)\n\n dhcp_packet[28 + 0] = replacement_mac[0]\n dhcp_packet[28 + 1] = replacement_mac[1]\n dhcp_packet[28 + 2] = replacement_mac[2]\n dhcp_packet[28 + 3] = replacement_mac[3]\n dhcp_packet[28 + 4] = replacement_mac[4]\n dhcp_packet[28 + 5] = replacement_mac[5]\n\n udp_packet[6] = udp_packet[7] = 0 // zero udp checksum\n }\n\n let offset = 0xf0\n while (offset < dhcp_packet.length) {\n const dhcp_option_type = dhcp_packet[offset++]\n\n if (dhcp_option_type === 0xff) {\n break\n }\n\n const length = dhcp_packet[offset++]\n\n if (\n dhcp_option_type === 0x3d && // client identifier\n dhcp_packet[offset + 0] === 0x01 && // ethernet\n dhcp_packet[offset + 1] === search_mac[0] &&\n dhcp_packet[offset + 2] === search_mac[1] &&\n dhcp_packet[offset + 3] === search_mac[2] &&\n dhcp_packet[offset + 4] === search_mac[3] &&\n dhcp_packet[offset + 5] === search_mac[4] &&\n dhcp_packet[offset + 6] === search_mac[5]\n ) {\n dbg_log('Replace mac in dhcp.clientidentifier', LOG_NET)\n\n dhcp_packet[offset + 1] = replacement_mac[0]\n dhcp_packet[offset + 2] = replacement_mac[1]\n dhcp_packet[offset + 3] = replacement_mac[2]\n dhcp_packet[offset + 4] = replacement_mac[3]\n dhcp_packet[offset + 5] = replacement_mac[4]\n dhcp_packet[offset + 6] = replacement_mac[5]\n\n udp_packet[6] = udp_packet[7] = 0 // zero udp checksum\n }\n\n offset += length\n }\n }\n } else {\n // tcp, ...\n }\n } else if (ethertype === 0x0806) {\n // arp\n const arp_packet = packet.subarray(14)\n dbg_log(\n 'arp oper=' +\n arp_packet[7] +\n ' ' +\n format_mac(arp_packet.subarray(8, 8 + 6)) +\n ' ' +\n format_mac(arp_packet.subarray(18, 18 + 6)),\n LOG_NET,\n )\n\n if (\n arp_packet[8 + 0] === search_mac[0] &&\n arp_packet[8 + 1] === search_mac[1] &&\n arp_packet[8 + 2] === search_mac[2] &&\n arp_packet[8 + 3] === search_mac[3] &&\n arp_packet[8 + 4] === search_mac[4] &&\n arp_packet[8 + 5] === search_mac[5]\n ) {\n dbg_log('Replace mac in arp.sha', LOG_NET)\n\n arp_packet[8 + 0] = replacement_mac[0]\n arp_packet[8 + 1] = replacement_mac[1]\n arp_packet[8 + 2] = replacement_mac[2]\n arp_packet[8 + 3] = replacement_mac[3]\n arp_packet[8 + 4] = replacement_mac[4]\n arp_packet[8 + 5] = replacement_mac[5]\n }\n } else {\n // TODO: ipv6, ...\n }\n}\n\nexport function format_mac(mac: Uint8Array): string {\n return [\n mac[0].toString(16).padStart(2, '0'),\n mac[1].toString(16).padStart(2, '0'),\n mac[2].toString(16).padStart(2, '0'),\n mac[3].toString(16).padStart(2, '0'),\n mac[4].toString(16).padStart(2, '0'),\n mac[5].toString(16).padStart(2, '0'),\n ].join(':')\n}\n\nfunction dump_packet(packet: Uint8Array, prefix: string): void {\n const ethertype = (packet[12] << 8) | (packet[13] << 0)\n if (ethertype === 0x0800) {\n const ipv4_packet = packet.subarray(14)\n const ipv4_len = (ipv4_packet[2] << 8) | ipv4_packet[3]\n const ipv4_proto = ipv4_packet[9]\n if (ipv4_proto === 0x11) {\n const udp_packet = ipv4_packet.subarray(5 * 4)\n const source_port = (udp_packet[0] << 8) | udp_packet[1]\n const destination_port = (udp_packet[2] << 8) | udp_packet[3]\n const checksum = (udp_packet[6] << 8) | udp_packet[7]\n\n if (source_port === 67 || destination_port === 67) {\n const dhcp_packet = udp_packet.subarray(8)\n const dhcp_chaddr = dhcp_packet.subarray(28, 28 + 6)\n dbg_log(\n prefix +\n ' len=' +\n packet.length +\n ' ethertype=' +\n h(ethertype) +\n ' ipv4.len=' +\n ipv4_len +\n ' ipv4.proto=' +\n h(packet[14 + 9]) +\n ' udp.srcport=' +\n source_port +\n ' udp.dstport=' +\n destination_port +\n ' udp.chksum=' +\n h(checksum, 4) +\n ' dhcp.chaddr=' +\n format_mac(dhcp_chaddr),\n )\n } else {\n dbg_log(\n prefix +\n ' len=' +\n packet.length +\n ' ethertype=' +\n h(ethertype) +\n ' ipv4.len=' +\n ipv4_len +\n ' ipv4.proto=' +\n h(packet[14 + 9]) +\n ' udp.srcport=' +\n source_port +\n ' udp.dstport=' +\n destination_port +\n ' udp.chksum=' +\n h(checksum, 4),\n )\n }\n } else if (ipv4_proto === 0x01) {\n // icmp, intentionally empty\n } else {\n dbg_log(\n prefix +\n ' len=' +\n packet.length +\n ' ethertype=' +\n h(ethertype) +\n ' ipv4.len=' +\n ipv4_len +\n ' ipv4.proto=' +\n h(packet[14 + 9]),\n )\n }\n } else {\n const _arp_packet = packet.subarray(14)\n dbg_log(\n prefix +\n ' len=' +\n packet.length +\n ' ethertype=' +\n h(ethertype) +\n ' arp',\n )\n }\n dbg_log(hex_dump(packet))\n}\n\nexport class Ne2k {\n name: string\n cpu: Ne2kCpu\n pci: PCI\n id: number\n preserve_mac_from_state_image: boolean\n mac_address_translation: boolean\n bus: BusConnector\n port: number\n\n pci_space: number[]\n pci_id: number\n pci_bars: { size: number }[]\n\n isr: number\n imr: number\n cr: number\n dcfg: number\n rcnt: number\n tcnt: number\n tpsr: number\n memory: Uint8Array\n rxcr: number\n txcr: number\n tsr: number\n mac: Uint8Array\n mar: Uint8Array\n mac_address_in_state: Uint8Array | null\n rsar: number\n pstart: number\n pstop: number\n curpg: number\n boundary: number\n\n constructor(\n cpu: Ne2kCpu,\n bus: BusConnector,\n preserve_mac_from_state_image: boolean,\n mac_address_translation: boolean,\n id?: number,\n ) {\n this.cpu = cpu\n this.pci = cpu.devices.pci\n this.id = id || 0\n this.preserve_mac_from_state_image = preserve_mac_from_state_image\n this.mac_address_translation = mac_address_translation\n this.bus = bus\n this.bus.register(\n 'net' + this.id + '-receive',\n function (this: Ne2k, data: Uint8Array) {\n this.receive(data)\n },\n this,\n )\n\n this.port = 0x300 + 0x100 * this.id\n\n this.name = 'ne2k'\n\n const use_pci = true\n\n if (use_pci) {\n this.pci_space = [\n 0xec,\n 0x10,\n 0x29,\n 0x80,\n 0x03,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x02,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n (this.port & 0xff) | 1,\n this.port >> 8,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0xf4,\n 0x1a,\n 0x00,\n 0x11,\n 0x00,\n 0x00,\n 0xb8,\n 0xfe,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x01,\n 0x00,\n 0x00,\n ]\n this.pci_id = (this.id === 0 ? 0x05 : 0x07 + this.id) << 3\n this.pci_bars = [\n {\n size: 32,\n },\n ]\n } else {\n this.pci_space = []\n this.pci_id = 0\n this.pci_bars = []\n }\n\n this.isr = 0\n this.imr = 0 // interrupt mask register\n\n this.cr = 1\n\n this.dcfg = 0\n\n this.rcnt = 0\n\n this.tcnt = 0\n this.tpsr = 0\n this.memory = new Uint8Array(256 * 0x80)\n\n this.rxcr = 0\n this.txcr = 0\n this.tsr = 1\n\n // mac address\n this.mac = new Uint8Array([\n 0x00,\n 0x22,\n 0x15,\n (Math.random() * 255) | 0,\n (Math.random() * 255) | 0,\n (Math.random() * 255) | 0,\n ])\n\n this.bus.send('net' + this.id + '-mac', format_mac(this.mac))\n\n // multicast addresses\n this.mar = Uint8Array.of(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)\n\n // Used for mac address translation\n // The mac the OS thinks it has\n this.mac_address_in_state = null\n\n for (let i = 0; i < 6; i++) {\n this.memory[i << 1] = this.memory[(i << 1) | 1] = this.mac[i]\n }\n\n // the PROM signature of 0x57, 0x57 is also doubled\n // resulting in setting the 4 bytes at the end, 28, 29, 30 and 31 to 0x57\n this.memory[14 << 1] = this.memory[(14 << 1) | 1] = 0x57\n this.memory[15 << 1] = this.memory[(15 << 1) | 1] = 0x57\n\n dbg_log('Mac: ' + format_mac(this.mac), LOG_NET)\n\n this.rsar = 0\n\n this.pstart = START_PAGE\n this.pstop = STOP_PAGE\n\n this.curpg = START_RX_PAGE\n this.boundary = START_RX_PAGE\n\n const io = cpu.io\n\n io.register_read(\n this.port | E8390_CMD,\n this,\n function (this: Ne2k): number {\n dbg_log('Read cmd', LOG_NET)\n return this.cr\n },\n function (this: Ne2k): number {\n dbg_log('Read16 cmd', LOG_NET)\n return this.cr\n },\n )\n\n io.register_write(\n this.port | E8390_CMD,\n this,\n function (this: Ne2k, data_byte: number): void {\n this.cr = data_byte\n dbg_log(\n 'Write command: ' +\n h(data_byte, 2) +\n ' newpg=' +\n (this.cr >> 6) +\n ' txcr=' +\n h(this.txcr, 2),\n LOG_NET,\n )\n\n if (this.cr & 1) {\n return\n }\n\n if (data_byte & 0x18 && this.rcnt === 0) {\n this.do_interrupt(ENISR_RDC)\n }\n\n if (data_byte & 4) {\n const start = this.tpsr << 8\n let data: Uint8Array = this.memory.subarray(\n start,\n start + this.tcnt,\n )\n\n if (NE2K_LOG_PACKETS) {\n dump_packet(data, 'send')\n }\n\n if (this.mac_address_in_state) {\n data = new Uint8Array(data) // make a copy\n translate_mac_address(\n data,\n this.mac_address_in_state,\n this.mac,\n )\n }\n\n this.bus.send('net' + this.id + '-send', data)\n this.bus.send('eth-transmit-end', [data.length])\n this.cr &= ~4\n this.do_interrupt(ENISR_TX)\n\n dbg_log(\n 'Command: Transfer. length=' + h(data.byteLength),\n LOG_NET,\n )\n }\n },\n )\n\n io.register_read(\n this.port | EN0_COUNTER0,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 1) {\n dbg_log('Read mar5', LOG_NET)\n return this.mar[5]\n } else {\n dbg_log('Read counter0 pg=' + pg, LOG_NET)\n return 0\n }\n },\n )\n\n io.register_read(\n this.port | EN0_COUNTER1,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 1) {\n dbg_log('Read mar6', LOG_NET)\n return this.mar[6]\n } else {\n dbg_log('Read8 counter1 pg=' + pg, LOG_NET)\n return 0\n }\n },\n function (this: Ne2k): number {\n dbg_log('Read16 counter1 pg=' + this.get_page(), LOG_NET)\n // openbsd\n return 0\n },\n )\n\n io.register_read(\n this.port | EN0_COUNTER2,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 1) {\n dbg_log('Read mar7', LOG_NET)\n return this.mar[7]\n } else {\n dbg_log('Read counter2 pg=' + pg, LOG_NET)\n return 0\n }\n },\n )\n\n io.register_read(\n this.port | NE_RESET,\n this,\n function (this: Ne2k): number {\n dbg_log('Read reset', LOG_NET)\n this.do_interrupt(ENISR_RESET)\n return 0\n },\n )\n\n io.register_write(\n this.port | NE_RESET,\n this,\n function (this: Ne2k, data_byte: number): void {\n dbg_log('Write reset: ' + h(data_byte, 2), LOG_NET)\n //this.isr &= ~ENISR_RESET;\n },\n )\n\n io.register_read(\n this.port | EN0_STARTPG,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n return this.pstart\n } else if (pg === 1) {\n dbg_log('Read pg1/01 (mac[0])', LOG_NET)\n return this.mac[0]\n } else if (pg === 2) {\n return this.pstart\n } else {\n dbg_log('Read pg' + pg + '/01')\n dbg_assert(false)\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_STARTPG,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('start page: ' + h(data_byte, 2), LOG_NET)\n this.pstart = data_byte\n } else if (pg === 1) {\n dbg_log('mac[0] = ' + h(data_byte), LOG_NET)\n this.mac[0] = data_byte\n } else if (pg === 3) {\n dbg_log(\n 'Unimplemented: Write pg3/01 (9346CR): ' + h(data_byte),\n LOG_NET,\n )\n } else {\n dbg_log('Write pg' + pg + '/01: ' + h(data_byte), LOG_NET)\n dbg_assert(false)\n }\n },\n )\n\n io.register_read(\n this.port | EN0_STOPPG,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n return this.pstop\n } else if (pg === 1) {\n dbg_log('Read pg1/02 (mac[1])', LOG_NET)\n return this.mac[1]\n } else if (pg === 2) {\n return this.pstop\n } else {\n dbg_log('Read pg' + pg + '/02', LOG_NET)\n dbg_assert(false)\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_STOPPG,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('stop page: ' + h(data_byte, 2), LOG_NET)\n if (data_byte > this.memory.length >> 8) {\n data_byte = this.memory.length >> 8\n dbg_log(\n 'XXX: Adjusting stop page to ' + h(data_byte),\n LOG_NET,\n )\n }\n this.pstop = data_byte\n } else if (pg === 1) {\n dbg_log('mac[1] = ' + h(data_byte), LOG_NET)\n this.mac[1] = data_byte\n } else {\n dbg_log('Write pg' + pg + '/02: ' + h(data_byte), LOG_NET)\n dbg_assert(false)\n }\n },\n )\n\n io.register_read(\n this.port | EN0_ISR,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('Read isr: ' + h(this.isr, 2), LOG_NET)\n return this.isr\n } else if (pg === 1) {\n dbg_log('Read curpg: ' + h(this.curpg, 2), LOG_NET)\n return this.curpg\n } else {\n dbg_assert(false)\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_ISR,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n // acknowledge interrupts where bit is set\n dbg_log('Write isr: ' + h(data_byte, 2), LOG_NET)\n this.isr &= ~data_byte\n this.update_irq()\n } else if (pg === 1) {\n dbg_log('Write curpg: ' + h(data_byte, 2), LOG_NET)\n this.curpg = data_byte\n } else {\n dbg_assert(false)\n }\n },\n )\n\n io.register_write(\n this.port | EN0_TXCR,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n this.txcr = data_byte\n dbg_log('Write tx config: ' + h(data_byte, 2), LOG_NET)\n } else {\n dbg_log(\n 'Unimplemented: Write pg' +\n pg +\n '/0d ' +\n h(data_byte, 2),\n LOG_NET,\n )\n }\n },\n )\n\n io.register_write(\n this.port | EN0_DCFG,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log(\n 'Write data configuration: ' + h(data_byte, 2),\n LOG_NET,\n )\n this.dcfg = data_byte\n } else {\n dbg_log(\n 'Unimplemented: Write pg' +\n pg +\n '/0e ' +\n h(data_byte, 2),\n LOG_NET,\n )\n }\n },\n )\n\n io.register_read(\n this.port | EN0_RCNTLO,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('Read pg0/0a', LOG_NET)\n return 0x50\n } else if (pg === 1) {\n dbg_log('Read mar2', LOG_NET)\n return this.mar[2]\n } else {\n dbg_assert(false, 'TODO')\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_RCNTLO,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log(\n 'Write remote byte count low: ' + h(data_byte, 2),\n LOG_NET,\n )\n this.rcnt = (this.rcnt & 0xff00) | (data_byte & 0xff)\n } else {\n dbg_log(\n 'Unimplemented: Write pg' +\n pg +\n '/0a ' +\n h(data_byte, 2),\n LOG_NET,\n )\n }\n },\n )\n\n io.register_read(\n this.port | EN0_RCNTHI,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('Read pg0/0b', LOG_NET)\n return 0x43\n } else if (pg === 1) {\n dbg_log('Read mar3', LOG_NET)\n return this.mar[3]\n } else {\n dbg_assert(false, 'TODO')\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_RCNTHI,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log(\n 'Write remote byte count high: ' + h(data_byte, 2),\n LOG_NET,\n )\n this.rcnt = (this.rcnt & 0xff) | ((data_byte << 8) & 0xff00)\n } else {\n dbg_log(\n 'Unimplemented: Write pg' +\n pg +\n '/0b ' +\n h(data_byte, 2),\n LOG_NET,\n )\n }\n },\n )\n\n io.register_read(\n this.port | EN0_RSARLO,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('Read remote start address low', LOG_NET)\n return this.rsar & 0xff\n } else if (pg === 1) {\n dbg_log('Read mar0', LOG_NET)\n return this.mar[0]\n } else {\n dbg_log('Unimplemented: Read pg' + pg + '/08', LOG_NET)\n dbg_assert(false)\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_RSARLO,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log(\n 'Write remote start address low: ' + h(data_byte, 2),\n LOG_NET,\n )\n this.rsar = (this.rsar & 0xff00) | (data_byte & 0xff)\n } else {\n dbg_log(\n 'Unimplemented: Write pg' +\n pg +\n '/08 ' +\n h(data_byte, 2),\n LOG_NET,\n )\n }\n },\n )\n\n io.register_read(\n this.port | EN0_RSARHI,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('Read remote start address high', LOG_NET)\n return (this.rsar >> 8) & 0xff\n } else if (pg === 1) {\n dbg_log('Read mar1', LOG_NET)\n return this.mar[1]\n } else {\n dbg_log('Unimplemented: Read pg' + pg + '/09', LOG_NET)\n dbg_assert(false)\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_RSARHI,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log(\n 'Write remote start address low: ' + h(data_byte, 2),\n LOG_NET,\n )\n this.rsar = (this.rsar & 0xff) | ((data_byte << 8) & 0xff00)\n } else {\n dbg_log(\n 'Unimplemented: Write pg' +\n pg +\n '/09 ' +\n h(data_byte, 2),\n LOG_NET,\n )\n }\n },\n )\n\n io.register_write(\n this.port | EN0_IMR,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log(\n 'Write interrupt mask register: ' +\n h(data_byte, 2) +\n ' isr=' +\n h(this.isr, 2),\n LOG_NET,\n )\n this.imr = data_byte\n this.update_irq()\n } else {\n dbg_log(\n 'Unimplemented: Write pg' +\n pg +\n '/0f ' +\n h(data_byte, 2),\n LOG_NET,\n )\n }\n },\n )\n\n io.register_read(\n this.port | EN0_BOUNDARY,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('Read boundary: ' + h(this.boundary, 2), LOG_NET)\n return this.boundary\n } else if (pg === 1) {\n dbg_log('Read pg1/03 (mac[2])', LOG_NET)\n return this.mac[2]\n } else if (pg === 3) {\n dbg_log('Unimplemented: Read pg3/03 (CONFIG0)', LOG_NET)\n return 0\n } else {\n dbg_log('Read pg' + pg + '/03', LOG_NET)\n dbg_assert(false)\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_BOUNDARY,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('Write boundary: ' + h(data_byte, 2), LOG_NET)\n this.boundary = data_byte\n } else if (pg === 1) {\n dbg_log('mac[2] = ' + h(data_byte), LOG_NET)\n this.mac[2] = data_byte\n } else {\n dbg_log('Write pg' + pg + '/03: ' + h(data_byte), LOG_NET)\n dbg_assert(false)\n }\n },\n )\n\n io.register_read(\n this.port | EN0_TSR,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n return this.tsr\n } else if (pg === 1) {\n dbg_log('Read pg1/04 (mac[3])', LOG_NET)\n return this.mac[3]\n } else {\n dbg_log('Read pg' + pg + '/04', LOG_NET)\n dbg_assert(false)\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_TPSR,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('Write tpsr: ' + h(data_byte, 2), LOG_NET)\n this.tpsr = data_byte\n } else if (pg === 1) {\n dbg_log('mac[3] = ' + h(data_byte), LOG_NET)\n this.mac[3] = data_byte\n } else {\n dbg_log('Write pg' + pg + '/04: ' + h(data_byte), LOG_NET)\n dbg_assert(false)\n }\n },\n )\n\n io.register_read(\n this.port | EN0_TCNTLO,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log(\n 'Unimplemented: Read pg0/05 (NCR: Number of Collisions Register)',\n LOG_NET,\n )\n return 0\n } else if (pg === 1) {\n dbg_log('Read pg1/05 (mac[4])', LOG_NET)\n return this.mac[4]\n } else if (pg === 3) {\n dbg_log('Unimplemented: Read pg3/05 (CONFIG2)', LOG_NET)\n return 0\n } else {\n dbg_log('Read pg' + pg + '/05', LOG_NET)\n dbg_assert(false)\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_TCNTLO,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('Write tcnt low: ' + h(data_byte, 2), LOG_NET)\n this.tcnt = (this.tcnt & ~0xff) | data_byte\n } else if (pg === 1) {\n dbg_log('mac[4] = ' + h(data_byte), LOG_NET)\n this.mac[4] = data_byte\n } else if (pg === 3) {\n dbg_log(\n 'Unimplemented: Write pg3/05 (CONFIG2): ' +\n h(data_byte),\n LOG_NET,\n )\n } else {\n dbg_log('Write pg' + pg + '/05: ' + h(data_byte), LOG_NET)\n dbg_assert(false)\n }\n },\n )\n\n io.register_read(\n this.port | EN0_TCNTHI,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_assert(false, 'TODO')\n return 0\n } else if (pg === 1) {\n dbg_log('Read pg1/06 (mac[5])', LOG_NET)\n return this.mac[5]\n } else if (pg === 3) {\n dbg_log('Unimplemented: Read pg3/06 (CONFIG3)', LOG_NET)\n return 0\n } else {\n dbg_log('Read pg' + pg + '/06', LOG_NET)\n dbg_assert(false)\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_TCNTHI,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log('Write tcnt high: ' + h(data_byte, 2), LOG_NET)\n this.tcnt = (this.tcnt & 0xff) | (data_byte << 8)\n } else if (pg === 1) {\n dbg_log('mac[5] = ' + h(data_byte), LOG_NET)\n this.mac[5] = data_byte\n } else if (pg === 3) {\n dbg_log(\n 'Unimplemented: Write pg3/06 (CONFIG3): ' +\n h(data_byte),\n LOG_NET,\n )\n } else {\n dbg_log('Write pg' + pg + '/06: ' + h(data_byte), LOG_NET)\n dbg_assert(false)\n }\n },\n )\n\n io.register_read(\n this.port | EN0_RSR,\n this,\n function (this: Ne2k): number {\n const pg = this.get_page()\n if (pg === 0) {\n return 1 | (1 << 3) // receive status ok\n } else if (pg === 1) {\n dbg_log('Read mar4', LOG_NET)\n return this.mar[4]\n } else {\n dbg_log('Unimplemented: Read pg' + pg + '/0c', LOG_NET)\n dbg_assert(false)\n return 0\n }\n },\n )\n\n io.register_write(\n this.port | EN0_RXCR,\n this,\n function (this: Ne2k, data_byte: number): void {\n const pg = this.get_page()\n if (pg === 0) {\n dbg_log(\n 'RX configuration reg write: ' + h(data_byte, 2),\n LOG_NET,\n )\n this.rxcr = data_byte\n } else {\n dbg_log(\n 'Unimplemented: Write pg' + pg + '/0c: ' + h(data_byte),\n LOG_NET,\n )\n }\n },\n )\n\n io.register_read(\n this.port | NE_DATAPORT | 0,\n this,\n this.data_port_read8,\n this.data_port_read16,\n this.data_port_read32,\n )\n io.register_write(\n this.port | NE_DATAPORT | 0,\n this,\n this.data_port_write16,\n this.data_port_write16,\n this.data_port_write32,\n )\n\n if (use_pci) {\n cpu.devices.pci.register_device(this)\n }\n }\n\n get_state(): (number | Uint8Array)[] {\n const state: (number | Uint8Array)[] = []\n\n state[0] = this.isr\n state[1] = this.imr\n state[2] = this.cr\n state[3] = this.dcfg\n state[4] = this.rcnt\n state[5] = this.tcnt\n state[6] = this.tpsr\n state[7] = this.rsar\n state[8] = this.pstart\n state[9] = this.curpg\n state[10] = this.boundary\n state[11] = this.pstop\n state[12] = this.rxcr\n state[13] = this.txcr\n state[14] = this.tsr\n state[15] = this.mac\n state[16] = this.memory\n\n return state\n }\n\n set_state(state: any[]): void {\n this.isr = state[0]\n this.imr = state[1]\n this.cr = state[2]\n this.dcfg = state[3]\n this.rcnt = state[4]\n this.tcnt = state[5]\n this.tpsr = state[6]\n this.rsar = state[7]\n this.pstart = state[8]\n this.curpg = state[9]\n this.boundary = state[10]\n this.pstop = state[11]\n this.rxcr = state[12]\n this.txcr = state[13]\n this.tsr = state[14]\n\n if (this.preserve_mac_from_state_image) {\n this.mac = state[15]\n this.memory = state[16]\n } else if (this.mac_address_translation) {\n this.mac_address_in_state = state[15]\n this.memory = state[16]\n\n dbg_log(\n 'Using mac address translation' +\n ' guest_os_mac=' +\n format_mac(this.mac_address_in_state!) +\n ' real_mac=' +\n format_mac(this.mac),\n LOG_NET,\n )\n }\n this.bus.send('net' + this.id + '-mac', format_mac(this.mac))\n }\n\n do_interrupt(ir_mask: number): void {\n dbg_log('Do interrupt ' + h(ir_mask, 2), LOG_NET)\n this.isr |= ir_mask\n this.update_irq()\n }\n\n update_irq(): void {\n if (this.imr & this.isr) {\n this.pci.raise_irq(this.pci_id)\n } else {\n this.pci.lower_irq(this.pci_id)\n }\n }\n\n data_port_write(data_byte: number): void {\n if (NE2K_LOG_VERBOSE) {\n dbg_log(\n 'Write data port: data=' +\n h(data_byte & 0xff, 2) +\n ' rsar=' +\n h(this.rsar, 4) +\n ' rcnt=' +\n h(this.rcnt, 4),\n LOG_NET,\n )\n }\n\n if (\n this.rsar <= 0x10 ||\n (this.rsar >= START_PAGE << 8 && this.rsar < STOP_PAGE << 8)\n ) {\n this.memory[this.rsar] = data_byte\n }\n\n this.rsar++\n this.rcnt--\n\n if (this.rsar >= this.pstop << 8) {\n this.rsar += (this.pstart - this.pstop) << 8\n }\n\n if (this.rcnt === 0) {\n this.do_interrupt(ENISR_RDC)\n }\n }\n\n data_port_write16(data: number): void {\n this.data_port_write(data)\n\n if (this.dcfg & 1) {\n this.data_port_write(data >> 8)\n }\n }\n\n data_port_write32(data: number): void {\n this.data_port_write(data)\n this.data_port_write(data >> 8)\n this.data_port_write(data >> 16)\n this.data_port_write(data >> 24)\n }\n\n data_port_read(): number {\n let data = 0\n\n if (this.rsar < STOP_PAGE << 8) {\n data = this.memory[this.rsar]\n }\n\n if (NE2K_LOG_VERBOSE) {\n dbg_log(\n 'Read data port: data=' +\n h(data, 2) +\n ' rsar=' +\n h(this.rsar, 4) +\n ' rcnt=' +\n h(this.rcnt, 4),\n LOG_NET,\n )\n }\n\n this.rsar++\n this.rcnt--\n\n if (this.rsar >= this.pstop << 8) {\n this.rsar += (this.pstart - this.pstop) << 8\n }\n\n if (this.rcnt === 0) {\n this.do_interrupt(ENISR_RDC)\n }\n\n return data\n }\n\n data_port_read8(): number {\n return this.data_port_read16() & 0xff\n }\n\n data_port_read16(): number {\n if (this.dcfg & 1) {\n return this.data_port_read() | (this.data_port_read() << 8)\n } else {\n return this.data_port_read()\n }\n }\n\n data_port_read32(): number {\n return (\n this.data_port_read() |\n (this.data_port_read() << 8) |\n (this.data_port_read() << 16) |\n (this.data_port_read() << 24)\n )\n }\n\n receive(data: Uint8Array): void {\n // called from the adapter when data is received over the network\n\n if (this.cr & 1) {\n // stop bit set\n return\n }\n\n if (NE2K_LOG_PACKETS) {\n dump_packet(data, 'receive')\n }\n\n this.bus.send('eth-receive-end', [data.length])\n\n if (this.rxcr & 0x10) {\n // promiscuous\n } else if (\n this.rxcr & 4 &&\n data[0] === 0xff &&\n data[1] === 0xff &&\n data[2] === 0xff &&\n data[3] === 0xff &&\n data[4] === 0xff &&\n data[5] === 0xff\n ) {\n // broadcast\n } else if (this.rxcr & 8 && (data[0] & 1) === 1) {\n // multicast\n // XXX\n return\n } else if (\n data[0] === this.mac[0] &&\n data[1] === this.mac[1] &&\n data[2] === this.mac[2] &&\n data[3] === this.mac[3] &&\n data[4] === this.mac[4] &&\n data[5] === this.mac[5]\n ) {\n // unicast match, intentionally empty\n } else {\n return\n }\n\n if (this.mac_address_in_state) {\n data = new Uint8Array(data) // make a copy\n translate_mac_address(data, this.mac, this.mac_address_in_state)\n }\n\n const packet_length = Math.max(60, data.length)\n\n const offset = this.curpg << 8\n const total_length = packet_length + 4\n const data_start = offset + 4\n let next = this.curpg + 1 + (total_length >> 8)\n\n const end = offset + total_length\n\n const needed = 1 + (total_length >> 8)\n\n // boundary == curpg interpreted as ringbuffer empty\n const available =\n this.boundary > this.curpg\n ? this.boundary - this.curpg\n : this.pstop - this.curpg + this.boundary - this.pstart\n\n if (\n available < needed &&\n this.boundary !== 0 // XXX: ReactOS sets this to 0 initially and never updates it unless it receives a packet\n ) {\n dbg_log(\n 'Buffer full, dropping packet pstart=' +\n h(this.pstart) +\n ' pstop=' +\n h(this.pstop) +\n ' curpg=' +\n h(this.curpg) +\n ' needed=' +\n h(needed) +\n ' boundary=' +\n h(this.boundary) +\n ' available=' +\n h(available),\n LOG_NET,\n )\n return\n }\n\n if (end > this.pstop << 8) {\n // Shouldn't happen because at this size it can't cross a page,\n // so we can skip filling with zeroes\n dbg_assert(data.length >= 60)\n\n const cut = (this.pstop << 8) - data_start\n dbg_assert(cut >= 0)\n\n this.memory.set(data.subarray(0, cut), data_start)\n this.memory.set(data.subarray(cut), this.pstart << 8)\n dbg_log('rcv cut=' + h(cut), LOG_NET)\n } else {\n this.memory.set(data, data_start)\n\n if (data.length < 60) {\n this.memory.fill(0, data_start + data.length, data_start + 60)\n }\n }\n\n if (next >= this.pstop) {\n next += this.pstart - this.pstop\n }\n\n // write packet header\n this.memory[offset] = ENRSR_RXOK // status\n this.memory[offset + 1] = next\n this.memory[offset + 2] = total_length\n this.memory[offset + 3] = total_length >> 8\n\n this.curpg = next\n\n dbg_log(\n 'rcv offset=' +\n h(offset) +\n ' len=' +\n h(total_length) +\n ' next=' +\n h(next),\n LOG_NET,\n )\n\n this.do_interrupt(ENISR_RX)\n }\n\n get_page(): number {\n return (this.cr >> 6) & 3\n }\n}\n", "declare let DEBUG: boolean\n\nimport { LOG_IO, MMAP_BLOCK_BITS, MMAP_BLOCK_SIZE, MMAP_MAX } from './const.js'\nimport { h } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\n\n// Enables logging all IO port reads and writes. Very verbose\nconst LOG_ALL_IO = false\n\ntype PortReadFn = (port: number) => number\ntype PortWriteFn = (port: number) => void\n\ninterface IOPortEntry {\n read8: PortReadFn\n read16: PortReadFn\n read32: PortReadFn\n write8: PortWriteFn\n write16: PortWriteFn\n write32: PortWriteFn\n device: IODevice | undefined\n}\n\ntype MmapReadFn = (addr: number) => number\ntype MmapWriteFn = (addr: number, value: number) => void\n\n// Minimal interface for the CPU fields IO needs\ninterface IOCpu {\n memory_size: Int32Array\n memory_map_read8: (MmapReadFn | undefined)[]\n memory_map_write8: (MmapWriteFn | undefined)[]\n memory_map_read32: (MmapReadFn | undefined)[]\n memory_map_write32: (MmapWriteFn | undefined)[]\n}\n\ninterface IODevice {\n name?: string\n}\n\nexport class IO {\n ports: IOPortEntry[]\n cpu: IOCpu\n\n constructor(cpu: IOCpu) {\n this.ports = []\n this.cpu = cpu\n\n for (let i = 0; i < 0x10000; i++) {\n this.ports[i] = this.create_empty_entry()\n }\n\n const memory_size = cpu.memory_size[0]\n\n for (let i = 0; i << MMAP_BLOCK_BITS < memory_size; i++) {\n // avoid sparse arrays\n cpu.memory_map_read8[i] = cpu.memory_map_write8[i] = undefined\n cpu.memory_map_read32[i] = cpu.memory_map_write32[i] = undefined\n }\n\n this.mmap_register(\n memory_size,\n MMAP_MAX - memory_size,\n function (addr) {\n // read outside of the memory size\n dbg_log(\n 'Read from unmapped memory space, addr=' + h(addr >>> 0, 8),\n LOG_IO,\n )\n return 0xff\n },\n function (addr, value) {\n // write outside of the memory size\n dbg_log(\n 'Write to unmapped memory space, addr=' +\n h(addr >>> 0, 8) +\n ' value=' +\n h(value, 2),\n LOG_IO,\n )\n },\n function (addr) {\n dbg_log(\n 'Read from unmapped memory space, addr=' + h(addr >>> 0, 8),\n LOG_IO,\n )\n return -1\n },\n function (addr, value) {\n dbg_log(\n 'Write to unmapped memory space, addr=' +\n h(addr >>> 0, 8) +\n ' value=' +\n h(value >>> 0, 8),\n LOG_IO,\n )\n },\n )\n }\n\n create_empty_entry(): IOPortEntry {\n return {\n read8: this.empty_port_read8,\n read16: this.empty_port_read16,\n read32: this.empty_port_read32,\n\n write8: this.empty_port_write,\n write16: this.empty_port_write,\n write32: this.empty_port_write,\n\n device: undefined,\n }\n }\n\n empty_port_read8(): number {\n return 0xff\n }\n\n empty_port_read16(): number {\n return 0xffff\n }\n\n empty_port_read32(): number {\n return -1\n }\n\n empty_port_write(_x: number): void {}\n\n register_read(\n port_addr: number,\n device: IODevice,\n r8?: PortReadFn,\n r16?: PortReadFn,\n r32?: PortReadFn,\n ): void {\n dbg_assert(typeof port_addr === 'number')\n dbg_assert(typeof device === 'object')\n dbg_assert(!r8 || typeof r8 === 'function')\n dbg_assert(!r16 || typeof r16 === 'function')\n dbg_assert(!r32 || typeof r32 === 'function')\n dbg_assert(!!(r8 || r16 || r32))\n\n if (DEBUG) {\n const fail = function (n: number): number {\n dbg_assert(\n false,\n 'Overlapped read' +\n n +\n ' ' +\n h(port_addr, 4) +\n ' (' +\n device.name +\n ')',\n )\n return (-1 >>> (32 - n)) | 0\n }\n if (!r8) r8 = fail.bind(this, 8)\n if (!r16) r16 = fail.bind(this, 16)\n if (!r32) r32 = fail.bind(this, 32)\n }\n\n if (r8) this.ports[port_addr].read8 = r8\n if (r16) this.ports[port_addr].read16 = r16\n if (r32) this.ports[port_addr].read32 = r32\n this.ports[port_addr].device = device\n }\n\n register_write(\n port_addr: number,\n device: IODevice,\n w8?: PortWriteFn,\n w16?: PortWriteFn,\n w32?: PortWriteFn,\n ): void {\n dbg_assert(typeof port_addr === 'number')\n dbg_assert(typeof device === 'object')\n dbg_assert(!w8 || typeof w8 === 'function')\n dbg_assert(!w16 || typeof w16 === 'function')\n dbg_assert(!w32 || typeof w32 === 'function')\n dbg_assert(!!(w8 || w16 || w32))\n\n if (DEBUG) {\n const fail = function (n: number): void {\n dbg_assert(\n false,\n 'Overlapped write' +\n n +\n ' ' +\n h(port_addr) +\n ' (' +\n device.name +\n ')',\n )\n }\n if (!w8) w8 = fail.bind(this, 8)\n if (!w16) w16 = fail.bind(this, 16)\n if (!w32) w32 = fail.bind(this, 32)\n }\n\n if (w8) this.ports[port_addr].write8 = w8\n if (w16) this.ports[port_addr].write16 = w16\n if (w32) this.ports[port_addr].write32 = w32\n this.ports[port_addr].device = device\n }\n\n // > Any two consecutive 8-bit ports can be treated as a 16-bit port;\n // > and four consecutive 8-bit ports can be treated as a 32-bit port\n // > http://css.csail.mit.edu/6.858/2012/readings/i386/s08_01.htm\n //\n // This info is not correct for all ports, but handled by the following functions\n //\n // Register the read of 2 or 4 consecutive 8-bit ports, 1 or 2 16-bit\n // ports and 0 or 1 32-bit ports\n register_read_consecutive(\n port_addr: number,\n device: IODevice,\n r8_1: PortReadFn,\n r8_2: PortReadFn,\n r8_3?: PortReadFn,\n r8_4?: PortReadFn,\n ): void {\n function r16_1(this: IODevice): number {\n return r8_1.call(this, 0) | (r8_2.call(this, 0) << 8)\n }\n function r16_2(this: IODevice): number {\n return r8_3!.call(this, 0) | (r8_4!.call(this, 0) << 8)\n }\n function r32(this: IODevice): number {\n return (\n r8_1.call(this, 0) |\n (r8_2.call(this, 0) << 8) |\n (r8_3!.call(this, 0) << 16) |\n (r8_4!.call(this, 0) << 24)\n )\n }\n\n if (r8_3 && r8_4) {\n this.register_read(port_addr, device, r8_1, r16_1, r32)\n this.register_read(port_addr + 1, device, r8_2)\n this.register_read(port_addr + 2, device, r8_3, r16_2)\n this.register_read(port_addr + 3, device, r8_4)\n } else {\n this.register_read(port_addr, device, r8_1, r16_1)\n this.register_read(port_addr + 1, device, r8_2)\n }\n }\n\n register_write_consecutive(\n port_addr: number,\n device: IODevice,\n w8_1: PortWriteFn,\n w8_2: PortWriteFn,\n w8_3?: PortWriteFn,\n w8_4?: PortWriteFn,\n ): void {\n function w16_1(this: IODevice, data: number): void {\n w8_1.call(this, data & 0xff)\n w8_2.call(this, (data >> 8) & 0xff)\n }\n function w16_2(this: IODevice, data: number): void {\n w8_3!.call(this, data & 0xff)\n w8_4!.call(this, (data >> 8) & 0xff)\n }\n function w32(this: IODevice, data: number): void {\n w8_1.call(this, data & 0xff)\n w8_2.call(this, (data >> 8) & 0xff)\n w8_3!.call(this, (data >> 16) & 0xff)\n w8_4!.call(this, data >>> 24)\n }\n\n if (w8_3 && w8_4) {\n this.register_write(port_addr, device, w8_1, w16_1, w32)\n this.register_write(port_addr + 1, device, w8_2)\n this.register_write(port_addr + 2, device, w8_3, w16_2)\n this.register_write(port_addr + 3, device, w8_4)\n } else {\n this.register_write(port_addr, device, w8_1, w16_1)\n this.register_write(port_addr + 1, device, w8_2)\n }\n }\n\n mmap_read32_shim(addr: number): number {\n const aligned_addr = addr >>> MMAP_BLOCK_BITS\n const fn = this.cpu.memory_map_read8[aligned_addr]!\n\n return (\n fn(addr) |\n (fn(addr + 1) << 8) |\n (fn(addr + 2) << 16) |\n (fn(addr + 3) << 24)\n )\n }\n\n mmap_write32_shim(addr: number, value: number): void {\n const aligned_addr = addr >>> MMAP_BLOCK_BITS\n const fn = this.cpu.memory_map_write8[aligned_addr]!\n\n fn(addr, value & 0xff)\n fn(addr + 1, (value >> 8) & 0xff)\n fn(addr + 2, (value >> 16) & 0xff)\n fn(addr + 3, value >>> 24)\n }\n\n mmap_register(\n addr: number,\n size: number,\n read_func8: MmapReadFn,\n write_func8: MmapWriteFn,\n read_func32?: MmapReadFn,\n write_func32?: MmapWriteFn,\n ): void {\n dbg_log(\n 'mmap_register addr=' + h(addr >>> 0, 8) + ' size=' + h(size, 8),\n LOG_IO,\n )\n\n dbg_assert((addr & (MMAP_BLOCK_SIZE - 1)) === 0)\n dbg_assert(size > 0 && (size & (MMAP_BLOCK_SIZE - 1)) === 0)\n\n if (!read_func32) read_func32 = this.mmap_read32_shim.bind(this)\n\n if (!write_func32) write_func32 = this.mmap_write32_shim.bind(this)\n\n let aligned_addr = addr >>> MMAP_BLOCK_BITS\n\n for (; size > 0; aligned_addr++) {\n this.cpu.memory_map_read8[aligned_addr] = read_func8\n this.cpu.memory_map_write8[aligned_addr] = write_func8\n this.cpu.memory_map_read32[aligned_addr] = read_func32\n this.cpu.memory_map_write32[aligned_addr] = write_func32\n\n size -= MMAP_BLOCK_SIZE\n }\n }\n\n port_write8(port_addr: number, data: number): void {\n const entry = this.ports[port_addr]\n\n if (entry.write8 === this.empty_port_write || LOG_ALL_IO) {\n dbg_log(\n 'write8 port #' +\n h(port_addr, 4) +\n ' <- ' +\n h(data, 2) +\n this.get_port_description(port_addr),\n LOG_IO,\n )\n }\n entry.write8.call(entry.device, data)\n }\n\n port_write16(port_addr: number, data: number): void {\n const entry = this.ports[port_addr]\n\n if (entry.write16 === this.empty_port_write || LOG_ALL_IO) {\n dbg_log(\n 'write16 port #' +\n h(port_addr, 4) +\n ' <- ' +\n h(data, 4) +\n this.get_port_description(port_addr),\n LOG_IO,\n )\n }\n entry.write16.call(entry.device, data)\n }\n\n port_write32(port_addr: number, data: number): void {\n const entry = this.ports[port_addr]\n\n if (entry.write32 === this.empty_port_write || LOG_ALL_IO) {\n dbg_log(\n 'write32 port #' +\n h(port_addr, 4) +\n ' <- ' +\n h(data >>> 0, 8) +\n this.get_port_description(port_addr),\n LOG_IO,\n )\n }\n entry.write32.call(entry.device, data)\n }\n\n port_read8(port_addr: number): number {\n const entry = this.ports[port_addr]\n\n if (entry.read8 === this.empty_port_read8 || LOG_ALL_IO) {\n dbg_log(\n 'read8 port #' +\n h(port_addr, 4) +\n this.get_port_description(port_addr),\n LOG_IO,\n )\n }\n const value = entry.read8.call(entry.device, port_addr)\n dbg_assert(typeof value === 'number')\n if (value < 0 || value >= 0x100)\n dbg_assert(\n false,\n '8 bit port returned large value: ' + h(port_addr),\n )\n return value\n }\n\n port_read16(port_addr: number): number {\n const entry = this.ports[port_addr]\n\n if (entry.read16 === this.empty_port_read16 || LOG_ALL_IO) {\n dbg_log(\n 'read16 port #' +\n h(port_addr, 4) +\n this.get_port_description(port_addr),\n LOG_IO,\n )\n }\n const value = entry.read16.call(entry.device, port_addr)\n dbg_assert(typeof value === 'number')\n if (value < 0 || value >= 0x10000)\n dbg_assert(\n false,\n '16 bit port returned large value: ' + h(port_addr),\n )\n return value\n }\n\n port_read32(port_addr: number): number {\n const entry = this.ports[port_addr]\n\n if (entry.read32 === this.empty_port_read32 || LOG_ALL_IO) {\n dbg_log(\n 'read32 port #' +\n h(port_addr, 4) +\n this.get_port_description(port_addr),\n LOG_IO,\n )\n }\n const value = entry.read32.call(entry.device, port_addr)\n dbg_assert((value | 0) === value)\n return value\n }\n\n get_port_description(addr: number): string {\n if (debug_port_list[addr]) {\n return ' (' + debug_port_list[addr] + ')'\n } else {\n return ''\n }\n }\n}\n\n// via seabios ioport.h\nconst debug_port_list: Record<number, string> = {\n 0x0004: 'PORT_DMA_ADDR_2',\n 0x0005: 'PORT_DMA_CNT_2',\n 0x000a: 'PORT_DMA1_MASK_REG',\n 0x000b: 'PORT_DMA1_MODE_REG',\n 0x000c: 'PORT_DMA1_CLEAR_FF_REG',\n 0x000d: 'PORT_DMA1_MASTER_CLEAR',\n 0x0020: 'PORT_PIC1_CMD',\n 0x0021: 'PORT_PIC1_DATA',\n 0x0040: 'PORT_PIT_COUNTER0',\n 0x0041: 'PORT_PIT_COUNTER1',\n 0x0042: 'PORT_PIT_COUNTER2',\n 0x0043: 'PORT_PIT_MODE',\n 0x0060: 'PORT_PS2_DATA',\n 0x0061: 'PORT_PS2_CTRLB',\n 0x0064: 'PORT_PS2_STATUS',\n 0x0070: 'PORT_CMOS_INDEX',\n 0x0071: 'PORT_CMOS_DATA',\n 0x0080: 'PORT_DIAG',\n 0x0081: 'PORT_DMA_PAGE_2',\n 0x0092: 'PORT_A20',\n 0x00a0: 'PORT_PIC2_CMD',\n 0x00a1: 'PORT_PIC2_DATA',\n 0x00b2: 'PORT_SMI_CMD',\n 0x00b3: 'PORT_SMI_STATUS',\n 0x00d4: 'PORT_DMA2_MASK_REG',\n 0x00d6: 'PORT_DMA2_MODE_REG',\n 0x00da: 'PORT_DMA2_MASTER_CLEAR',\n 0x00f0: 'PORT_MATH_CLEAR',\n 0x0170: 'PORT_ATA2_CMD_BASE',\n 0x01f0: 'PORT_ATA1_CMD_BASE',\n 0x0278: 'PORT_LPT2',\n 0x02e8: 'PORT_SERIAL4',\n 0x02f8: 'PORT_SERIAL2',\n 0x0374: 'PORT_ATA2_CTRL_BASE',\n 0x0378: 'PORT_LPT1',\n 0x03e8: 'PORT_SERIAL3',\n //0x03f4: \"PORT_ATA1_CTRL_BASE\",\n 0x03f0: 'PORT_FD_BASE',\n 0x03f2: 'PORT_FD_DOR',\n 0x03f4: 'PORT_FD_STATUS',\n 0x03f5: 'PORT_FD_DATA',\n 0x03f6: 'PORT_HD_DATA',\n 0x03f7: 'PORT_FD_DIR',\n 0x03f8: 'PORT_SERIAL1',\n 0x0cf8: 'PORT_PCI_CMD',\n 0x0cf9: 'PORT_PCI_REBOOT',\n 0x0cfc: 'PORT_PCI_DATA',\n 0x0402: 'PORT_BIOS_DEBUG',\n 0x0510: 'PORT_QEMU_CFG_CTL',\n 0x0511: 'PORT_QEMU_CFG_DATA',\n 0xb000: 'PORT_ACPI_PM_BASE',\n 0xb100: 'PORT_SMB_BASE',\n 0x8900: 'PORT_BIOS_APM',\n}\n", "declare let DEBUG: boolean\n\nimport { LOG_VIRTIO } from './const.js'\nimport { h, int_log2 } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\n\n// Minimal interface for the CPU fields VirtIO needs\ninterface VirtioCPU {\n io: VirtioIO\n devices: {\n pci: VirtioPCI\n net?: unknown\n }\n read16(addr: number): number\n read32s(addr: number): number\n write16(addr: number, value: number): void\n write32(addr: number, value: number): void\n read_blob(addr: number, length: number): Uint8Array\n write_blob(blob: Uint8Array, addr: number): void\n zero_memory(addr: number, length: number): void\n memory_size: Int32Array\n}\n\ninterface VirtioIO {\n register_read(\n port: number,\n device: object,\n r8?: ((port: number) => number) | undefined,\n r16?: ((port: number) => number) | undefined,\n r32?: ((port: number) => number) | undefined,\n ): void\n register_write(\n port: number,\n device: object,\n w8?: ((port: number) => void) | undefined,\n w16?: ((port: number) => void) | undefined,\n w32?: ((port: number) => void) | undefined,\n ): void\n}\n\ninterface VirtioPCI {\n register_device(device: VirtIO): void\n raise_irq(pci_id: number): void\n lower_irq(pci_id: number): void\n}\n\n// http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.html\n\nconst VIRTIO_PCI_VENDOR_ID = 0x1af4\n// Identifies vendor-specific PCI capability.\nconst VIRTIO_PCI_CAP_VENDOR = 0x09\n// Length (bytes) of VIRTIO_PCI_CAP linked list entry.\nconst VIRTIO_PCI_CAP_LENGTH = 16\n\n// Capability types.\n\nconst VIRTIO_PCI_CAP_COMMON_CFG = 1\nconst VIRTIO_PCI_CAP_NOTIFY_CFG = 2\nconst VIRTIO_PCI_CAP_ISR_CFG = 3\nconst VIRTIO_PCI_CAP_DEVICE_CFG = 4\nconst VIRTIO_PCI_CAP_PCI_CFG = 5\n\n// Status bits (device_status values).\n\nconst VIRTIO_STATUS_ACKNOWLEDGE = 1\nconst VIRTIO_STATUS_DRIVER = 2\nconst VIRTIO_STATUS_DRIVER_OK = 4\nconst VIRTIO_STATUS_FEATURES_OK = 8\nconst VIRTIO_STATUS_DEVICE_NEEDS_RESET = 64\nconst VIRTIO_STATUS_FAILED = 128\n\n// ISR bits (isr_status values).\n\nconst VIRTIO_ISR_QUEUE = 1\nconst VIRTIO_ISR_DEVICE_CFG = 2\n\n// Feature bits (bit positions).\n\nexport const VIRTIO_F_RING_INDIRECT_DESC = 28\nexport const VIRTIO_F_RING_EVENT_IDX = 29\nexport const VIRTIO_F_VERSION_1 = 32\n\n// Queue struct sizes.\n\n// Size (bytes) of the virtq_desc struct per queue size.\nconst VIRTQ_DESC_ENTRYSIZE = 16\n// Size (bytes) of the virtq_avail struct ignoring ring entries.\nconst _VIRTQ_AVAIL_BASESIZE = 6\n// Size (bytes) of the virtq_avail struct per queue size.\nconst VIRTQ_AVAIL_ENTRYSIZE = 2\n// Size (bytes) of the virtq_used struct ignoring ring entries.\nconst _VIRTQ_USED_BASESIZE = 6\n// Size (bytes) of the virtq_desc struct per queue size.\nconst VIRTQ_USED_ENTRYSIZE = 8\n// Mask for wrapping the idx field of the virtq_used struct so that the value\n// naturally overflows after 65535 (idx is a word).\nconst VIRTQ_IDX_MASK = 0xffff\n\n// Queue flags.\n\nconst VIRTQ_DESC_F_NEXT = 1\nconst VIRTQ_DESC_F_WRITE = 2\nconst VIRTQ_DESC_F_INDIRECT = 4\nconst VIRTQ_AVAIL_F_NO_INTERRUPT = 1\nconst _VIRTQ_USED_F_NO_NOTIFY = 1\n\n// TypeScript types.\n\nexport interface VirtIO_CapabilityStructEntry {\n bytes: number\n name: string\n read: () => number\n write: (data: number) => void\n}\n\nexport type VirtIO_CapabilityStruct = VirtIO_CapabilityStructEntry[]\n\nexport interface VirtIO_CapabilityInfo {\n type: number\n bar: number\n port: number\n use_mmio: boolean\n offset: number\n extra: Uint8Array\n struct: VirtIO_CapabilityStruct\n}\n\nexport interface VirtQueue_Options {\n size_supported: number\n notify_offset: number\n}\n\nexport interface VirtIO_CommonCapabilityOptions {\n initial_port: number\n queues: VirtQueue_Options[]\n features: number[]\n on_driver_ok: () => void\n}\n\nexport interface VirtIO_NotificationCapabilityOptions {\n initial_port: number\n single_handler: boolean\n handlers: ((queue_id: number) => void)[]\n}\n\nexport interface VirtIO_ISRCapabilityOptions {\n initial_port: number\n}\n\nexport interface VirtIO_DeviceSpecificCapabilityOptions {\n initial_port: number\n struct: VirtIO_CapabilityStruct\n}\n\nexport interface VirtIO_Options {\n name: string\n pci_id: number\n device_id: number\n subsystem_device_id: number\n common: VirtIO_CommonCapabilityOptions\n notification: VirtIO_NotificationCapabilityOptions\n isr_status: VirtIO_ISRCapabilityOptions\n device_specific?: VirtIO_DeviceSpecificCapabilityOptions\n}\n\ninterface VirtQueueDescriptor {\n addr_low: number\n addr_high: number\n len: number\n flags: number\n next: number\n}\n\nexport class VirtIO {\n cpu: VirtioCPU\n pci: VirtioPCI\n device_id: number\n pci_space: number[]\n pci_id: number\n pci_bars: { size: number }[]\n name: string\n device_feature_select: number\n driver_feature_select: number\n device_feature: Uint32Array\n driver_feature: Uint32Array\n features_ok: boolean\n device_status: number\n config_has_changed: boolean\n config_generation: number\n queues: VirtQueue[]\n queue_select: number\n queue_selected: VirtQueue | null\n isr_status: number\n\n constructor(cpu: VirtioCPU, options: VirtIO_Options) {\n this.cpu = cpu\n this.pci = cpu.devices.pci\n this.device_id = options.device_id\n\n this.pci_space = [\n // Vendor ID\n VIRTIO_PCI_VENDOR_ID & 0xff,\n VIRTIO_PCI_VENDOR_ID >> 8,\n // Device ID\n options.device_id & 0xff,\n options.device_id >> 8,\n // Command\n 0x07,\n 0x05,\n // Status - enable capabilities list\n 0x10,\n 0x00,\n // Revision ID\n 0x01,\n // Prof IF, Subclass, Class code\n 0x00,\n 0x02,\n 0x00,\n // Cache line size\n 0x00,\n // Latency Timer\n 0x00,\n // Header Type\n 0x00,\n // Built-in self test\n 0x00,\n // BAR0\n 0x01,\n 0xa8,\n 0x00,\n 0x00,\n // BAR1\n 0x00,\n 0x10,\n 0xbf,\n 0xfe,\n // BAR2\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n // BAR3\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n // BAR4\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n // BAR5\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n // CardBus CIS pointer\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n // Subsystem vendor ID\n VIRTIO_PCI_VENDOR_ID & 0xff,\n VIRTIO_PCI_VENDOR_ID >> 8,\n // Subsystem ID\n options.subsystem_device_id & 0xff,\n options.subsystem_device_id >> 8,\n // Expansion ROM base address\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n // Capabilities pointer\n 0x40,\n // Reserved\n 0x00,\n 0x00,\n 0x00,\n // Reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n // Interrupt line\n 0x00,\n // Interrupt pin\n 0x01,\n // Min grant\n 0x00,\n // Max latency\n 0x00,\n ]\n\n // Prevent sparse arrays by preallocating.\n this.pci_space = this.pci_space.concat(\n Array(256 - this.pci_space.length).fill(0),\n )\n // Remaining PCI space is appended by capabilities further below.\n\n this.pci_id = options.pci_id\n\n // PCI bars gets filled in by capabilities further below.\n this.pci_bars = []\n\n this.name = options.name\n\n // Feature bits grouped in dwords, dword selected by device_feature_select.\n this.device_feature_select = 0\n this.driver_feature_select = 0\n\n // Unspecified upper bound. Assume 4*32=128 bits.\n this.device_feature = new Uint32Array(4)\n this.driver_feature = new Uint32Array(4)\n for (const f of options.common.features) {\n dbg_assert(\n f >= 0,\n 'VirtIO device<' +\n this.name +\n '> feature bit numbers must be non-negative',\n )\n dbg_assert(\n f < 128,\n 'VirtIO device<' +\n this.name +\n '> feature bit numbers assumed less than 128 in implementation',\n )\n\n // Feature bits are grouped in 32 bits.\n this.device_feature[f >>> 5] |= 1 << (f & 0x1f)\n this.driver_feature[f >>> 5] |= 1 << (f & 0x1f)\n }\n\n dbg_assert(\n options.common.features.includes(VIRTIO_F_VERSION_1),\n 'VirtIO device<' +\n this.name +\n '> only non-transitional devices are supported',\n )\n\n // Indicates whether driver_feature bits is subset of device_feature bits.\n this.features_ok = true\n\n this.device_status = 0\n\n this.config_has_changed = false\n this.config_generation = 0\n\n this.queues = []\n for (const queue_options of options.common.queues) {\n this.queues.push(new VirtQueue(cpu, this, queue_options))\n }\n this.queue_select = 0\n this.queue_selected = this.queues[0]\n\n this.isr_status = 0\n\n // Verify notification options.\n if (DEBUG) {\n const offsets = new Set<number>()\n for (const offset of this.queues.map((q) => q.notify_offset)) {\n const effective_offset = options.notification.single_handler\n ? 0\n : offset\n offsets.add(effective_offset)\n dbg_assert(\n !!options.notification.handlers[effective_offset],\n 'VirtIO device<' +\n this.name +\n \"> every queue's notifier must exist\",\n )\n }\n for (const [\n index,\n handler,\n ] of options.notification.handlers.entries()) {\n dbg_assert(\n !handler || offsets.has(index),\n 'VirtIO device<' +\n this.name +\n '> no defined notify handler should be unused',\n )\n }\n }\n\n const capabilities: VirtIO_CapabilityInfo[] = []\n capabilities.push(this.create_common_capability(options.common))\n capabilities.push(\n this.create_notification_capability(options.notification),\n )\n capabilities.push(this.create_isr_capability(options.isr_status))\n if (options.device_specific) {\n capabilities.push(\n this.create_device_specific_capability(options.device_specific),\n )\n }\n this.init_capabilities(capabilities)\n\n cpu.devices.pci.register_device(this)\n this.reset()\n }\n\n create_common_capability(\n options: VirtIO_CommonCapabilityOptions,\n ): VirtIO_CapabilityInfo {\n return {\n type: VIRTIO_PCI_CAP_COMMON_CFG,\n bar: 0,\n port: options.initial_port,\n use_mmio: false,\n offset: 0,\n extra: new Uint8Array(0),\n struct: [\n {\n bytes: 4,\n name: 'device_feature_select',\n read: () => this.device_feature_select,\n write: (data: number) => {\n this.device_feature_select = data\n },\n },\n {\n bytes: 4,\n name: 'device_feature',\n read: () =>\n this.device_feature[this.device_feature_select] || 0,\n write: (_data: number) => {\n /* read only */\n },\n },\n {\n bytes: 4,\n name: 'driver_feature_select',\n read: () => this.driver_feature_select,\n write: (data: number) => {\n this.driver_feature_select = data\n },\n },\n {\n bytes: 4,\n name: 'driver_feature',\n read: () =>\n this.driver_feature[this.driver_feature_select] || 0,\n write: (data: number) => {\n const supported_feature =\n this.device_feature[this.driver_feature_select]\n\n if (\n this.driver_feature_select <\n this.driver_feature.length\n ) {\n // Note: only set subset of device_features is set.\n // Required in our implementation for is_feature_negotiated().\n this.driver_feature[this.driver_feature_select] =\n data & supported_feature\n }\n\n // Check that driver features is an inclusive subset of device features.\n const invalid_bits = data & ~supported_feature\n this.features_ok = this.features_ok && !invalid_bits\n },\n },\n {\n bytes: 2,\n name: 'msix_config',\n read: () => {\n dbg_log('No msi-x capability supported.', LOG_VIRTIO)\n return 0xffff\n },\n write: (_data: number) => {\n dbg_log('No msi-x capability supported.', LOG_VIRTIO)\n },\n },\n {\n bytes: 2,\n name: 'num_queues',\n read: () => this.queues.length,\n write: (_data: number) => {\n /* read only */\n },\n },\n {\n bytes: 1,\n name: 'device_status',\n read: () => this.device_status,\n write: (data: number) => {\n if (data === 0) {\n dbg_log(\n 'Reset device<' + this.name + '>',\n LOG_VIRTIO,\n )\n this.reset()\n } else if (data & VIRTIO_STATUS_FAILED) {\n dbg_log(\n 'Warning: Device<' +\n this.name +\n '> status failed',\n LOG_VIRTIO,\n )\n } else {\n dbg_log(\n 'Device<' +\n this.name +\n '> status: ' +\n (data & VIRTIO_STATUS_ACKNOWLEDGE\n ? 'ACKNOWLEDGE '\n : '') +\n (data & VIRTIO_STATUS_DRIVER\n ? 'DRIVER '\n : '') +\n (data & VIRTIO_STATUS_DRIVER_OK\n ? 'DRIVER_OK'\n : '') +\n (data & VIRTIO_STATUS_FEATURES_OK\n ? 'FEATURES_OK '\n : '') +\n (data & VIRTIO_STATUS_DEVICE_NEEDS_RESET\n ? 'DEVICE_NEEDS_RESET'\n : ''),\n LOG_VIRTIO,\n )\n }\n\n if (\n data &\n ~this.device_status &\n VIRTIO_STATUS_DRIVER_OK &&\n this.device_status &\n VIRTIO_STATUS_DEVICE_NEEDS_RESET\n ) {\n // We couldn't notify NEEDS_RESET earlier because DRIVER_OK was not set.\n // Now it has been set, notify now.\n this.notify_config_changes()\n }\n\n // Don't set FEATURES_OK if our device doesn't support requested features.\n if (!this.features_ok) {\n if (DEBUG && data & VIRTIO_STATUS_FEATURES_OK) {\n dbg_log('Removing FEATURES_OK', LOG_VIRTIO)\n }\n data &= ~VIRTIO_STATUS_FEATURES_OK\n }\n\n this.device_status = data\n\n if (\n data &\n ~this.device_status &\n VIRTIO_STATUS_DRIVER_OK\n ) {\n options.on_driver_ok()\n }\n },\n },\n {\n bytes: 1,\n name: 'config_generation',\n read: () => this.config_generation,\n write: (_data: number) => {\n /* read only */\n },\n },\n {\n bytes: 2,\n name: 'queue_select',\n read: () => this.queue_select,\n write: (data: number) => {\n this.queue_select = data\n\n if (this.queue_select < this.queues.length) {\n this.queue_selected = this.queues[this.queue_select]\n } else {\n // Allow queue_select >= num_queues.\n this.queue_selected = null\n // Drivers can then detect that the queue is not available\n // using the below fields.\n }\n },\n },\n {\n bytes: 2,\n name: 'queue_size',\n read: () =>\n this.queue_selected ? this.queue_selected.size : 0,\n write: (data: number) => {\n if (!this.queue_selected) {\n return\n }\n if (data & (data - 1)) {\n dbg_log(\n 'Warning: dev<' +\n this.name +\n '> ' +\n 'Given queue size was not a power of 2. ' +\n 'Rounding up to next power of 2.',\n LOG_VIRTIO,\n )\n data = 1 << (int_log2(data - 1) + 1)\n }\n if (data > this.queue_selected.size_supported) {\n dbg_log(\n 'Warning: dev<' +\n this.name +\n '> ' +\n 'Trying to set queue size greater than supported. ' +\n 'Clamping to supported size.',\n LOG_VIRTIO,\n )\n data = this.queue_selected.size_supported\n }\n this.queue_selected.set_size(data)\n },\n },\n {\n bytes: 2,\n name: 'queue_msix_vector',\n read: () => {\n dbg_log('No msi-x capability supported.', LOG_VIRTIO)\n return 0xffff\n },\n write: (_data: number) => {\n dbg_log('No msi-x capability supported.', LOG_VIRTIO)\n },\n },\n {\n bytes: 2,\n name: 'queue_enable',\n read: () =>\n this.queue_selected\n ? this.queue_selected.enabled\n ? 1\n : 0\n : 0,\n write: (data: number) => {\n if (!this.queue_selected) {\n return\n }\n if (data === 1) {\n if (this.queue_selected.is_configured()) {\n this.queue_selected.enable()\n } else {\n dbg_log(\n 'Driver bug: tried enabling unconfigured queue',\n LOG_VIRTIO,\n )\n }\n } else if (data === 0) {\n dbg_log(\n 'Driver bug: tried writing 0 to queue_enable',\n LOG_VIRTIO,\n )\n }\n },\n },\n {\n bytes: 2,\n name: 'queue_notify_off',\n read: () =>\n this.queue_selected\n ? this.queue_selected.notify_offset\n : 0,\n write: (_data: number) => {\n /* read only */\n },\n },\n {\n bytes: 4,\n name: 'queue_desc (low dword)',\n read: () =>\n this.queue_selected ? this.queue_selected.desc_addr : 0,\n write: (data: number) => {\n if (this.queue_selected)\n this.queue_selected.desc_addr = data\n },\n },\n {\n bytes: 4,\n name: 'queue_desc (high dword)',\n read: () => 0,\n write: (data: number) => {\n if (data !== 0)\n dbg_log(\n 'Warning: High dword of 64 bit queue_desc ignored:' +\n data,\n LOG_VIRTIO,\n )\n },\n },\n {\n bytes: 4,\n name: 'queue_avail (low dword)',\n read: () =>\n this.queue_selected\n ? this.queue_selected.avail_addr\n : 0,\n write: (data: number) => {\n if (this.queue_selected)\n this.queue_selected.avail_addr = data\n },\n },\n {\n bytes: 4,\n name: 'queue_avail (high dword)',\n read: () => 0,\n write: (data: number) => {\n if (data !== 0)\n dbg_log(\n 'Warning: High dword of 64 bit queue_avail ignored:' +\n data,\n LOG_VIRTIO,\n )\n },\n },\n {\n bytes: 4,\n name: 'queue_used (low dword)',\n read: () =>\n this.queue_selected ? this.queue_selected.used_addr : 0,\n write: (data: number) => {\n if (this.queue_selected)\n this.queue_selected.used_addr = data\n },\n },\n {\n bytes: 4,\n name: 'queue_used (high dword)',\n read: () => 0,\n write: (data: number) => {\n if (data !== 0)\n dbg_log(\n 'Warning: High dword of 64 bit queue_used ignored:' +\n data,\n LOG_VIRTIO,\n )\n },\n },\n ],\n }\n }\n\n create_notification_capability(\n options: VirtIO_NotificationCapabilityOptions,\n ): VirtIO_CapabilityInfo {\n const notify_struct: VirtIO_CapabilityStruct = []\n let notify_off_multiplier: number\n\n if (options.single_handler) {\n dbg_assert(\n options.handlers.length === 1,\n 'VirtIO device<' +\n this.name +\n '> too many notify handlers specified: expected single handler',\n )\n\n // Forces all queues to use the same address for notifying.\n notify_off_multiplier = 0\n } else {\n notify_off_multiplier = 2\n }\n\n for (const [i, handler] of options.handlers.entries()) {\n notify_struct.push({\n bytes: 2,\n name: 'notify' + i,\n read: () => 0xffff,\n write: handler || ((_data: number) => {}),\n })\n }\n\n return {\n type: VIRTIO_PCI_CAP_NOTIFY_CFG,\n bar: 1,\n port: options.initial_port,\n use_mmio: false,\n offset: 0,\n extra: new Uint8Array([\n notify_off_multiplier & 0xff,\n (notify_off_multiplier >> 8) & 0xff,\n (notify_off_multiplier >> 16) & 0xff,\n notify_off_multiplier >> 24,\n ]),\n struct: notify_struct,\n }\n }\n\n create_isr_capability(\n options: VirtIO_ISRCapabilityOptions,\n ): VirtIO_CapabilityInfo {\n return {\n type: VIRTIO_PCI_CAP_ISR_CFG,\n bar: 2,\n port: options.initial_port,\n use_mmio: false,\n offset: 0,\n extra: new Uint8Array(0),\n struct: [\n {\n bytes: 1,\n name: 'isr_status',\n read: () => {\n const isr_status = this.isr_status\n this.lower_irq()\n return isr_status\n },\n write: (_data: number) => {\n /* read only */\n },\n },\n ],\n }\n }\n\n create_device_specific_capability(\n options: VirtIO_DeviceSpecificCapabilityOptions,\n ): VirtIO_CapabilityInfo {\n dbg_assert(\n !(options.initial_port & 0x3),\n 'VirtIO device<' +\n this.name +\n '> device specific cap offset must be 4-byte aligned',\n )\n\n return {\n type: VIRTIO_PCI_CAP_DEVICE_CFG,\n bar: 3,\n port: options.initial_port,\n use_mmio: false,\n offset: 0,\n extra: new Uint8Array(0),\n struct: options.struct,\n }\n }\n\n // Writes capabilities into pci_space and hook up IO/MMIO handlers.\n // Call only within constructor.\n init_capabilities(capabilities: VirtIO_CapabilityInfo[]): void {\n // Next available offset for capabilities linked list.\n let cap_next = (this.pci_space[0x34] = 0x40)\n\n // Current offset.\n let cap_ptr = cap_next\n\n for (const cap of capabilities) {\n const cap_len = VIRTIO_PCI_CAP_LENGTH + cap.extra.length\n\n cap_ptr = cap_next\n cap_next = cap_ptr + cap_len\n\n dbg_assert(\n cap_next <= 256,\n 'VirtIO device<' +\n this.name +\n \"> can't fit all capabilities into 256byte configspace\",\n )\n\n dbg_assert(\n 0 <= cap.bar && cap.bar < 6,\n 'VirtIO device<' +\n this.name +\n '> capability invalid bar number',\n )\n\n let bar_size = cap.struct.reduce(\n (bytes, field) => bytes + field.bytes,\n 0,\n )\n bar_size += cap.offset\n\n // Round up to next power of 2,\n // Minimum 16 bytes for its size to be detectable in general (esp. mmio).\n bar_size = bar_size < 16 ? 16 : 1 << (int_log2(bar_size - 1) + 1)\n\n dbg_assert(\n (cap.port & (bar_size - 1)) === 0,\n 'VirtIO device<' +\n this.name +\n '> capability port should be aligned to pci bar size',\n )\n\n this.pci_bars[cap.bar] = {\n size: bar_size,\n }\n\n this.pci_space[cap_ptr] = VIRTIO_PCI_CAP_VENDOR\n this.pci_space[cap_ptr + 1] = cap_next\n this.pci_space[cap_ptr + 2] = cap_len\n this.pci_space[cap_ptr + 3] = cap.type\n this.pci_space[cap_ptr + 4] = cap.bar\n\n this.pci_space[cap_ptr + 5] = 0 // Padding.\n this.pci_space[cap_ptr + 6] = 0 // Padding.\n this.pci_space[cap_ptr + 7] = 0 // Padding.\n\n this.pci_space[cap_ptr + 8] = cap.offset & 0xff\n this.pci_space[cap_ptr + 9] = (cap.offset >>> 8) & 0xff\n this.pci_space[cap_ptr + 10] = (cap.offset >>> 16) & 0xff\n this.pci_space[cap_ptr + 11] = cap.offset >>> 24\n\n this.pci_space[cap_ptr + 12] = bar_size & 0xff\n this.pci_space[cap_ptr + 13] = (bar_size >>> 8) & 0xff\n this.pci_space[cap_ptr + 14] = (bar_size >>> 16) & 0xff\n this.pci_space[cap_ptr + 15] = bar_size >>> 24\n\n for (const [i, extra_byte] of cap.extra.entries()) {\n this.pci_space[cap_ptr + 16 + i] = extra_byte\n }\n\n const bar_offset = 0x10 + 4 * cap.bar\n this.pci_space[bar_offset] = (cap.port & 0xfe) | +!cap.use_mmio\n this.pci_space[bar_offset + 1] = (cap.port >>> 8) & 0xff\n this.pci_space[bar_offset + 2] = (cap.port >>> 16) & 0xff\n this.pci_space[bar_offset + 3] = (cap.port >>> 24) & 0xff\n\n let port = cap.port + cap.offset\n\n for (const field of cap.struct) {\n let read: (...args: any[]) => number = field.read\n let write: (...args: any[]) => void = field.write\n\n if (DEBUG) {\n read = () => {\n const val = field.read()\n\n dbg_log(\n 'Device<' +\n this.name +\n '> ' +\n 'cap[' +\n cap.type +\n '] ' +\n 'read[' +\n field.name +\n '] ' +\n '=> ' +\n h(val, field.bytes * 8),\n LOG_VIRTIO,\n )\n\n return val\n }\n write = (data: number) => {\n dbg_log(\n 'Device<' +\n this.name +\n '> ' +\n 'cap[' +\n cap.type +\n '] ' +\n 'write[' +\n field.name +\n '] ' +\n '<= ' +\n h(data, field.bytes * 8),\n LOG_VIRTIO,\n )\n\n field.write(data)\n }\n }\n\n if (cap.use_mmio) {\n dbg_assert(\n false,\n 'VirtIO device <' +\n this.name +\n '> mmio capability not implemented.',\n )\n } else {\n // DSL (2.4 kernel) does these reads\n const shim_read8_on_16 = function (addr: number): number {\n dbg_log(\n 'Warning: 8-bit read from 16-bit virtio port',\n LOG_VIRTIO,\n )\n return (read(addr & ~1) >> ((addr & 1) << 3)) & 0xff\n }\n const shim_read8_on_32 = function (addr: number): number {\n dbg_log(\n 'Warning: 8-bit read from 32-bit virtio port',\n LOG_VIRTIO,\n )\n return (read(addr & ~3) >> ((addr & 3) << 3)) & 0xff\n }\n\n // archhurd does these reads\n const shim_read32_on_16 = function (addr: number): number {\n dbg_log(\n 'Warning: 32-bit read from 16-bit virtio port',\n LOG_VIRTIO,\n )\n return read(addr)\n }\n\n switch (field.bytes) {\n case 4:\n this.cpu.io.register_read(\n port,\n this,\n shim_read8_on_32,\n undefined,\n read,\n )\n this.cpu.io.register_read(\n port + 1,\n this,\n shim_read8_on_32,\n )\n this.cpu.io.register_read(\n port + 2,\n this,\n shim_read8_on_32,\n )\n this.cpu.io.register_read(\n port + 3,\n this,\n shim_read8_on_32,\n )\n this.cpu.io.register_write(\n port,\n this,\n undefined,\n undefined,\n write,\n )\n break\n case 2:\n this.cpu.io.register_read(\n port,\n this,\n shim_read8_on_16,\n read,\n shim_read32_on_16,\n )\n this.cpu.io.register_read(\n port + 1,\n this,\n shim_read8_on_16,\n )\n this.cpu.io.register_write(\n port,\n this,\n undefined,\n write,\n )\n break\n case 1:\n this.cpu.io.register_read(port, this, read)\n this.cpu.io.register_write(port, this, write)\n break\n default:\n dbg_assert(\n false,\n 'VirtIO device <' +\n this.name +\n '> invalid capability field width of ' +\n field.bytes +\n ' bytes',\n )\n break\n }\n }\n\n port += field.bytes\n }\n }\n\n // Terminate linked list with the pci config access capability.\n\n const cap_len = VIRTIO_PCI_CAP_LENGTH + 4\n dbg_assert(\n cap_next + cap_len <= 256,\n 'VirtIO device<' +\n this.name +\n \"> can't fit all capabilities into 256byte configspace\",\n )\n this.pci_space[cap_next] = VIRTIO_PCI_CAP_VENDOR\n this.pci_space[cap_next + 1] = 0 // cap next (null terminator)\n this.pci_space[cap_next + 2] = cap_len\n this.pci_space[cap_next + 3] = VIRTIO_PCI_CAP_PCI_CFG // cap type\n this.pci_space[cap_next + 4] = 0 // bar (written by device)\n this.pci_space[cap_next + 5] = 0 // Padding.\n this.pci_space[cap_next + 6] = 0 // Padding.\n this.pci_space[cap_next + 7] = 0 // Padding.\n\n // Remaining fields are configured by driver when needed.\n\n // offset\n this.pci_space[cap_next + 8] = 0\n this.pci_space[cap_next + 9] = 0\n this.pci_space[cap_next + 10] = 0\n this.pci_space[cap_next + 11] = 0\n\n // bar size\n this.pci_space[cap_next + 12] = 0\n this.pci_space[cap_next + 13] = 0\n this.pci_space[cap_next + 14] = 0\n this.pci_space[cap_next + 15] = 0\n\n // cfg_data\n this.pci_space[cap_next + 16] = 0\n this.pci_space[cap_next + 17] = 0\n this.pci_space[cap_next + 18] = 0\n this.pci_space[cap_next + 19] = 0\n\n //\n // TODO\n // The pci config access capability is required by spec, but so far, devices\n // seem to work well without it.\n // This capability provides a cfg_data field (at cap_next + 16 for 4 bytes)\n // that acts like a window to the previous bars. The driver writes the bar number,\n // offset, and length values in this capability, and the cfg_data field should\n // mirror the data referred by the bar, offset and length. Here, length can be\n // 1, 2, or 4.\n //\n // This requires some sort of pci devicespace read and write handlers.\n }\n\n get_state(): any[] {\n let state: any[] = []\n\n state[0] = this.device_feature_select\n state[1] = this.driver_feature_select\n state[2] = this.device_feature\n state[3] = this.driver_feature\n state[4] = this.features_ok\n state[5] = this.device_status\n state[6] = this.config_has_changed\n state[7] = this.config_generation\n state[8] = this.isr_status\n state[9] = this.queue_select\n state = state.concat(this.queues)\n\n return state\n }\n\n set_state(state: any[]): void {\n this.device_feature_select = state[0]\n this.driver_feature_select = state[1]\n this.device_feature = state[2]\n this.driver_feature = state[3]\n this.features_ok = state[4]\n this.device_status = state[5]\n this.config_has_changed = state[6]\n this.config_generation = state[7]\n this.isr_status = state[8]\n this.queue_select = state[9]\n let i = 0\n for (const queue of state.slice(10)) {\n this.queues[i].set_state(queue)\n i++\n }\n this.queue_selected = this.queues[this.queue_select] || null\n }\n\n reset(): void {\n this.device_feature_select = 0\n this.driver_feature_select = 0\n this.driver_feature.set(this.device_feature)\n\n this.features_ok = true\n this.device_status = 0\n\n this.queue_select = 0\n this.queue_selected = this.queues[0]\n\n for (const queue of this.queues) {\n queue.reset()\n }\n\n this.config_has_changed = false\n this.config_generation = 0\n\n this.lower_irq()\n }\n\n // Call this when device-specific configuration state changes.\n // Also called when status DEVICE_NEEDS_RESET is set.\n notify_config_changes(): void {\n this.config_has_changed = true\n\n if (this.device_status & VIRTIO_STATUS_DRIVER_OK) {\n this.raise_irq(VIRTIO_ISR_DEVICE_CFG)\n } else {\n dbg_assert(\n false,\n 'VirtIO device<' +\n this.name +\n '> attempted to notify driver before DRIVER_OK',\n )\n }\n }\n\n // To be called after reading any field whose write can trigger notify_config_changes().\n update_config_generation(): void {\n if (this.config_has_changed) {\n this.config_generation++\n this.config_generation &= 0xff\n this.config_has_changed = false\n }\n }\n\n is_feature_negotiated(feature: number): boolean {\n // Feature bits are grouped in 32 bits.\n // Note: earlier we chose not to set invalid features into driver_feature.\n return (\n (this.driver_feature[feature >>> 5] & (1 << (feature & 0x1f))) > 0\n )\n }\n\n // Call this if an irrecoverable error has occurred.\n // Notifies driver if DRIVER_OK, or when DRIVER_OK gets set.\n needs_reset(): void {\n dbg_log(\n 'Device<' + this.name + '> experienced error - requires reset',\n LOG_VIRTIO,\n )\n this.device_status |= VIRTIO_STATUS_DEVICE_NEEDS_RESET\n\n if (this.device_status & VIRTIO_STATUS_DRIVER_OK) {\n this.notify_config_changes()\n }\n }\n\n raise_irq(type: number): void {\n dbg_log('Raise irq ' + h(type), LOG_VIRTIO)\n this.isr_status |= type\n this.pci.raise_irq(this.pci_id)\n }\n\n lower_irq(): void {\n dbg_log('Lower irq ', LOG_VIRTIO)\n this.isr_status = 0\n this.pci.lower_irq(this.pci_id)\n }\n}\n\nexport class VirtQueue {\n cpu: VirtioCPU\n virtio: VirtIO\n size: number\n size_supported: number\n mask: number\n enabled: boolean\n notify_offset: number\n desc_addr: number\n avail_addr: number\n avail_last_idx: number\n used_addr: number\n num_staged_replies: number\n fix_wrapping: boolean\n\n constructor(cpu: VirtioCPU, virtio: VirtIO, options: VirtQueue_Options) {\n this.cpu = cpu\n this.virtio = virtio\n\n // Number of entries.\n this.size = options.size_supported\n this.size_supported = options.size_supported\n this.mask = this.size - 1\n this.enabled = false\n this.notify_offset = options.notify_offset\n\n this.desc_addr = 0\n\n this.avail_addr = 0\n this.avail_last_idx = 0\n\n this.used_addr = 0\n this.num_staged_replies = 0\n\n this.fix_wrapping = false\n\n this.reset()\n }\n\n get_state(): any[] {\n const state: any[] = []\n\n state[0] = this.size\n state[1] = this.size_supported\n state[2] = this.enabled\n state[3] = this.notify_offset\n state[4] = this.desc_addr\n state[5] = this.avail_addr\n state[6] = this.avail_last_idx\n state[7] = this.used_addr\n state[8] = this.num_staged_replies\n state[9] = 1\n\n return state\n }\n\n set_state(state: any[]): void {\n this.size = state[0]\n this.size_supported = state[1]\n this.enabled = state[2]\n this.notify_offset = state[3]\n this.desc_addr = state[4]\n this.avail_addr = state[5]\n this.avail_last_idx = state[6]\n this.used_addr = state[7]\n this.num_staged_replies = state[8]\n\n this.mask = this.size - 1\n this.fix_wrapping = state[9] !== 1\n }\n\n reset(): void {\n this.enabled = false\n this.desc_addr = 0\n this.avail_addr = 0\n this.avail_last_idx = 0\n this.used_addr = 0\n this.num_staged_replies = 0\n this.set_size(this.size_supported)\n }\n\n is_configured(): boolean {\n return !!(this.desc_addr && this.avail_addr && this.used_addr)\n }\n\n enable(): void {\n dbg_assert(\n this.is_configured(),\n 'VirtQueue must be configured before enabled',\n )\n this.enabled = true\n }\n\n set_size(size: number): void {\n dbg_assert(\n (size & (size - 1)) === 0,\n 'VirtQueue size must be power of 2 or zero',\n )\n dbg_assert(\n size <= this.size_supported,\n 'VirtQueue size must be within supported size',\n )\n this.size = size\n this.mask = size - 1\n }\n\n count_requests(): number {\n dbg_assert(\n !!this.avail_addr,\n 'VirtQueue addresses must be configured before use',\n )\n if (this.fix_wrapping) {\n this.fix_wrapping = false\n this.avail_last_idx =\n (this.avail_get_idx() & ~this.mask) +\n (this.avail_last_idx & this.mask)\n }\n return (this.avail_get_idx() - this.avail_last_idx) & 0xffff\n }\n\n has_request(): boolean {\n dbg_assert(\n !!this.avail_addr,\n 'VirtQueue addresses must be configured before use',\n )\n return this.count_requests() !== 0\n }\n\n pop_request(): VirtQueueBufferChain {\n dbg_assert(\n !!this.avail_addr,\n 'VirtQueue addresses must be configured before use',\n )\n dbg_assert(\n this.has_request(),\n 'VirtQueue must not pop nonexistent request',\n )\n\n const desc_idx = this.avail_get_entry(this.avail_last_idx)\n dbg_log(\n 'Pop request: avail_last_idx=' +\n this.avail_last_idx +\n ' desc_idx=' +\n desc_idx,\n LOG_VIRTIO,\n )\n\n const bufchain = new VirtQueueBufferChain(this, desc_idx)\n\n this.avail_last_idx = (this.avail_last_idx + 1) & 0xffff\n\n return bufchain\n }\n\n // Stage a buffer chain into the used ring.\n // Can call push_reply many times before flushing to batch replies together.\n // Note: this reply is not visible to driver until flush_replies is called.\n push_reply(bufchain: VirtQueueBufferChain): void {\n dbg_assert(\n !!this.used_addr,\n 'VirtQueue addresses must be configured before use',\n )\n dbg_assert(\n this.num_staged_replies < this.size,\n 'VirtQueue replies must not exceed queue size',\n )\n\n const used_idx =\n (this.used_get_idx() + this.num_staged_replies) & this.mask\n dbg_log(\n 'Push reply: used_idx=' +\n used_idx +\n ' desc_idx=' +\n bufchain.head_idx,\n LOG_VIRTIO,\n )\n\n this.used_set_entry(\n used_idx,\n bufchain.head_idx,\n bufchain.length_written,\n )\n this.num_staged_replies++\n }\n\n // Makes replies visible to driver by updating the used ring idx and\n // firing appropriate interrupt if needed.\n flush_replies(): void {\n dbg_assert(\n !!this.used_addr,\n 'VirtQueue addresses must be configured before use',\n )\n\n if (this.num_staged_replies === 0) {\n dbg_log('flush_replies: Nothing to flush', LOG_VIRTIO)\n return\n }\n\n dbg_log('Flushing ' + this.num_staged_replies + ' replies', LOG_VIRTIO)\n const old_idx = this.used_get_idx()\n const new_idx = (old_idx + this.num_staged_replies) & VIRTQ_IDX_MASK\n this.used_set_idx(new_idx)\n\n this.num_staged_replies = 0\n\n if (this.virtio.is_feature_negotiated(VIRTIO_F_RING_EVENT_IDX)) {\n const used_event = this.avail_get_used_event()\n\n // Fire irq when idx values associated with the pushed reply buffers\n // has reached or gone past used_event.\n let _has_passed = old_idx <= used_event && used_event < new_idx\n\n // Has overflowed? Assumes num_staged_replies > 0.\n if (new_idx <= old_idx) {\n _has_passed = used_event < new_idx || old_idx <= used_event\n }\n\n // Commented out: Workaround for sometimes loading from the filesystem hangs and the emulator stays idle\n //if(has_passed)\n {\n this.virtio.raise_irq(VIRTIO_ISR_QUEUE)\n }\n } else {\n if (~this.avail_get_flags() & VIRTQ_AVAIL_F_NO_INTERRUPT) {\n this.virtio.raise_irq(VIRTIO_ISR_QUEUE)\n }\n }\n }\n\n // If using VIRTIO_F_RING_EVENT_IDX, device must tell driver when\n // to get notifications or else driver won't notify regularly.\n // If not using VIRTIO_F_RING_EVENT_IDX, driver will ignore avail_event\n // and notify every request regardless unless NO_NOTIFY is set (TODO implement when needed).\n notify_me_after(num_skipped_requests: number): void {\n dbg_assert(\n num_skipped_requests >= 0,\n 'Must skip a non-negative number of requests',\n )\n\n // The 16 bit idx field wraps around after 2^16.\n const avail_event =\n (this.avail_get_idx() + num_skipped_requests) & 0xffff\n this.used_set_avail_event(avail_event)\n }\n\n get_descriptor(table_address: number, i: number): VirtQueueDescriptor {\n return {\n addr_low: this.cpu.read32s(\n table_address + i * VIRTQ_DESC_ENTRYSIZE,\n ),\n addr_high: this.cpu.read32s(\n table_address + i * VIRTQ_DESC_ENTRYSIZE + 4,\n ),\n len: this.cpu.read32s(table_address + i * VIRTQ_DESC_ENTRYSIZE + 8),\n flags: this.cpu.read16(\n table_address + i * VIRTQ_DESC_ENTRYSIZE + 12,\n ),\n next: this.cpu.read16(\n table_address + i * VIRTQ_DESC_ENTRYSIZE + 14,\n ),\n }\n }\n\n // Avail ring fields\n\n avail_get_flags(): number {\n return this.cpu.read16(this.avail_addr)\n }\n\n avail_get_idx(): number {\n return this.cpu.read16(this.avail_addr + 2)\n }\n\n avail_get_entry(i: number): number {\n return this.cpu.read16(\n this.avail_addr + 4 + VIRTQ_AVAIL_ENTRYSIZE * (i & this.mask),\n )\n }\n\n avail_get_used_event(): number {\n return this.cpu.read16(\n this.avail_addr + 4 + VIRTQ_AVAIL_ENTRYSIZE * this.size,\n )\n }\n\n // Used ring fields\n\n used_get_flags(): number {\n return this.cpu.read16(this.used_addr)\n }\n\n used_set_flags(value: number): void {\n this.cpu.write16(this.used_addr, value)\n }\n\n used_get_idx(): number {\n return this.cpu.read16(this.used_addr + 2)\n }\n\n used_set_idx(value: number): void {\n this.cpu.write16(this.used_addr + 2, value)\n }\n\n used_set_entry(i: number, desc_idx: number, length_written: number): void {\n this.cpu.write32(\n this.used_addr + 4 + VIRTQ_USED_ENTRYSIZE * i,\n desc_idx,\n )\n this.cpu.write32(\n this.used_addr + 8 + VIRTQ_USED_ENTRYSIZE * i,\n length_written,\n )\n }\n\n used_set_avail_event(value: number): void {\n this.cpu.write16(\n this.used_addr + 4 + VIRTQ_USED_ENTRYSIZE * this.size,\n value,\n )\n }\n}\n\n// Traverses through descriptor chain starting at head_id.\n// Provides means to read/write to buffers represented by the descriptors.\nexport class VirtQueueBufferChain {\n cpu: VirtioCPU\n virtio: VirtIO\n head_idx: number\n read_buffers: VirtQueueDescriptor[]\n read_buffer_idx: number\n read_buffer_offset: number\n length_readable: number\n write_buffers: VirtQueueDescriptor[]\n write_buffer_idx: number\n write_buffer_offset: number\n length_written: number\n length_writable: number\n\n constructor(virtqueue: VirtQueue, head_idx: number) {\n this.cpu = virtqueue.cpu\n this.virtio = virtqueue.virtio\n\n this.head_idx = head_idx\n\n this.read_buffers = []\n // Pointers for sequential consumption via get_next_blob.\n this.read_buffer_idx = 0\n this.read_buffer_offset = 0\n this.length_readable = 0\n\n this.write_buffers = []\n // Pointers for sequential write via set_next_blob.\n this.write_buffer_idx = 0\n this.write_buffer_offset = 0\n this.length_written = 0\n this.length_writable = 0\n\n // Traverse chain to discover buffers.\n // - There shouldn't be an excessive amount of descriptor elements.\n let table_address = virtqueue.desc_addr\n let desc_idx = head_idx\n let chain_length = 0\n let chain_max = virtqueue.size\n let writable_region = false\n const has_indirect_feature = this.virtio.is_feature_negotiated(\n VIRTIO_F_RING_INDIRECT_DESC,\n )\n dbg_log('<<< Descriptor chain start', LOG_VIRTIO)\n do {\n const desc = virtqueue.get_descriptor(table_address, desc_idx)\n\n dbg_log(\n 'descriptor: idx=' +\n desc_idx +\n ' addr=' +\n h(desc.addr_high, 8) +\n ':' +\n h(desc.addr_low, 8) +\n ' len=' +\n h(desc.len, 8) +\n ' flags=' +\n h(desc.flags, 4) +\n ' next=' +\n h(desc.next, 4),\n LOG_VIRTIO,\n )\n\n if (has_indirect_feature && desc.flags & VIRTQ_DESC_F_INDIRECT) {\n if (DEBUG && desc.flags & VIRTQ_DESC_F_NEXT) {\n dbg_log(\n 'Driver bug: has set VIRTQ_DESC_F_NEXT flag in an indirect table descriptor',\n LOG_VIRTIO,\n )\n }\n\n // Carry on using indirect table, starting at first entry.\n table_address = desc.addr_low\n desc_idx = 0\n chain_length = 0\n chain_max = desc.len / VIRTQ_DESC_ENTRYSIZE\n dbg_log('start indirect', LOG_VIRTIO)\n continue\n }\n\n if (desc.flags & VIRTQ_DESC_F_WRITE) {\n writable_region = true\n this.write_buffers.push(desc)\n this.length_writable += desc.len\n } else {\n if (writable_region) {\n dbg_log(\n 'Driver bug: readonly buffer after writeonly buffer within chain',\n LOG_VIRTIO,\n )\n break\n }\n this.read_buffers.push(desc)\n this.length_readable += desc.len\n }\n\n chain_length++\n if (chain_length > chain_max) {\n dbg_log(\n 'Driver bug: descriptor chain cycle detected',\n LOG_VIRTIO,\n )\n break\n }\n\n if (desc.flags & VIRTQ_DESC_F_NEXT) {\n desc_idx = desc.next\n } else {\n break\n }\n // eslint-disable-next-line no-constant-condition\n } while (true)\n dbg_log('Descriptor chain end >>>', LOG_VIRTIO)\n }\n\n // Reads the next blob of memory represented by the buffer chain into dest_buffer.\n get_next_blob(dest_buffer: Uint8Array): number {\n let dest_offset = 0\n let remaining = dest_buffer.length\n\n while (remaining) {\n if (this.read_buffer_idx === this.read_buffers.length) {\n dbg_log(\n 'Device<' +\n this.virtio.name +\n '> Read more than device-readable buffers has',\n LOG_VIRTIO,\n )\n break\n }\n\n const buf = this.read_buffers[this.read_buffer_idx]\n const read_address = buf.addr_low + this.read_buffer_offset\n let read_length = buf.len - this.read_buffer_offset\n\n if (read_length > remaining) {\n read_length = remaining\n this.read_buffer_offset += remaining\n } else {\n this.read_buffer_idx++\n this.read_buffer_offset = 0\n }\n\n dest_buffer.set(\n this.cpu.read_blob(read_address, read_length),\n dest_offset,\n )\n\n dest_offset += read_length\n remaining -= read_length\n }\n\n return dest_offset\n }\n\n // Appends contents of src_buffer into the memory represented by the buffer chain.\n set_next_blob(src_buffer: Uint8Array): number {\n let src_offset = 0\n let remaining = src_buffer.length\n\n while (remaining) {\n if (this.write_buffer_idx === this.write_buffers.length) {\n dbg_log(\n 'Device<' +\n this.virtio.name +\n '> Write more than device-writable capacity',\n LOG_VIRTIO,\n )\n break\n }\n\n const buf = this.write_buffers[this.write_buffer_idx]\n const write_address = buf.addr_low + this.write_buffer_offset\n let write_length = buf.len - this.write_buffer_offset\n\n if (write_length > remaining) {\n write_length = remaining\n this.write_buffer_offset += remaining\n } else {\n this.write_buffer_idx++\n this.write_buffer_offset = 0\n }\n\n const src_end = src_offset + write_length\n this.cpu.write_blob(\n src_buffer.subarray(src_offset, src_end),\n write_address,\n )\n\n src_offset += write_length\n remaining -= write_length\n }\n\n this.length_written += src_offset\n return src_offset\n }\n}\n", "// -------------------------------------------------\n// ------------------ Marshall ---------------------\n// -------------------------------------------------\n// helper functions for virtio and 9p.\n\nimport { dbg_log } from './../src/log.js'\n\nconst textde = new TextDecoder()\nconst texten = new TextEncoder()\n\n// QID structure used in the 9P protocol.\nexport interface QID {\n type: number\n version: number\n path: number\n}\n\n// Tracks the current read offset during unmarshalling.\nexport interface MarshallState {\n offset: number\n}\n\n// Type codes used by Marshall/Unmarshall:\n// 'w' = word (4 bytes), 'd' = double word (8 bytes, only low 32 bits written),\n// 'h' = half word (2 bytes), 'b' = byte, 's' = length-prefixed string, 'Q' = QID (13 bytes).\nexport type MarshallTypeCode = 'w' | 'd' | 'h' | 'b' | 's' | 'Q'\n\ntype MarshallInput = any\n\n// Inserts data from an array to a byte aligned struct in memory\nexport function Marshall(\n typelist: MarshallTypeCode[],\n input: MarshallInput[],\n struct: Uint8Array,\n offset: number,\n): number {\n let item: MarshallInput\n let size = 0\n for (let i = 0; i < typelist.length; i++) {\n item = input[i]\n switch (typelist[i]) {\n case 'w':\n struct[offset++] = item & 0xff\n struct[offset++] = (item >> 8) & 0xff\n struct[offset++] = (item >> 16) & 0xff\n struct[offset++] = (item >> 24) & 0xff\n size += 4\n break\n case 'd': // double word\n struct[offset++] = item & 0xff\n struct[offset++] = (item >> 8) & 0xff\n struct[offset++] = (item >> 16) & 0xff\n struct[offset++] = (item >> 24) & 0xff\n struct[offset++] = 0x0\n struct[offset++] = 0x0\n struct[offset++] = 0x0\n struct[offset++] = 0x0\n size += 8\n break\n case 'h':\n struct[offset++] = item & 0xff\n struct[offset++] = item >> 8\n size += 2\n break\n case 'b':\n struct[offset++] = item\n size += 1\n break\n case 's': {\n const lengthoffset = offset\n let length = 0\n struct[offset++] = 0 // set the length later\n struct[offset++] = 0\n size += 2\n\n const stringBytes = texten.encode(item)\n size += stringBytes.byteLength\n length += stringBytes.byteLength\n struct.set(stringBytes, offset)\n offset += stringBytes.byteLength\n\n struct[lengthoffset + 0] = length & 0xff\n struct[lengthoffset + 1] = (length >> 8) & 0xff\n break\n }\n case 'Q':\n Marshall(\n ['b', 'w', 'd'],\n [item.type, item.version, item.path],\n struct,\n offset,\n )\n offset += 13\n size += 13\n break\n default:\n dbg_log('Marshall: Unknown type=' + typelist[i])\n break\n }\n }\n return size\n}\n\n// Extracts data from a byte aligned struct in memory to an array\n\nexport function Unmarshall(\n typelist: MarshallTypeCode[],\n struct: Uint8Array,\n state: MarshallState,\n): any[] {\n let offset = state.offset\n\n const output: any[] = []\n for (let i = 0; i < typelist.length; i++) {\n switch (typelist[i]) {\n case 'w': {\n let val = struct[offset++]\n val += struct[offset++] << 8\n val += struct[offset++] << 16\n val += (struct[offset++] << 24) >>> 0\n output.push(val)\n break\n }\n case 'd': {\n let val = struct[offset++]\n val += struct[offset++] << 8\n val += struct[offset++] << 16\n val += (struct[offset++] << 24) >>> 0\n offset += 4\n output.push(val)\n break\n }\n case 'h': {\n const val = struct[offset++]\n output.push(val + (struct[offset++] << 8))\n break\n }\n case 'b':\n output.push(struct[offset++])\n break\n case 's': {\n let len = struct[offset++]\n len += struct[offset++] << 8\n\n const stringBytes = struct.slice(offset, offset + len)\n offset += len\n output.push(textde.decode(stringBytes))\n break\n }\n case 'Q': {\n state.offset = offset\n const qid = Unmarshall(['b', 'w', 'd'], struct, state)\n offset = state.offset\n output.push({\n type: qid[0],\n version: qid[1],\n path: qid[2],\n })\n break\n }\n default:\n dbg_log('Error in Unmarshall: Unknown type=' + typelist[i])\n break\n }\n }\n state.offset = offset\n return output\n}\n", "import { dbg_assert } from './log.js'\nimport { VirtIO, VIRTIO_F_VERSION_1 } from './virtio.js'\nimport type { VirtQueueBufferChain } from './virtio.js'\nimport * as marshall from '../lib/marshall.js'\nimport { BusConnector } from './bus.js'\n\n// Minimal interface for the CPU fields VirtioConsole needs\ninterface VirtioConsoleCPU {\n io: {\n register_read(\n port: number,\n device: object,\n r8?: ((port: number) => number) | undefined,\n r16?: ((port: number) => number) | undefined,\n r32?: ((port: number) => number) | undefined,\n ): void\n register_write(\n port: number,\n device: object,\n w8?: ((port: number) => void) | undefined,\n w16?: ((port: number) => void) | undefined,\n w32?: ((port: number) => void) | undefined,\n ): void\n }\n devices: {\n pci: {\n register_device(device: VirtIO): void\n raise_irq(pci_id: number): void\n lower_irq(pci_id: number): void\n }\n }\n read16(addr: number): number\n read32s(addr: number): number\n write16(addr: number, value: number): void\n write32(addr: number, value: number): void\n read_blob(addr: number, length: number): Uint8Array\n write_blob(blob: Uint8Array, addr: number): void\n zero_memory(addr: number, length: number): void\n memory_size: Int32Array\n}\n\n// https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-2900003\n\nconst VIRTIO_CONSOLE_DEVICE_READY = 0\nconst VIRTIO_CONSOLE_DEVICE_ADD = 1\nconst _VIRTIO_CONSOLE_DEVICE_REMOVE = 2\nconst VIRTIO_CONSOLE_PORT_READY = 3\nconst VIRTIO_CONSOLE_CONSOLE_PORT = 4\nconst VIRTIO_CONSOLE_RESIZE = 5\nconst VIRTIO_CONSOLE_PORT_OPEN = 6\nconst VIRTIO_CONSOLE_PORT_NAME = 7\n\nconst VIRTIO_CONSOLE_F_SIZE = 0\nconst VIRTIO_CONSOLE_F_MULTIPORT = 1\nconst _VIRTIO_CONSOLE_F_EMERG_WRITE = 2\n\nexport class VirtioConsole {\n bus: BusConnector\n rows: number\n cols: number\n ports: number\n virtio: VirtIO\n\n constructor(cpu: VirtioConsoleCPU, bus: BusConnector) {\n this.bus = bus\n this.rows = 25\n this.cols = 80\n this.ports = 4\n\n const queues = [\n {\n size_supported: 16,\n notify_offset: 0,\n },\n {\n size_supported: 16,\n notify_offset: 1,\n },\n {\n size_supported: 16,\n notify_offset: 2,\n },\n {\n size_supported: 16,\n notify_offset: 3,\n },\n ]\n\n for (let i = 1; i < this.ports; ++i) {\n queues.push({ size_supported: 16, notify_offset: 0 })\n queues.push({ size_supported: 8, notify_offset: 1 })\n }\n\n this.virtio = new VirtIO(cpu, {\n name: 'virtio-console',\n pci_id: 0x0c << 3,\n device_id: 0x1043,\n subsystem_device_id: 3,\n common: {\n initial_port: 0xb800,\n queues: queues,\n features: [\n VIRTIO_CONSOLE_F_SIZE,\n VIRTIO_CONSOLE_F_MULTIPORT,\n VIRTIO_F_VERSION_1,\n ],\n on_driver_ok: () => {},\n },\n notification: {\n initial_port: 0xb900,\n single_handler: false,\n handlers: [\n (_queue_id: number) => {},\n (queue_id: number) => {\n const queue = this.virtio.queues[queue_id]\n const port = queue_id > 3 ? (queue_id - 3) >> 1 : 0\n while (queue.has_request()) {\n const bufchain = queue.pop_request()\n const buffer = new Uint8Array(\n bufchain.length_readable,\n )\n bufchain.get_next_blob(buffer)\n this.bus.send(\n 'virtio-console' + port + '-output-bytes',\n buffer,\n )\n this.Ack(queue_id, bufchain)\n }\n },\n (queue_id: number) => {\n if (queue_id !== 2) {\n dbg_assert(\n false,\n 'VirtioConsole Notified for wrong queue: ' +\n queue_id +\n ' (expected queue_id of 2)',\n )\n }\n },\n (queue_id: number) => {\n if (queue_id !== 3) {\n dbg_assert(\n false,\n 'VirtioConsole Notified for wrong queue: ' +\n queue_id +\n ' (expected queue_id of 3)',\n )\n return\n }\n const queue = this.virtio.queues[queue_id]\n\n while (queue.has_request()) {\n const bufchain = queue.pop_request()\n const buffer = new Uint8Array(\n bufchain.length_readable,\n )\n bufchain.get_next_blob(buffer)\n\n const parts = marshall.Unmarshall(\n ['w', 'h', 'h'],\n buffer,\n { offset: 0 },\n )\n const port = parts[0]\n const event = parts[1]\n const _value = parts[2]\n\n this.Ack(queue_id, bufchain)\n\n switch (event) {\n case VIRTIO_CONSOLE_DEVICE_READY:\n for (let i = 0; i < this.ports; ++i) {\n this.SendEvent(\n i,\n VIRTIO_CONSOLE_DEVICE_ADD,\n 0,\n )\n }\n break\n case VIRTIO_CONSOLE_PORT_READY:\n this.Ack(queue_id, bufchain)\n this.SendEvent(\n port,\n VIRTIO_CONSOLE_CONSOLE_PORT,\n 1,\n )\n this.SendName(port, 'virtio-' + port)\n this.SendEvent(\n port,\n VIRTIO_CONSOLE_PORT_OPEN,\n 1,\n )\n\n break\n case VIRTIO_CONSOLE_PORT_OPEN:\n this.Ack(queue_id, bufchain)\n if (port === 0) {\n this.SendWindowSize(port)\n }\n break\n default:\n dbg_assert(\n false,\n ' VirtioConsole received unknown event: ' +\n event,\n )\n return\n }\n }\n },\n ],\n },\n isr_status: {\n initial_port: 0xb700,\n },\n device_specific: {\n initial_port: 0xb600,\n struct: [\n {\n bytes: 2,\n name: 'cols',\n read: () => this.cols,\n write: (_data: number) => {\n /* read only */\n },\n },\n {\n bytes: 2,\n name: 'rows',\n read: () => this.rows,\n write: (_data: number) => {\n /* read only */\n },\n },\n {\n bytes: 4,\n name: 'max_nr_ports',\n read: () => this.ports,\n write: (_data: number) => {\n /* read only */\n },\n },\n {\n bytes: 4,\n name: 'emerg_wr',\n read: () => 0,\n write: (_data: number) => {\n dbg_assert(false, 'Emergency write!')\n },\n },\n ],\n },\n })\n\n for (let port = 0; port < this.ports; ++port) {\n const queue_id = port === 0 ? 0 : port * 2 + 2\n this.bus.register(\n 'virtio-console' + port + '-input-bytes',\n function (this: VirtioConsole, data: any) {\n const queue = this.virtio.queues[queue_id]\n if (queue.has_request()) {\n const bufchain = queue.pop_request()\n this.Send(queue_id, bufchain, new Uint8Array(data))\n } else {\n //TODO: Buffer\n }\n },\n this,\n )\n\n this.bus.register(\n 'virtio-console' + port + '-resize',\n function (this: VirtioConsole, size: any) {\n if (port === 0) {\n this.cols = size[0]\n this.rows = size[1]\n }\n\n if (\n this.virtio.queues[2].is_configured() &&\n this.virtio.queues[2].has_request()\n ) {\n this.SendWindowSize(port, size[0], size[1])\n }\n },\n this,\n )\n }\n }\n\n SendWindowSize(\n port: number,\n cols: number | undefined = undefined,\n rows: number | undefined = undefined,\n ): void {\n rows = rows || this.rows\n cols = cols || this.cols\n const bufchain = this.virtio.queues[2].pop_request()\n const buf = new Uint8Array(12)\n marshall.Marshall(\n ['w', 'h', 'h', 'h', 'h'],\n [port, VIRTIO_CONSOLE_RESIZE, 0, rows, cols],\n buf,\n 0,\n )\n this.Send(2, bufchain, buf)\n }\n\n SendName(port: number, name: string): void {\n const bufchain = this.virtio.queues[2].pop_request()\n const namex = new TextEncoder().encode(name)\n const buf = new Uint8Array(8 + namex.length + 1)\n marshall.Marshall(\n ['w', 'h', 'h'],\n [port, VIRTIO_CONSOLE_PORT_NAME, 1],\n buf,\n 0,\n )\n for (let i = 0; i < namex.length; ++i) {\n buf[i + 8] = namex[i]\n }\n buf[8 + namex.length] = 0\n this.Send(2, bufchain, buf)\n }\n\n get_state(): any[] {\n const state: any[] = []\n\n state[0] = this.virtio\n state[1] = this.rows\n state[2] = this.cols\n state[3] = this.ports\n\n return state\n }\n\n set_state(state: any[]): void {\n this.virtio.set_state(state[0])\n this.rows = state[1]\n this.cols = state[2]\n this.ports = state[3]\n }\n\n reset(): void {\n this.virtio.reset()\n }\n\n SendEvent(port: number, event: number, value: number): void {\n const queue = this.virtio.queues[2]\n const bufchain = queue.pop_request()\n\n const buf = new Uint8Array(8)\n marshall.Marshall(['w', 'h', 'h'], [port, event, value], buf, 0)\n this.Send(2, bufchain, buf)\n }\n\n Send(\n queue_id: number,\n bufchain: VirtQueueBufferChain,\n blob: Uint8Array,\n ): void {\n bufchain.set_next_blob(blob)\n this.virtio.queues[queue_id].push_reply(bufchain)\n this.virtio.queues[queue_id].flush_replies()\n }\n\n Ack(queue_id: number, bufchain: VirtQueueBufferChain): void {\n bufchain.set_next_blob(new Uint8Array(0))\n this.virtio.queues[queue_id].push_reply(bufchain)\n this.virtio.queues[queue_id].flush_replies()\n }\n}\n", "import { LOG_PCI } from './const.js'\nimport { h } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\nimport { IO } from './io.js'\n\n// http://wiki.osdev.org/PCI\n\nexport const PCI_CONFIG_ADDRESS = 0xcf8\nexport const PCI_CONFIG_DATA = 0xcfc\n\n// Minimal interface for CPU fields PCI uses.\ninterface PCICpu {\n io: IO\n device_raise_irq(irq: number): void\n device_lower_irq(irq: number): void\n reboot_internal(): void\n}\n\n// Mirrors IOPortEntry from io.ts (not exported there).\ninterface PCIPortEntry {\n read8: (port: number) => number\n read16: (port: number) => number\n read32: (port: number) => number\n write8: (port: number) => void\n write16: (port: number) => void\n write32: (port: number) => void\n device: { name?: string } | undefined\n}\n\n// PCIBar starts as { size: number } from devices. register_device()\n// populates original_bar and entries at registration time.\nexport interface PCIBar {\n size: number\n original_bar?: number\n entries?: PCIPortEntry[]\n}\n\nexport interface PCIDevice {\n pci_id: number\n pci_space: number[]\n pci_bars: (PCIBar | undefined)[]\n name: string\n pci_rom_size?: number\n pci_rom_address?: number\n}\n\nexport class PCI {\n name: string\n pci_addr: Uint8Array\n pci_value: Uint8Array\n pci_response: Uint8Array\n pci_status: Uint8Array\n\n pci_addr32: Int32Array\n pci_value32: Int32Array\n pci_response32: Int32Array\n pci_status32: Int32Array\n\n device_spaces: (Int32Array | undefined)[]\n devices: (PCIDevice | undefined)[]\n\n cpu: PCICpu\n io: IO\n\n isa_bridge: PCIDevice\n isa_bridge_space: Int32Array\n isa_bridge_space8: Uint8Array\n\n constructor(cpu: PCICpu) {\n this.name = 'PCI'\n this.pci_addr = new Uint8Array(4)\n this.pci_value = new Uint8Array(4)\n this.pci_response = new Uint8Array(4)\n this.pci_status = new Uint8Array(4)\n\n this.pci_addr32 = new Int32Array(this.pci_addr.buffer)\n this.pci_value32 = new Int32Array(this.pci_value.buffer)\n this.pci_response32 = new Int32Array(this.pci_response.buffer)\n this.pci_status32 = new Int32Array(this.pci_status.buffer)\n\n this.device_spaces = []\n this.devices = []\n\n this.cpu = cpu\n\n for (let i = 0; i < 256; i++) {\n this.device_spaces[i] = undefined\n this.devices[i] = undefined\n }\n\n this.io = cpu.io\n\n cpu.io.register_write(\n PCI_CONFIG_DATA,\n this,\n (value: number): void => {\n this.pci_write8(this.pci_addr32[0], value)\n },\n (value: number): void => {\n this.pci_write16(this.pci_addr32[0], value)\n },\n (value: number): void => {\n this.pci_write32(this.pci_addr32[0], value)\n },\n )\n\n cpu.io.register_write(\n PCI_CONFIG_DATA + 1,\n this,\n (value: number): void => {\n this.pci_write8((this.pci_addr32[0] + 1) | 0, value)\n },\n )\n\n cpu.io.register_write(\n PCI_CONFIG_DATA + 2,\n this,\n (value: number): void => {\n this.pci_write8((this.pci_addr32[0] + 2) | 0, value)\n },\n (value: number): void => {\n this.pci_write16((this.pci_addr32[0] + 2) | 0, value)\n },\n )\n\n cpu.io.register_write(\n PCI_CONFIG_DATA + 3,\n this,\n (value: number): void => {\n this.pci_write8((this.pci_addr32[0] + 3) | 0, value)\n },\n )\n\n cpu.io.register_read_consecutive(\n PCI_CONFIG_DATA,\n this,\n (): number => {\n return this.pci_response[0]\n },\n (): number => {\n return this.pci_response[1]\n },\n (): number => {\n return this.pci_response[2]\n },\n (): number => {\n return this.pci_response[3]\n },\n )\n\n cpu.io.register_read_consecutive(\n PCI_CONFIG_ADDRESS,\n this,\n (): number => {\n return this.pci_status[0]\n },\n (): number => {\n return this.pci_status[1]\n },\n (): number => {\n return this.pci_status[2]\n },\n (): number => {\n return this.pci_status[3]\n },\n )\n\n cpu.io.register_write_consecutive(\n PCI_CONFIG_ADDRESS,\n this,\n (out_byte: number): void => {\n this.pci_addr[0] = out_byte & 0xfc\n },\n (out_byte: number): void => {\n if (\n (this.pci_addr[1] & 0x06) === 0x02 &&\n (out_byte & 0x06) === 0x06\n ) {\n dbg_log('CPU reboot via PCI')\n cpu.reboot_internal()\n return\n }\n\n this.pci_addr[1] = out_byte\n },\n (out_byte: number): void => {\n this.pci_addr[2] = out_byte\n },\n (out_byte: number): void => {\n this.pci_addr[3] = out_byte\n this.pci_query()\n },\n )\n\n // Some experimental PCI devices taken from my PC:\n\n // 00:00.0 Host bridge: Intel Corporation 4 Series Chipset DRAM Controller (rev 02)\n //var host_bridge = {\n // pci_id: 0,\n // pci_space: [\n // 0x86, 0x80, 0x20, 0x2e, 0x06, 0x00, 0x90, 0x20, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,\n // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x10, 0xd3, 0x82,\n // 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n // ],\n // pci_bars: [],\n //};\n\n // This needs to be set in order for seabios to not execute code outside of\n // mapped memory. While we map the BIOS into high memory, we don't allow\n // executing code there, which enables optimisations in read_imm8.\n // See [make_bios_writable_intel] in src/fw/shadow.c in seabios for details\n const PAM0 = 0x10\n\n const host_bridge: PCIDevice = {\n pci_id: 0,\n pci_space: [\n // 00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02)\n 0x86,\n 0x80,\n 0x37,\n 0x12,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x02,\n 0x00,\n 0x00,\n 0x06,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n PAM0,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n ],\n pci_bars: [],\n name: '82441FX PMC',\n }\n this.register_device(host_bridge)\n\n this.isa_bridge = {\n pci_id: 1 << 3,\n pci_space: [\n // 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]\n 0x86,\n 0x80, 0x00, 0x70, 0x07, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,\n 0x06, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00,\n ],\n pci_bars: [],\n name: '82371SB PIIX3 ISA',\n }\n this.isa_bridge_space = this.register_device(this.isa_bridge)\n this.isa_bridge_space8 = new Uint8Array(this.isa_bridge_space.buffer)\n\n // 00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev 90)\n //this.register_device([\n // 0x86, 0x80, 0x4e, 0x24, 0x07, 0x01, 0x10, 0x00, 0x90, 0x01, 0x04, 0x06, 0x00, 0x00, 0x01, 0x00,\n // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x20, 0xe0, 0xe0, 0x80, 0x22,\n // 0xb0, 0xfe, 0xb0, 0xfe, 0xf1, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n // 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x02, 0x00,\n //], 0x1e << 3);\n }\n\n get_state(): (Int32Array | Uint8Array | undefined)[] {\n const state: (Int32Array | Uint8Array | undefined)[] = []\n\n for (let i = 0; i < 256; i++) {\n state[i] = this.device_spaces[i]\n }\n\n state[256] = this.pci_addr\n state[257] = this.pci_value\n state[258] = this.pci_response\n state[259] = this.pci_status\n\n return state\n }\n\n set_state(state: (Int32Array | Uint8Array | undefined)[]): void {\n for (let i = 0; i < 256; i++) {\n const device = this.devices[i]\n const space = state[i]\n\n if (!device || !space) {\n if (device) {\n dbg_log(\n 'Warning: While restoring PCI device: Device exists in current ' +\n 'configuration but not in snapshot (' +\n device.name +\n ')',\n )\n }\n if (space) {\n dbg_log(\n \"Warning: While restoring PCI device: Device doesn't exist in current \" +\n 'configuration but does in snapshot (device ' +\n h(i, 2) +\n ')',\n )\n }\n continue\n }\n\n const space32 = new Int32Array(space.buffer)\n\n for (let bar_nr = 0; bar_nr < device.pci_bars.length; bar_nr++) {\n const value = space32[(0x10 >> 2) + bar_nr]\n\n if (value & 1) {\n const bar = device.pci_bars[bar_nr]\n if (bar) {\n const from = bar.original_bar! & ~1 & 0xffff\n const to = value & ~1 & 0xffff\n this.set_io_bars(bar, from, to)\n }\n } else {\n // memory, cannot be changed\n }\n }\n\n const device_space = this.device_spaces[i]\n if (device_space) {\n device_space.set(new Int32Array(space.buffer))\n }\n }\n\n this.pci_addr.set(state[256]!)\n this.pci_value.set(state[257]!)\n this.pci_response.set(state[258]!)\n this.pci_status.set(state[259]!)\n }\n\n pci_query(): void {\n let dbg_line = 'query'\n\n // Bit | .31 .0\n // Fmt | EBBBBBBBBDDDDDFFFRRRRRR00\n\n const bdf = (this.pci_addr[2] << 8) | this.pci_addr[1],\n addr = this.pci_addr[0] & 0xfc,\n //devfn = bdf & 0xFF,\n //bus = bdf >> 8,\n dev = (bdf >> 3) & 0x1f,\n //fn = bdf & 7,\n enabled = this.pci_addr[3] >> 7\n\n dbg_line += ' enabled=' + enabled\n dbg_line += ' bdf=' + h(bdf, 4)\n dbg_line += ' dev=' + h(dev, 2)\n dbg_line += ' addr=' + h(addr, 2)\n\n const device = this.device_spaces[bdf]\n\n if (device !== undefined) {\n this.pci_status32[0] = 0x80000000 | 0\n\n if (addr < device.byteLength) {\n this.pci_response32[0] = device[addr >> 2]\n } else {\n // required by freebsd-9.1\n this.pci_response32[0] = 0\n }\n\n dbg_line +=\n ' ' +\n h(this.pci_addr32[0] >>> 0, 8) +\n ' -> ' +\n h(this.pci_response32[0] >>> 0, 8)\n\n if (addr >= device.byteLength) {\n dbg_line += ' (undef)'\n }\n\n dbg_line += ' (' + this.devices[bdf]!.name + ')'\n\n dbg_log(dbg_line, LOG_PCI)\n } else {\n this.pci_response32[0] = -1\n this.pci_status32[0] = 0\n }\n }\n\n pci_write8(address: number, written: number): void {\n const bdf = (address >> 8) & 0xffff\n const addr = address & 0xff\n\n const device_space = this.device_spaces[bdf]\n const device = this.devices[bdf]\n\n if (!device_space) {\n return\n }\n\n const space = new Uint8Array(device_space.buffer)\n\n dbg_assert(\n !((addr >= 0x10 && addr < 0x2c) || (addr >= 0x30 && addr < 0x34)),\n 'PCI: Expected 32-bit write, got 8-bit (addr: ' + h(addr) + ')',\n )\n\n dbg_log(\n 'PCI write8 dev=' +\n h(bdf >> 3, 2) +\n ' (' +\n device!.name +\n ') addr=' +\n h(addr, 4) +\n ' value=' +\n h(written, 2),\n LOG_PCI,\n )\n\n space[addr] = written\n }\n\n pci_write16(address: number, written: number): void {\n dbg_assert((address & 1) === 0)\n\n const bdf = (address >> 8) & 0xffff\n const addr = address & 0xff\n\n const device_space = this.device_spaces[bdf]\n const device = this.devices[bdf]\n\n if (!device_space) {\n return\n }\n\n const space = new Uint16Array(device_space.buffer)\n\n if (addr >= 0x10 && addr < 0x2c) {\n // Bochs bios\n dbg_log(\n 'Warning: PCI: Expected 32-bit write, got 16-bit (addr: ' +\n h(addr) +\n ')',\n )\n return\n }\n\n dbg_assert(\n !(addr >= 0x30 && addr < 0x34),\n 'PCI: Expected 32-bit write, got 16-bit (addr: ' + h(addr) + ')',\n )\n\n dbg_log(\n 'PCI writ16 dev=' +\n h(bdf >> 3, 2) +\n ' (' +\n device!.name +\n ') addr=' +\n h(addr, 4) +\n ' value=' +\n h(written, 4),\n LOG_PCI,\n )\n\n space[addr >>> 1] = written\n }\n\n pci_write32(address: number, written: number): void {\n dbg_assert((address & 3) === 0)\n\n const bdf = (address >> 8) & 0xffff\n const addr = address & 0xff\n\n const space = this.device_spaces[bdf]\n const device = this.devices[bdf]\n\n if (!space) {\n return\n }\n\n if (addr >= 0x10 && addr < 0x28) {\n const bar_nr = (addr - 0x10) >> 2\n const bar = device!.pci_bars[bar_nr]\n\n dbg_log(\n 'BAR' +\n bar_nr +\n ' exists=' +\n (bar ? 'y' : 'n') +\n ' changed from ' +\n h(space[addr >> 2]) +\n ' to ' +\n h(written >>> 0) +\n ' dev=' +\n h(bdf >> 3, 2) +\n ' (' +\n device!.name +\n ') ',\n LOG_PCI,\n )\n\n if (bar) {\n dbg_assert(\n !(bar.size & (bar.size - 1)),\n 'bar size should be power of 2',\n )\n\n const space_addr = addr >> 2\n const type = space[space_addr] & 1\n\n if ((written | 3 | (bar.size - 1)) === -1) // size check\n {\n written = ~(bar.size - 1) | type\n\n if (type === 0) {\n space[space_addr] = written\n }\n } else {\n if (type === 0) {\n // memory\n const original_bar = bar.original_bar!\n\n if ((written & ~0xf) !== (original_bar & ~0xf)) {\n // seabios\n dbg_log(\n 'Warning: Changing memory bar not supported, ignored',\n LOG_PCI,\n )\n }\n\n // changing isn't supported yet, reset to default\n space[space_addr] = original_bar\n }\n }\n\n if (type === 1) {\n // io\n dbg_assert(type === 1)\n\n const from = space[space_addr] & ~1 & 0xffff\n const to = written & ~1 & 0xffff\n dbg_log(\n 'io bar changed from ' +\n h(from >>> 0, 8) +\n ' to ' +\n h(to >>> 0, 8) +\n ' size=' +\n bar.size,\n LOG_PCI,\n )\n this.set_io_bars(bar, from, to)\n space[space_addr] = written | 1\n }\n } else {\n space[addr >> 2] = 0\n }\n\n dbg_log(\n 'BAR effective value: ' + h(space[addr >> 2] >>> 0),\n LOG_PCI,\n )\n } else if (addr === 0x30) {\n dbg_log(\n 'PCI write rom address dev=' +\n h(bdf >> 3, 2) +\n ' (' +\n device!.name +\n ')' +\n ' value=' +\n h(written >>> 0, 8),\n LOG_PCI,\n )\n\n if (device!.pci_rom_size) {\n if ((written | 0x7ff) === (0xffffffff | 0)) {\n space[addr >> 2] = -device!.pci_rom_size! | 0\n } else {\n space[addr >> 2] = device!.pci_rom_address! | 0\n }\n } else {\n space[addr >> 2] = 0\n }\n } else if (addr === 0x04) {\n dbg_log(\n 'PCI write dev=' +\n h(bdf >> 3, 2) +\n ' (' +\n device!.name +\n ') addr=' +\n h(addr, 4) +\n ' value=' +\n h(written >>> 0, 8),\n LOG_PCI,\n )\n } else {\n dbg_log(\n 'PCI write dev=' +\n h(bdf >> 3, 2) +\n ' (' +\n device!.name +\n ') addr=' +\n h(addr, 4) +\n ' value=' +\n h(written >>> 0, 8),\n LOG_PCI,\n )\n space[addr >>> 2] = written\n }\n }\n\n register_device(device: PCIDevice): Int32Array {\n dbg_assert(device.pci_id !== undefined)\n dbg_assert(device.pci_space !== undefined)\n dbg_assert(device.pci_bars !== undefined)\n\n const device_id = device.pci_id\n\n dbg_log(\n 'PCI register bdf=' + h(device_id) + ' (' + device.name + ')',\n LOG_PCI,\n )\n\n if (this.devices[device_id]) {\n dbg_log(\n 'warning: overwriting device ' +\n this.devices[device_id]!.name +\n ' with ' +\n device.name,\n LOG_PCI,\n )\n }\n dbg_assert(device.pci_space.length >= 64)\n dbg_assert(device_id < this.devices.length)\n\n // convert bytewise notation from lspci to double words\n const space = new Int32Array(64)\n space.set(new Int32Array(new Uint8Array(device.pci_space).buffer))\n this.device_spaces[device_id] = space\n this.devices[device_id] = device\n\n const bar_space = space.slice(4, 10)\n\n for (let i = 0; i < device.pci_bars.length; i++) {\n const bar = device.pci_bars[i]\n\n if (!bar) {\n continue\n }\n\n const bar_base = bar_space[i]\n const type = bar_base & 1\n dbg_log(\n 'device ' +\n device.name +\n ' register bar of size ' +\n bar.size +\n ' at ' +\n h(bar_base),\n LOG_PCI,\n )\n\n bar.original_bar = bar_base\n bar.entries = []\n\n if (type === 0) {\n // memory, not needed currently\n } else {\n dbg_assert(type === 1)\n const port = bar_base & ~1\n\n for (let j = 0; j < bar.size; j++) {\n bar.entries[j] = this.io.ports[port + j]\n }\n }\n }\n\n return space\n }\n\n set_io_bars(bar: PCIBar, from: number, to: number): void {\n const count = bar.size\n dbg_log(\n 'Move io bars: from=' +\n h(from) +\n ' to=' +\n h(to) +\n ' count=' +\n count,\n LOG_PCI,\n )\n\n const ports = this.io.ports\n\n for (let i = 0; i < count; i++) {\n const _old_entry = ports[from + i]\n\n if (from + i >= 0x1000) {\n ports[from + i] = this.io.create_empty_entry()\n }\n\n const entry = bar.entries![i]\n const empty_entry = ports[to + i]\n dbg_assert(!!entry && !!empty_entry)\n\n if (to + i >= 0x1000) {\n ports[to + i] = entry\n }\n }\n }\n\n raise_irq(pci_id: number): void {\n const space = this.device_spaces[pci_id]\n dbg_assert(!!space)\n\n const pin = ((space![0x3c >>> 2] >> 8) & 0xff) - 1\n const device = ((pci_id >> 3) - 1) & 0xff\n const parent_pin = (pin + device) & 3\n const irq = this.isa_bridge_space8[0x60 + parent_pin]\n\n //dbg_log(\"PCI raise irq \" + h(irq) + \" dev=\" + h(device, 2) +\n // \" (\" + this.devices[pci_id].name + \")\", LOG_PCI);\n this.cpu.device_raise_irq(irq)\n }\n\n lower_irq(pci_id: number): void {\n const space = this.device_spaces[pci_id]\n dbg_assert(!!space)\n\n const pin = (space![0x3c >>> 2] >> 8) & 0xff\n const device = (pci_id >> 3) & 0xff\n const parent_pin = (pin + device - 2) & 3\n const irq = this.isa_bridge_space8[0x60 + parent_pin]\n\n //dbg_log(\"PCI lower irq \" + h(irq) + \" dev=\" + h(device, 2) +\n // \" (\" + this.devices[pci_id].name + \")\", LOG_PCI);\n this.cpu.device_lower_irq(irq)\n }\n}\n", "import { LOG_PS2 } from './const.js'\nimport { h, ByteQueue } from './lib.js'\nimport { dbg_log } from './log.js'\nimport { IO } from './io.js'\nimport { BusConnector } from './bus.js'\n\nconst PS2_LOG_VERBOSE = false\n\n// Minimal interface for CPU fields PS2 uses\ninterface PS2Cpu {\n io: IO\n device_raise_irq(irq: number): void\n device_lower_irq(irq: number): void\n reboot_internal(): void\n}\n\ntype PS2State = [\n boolean, // 0: enable_mouse_stream\n boolean, // 1: use_mouse\n boolean, // 2: have_mouse\n number, // 3: mouse_delta_x\n number, // 4: mouse_delta_y\n number, // 5: mouse_clicks\n boolean, // 6: have_keyboard\n boolean, // 7: enable_keyboard_stream\n boolean, // 8: next_is_mouse_command\n boolean, // 9: next_read_sample\n boolean, // 10: next_read_led\n boolean, // 11: next_handle_scan_code_set\n boolean, // 12: next_read_rate\n boolean, // 13: next_read_resolution\n undefined, // 14: kbd_buffer (unused)\n number, // 15: last_port60_byte\n number, // 16: sample_rate\n number, // 17: resolution\n boolean, // 18: scaling2\n undefined, // 19: mouse_buffer (unused)\n number, // 20: command_register\n boolean, // 21: read_output_register\n boolean, // 22: read_command_register\n number, // 23: controller_output_port\n boolean, // 24: read_controller_output_port\n number, // 25: mouse_id\n number, // 26: mouse_detect_state\n boolean, // 27: mouse_reset_workaround\n]\n\n/**\n * PS2 controller for keyboard and mouse.\n */\nexport class PS2 {\n name: string\n cpu: PS2Cpu\n bus: BusConnector\n\n enable_mouse_stream: boolean = false\n use_mouse: boolean = false\n have_mouse: boolean = true\n mouse_delta_x: number = 0\n mouse_delta_y: number = 0\n mouse_clicks: number = 0\n have_keyboard: boolean = true\n enable_keyboard_stream: boolean = false\n next_is_mouse_command: boolean = false\n next_read_sample: boolean = false\n next_read_led: boolean = false\n next_handle_scan_code_set: boolean = false\n next_read_rate: boolean = false\n next_read_resolution: boolean = false\n kbd_buffer: ByteQueue\n last_port60_byte: number = 0\n sample_rate: number = 100\n mouse_detect_state: number = 0\n mouse_id: number = 0x00\n mouse_reset_workaround: boolean = false\n wheel_movement: number = 0\n resolution: number = 4\n scaling2: boolean = false\n last_mouse_packet: number = -1\n mouse_buffer: ByteQueue\n next_byte_is_ready: boolean = false\n next_byte_is_aux: boolean = false\n command_register: number = 0\n controller_output_port: number = 0\n read_output_register: boolean = false\n read_command_register: boolean = false\n read_controller_output_port: boolean = false\n\n constructor(cpu: PS2Cpu, bus: BusConnector) {\n this.name = 'ps2'\n this.cpu = cpu\n this.bus = bus\n\n this.kbd_buffer = new ByteQueue(1024)\n this.mouse_buffer = new ByteQueue(1024)\n\n this.reset()\n\n this.bus.register(\n 'keyboard-code',\n (code: number): void => {\n this.kbd_send_code(code)\n },\n this,\n )\n\n this.bus.register(\n 'mouse-click',\n (data: [number, number, number]): void => {\n this.mouse_send_click(data[0], data[1], data[2])\n },\n this,\n )\n\n this.bus.register(\n 'mouse-delta',\n (data: [number, number]): void => {\n this.mouse_send_delta(data[0], data[1])\n },\n this,\n )\n\n this.bus.register(\n 'mouse-wheel',\n (data: [number, number]): void => {\n this.wheel_movement -= data[0]\n this.wheel_movement -= data[1] * 2 // X Wheel Movement\n this.wheel_movement = Math.min(\n 7,\n Math.max(-8, this.wheel_movement),\n )\n this.send_mouse_packet(0, 0)\n },\n this,\n )\n\n cpu.io.register_read(0x60, this, this.port60_read.bind(this))\n cpu.io.register_read(0x64, this, this.port64_read.bind(this))\n\n cpu.io.register_write(0x60, this, this.port60_write.bind(this))\n cpu.io.register_write(0x64, this, this.port64_write.bind(this))\n }\n\n reset(): void {\n this.enable_mouse_stream = false\n this.use_mouse = false\n this.have_mouse = true\n this.mouse_delta_x = 0\n this.mouse_delta_y = 0\n this.mouse_clicks = 0\n this.have_keyboard = true\n this.enable_keyboard_stream = false\n this.next_is_mouse_command = false\n this.next_read_sample = false\n this.next_read_led = false\n this.next_handle_scan_code_set = false\n this.next_read_rate = false\n this.next_read_resolution = false\n\n this.kbd_buffer = new ByteQueue(1024)\n\n this.last_port60_byte = 0\n\n this.sample_rate = 100\n this.mouse_detect_state = 0\n this.mouse_id = 0x00\n this.mouse_reset_workaround = false\n this.wheel_movement = 0\n this.resolution = 4\n this.scaling2 = false\n this.last_mouse_packet = -1\n\n this.mouse_buffer = new ByteQueue(1024)\n\n // Also known as DBBOUT OBF - Output Buffer Full flag\n this.next_byte_is_ready = false\n this.next_byte_is_aux = false\n\n this.command_register = 1 | 4\n // TODO: What should be the initial value?\n this.controller_output_port = 0\n this.read_output_register = false\n this.read_command_register = false\n this.read_controller_output_port = false\n }\n\n get_state(): PS2State {\n const state: PS2State = [\n this.enable_mouse_stream,\n this.use_mouse,\n this.have_mouse,\n this.mouse_delta_x,\n this.mouse_delta_y,\n this.mouse_clicks,\n this.have_keyboard,\n this.enable_keyboard_stream,\n this.next_is_mouse_command,\n this.next_read_sample,\n this.next_read_led,\n this.next_handle_scan_code_set,\n this.next_read_rate,\n this.next_read_resolution,\n undefined, //this.kbd_buffer;\n this.last_port60_byte,\n this.sample_rate,\n this.resolution,\n this.scaling2,\n undefined, //this.mouse_buffer;\n this.command_register,\n this.read_output_register,\n this.read_command_register,\n this.controller_output_port,\n this.read_controller_output_port,\n this.mouse_id,\n this.mouse_detect_state,\n this.mouse_reset_workaround,\n ]\n\n return state\n }\n\n set_state(state: PS2State): void {\n this.enable_mouse_stream = state[0]\n this.use_mouse = state[1]\n this.have_mouse = state[2]\n this.mouse_delta_x = state[3]\n this.mouse_delta_y = state[4]\n this.mouse_clicks = state[5]\n this.have_keyboard = state[6]\n this.enable_keyboard_stream = state[7]\n this.next_is_mouse_command = state[8]\n this.next_read_sample = state[9]\n this.next_read_led = state[10]\n this.next_handle_scan_code_set = state[11]\n this.next_read_rate = state[12]\n this.next_read_resolution = state[13]\n //this.kbd_buffer = state[14];\n this.last_port60_byte = state[15]\n this.sample_rate = state[16]\n this.resolution = state[17]\n this.scaling2 = state[18]\n //this.mouse_buffer = state[19];\n this.command_register = state[20]\n this.read_output_register = state[21]\n this.read_command_register = state[22]\n this.controller_output_port = state[23]\n this.read_controller_output_port = state[24]\n this.mouse_id = state[25] || 0\n this.mouse_detect_state = state[26] || 0\n this.mouse_reset_workaround = state[27] || false\n\n this.next_byte_is_ready = false\n this.next_byte_is_aux = false\n this.kbd_buffer.clear()\n this.mouse_buffer.clear()\n\n this.bus.send('mouse-enable', this.use_mouse)\n }\n\n raise_irq(): void {\n if (this.next_byte_is_ready) {\n // Wait until previous byte is read\n // http://halicery.com/Hardware/8042/8042_1503033_TXT.htm\n return\n }\n\n // Kbd has priority over aux\n if (this.kbd_buffer.length) {\n this.kbd_irq()\n } else if (this.mouse_buffer.length) {\n this.mouse_irq()\n }\n }\n\n mouse_irq(): void {\n this.next_byte_is_ready = true\n this.next_byte_is_aux = true\n\n if (this.command_register & 2) {\n dbg_log('Mouse irq', LOG_PS2)\n\n // Pulse the irq line\n // Note: can't lower immediately after rising, so lower before rising\n // http://www.os2museum.com/wp/ibm-ps2-model-50-keyboard-controller/\n this.cpu.device_lower_irq(12)\n this.cpu.device_raise_irq(12)\n }\n }\n\n kbd_irq(): void {\n this.next_byte_is_ready = true\n this.next_byte_is_aux = false\n\n if (this.command_register & 1) {\n dbg_log('Keyboard irq', LOG_PS2)\n\n // Pulse the irq line\n // Note: can't lower immediately after rising, so lower before rising\n // http://www.os2museum.com/wp/ibm-ps2-model-50-keyboard-controller/\n this.cpu.device_lower_irq(1)\n this.cpu.device_raise_irq(1)\n }\n }\n\n kbd_send_code(code: number): void {\n if (this.enable_keyboard_stream) {\n dbg_log('adding kbd code: ' + h(code), LOG_PS2)\n this.kbd_buffer.push(code)\n this.raise_irq()\n }\n }\n\n mouse_send_delta(delta_x: number, delta_y: number): void {\n if (!this.have_mouse || !this.use_mouse) {\n return\n }\n\n // note: delta_x or delta_y can be floating point numbers\n\n //const factor = this.resolution * this.sample_rate / 80;\n const factor = 1\n\n this.mouse_delta_x += delta_x * factor\n this.mouse_delta_y += delta_y * factor\n\n if (this.enable_mouse_stream) {\n const change_x = this.mouse_delta_x | 0,\n change_y = this.mouse_delta_y | 0\n\n if (change_x || change_y) {\n //var now = Date.now();\n //if(now - this.last_mouse_packet < 1000 / this.sample_rate)\n //{\n // // TODO: set timeout\n // return;\n //}\n\n this.mouse_delta_x -= change_x\n this.mouse_delta_y -= change_y\n\n this.send_mouse_packet(change_x, change_y)\n }\n }\n }\n\n mouse_send_click(left: number, middle: number, right: number): void {\n if (!this.have_mouse || !this.use_mouse) {\n return\n }\n\n this.mouse_clicks = left | (right << 1) | (middle << 2)\n\n if (this.enable_mouse_stream) {\n this.send_mouse_packet(0, 0)\n }\n }\n\n send_mouse_packet(dx: number, dy: number): void {\n const info_byte =\n ((dy < 0 ? 1 : 0) << 5) |\n ((dx < 0 ? 1 : 0) << 4) |\n (1 << 3) |\n this.mouse_clicks,\n delta_x = dx,\n delta_y = dy\n\n this.last_mouse_packet = Date.now()\n\n //if(this.scaling2)\n //{\n // // only in automatic packets, not 0xEB requests\n // delta_x = this.apply_scaling2(delta_x);\n // delta_y = this.apply_scaling2(delta_y);\n //}\n\n this.mouse_buffer.push(info_byte)\n this.mouse_buffer.push(delta_x)\n this.mouse_buffer.push(delta_y)\n\n if (this.mouse_id === 0x04) {\n this.mouse_buffer.push(\n (0 << 5) | // TODO: 5th button\n (0 << 4) | // TODO: 4th button\n (this.wheel_movement & 0x0f),\n )\n this.wheel_movement = 0\n } else if (this.mouse_id === 0x03) {\n this.mouse_buffer.push(this.wheel_movement & 0xff) // Byte 4 - Z Movement\n this.wheel_movement = 0\n }\n\n if (PS2_LOG_VERBOSE) {\n dbg_log('adding mouse packets: ' + [info_byte, dx, dy], LOG_PS2)\n }\n\n this.raise_irq()\n }\n\n apply_scaling2(n: number): number {\n // http://www.computer-engineering.org/ps2mouse/#Inputs.2C_Resolution.2C_and_Scaling\n const abs = Math.abs(n),\n sign = n >> 31\n\n switch (abs) {\n case 0:\n case 1:\n case 3:\n return n\n case 2:\n return sign\n case 4:\n return 6 * sign\n case 5:\n return 9 * sign\n default:\n return n << 1\n }\n }\n\n port60_read(): number {\n //dbg_log(\"port 60 read: \" + (buffer[0] || \"(none)\"));\n\n this.next_byte_is_ready = false\n\n if (!this.kbd_buffer.length && !this.mouse_buffer.length) {\n // should not happen\n dbg_log('Port 60 read: Empty', LOG_PS2)\n return this.last_port60_byte\n }\n\n if (this.next_byte_is_aux) {\n this.cpu.device_lower_irq(12)\n this.last_port60_byte = this.mouse_buffer.shift()\n dbg_log(\n 'Port 60 read (mouse): ' + h(this.last_port60_byte),\n LOG_PS2,\n )\n } else {\n this.cpu.device_lower_irq(1)\n this.last_port60_byte = this.kbd_buffer.shift()\n dbg_log(\n 'Port 60 read (kbd) : ' + h(this.last_port60_byte),\n LOG_PS2,\n )\n }\n\n if (this.kbd_buffer.length || this.mouse_buffer.length) {\n this.raise_irq()\n }\n\n return this.last_port60_byte\n }\n\n port64_read(): number {\n // status port\n\n let status_byte = 0x10\n\n if (this.next_byte_is_ready) {\n status_byte |= 0x1\n }\n if (this.next_byte_is_aux) {\n status_byte |= 0x20\n }\n\n dbg_log('port 64 read: ' + h(status_byte), LOG_PS2)\n\n return status_byte\n }\n\n port60_write(write_byte: number): void {\n dbg_log('port 60 write: ' + h(write_byte), LOG_PS2)\n\n if (this.read_command_register) {\n this.command_register = write_byte\n this.read_command_register = false\n\n // not sure, causes \"spurious ack\" in Linux\n //this.kbd_buffer.push(0xFA);\n //this.kbd_irq();\n\n dbg_log(\n 'Keyboard command register = ' + h(this.command_register),\n LOG_PS2,\n )\n } else if (this.read_output_register) {\n this.read_output_register = false\n\n this.mouse_buffer.clear()\n this.mouse_buffer.push(write_byte)\n this.mouse_irq()\n } else if (this.next_read_sample) {\n this.next_read_sample = false\n this.mouse_buffer.clear()\n this.mouse_buffer.push(0xfa)\n\n this.sample_rate = write_byte\n\n switch (this.mouse_detect_state) {\n case -1:\n if (write_byte === 60) {\n // Detect Windows NT and turn on workaround the bug\n // 200->100->80->60\n this.mouse_reset_workaround = true\n this.mouse_detect_state = 0\n } else {\n this.mouse_reset_workaround = false\n this.mouse_detect_state = write_byte === 200 ? 1 : 0\n }\n break\n case 0:\n if (write_byte === 200) this.mouse_detect_state = 1\n break\n case 1:\n if (write_byte === 100) this.mouse_detect_state = 2\n else if (write_byte === 200) this.mouse_detect_state = 3\n else this.mouse_detect_state = 0\n break\n case 2:\n // Host sends sample rate 200->100->80 to activate Intellimouse wheel\n if (write_byte === 80) this.mouse_id = 0x03\n this.mouse_detect_state = -1\n break\n case 3:\n // Host sends sample rate 200->200->80 to activate Intellimouse 4th, 5th buttons\n if (write_byte === 80) this.mouse_id = 0x04\n this.mouse_detect_state = -1\n break\n }\n\n dbg_log(\n 'mouse sample rate: ' +\n h(write_byte) +\n ', mouse id: ' +\n h(this.mouse_id),\n LOG_PS2,\n )\n\n if (!this.sample_rate) {\n dbg_log('invalid sample rate, reset to 100', LOG_PS2)\n this.sample_rate = 100\n }\n\n this.mouse_irq()\n } else if (this.next_read_resolution) {\n this.next_read_resolution = false\n this.mouse_buffer.clear()\n this.mouse_buffer.push(0xfa)\n\n if (write_byte > 3) {\n this.resolution = 4\n dbg_log('invalid resolution, resetting to 4', LOG_PS2)\n } else {\n this.resolution = 1 << write_byte\n dbg_log('resolution: ' + this.resolution, LOG_PS2)\n }\n this.mouse_irq()\n } else if (this.next_read_led) {\n // nope\n this.next_read_led = false\n this.kbd_buffer.push(0xfa)\n this.kbd_irq()\n } else if (this.next_handle_scan_code_set) {\n this.next_handle_scan_code_set = false\n\n this.kbd_buffer.push(0xfa)\n this.kbd_irq()\n\n if (write_byte) {\n // set scan code set\n } else {\n this.kbd_buffer.push(1)\n }\n } else if (this.next_read_rate) {\n // nope\n this.next_read_rate = false\n this.kbd_buffer.push(0xfa)\n this.kbd_irq()\n } else if (this.next_is_mouse_command) {\n this.next_is_mouse_command = false\n dbg_log('Port 60 data register write: ' + h(write_byte), LOG_PS2)\n\n if (!this.have_mouse) {\n return\n }\n\n // send ack\n this.kbd_buffer.clear()\n this.mouse_buffer.clear()\n this.mouse_buffer.push(0xfa)\n\n switch (write_byte) {\n case 0xe6:\n // set scaling to 1:1\n dbg_log('Scaling 1:1', LOG_PS2)\n this.scaling2 = false\n break\n case 0xe7:\n // set scaling to 2:1\n dbg_log('Scaling 2:1', LOG_PS2)\n this.scaling2 = true\n break\n case 0xe8:\n // set mouse resolution\n this.next_read_resolution = true\n break\n case 0xe9:\n // status request - send one packet\n this.send_mouse_packet(0, 0)\n break\n case 0xeb:\n // request single packet\n dbg_log('unimplemented request single packet', LOG_PS2)\n this.send_mouse_packet(0, 0)\n break\n case 0xf2:\n // MouseID Byte\n dbg_log('required id: ' + h(this.mouse_id), LOG_PS2)\n this.mouse_buffer.push(this.mouse_id)\n\n this.mouse_clicks =\n this.mouse_delta_x =\n this.mouse_delta_y =\n 0\n // this.send_mouse_packet(0, 0);\n this.raise_irq()\n break\n case 0xf3:\n // sample rate\n this.next_read_sample = true\n break\n case 0xf4:\n // enable streaming\n this.enable_mouse_stream = true\n this.use_mouse = true\n this.bus.send('mouse-enable', true)\n\n this.mouse_clicks =\n this.mouse_delta_x =\n this.mouse_delta_y =\n 0\n break\n case 0xf5:\n // disable streaming\n this.enable_mouse_stream = false\n break\n case 0xf6:\n // set defaults\n this.enable_mouse_stream = false\n this.sample_rate = 100\n this.scaling2 = false\n this.resolution = 4\n break\n case 0xff:\n // reset, send completion code\n dbg_log('Mouse reset', LOG_PS2)\n this.mouse_buffer.push(0xaa)\n this.mouse_buffer.push(0)\n\n this.use_mouse = true\n this.bus.send('mouse-enable', true)\n\n this.enable_mouse_stream = false\n this.sample_rate = 100\n this.scaling2 = false\n this.resolution = 4\n\n if (!this.mouse_reset_workaround) {\n this.mouse_id = 0x00\n }\n\n this.mouse_clicks =\n this.mouse_delta_x =\n this.mouse_delta_y =\n 0\n break\n\n default:\n dbg_log(\n 'Unimplemented mouse command: ' + h(write_byte),\n LOG_PS2,\n )\n }\n\n this.mouse_irq()\n } else if (this.read_controller_output_port) {\n this.read_controller_output_port = false\n this.controller_output_port = write_byte\n // If we ever want to implement A20 masking, here is where\n // we should turn the masking off if the second bit is on\n } else {\n dbg_log('Port 60 data register write: ' + h(write_byte), LOG_PS2)\n\n // send ack\n this.mouse_buffer.clear()\n this.kbd_buffer.clear()\n this.kbd_buffer.push(0xfa)\n\n switch (write_byte) {\n case 0xed:\n this.next_read_led = true\n break\n case 0xf0:\n // get/set scan code set\n this.next_handle_scan_code_set = true\n break\n case 0xf2:\n // identify\n this.kbd_buffer.push(0xab)\n this.kbd_buffer.push(0x83)\n break\n case 0xf3:\n // Set typematic rate and delay\n this.next_read_rate = true\n break\n case 0xf4:\n // enable scanning\n dbg_log('kbd enable scanning', LOG_PS2)\n this.enable_keyboard_stream = true\n break\n case 0xf5:\n // disable scanning\n dbg_log('kbd disable scanning', LOG_PS2)\n this.enable_keyboard_stream = false\n break\n case 0xf6:\n // reset defaults\n //this.enable_keyboard_stream = false;\n break\n case 0xff:\n this.kbd_buffer.clear()\n this.kbd_buffer.push(0xfa)\n this.kbd_buffer.push(0xaa)\n this.kbd_buffer.push(0)\n break\n default:\n dbg_log(\n 'Unimplemented keyboard command: ' + h(write_byte),\n LOG_PS2,\n )\n }\n\n this.kbd_irq()\n }\n }\n\n port64_write(write_byte: number): void {\n dbg_log('port 64 write: ' + h(write_byte), LOG_PS2)\n\n switch (write_byte) {\n case 0x20:\n this.kbd_buffer.clear()\n this.mouse_buffer.clear()\n this.kbd_buffer.push(this.command_register)\n this.kbd_irq()\n break\n case 0x60:\n this.read_command_register = true\n break\n case 0xd1:\n this.read_controller_output_port = true\n break\n case 0xd3:\n this.read_output_register = true\n break\n case 0xd4:\n this.next_is_mouse_command = true\n break\n case 0xa7:\n // Disable second port\n dbg_log('Disable second port', LOG_PS2)\n this.command_register |= 0x20\n break\n case 0xa8:\n // Enable second port\n dbg_log('Enable second port', LOG_PS2)\n this.command_register &= ~0x20\n break\n case 0xa9:\n // test second ps/2 port\n this.kbd_buffer.clear()\n this.mouse_buffer.clear()\n this.kbd_buffer.push(0)\n this.kbd_irq()\n break\n case 0xaa:\n this.kbd_buffer.clear()\n this.mouse_buffer.clear()\n this.kbd_buffer.push(0x55)\n this.kbd_irq()\n break\n case 0xab:\n // Test first PS/2 port\n this.kbd_buffer.clear()\n this.mouse_buffer.clear()\n this.kbd_buffer.push(0)\n this.kbd_irq()\n break\n case 0xad:\n // Disable Keyboard\n dbg_log('Disable Keyboard', LOG_PS2)\n this.command_register |= 0x10\n break\n case 0xae:\n // Enable Keyboard\n dbg_log('Enable Keyboard', LOG_PS2)\n this.command_register &= ~0x10\n break\n case 0xfe:\n dbg_log('CPU reboot via PS2')\n this.cpu.reboot_internal()\n break\n default:\n dbg_log(\n 'port 64: Unimplemented command byte: ' + h(write_byte),\n LOG_PS2,\n )\n }\n }\n}\n", "declare let DEBUG: boolean\n\nimport { dbg_log, LOG_LEVEL } from './log.js'\n\n// A minimal elf parser for loading 32 bit, x86, little endian, executable elf files\n\nconst ELF_MAGIC = 0x464c457f\n\ninterface FieldType {\n size: number\n get: (offset: number, littleEndian?: boolean) => number\n set?: (offset: number, value: number, littleEndian?: boolean) => void\n}\n\ninterface StructEntry {\n name: string\n type: FieldType\n size: number\n get: (offset: number, littleEndian?: boolean) => number\n set:\n | ((offset: number, value: number, littleEndian?: boolean) => void)\n | undefined\n}\n\ntype StructRecord = Record<string, number>\n\nexport interface ElfResult {\n header: StructRecord\n program_headers: StructRecord[]\n sections_headers: StructRecord[]\n}\n\nconst types = DataView.prototype\nconst U8: FieldType = { size: 1, get: types.getUint8, set: types.setUint8 }\nconst U16: FieldType = { size: 2, get: types.getUint16, set: types.setUint16 }\nconst U32: FieldType = { size: 4, get: types.getUint32, set: types.setUint32 }\nconst pad = function (size: number): FieldType {\n return {\n size,\n get: (_offset: number): number => -1,\n }\n}\n\nconst Header: StructEntry[] = create_struct([\n { magic: U32 },\n\n { class: U8 },\n { data: U8 },\n { version0: U8 },\n { osabi: U8 },\n\n { abiversion: U8 },\n { pad0: pad(7) },\n\n { type: U16 },\n { machine: U16 },\n\n { version1: U32 },\n { entry: U32 },\n { phoff: U32 },\n { shoff: U32 },\n { flags: U32 },\n\n { ehsize: U16 },\n { phentsize: U16 },\n { phnum: U16 },\n { shentsize: U16 },\n { shnum: U16 },\n { shstrndx: U16 },\n])\nconsole.assert(\n Header.reduce((a: number, entry: StructEntry) => a + entry.size, 0) === 52,\n)\n\nconst ProgramHeader: StructEntry[] = create_struct([\n { type: U32 },\n { offset: U32 },\n { vaddr: U32 },\n { paddr: U32 },\n { filesz: U32 },\n { memsz: U32 },\n { flags: U32 },\n { align: U32 },\n])\nconsole.assert(\n ProgramHeader.reduce(\n (a: number, entry: StructEntry) => a + entry.size,\n 0,\n ) === 32,\n)\n\nconst SectionHeader: StructEntry[] = create_struct([\n { name: U32 },\n { type: U32 },\n { flags: U32 },\n { addr: U32 },\n { offset: U32 },\n { size: U32 },\n { link: U32 },\n { info: U32 },\n { addralign: U32 },\n { entsize: U32 },\n])\nconsole.assert(\n SectionHeader.reduce(\n (a: number, entry: StructEntry) => a + entry.size,\n 0,\n ) === 40,\n)\n\n// From [{ name: type }, ...] to [{ name, type, size, get, set }, ...]\nfunction create_struct(struct: Record<string, FieldType>[]): StructEntry[] {\n return struct.map(function (entry: Record<string, FieldType>): StructEntry {\n const keys = Object.keys(entry)\n console.assert(keys.length === 1)\n const name = keys[0]\n const type = entry[name]\n\n console.assert(type.size > 0)\n\n return {\n name,\n type,\n size: type.size,\n get: type.get,\n set: type.set,\n }\n })\n}\n\nexport function read_elf(buffer: ArrayBuffer): ElfResult {\n const view = new DataView(buffer)\n\n const [header, offset] = read_struct(view, Header)\n console.assert(offset === 52)\n\n if (DEBUG) {\n for (const key of Object.keys(header)) {\n dbg_log(key + ': 0x' + (Number(header[key].toString(16)) >>> 0))\n }\n }\n\n console.assert(header.magic === ELF_MAGIC, 'Bad magic')\n console.assert(header.class === 1, 'Unimplemented: 64 bit elf')\n console.assert(header.data === 1, 'Unimplemented: big endian')\n console.assert(header.version0 === 1, 'Bad version0')\n\n // 1, 2, 3, 4 specify whether the object is relocatable, executable,\n // shared, or core, respectively.\n console.assert(header.type === 2, 'Unimplemented type')\n\n console.assert(header.version1 === 1, 'Bad version1')\n\n // these are different in 64 bit\n console.assert(header.ehsize === 52, 'Bad header size')\n console.assert(header.phentsize === 32, 'Bad program header size')\n console.assert(header.shentsize === 40, 'Bad section header size')\n\n const [program_headers, _ph_offset] = read_structs(\n view_slice(view, header.phoff, header.phentsize * header.phnum),\n ProgramHeader,\n header.phnum,\n )\n\n const [sections_headers, _sh_offset] = read_structs(\n view_slice(view, header.shoff, header.shentsize * header.shnum),\n SectionHeader,\n header.shnum,\n )\n\n if (DEBUG && LOG_LEVEL) {\n console.log('%d program headers:', program_headers.length)\n for (const program of program_headers) {\n console.log(\n 'type=%s offset=%s vaddr=%s paddr=%s ' +\n 'filesz=%s memsz=%s flags=%s align=%s',\n program.type.toString(16),\n program.offset.toString(16),\n program.vaddr.toString(16),\n program.paddr.toString(16),\n program.filesz.toString(16),\n program.memsz.toString(16),\n program.flags.toString(16),\n program.align.toString(16),\n )\n }\n\n console.log('%d section headers:', sections_headers.length)\n for (const section of sections_headers) {\n console.log(\n 'name=%s type=%s flags=%s addr=%s offset=%s ' +\n 'size=%s link=%s info=%s addralign=%s entsize=%s',\n section.name.toString(16),\n section.type.toString(16),\n section.flags.toString(16),\n section.addr.toString(16),\n section.offset.toString(16),\n section.size.toString(16),\n section.link.toString(16),\n section.info.toString(16),\n section.addralign.toString(16),\n section.entsize.toString(16),\n )\n }\n }\n\n return {\n header,\n program_headers,\n sections_headers,\n }\n}\n\nfunction read_struct(\n view: DataView,\n Struct: StructEntry[],\n): [StructRecord, number] {\n const result: StructRecord = {}\n let offset = 0\n const LITTLE_ENDIAN = true // big endian not supported yet\n\n for (const entry of Struct) {\n const value = entry.get.call(view, offset, LITTLE_ENDIAN)\n console.assert(result[entry.name] === undefined)\n result[entry.name] = value\n offset += entry.size\n }\n\n return [result, offset]\n}\n\nfunction read_structs(\n view: DataView,\n Struct: StructEntry[],\n count: number,\n): [StructRecord[], number] {\n const result: StructRecord[] = []\n let offset = 0\n\n for (let i = 0; i < count; i++) {\n const [s, size] = read_struct(view_slice(view, offset), Struct)\n result.push(s)\n offset += size\n }\n\n return [result, offset]\n}\n\nfunction view_slice(view: DataView, offset: number, length?: number): DataView {\n return new DataView(view.buffer, view.byteOffset + offset, length)\n}\n", "import { v86 } from './main.js'\nimport { LOG_RTC } from './const.js'\nimport { h } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\nimport { IO } from './io.js'\n\n// Minimal interface for CPU fields RTC uses\ninterface RTCCpu {\n io: IO\n device_raise_irq(irq: number): void\n device_lower_irq(irq: number): void\n}\n\nexport const CMOS_RTC_SECONDS = 0x00\nexport const CMOS_RTC_SECONDS_ALARM = 0x01\nexport const CMOS_RTC_MINUTES = 0x02\nexport const CMOS_RTC_MINUTES_ALARM = 0x03\nexport const CMOS_RTC_HOURS = 0x04\nexport const CMOS_RTC_HOURS_ALARM = 0x05\nexport const CMOS_RTC_DAY_WEEK = 0x06\nexport const CMOS_RTC_DAY_MONTH = 0x07\nexport const CMOS_RTC_MONTH = 0x08\nexport const CMOS_RTC_YEAR = 0x09\nexport const CMOS_STATUS_A = 0x0a\nexport const CMOS_STATUS_B = 0x0b\nexport const CMOS_STATUS_C = 0x0c\nexport const CMOS_STATUS_D = 0x0d\nexport const CMOS_DIAG_STATUS = 0x0e\nexport const CMOS_RESET_CODE = 0x0f\n\nexport const CMOS_FLOPPY_DRIVE_TYPE = 0x10\nexport const CMOS_DISK_DATA = 0x12\nexport const CMOS_EQUIPMENT_INFO = 0x14\nexport const CMOS_MEM_BASE_LOW = 0x15\nexport const CMOS_MEM_BASE_HIGH = 0x16\nexport const CMOS_MEM_OLD_EXT_LOW = 0x17\nexport const CMOS_MEM_OLD_EXT_HIGH = 0x18\nexport const CMOS_DISK_DRIVE1_TYPE = 0x19\nexport const CMOS_DISK_DRIVE2_TYPE = 0x1a\nexport const CMOS_DISK_DRIVE1_CYL = 0x1b\nexport const CMOS_DISK_DRIVE2_CYL = 0x24\nexport const CMOS_MEM_EXTMEM_LOW = 0x30\nexport const CMOS_MEM_EXTMEM_HIGH = 0x31\nexport const CMOS_CENTURY = 0x32\nexport const CMOS_MEM_EXTMEM2_LOW = 0x34\nexport const CMOS_MEM_EXTMEM2_HIGH = 0x35\nexport const CMOS_CENTURY2 = 0x37\nexport const CMOS_BIOS_BOOTFLAG1 = 0x38\nexport const CMOS_BIOS_DISKTRANSFLAG = 0x39\nexport const CMOS_BIOS_BOOTFLAG2 = 0x3d\nexport const CMOS_MEM_HIGHMEM_LOW = 0x5b\nexport const CMOS_MEM_HIGHMEM_MID = 0x5c\nexport const CMOS_MEM_HIGHMEM_HIGH = 0x5d\nexport const CMOS_BIOS_SMP_COUNT = 0x5f\n\n// see CPU.prototype.fill_cmos\nexport const BOOT_ORDER_CD_FIRST = 0x123\nexport const BOOT_ORDER_HD_FIRST = 0x312\nexport const BOOT_ORDER_FD_FIRST = 0x321\n\ntype RTCState = [\n number,\n Uint8Array,\n number,\n number,\n number,\n number,\n boolean,\n number,\n number,\n number,\n number,\n number,\n boolean,\n number,\n number,\n]\n\n/**\n * RTC (real time clock) and CMOS\n */\nexport class RTC {\n name: string\n cpu: RTCCpu\n cmos_index: number\n cmos_data: Uint8Array\n rtc_time: number\n last_update: number\n next_interrupt: number\n next_interrupt_alarm: number\n periodic_interrupt: boolean\n periodic_interrupt_time: number\n cmos_a: number\n cmos_b: number\n cmos_c: number\n cmos_diag_status: number\n nmi_disabled: number\n update_interrupt: boolean\n update_interrupt_time: number\n\n constructor(cpu: RTCCpu) {\n this.name = 'rtc'\n this.cpu = cpu\n\n this.cmos_index = 0\n this.cmos_data = new Uint8Array(128)\n\n // used for cmos entries\n this.rtc_time = Date.now()\n this.last_update = this.rtc_time\n\n // used for periodic interrupt\n this.next_interrupt = 0\n\n // next alarm interrupt\n this.next_interrupt_alarm = 0\n\n this.periodic_interrupt = false\n\n // corresponds to default value for cmos_a\n this.periodic_interrupt_time = 1000 / 1024\n\n this.cmos_a = 0x26\n this.cmos_b = 2\n this.cmos_c = 0\n\n this.cmos_diag_status = 0\n\n this.nmi_disabled = 0\n\n this.update_interrupt = false\n this.update_interrupt_time = 0\n\n cpu.io.register_write(0x70, this, (out_byte: number): void => {\n this.cmos_index = out_byte & 0x7f\n this.nmi_disabled = out_byte >> 7\n })\n\n cpu.io.register_write(0x71, this, this.cmos_port_write.bind(this))\n cpu.io.register_read(0x71, this, this.cmos_port_read.bind(this))\n }\n\n get_state(): RTCState {\n const state: RTCState = [\n this.cmos_index,\n this.cmos_data,\n this.rtc_time,\n this.last_update,\n this.next_interrupt,\n this.next_interrupt_alarm,\n this.periodic_interrupt,\n this.periodic_interrupt_time,\n this.cmos_a,\n this.cmos_b,\n this.cmos_c,\n this.nmi_disabled,\n this.update_interrupt,\n this.update_interrupt_time,\n this.cmos_diag_status,\n ]\n\n return state\n }\n\n set_state(state: RTCState): void {\n this.cmos_index = state[0]\n this.cmos_data = state[1]\n this.rtc_time = state[2]\n this.last_update = state[3]\n this.next_interrupt = state[4]\n this.next_interrupt_alarm = state[5]\n this.periodic_interrupt = state[6]\n this.periodic_interrupt_time = state[7]\n this.cmos_a = state[8]\n this.cmos_b = state[9]\n this.cmos_c = state[10]\n this.nmi_disabled = state[11]\n this.update_interrupt = state[12] || false\n this.update_interrupt_time = state[13] || 0\n this.cmos_diag_status = state[14] || 0\n }\n\n timer(time: number, _legacy_mode: boolean): number {\n time = Date.now() // XXX\n this.rtc_time += time - this.last_update\n this.last_update = time\n\n if (this.periodic_interrupt && this.next_interrupt < time) {\n this.cpu.device_raise_irq(8)\n this.cmos_c |= (1 << 6) | (1 << 7)\n\n this.next_interrupt +=\n this.periodic_interrupt_time *\n Math.ceil(\n (time - this.next_interrupt) / this.periodic_interrupt_time,\n )\n } else if (\n this.next_interrupt_alarm &&\n this.next_interrupt_alarm < time\n ) {\n this.cpu.device_raise_irq(8)\n this.cmos_c |= (1 << 5) | (1 << 7)\n\n this.next_interrupt_alarm = 0\n } else if (this.update_interrupt && this.update_interrupt_time < time) {\n this.cpu.device_raise_irq(8)\n this.cmos_c |= (1 << 4) | (1 << 7)\n\n this.update_interrupt_time = time + 1000 // 1 second\n }\n\n let t = 100\n\n if (this.periodic_interrupt && this.next_interrupt) {\n t = Math.min(t, Math.max(0, this.next_interrupt - time))\n }\n if (this.next_interrupt_alarm) {\n t = Math.min(t, Math.max(0, this.next_interrupt_alarm - time))\n }\n if (this.update_interrupt) {\n t = Math.min(t, Math.max(0, this.update_interrupt_time - time))\n }\n\n return t\n }\n\n bcd_pack(n: number): number {\n let i = 0,\n result = 0,\n digit: number\n\n while (n) {\n digit = n % 10\n\n result |= digit << (4 * i)\n i++\n n = (n - digit) / 10\n }\n\n return result\n }\n\n bcd_unpack(n: number): number {\n const low = n & 0xf\n const high = (n >> 4) & 0xf\n\n dbg_assert(n < 0x100)\n dbg_assert(low < 10)\n dbg_assert(high < 10)\n\n return low + 10 * high\n }\n\n encode_time(t: number): number {\n if (this.cmos_b & 4) {\n // binary mode\n return t\n } else {\n return this.bcd_pack(t)\n }\n }\n\n decode_time(t: number): number {\n if (this.cmos_b & 4) {\n // binary mode\n return t\n } else {\n return this.bcd_unpack(t)\n }\n }\n\n // TODO\n // - interrupt on update\n // - countdown\n // - letting bios/os set values\n // (none of these are used by seabios or the OSes we're\n // currently testing)\n cmos_port_read(): number {\n const index = this.cmos_index\n\n //this.cmos_index = 0xD;\n\n switch (index) {\n case CMOS_RTC_SECONDS:\n dbg_log(\n 'read second: ' +\n h(\n this.encode_time(\n new Date(this.rtc_time).getUTCSeconds(),\n ),\n ),\n LOG_RTC,\n )\n return this.encode_time(new Date(this.rtc_time).getUTCSeconds())\n case CMOS_RTC_MINUTES:\n dbg_log(\n 'read minute: ' +\n h(\n this.encode_time(\n new Date(this.rtc_time).getUTCMinutes(),\n ),\n ),\n LOG_RTC,\n )\n return this.encode_time(new Date(this.rtc_time).getUTCMinutes())\n case CMOS_RTC_HOURS:\n dbg_log(\n 'read hour: ' +\n h(\n this.encode_time(\n new Date(this.rtc_time).getUTCHours(),\n ),\n ),\n LOG_RTC,\n )\n // TODO: 12 hour mode\n return this.encode_time(new Date(this.rtc_time).getUTCHours())\n case CMOS_RTC_DAY_WEEK:\n dbg_log(\n 'read day: ' +\n h(\n this.encode_time(\n new Date(this.rtc_time).getUTCDay() + 1,\n ),\n ),\n LOG_RTC,\n )\n return this.encode_time(new Date(this.rtc_time).getUTCDay() + 1)\n case CMOS_RTC_DAY_MONTH:\n dbg_log(\n 'read day of month: ' +\n h(\n this.encode_time(\n new Date(this.rtc_time).getUTCDate(),\n ),\n ),\n LOG_RTC,\n )\n return this.encode_time(new Date(this.rtc_time).getUTCDate())\n case CMOS_RTC_MONTH:\n dbg_log(\n 'read month: ' +\n h(\n this.encode_time(\n new Date(this.rtc_time).getUTCMonth() + 1,\n ),\n ),\n LOG_RTC,\n )\n return this.encode_time(\n new Date(this.rtc_time).getUTCMonth() + 1,\n )\n case CMOS_RTC_YEAR:\n dbg_log(\n 'read year: ' +\n h(\n this.encode_time(\n new Date(this.rtc_time).getUTCFullYear() % 100,\n ),\n ),\n LOG_RTC,\n )\n return this.encode_time(\n new Date(this.rtc_time).getUTCFullYear() % 100,\n )\n\n case CMOS_STATUS_A:\n if (v86.microtick() % 1000 >= 999) {\n // Set update-in-progress for one millisecond every second (we\n // may not have precision higher than that in browser\n // environments)\n return this.cmos_a | 0x80\n }\n return this.cmos_a\n case CMOS_STATUS_B:\n //dbg_log(\"cmos read from index \" + h(index));\n return this.cmos_b\n\n case CMOS_STATUS_C: {\n // It is important to know that upon a IRQ 8, Status Register C\n // will contain a bitmask telling which interrupt happened.\n // What is important is that if register C is not read after an\n // IRQ 8, then the interrupt will not happen again.\n this.cpu.device_lower_irq(8)\n\n dbg_log('cmos reg C read', LOG_RTC)\n // Missing IRQF flag\n //return cmos_b & 0x70;\n const c = this.cmos_c\n\n this.cmos_c &= ~0xf0\n\n return c\n }\n\n case CMOS_STATUS_D:\n return 1 << 7 // CMOS battery charged\n\n case CMOS_DIAG_STATUS:\n dbg_log('cmos diagnostic status read', LOG_RTC)\n return this.cmos_diag_status\n\n case CMOS_CENTURY:\n case CMOS_CENTURY2:\n dbg_log(\n 'read century: ' +\n h(\n this.encode_time(\n (new Date(this.rtc_time).getUTCFullYear() /\n 100) |\n 0,\n ),\n ),\n LOG_RTC,\n )\n return this.encode_time(\n (new Date(this.rtc_time).getUTCFullYear() / 100) | 0,\n )\n\n default:\n dbg_log('cmos read from index ' + h(index), LOG_RTC)\n return this.cmos_data[this.cmos_index]\n }\n }\n\n cmos_port_write(data_byte: number): void {\n switch (this.cmos_index) {\n case 0xa:\n this.cmos_a = data_byte & 0x7f\n this.periodic_interrupt_time =\n 1000 / (32768 >> ((this.cmos_a & 0xf) - 1))\n\n dbg_log(\n 'Periodic interrupt, a=' +\n h(this.cmos_a, 2) +\n ' t=' +\n this.periodic_interrupt_time,\n LOG_RTC,\n )\n break\n case 0xb:\n this.cmos_b = data_byte\n if (this.cmos_b & 0x80) {\n // remove update interrupt flag\n this.cmos_b &= 0xef\n }\n if (this.cmos_b & 0x40) {\n this.next_interrupt = Date.now()\n }\n\n if (this.cmos_b & 0x20) {\n const now = new Date()\n\n const seconds = this.decode_time(\n this.cmos_data[CMOS_RTC_SECONDS_ALARM],\n )\n const minutes = this.decode_time(\n this.cmos_data[CMOS_RTC_MINUTES_ALARM],\n )\n const hours = this.decode_time(\n this.cmos_data[CMOS_RTC_HOURS_ALARM],\n )\n\n const alarm_date = new Date(\n Date.UTC(\n now.getUTCFullYear(),\n now.getUTCMonth(),\n now.getUTCDate(),\n hours,\n minutes,\n seconds,\n ),\n )\n\n const ms_from_now = +alarm_date - +now\n dbg_log(\n 'RTC alarm scheduled for ' +\n alarm_date +\n ' hh:mm:ss=' +\n hours +\n ':' +\n minutes +\n ':' +\n seconds +\n ' ms_from_now=' +\n ms_from_now,\n LOG_RTC,\n )\n\n this.next_interrupt_alarm = +alarm_date\n }\n\n if (this.cmos_b & 0x10) {\n dbg_log('update interrupt', LOG_RTC)\n this.update_interrupt_time = Date.now()\n }\n\n dbg_log('cmos b=' + h(this.cmos_b, 2), LOG_RTC)\n break\n\n case CMOS_DIAG_STATUS:\n this.cmos_diag_status = data_byte\n break\n\n case CMOS_RTC_SECONDS_ALARM:\n case CMOS_RTC_MINUTES_ALARM:\n case CMOS_RTC_HOURS_ALARM:\n this.cmos_write(this.cmos_index, data_byte)\n break\n\n default:\n dbg_log(\n 'cmos write index ' +\n h(this.cmos_index) +\n ': ' +\n h(data_byte),\n LOG_RTC,\n )\n }\n\n this.update_interrupt =\n (this.cmos_b & 0x10) === 0x10 && (this.cmos_a & 0xf) > 0\n this.periodic_interrupt =\n (this.cmos_b & 0x40) === 0x40 && (this.cmos_a & 0xf) > 0\n }\n\n cmos_read(index: number): number {\n dbg_assert(index < 128)\n return this.cmos_data[index]\n }\n\n cmos_write(index: number, value: number): void {\n dbg_log('cmos ' + h(index) + ' <- ' + h(value), LOG_RTC)\n dbg_assert(index < 128)\n this.cmos_data[index] = value\n }\n}\n", "// v86 Floppy Disk Controller emulation\n//\n// This file is licensed under both BSD and MIT, see LICENSE and LICENSE.MIT.\n//\n// Links\n// - Intel 82078 44 Pin CHMOS Single-Chip Floppy Disk Controller\n// https://wiki.qemu.org/images/f/f0/29047403.pdf\n// - qemu: fdc.c\n// https://github.com/qemu/qemu/blob/master/hw/block/fdc.c\n// - Programming Floppy Disk Controllers\n// https://www.isdaman.com/alsos/hardware/fdc/floppy.htm\n// - OSDev: Floppy Disk Controller\n// https://wiki.osdev.org/Floppy_Disk_Controller\n\ndeclare let DEBUG: boolean\n\nimport { LOG_FLOPPY } from './const.js'\nimport { h } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\nimport { CMOS_FLOPPY_DRIVE_TYPE } from './rtc.js'\nimport { SyncBuffer } from './buffer.js'\nimport { DMA } from './dma.js'\nimport { IO } from './io.js'\n\n// Minimal interface for the CPU fields FloppyController uses.\ninterface FloppyCpu {\n io: IO\n devices: {\n dma: DMA\n rtc: { cmos_write(register: number, value: number): void }\n }\n device_raise_irq(irq: number): void\n device_lower_irq(irq: number): void\n}\n\ninterface FloppyDriveConfig {\n drive_type?: number\n read_only?: boolean\n}\n\ninterface FloppyControllerConfig {\n fda?: FloppyDriveConfig\n fdb?: FloppyDriveConfig\n}\n\n// System resources\nconst FDC_IRQ_CHANNEL = 6\nconst FDC_DMA_CHANNEL = 2\n\n/**\n * Floppy drive types\n * CMOS register 0x10 bits: upper nibble: fda, lower nibble: fdb\n * @see {@link https://wiki.osdev.org/CMOS#Register_0x10}\n */\nconst CMOS_FDD_TYPE_NO_DRIVE = 0x0 // no floppy drive\nconst CMOS_FDD_TYPE_360 = 0x1 // 360 KB 5\"1/4 drive\nconst CMOS_FDD_TYPE_1200 = 0x2 // 1.2 MB 5\"1/4 drive\nconst CMOS_FDD_TYPE_720 = 0x3 // 720 KB 3\"1/2 drive\nconst CMOS_FDD_TYPE_1440 = 0x4 // 1.44 MB 3\"1/2 drive\nconst CMOS_FDD_TYPE_2880 = 0x5 // 2.88 MB 3\"1/2 drive\n\n// Physical floppy disk size identifier of each drive type\nconst CMOS_FDD_TYPE_MEDIUM: Record<number, number> = {\n [CMOS_FDD_TYPE_NO_DRIVE]: 0, // no disk\n [CMOS_FDD_TYPE_360]: 525, // 5\"1/4 disk\n [CMOS_FDD_TYPE_1200]: 525, // 5\"1/4 disk\n [CMOS_FDD_TYPE_720]: 350, // 3\"1/2 disk\n [CMOS_FDD_TYPE_1440]: 350, // 3\"1/2 disk\n [CMOS_FDD_TYPE_2880]: 350, // 3\"1/2 disk\n}\n\n// Floppy Controller PIO Register offsets (base: 0x3F0/0x370, offset 0x6 is reserved for ATA IDE)\nconst REG_SRA = 0x0 // R, Status Register A (SRA)\nconst REG_SRB = 0x1 // R, Status Register B (SRB)\nconst REG_DOR = 0x2 // RW, Digital Output Register (DOR)\nconst REG_TDR = 0x3 // RW, Tape Drive Register (TDR)\nconst REG_MSR = 0x4 // R, Main Status Register (MSR)\nconst REG_DSR = 0x4 // W, Datarate Select Register (DSR)\nconst REG_FIFO = 0x5 // RW, W: command bytes, R: response bytes (FIFO)\nconst REG_DIR = 0x7 // R, Digital Input Register (DIR)\nconst REG_CCR = 0x7 // W, Configuration Control Register (CCR)\n\n// Status Register A (SRA) bits\nconst _SRA_NDRV2 = 0x40 // true: second drive is not connected\nconst SRA_INTPEND = 0x80 // true: interrupt pending\n\n// Status Register B (SRB) bits\nconst SRB_MTR0 = 0x1 // follows DOR.DOR_MOT0\nconst SRB_MTR1 = 0x2 // follows DOR.DOR_MOT1\nconst SRB_DR0 = 0x20 // follows DOR.DOR_SEL_LO\nconst SRB_RESET = 0xc0 // magic value after reset\n\n// Digital Output Register (DOR) bits\nconst DOR_SEL_LO = 0x1 // lower bit of selected FDD number\nconst DOR_SEL_HI = 0x2 // upper bit of selected FDD number\nconst DOR_NRESET = 0x4 // true: normal controller mode, false: reset mode (\"not RESET\")\nconst DOR_DMAEN = 0x8 // true: use DMA\nconst DOR_MOTEN0 = 0x10 // true: enable motor of FDD0\nconst DOR_MOTEN1 = 0x20 // true: enable motor of FDD1\nconst _DOR_MOTEN2 = 0x40 // true: enable motor of FDD2\nconst _DOR_MOTEN3 = 0x80 // true: enable motor of FDD3\nconst DOR_SELMASK = 0x01\n\n// Tape Drive Register (TDR) bits\nconst TDR_BOOTSEL = 0x4\n\n// Main Status Register (MSR) bits\nconst _MSR_FDD0 = 0x1 // true: FDD0 is busy in seek mode\nconst _MSR_FDD1 = 0x2 // true: FDD1 is busy in seek mode\nconst _MSR_FDD2 = 0x4 // true: FDD2 is busy in seek mode\nconst _MSR_FDD3 = 0x8 // true: FDD3 is busy in seek mode\nconst MSR_CMDBUSY = 0x10 // true: FDC busy, Read/Write command in progress, cleared at end of Result phase\nconst MSR_NDMA = 0x20 // Non-DMA mode, set in Execution phase of PIO mode read/write commands only.\nconst MSR_DIO = 0x40 // Data Input/Output, true: FDC has data for CPU, false: FDC expects data from CPU\nconst MSR_RQM = 0x80 // true: DATA register is ready for I/O\n\n// Datarate Select Register (DSR) bits\nconst DSR_DRATEMASK = 0x3\nconst DSR_PWRDOWN = 0x40\nconst DSR_SWRESET = 0x80\n\n// Digital Input Register (DIR) bits\nconst DIR_DOOR = 0x80 // true: No disk or disk changed since last command\n\n// Status Register 0 (SR0) bits\nconst SR0_DS0 = 0x1 // Drive select 0..3 lower bit\nconst SR0_DS1 = 0x2 // Drive select 0..3 upper bit\nconst SR0_HEAD = 0x4 // true: Use 2nd head\nconst _SR0_EQPMT = 0x10 // (?)\nconst SR0_SEEK = 0x20 // (?)\nconst SR0_ABNTERM = 0x40 // true: Command failed\nconst SR0_INVCMD = 0x80 // true: Unknown/unimplemented command code\nconst SR0_RDYCHG = SR0_ABNTERM | SR0_INVCMD // 0xC0 (?)\n\n// Status Register 1 (SR1) bits\nconst SR1_MA = 0x1 // true: Missing address mark error\nconst SR1_NW = 0x2 // true: Not writable error\nconst SR1_EC = 0x80 // true: End of cylinder error\n\n// Status Register 2 (SR2) bits\nconst _SR2_SNS = 0x4 // true: Scan not satisfied (?)\nconst _SR2_SEH = 0x8 // true: Scan equal hit (?)\n\n/**\n * FDC command codes\n * We declare all known floppy commands but implement only the subset that\n * we actually observe in the field. See also build_cmd_lookup_table().\n * @see {@link https://github.com/qemu/qemu/blob/6e1571533fd92bec67e5ab9b1dd1e15032925757/hw/block/fdc.c#L619}\n */\nconst CMD_READ_TRACK = 0x2 // unimplemented\nconst CMD_SPECIFY = 0x3\nconst CMD_SENSE_DRIVE_STATUS = 0x4\nconst CMD_WRITE = 0x5\nconst CMD_READ = 0x6\nconst CMD_RECALIBRATE = 0x7\nconst CMD_SENSE_INTERRUPT_STATUS = 0x8\nconst CMD_WRITE_DELETED_DATA = 0x9 // unimplemented\nconst CMD_READ_ID = 0xa\nconst CMD_READ_DELETED_DATA = 0xc // unimplemented\nconst CMD_FORMAT_TRACK = 0xd\nconst CMD_DUMP_REGS = 0xe\nconst CMD_SEEK = 0xf\nconst CMD_VERSION = 0x10\nconst CMD_SCAN_EQUAL = 0x11 // unimplemented\nconst CMD_PERPENDICULAR_MODE = 0x12\nconst CMD_CONFIGURE = 0x13\nconst CMD_LOCK = 0x14\nconst CMD_VERIFY = 0x16 // unimplemented\nconst CMD_POWERDOWN_MODE = 0x17 // unimplemented\nconst CMD_PART_ID = 0x18\nconst CMD_SCAN_LOW_OR_EQUAL = 0x19 // unimplemented\nconst CMD_SCAN_HIGH_OR_EQUAL = 0x1d // unimplemented\nconst CMD_SAVE = 0x2e // unimplemented\nconst CMD_OPTION = 0x33 // unimplemented\nconst CMD_RESTORE = 0x4e // unimplemented\nconst CMD_DRIVE_SPECIFICATION = 0x8e // unimplemented\nconst CMD_RELATIVE_SEEK_OUT = 0x8f // unimplemented\nconst CMD_FORMAT_AND_WRITE = 0xcd // unimplemented\nconst CMD_RELATIVE_SEEK_IN = 0xcf // unimplemented\n\n// FDC command flags\nconst CMD_FLAG_MULTI_TRACK = 0x1 // MT: multi-track selector (use both heads) in READ/WRITE\n\n// FDC command execution phases\nconst CMD_PHASE_COMMAND = 1\nconst CMD_PHASE_EXECUTION = 2\nconst CMD_PHASE_RESULT = 3\n\n// FDC config bits\nconst _CONFIG_PRETRK = 0xff // Pre-compensation set to track 0\nconst _CONFIG_FIFOTHR = 0x0f // FIFO threshold set to 1 byte\nconst _CONFIG_POLL = 0x10 // Poll enabled\nconst CONFIG_EFIFO = 0x20 // FIFO disabled\nconst CONFIG_EIS = 0x40 // No implied seeks\n\n// Number of CMD_SENSE_INTERRUPT_STATUS expected after reset\nconst RESET_SENSE_INT_MAX = 4\n\n// Sector size\nconst SECTOR_SIZE = 512 // fixed size of 512 bytes/sector\nconst SECTOR_SIZE_CODE = 2 // sector size code 2: 512 bytes/sector\n\ninterface CmdDescriptor {\n code: number\n mask: number\n argc: number\n name: string\n handler: (args: Uint8Array) => void\n}\n\n// class FloppyController ----------------------------------------------------\n\nexport class FloppyController {\n name: string = 'fdc'\n io: IO\n cpu: FloppyCpu\n dma: DMA\n\n cmd_table: CmdDescriptor[]\n\n sra: number\n srb: number\n dor: number\n tdr: number\n msr: number\n dsr: number\n\n cmd_phase: number\n cmd_code: number\n cmd_flags: number\n cmd_buffer: Uint8Array\n cmd_cursor: number\n cmd_remaining: number\n\n response_data: Uint8Array\n response_cursor: number\n response_length: number\n status0: number\n status1: number\n\n curr_drive_no: number\n reset_sense_int_count: number\n locked: boolean\n step_rate_interval: number\n head_load_time: number\n fdc_config: number\n precomp_trk: number\n eot: number\n\n drives: [FloppyDrive, FloppyDrive]\n\n constructor(\n cpu: FloppyCpu,\n fda_image: SyncBuffer | Uint8Array | null | undefined,\n fdb_image: SyncBuffer | Uint8Array | null | undefined,\n fdc_config?: FloppyControllerConfig,\n ) {\n this.io = cpu.io\n this.cpu = cpu\n this.dma = cpu.devices.dma\n\n this.cmd_table = this.build_cmd_lookup_table()\n\n this.sra = 0\n this.srb = SRB_RESET\n this.dor = DOR_NRESET | DOR_DMAEN\n this.tdr = 0\n this.msr = MSR_RQM\n this.dsr = 0\n\n this.cmd_phase = CMD_PHASE_COMMAND\n this.cmd_code = 0\n this.cmd_flags = 0\n this.cmd_buffer = new Uint8Array(17) // CMD_RESTORE has 17 argument bytes\n this.cmd_cursor = 0\n this.cmd_remaining = 0\n\n this.response_data = new Uint8Array(15) // CMD_SAVE response size is 15 bytes\n this.response_cursor = 0\n this.response_length = 0\n this.status0 = 0\n this.status1 = 0\n\n this.curr_drive_no = 0 // was: this.drive; qemu: fdctrl->cur_drv\n this.reset_sense_int_count = 0 // see SENSE INTERRUPT\n this.locked = false // see LOCK\n this.step_rate_interval = 0 // see SPECIFY, qemu: timer0\n this.head_load_time = 0 // see SPECIFY, qemu: timer1\n this.fdc_config = CONFIG_EIS | CONFIG_EFIFO // see CONFIGURE, qemu: config\n this.precomp_trk = 0 // see CONFIGURE\n this.eot = 0 // see READ/WRITE\n\n this.drives = [\n new FloppyDrive(\n 'fda',\n fdc_config?.fda,\n fda_image,\n CMOS_FDD_TYPE_1440,\n ),\n new FloppyDrive(\n 'fdb',\n fdc_config?.fdb,\n fdb_image,\n CMOS_FDD_TYPE_1440,\n ),\n ]\n\n // To make the floppy drives visible to the guest OS we MUST write a\n // drive type other than 0 (CMOS_FDD_TYPE_NO_DRIVE) to either nibble of\n // CMOS register 0x10 before the guest is started (CMOS registers are\n // usually read only once at startup).\n this.cpu.devices.rtc.cmos_write(\n CMOS_FLOPPY_DRIVE_TYPE,\n (this.drives[0].drive_type << 4) | this.drives[1].drive_type,\n )\n\n const fdc_io_base = 0x3f0 // alt: 0x370\n\n this.io.register_read(fdc_io_base | REG_SRA, this, this.read_reg_sra)\n this.io.register_read(fdc_io_base | REG_SRB, this, this.read_reg_srb)\n this.io.register_read(fdc_io_base | REG_DOR, this, this.read_reg_dor)\n this.io.register_read(fdc_io_base | REG_TDR, this, this.read_reg_tdr)\n this.io.register_read(fdc_io_base | REG_MSR, this, this.read_reg_msr)\n this.io.register_read(fdc_io_base | REG_FIFO, this, this.read_reg_fifo)\n this.io.register_read(fdc_io_base | REG_DIR, this, this.read_reg_dir)\n\n this.io.register_write(fdc_io_base | REG_DOR, this, this.write_reg_dor)\n this.io.register_write(fdc_io_base | REG_TDR, this, this.write_reg_tdr)\n this.io.register_write(fdc_io_base | REG_DSR, this, this.write_reg_dsr)\n this.io.register_write(\n fdc_io_base | REG_FIFO,\n this,\n this.write_reg_fifo,\n )\n this.io.register_write(fdc_io_base | REG_CCR, this, this.write_reg_ccr)\n\n dbg_log('floppy controller ready', LOG_FLOPPY)\n }\n\n build_cmd_lookup_table(): CmdDescriptor[] {\n /**\n * NOTE: The order of items in the table below is significant.\n * @see {@link https://github.com/qemu/qemu/blob/aec6836c73403cffa56b9a4c5556451ee16071fe/hw/block/fdc.c#L2160}\n */\n const CMD_DESCRIPTOR: CmdDescriptor[] = [\n {\n code: CMD_READ,\n mask: 0x1f,\n argc: 8,\n name: 'READ',\n handler: this.exec_read,\n },\n {\n code: CMD_WRITE,\n mask: 0x3f,\n argc: 8,\n name: 'WRITE',\n handler: this.exec_write,\n },\n {\n code: CMD_SEEK,\n mask: 0xff,\n argc: 2,\n name: 'SEEK',\n handler: this.exec_seek,\n },\n {\n code: CMD_SENSE_INTERRUPT_STATUS,\n mask: 0xff,\n argc: 0,\n name: 'SENSE INTERRUPT STATUS',\n handler: this.exec_sense_interrupt_status,\n },\n {\n code: CMD_RECALIBRATE,\n mask: 0xff,\n argc: 1,\n name: 'RECALIBRATE',\n handler: this.exec_recalibrate,\n },\n {\n code: CMD_FORMAT_TRACK,\n mask: 0xbf,\n argc: 5,\n name: 'FORMAT TRACK',\n handler: this.exec_format_track,\n },\n {\n code: CMD_READ_TRACK,\n mask: 0xbf,\n argc: 8,\n name: 'READ TRACK',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_RESTORE,\n mask: 0xff,\n argc: 17,\n name: 'RESTORE',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_SAVE,\n mask: 0xff,\n argc: 0,\n name: 'SAVE',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_READ_DELETED_DATA,\n mask: 0x1f,\n argc: 8,\n name: 'READ DELETED DATA',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_SCAN_EQUAL,\n mask: 0x1f,\n argc: 8,\n name: 'SCAN EQUAL',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_VERIFY,\n mask: 0x1f,\n argc: 8,\n name: 'VERIFY',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_SCAN_LOW_OR_EQUAL,\n mask: 0x1f,\n argc: 8,\n name: 'SCAN LOW OR EQUAL',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_SCAN_HIGH_OR_EQUAL,\n mask: 0x1f,\n argc: 8,\n name: 'SCAN HIGH OR EQUAL',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_WRITE_DELETED_DATA,\n mask: 0x3f,\n argc: 8,\n name: 'WRITE DELETED DATA',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_READ_ID,\n mask: 0xbf,\n argc: 1,\n name: 'READ ID',\n handler: this.exec_read_id,\n },\n {\n code: CMD_SPECIFY,\n mask: 0xff,\n argc: 2,\n name: 'SPECIFY',\n handler: this.exec_specify,\n },\n {\n code: CMD_SENSE_DRIVE_STATUS,\n mask: 0xff,\n argc: 1,\n name: 'SENSE DRIVE STATUS',\n handler: this.exec_sense_drive_status,\n },\n {\n code: CMD_PERPENDICULAR_MODE,\n mask: 0xff,\n argc: 1,\n name: 'PERPENDICULAR MODE',\n handler: this.exec_perpendicular_mode,\n },\n {\n code: CMD_CONFIGURE,\n mask: 0xff,\n argc: 3,\n name: 'CONFIGURE',\n handler: this.exec_configure,\n },\n {\n code: CMD_POWERDOWN_MODE,\n mask: 0xff,\n argc: 2,\n name: 'POWERDOWN MODE',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_OPTION,\n mask: 0xff,\n argc: 1,\n name: 'OPTION',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_DRIVE_SPECIFICATION,\n mask: 0xff,\n argc: 5,\n name: 'DRIVE SPECIFICATION',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_RELATIVE_SEEK_OUT,\n mask: 0xff,\n argc: 2,\n name: 'RELATIVE SEEK OUT',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_FORMAT_AND_WRITE,\n mask: 0xff,\n argc: 10,\n name: 'FORMAT AND WRITE',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_RELATIVE_SEEK_IN,\n mask: 0xff,\n argc: 2,\n name: 'RELATIVE SEEK IN',\n handler: this.exec_unimplemented,\n },\n {\n code: CMD_LOCK,\n mask: 0x7f,\n argc: 0,\n name: 'LOCK',\n handler: this.exec_lock,\n },\n {\n code: CMD_DUMP_REGS,\n mask: 0xff,\n argc: 0,\n name: 'DUMP REGISTERS',\n handler: this.exec_dump_regs,\n },\n {\n code: CMD_VERSION,\n mask: 0xff,\n argc: 0,\n name: 'VERSION',\n handler: this.exec_version,\n },\n {\n code: CMD_PART_ID,\n mask: 0xff,\n argc: 0,\n name: 'PART ID',\n handler: this.exec_part_id,\n },\n\n {\n code: 0,\n mask: 0x00,\n argc: 0,\n name: 'UNKNOWN COMMAND',\n handler: this.exec_unimplemented,\n }, // default handler\n ]\n\n const cmd_table: CmdDescriptor[] = new Array(256)\n for (let i = CMD_DESCRIPTOR.length - 1; i >= 0; i--) {\n const cmd_desc = CMD_DESCRIPTOR[i]\n if (cmd_desc.mask === 0xff) {\n cmd_table[cmd_desc.code] = cmd_desc\n } else {\n for (let j = 0; j < 256; j++) {\n if ((j & cmd_desc.mask) === cmd_desc.code) {\n cmd_table[j] = cmd_desc\n }\n }\n }\n }\n return cmd_table\n }\n\n raise_irq(reason: string): void {\n if (!(this.sra & SRA_INTPEND)) {\n this.cpu.device_raise_irq(FDC_IRQ_CHANNEL)\n this.sra |= SRA_INTPEND\n dbg_log('IRQ raised, reason: ' + reason, LOG_FLOPPY)\n }\n this.reset_sense_int_count = 0\n }\n\n lower_irq(reason: string): void {\n this.status0 = 0\n if (this.sra & SRA_INTPEND) {\n this.cpu.device_lower_irq(FDC_IRQ_CHANNEL)\n this.sra &= ~SRA_INTPEND\n dbg_log('IRQ lowered, reason: ' + reason, LOG_FLOPPY)\n }\n }\n\n set_curr_drive_no(curr_drive_no: number): FloppyDrive {\n this.curr_drive_no = curr_drive_no & 1\n return this.drives[this.curr_drive_no]\n }\n\n enter_command_phase(): void {\n this.cmd_phase = CMD_PHASE_COMMAND\n this.cmd_cursor = 0\n this.cmd_remaining = 0\n this.msr &= ~(MSR_CMDBUSY | MSR_DIO)\n this.msr |= MSR_RQM\n }\n\n enter_result_phase(fifo_len: number): void {\n this.cmd_phase = CMD_PHASE_RESULT\n this.response_cursor = 0\n this.response_length = fifo_len\n this.msr |= MSR_CMDBUSY | MSR_RQM | MSR_DIO\n }\n\n reset_fdc(): void {\n dbg_log('resetting controller', LOG_FLOPPY)\n this.lower_irq('controller reset')\n\n this.sra = 0 // NOTE: set SRA to SRA_NDRV2 if fdb does not exist\n this.srb = SRB_RESET\n this.dor = DOR_NRESET | DOR_DMAEN\n this.msr = MSR_RQM\n this.curr_drive_no = 0\n this.status0 |= SR0_RDYCHG\n\n this.response_cursor = 0\n this.response_length = 0\n\n this.drives[0].seek(0, 0, 1)\n this.drives[1].seek(0, 0, 1)\n\n // raise interrupt\n this.enter_command_phase()\n this.raise_irq('controller reset')\n this.reset_sense_int_count = RESET_SENSE_INT_MAX\n }\n\n // Register I/O callbacks ----------------------------------------------------\n\n read_reg_sra(): number {\n dbg_log('SRA read: ' + h(this.sra), LOG_FLOPPY)\n return this.sra\n }\n\n read_reg_srb(): number {\n dbg_log('SRB read: ' + h(this.srb), LOG_FLOPPY)\n return this.srb\n }\n\n read_reg_dor(): number {\n const dor_byte =\n (this.dor & ~(DOR_SEL_LO | DOR_SEL_HI)) | this.curr_drive_no\n dbg_log('DOR read: ' + h(dor_byte), LOG_FLOPPY)\n return dor_byte\n }\n\n read_reg_tdr(): number {\n dbg_log('TDR read: ' + h(this.tdr), LOG_FLOPPY)\n return this.tdr\n }\n\n read_reg_msr(): number {\n dbg_log('MSR read: ' + h(this.msr), LOG_FLOPPY)\n this.dsr &= ~DSR_PWRDOWN\n this.dor |= DOR_NRESET\n return this.msr\n }\n\n read_reg_fifo(): number {\n this.dsr &= ~DSR_PWRDOWN\n if (!(this.msr & MSR_RQM) || !(this.msr & MSR_DIO)) {\n dbg_log(\n 'FIFO read rejected: controller not ready for reading',\n LOG_FLOPPY,\n )\n return 0\n } else if (this.cmd_phase !== CMD_PHASE_RESULT) {\n dbg_log(\n 'FIFO read rejected: floppy controller not in RESULT phase, phase: ' +\n this.cmd_phase,\n LOG_FLOPPY,\n )\n return 0\n }\n\n if (this.response_cursor < this.response_length) {\n const fifo_byte = this.response_data[this.response_cursor++]\n if (this.response_cursor === this.response_length) {\n const lower_irq_reason = DEBUG\n ? 'end of ' +\n this.cmd_table[this.cmd_code].name +\n ' response'\n : ''\n this.msr &= ~MSR_RQM\n this.enter_command_phase()\n this.lower_irq(lower_irq_reason)\n }\n return fifo_byte\n } else {\n dbg_log('FIFO read: empty', LOG_FLOPPY)\n return 0\n }\n }\n\n read_reg_dir(): number {\n const curr_drive = this.drives[this.curr_drive_no]\n const dir_byte = curr_drive.media_changed ? DIR_DOOR : 0\n dbg_log('DIR read: ' + h(dir_byte), LOG_FLOPPY)\n return dir_byte\n }\n\n write_reg_dor(dor_byte: number): void {\n // update motor and drive bits in Status Register B\n this.srb =\n (this.srb & ~(SRB_MTR0 | SRB_MTR1 | SRB_DR0)) |\n (dor_byte & DOR_MOTEN0 ? SRB_MTR0 : 0) |\n (dor_byte & DOR_MOTEN1 ? SRB_MTR1 : 0) |\n (dor_byte & DOR_SEL_LO ? SRB_DR0 : 0)\n\n // RESET-state transitions\n if (this.dor & DOR_NRESET) {\n if (!(dor_byte & DOR_NRESET)) {\n dbg_log('enter RESET state', LOG_FLOPPY)\n }\n } else {\n if (dor_byte & DOR_NRESET) {\n this.reset_fdc()\n this.dsr &= ~DSR_PWRDOWN\n dbg_log('exit RESET state', LOG_FLOPPY)\n }\n }\n\n // select current drive\n const new_drive_no = dor_byte & (DOR_SEL_LO | DOR_SEL_HI)\n dbg_log(\n 'DOR write: ' +\n h(dor_byte) +\n ', motors: ' +\n h(dor_byte >> 4) +\n ', dma: ' +\n !!(dor_byte & DOR_DMAEN) +\n ', reset: ' +\n !(dor_byte & DOR_NRESET) +\n ', drive: ' +\n new_drive_no,\n LOG_FLOPPY,\n )\n if (new_drive_no > 1) {\n dbg_log(\n '*** WARNING: floppy drive number ' +\n new_drive_no +\n ' not implemented!',\n LOG_FLOPPY,\n )\n }\n this.curr_drive_no = new_drive_no & DOR_SEL_LO\n\n this.dor = dor_byte\n }\n\n write_reg_tdr(tdr_byte: number): void {\n if (!(this.dor & DOR_NRESET)) {\n dbg_log(\n 'TDR write ' +\n h(tdr_byte) +\n ' rejected: Floppy controller in RESET mode!',\n LOG_FLOPPY,\n )\n return\n }\n\n dbg_log('TDR write: ' + h(tdr_byte), LOG_FLOPPY)\n this.tdr = tdr_byte & TDR_BOOTSEL // Disk boot selection indicator\n }\n\n write_reg_dsr(dsr_byte: number): void {\n if (!(this.dor & DOR_NRESET)) {\n dbg_log(\n 'DSR write: ' +\n h(dsr_byte) +\n ' rejected: Floppy controller in RESET mode!',\n LOG_FLOPPY,\n )\n return\n }\n\n dbg_log('DSR write: ' + h(dsr_byte), LOG_FLOPPY)\n if (dsr_byte & DSR_SWRESET) {\n this.dor &= ~DOR_NRESET\n this.reset_fdc()\n this.dor |= DOR_NRESET\n }\n if (dsr_byte & DSR_PWRDOWN) {\n this.reset_fdc()\n }\n this.dsr = dsr_byte\n }\n\n write_reg_fifo(fifo_byte: number): void {\n this.dsr &= ~DSR_PWRDOWN\n if (!(this.dor & DOR_NRESET)) {\n dbg_log(\n 'FIFO write ' +\n h(fifo_byte) +\n ' rejected: floppy controller in RESET mode!',\n LOG_FLOPPY,\n )\n return\n } else if (!(this.msr & MSR_RQM) || this.msr & MSR_DIO) {\n dbg_log(\n 'FIFO write ' +\n h(fifo_byte) +\n ' rejected: controller not ready for writing',\n LOG_FLOPPY,\n )\n return\n } else if (this.cmd_phase !== CMD_PHASE_COMMAND) {\n dbg_log(\n 'FIFO write ' +\n h(fifo_byte) +\n ' rejected: floppy controller not in COMMAND phase, phase: ' +\n this.cmd_phase,\n LOG_FLOPPY,\n )\n return\n }\n\n if (this.cmd_remaining === 0) {\n // start reading command, fifo_byte contains the command code\n const cmd_desc = this.cmd_table[fifo_byte]\n this.cmd_code = fifo_byte\n this.cmd_remaining = cmd_desc.argc\n this.cmd_cursor = 0\n this.cmd_flags = 0\n if (\n (cmd_desc.code === CMD_READ || cmd_desc.code === CMD_WRITE) &&\n this.cmd_code & 0x80\n ) // 0x80: Multi-track (MT)\n {\n this.cmd_flags |= CMD_FLAG_MULTI_TRACK\n }\n if (this.cmd_remaining) {\n this.msr |= MSR_RQM\n }\n this.msr |= MSR_CMDBUSY\n } else {\n // continue reading command, fifo_byte contains an argument value\n this.cmd_buffer[this.cmd_cursor++] = fifo_byte\n this.cmd_remaining--\n }\n\n if (this.cmd_remaining === 0) {\n // done reading command: execute\n this.cmd_phase = CMD_PHASE_EXECUTION\n const cmd_desc = this.cmd_table[this.cmd_code]\n const args = this.cmd_buffer.slice(0, this.cmd_cursor)\n if (DEBUG) {\n const args_hex: string[] = []\n for (const arg of args) {\n args_hex.push(h(arg, 2))\n }\n dbg_log(\n 'FD command ' +\n h(this.cmd_code) +\n ': ' +\n cmd_desc.name +\n '(' +\n args_hex.join(', ') +\n ')',\n LOG_FLOPPY,\n )\n }\n cmd_desc.handler.call(this, args)\n }\n }\n\n write_reg_ccr(ccr_byte: number): void {\n if (!(this.dor & DOR_NRESET)) {\n dbg_log(\n 'CCR write: ' +\n h(ccr_byte) +\n ' rejected: Floppy controller in RESET mode!',\n LOG_FLOPPY,\n )\n return\n }\n\n dbg_log('CCR write: ' + h(ccr_byte), LOG_FLOPPY)\n // only the rate selection bits used in AT mode, and we store those in the DSR\n this.dsr = (this.dsr & ~DSR_DRATEMASK) | (ccr_byte & DSR_DRATEMASK)\n }\n\n // Floppy command handler ----------------------------------------------------\n\n exec_unimplemented(_args: Uint8Array): void {\n dbg_assert(\n false,\n 'Unimplemented floppy command code ' + h(this.cmd_code) + '!',\n )\n this.status0 = SR0_INVCMD\n this.response_data[0] = this.status0\n\n // no interrupt\n this.enter_result_phase(1)\n }\n\n exec_read(args: Uint8Array): void {\n this.start_read_write(args, false)\n }\n\n exec_write(args: Uint8Array): void {\n this.start_read_write(args, true)\n }\n\n exec_seek(args: Uint8Array): void {\n const curr_drive = this.set_curr_drive_no(args[0] & DOR_SELMASK)\n const track = args[1]\n\n this.enter_command_phase()\n curr_drive.seek(curr_drive.curr_head, track, curr_drive.curr_sect)\n\n // raise interrupt without response\n this.status0 |= SR0_SEEK\n this.raise_irq('SEEK command')\n }\n\n exec_sense_interrupt_status(_args: Uint8Array): void {\n const curr_drive = this.drives[this.curr_drive_no]\n\n let status0: number\n if (this.reset_sense_int_count > 0) {\n const drv_nr = RESET_SENSE_INT_MAX - this.reset_sense_int_count--\n status0 = SR0_RDYCHG | drv_nr\n } else if (this.sra & SRA_INTPEND) {\n status0 =\n (this.status0 & ~(SR0_HEAD | SR0_DS1 | SR0_DS0)) |\n this.curr_drive_no\n } else {\n dbg_log(\n 'No interrupt pending, aborting SENSE INTERRUPT command!',\n LOG_FLOPPY,\n )\n this.response_data[0] = SR0_INVCMD\n this.enter_result_phase(1)\n return\n }\n\n this.response_data[0] = status0\n this.response_data[1] = curr_drive.curr_track\n\n // lower interrupt\n this.enter_result_phase(2)\n this.lower_irq('SENSE INTERRUPT command')\n this.status0 = SR0_RDYCHG\n }\n\n exec_recalibrate(args: Uint8Array): void {\n const curr_drive = this.set_curr_drive_no(args[0] & DOR_SELMASK)\n\n curr_drive.seek(0, 0, 1)\n\n // raise interrupt without response\n this.enter_command_phase()\n this.status0 |= SR0_SEEK\n this.raise_irq('RECALIBRATE command')\n }\n\n exec_format_track(args: Uint8Array): void {\n const curr_drive = this.set_curr_drive_no(args[0] & DOR_SELMASK)\n\n let status0 = 0,\n status1 = 0\n if (curr_drive.read_only) {\n status0 = SR0_ABNTERM | SR0_SEEK\n status1 = SR1_NW\n }\n\n // raise interrupt\n this.end_read_write(status0, status1, 0)\n }\n\n exec_read_id(args: Uint8Array): void {\n const head_sel = args[0]\n const curr_drive = this.drives[this.curr_drive_no]\n\n curr_drive.curr_head = (head_sel >> 2) & 1\n if (curr_drive.max_sect !== 0) {\n curr_drive.curr_sect =\n (curr_drive.curr_sect % curr_drive.max_sect) + 1\n }\n\n // raise interrupt\n this.end_read_write(0, 0, 0)\n }\n\n exec_specify(args: Uint8Array): void {\n const hut_srt = args[0] // 0..3: Head Unload Time (HUT), 4..7: Step Rate Interval (SRT)\n const nd_hlt = args[1] // 0: Non-DMA mode flag (ND), 1..7: Head Load Time (HLT)\n\n this.step_rate_interval = hut_srt >> 4\n this.head_load_time = nd_hlt >> 1\n if (nd_hlt & 0x1) {\n this.dor &= ~DOR_DMAEN\n } else {\n this.dor |= DOR_DMAEN\n }\n\n // no interrupt or response\n this.enter_command_phase()\n }\n\n exec_sense_drive_status(args: Uint8Array): void {\n const drv_sel = args[0]\n const curr_drive = this.set_curr_drive_no(drv_sel & DOR_SELMASK)\n curr_drive.curr_head = (drv_sel >> 2) & 1\n\n this.response_data[0] =\n (curr_drive.read_only ? 0x40 : 0) | // response byte is Status Register 3\n (curr_drive.curr_track === 0 ? 0x10 : 0) |\n (curr_drive.curr_head << 2) |\n this.curr_drive_no |\n 0x28 // bits 3 and 5 unused, always \"1\"\n\n // no interrupt\n this.enter_result_phase(1)\n }\n\n exec_perpendicular_mode(args: Uint8Array): void {\n const perp_mode = args[0]\n\n if (perp_mode & 0x80) // 0x80: OW, bits D0 and D1 can be overwritten\n {\n const curr_drive = this.drives[this.curr_drive_no]\n curr_drive.perpendicular = perp_mode & 0x7\n }\n\n // no interrupt or response\n this.enter_command_phase()\n }\n\n exec_configure(args: Uint8Array): void {\n // args[0] is always 0\n this.fdc_config = args[1]\n this.precomp_trk = args[2]\n\n // no interrupt or response\n this.enter_command_phase()\n }\n\n exec_lock(_args: Uint8Array): void {\n if (this.cmd_code & 0x80) {\n // LOCK command\n this.locked = true\n this.response_data[0] = 0x10\n } else {\n // UNLOCK command\n this.locked = false\n this.response_data[0] = 0\n }\n\n // no interrupt\n this.enter_result_phase(1)\n }\n\n exec_dump_regs(_args: Uint8Array): void {\n const curr_drive = this.drives[this.curr_drive_no]\n\n // drive positions\n this.response_data[0] = this.drives[0].curr_track\n this.response_data[1] = this.drives[1].curr_track\n this.response_data[2] = 0\n this.response_data[3] = 0\n // timers\n this.response_data[4] = this.step_rate_interval\n this.response_data[5] =\n (this.head_load_time << 1) | (this.dor & DOR_DMAEN ? 1 : 0)\n this.response_data[6] = curr_drive.max_sect\n this.response_data[7] =\n (this.locked ? 0x80 : 0) | (curr_drive.perpendicular << 2)\n this.response_data[8] = this.fdc_config\n this.response_data[9] = this.precomp_trk\n\n // no interrupt\n this.enter_result_phase(10)\n }\n\n exec_version(_args: Uint8Array): void {\n this.response_data[0] = 0x90 // 0x80: Standard controller, 0x81: Intel 82077, 0x90: Intel 82078\n\n // no interrupt\n this.enter_result_phase(1)\n }\n\n exec_part_id(_args: Uint8Array): void {\n this.response_data[0] = 0x41 // Stepping 1 (PS/2 mode)\n\n // no interrupt\n this.enter_result_phase(1)\n }\n\n // ---------------------------------------------------------------------------\n\n start_read_write(args: Uint8Array, do_write: boolean): void {\n const curr_drive = this.set_curr_drive_no(args[0] & DOR_SELMASK)\n const track = args[1]\n const head = args[2]\n const sect = args[3]\n const ssc = args[4] // sector size code 0..7 (0:128, 1:256, 2:512, ..., 7:16384 bytes/sect)\n const eot = args[5] // last sector number of current track\n const dtl = args[7] < 128 ? args[7] : 128 // data length in bytes if ssc is 0, else unused\n\n switch (curr_drive.seek(head, track, sect)) {\n case 2: // error: sect too big\n this.end_read_write(SR0_ABNTERM, 0, 0)\n this.response_data[3] = track\n this.response_data[4] = head\n this.response_data[5] = sect\n return\n case 3: // error: track too big\n this.end_read_write(SR0_ABNTERM, SR1_EC, 0)\n this.response_data[3] = track\n this.response_data[4] = head\n this.response_data[5] = sect\n return\n case 1: // track changed\n this.status0 |= SR0_SEEK\n break\n }\n\n const sect_size = 128 << (ssc > 7 ? 7 : ssc) // sector size in bytes\n const sect_start = curr_drive.chs2lba(track, head, sect) // linear start sector\n const data_offset = sect_start * sect_size // data offset in bytes\n let data_length: number // data length in bytes\n if (sect_size === 128) {\n // if requested data length (dtl) is < 128:\n // - READ: return only dtl bytes, skipping the sector's remaining bytes (OK)\n // - WRITE: we must fill the sector's remaining bytes with 0 (TODO!)\n if (do_write && dtl < 128) {\n dbg_assert(\n false,\n 'dtl=' +\n dtl +\n ' is less than 128, zero-padding is still unimplemented!',\n )\n }\n data_length = dtl\n } else {\n if (this.cmd_flags & CMD_FLAG_MULTI_TRACK) {\n data_length = (2 * eot - sect + 1) * sect_size\n } else {\n data_length = (eot - sect + 1) * sect_size\n }\n if (data_length <= 0) {\n dbg_log(\n 'invalid data_length: ' +\n data_length +\n ' sect=' +\n sect +\n ' eot=' +\n eot,\n LOG_FLOPPY,\n )\n this.end_read_write(SR0_ABNTERM, SR1_MA, 0)\n this.response_data[3] = track\n this.response_data[4] = head\n this.response_data[5] = sect\n return\n }\n }\n this.eot = eot\n\n if (DEBUG) {\n dbg_log(\n 'Floppy ' +\n this.cmd_table[this.cmd_code].name +\n ' from: ' +\n h(data_offset) +\n ', length: ' +\n h(data_length) +\n ', C/H/S: ' +\n track +\n '/' +\n head +\n '/' +\n sect +\n ', ro: ' +\n curr_drive.read_only +\n ', #S: ' +\n curr_drive.max_sect +\n ', #H: ' +\n curr_drive.max_head,\n LOG_FLOPPY,\n )\n }\n\n if (do_write && curr_drive.read_only) {\n this.end_read_write(SR0_ABNTERM | SR0_SEEK, SR1_NW, 0)\n this.response_data[3] = track\n this.response_data[4] = head\n this.response_data[5] = sect\n return\n }\n\n if (this.dor & DOR_DMAEN) {\n // start DMA transfer\n this.msr &= ~MSR_RQM\n const do_dma = do_write ? this.dma.do_write : this.dma.do_read\n do_dma.call(\n this.dma,\n curr_drive.buffer!,\n data_offset,\n data_length,\n FDC_DMA_CHANNEL,\n (dma_error: boolean) => {\n if (dma_error) {\n dbg_log('DMA floppy error', LOG_FLOPPY)\n this.end_read_write(SR0_ABNTERM, 0, 0)\n } else {\n this.seek_next_sect()\n this.end_read_write(0, 0, 0)\n }\n },\n )\n } else {\n // start PIO transfer\n dbg_assert(\n false,\n this.cmd_table[this.cmd_code].name +\n ' in PIO mode not supported!',\n )\n }\n }\n\n end_read_write(status0: number, status1: number, status2: number): void {\n const curr_drive = this.drives[this.curr_drive_no]\n\n this.status0 &= ~(SR0_DS0 | SR0_DS1 | SR0_HEAD)\n this.status0 |= this.curr_drive_no\n if (curr_drive.curr_head) {\n this.status0 |= SR0_HEAD\n }\n this.status0 |= status0\n\n this.msr |= MSR_RQM | MSR_DIO\n this.msr &= ~MSR_NDMA\n\n this.response_data[0] = this.status0\n this.response_data[1] = status1\n this.response_data[2] = status2\n this.response_data[3] = curr_drive.curr_track\n this.response_data[4] = curr_drive.curr_head\n this.response_data[5] = curr_drive.curr_sect\n this.response_data[6] = SECTOR_SIZE_CODE\n\n // raise interrupt\n this.enter_result_phase(7)\n this.raise_irq(this.cmd_table[this.cmd_code].name + ' command')\n }\n\n seek_next_sect(): number {\n // Seek to next sector\n // returns 0 when end of track reached (for DBL_SIDES on head 1). otherwise returns 1\n const curr_drive = this.drives[this.curr_drive_no]\n\n // XXX: curr_sect >= max_sect should be an error in fact (TODO: this comment comes from qemu, not sure what to make of it)\n let new_track = curr_drive.curr_track\n let new_head = curr_drive.curr_head\n let new_sect = curr_drive.curr_sect\n let ret = 1\n\n if (new_sect >= curr_drive.max_sect || new_sect === this.eot) {\n new_sect = 1\n if (this.cmd_flags & CMD_FLAG_MULTI_TRACK) {\n if (new_head === 0 && curr_drive.max_head === 2) {\n new_head = 1\n } else {\n new_head = 0\n new_track++\n this.status0 |= SR0_SEEK\n if (curr_drive.max_head === 1) {\n ret = 0\n }\n }\n } else {\n this.status0 |= SR0_SEEK\n new_track++\n ret = 0\n }\n } else {\n new_sect++\n }\n\n curr_drive.seek(new_head, new_track, new_sect)\n return ret\n }\n\n get_state(): (number | boolean | Uint8Array | unknown[])[] {\n // NOTE: Old-style state snapshots (state indices 0..18) did not include\n // the disk image buffer, only a few register states, so a floppy drive\n // remained essentially unchangd when a state snapshot was applied.\n // The snapshotted registers can be safely ignored when restoring state,\n // hence the entire old-style state is now ignored and deprecated.\n const state: (number | boolean | Uint8Array | unknown[])[] = []\n state[19] = this.sra\n state[20] = this.srb\n state[21] = this.dor\n state[22] = this.tdr\n state[23] = this.msr\n state[24] = this.dsr\n state[25] = this.cmd_phase\n state[26] = this.cmd_code\n state[27] = this.cmd_flags\n state[28] = this.cmd_buffer // Uint8Array\n state[29] = this.cmd_cursor\n state[30] = this.cmd_remaining\n state[31] = this.response_data // Uint8Array\n state[32] = this.response_cursor\n state[33] = this.response_length\n state[34] = this.status0\n state[35] = this.status1\n state[36] = this.curr_drive_no\n state[37] = this.reset_sense_int_count\n state[38] = this.locked\n state[39] = this.step_rate_interval\n state[40] = this.head_load_time\n state[41] = this.fdc_config\n state[42] = this.precomp_trk\n state[43] = this.eot\n state[44] = this.drives[0].get_state()\n state[45] = this.drives[1].get_state()\n return state\n }\n\n set_state(state: any[]): void {\n if (typeof state[19] === 'undefined') {\n // see comment above in get_state()\n return\n }\n this.sra = state[19]\n this.srb = state[20]\n this.dor = state[21]\n this.tdr = state[22]\n this.msr = state[23]\n this.dsr = state[24]\n this.cmd_phase = state[25]\n this.cmd_code = state[26]\n this.cmd_flags = state[27]\n this.cmd_buffer.set(state[28]) // Uint8Array\n this.cmd_cursor = state[29]\n this.cmd_remaining = state[30]\n this.response_data.set(state[31]) // Uint8Array\n this.response_cursor = state[32]\n this.response_length = state[33]\n this.status0 = state[34]\n this.status1 = state[35]\n this.curr_drive_no = state[36]\n this.reset_sense_int_count = state[37]\n this.locked = state[38]\n this.step_rate_interval = state[39]\n this.head_load_time = state[40]\n this.fdc_config = state[41]\n this.precomp_trk = state[42]\n this.eot = state[43]\n this.drives[0].set_state(state[44])\n this.drives[1].set_state(state[45])\n }\n}\n\n// class FloppyDrive ---------------------------------------------------------\n\n/**\n * Floppy disk formats\n *\n * In many cases, the total sector count (sectors*tracks*heads) of a format\n * is enough to uniquely identify it. However, there are some total sector\n * collisions between formats of different physical size (drive_type), these\n * are highlighed below in the \"collides\" column.\n *\n * Matches that are higher up in the table take precedence over later matches.\n *\n * @see {@link https://github.com/qemu/qemu/blob/e240f6cc25917f3138d9e95e0343ae23b63a3f8c/hw/block/fdc.c#L99}\n * @see {@link https://en.wikipedia.org/wiki/List_of_floppy_disk_formats}\n */\n\ninterface DiskFormat {\n drive_type: number\n sectors: number\n tracks: number\n heads: number\n}\n\nconst DISK_FORMATS: DiskFormat[] = [\n // ttl_sect size collides\n // 1.44 MB 3\"1/2 floppy disks | | |\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 18, tracks: 80, heads: 2 }, // 2880 1.44 MB 3.5\"\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 20, tracks: 80, heads: 2 }, // 3200 1.6 MB 3.5\"\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 21, tracks: 80, heads: 2 }, // 3360 1.68 MB\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 21, tracks: 82, heads: 2 }, // 3444 1.72 MB\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 21, tracks: 83, heads: 2 }, // 3486 1.74 MB\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 22, tracks: 80, heads: 2 }, // 3520 1.76 MB\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 23, tracks: 80, heads: 2 }, // 3680 1.84 MB\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 24, tracks: 80, heads: 2 }, // 3840 1.92 MB\n // 2.88 MB 3\"1/2 floppy disks\n { drive_type: CMOS_FDD_TYPE_2880, sectors: 36, tracks: 80, heads: 2 }, // 5760 2.88 MB\n { drive_type: CMOS_FDD_TYPE_2880, sectors: 39, tracks: 80, heads: 2 }, // 6240 3.12 MB\n { drive_type: CMOS_FDD_TYPE_2880, sectors: 40, tracks: 80, heads: 2 }, // 6400 3.2 MB\n { drive_type: CMOS_FDD_TYPE_2880, sectors: 44, tracks: 80, heads: 2 }, // 7040 3.52 MB\n { drive_type: CMOS_FDD_TYPE_2880, sectors: 48, tracks: 80, heads: 2 }, // 7680 3.84 MB\n // 720 kB 3\"1/2 floppy disks\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 8, tracks: 80, heads: 2 }, // 1280 640 kB\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 9, tracks: 80, heads: 2 }, // 1440 720 kB 3.5\"\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 10, tracks: 80, heads: 2 }, // 1600 800 kB\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 10, tracks: 82, heads: 2 }, // 1640 820 kB\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 10, tracks: 83, heads: 2 }, // 1660 830 kB\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 13, tracks: 80, heads: 2 }, // 2080 1.04 MB\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 14, tracks: 80, heads: 2 }, // 2240 1.12 MB\n // 1.2 MB 5\"1/4 floppy disks\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 15, tracks: 80, heads: 2 }, // 2400 1.2 MB\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 18, tracks: 80, heads: 2 }, // 2880 1.44 MB 5.25\"\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 18, tracks: 82, heads: 2 }, // 2952 1.48 MB\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 18, tracks: 83, heads: 2 }, // 2988 1.49 MB\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 20, tracks: 80, heads: 2 }, // 3200 1.6 MB 5.25\"\n // 720 kB 5\"1/4 floppy disks\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 9, tracks: 80, heads: 2 }, // 1440 720 kB 5.25\"\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 11, tracks: 80, heads: 2 }, // 1760 880 kB\n // 360 kB 5\"1/4 floppy disks\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 9, tracks: 40, heads: 2 }, // 720 360 kB 5.25\"\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 9, tracks: 40, heads: 1 }, // 360 180 kB\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 10, tracks: 41, heads: 2 }, // 820 410 kB\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 10, tracks: 42, heads: 2 }, // 840 420 kB\n // 320 kB 5\"1/4 floppy disks\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 8, tracks: 40, heads: 2 }, // 640 320 kB\n { drive_type: CMOS_FDD_TYPE_1200, sectors: 8, tracks: 40, heads: 1 }, // 320 160 kB\n // 360 kB must match 5\"1/4 better than 3\"1/2...\n { drive_type: CMOS_FDD_TYPE_1440, sectors: 9, tracks: 80, heads: 1 }, // 720 360 kB 3.5\"\n // types defined in earlier v86 releases (not defined in qemu)\n { drive_type: CMOS_FDD_TYPE_360, sectors: 10, tracks: 40, heads: 1 }, // 400 200 kB\n { drive_type: CMOS_FDD_TYPE_360, sectors: 10, tracks: 40, heads: 2 }, // 800 400 kB\n]\n\nclass FloppyDrive {\n name: string\n\n // drive state\n drive_type: number\n\n // disk state\n max_track: number // disk's max. track\n max_head: number // disk's max. head (1 or 2)\n max_sect: number // disk's max. sect\n curr_track: number // >= 0\n curr_head: number // 0 or 1\n curr_sect: number // > 0\n perpendicular: number\n read_only: boolean\n media_changed: boolean\n buffer: SyncBuffer | null\n\n constructor(\n name: string,\n fdd_config: FloppyDriveConfig | undefined,\n buffer: SyncBuffer | Uint8Array | null | undefined,\n fallback_drive_type: number,\n ) {\n this.name = name\n\n // drive state\n this.drive_type = CMOS_FDD_TYPE_NO_DRIVE\n\n // disk state\n this.max_track = 0\n this.max_head = 0\n this.max_sect = 0\n this.curr_track = 0\n this.curr_head = 0\n this.curr_sect = 1\n this.perpendicular = 0\n this.read_only = false\n this.media_changed = true\n this.buffer = null\n\n // Drive type this.drive_type is either (in this order):\n // - specified in fdd_config.drive_type (if defined),\n // - derived from given image buffer (if provided), or\n // - specfied in fallback_drive_type.\n // If buffer is undefined and fdd_config.drive_type is\n // CMOS_FDD_TYPE_NO_DRIVE then the drive will be invisible to the guest.\n const cfg_drive_type = fdd_config?.drive_type\n if (\n cfg_drive_type !== undefined &&\n cfg_drive_type >= 0 &&\n cfg_drive_type <= 5\n ) {\n this.drive_type = cfg_drive_type\n }\n\n this.insert_disk(buffer, !!fdd_config?.read_only)\n\n if (\n this.drive_type === CMOS_FDD_TYPE_NO_DRIVE &&\n cfg_drive_type === undefined\n ) {\n this.drive_type = fallback_drive_type\n }\n\n dbg_log(\n 'floppy drive ' +\n this.name +\n ' ready, drive type: ' +\n this.drive_type,\n LOG_FLOPPY,\n )\n }\n\n /**\n * Insert disk image into floppy drive.\n */\n insert_disk(\n buffer: SyncBuffer | Uint8Array | null | undefined,\n read_only?: boolean,\n ): boolean {\n if (!buffer) {\n return false\n }\n\n if (buffer instanceof Uint8Array) {\n const ab = new ArrayBuffer(buffer.byteLength)\n new Uint8Array(ab).set(buffer)\n buffer = new SyncBuffer(ab)\n }\n\n const [new_buffer, disk_format] = this.find_disk_format(\n buffer,\n this.drive_type,\n )\n if (!new_buffer) {\n dbg_log(\n 'WARNING: disk rejected, no suitable disk format found for image of size ' +\n buffer.byteLength +\n ' bytes',\n LOG_FLOPPY,\n )\n return false\n }\n\n this.max_track = disk_format!.tracks\n this.max_head = disk_format!.heads\n this.max_sect = disk_format!.sectors\n this.read_only = !!read_only\n this.media_changed = true\n this.buffer = new_buffer\n\n if (this.drive_type === CMOS_FDD_TYPE_NO_DRIVE) {\n // auto-select drive type once during construction\n this.drive_type = disk_format!.drive_type\n }\n\n if (DEBUG) {\n dbg_log(\n 'disk inserted into ' +\n this.name +\n ': type: ' +\n disk_format!.drive_type +\n ', C/H/S: ' +\n disk_format!.tracks +\n '/' +\n disk_format!.heads +\n '/' +\n disk_format!.sectors +\n ', size: ' +\n new_buffer.byteLength,\n LOG_FLOPPY,\n )\n }\n return true\n }\n\n /**\n * Eject disk from this floppy drive.\n */\n eject_disk(): void {\n this.max_track = 0\n this.max_head = 0\n this.max_sect = 0\n this.media_changed = true\n this.buffer = null\n }\n\n /**\n * Returns this drive's current image buffer or null if no disk is inserted.\n */\n get_buffer(): Uint8Array | null {\n return this.buffer ? new Uint8Array(this.buffer.buffer) : null\n }\n\n /**\n * Map structured C/H/S address to linear block address (LBA).\n */\n chs2lba(track: number, head: number, sect: number): number {\n return (track * this.max_head + head) * this.max_sect + sect - 1\n }\n\n /**\n * Find best-matching disk format for the given image buffer.\n *\n * If the given drive_type is CMOS_FDD_TYPE_NO_DRIVE then drive types are\n * ignored and the first matching disk format is selected (auto-detect).\n *\n * If the size of the given buffer does not match any known floppy disk\n * format then the smallest format larger than the image buffer is\n * selected, and buffer is copied into a new, format-sized buffer with\n * trailing zeroes.\n *\n * Returns [null, null] if the given buffer is larger than any known\n * floppy disk format.\n */\n find_disk_format(\n buffer: SyncBuffer,\n drive_type: number,\n ): [SyncBuffer | null, DiskFormat | null] {\n const autodetect = drive_type === CMOS_FDD_TYPE_NO_DRIVE\n const buffer_size = buffer.byteLength\n\n let preferred_match = -1,\n medium_match = -1,\n size_match = -1,\n nearest_match = -1,\n nearest_size = -1\n for (let i = 0; i < DISK_FORMATS.length; i++) {\n const disk_format = DISK_FORMATS[i]\n const disk_size =\n disk_format.sectors *\n disk_format.tracks *\n disk_format.heads *\n SECTOR_SIZE\n if (buffer_size === disk_size) {\n if (autodetect || disk_format.drive_type === drive_type) {\n // (1) same size and CMOS drive type\n preferred_match = i\n break\n } else if (\n !autodetect &&\n CMOS_FDD_TYPE_MEDIUM[disk_format.drive_type] ===\n CMOS_FDD_TYPE_MEDIUM[drive_type]\n ) {\n // (2) same size and physical medium size (5\"1/4 or 3\"1/2)\n medium_match = medium_match === -1 ? i : medium_match\n } else {\n // (3) same size\n size_match = size_match === -1 ? i : size_match\n }\n } else if (buffer_size < disk_size) {\n if (nearest_size === -1 || disk_size < nearest_size) {\n // (4) nearest matching size\n nearest_match = i\n nearest_size = disk_size\n }\n }\n }\n\n if (preferred_match !== -1) {\n return [buffer, DISK_FORMATS[preferred_match]]\n } else if (medium_match !== -1) {\n return [buffer, DISK_FORMATS[medium_match]]\n } else if (size_match !== -1) {\n return [buffer, DISK_FORMATS[size_match]]\n } else if (nearest_match !== -1) {\n const tmp_buffer = new Uint8Array(nearest_size)\n tmp_buffer.set(new Uint8Array(buffer.buffer))\n return [\n new SyncBuffer(tmp_buffer.buffer),\n DISK_FORMATS[nearest_match],\n ]\n } else {\n return [null, null]\n }\n }\n\n /**\n * Seek to a new position, returns:\n * 0 if already on right track\n * 1 if track changed\n * 2 if track is invalid\n * 3 if sector is invalid\n */\n seek(head: number, track: number, sect: number): number {\n if (track > this.max_track || (head !== 0 && this.max_head === 1)) {\n dbg_log(\n 'WARNING: attempt to seek to invalid track: head: ' +\n head +\n ', track: ' +\n track +\n ', sect: ' +\n sect,\n LOG_FLOPPY,\n )\n return 2\n }\n if (sect > this.max_sect) {\n dbg_log(\n 'WARNING: attempt to seek beyond last sector: ' +\n sect +\n ' (max: ' +\n this.max_sect +\n ')',\n LOG_FLOPPY,\n )\n return 3\n }\n\n let result = 0\n const curr_lba = this.chs2lba(\n this.curr_track,\n this.curr_head,\n this.curr_sect,\n )\n const new_lba = this.chs2lba(track, head, sect)\n if (curr_lba !== new_lba) {\n if (this.curr_track !== track) {\n if (this.buffer) {\n this.media_changed = false\n }\n result = 1\n }\n this.curr_head = head\n this.curr_track = track\n this.curr_sect = sect\n }\n\n if (!this.buffer) {\n result = 2\n }\n\n return result\n }\n\n get_state(): (number | boolean | [number, Uint8Array] | null)[] {\n const state: (number | boolean | [number, Uint8Array] | null)[] = []\n state[0] = this.drive_type\n state[1] = this.max_track\n state[2] = this.max_head\n state[3] = this.max_sect\n state[4] = this.curr_track\n state[5] = this.curr_head\n state[6] = this.curr_sect\n state[7] = this.perpendicular\n state[8] = this.read_only\n state[9] = this.media_changed\n state[10] = this.buffer ? this.buffer.get_state() : null // SyncBuffer\n return state\n }\n\n set_state(state: any[]): void {\n this.drive_type = state[0]\n this.max_track = state[1]\n this.max_head = state[2]\n this.max_sect = state[3]\n this.curr_track = state[4]\n this.curr_head = state[5]\n this.curr_sect = state[6]\n this.perpendicular = state[7]\n this.read_only = state[8]\n this.media_changed = state[9]\n if (state[10]) {\n if (!this.buffer) {\n this.buffer = new SyncBuffer(new ArrayBuffer(0))\n }\n this.buffer.set_state(state[10])\n } else {\n this.buffer = null\n }\n }\n}\n", "declare let DEBUG: boolean\n\nimport { LOG_DISK } from './const.js'\nimport { h } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\nimport {\n CMOS_BIOS_DISKTRANSFLAG,\n CMOS_DISK_DATA,\n CMOS_DISK_DRIVE1_CYL,\n CMOS_DISK_DRIVE2_CYL,\n} from './rtc.js'\n\nimport { BusConnector } from './bus.js'\nimport { IO } from './io.js'\nimport { PCI } from './pci.js'\n\n// Minimal interface for the buffer objects IDE uses (SyncBuffer, AsyncXHRBuffer, etc.)\ninterface IDEDiskBuffer {\n byteLength: number\n get(start: number, len: number, fn: (data: Uint8Array) => void): void\n set(start: number, slice: Uint8Array, fn: () => void): void\n\n set_state(state: any[]): void\n}\n\n// Minimal interface for the RTC fields IDE uses.\ninterface IDERTC {\n cmos_read(index: number): number\n cmos_write(index: number, value: number): void\n}\n\n// Minimal interface for CPU fields IDE uses.\ninterface IDECpu {\n io: IO\n mem8: Uint8Array\n devices: {\n pci: PCI\n rtc: IDERTC\n }\n device_raise_irq(irq: number): void\n device_lower_irq(irq: number): void\n read8(addr: number): number\n read16(addr: number): number\n read32s(addr: number): number\n write_blob(blob: Uint8Array, addr: number): void\n}\n\n// IDE device configuration entry\ninterface IDEDeviceConfig {\n buffer?: IDEDiskBuffer\n is_cdrom?: boolean\n}\n\n// ide_config: [ [primary-master, primary-slave], [secondary-master, secondary-slave] ]\ntype IDEConfig = [\n [IDEDeviceConfig | undefined, IDEDeviceConfig | undefined],\n [IDEDeviceConfig | undefined, IDEDeviceConfig | undefined],\n]\n\n// ATA/ATAPI-6/8 IDE Controller\n//\n// References\n// - [ATA8-ACS]\n// ATA/ATAPI Command Set - 3 (ACS-3) (Rev. 5, Oct. 28, 2013)\n// https://read.seas.harvard.edu/cs161/2019/pdf/ata-atapi-8.pdf\n// - [ATA-6]\n// AT Attachment with Packet Interface - 6 (ATA/ATAPI-6) (Rev. 3a; Dec. 14, 2001)\n// https://technion-csl.github.io/ose/readings/hardware/ATA-d1410r3a.pdf\n// - [CD-SCSI-2]\n// PROPOSAL FOR CD-ROM IN SCSI-2 (X3T9.2/87) (Rev. 0, Jun. 30, 1987)\n// https://www.t10.org/ftp/x3t9.2/document.87/87-106r0.txt\n// https://www.t10.org/ftp/x3t9.2/document.87/87-106r1.txt (errata to r0)\n// - [SAM-3]\n// SCSI Architecture Model - 3 (SAM-3) (Sep. 21, 2004)\n// https://dn790004.ca.archive.org/0/items/SCSISpecificationDocumentsSCSIDocuments/SCSI%20Architecture%20Model/SCSI%20Architecture%20Model%203%20rev%2014.pdf\n// - [SPC-3]\n// SCSI Primary Commands - 3 (SPC-3) (July 20, 2008)\n// https://www.t10.org/ftp/t10/document.08/08-309r0.pdf\n// - [MMC-3]\n// SCSI Multimedia Commands - 3 (MMC-3) (Rev. 10g, Nov. 12, 2001)\n// https://ia902808.us.archive.org/33/items/mmc3r10g/mmc3r10g.pdf\n// - [MMC-2]\n// Packet Commands for C/DVD Devices (1997)\n// https://www.t10.org/ftp/t10/document.97/97-108r0.pdf\n// - [BMI-1]\n// Programming Interface for Bus Master IDE Controller, Revision 1.0, 5/16/94\n// https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/u9proj/idems100.pdf\n// - [SFF-8020]\n// ATA Packet Interface for CD-ROMs (Rev. 1.2, Feb. 12, 1994)\n// https://dn790009.ca.archive.org/0/items/SCSISpecificationDocumentsATAATAPI/SFF-8020_%20ATA%20Packet%20Interface%20for%20CD-ROMs%20-%20SFF.pdf\n\nconst CDROM_SECTOR_SIZE = 2048\nconst HD_SECTOR_SIZE = 512\n\nconst BUS_MASTER_BASE = 0xb400\n\n// Per-channel ATA register offsets, legend:\n// (*1*) Control block register (BAR1/3), else: Command block register (BAR0/2)\n// Read-only registers:\nconst ATA_REG_ERROR = 0x01 // Error register, see [ATA-6] 7.9\nconst ATA_REG_STATUS = 0x07 // Status register, see [ATA-6] 7.15\nconst ATA_REG_ALT_STATUS = 0x00 // (*1*) Alternate Status register, see [ATA-6] 7.3\n// Read-/writable registers:\nconst ATA_REG_DATA = 0x00 // Data register, see [ATA-6] 7.6\nconst ATA_REG_SECTOR = 0x02 // Sector Count register, see [ATA-6] 7.14\nconst ATA_REG_LBA_LOW = 0x03 // LBA Low register, see [ATA-6] 7.12\nconst ATA_REG_LBA_MID = 0x04 // LBA Mid register, see [ATA-6] 7.13\nconst ATA_REG_LBA_HIGH = 0x05 // LBA High register, see [ATA-6] 7.11\nconst ATA_REG_DEVICE = 0x06 // Device register, see [ATA-6] 7.7\n// Write-only registers:\nconst ATA_REG_FEATURES = 0x01 // Features register, see [ATA-6] 7.10\nconst ATA_REG_COMMAND = 0x07 // Command register, see [ATA-6] 7.4\nconst ATA_REG_CONTROL = 0x00 // (*1*) Device Control register, see [ATA-6] 7.8\n\n// Per-channel Bus Master IDE register offsets (BAR4), see [BMI-1] 2.0\n// these are the primary channel's offsets, add 8 for secondary\nconst BMI_REG_COMMAND = 0x00 // Bus Master IDE Command register\nconst BMI_REG_STATUS = 0x02 // Bus Master IDE Status register\nconst BMI_REG_PRDT = 0x04 // Bus Master IDE PRD Table Address register\n\n// Error register bits:\n// All bits except for bit 0x04 are command dependent.\nconst ATA_ER_ABRT = 0x04 // Command aborted\n\n// Status register bits:\nconst ATA_SR_ERR = 0x01 // Error (ATA)\nconst ATA_SR_COND = 0x01 // Check Condition (ATAPI)\nconst _ATA_SR_SENS = 0x02 // Sense Available (ATAPI)\nconst _ATA_SR_AERR = 0x04 // Alignment Error\nconst ATA_SR_DRQ = 0x08 // Data Request\nconst ATA_SR_DSC = 0x10 // Drive Seek Complete / Deferred Write Error\nconst ATA_SR_DF = 0x20 // Device Fault / Stream Error\nconst ATA_SR_DRDY = 0x40 // Drive Ready\nconst ATA_SR_BSY = 0x80 // Busy\n\n// Device register bits:\n// Bits 0x20/0x80 are obsolete and 0x01/0x02/0x04/0x08/0x40 are command dependent.\nconst ATA_DR_DEV = 0x10 // Device select; slave device if set, else master device\n\n// Device Control register bits:\n// Bits 0x08/0x10/0x20/0x40 are reserved and bit 0x01 is always zero.\nconst ATA_CR_NIEN = 0x02 // Interrupt disable (not Interrupt ENable)\nconst ATA_CR_SRST = 0x04 // Software reset\nconst _ATA_CR_HOB = 0x80 // 48-bit Address feature set\n\n// ATA commands\nconst ATA_CMD_DEVICE_RESET = 0x08 // see [ATA8-ACS] 7.6\nconst ATA_CMD_EXECUTE_DEVICE_DIAGNOSTIC = 0x90 // see [ATA8-ACS] 7.9\nconst ATA_CMD_FLUSH_CACHE = 0xe7 // see [ATA8-ACS] 7.10\nconst ATA_CMD_FLUSH_CACHE_EXT = 0xea // see [ATA8-ACS] 7.11\nconst ATA_CMD_GET_MEDIA_STATUS = 0xda // see [ATA-6] 8.14\nconst ATA_CMD_IDENTIFY_DEVICE = 0xec // see [ATA8-ACS] 7.12\nconst ATA_CMD_IDENTIFY_PACKET_DEVICE = 0xa1 // see [ATA8-ACS] 7.13\nconst ATA_CMD_IDLE_IMMEDIATE = 0xe1 // see [ATA8-ACS] 7.15\nconst ATA_CMD_INITIALIZE_DEVICE_PARAMETERS = 0x91 // not mentioned in [ATA-6] or [ATA8-ACS]\nconst ATA_CMD_MEDIA_LOCK = 0xde // see [ATA-6] 8.20\nconst ATA_CMD_NOP = 0x00 // see [ATA8-ACS] 7.17\nconst ATA_CMD_PACKET = 0xa0 // see [ATA8-ACS] 7.18\nconst ATA_CMD_READ_DMA = 0xc8 // see [ATA8-ACS] 7.21\nconst ATA_CMD_READ_DMA_EXT = 0x25 // see [ATA8-ACS] 7.22\nconst ATA_CMD_READ_MULTIPLE = 0x29 // see [ATA8-ACS] 7.26\nconst ATA_CMD_READ_MULTIPLE_EXT = 0xc4 // see [ATA8-ACS] 7.27\nconst ATA_CMD_READ_NATIVE_MAX_ADDRESS = 0xf8 // see [ATA-6] 8.32\nconst ATA_CMD_READ_NATIVE_MAX_ADDRESS_EXT = 0x27 // see [ATA-6] 8.33\nconst ATA_CMD_READ_SECTORS = 0x20 // see [ATA8-ACS] 7.28\nconst ATA_CMD_READ_SECTORS_EXT = 0x24 // see [ATA8-ACS] 7.29\nconst ATA_CMD_READ_VERIFY_SECTORS = 0x40 // see [ATA8-ACS] 7.32\nconst ATA_CMD_SECURITY_FREEZE_LOCK = 0xf5 // see [ATA8-ACS] 7.40\nconst ATA_CMD_SET_FEATURES = 0xef // see [ATA8-ACS] 7.45\nconst ATA_CMD_SET_MAX = 0xf9 // see [ATA-6] 8.47\nconst ATA_CMD_SET_MULTIPLE_MODE = 0xc6 // see [ATA8-ACS] 7.46\nconst ATA_CMD_STANDBY_IMMEDIATE = 0xe0 // see [ATA8-ACS] 7.50\nconst ATA_CMD_WRITE_DMA = 0xca // see [ATA8-ACS] 7.58\nconst ATA_CMD_WRITE_DMA_EXT = 0x35 // see [ATA8-ACS] 7.59\nconst ATA_CMD_WRITE_MULTIPLE = 0x39 // see [ATA8-ACS] 7.64\nconst ATA_CMD_WRITE_MULTIPLE_EXT = 0xc5 // see [ATA8-ACS] 7.65\nconst ATA_CMD_WRITE_SECTORS = 0x30 // see [ATA8-ACS] 7.67\nconst ATA_CMD_WRITE_SECTORS_EXT = 0x34 // see [ATA8-ACS] 7.68\nconst ATA_CMD_10h = 0x10 // command obsolete/unknown, see [ATA-6] Table E.2\nconst ATA_CMD_F0h = 0xf0 // vendor-specific\n\nconst ATA_CMD_NAME: Record<number, string> = {\n [ATA_CMD_DEVICE_RESET]: 'DEVICE RESET',\n [ATA_CMD_EXECUTE_DEVICE_DIAGNOSTIC]: 'EXECUTE DEVICE DIAGNOSTIC',\n [ATA_CMD_FLUSH_CACHE]: 'FLUSH CACHE',\n [ATA_CMD_FLUSH_CACHE_EXT]: 'FLUSH CACHE EXT',\n [ATA_CMD_GET_MEDIA_STATUS]: 'GET MEDIA STATUS',\n [ATA_CMD_IDENTIFY_DEVICE]: 'IDENTIFY DEVICE',\n [ATA_CMD_IDENTIFY_PACKET_DEVICE]: 'IDENTIFY PACKET DEVICE',\n [ATA_CMD_IDLE_IMMEDIATE]: 'IDLE IMMEDIATE',\n [ATA_CMD_INITIALIZE_DEVICE_PARAMETERS]: 'INITIALIZE DEVICE PARAMETERS',\n [ATA_CMD_MEDIA_LOCK]: 'MEDIA LOCK',\n [ATA_CMD_NOP]: 'NOP',\n [ATA_CMD_PACKET]: 'PACKET',\n [ATA_CMD_READ_DMA]: 'READ DMA',\n [ATA_CMD_READ_DMA_EXT]: 'READ DMA EXT',\n [ATA_CMD_READ_MULTIPLE]: 'READ MULTIPLE',\n [ATA_CMD_READ_MULTIPLE_EXT]: 'READ MULTIPLE EXT',\n [ATA_CMD_READ_NATIVE_MAX_ADDRESS]: 'READ NATIVE MAX ADDRESS',\n [ATA_CMD_READ_NATIVE_MAX_ADDRESS_EXT]: 'READ NATIVE MAX ADDRESS EXT',\n [ATA_CMD_READ_SECTORS]: 'READ SECTORS',\n [ATA_CMD_READ_SECTORS_EXT]: 'READ SECTORS EXT',\n [ATA_CMD_READ_VERIFY_SECTORS]: 'READ VERIFY SECTORS',\n [ATA_CMD_SECURITY_FREEZE_LOCK]: 'SECURITY FREEZE LOCK',\n [ATA_CMD_SET_FEATURES]: 'SET FEATURES',\n [ATA_CMD_SET_MAX]: 'SET MAX',\n [ATA_CMD_SET_MULTIPLE_MODE]: 'SET MULTIPLE MODE',\n [ATA_CMD_STANDBY_IMMEDIATE]: 'STANDBY IMMEDIATE',\n [ATA_CMD_WRITE_DMA]: 'WRITE DMA',\n [ATA_CMD_WRITE_DMA_EXT]: 'WRITE DMA EXT',\n [ATA_CMD_WRITE_MULTIPLE]: 'WRITE MULTIPLE',\n [ATA_CMD_WRITE_MULTIPLE_EXT]: 'WRITE MULTIPLE EXT',\n [ATA_CMD_WRITE_SECTORS]: 'WRITE SECTORS',\n [ATA_CMD_WRITE_SECTORS_EXT]: 'WRITE SECTORS EXT',\n [ATA_CMD_10h]: '<UNKNOWN 10h>',\n [ATA_CMD_F0h]: '<VENDOR-SPECIFIC F0h>',\n}\n\n// ATAPI (SCSI-2/MMC-2) commands\nconst ATAPI_CMD_GET_CONFIGURATION = 0x46 // see [CD-SCSI-2]\nconst ATAPI_CMD_GET_EVENT_STATUS_NOTIFICATION = 0x4a // see [MMC-2] 9.1.2\nconst ATAPI_CMD_INQUIRY = 0x12 // see [MMC-2] 9.1.3\nconst ATAPI_CMD_MECHANISM_STATUS = 0xbd // see [MMC-2] 9.1.5\nconst ATAPI_CMD_MODE_SENSE_6 = 0x1a // see [CD-SCSI-2]\nconst ATAPI_CMD_MODE_SENSE_10 = 0x5a // see [MMC-2] 9.1.7\nconst ATAPI_CMD_PAUSE = 0x45 // see [CD-SCSI-2]\nconst ATAPI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1e // see [MMC-2] 9.1.9\nconst ATAPI_CMD_READ_10 = 0x28 // see [CD-SCSI-2]\nconst ATAPI_CMD_READ_12 = 0xa8 // see [SFF-8020] 9.8.14\nconst ATAPI_CMD_READ_CAPACITY = 0x25 // see [MMC-2] 9.1.12\nconst ATAPI_CMD_READ_CD = 0xbe // see [CD-SCSI-2]\nconst ATAPI_CMD_READ_DISK_INFORMATION = 0x51 // see [CD-SCSI-2]\nconst ATAPI_CMD_READ_SUBCHANNEL = 0x42 // see [CD-SCSI-2]\nconst ATAPI_CMD_READ_TOC_PMA_ATIP = 0x43 // see [CD-SCSI-2]\nconst ATAPI_CMD_READ_TRACK_INFORMATION = 0x52 // see [CD-SCSI-2]\nconst ATAPI_CMD_REQUEST_SENSE = 0x03 // see [MMC-2] 9.1.18\nconst ATAPI_CMD_START_STOP_UNIT = 0x1b // see [CD-SCSI-2]\nconst ATAPI_CMD_TEST_UNIT_READY = 0x00 // see [MMC-2] 9.1.20\n\n// ATAPI command flags\nconst ATAPI_CF_NONE = 0x00 // no flags\nconst ATAPI_CF_NEEDS_DISK = 0x01 // command needs inserted disk\nconst _ATAPI_CF_UNIT_ATTN = 0x02 // bounce command if unit attention condition is active\n\n// ATAPI commands, for flags see [MMC-3] 4.2.6\nconst ATAPI_CMD: Record<number, { name: string; flags: number }> = {\n [ATAPI_CMD_GET_CONFIGURATION]: {\n name: 'GET CONFIGURATION',\n flags: ATAPI_CF_NONE,\n },\n [ATAPI_CMD_GET_EVENT_STATUS_NOTIFICATION]: {\n name: 'GET EVENT STATUS NOTIFICATION',\n flags: ATAPI_CF_NONE,\n },\n [ATAPI_CMD_INQUIRY]: { name: 'INQUIRY', flags: ATAPI_CF_NONE },\n [ATAPI_CMD_MECHANISM_STATUS]: {\n name: 'MECHANISM STATUS',\n flags: ATAPI_CF_NONE,\n },\n [ATAPI_CMD_MODE_SENSE_6]: { name: 'MODE SENSE (6)', flags: ATAPI_CF_NONE },\n [ATAPI_CMD_MODE_SENSE_10]: {\n name: 'MODE SENSE (10)',\n flags: ATAPI_CF_NONE,\n },\n [ATAPI_CMD_PAUSE]: { name: 'PAUSE', flags: ATAPI_CF_NEEDS_DISK },\n [ATAPI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL]: {\n name: 'PREVENT ALLOW MEDIUM REMOVAL',\n flags: ATAPI_CF_NONE,\n },\n [ATAPI_CMD_READ_10]: { name: 'READ (10)', flags: ATAPI_CF_NEEDS_DISK },\n [ATAPI_CMD_READ_12]: { name: 'READ (12)', flags: ATAPI_CF_NEEDS_DISK },\n [ATAPI_CMD_READ_CAPACITY]: {\n name: 'READ CAPACITY',\n flags: ATAPI_CF_NEEDS_DISK,\n },\n [ATAPI_CMD_READ_CD]: { name: 'READ CD', flags: ATAPI_CF_NEEDS_DISK },\n [ATAPI_CMD_READ_DISK_INFORMATION]: {\n name: 'READ DISK INFORMATION',\n flags: ATAPI_CF_NEEDS_DISK,\n },\n [ATAPI_CMD_READ_SUBCHANNEL]: {\n name: 'READ SUBCHANNEL',\n flags: ATAPI_CF_NEEDS_DISK,\n },\n [ATAPI_CMD_READ_TOC_PMA_ATIP]: {\n name: 'READ TOC PMA ATIP',\n flags: ATAPI_CF_NEEDS_DISK,\n },\n [ATAPI_CMD_READ_TRACK_INFORMATION]: {\n name: 'READ TRACK INFORMATION',\n flags: ATAPI_CF_NEEDS_DISK,\n },\n [ATAPI_CMD_REQUEST_SENSE]: { name: 'REQUEST SENSE', flags: ATAPI_CF_NONE },\n [ATAPI_CMD_START_STOP_UNIT]: {\n name: 'START STOP UNIT',\n flags: ATAPI_CF_NONE,\n },\n [ATAPI_CMD_TEST_UNIT_READY]: {\n name: 'TEST UNIT READY',\n flags: ATAPI_CF_NEEDS_DISK,\n },\n}\n\n// ATAPI device signature\nconst ATAPI_SIGNATURE_LO = 0x14\nconst ATAPI_SIGNATURE_HI = 0xeb\n\n// ATAPI 4-bit Sense Keys, see [MMC-2] 9.1.18.3, Table 123\nconst _ATAPI_SK_NO_SENSE = 0\nconst _ATAPI_SK_RECOVERED_ERROR = 1\nconst ATAPI_SK_NOT_READY = 2\nconst _ATAPI_SK_MEDIUM_ERROR = 3\nconst _ATAPI_SK_HARDWARE_ERROR = 4\nconst ATAPI_SK_ILLEGAL_REQUEST = 5\nconst ATAPI_SK_UNIT_ATTENTION = 6\nconst _ATAPI_SK_DATA_PROTECT = 7\nconst _ATAPI_SK_BLANK_CHECK = 8\nconst _ATAPI_SK_ABORTED_COMMAND = 11\n\n// ATAPI 8-bit Additional Sense Codes, see [MMC-2] 9.1.18.3, Table 124\n// https://github.com/qemu/qemu/blob/3c5a5e213e5f08fbfe70728237f7799ac70f5b99/hw/ide/ide-internal.h#L288\nconst ATAPI_ASC_INV_FIELD_IN_CMD_PACKET = 0x24\nconst _ATAPI_ASC_MEDIUM_MAY_HAVE_CHANGED = 0x28\nconst ATAPI_ASC_MEDIUM_NOT_PRESENT = 0x3a\n\n// Debug log detail bits (internal to this module)\nconst LOG_DETAIL_NONE = 0x00 // disable debug logging of details\nconst LOG_DETAIL_REG_IO = 0x01 // log register read/write access\nconst LOG_DETAIL_IRQ = 0x02 // log IRQ raise/lower events\nconst LOG_DETAIL_RW = 0x04 // log data read/write-related events\nconst LOG_DETAIL_RW_DMA = 0x08 // log DMA data read/write-related events\nconst LOG_DETAIL_CHS = 0x10 // log register-CHS to LBA conversions\nconst _LOG_DETAIL_ALL = 0xff // log all details\n// the bitset of active log details (should be 0 when not in DEBUG mode)\nconst LOG_DETAILS = DEBUG ? LOG_DETAIL_NONE : 0\n\nexport class IDEController {\n cpu: IDECpu\n bus: BusConnector\n primary: IDEChannel | undefined\n secondary: IDEChannel | undefined\n name: string\n pci_id: number\n pci_space: number[]\n pci_bars: ({ size: number } | undefined)[]\n\n constructor(\n cpu: IDECpu,\n bus: BusConnector,\n ide_config: IDEConfig | undefined,\n ) {\n this.cpu = cpu\n this.bus = bus\n\n this.primary = undefined\n this.secondary = undefined\n this.name = 'ide'\n this.pci_id = 0\n this.pci_space = []\n this.pci_bars = []\n\n const has_primary = ide_config && ide_config[0][0]\n const has_secondary = ide_config && ide_config[1][0]\n if (has_primary || has_secondary) {\n if (has_primary) {\n this.primary = new IDEChannel(\n this,\n 0,\n ide_config![0],\n 0x1f0,\n 0x3f6,\n 14,\n )\n }\n if (has_secondary) {\n this.secondary = new IDEChannel(\n this,\n 1,\n ide_config![1],\n 0x170,\n 0x376,\n 15,\n )\n }\n\n const vendor_id = 0x8086 // Intel Corporation\n const device_id = 0x7010 // 82371SB PIIX3 IDE [Natoma/Triton II]\n const class_code = 0x01 // Mass Storage Controller\n const subclass = 0x01 // IDE Controller\n const prog_if = 0x80 // ISA Compatibility mode-only controller, supports bus mastering\n const interrupt_line = 0x00 // IRQs 14 and 15 are predefined in Compatibility mode and this field is ignored\n const command_base0 = has_primary ? this.primary!.command_base : 0\n const control_base0 = has_primary ? this.primary!.control_base : 0\n const command_base1 = has_secondary\n ? this.secondary!.command_base\n : 0\n const control_base1 = has_secondary\n ? this.secondary!.control_base\n : 0\n\n this.name = 'ide'\n this.pci_id = 0x1e << 3\n this.pci_space = [\n vendor_id & 0xff,\n vendor_id >> 8,\n device_id & 0xff,\n device_id >> 8,\n 0x05,\n 0x00,\n 0xa0,\n 0x02,\n 0x00,\n prog_if,\n subclass,\n class_code,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n (command_base0 & 0xff) | 1,\n command_base0 >> 8,\n 0x00,\n 0x00,\n (control_base0 & 0xff) | 1,\n control_base0 >> 8,\n 0x00,\n 0x00,\n (command_base1 & 0xff) | 1,\n command_base1 >> 8,\n 0x00,\n 0x00,\n (control_base1 & 0xff) | 1,\n control_base1 >> 8,\n 0x00,\n 0x00,\n (BUS_MASTER_BASE & 0xff) | 1,\n BUS_MASTER_BASE >> 8,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x43,\n 0x10,\n 0xd4,\n 0x82,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n interrupt_line,\n 0x01,\n 0x00,\n 0x00,\n // 0x40\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n // 0x80\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n ]\n this.pci_bars = [\n has_primary ? { size: 8 } : undefined, // BAR0: Command block register address of primary channel\n has_primary ? { size: 1 } : undefined, // BAR1: Control block register address of primary channel\n has_secondary ? { size: 8 } : undefined, // BAR2: Command block register address of secondary channel\n has_secondary ? { size: 1 } : undefined, // BAR3: Control block register address of secondary channel\n { size: 16 }, // BAR4: Bus Master I/O register address of both channels (8+8)\n ]\n cpu.devices.pci.register_device(this)\n }\n }\n\n get_state(): unknown[] {\n const state: unknown[] = []\n state[0] = this.primary\n state[1] = this.secondary\n return state\n }\n\n set_state(state: any[]): void {\n if (this.primary) {\n this.primary.set_state(state[0])\n }\n if (this.secondary) {\n this.secondary.set_state(state[1])\n }\n }\n}\n\nclass IDEChannel {\n controller: IDEController\n channel_nr: number\n cpu: IDECpu\n bus: BusConnector\n command_base: number\n control_base: number\n irq: number\n name: string\n master: IDEInterface\n slave: IDEInterface\n current_interface: IDEInterface\n device_control_reg: number\n prdt_addr: number\n dma_status: number\n dma_command: number\n\n constructor(\n controller: IDEController,\n channel_nr: number,\n channel_config:\n | [IDEDeviceConfig | undefined, IDEDeviceConfig | undefined]\n | undefined,\n command_base: number,\n control_base: number,\n irq: number,\n ) {\n this.controller = controller\n this.channel_nr = channel_nr\n this.cpu = controller.cpu\n this.bus = controller.bus\n this.command_base = command_base\n this.control_base = control_base\n this.irq = irq\n this.name = 'ide' + channel_nr\n\n const master_cfg = channel_config ? channel_config[0] : undefined\n const slave_cfg = channel_config ? channel_config[1] : undefined\n this.master = new IDEInterface(\n this,\n 0,\n master_cfg?.buffer,\n master_cfg?.is_cdrom,\n )\n this.slave = new IDEInterface(\n this,\n 1,\n slave_cfg?.buffer,\n slave_cfg?.is_cdrom,\n )\n\n this.current_interface = this.master\n\n this.device_control_reg = ATA_CR_NIEN\n this.prdt_addr = 0\n this.dma_status = 0\n this.dma_command = 0\n\n const cpu = controller.cpu\n\n //\n // Command Block Registers: command_base + 0...7 (BAR0: 1F0h, BAR2: 170h)\n //\n\n cpu.io.register_read(\n this.command_base | ATA_REG_DATA,\n this,\n () => {\n return this.current_interface.read_data(1)\n },\n () => {\n return this.current_interface.read_data(2)\n },\n () => {\n return this.current_interface.read_data(4)\n },\n )\n\n cpu.io.register_read(this.command_base | ATA_REG_ERROR, this, () => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': read Error register: ' +\n h(this.current_interface.error_reg & 0xff),\n LOG_DISK,\n )\n }\n return this.current_interface.error_reg & 0xff\n })\n\n cpu.io.register_read(this.command_base | ATA_REG_SECTOR, this, () => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': read Sector Count register: ' +\n h(this.current_interface.sector_count_reg & 0xff),\n LOG_DISK,\n )\n }\n return this.current_interface.sector_count_reg & 0xff\n })\n\n cpu.io.register_read(this.command_base | ATA_REG_LBA_LOW, this, () => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': read LBA Low register: ' +\n h(this.current_interface.lba_low_reg & 0xff),\n LOG_DISK,\n )\n }\n return this.current_interface.lba_low_reg & 0xff\n })\n\n cpu.io.register_read(this.command_base | ATA_REG_LBA_MID, this, () => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': read LBA Mid register: ' +\n h(this.current_interface.lba_mid_reg & 0xff),\n LOG_DISK,\n )\n }\n return this.current_interface.lba_mid_reg & 0xff\n })\n\n cpu.io.register_read(this.command_base | ATA_REG_LBA_HIGH, this, () => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': read LBA High register: ' +\n h(this.current_interface.lba_high_reg & 0xff),\n LOG_DISK,\n )\n }\n return this.current_interface.lba_high_reg & 0xff\n })\n\n cpu.io.register_read(this.command_base | ATA_REG_DEVICE, this, () => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name + ': read Device register',\n LOG_DISK,\n )\n }\n return this.current_interface.device_reg & 0xff\n })\n\n cpu.io.register_read(this.command_base | ATA_REG_STATUS, this, () => {\n const status = this.read_status()\n if (LOG_DETAILS & (LOG_DETAIL_REG_IO | LOG_DETAIL_IRQ)) {\n dbg_log(\n `${this.current_interface.name}: read Status register: ${h(status, 2)} (lower IRQ ${this.irq})`,\n LOG_DISK,\n )\n }\n this.cpu.device_lower_irq(this.irq)\n return status\n })\n\n cpu.io.register_write(\n this.command_base | ATA_REG_DATA,\n this,\n (data: number) => {\n this.current_interface.write_data_port8(data)\n },\n (data: number) => {\n this.current_interface.write_data_port16(data)\n },\n (data: number) => {\n this.current_interface.write_data_port32(data)\n },\n )\n\n cpu.io.register_write(\n this.command_base | ATA_REG_FEATURES,\n this,\n (data: number) => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': write Features register: ' +\n h(data),\n LOG_DISK,\n )\n }\n this.current_interface.features_reg =\n ((this.current_interface.features_reg << 8) | data) & 0xffff\n },\n )\n\n cpu.io.register_write(\n this.command_base | ATA_REG_SECTOR,\n this,\n (data: number) => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': write Sector Count register: ' +\n h(data),\n LOG_DISK,\n )\n }\n this.current_interface.sector_count_reg =\n ((this.current_interface.sector_count_reg << 8) | data) &\n 0xffff\n },\n )\n\n cpu.io.register_write(\n this.command_base | ATA_REG_LBA_LOW,\n this,\n (data: number) => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': write LBA Low register: ' +\n h(data),\n LOG_DISK,\n )\n }\n this.current_interface.lba_low_reg =\n ((this.current_interface.lba_low_reg << 8) | data) & 0xffff\n },\n )\n\n cpu.io.register_write(\n this.command_base | ATA_REG_LBA_MID,\n this,\n (data: number) => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': write LBA Mid register: ' +\n h(data),\n LOG_DISK,\n )\n }\n this.current_interface.lba_mid_reg =\n ((this.current_interface.lba_mid_reg << 8) | data) & 0xffff\n },\n )\n\n cpu.io.register_write(\n this.command_base | ATA_REG_LBA_HIGH,\n this,\n (data: number) => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': write LBA High register: ' +\n h(data),\n LOG_DISK,\n )\n }\n this.current_interface.lba_high_reg =\n ((this.current_interface.lba_high_reg << 8) | data) & 0xffff\n },\n )\n\n cpu.io.register_write(\n this.command_base | ATA_REG_DEVICE,\n this,\n (data: number) => {\n const select_slave = data & ATA_DR_DEV\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': write Device register: ' +\n h(data, 2),\n LOG_DISK,\n )\n }\n if (\n (select_slave && this.current_interface === this.master) ||\n (!select_slave && this.current_interface === this.slave)\n ) {\n if (select_slave) {\n dbg_log(\n `${this.current_interface.name}: select slave device (${this.channel_nr ? 'secondary' : 'primary'})`,\n LOG_DISK,\n )\n this.current_interface = this.slave\n } else {\n dbg_log(\n `${this.current_interface.name}: select master device (${this.channel_nr ? 'secondary' : 'primary'})`,\n LOG_DISK,\n )\n this.current_interface = this.master\n }\n }\n this.current_interface.device_reg = data\n this.current_interface.is_lba = (data >> 6) & 1 // TODO: where does this definition of bit 6 come from? not in [ATA-6] or [ATA-4]!\n this.current_interface.head = data & 0xf // TODO: same for lower nibble?\n },\n )\n\n cpu.io.register_write(\n this.command_base | ATA_REG_COMMAND,\n this,\n (data: number) => {\n if (LOG_DETAILS & LOG_DETAIL_REG_IO) {\n dbg_log(\n this.current_interface.name +\n ': write Command register',\n LOG_DISK,\n )\n }\n this.current_interface.status_reg &= ~(ATA_SR_ERR | ATA_SR_DF)\n this.current_interface.ata_command(data)\n if (LOG_DETAILS & LOG_DETAIL_IRQ) {\n dbg_log(\n this.current_interface.name + ': lower IRQ ' + this.irq,\n LOG_DISK,\n )\n }\n this.cpu.device_lower_irq(this.irq)\n },\n )\n\n //\n // Control Block Register: control_base (BAR1: 3F6h, BAR3: 376h)\n //\n\n // read Alternate Status register\n cpu.io.register_read(this.control_base | ATA_REG_ALT_STATUS, this, () =>\n this.read_status(),\n )\n\n // write Device Control register\n cpu.io.register_write(\n this.control_base | ATA_REG_CONTROL,\n this,\n (data: number) => this.write_control(data),\n )\n\n //\n // Bus Master Registers: bus_master_base + 0...15 (BAR4: B400h)\n // primary channel: bus_master_base + 0...7, secondary: bus_master_base + 8...15\n //\n\n const bus_master_base = BUS_MASTER_BASE + channel_nr * 8\n\n // read/write Bus Master IDE Command register\n cpu.io.register_read(\n bus_master_base | BMI_REG_COMMAND,\n this,\n () => this.dma_read_command8(),\n undefined,\n () => this.dma_read_command(),\n )\n cpu.io.register_write(\n bus_master_base | BMI_REG_COMMAND,\n this,\n (data: number) => this.dma_write_command8(data),\n undefined,\n (data: number) => this.dma_write_command(data),\n )\n\n // read/write Bus Master IDE Status register\n cpu.io.register_read(bus_master_base | BMI_REG_STATUS, this, () =>\n this.dma_read_status(),\n )\n cpu.io.register_write(\n bus_master_base | BMI_REG_STATUS,\n this,\n (data: number) => this.dma_write_status(data),\n )\n\n // read/write Bus Master IDE PRD Table Address register\n cpu.io.register_read(\n bus_master_base | BMI_REG_PRDT,\n this,\n undefined,\n undefined,\n () => this.dma_read_addr(),\n )\n cpu.io.register_write(\n bus_master_base | BMI_REG_PRDT,\n this,\n undefined,\n undefined,\n (data: number) => this.dma_set_addr(data),\n )\n\n if (DEBUG) {\n Object.seal(this)\n }\n }\n\n read_status(): number {\n return this.current_interface.drive_connected\n ? this.current_interface.status_reg\n : 0\n }\n\n write_control(data: number): void {\n if (LOG_DETAILS & (LOG_DETAIL_REG_IO | LOG_DETAIL_IRQ)) {\n dbg_log(\n this.current_interface.name +\n ': write Device Control register: ' +\n h(data, 2) +\n ' interrupts ' +\n (data & ATA_CR_NIEN ? 'disabled' : 'enabled'),\n LOG_DISK,\n )\n }\n if (data & ATA_CR_SRST) {\n dbg_log(\n `${this.current_interface.name}: soft reset via control port (lower IRQ ${this.irq})`,\n LOG_DISK,\n )\n this.cpu.device_lower_irq(this.irq)\n this.master.device_reset()\n this.slave.device_reset()\n }\n this.device_control_reg = data\n }\n\n dma_read_addr(): number {\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.current_interface.name +\n ': DMA get address: ' +\n h(this.prdt_addr, 8),\n LOG_DISK,\n )\n }\n return this.prdt_addr\n }\n\n dma_set_addr(data: number): void {\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.current_interface.name +\n ': DMA set address: ' +\n h(data, 8),\n LOG_DISK,\n )\n }\n this.prdt_addr = data\n }\n\n dma_read_status(): number {\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.current_interface.name +\n ': DMA read status: ' +\n h(this.dma_status),\n LOG_DISK,\n )\n }\n return this.dma_status\n }\n\n dma_write_status(value: number): void {\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.current_interface.name + ': DMA write status: ' + h(value),\n LOG_DISK,\n )\n }\n this.dma_status &= ~(value & 6)\n }\n\n dma_read_command(): number {\n return this.dma_read_command8() | (this.dma_read_status() << 16)\n }\n\n dma_read_command8(): number {\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.current_interface.name +\n ': DMA read command: ' +\n h(this.dma_command),\n LOG_DISK,\n )\n }\n return this.dma_command\n }\n\n dma_write_command(value: number): void {\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.current_interface.name +\n ': DMA write command: ' +\n h(value),\n LOG_DISK,\n )\n }\n this.dma_write_command8(value & 0xff)\n this.dma_write_status((value >> 16) & 0xff)\n }\n\n dma_write_command8(value: number): void {\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.current_interface.name +\n ': DMA write command8: ' +\n h(value),\n LOG_DISK,\n )\n }\n\n const old_command = this.dma_command\n this.dma_command = value & 0x09\n\n if ((old_command & 1) === (value & 1)) {\n return\n }\n\n if ((value & 1) === 0) {\n this.dma_status &= ~1\n return\n }\n\n this.dma_status |= 1\n\n switch (this.current_interface.current_command) {\n case ATA_CMD_READ_DMA:\n case ATA_CMD_READ_DMA_EXT:\n this.current_interface.do_ata_read_sectors_dma()\n break\n case ATA_CMD_WRITE_DMA:\n case ATA_CMD_WRITE_DMA_EXT:\n this.current_interface.do_ata_write_sectors_dma()\n break\n case ATA_CMD_PACKET:\n this.current_interface.do_atapi_dma()\n break\n default:\n dbg_log(\n this.current_interface.name +\n ': spurious DMA command write, current command: ' +\n h(this.current_interface.current_command),\n LOG_DISK,\n )\n dbg_log(\n this.current_interface.name +\n ': DMA clear status bit 1h, set status bit 2h',\n LOG_DISK,\n )\n this.dma_status &= ~1\n this.dma_status |= 2\n this.push_irq()\n break\n }\n }\n\n push_irq(): void {\n if ((this.device_control_reg & ATA_CR_NIEN) === 0) {\n if (LOG_DETAILS & LOG_DETAIL_IRQ) {\n dbg_log(\n this.current_interface.name + ': push IRQ ' + this.irq,\n LOG_DISK,\n )\n }\n this.dma_status |= 4\n this.cpu.device_raise_irq(this.irq)\n }\n }\n\n get_state(): unknown[] {\n const state: unknown[] = []\n state[0] = this.master\n state[1] = this.slave\n state[2] = this.command_base\n state[3] = this.irq\n // state[4] = this.pci_id;\n state[5] = this.control_base\n // state[6] = this.bus_master_base;\n state[7] = this.name\n state[8] = this.device_control_reg\n state[9] = this.prdt_addr\n state[10] = this.dma_status\n state[11] = this.current_interface === this.master\n state[12] = this.dma_command\n return state\n }\n\n set_state(state: any[]): void {\n this.master.set_state(state[0])\n this.slave.set_state(state[1])\n this.command_base = state[2]\n this.irq = state[3]\n // this.pci_id = state[4];\n this.control_base = state[5]\n // this.bus_master_base = state[6];\n this.name = state[7]\n this.device_control_reg = state[8]\n this.prdt_addr = state[9]\n this.dma_status = state[10]\n this.current_interface = state[11] ? this.master : this.slave\n this.dma_command = state[12]\n }\n}\n\nclass IDEInterface {\n channel: IDEChannel\n name: string\n bus: BusConnector\n channel_nr: number\n interface_nr: number\n cpu: IDECpu\n buffer: IDEDiskBuffer | null\n drive_connected: boolean\n sector_size: number\n is_atapi: boolean\n sector_count: number\n head_count: number\n sectors_per_track: number\n cylinder_count: number\n is_lba: number\n sector_count_reg: number\n lba_low_reg: number\n features_reg: number\n lba_mid_reg: number\n lba_high_reg: number\n head: number\n device_reg: number\n status_reg: number\n sectors_per_drq: number\n error_reg: number\n data_pointer: number\n data: Uint8Array\n data16: Uint16Array\n data32: Int32Array\n data_length: number\n data_end: number\n current_command: number\n write_dest: number\n last_io_id: number\n in_progress_io_ids: Set<number>\n cancelled_io_ids: Set<number>\n current_atapi_command: number\n atapi_sense_key: number\n atapi_add_sense: number\n medium_changed: boolean\n\n constructor(\n channel: IDEChannel,\n interface_nr: number,\n buffer: IDEDiskBuffer | undefined,\n is_cd: boolean | undefined,\n ) {\n this.channel = channel\n this.name = channel.name + '.' + interface_nr\n\n this.bus = channel.bus\n this.channel_nr = channel.channel_nr\n this.interface_nr = interface_nr\n this.cpu = channel.cpu\n\n this.buffer = null\n\n this.drive_connected = !!is_cd || !!buffer\n this.sector_size = is_cd ? CDROM_SECTOR_SIZE : HD_SECTOR_SIZE\n this.is_atapi = !!is_cd\n this.sector_count = 0\n this.head_count = this.is_atapi ? 1 : 0\n this.sectors_per_track = 0\n this.cylinder_count = 0\n this.is_lba = 0\n this.sector_count_reg = 0\n this.lba_low_reg = 0\n this.features_reg = 0\n this.lba_mid_reg = 0\n this.lba_high_reg = 0\n this.head = 0\n this.device_reg = 0\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.sectors_per_drq = 0x80\n this.error_reg = 0\n this.data_pointer = 0\n\n this.data = new Uint8Array(64 * 1024)\n this.data16 = new Uint16Array(this.data.buffer)\n this.data32 = new Int32Array(this.data.buffer)\n\n this.data_length = 0\n this.data_end = 0\n this.current_command = -1\n this.write_dest = 0\n\n // cancellation support\n this.last_io_id = 0\n this.in_progress_io_ids = new Set()\n this.cancelled_io_ids = new Set()\n\n // ATAPI-only\n this.current_atapi_command = -1\n this.atapi_sense_key = 0\n this.atapi_add_sense = 0\n this.medium_changed = false\n\n this.set_disk_buffer(buffer)\n\n if (this.drive_connected) {\n dbg_log(\n `${this.name}: ${this.is_atapi ? 'ATAPI CD-ROM' : 'ATA HD'} device ready`,\n LOG_DISK,\n )\n }\n\n Object.seal(this)\n }\n\n has_disk(): boolean {\n return !!this.buffer\n }\n\n eject(): void {\n if (this.is_atapi && this.buffer) {\n this.medium_changed = true\n this.buffer = null\n this.status_reg =\n ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ | ATA_SR_COND\n this.error_reg = ATAPI_SK_UNIT_ATTENTION << 4\n this.push_irq()\n }\n }\n\n set_cdrom(buffer: IDEDiskBuffer): void {\n if (this.is_atapi && buffer) {\n this.set_disk_buffer(buffer)\n this.medium_changed = true\n }\n }\n\n set_disk_buffer(buffer: IDEDiskBuffer | undefined): void {\n if (!buffer) {\n return\n }\n\n this.buffer = buffer\n if (this.is_atapi) {\n this.status_reg =\n ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ | ATA_SR_COND\n this.error_reg = ATAPI_SK_UNIT_ATTENTION << 4\n }\n this.sector_count = this.buffer.byteLength / this.sector_size\n\n if (this.sector_count !== (this.sector_count | 0)) {\n dbg_log(\n this.name + ': warning: disk size not aligned with sector size',\n LOG_DISK,\n )\n this.sector_count = Math.ceil(this.sector_count)\n }\n\n if (this.is_atapi) {\n // default values: 1/2048\n this.head_count = 1\n this.sectors_per_track = 2048\n } else {\n // \"default\" values: 16/63\n // common: 255, 63\n this.head_count = 16\n this.sectors_per_track = 63\n }\n\n this.cylinder_count =\n this.sector_count / this.head_count / this.sectors_per_track\n\n if (this.cylinder_count !== (this.cylinder_count | 0)) {\n dbg_log(\n this.name +\n ': warning: rounding up cylinder count, choose different head number',\n LOG_DISK,\n )\n this.cylinder_count = Math.floor(this.cylinder_count)\n }\n\n if (this.interface_nr === 0) {\n // for CMOS see:\n // https://github.com/copy/v86/blob/master/src/rtc.js\n // https://github.com/coreboot/seabios/blob/master/src/hw/rtc.h\n // https://web.archive.org/web/20240119203005/http://www.bioscentral.com/misc/cmosmap.htm\n const rtc = this.cpu.devices.rtc\n\n // master\n rtc.cmos_write(\n CMOS_BIOS_DISKTRANSFLAG, // TODO: what is this doing, setting LBA translation?\n rtc.cmos_read(CMOS_BIOS_DISKTRANSFLAG) |\n (1 << (this.channel_nr * 4)),\n )\n\n // set hard disk type (CMOS_DISK_DATA = 0x12) of C: to 0b1111, keep type of D:\n // bits 0-3: hard disk type of D:\n // bits 4-7: hard disk type of C:\n // TODO: should this not also set CMOS_DISK_DRIVE1_TYPE to a hard disk type (see SeaBIOS rtc.h)?\n rtc.cmos_write(\n CMOS_DISK_DATA,\n (rtc.cmos_read(CMOS_DISK_DATA) & 0x0f) | 0xf0,\n )\n\n const drive_reg =\n this.channel_nr === 0\n ? CMOS_DISK_DRIVE1_CYL\n : CMOS_DISK_DRIVE2_CYL // 0x1B : 0x24 (drive C: or D:)\n rtc.cmos_write(drive_reg + 0, this.cylinder_count & 0xff) // number of cylinders least significant byte\n rtc.cmos_write(drive_reg + 1, (this.cylinder_count >> 8) & 0xff) // number of cylinders most significant byte\n rtc.cmos_write(drive_reg + 2, this.head_count & 0xff) // number of heads\n rtc.cmos_write(drive_reg + 3, 0xff) // write precomp cylinder least significant byte\n rtc.cmos_write(drive_reg + 4, 0xff) // write precomp cylinder most significant byte\n rtc.cmos_write(drive_reg + 5, 0xc8) // control byte\n rtc.cmos_write(drive_reg + 6, this.cylinder_count & 0xff) // landing zone least significant byte\n rtc.cmos_write(drive_reg + 7, (this.cylinder_count >> 8) & 0xff) // landing zone most significant byte\n rtc.cmos_write(drive_reg + 8, this.sectors_per_track & 0xff) // number of sectors\n }\n\n if (this.channel.cpu) {\n this.push_irq()\n }\n }\n\n device_reset(): void {\n if (this.is_atapi) {\n this.status_reg = 0\n this.sector_count_reg = 1\n this.error_reg = 1\n this.lba_low_reg = 1\n this.lba_mid_reg = ATAPI_SIGNATURE_LO // TODO: missing documentation\n this.lba_high_reg = ATAPI_SIGNATURE_HI\n } else {\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_ERR\n this.sector_count_reg = 1\n this.error_reg = 1\n this.lba_low_reg = 1\n this.lba_mid_reg = 0\n this.lba_high_reg = 0\n }\n this.cancel_io_operations()\n }\n\n push_irq(): void {\n this.channel.push_irq()\n }\n\n ata_abort_command(): void {\n this.error_reg = ATA_ER_ABRT\n this.status_reg = ATA_SR_DRDY | ATA_SR_ERR\n this.push_irq()\n }\n\n capture_regs(): string {\n return (\n `ST=${h(this.status_reg & 0xff)} ER=${h(this.error_reg & 0xff)} ` +\n `SC=${h(this.sector_count_reg & 0xff)} LL=${h(this.lba_low_reg & 0xff)} ` +\n `LM=${h(this.lba_mid_reg & 0xff)} LH=${h(this.lba_high_reg & 0xff)} ` +\n `FE=${h(this.features_reg & 0xff)}`\n )\n }\n\n ata_command(cmd: number): void {\n if (\n !this.drive_connected &&\n cmd !== ATA_CMD_EXECUTE_DEVICE_DIAGNOSTIC\n ) {\n dbg_log(\n `${this.name}: ATA command ${ATA_CMD_NAME[cmd]} (${h(cmd)}) ignored: no slave drive connected`,\n LOG_DISK,\n )\n return\n }\n\n const regs_pre = DEBUG ? this.capture_regs() : undefined\n let do_dbg_log = DEBUG\n\n this.current_command = cmd\n this.error_reg = 0\n\n switch (cmd) {\n case ATA_CMD_DEVICE_RESET:\n this.data_pointer = 0\n this.data_end = 0\n this.data_length = 0\n this.device_reset()\n this.push_irq()\n break\n\n case ATA_CMD_10h:\n this.lba_mid_reg = 0\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n\n case ATA_CMD_READ_NATIVE_MAX_ADDRESS: {\n const last_sector = this.sector_count - 1\n this.lba_low_reg = last_sector & 0xff\n this.lba_mid_reg = (last_sector >> 8) & 0xff\n this.lba_high_reg = (last_sector >> 16) & 0xff\n this.device_reg =\n (this.device_reg & 0xf0) | ((last_sector >> 24) & 0x0f)\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n }\n\n case ATA_CMD_READ_NATIVE_MAX_ADDRESS_EXT: {\n const last_sector = this.sector_count - 1\n this.lba_low_reg = last_sector & 0xff\n this.lba_mid_reg = (last_sector >> 8) & 0xff\n this.lba_high_reg = (last_sector >> 16) & 0xff\n this.lba_low_reg |= ((last_sector >> 24) << 8) & 0xff00\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n }\n\n case ATA_CMD_READ_SECTORS:\n do_dbg_log = false\n if (this.is_atapi) {\n this.lba_mid_reg = ATAPI_SIGNATURE_LO // see [ATA8-ACS] 4.3\n this.lba_high_reg = ATAPI_SIGNATURE_HI\n this.ata_abort_command()\n } else {\n this.ata_read_sectors(cmd)\n }\n break\n\n case ATA_CMD_READ_SECTORS_EXT:\n case ATA_CMD_READ_MULTIPLE:\n case ATA_CMD_READ_MULTIPLE_EXT:\n do_dbg_log = false\n if (this.is_atapi) {\n this.ata_abort_command()\n } else {\n this.ata_read_sectors(cmd)\n }\n break\n\n case ATA_CMD_WRITE_SECTORS:\n case ATA_CMD_WRITE_SECTORS_EXT:\n case ATA_CMD_WRITE_MULTIPLE:\n case ATA_CMD_WRITE_MULTIPLE_EXT:\n do_dbg_log = false\n if (this.is_atapi) {\n this.ata_abort_command()\n } else {\n this.ata_write_sectors(cmd)\n }\n break\n\n case ATA_CMD_EXECUTE_DEVICE_DIAGNOSTIC:\n // the behaviour of this command is independent of the selected device\n this.channel.master.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.channel.master.error_reg = 0x01 // Master drive passed, slave drive passed or not present\n this.channel.master.push_irq()\n if (this.channel.slave.drive_connected) {\n this.channel.slave.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.channel.slave.error_reg = 0x01 // Slave drive passed\n this.channel.slave.push_irq()\n }\n break\n\n case ATA_CMD_INITIALIZE_DEVICE_PARAMETERS:\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n\n case ATA_CMD_PACKET:\n if (this.is_atapi) {\n do_dbg_log = false\n this.data_allocate(12)\n this.data_end = 12\n this.sector_count_reg = 0x01 // 0x01: indicates transfer of a command packet (C/D)\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.push_irq()\n } else {\n this.ata_abort_command()\n }\n break\n\n case ATA_CMD_IDENTIFY_PACKET_DEVICE:\n if (this.is_atapi) {\n this.create_identify_packet()\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.push_irq()\n } else {\n this.ata_abort_command()\n }\n break\n\n case ATA_CMD_SET_MULTIPLE_MODE:\n // Logical sectors per DRQ Block in word 1\n dbg_log(\n this.name +\n ': logical sectors per DRQ Block: ' +\n h(this.sector_count_reg & 0xff),\n LOG_DISK,\n )\n this.sectors_per_drq = this.sector_count_reg & 0xff\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n\n case ATA_CMD_READ_DMA:\n case ATA_CMD_READ_DMA_EXT:\n do_dbg_log = false\n this.ata_read_sectors_dma(cmd)\n break\n\n case ATA_CMD_WRITE_DMA:\n case ATA_CMD_WRITE_DMA_EXT:\n do_dbg_log = false\n this.ata_write_sectors_dma(cmd)\n break\n\n case ATA_CMD_READ_VERIFY_SECTORS:\n // TODO: check that lba_low/mid/high and sector_count regs are within the bounds of the disk's size\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n\n case ATA_CMD_GET_MEDIA_STATUS:\n if (this.is_atapi) {\n if (!this.buffer) {\n this.error_reg |= 0x02 // NM: No Media\n }\n if (this.medium_changed) {\n this.error_reg |= 0x20 // MC: Media Change\n this.medium_changed = false\n }\n this.error_reg |= 0x40 // WP: Write Protect\n }\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n\n case ATA_CMD_STANDBY_IMMEDIATE:\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n\n case ATA_CMD_IDLE_IMMEDIATE:\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n\n case ATA_CMD_FLUSH_CACHE:\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n\n case ATA_CMD_FLUSH_CACHE_EXT:\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n\n case ATA_CMD_IDENTIFY_DEVICE:\n if (this.is_atapi) {\n this.lba_mid_reg = ATAPI_SIGNATURE_LO // see [ATA8-ACS] 4.3\n this.lba_high_reg = ATAPI_SIGNATURE_HI\n this.ata_abort_command()\n } else {\n this.create_identify_packet()\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.push_irq()\n }\n break\n\n case ATA_CMD_SET_FEATURES:\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n\n case ATA_CMD_MEDIA_LOCK:\n this.status_reg = ATA_SR_DRDY\n this.push_irq()\n break\n\n case ATA_CMD_SECURITY_FREEZE_LOCK:\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n break\n\n case ATA_CMD_SET_MAX:\n this.ata_abort_command()\n break\n\n case ATA_CMD_NOP:\n this.ata_abort_command()\n break\n\n case ATA_CMD_F0h:\n dbg_log(\n `${this.name}: error: unimplemented vendor-specific ATA command ${h(cmd)}: ABORT [${this.capture_regs()}]`,\n LOG_DISK,\n )\n this.ata_abort_command()\n break\n\n default:\n dbg_assert(\n false,\n `${this.name}: error: unimplemented ATA command ${h(cmd)}: ABORT [${this.capture_regs()}]`,\n LOG_DISK,\n )\n this.ata_abort_command()\n break\n }\n\n if (DEBUG && do_dbg_log) {\n const regs_msg = `[${regs_pre}] -> [${this.capture_regs()}]`\n const result =\n this.status_reg & ATA_SR_ERR\n ? this.error_reg & ATA_ER_ABRT\n ? 'ABORT'\n : 'ERROR'\n : 'OK'\n dbg_log(\n `${this.name}: ATA command ${ATA_CMD_NAME[cmd]} (${h(cmd)}): ${result} ${regs_msg}`,\n LOG_DISK,\n )\n }\n }\n\n atapi_handle(): void {\n const cmd = this.data[0]\n const cmd_name = ATAPI_CMD[cmd] ? ATAPI_CMD[cmd].name : '<undefined>'\n const cmd_flags = ATAPI_CMD[cmd] ? ATAPI_CMD[cmd].flags : ATAPI_CF_NONE\n const regs_pre = DEBUG ? this.capture_regs() : undefined\n\n let do_dbg_log = DEBUG\n let dbg_log_extra: string | undefined\n\n this.data_pointer = 0\n this.current_atapi_command = cmd\n\n if (cmd !== ATAPI_CMD_REQUEST_SENSE) // TODO\n {\n this.atapi_sense_key = 0\n this.atapi_add_sense = 0\n }\n\n if (!this.buffer && cmd_flags & ATAPI_CF_NEEDS_DISK) {\n this.atapi_check_condition_response(\n ATAPI_SK_NOT_READY,\n ATAPI_ASC_MEDIUM_NOT_PRESENT,\n )\n this.push_irq()\n if (DEBUG) {\n dbg_log(\n `${this.name}: ATAPI command ${cmd_name} (${h(cmd)}) without medium: ERROR [${regs_pre}]`,\n LOG_DISK,\n )\n }\n return\n }\n\n switch (cmd) {\n case ATAPI_CMD_TEST_UNIT_READY:\n if (this.buffer) {\n this.data_allocate(0)\n this.data_end = this.data_length\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n } else {\n this.atapi_check_condition_response(\n ATAPI_SK_NOT_READY,\n ATAPI_ASC_MEDIUM_NOT_PRESENT,\n )\n }\n break\n\n case ATAPI_CMD_REQUEST_SENSE:\n this.data_allocate(this.data[4])\n this.data_end = this.data_length\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.data[0] = 0x80 | 0x70 // valid | SCSI error code\n this.data[2] = this.atapi_sense_key // SCSI sense key\n this.data[7] = 8 // SCSI additional sense length (fixed 8 for this error code 0x70)\n this.data[12] = this.atapi_add_sense // SCSI additional sense code\n this.atapi_sense_key = 0\n this.atapi_add_sense = 0\n break\n\n case ATAPI_CMD_INQUIRY: {\n const length = this.data[4]\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n dbg_log_extra =\n 'lun=' + h(this.data[1], 2) + ' length=' + length\n // for data layout see [CD-SCSI-2] \"INQUIRY Command\"\n this.data.set([\n // 0: Device-type, Removable, ANSI-Version, Response Format\n 0x05, 0x80, 0x01, 0x31,\n // 4: Additional length, Reserved, Reserved, Reserved\n 31, 0, 0, 0,\n // 8: Vendor Identification \"SONY \"\n 0x53, 0x4f, 0x4e, 0x59, 0x20, 0x20, 0x20, 0x20,\n // 16: Product Identification \"CD-ROM CDU-1000 \"\n 0x43, 0x44, 0x2d, 0x52, 0x4f, 0x4d, 0x20, 0x43, 0x44, 0x55,\n 0x2d, 0x31, 0x30, 0x30, 0x30, 0x20,\n // 32: Product Revision Level \"1.1a\"\n 0x31, 0x2e, 0x31, 0x61,\n ])\n this.data_end = this.data_length = Math.min(36, length)\n break\n }\n\n case ATAPI_CMD_MODE_SENSE_6:\n this.data_allocate(this.data[4])\n this.data_end = this.data_length\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n break\n\n case ATAPI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:\n this.data_allocate(0)\n this.data_end = this.data_length\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n break\n\n case ATAPI_CMD_READ_CAPACITY: {\n const count = this.sector_count - 1\n this.data_set(\n new Uint8Array([\n (count >> 24) & 0xff,\n (count >> 16) & 0xff,\n (count >> 8) & 0xff,\n count & 0xff,\n 0,\n 0,\n (this.sector_size >> 8) & 0xff,\n this.sector_size & 0xff,\n ]),\n )\n this.data_end = this.data_length\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n break\n }\n\n case ATAPI_CMD_READ_10:\n case ATAPI_CMD_READ_12:\n do_dbg_log = false\n if (this.features_reg & 1) {\n this.atapi_read_dma(this.data)\n } else {\n this.atapi_read(this.data)\n }\n break\n\n case ATAPI_CMD_READ_SUBCHANNEL: {\n const length = this.data[8]\n dbg_log_extra = 'length=' + length\n this.data_allocate(Math.min(8, length))\n this.data_end = this.data_length\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n break\n }\n\n case ATAPI_CMD_READ_TOC_PMA_ATIP: {\n const length = this.data[8] | (this.data[7] << 8)\n const format = this.data[9] >> 6\n dbg_log_extra = `${h(format, 2)} length=${length} ${!!(this.data[1] & 2)} ${h(this.data[6])}`\n\n this.data_allocate(length)\n this.data_end = this.data_length\n if (format === 0) {\n const sector_count = this.sector_count\n this.data.set(\n new Uint8Array([\n 0,\n 18, // length\n 1,\n 1, // first and last session\n\n 0,\n 0x14,\n 1, // track number\n 0,\n 0,\n 0,\n 0,\n 0,\n\n 0,\n 0x16,\n 0xaa, // track number\n 0,\n sector_count >> 24,\n (sector_count >> 16) & 0xff,\n (sector_count >> 8) & 0xff,\n sector_count & 0xff,\n ]),\n )\n } else if (format === 1) {\n this.data.set(\n new Uint8Array([\n 0,\n 10, // length\n 1,\n 1, // first and last session\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n ]),\n )\n } else {\n dbg_assert(\n false,\n this.name + ': error: unimplemented format: ' + format,\n )\n }\n\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n break\n }\n\n case ATAPI_CMD_GET_CONFIGURATION: {\n const length = Math.min(this.data[8] | (this.data[7] << 8), 32)\n dbg_log_extra = 'length=' + length\n this.data_allocate(length)\n this.data_end = this.data_length\n this.data[0] = ((length - 4) >> 24) & 0xff\n this.data[1] = ((length - 4) >> 16) & 0xff\n this.data[2] = ((length - 4) >> 8) & 0xff\n this.data[3] = (length - 4) & 0xff\n this.data[6] = 0x08\n this.data[10] = 3\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n break\n }\n\n case ATAPI_CMD_READ_DISK_INFORMATION:\n this.data_allocate(0)\n this.data_end = this.data_length\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n break\n\n case ATAPI_CMD_READ_TRACK_INFORMATION:\n dbg_log_extra = 'unimplemented'\n this.atapi_check_condition_response(\n ATAPI_SK_ILLEGAL_REQUEST,\n ATAPI_ASC_INV_FIELD_IN_CMD_PACKET,\n )\n break\n\n case ATAPI_CMD_MODE_SENSE_10: {\n const length = this.data[8] | (this.data[7] << 8)\n const page_code = this.data[2]\n dbg_log_extra =\n 'page_code=' + h(page_code) + ' length=' + length\n if (page_code === 0x2a) {\n this.data_allocate(Math.min(30, length))\n }\n this.data_end = this.data_length\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n break\n }\n\n case ATAPI_CMD_MECHANISM_STATUS:\n this.data_allocate(this.data[9] | (this.data[8] << 8))\n this.data_end = this.data_length\n this.data[5] = 1\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n break\n\n case ATAPI_CMD_START_STOP_UNIT: {\n const loej_start = this.data[4] & 0x3\n dbg_log_extra = `Immed=${h(this.data[1] & 1)} LoEj/Start=${h(loej_start)}`\n if (this.buffer && loej_start === 0x2) {\n dbg_log_extra += ': disk ejected'\n this.medium_changed = true\n this.buffer = null\n }\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.data_allocate(0)\n this.data_end = this.data_length\n break\n }\n\n case ATAPI_CMD_PAUSE:\n case ATAPI_CMD_GET_EVENT_STATUS_NOTIFICATION:\n dbg_log_extra = 'unimplemented'\n this.atapi_check_condition_response(\n ATAPI_SK_ILLEGAL_REQUEST,\n ATAPI_ASC_INV_FIELD_IN_CMD_PACKET,\n )\n break\n\n case ATAPI_CMD_READ_CD:\n dbg_log_extra = 'unimplemented'\n this.data_allocate(0)\n this.data_end = this.data_length\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n break\n\n default:\n dbg_assert(\n false,\n `${this.name}: error: unimplemented ATAPI command ${h(this.data[0])}`,\n LOG_DISK,\n )\n this.atapi_check_condition_response(\n ATAPI_SK_ILLEGAL_REQUEST,\n ATAPI_ASC_INV_FIELD_IN_CMD_PACKET,\n )\n break\n }\n\n this.sector_count_reg = (this.sector_count_reg & ~7) | 2\n\n if ((this.status_reg & ATA_SR_BSY) === 0) {\n this.push_irq()\n }\n\n if ((this.status_reg & ATA_SR_BSY) === 0 && this.data_length === 0) {\n this.sector_count_reg |= 1\n this.status_reg &= ~ATA_SR_DRQ\n }\n\n if (DEBUG && do_dbg_log) {\n const regs_msg = `[${regs_pre}] -> [${this.capture_regs()}]`\n const result =\n this.status_reg & ATA_SR_ERR\n ? this.error_reg & ATA_ER_ABRT\n ? 'ABORT'\n : 'ERROR'\n : 'OK'\n dbg_log_extra = dbg_log_extra ? ` ${dbg_log_extra}:` : ''\n dbg_log(\n `${this.name}: ATAPI command ${cmd_name} (${h(cmd)}):${dbg_log_extra} ${result} ${regs_msg}`,\n LOG_DISK,\n )\n }\n }\n\n atapi_check_condition_response(\n sense_key: number,\n additional_sense: number,\n ): void {\n // Setup ATA registers to CHECK CONDITION state.\n // The sense state (sense_key and additional_sense) must be requested\n // by the host using ATAPI_CMD_REQUEST_SENSE immediately following a\n // CHECK CONDITION response or else it will be lost.\n // https://github.com/qemu/qemu/blob/757a34115e7491744a63dfc3d291fd1de5297ee2/hw/ide/atapi.c#L186\n this.data_allocate(0)\n this.data_end = this.data_length\n this.status_reg = ATA_SR_DRDY | ATA_SR_COND\n this.error_reg = sense_key << 4\n this.sector_count_reg = (this.sector_count_reg & ~7) | 2 | 1\n this.atapi_sense_key = sense_key\n this.atapi_add_sense = additional_sense\n }\n\n do_write(): void {\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n\n dbg_assert(this.data_length <= this.data.length)\n const data = this.data.subarray(0, this.data_length)\n\n //dbg_log(hex_dump(data), LOG_DISK);\n dbg_assert(this.data_length % 512 === 0)\n this.ata_advance(this.current_command, this.data_length / 512)\n this.push_irq()\n\n this.buffer!.set(this.write_dest, data, function () {})\n\n this.report_write(this.data_length)\n }\n\n atapi_read(cmd: Uint8Array): void {\n // Note: Big Endian\n const lba = (cmd[2] << 24) | (cmd[3] << 16) | (cmd[4] << 8) | cmd[5]\n let count =\n cmd[0] === ATAPI_CMD_READ_12\n ? (cmd[6] << 24) | (cmd[7] << 16) | (cmd[8] << 8) | cmd[9]\n : (cmd[7] << 8) | cmd[8]\n count >>>= 0\n const flags = cmd[1]\n let byte_count = count * this.sector_size\n const start = lba * this.sector_size\n\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n dbg_log(\n this.name +\n ': CD read lba=' +\n h(lba) +\n ' lbacount=' +\n h(count) +\n ' bytecount=' +\n h(byte_count) +\n ' flags=' +\n h(flags),\n LOG_DISK,\n )\n }\n\n this.data_length = 0\n let req_length =\n ((this.lba_high_reg << 8) & 0xff00) | (this.lba_mid_reg & 0xff)\n //dbg_log(this.name + \": \" + h(this.lba_high_reg, 2) + \" \" + h(this.lba_mid_reg, 2), LOG_DISK);\n this.lba_mid_reg = this.lba_high_reg = 0 // oak technology driver (windows 3.0)\n\n if (req_length === 0xffff) req_length--\n\n if (req_length > byte_count) {\n req_length = byte_count\n }\n\n if (!this.buffer) {\n dbg_assert(false, this.name + ': CD read: no buffer', LOG_DISK)\n this.status_reg = 0xff\n this.error_reg = 0x41\n this.push_irq()\n } else if (start >= this.buffer.byteLength) {\n dbg_assert(\n false,\n this.name +\n ': CD read: Outside of disk end=' +\n h(start + byte_count) +\n ' size=' +\n h(this.buffer.byteLength),\n LOG_DISK,\n )\n\n this.status_reg = 0xff\n this.push_irq()\n } else if (byte_count === 0) {\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n\n this.data_pointer = 0\n //this.push_irq();\n } else {\n byte_count = Math.min(byte_count, this.buffer.byteLength - start)\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_BSY\n this.report_read_start()\n\n this.read_buffer(start, byte_count, (data) => {\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n dbg_log(this.name + ': CD read: data arrived', LOG_DISK)\n }\n this.data_set(data)\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.sector_count_reg = (this.sector_count_reg & ~7) | 2\n\n this.push_irq()\n\n req_length &= ~3\n\n this.data_end = req_length\n if (this.data_end > this.data_length) {\n this.data_end = this.data_length\n }\n this.lba_mid_reg = this.data_end & 0xff\n this.lba_high_reg = (this.data_end >> 8) & 0xff\n\n this.report_read_end(byte_count)\n })\n }\n }\n\n atapi_read_dma(cmd: Uint8Array): void {\n // Note: Big Endian\n const lba = (cmd[2] << 24) | (cmd[3] << 16) | (cmd[4] << 8) | cmd[5]\n let count =\n cmd[0] === ATAPI_CMD_READ_12\n ? (cmd[6] << 24) | (cmd[7] << 16) | (cmd[8] << 8) | cmd[9]\n : (cmd[7] << 8) | cmd[8]\n count >>>= 0\n const flags = cmd[1]\n const byte_count = count * this.sector_size\n const start = lba * this.sector_size\n\n dbg_log(\n this.name +\n ': CD read DMA lba=' +\n h(lba) +\n ' lbacount=' +\n h(count) +\n ' bytecount=' +\n h(byte_count) +\n ' flags=' +\n h(flags),\n LOG_DISK,\n )\n\n if (start >= this.buffer!.byteLength) {\n dbg_assert(\n false,\n this.name +\n ': CD read: Outside of disk end=' +\n h(start + byte_count) +\n ' size=' +\n h(this.buffer!.byteLength),\n LOG_DISK,\n )\n\n this.status_reg = 0xff\n this.push_irq()\n } else {\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_BSY\n this.report_read_start()\n\n this.read_buffer(start, byte_count, (data) => {\n dbg_log(this.name + ': atapi_read_dma: Data arrived', LOG_DISK)\n this.report_read_end(byte_count)\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.sector_count_reg = (this.sector_count_reg & ~7) | 2\n this.data_set(data)\n\n this.do_atapi_dma()\n })\n }\n }\n\n do_atapi_dma(): void {\n if ((this.channel.dma_status & 1) === 0) {\n dbg_log(this.name + ': do_atapi_dma: Status not set', LOG_DISK)\n return\n }\n\n if ((this.status_reg & ATA_SR_DRQ) === 0) {\n dbg_log(this.name + ': do_atapi_dma: DRQ not set', LOG_DISK)\n return\n }\n\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.name + ': ATAPI DMA transfer len=' + this.data_length,\n LOG_DISK,\n )\n }\n\n let prdt_start = this.channel.prdt_addr\n let offset = 0\n\n const data = this.data\n\n let end: number\n do {\n const addr = this.cpu.read32s(prdt_start)\n let count = this.cpu.read16(prdt_start + 4)\n end = this.cpu.read8(prdt_start + 7) & 0x80\n\n if (!count) {\n count = 0x10000\n }\n\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.name +\n ': DMA read dest=' +\n h(addr) +\n ' count=' +\n h(count) +\n ' datalen=' +\n h(this.data_length),\n LOG_DISK,\n )\n }\n this.cpu.write_blob(\n data.subarray(\n offset,\n Math.min(offset + count, this.data_length),\n ),\n addr,\n )\n\n offset += count\n prdt_start += 8\n\n if (offset >= this.data_length && !end) {\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.name +\n ': leave early end=' +\n +end +\n ' offset=' +\n h(offset) +\n ' data_length=' +\n h(this.data_length) +\n ' cmd=' +\n h(this.current_command),\n LOG_DISK,\n )\n }\n break\n }\n } while (!end)\n\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(this.name + ': end offset=' + offset, LOG_DISK)\n }\n\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.channel.dma_status &= ~1\n this.sector_count_reg = (this.sector_count_reg & ~7) | 3\n this.push_irq()\n }\n\n read_data(length: number): number {\n if (this.data_pointer < this.data_end) {\n dbg_assert(this.data_pointer + length - 1 < this.data_end)\n dbg_assert(\n this.data_pointer % length === 0,\n h(this.data_pointer) + ' ' + length,\n )\n\n let result: number\n if (length === 1) {\n result = this.data[this.data_pointer]\n } else if (length === 2) {\n result = this.data16[this.data_pointer >>> 1]\n } else {\n result = this.data32[this.data_pointer >>> 2]\n }\n\n this.data_pointer += length\n\n const align = (this.data_end & 0xfff) === 0 ? 0xfff : 0xff\n\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n if ((this.data_pointer & align) === 0) {\n dbg_log(\n this.name +\n ': read 1F0: ' +\n h(this.data[this.data_pointer], 2) +\n ' cur=' +\n h(this.data_pointer) +\n ' cnt=' +\n h(this.data_length),\n LOG_DISK,\n )\n }\n }\n\n if (this.data_pointer >= this.data_end) {\n this.read_end()\n }\n\n return result\n } else {\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n dbg_log(this.name + ': read 1F0: empty', LOG_DISK)\n }\n this.data_pointer += length\n return 0\n }\n }\n\n read_end(): void {\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n dbg_log(\n this.name +\n ': read_end cmd=' +\n h(this.current_command) +\n ' data_pointer=' +\n h(this.data_pointer) +\n ' end=' +\n h(this.data_end) +\n ' length=' +\n h(this.data_length),\n LOG_DISK,\n )\n }\n\n if (this.current_command === ATA_CMD_PACKET) {\n if (this.data_end === this.data_length) {\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.sector_count_reg = (this.sector_count_reg & ~7) | 3\n this.push_irq()\n } else {\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.sector_count_reg = (this.sector_count_reg & ~7) | 2\n this.push_irq()\n const byte_count =\n ((this.lba_high_reg << 8) & 0xff00) |\n (this.lba_mid_reg & 0xff)\n\n if (this.data_end + byte_count > this.data_length) {\n this.lba_mid_reg = (this.data_length - this.data_end) & 0xff\n this.lba_high_reg =\n ((this.data_length - this.data_end) >> 8) & 0xff\n this.data_end = this.data_length\n } else {\n this.data_end += byte_count\n }\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n dbg_log(\n this.name + ': data_end=' + h(this.data_end),\n LOG_DISK,\n )\n }\n }\n } else {\n this.error_reg = 0\n if (this.data_pointer >= this.data_length) {\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n } else {\n let sector_count: number\n if (\n this.current_command === ATA_CMD_READ_MULTIPLE ||\n this.current_command === ATA_CMD_READ_MULTIPLE_EXT\n ) {\n sector_count = Math.min(\n this.sectors_per_drq,\n (this.data_length - this.data_end) / 512,\n )\n dbg_assert(sector_count % 1 === 0)\n } else {\n dbg_assert(\n this.current_command === ATA_CMD_READ_SECTORS ||\n this.current_command === ATA_CMD_READ_SECTORS_EXT,\n )\n sector_count = 1\n }\n this.ata_advance(this.current_command, sector_count)\n this.data_end += 512 * sector_count\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.push_irq()\n }\n }\n }\n\n write_data_port(data: number, length: number): void {\n dbg_assert(this.data_pointer % length === 0)\n\n if (this.data_pointer >= this.data_end) {\n dbg_log(\n this.name +\n ': redundant write to data port: ' +\n h(data) +\n ' count=' +\n h(this.data_end) +\n ' cur=' +\n h(this.data_pointer),\n LOG_DISK,\n )\n } else {\n const align = (this.data_end & 0xfff) === 0 ? 0xfff : 0xff\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n if (\n ((this.data_pointer + length) & align) === 0 ||\n this.data_end < 20\n ) {\n dbg_log(\n this.name +\n ': data port: ' +\n h(data >>> 0) +\n ' count=' +\n h(this.data_end) +\n ' cur=' +\n h(this.data_pointer),\n LOG_DISK,\n )\n }\n }\n\n if (length === 1) {\n this.data[this.data_pointer++] = data\n } else if (length === 2) {\n this.data16[this.data_pointer >>> 1] = data\n this.data_pointer += 2\n } else {\n this.data32[this.data_pointer >>> 2] = data\n this.data_pointer += 4\n }\n\n dbg_assert(this.data_pointer <= this.data_end)\n if (this.data_pointer === this.data_end) {\n this.write_end()\n }\n }\n }\n\n write_data_port8(data: number): void {\n this.write_data_port(data, 1)\n }\n\n write_data_port16(data: number): void {\n this.write_data_port(data, 2)\n }\n\n write_data_port32(data: number): void {\n this.write_data_port(data, 4)\n }\n\n write_end(): void {\n if (this.current_command === ATA_CMD_PACKET) {\n this.atapi_handle()\n } else {\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n dbg_log(\n this.name +\n ': write_end data_pointer=' +\n h(this.data_pointer) +\n ' data_length=' +\n h(this.data_length),\n LOG_DISK,\n )\n }\n\n if (this.data_pointer >= this.data_length) {\n this.do_write()\n } else {\n dbg_assert(\n this.current_command === ATA_CMD_WRITE_SECTORS ||\n this.current_command === ATA_CMD_WRITE_SECTORS_EXT ||\n this.current_command === ATA_CMD_WRITE_MULTIPLE_EXT,\n 'Unexpected command: ' + h(this.current_command),\n )\n\n // XXX: Should advance here, but do_write does all the advancing\n //this.ata_advance(this.current_command, 1);\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.data_end += 512\n this.push_irq()\n }\n }\n }\n\n ata_advance(cmd: number, sectors: number): void {\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n dbg_log(\n this.name +\n ': advance sectors=' +\n sectors +\n ' old_sector_count_reg=' +\n this.sector_count_reg,\n LOG_DISK,\n )\n }\n this.sector_count_reg -= sectors\n\n let new_sector: number\n if (\n cmd === ATA_CMD_READ_SECTORS_EXT ||\n cmd === ATA_CMD_READ_MULTIPLE ||\n cmd === ATA_CMD_READ_DMA_EXT ||\n cmd === ATA_CMD_WRITE_SECTORS_EXT ||\n cmd === ATA_CMD_WRITE_MULTIPLE ||\n cmd === ATA_CMD_WRITE_DMA_EXT\n ) {\n new_sector = sectors + this.get_lba48()\n this.lba_low_reg =\n (new_sector & 0xff) | ((new_sector >> 16) & 0xff00)\n this.lba_mid_reg = (new_sector >> 8) & 0xff\n this.lba_high_reg = (new_sector >> 16) & 0xff\n } else if (this.is_lba) {\n new_sector = sectors + this.get_lba28()\n this.lba_low_reg = new_sector & 0xff\n this.lba_mid_reg = (new_sector >> 8) & 0xff\n this.lba_high_reg = (new_sector >> 16) & 0xff\n this.head = (this.head & ~0xf) | (new_sector & 0xf)\n } else // chs\n {\n new_sector = sectors + this.get_chs()\n\n const c =\n (new_sector / (this.head_count * this.sectors_per_track)) | 0\n this.lba_mid_reg = c & 0xff\n this.lba_high_reg = (c >> 8) & 0xff\n this.head =\n (((new_sector / this.sectors_per_track) | 0) %\n this.head_count) &\n 0xf\n this.lba_low_reg =\n ((new_sector % this.sectors_per_track) + 1) & 0xff\n\n dbg_assert(new_sector === this.get_chs())\n }\n }\n\n ata_read_sectors(cmd: number): void {\n const is_lba48 =\n cmd === ATA_CMD_READ_SECTORS_EXT || cmd === ATA_CMD_READ_MULTIPLE\n const count = this.get_count(is_lba48)\n const lba = this.get_lba(is_lba48)\n\n const is_single =\n cmd === ATA_CMD_READ_SECTORS || cmd === ATA_CMD_READ_SECTORS_EXT\n\n const byte_count = count * this.sector_size\n const start = lba * this.sector_size\n\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n dbg_log(\n this.name +\n ': ATA read cmd=' +\n h(cmd) +\n ' mode=' +\n (this.is_lba ? 'lba' : 'chs') +\n ' lba=' +\n h(lba) +\n ' lbacount=' +\n h(count) +\n ' bytecount=' +\n h(byte_count),\n LOG_DISK,\n )\n }\n\n if (start + byte_count > this.buffer!.byteLength) {\n dbg_assert(\n false,\n this.name + ': ATA read: Outside of disk',\n LOG_DISK,\n )\n\n this.status_reg = 0xff\n this.push_irq()\n } else {\n this.status_reg = ATA_SR_DRDY | ATA_SR_BSY\n this.report_read_start()\n\n this.read_buffer(start, byte_count, (data) => {\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n dbg_log(this.name + ': ata_read: Data arrived', LOG_DISK)\n }\n\n this.data_set(data)\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.data_end = is_single\n ? 512\n : Math.min(byte_count, this.sectors_per_drq * 512)\n this.ata_advance(\n cmd,\n is_single ? 1 : Math.min(count, this.sectors_per_track),\n )\n\n this.push_irq()\n this.report_read_end(byte_count)\n })\n }\n }\n\n ata_read_sectors_dma(cmd: number): void {\n const is_lba48 = cmd === ATA_CMD_READ_DMA_EXT\n const count = this.get_count(is_lba48)\n const lba = this.get_lba(is_lba48)\n\n const byte_count = count * this.sector_size\n const start = lba * this.sector_size\n\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.name +\n ': ATA DMA read lba=' +\n h(lba) +\n ' lbacount=' +\n h(count) +\n ' bytecount=' +\n h(byte_count),\n LOG_DISK,\n )\n }\n\n if (start + byte_count > this.buffer!.byteLength) {\n dbg_assert(\n false,\n this.name + ': ATA read: Outside of disk',\n LOG_DISK,\n )\n\n this.status_reg = 0xff\n this.push_irq()\n return\n }\n\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.channel.dma_status |= 1\n }\n\n do_ata_read_sectors_dma(): void {\n const cmd = this.current_command\n\n const is_lba48 = cmd === ATA_CMD_READ_DMA_EXT\n const count = this.get_count(is_lba48)\n const lba = this.get_lba(is_lba48)\n\n const byte_count = count * this.sector_size\n const start = lba * this.sector_size\n\n dbg_assert(lba < this.buffer!.byteLength)\n\n this.report_read_start()\n\n const orig_prdt_start = this.channel.prdt_addr\n\n this.read_buffer(start, byte_count, (data) => {\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.name + ': do_ata_read_sectors_dma: Data arrived',\n LOG_DISK,\n )\n }\n let prdt_start = this.channel.prdt_addr\n let offset = 0\n\n dbg_assert(orig_prdt_start === prdt_start)\n\n let end: number\n do {\n const prd_addr = this.cpu.read32s(prdt_start)\n let prd_count = this.cpu.read16(prdt_start + 4)\n end = this.cpu.read8(prdt_start + 7) & 0x80\n\n if (!prd_count) {\n prd_count = 0x10000\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(this.name + ': DMA: prd count was 0', LOG_DISK)\n }\n }\n\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.name +\n ': DMA read transfer dest=' +\n h(prd_addr) +\n ' prd_count=' +\n h(prd_count),\n LOG_DISK,\n )\n }\n this.cpu.write_blob(\n data.subarray(offset, offset + prd_count),\n prd_addr,\n )\n\n offset += prd_count\n prdt_start += 8\n } while (!end)\n\n dbg_assert(offset === byte_count)\n\n this.ata_advance(this.current_command, count)\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.channel.dma_status &= ~1\n this.current_command = -1\n\n this.report_read_end(byte_count)\n\n this.push_irq()\n })\n }\n\n ata_write_sectors(cmd: number): void {\n const is_lba48 =\n cmd === ATA_CMD_WRITE_SECTORS_EXT || cmd === ATA_CMD_WRITE_MULTIPLE\n const count = this.get_count(is_lba48)\n const lba = this.get_lba(is_lba48)\n\n const is_single =\n cmd === ATA_CMD_WRITE_SECTORS || cmd === ATA_CMD_WRITE_SECTORS_EXT\n\n const byte_count = count * this.sector_size\n const start = lba * this.sector_size\n\n if (LOG_DETAILS & LOG_DETAIL_RW) {\n dbg_log(\n this.name +\n ': ATA write lba=' +\n h(lba) +\n ' mode=' +\n (this.is_lba ? 'lba' : 'chs') +\n ' lbacount=' +\n h(count) +\n ' bytecount=' +\n h(byte_count),\n LOG_DISK,\n )\n }\n\n if (start + byte_count > this.buffer!.byteLength) {\n dbg_assert(\n false,\n this.name + ': ATA write: Outside of disk',\n LOG_DISK,\n )\n\n this.status_reg = 0xff\n this.push_irq()\n } else {\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.data_allocate_noclear(byte_count)\n this.data_end = is_single\n ? 512\n : Math.min(byte_count, this.sectors_per_drq * 512)\n this.write_dest = start\n }\n }\n\n ata_write_sectors_dma(cmd: number): void {\n const is_lba48 = cmd === ATA_CMD_WRITE_DMA_EXT\n const count = this.get_count(is_lba48)\n const lba = this.get_lba(is_lba48)\n\n const byte_count = count * this.sector_size\n const start = lba * this.sector_size\n\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.name +\n ': ATA DMA write lba=' +\n h(lba) +\n ' lbacount=' +\n h(count) +\n ' bytecount=' +\n h(byte_count),\n LOG_DISK,\n )\n }\n\n if (start + byte_count > this.buffer!.byteLength) {\n dbg_assert(\n false,\n this.name + ': ATA DMA write: Outside of disk',\n LOG_DISK,\n )\n\n this.status_reg = 0xff\n this.push_irq()\n return\n }\n\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC | ATA_SR_DRQ\n this.channel.dma_status |= 1\n }\n\n do_ata_write_sectors_dma(): void {\n const cmd = this.current_command\n\n const is_lba48 = cmd === ATA_CMD_WRITE_DMA_EXT\n const count = this.get_count(is_lba48)\n const lba = this.get_lba(is_lba48)\n\n const byte_count = count * this.sector_size\n const start = lba * this.sector_size\n\n let prdt_start = this.channel.prdt_addr\n let offset = 0\n\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(this.name + ': prdt addr: ' + h(prdt_start, 8), LOG_DISK)\n }\n\n const buffer = new Uint8Array(byte_count)\n\n let end: number\n do {\n const prd_addr = this.cpu.read32s(prdt_start)\n let prd_count = this.cpu.read16(prdt_start + 4)\n end = this.cpu.read8(prdt_start + 7) & 0x80\n\n if (!prd_count) {\n prd_count = 0x10000\n dbg_log(this.name + ': DMA: prd count was 0', LOG_DISK)\n }\n\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(\n this.name +\n ': DMA write transfer dest=' +\n h(prd_addr) +\n ' prd_count=' +\n h(prd_count),\n LOG_DISK,\n )\n }\n\n const slice = this.cpu.mem8.subarray(prd_addr, prd_addr + prd_count)\n dbg_assert(slice.length === prd_count)\n\n buffer.set(slice, offset)\n\n //if(DEBUG)\n //{\n // dbg_log(hex_dump(slice), LOG_DISK);\n //}\n\n offset += prd_count\n prdt_start += 8\n } while (!end)\n\n dbg_assert(offset === buffer.length)\n\n this.buffer!.set(start, buffer, () => {\n if (LOG_DETAILS & LOG_DETAIL_RW_DMA) {\n dbg_log(this.name + ': DMA write completed', LOG_DISK)\n }\n this.ata_advance(this.current_command, count)\n this.status_reg = ATA_SR_DRDY | ATA_SR_DSC\n this.push_irq()\n this.channel.dma_status &= ~1\n this.current_command = -1\n })\n\n this.report_write(byte_count)\n }\n\n get_chs(): number {\n const c =\n (this.lba_mid_reg & 0xff) | ((this.lba_high_reg << 8) & 0xff00)\n const h = this.head\n const s = this.lba_low_reg & 0xff\n\n if (LOG_DETAILS & LOG_DETAIL_CHS) {\n dbg_log(\n this.name + ': get_chs: c=' + c + ' h=' + h + ' s=' + s,\n LOG_DISK,\n )\n }\n\n return (c * this.head_count + h) * this.sectors_per_track + s - 1\n }\n\n get_lba28(): number {\n return (\n (this.lba_low_reg & 0xff) |\n ((this.lba_mid_reg << 8) & 0xff00) |\n ((this.lba_high_reg << 16) & 0xff0000) |\n ((this.head & 0xf) << 24)\n )\n }\n\n get_lba48(): number {\n // Note: Bits over 32 missing\n return (\n ((this.lba_low_reg & 0xff) |\n ((this.lba_mid_reg << 8) & 0xff00) |\n ((this.lba_high_reg << 16) & 0xff0000) |\n (((this.lba_low_reg >> 8) << 24) & 0xff000000)) >>>\n 0\n )\n }\n\n get_lba(is_lba48: boolean): number {\n if (is_lba48) {\n return this.get_lba48()\n } else if (this.is_lba) {\n return this.get_lba28()\n } else {\n return this.get_chs()\n }\n }\n\n get_count(is_lba48: boolean): number {\n if (is_lba48) {\n let count = this.sector_count_reg\n if (count === 0) count = 0x10000\n return count\n } else {\n let count = this.sector_count_reg & 0xff\n if (count === 0) count = 0x100\n return count\n }\n }\n\n create_identify_packet(): void {\n const cylinder_count = Math.min(16383, this.cylinder_count)\n const strcpy_be16 = (\n out_buffer: Uint8Array,\n ofs16: number,\n len16: number,\n str: string,\n ): void => {\n let ofs8 = ofs16 << 1\n const len8 = len16 << 1\n const end8 = ofs8 + len8\n out_buffer.fill(32, ofs8, len8) // fill output buffer with ASCII whitespace\n for (let i_str = 0; i_str < str.length && ofs8 < end8; i_str++) {\n if (i_str & 1) {\n out_buffer[ofs8] = str.charCodeAt(i_str)\n ofs8 += 2\n } else {\n out_buffer[ofs8 + 1] = str.charCodeAt(i_str)\n }\n }\n }\n\n // Initialize array of 256 16-bit words (big-endian)\n // Best source for the lower 64 words of the memory layout used below:\n // - [ATA-retro]\n // AT Attachment Interface for Disk Drives, Revision 4c\n // https://dn790009.ca.archive.org/0/items/SCSISpecificationDocumentsATAATAPI/ATA_ATAPI/AT%20Attachment%20Interface%20for%20Disk%20Drives%20Revision%204c.pdf\n // For the words above 64 see [ATA-6] Table 27, [ATA8-ACS] 7.12 and 7.13.\n //\n // dead link: http://bochs.sourceforge.net/cgi-bin/lxr/source/iodev/harddrv.cc#L2821\n\n // most significant bit indicates ATAPI CD-ROM device\n const general_cfg = this.is_atapi ? 0x8540 : 0x0040\n // multiword DMA transfer mode, meaning of 0x0407:\n // - 0x0007: Multiword DMA modes 2, 1 and 0 are supported\n // - 0x0400: Multiword DMA mode 2 is selected\n const multiword_dma_mode =\n this.current_command === ATA_CMD_PACKET ? 0 : 0x0407\n // Major version number: bits 3/4/5/6 indicate support for ATA/ATAPI-3/4/5/6 (bits 0/1/2 are obsolete in [ATA-6])\n const major_version = 0x0000 // device does not report version\n // supported ATA: NOP, FLUSH CACHE, FLUSH CACHE EXT, 48-bit addr\n // supported ATAPI: NOP, DEVICE RESET, PACKET and FLUSH CACHE\n const feat_82 = this.is_atapi\n ? (1 << 14) | (1 << 9) | (1 << 5)\n : 1 << 14\n const feat_83 = this.is_atapi\n ? (1 << 14) | (1 << 12)\n : (1 << 14) | (1 << 13) | (1 << 12) | (1 << 10)\n const feat_84 = this.is_atapi ? 1 << 14 : 1 << 14\n\n this.data.fill(0, 0, 512)\n this.data_set([\n // 0: General configuration\n general_cfg & 0xff,\n (general_cfg >> 8) & 0xff,\n // 1: Number of cylinders\n cylinder_count & 0xff,\n (cylinder_count >> 8) & 0xff,\n // 2: reserved\n 0,\n 0,\n // 3: Number of heads\n this.head_count & 0xff,\n (this.head_count >> 8) & 0xff,\n // 4: Number of unformatted bytes per track\n (this.sectors_per_track / 512) & 0xff,\n ((this.sectors_per_track / 512) >> 8) & 0xff,\n // 5: Number of unformatted bytes per sector\n 0,\n 512 >> 8,\n // 6: Number of sectors per track\n this.sectors_per_track & 0xff,\n (this.sectors_per_track >> 8) & 0xff,\n // 7-9: Vendor-unique\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n // 10-19: Serial number (20 ASCII characters, filled below)\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n // 20: Buffer type\n 3,\n 0,\n // 21: Buffer size in 512 byte increments\n 0,\n 2,\n // 22: Number of ECC bytes avail on read/write long cmds\n 4,\n 0,\n // 23-26: Firmware revision (8 ASCII characters, filled below)\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n // 27-46: Model number (40 ASCII characters, filled below)\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n // 47: Max. number of sectors per interrupt on read/write multiple commands (1st byte) and Vendor-unique (2nd)\n 0x80,\n 0,\n // 48: Indicates whether can perform doubleword I/O (1st byte) [0: no, 1: yes]\n 1,\n 0,\n // 49: Vendor-unique (1st byte) and Capabilities (2nd) [2: Only LBA, 3: LBA and DMA]\n 0,\n 2,\n // 50: reserved\n 0,\n 0,\n // 51: PIO data transfer cycle timing mode\n 0,\n 2,\n // 52: DMA data transfer cycle timing mode\n 0,\n 2,\n // 53: Indicates whether fields 54-58 are valid (1st byte) [0: no, 1: yes]\n 7,\n 0,\n // 54: Number of current cylinders\n cylinder_count & 0xff,\n (cylinder_count >> 8) & 0xff,\n // 55: Number of current heads\n this.head_count & 0xff,\n (this.head_count >> 8) & 0xff,\n // 56: Number of current sectors per track\n this.sectors_per_track,\n 0,\n // 57-58: Current capacity in sectors\n this.sector_count & 0xff,\n (this.sector_count >> 8) & 0xff,\n (this.sector_count >> 16) & 0xff,\n (this.sector_count >> 24) & 0xff,\n // 59: Multiple sector setting\n 0,\n 0,\n // 60-61: Total number of user addressable sectors (LBA mode only)\n this.sector_count & 0xff,\n (this.sector_count >> 8) & 0xff,\n (this.sector_count >> 16) & 0xff,\n (this.sector_count >> 24) & 0xff,\n // 62: Single word DMA transfer mode\n 0,\n 0,\n // 63: Multiword DMA transfer mode (DMA supported mode, DMA selected mode)\n multiword_dma_mode & 0xff,\n (multiword_dma_mode >> 8) & 0xff,\n\n // 64: PIO modes supported\n 0,\n 0,\n // 65-68: fields related to cycle-time\n 30,\n 0,\n 30,\n 0,\n 30,\n 0,\n 30,\n 0,\n // 69-74: reserved\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n // 75: Queue depth\n 0,\n 0,\n // 76-79: reserved\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n // 80: Major version number\n major_version & 0xff,\n (major_version >> 8) & 0xff,\n // 81: Minor version number\n 0,\n 0,\n // 82: Command set supported\n feat_82 & 0xff,\n (feat_82 >> 8) & 0xff,\n // 83: Command set supported\n feat_83 & 0xff,\n (feat_83 >> 8) & 0xff,\n // 84: Command set/feature supported extension\n feat_84 & 0xff,\n (feat_84 >> 8) & 0xff,\n // 85: Command set/feature enabled (copy of 82)\n feat_82 & 0xff,\n (feat_82 >> 8) & 0xff,\n // 86: Command set/feature enabled (copy of 83)\n feat_83 & 0xff,\n (feat_83 >> 8) & 0xff,\n // 87: Command set/feature default (copy of 84)\n feat_84 & 0xff,\n (feat_84 >> 8) & 0xff,\n // 88: DMA related field\n 0,\n 0,\n // 89: Time required for security erase unit completion\n 0,\n 0,\n // 90: Time required for Enhanced security erase completion\n 0,\n 0,\n // 91: Current advanced power management value\n 0,\n 0,\n // 92: Master Password Revision Code\n 0,\n 0,\n // 93: Hardware reset result\n 1,\n 0x60,\n // 94: Acoustic management value\n 0,\n 0,\n // 95-99: reserved\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n // 100-101: Maximum user LBA for 48-bit Address feature set.\n this.sector_count & 0xff,\n (this.sector_count >> 8) & 0xff,\n (this.sector_count >> 16) & 0xff,\n (this.sector_count >> 24) & 0xff,\n ])\n\n // 10-19 serial number\n strcpy_be16(\n this.data,\n 10,\n 10,\n `8086-86${this.channel_nr}${this.interface_nr}`,\n )\n // 23-26 firmware revision\n strcpy_be16(this.data, 23, 4, '1.00')\n // 27-46 model number\n strcpy_be16(\n this.data,\n 27,\n 20,\n this.is_atapi ? 'v86 ATAPI CD-ROM' : 'v86 ATA HD',\n )\n\n this.data_length = 512\n this.data_end = 512\n }\n\n data_allocate(len: number): void {\n this.data_allocate_noclear(len)\n this.data32.fill(0, 0, (len + 3) >> 2)\n }\n\n data_allocate_noclear(len: number): void {\n if (this.data.length < len) {\n this.data = new Uint8Array((len + 3) & ~3)\n this.data16 = new Uint16Array(this.data.buffer)\n this.data32 = new Int32Array(this.data.buffer)\n }\n\n this.data_length = len\n this.data_pointer = 0\n }\n\n data_set(data: Uint8Array | number[]): void {\n this.data_allocate_noclear(data.length)\n this.data.set(data)\n }\n\n report_read_start(): void {\n this.bus.send('ide-read-start')\n }\n\n report_read_end(byte_count: number): void {\n const sector_count = (byte_count / this.sector_size) | 0\n this.bus.send('ide-read-end', [\n this.channel_nr,\n byte_count,\n sector_count,\n ])\n }\n\n report_write(byte_count: number): void {\n const sector_count = (byte_count / this.sector_size) | 0\n this.bus.send('ide-write-end', [\n this.channel_nr,\n byte_count,\n sector_count,\n ])\n }\n\n read_buffer(\n start: number,\n length: number,\n callback: (data: Uint8Array) => void,\n ): void {\n const id = this.last_io_id++\n this.in_progress_io_ids.add(id)\n\n this.buffer!.get(start, length, (data) => {\n if (this.cancelled_io_ids.delete(id)) {\n dbg_assert(!this.in_progress_io_ids.has(id))\n return\n }\n\n const removed = this.in_progress_io_ids.delete(id)\n dbg_assert(removed)\n\n callback(data)\n })\n }\n\n cancel_io_operations(): void {\n for (const id of this.in_progress_io_ids) {\n this.cancelled_io_ids.add(id)\n }\n this.in_progress_io_ids.clear()\n }\n\n get_state(): unknown[] {\n const state: unknown[] = []\n state[0] = this.sector_count_reg\n state[1] = this.cylinder_count\n state[2] = this.lba_high_reg\n state[3] = this.lba_mid_reg\n state[4] = this.data_pointer\n state[5] = 0\n state[6] = 0\n state[7] = 0\n state[8] = 0\n state[9] = this.device_reg\n state[10] = this.error_reg\n state[11] = this.head\n state[12] = this.head_count\n state[13] = this.is_atapi\n state[14] = this.is_lba\n state[15] = this.features_reg\n state[16] = this.data\n state[17] = this.data_length\n state[18] = this.lba_low_reg\n state[19] = this.sector_count\n state[20] = this.sector_size\n state[21] = this.sectors_per_drq\n state[22] = this.sectors_per_track\n state[23] = this.status_reg\n state[24] = this.write_dest\n state[25] = this.current_command\n state[26] = this.data_end\n state[27] = this.current_atapi_command\n state[28] = this.buffer\n return state\n }\n\n set_state(state: any[]): void {\n this.sector_count_reg = state[0]\n this.cylinder_count = state[1]\n this.lba_high_reg = state[2]\n this.lba_mid_reg = state[3]\n this.data_pointer = state[4]\n\n this.device_reg = state[9]\n this.error_reg = state[10]\n this.head = state[11]\n this.head_count = state[12]\n this.is_atapi = state[13]\n this.is_lba = state[14]\n this.features_reg = state[15]\n this.data = state[16]\n this.data_length = state[17]\n this.lba_low_reg = state[18]\n this.sector_count = state[19]\n this.sector_size = state[20]\n this.sectors_per_drq = state[21]\n this.sectors_per_track = state[22]\n this.status_reg = state[23]\n this.write_dest = state[24]\n this.current_command = state[25]\n\n this.data_end = state[26]\n this.current_atapi_command = state[27]\n\n this.data16 = new Uint16Array(this.data.buffer)\n this.data32 = new Int32Array(this.data.buffer)\n\n if (this.buffer) {\n this.buffer.set_state(state[28])\n }\n\n this.drive_connected = this.is_atapi || !!this.buffer\n this.medium_changed = false\n }\n}\n", "// https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-2900003\n\nimport { dbg_assert } from './log.js'\nimport { VirtIO, VIRTIO_F_VERSION_1 } from './virtio.js'\nimport type { VirtQueueBufferChain } from './virtio.js'\nimport { format_mac } from './ne2k.js'\nimport * as marshall from '../lib/marshall.js'\nimport { BusConnector } from './bus.js'\n\n// Minimal interface for the CPU fields VirtioNet needs\ninterface VirtioNetCPU {\n io: {\n register_read(\n port: number,\n device: object,\n r8?: ((port: number) => number) | undefined,\n r16?: ((port: number) => number) | undefined,\n r32?: ((port: number) => number) | undefined,\n ): void\n register_write(\n port: number,\n device: object,\n w8?: ((port: number) => void) | undefined,\n w16?: ((port: number) => void) | undefined,\n w32?: ((port: number) => void) | undefined,\n ): void\n }\n devices: {\n pci: {\n register_device(device: VirtIO): void\n raise_irq(pci_id: number): void\n lower_irq(pci_id: number): void\n }\n net?: unknown\n }\n read16(addr: number): number\n read32s(addr: number): number\n write16(addr: number, value: number): void\n write32(addr: number, value: number): void\n read_blob(addr: number, length: number): Uint8Array\n write_blob(blob: Uint8Array, addr: number): void\n zero_memory(addr: number, length: number): void\n memory_size: Int32Array\n}\n\nconst MTU_DEFAULT = 1500\n\nconst VIRTIO_NET_F_MAC = 5\nconst VIRTIO_NET_F_CTRL_VQ = 17\nconst VIRTIO_NET_F_STATUS = 16\nconst VIRTIO_NET_F_MQ = 22\nconst VIRTIO_NET_F_CTRL_MAC_ADDR = 23\nconst VIRTIO_NET_F_MTU = 3\n\nconst VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET = 0\nconst VIRTIO_NET_CTRL_MAC_ADDR_SET = 1\n\nexport class VirtioNet {\n bus: BusConnector\n id: number\n pairs: number\n status: number\n preserve_mac_from_state_image: boolean\n mac: Uint8Array\n virtio: VirtIO\n\n constructor(\n cpu: VirtioNetCPU,\n bus: BusConnector,\n preserve_mac_from_state_image: boolean,\n mtu: number = MTU_DEFAULT,\n ) {\n this.bus = bus\n this.id = cpu.devices.net ? 1 : 0\n this.pairs = 1\n this.status = 1\n this.preserve_mac_from_state_image = preserve_mac_from_state_image\n this.mac = new Uint8Array([\n 0x00,\n 0x22,\n 0x15,\n (Math.random() * 255) | 0,\n (Math.random() * 255) | 0,\n (Math.random() * 255) | 0,\n ])\n\n this.bus.send('net' + this.id + '-mac', format_mac(this.mac))\n\n const queues = []\n\n for (let i = 0; i < this.pairs; ++i) {\n queues.push({ size_supported: 1024, notify_offset: 0 })\n queues.push({ size_supported: 1024, notify_offset: 1 })\n }\n queues.push({\n size_supported: 16,\n notify_offset: 2,\n })\n\n this.virtio = new VirtIO(cpu, {\n name: 'virtio-net',\n pci_id: 0x0a << 3,\n device_id: 0x1041,\n subsystem_device_id: 1,\n common: {\n initial_port: 0xc800,\n queues: queues,\n features: [\n VIRTIO_NET_F_MAC,\n VIRTIO_NET_F_STATUS,\n VIRTIO_NET_F_MQ,\n VIRTIO_NET_F_MTU,\n VIRTIO_NET_F_CTRL_VQ,\n VIRTIO_NET_F_CTRL_MAC_ADDR,\n VIRTIO_F_VERSION_1,\n ],\n on_driver_ok: () => {},\n },\n notification: {\n initial_port: 0xc900,\n single_handler: false,\n handlers: [\n (_queue_id: number) => {},\n (queue_id: number) => {\n const queue = this.virtio.queues[queue_id]\n\n while (queue.has_request()) {\n const bufchain = queue.pop_request()\n const buffer = new Uint8Array(\n bufchain.length_readable,\n )\n bufchain.get_next_blob(buffer)\n this.bus.send(\n 'net' + this.id + '-send',\n buffer.subarray(12),\n )\n this.bus.send('eth-transmit-end', [\n buffer.length - 12,\n ])\n this.virtio.queues[queue_id].push_reply(bufchain)\n }\n this.virtio.queues[queue_id].flush_replies()\n },\n (queue_id: number) => {\n if (queue_id !== this.pairs * 2) {\n dbg_assert(\n false,\n 'VirtioNet Notified for wrong queue: ' +\n queue_id +\n ' (expected queue_id of 3)',\n )\n return\n }\n const queue = this.virtio.queues[queue_id]\n\n while (queue.has_request()) {\n const bufchain = queue.pop_request()\n const buffer = new Uint8Array(\n bufchain.length_readable,\n )\n bufchain.get_next_blob(buffer)\n\n const parts = marshall.Unmarshall(\n ['b', 'b'],\n buffer,\n {\n offset: 0,\n },\n )\n const xclass = parts[0]\n const command = parts[1]\n\n //this.Ack(queue_id, bufchain);\n\n switch ((xclass << 8) | command) {\n case (4 << 8) |\n VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET: {\n const data = marshall.Unmarshall(\n ['h'],\n buffer,\n { offset: 2 },\n )\n dbg_assert(data[0] === 1)\n this.Send(\n queue_id,\n bufchain,\n new Uint8Array([0]),\n )\n break\n }\n case (1 << 8) | VIRTIO_NET_CTRL_MAC_ADDR_SET:\n this.mac = buffer.subarray(2, 8)\n this.Send(\n queue_id,\n bufchain,\n new Uint8Array([0]),\n )\n this.bus.send(\n 'net' + this.id + '-mac',\n format_mac(this.mac),\n )\n break\n default:\n dbg_assert(\n false,\n ' VirtioNet received unknown command: ' +\n xclass +\n ':' +\n command,\n )\n this.Send(\n queue_id,\n bufchain,\n new Uint8Array([1]),\n )\n return\n }\n }\n },\n ],\n },\n isr_status: {\n initial_port: 0xc700,\n },\n device_specific: {\n initial_port: 0xc600,\n struct: [0, 1, 2, 3, 4, 5]\n .map((v, k) => ({\n bytes: 1,\n name: 'mac_' + k,\n read: () => this.mac[k],\n write: (_data: number) => {\n /* read only */\n },\n }))\n .concat([\n {\n bytes: 2,\n name: 'status',\n read: () => this.status,\n write: (_data: number) => {\n /* read only */\n },\n },\n {\n bytes: 2,\n name: 'max_pairs',\n read: () => this.pairs,\n write: (_data: number) => {\n /* read only */\n },\n },\n {\n bytes: 2,\n name: 'mtu',\n read: () => mtu,\n write: (_data: number) => {},\n },\n ]),\n },\n })\n\n this.bus.register(\n 'net' + this.id + '-receive',\n (data: any) => {\n this.bus.send('eth-receive-end', [data.length])\n const with_header = new Uint8Array(12 + data.byteLength)\n const view = new DataView(\n with_header.buffer,\n with_header.byteOffset,\n with_header.byteLength,\n )\n view.setInt16(10, 1)\n with_header.set(data, 12)\n\n const queue = this.virtio.queues[0]\n if (queue.has_request()) {\n const bufchain = queue.pop_request()\n bufchain.set_next_blob(with_header)\n this.virtio.queues[0].push_reply(bufchain)\n this.virtio.queues[0].flush_replies()\n } else {\n console.log('No buffer to write into!')\n }\n },\n this,\n )\n }\n\n get_state(): any[] {\n const state: any[] = []\n state[0] = this.virtio\n state[1] = this.id\n state[2] = this.mac\n return state\n }\n\n set_state(state: any[]): void {\n this.virtio.set_state(state[0])\n this.id = state[1]\n if (this.preserve_mac_from_state_image) {\n this.mac = state[2]\n this.bus.send('net' + this.id + '-mac', format_mac(this.mac))\n }\n }\n\n reset(): void {\n this.virtio.reset()\n }\n\n Send(\n queue_id: number,\n bufchain: VirtQueueBufferChain,\n blob: Uint8Array,\n ): void {\n bufchain.set_next_blob(blob)\n this.virtio.queues[queue_id].push_reply(bufchain)\n this.virtio.queues[queue_id].flush_replies()\n }\n\n Ack(queue_id: number, bufchain: VirtQueueBufferChain): void {\n //bufchain.set_next_blob(new Uint8Array(0));\n this.virtio.queues[queue_id].push_reply(bufchain)\n this.virtio.queues[queue_id].flush_replies()\n }\n}\n", "import { LOG_VGA } from './const.js'\nimport { h, round_up_to_next_power_of_2, view } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\nimport { IO } from './io.js'\nimport { BusConnector } from './bus.js'\nimport { PCI } from './pci.js'\n\n// Always 64k\nconst VGA_BANK_SIZE = 64 * 1024\n\nconst MAX_XRES = 2560\nconst MAX_YRES = 1600\nconst MAX_BPP = 32\n\n//const VGA_LFB_ADDRESS = 0xFE000000; // set by seabios\nconst VGA_LFB_ADDRESS = 0xe0000000\n\n// Equals the maximum number of pixels for non svga.\n// 8 pixels per byte.\nconst VGA_PIXEL_BUFFER_SIZE = 8 * VGA_BANK_SIZE\n\nconst VGA_MIN_MEMORY_SIZE = 4 * VGA_BANK_SIZE\n\n// Avoid wrapping past VGA_LFB_ADDRESS\nconst VGA_MAX_MEMORY_SIZE = 256 * 1024 * 1024\n\n// @see http://www.osdever.net/FreeVGA/vga/graphreg.htm#06\nconst VGA_HOST_MEMORY_SPACE_START = Uint32Array.from([\n 0xa0000, 0xa0000, 0xb0000, 0xb8000,\n])\n\n// @see http://www.osdever.net/FreeVGA/vga/graphreg.htm#06\nconst VGA_HOST_MEMORY_SPACE_SIZE = Uint32Array.from([\n 0x20000, // 128K\n 0x10000, // 64K\n 0x8000, // 32K\n 0x8000, // 32K\n])\n\n// Minimal interface for the CPU fields VGA uses.\ninterface VGACpu {\n io: IO\n wasm_memory: WebAssembly.Memory\n devices: { pci: PCI }\n read8(addr: number): number\n write8(addr: number, value: number): void\n svga_allocate_memory(size: number): number\n svga_allocate_dest_buffer(size: number): number\n svga_mark_dirty(): void\n svga_fill_pixel_buffer(bpp: number, offset: number): void\n svga_dirty_bitmap_min_offset: Int32Array\n svga_dirty_bitmap_max_offset: Int32Array\n}\n\n// Minimal interface for the screen adapter (ScreenAdapter or DummyScreenAdapter).\ninterface VGAScreenAdapter {\n FLAG_BLINKING: number\n FLAG_FONT_PAGE_B: number\n set_mode(graphical: boolean): void\n set_size_text(cols: number, rows: number): void\n set_size_graphical(\n width: number,\n height: number,\n virtual_width: number,\n virtual_height: number,\n ): void\n put_char(\n row: number,\n col: number,\n chr: number,\n flags: number,\n bg_color: number,\n fg_color: number,\n ): void\n update_cursor(row: number, col: number): void\n update_cursor_scanline(start: number, end: number, visible: boolean): void\n update_buffer(layers: VGALayer[]): void\n clear_screen(): void\n set_font_bitmap(\n height: number,\n width_9px: boolean,\n width_dbl: boolean,\n copy_8th_col: boolean,\n bitmap: Uint8Array,\n bitmap_changed: boolean,\n ): void\n set_font_page(page_a: number, page_b: number): void\n}\n\ninterface VGALayer {\n image_data: ImageData | null\n screen_x: number\n screen_y: number\n buffer_x: number\n buffer_y: number\n buffer_width: number\n buffer_height: number\n}\n\nexport class VGAScreen {\n cpu: VGACpu\n bus: BusConnector\n screen: VGAScreenAdapter\n vga_memory_size: number\n cursor_address: number\n cursor_scanline_start: number\n cursor_scanline_end: number\n\n // Number of columns in text mode\n max_cols: number\n\n // Number of rows in text mode\n max_rows: number\n\n // Width in pixels in graphical mode\n screen_width: number\n\n // Height in pixels in graphical mode\n screen_height: number\n\n // Logical width in pixels of virtual buffer available for panning\n virtual_width: number\n\n // Logical height in pixels of virtual buffer available for panning\n virtual_height: number\n\n // The rectangular fragments of the image buffer, and their destination\n // locations, to be drawn every screen_fill_buffer during VGA modes.\n layers: VGALayer[]\n\n // video memory start address\n start_address: number\n\n // Start address - a copy of start_address that only gets updated\n // during VSync, used for panning and page flipping\n start_address_latched: number\n\n // Unimplemented CRTC registers go here\n crtc: Uint8Array\n\n crtc_mode: number\n horizontal_display_enable_end: number\n horizontal_blank_start: number\n vertical_display_enable_end: number\n vertical_blank_start: number\n underline_location_register: number\n preset_row_scan: number\n offset_register: number\n line_compare: number\n graphical_mode: boolean\n\n // VGA palette containing 256 colors for video mode 13, svga 8bpp, etc.\n // Needs to be initialised by the BIOS\n vga256_palette: Int32Array\n\n // VGA read latches\n latch_dword: number\n svga_version: number\n svga_width: number\n svga_height: number\n svga_enabled: boolean\n svga_bpp: number\n svga_bank_offset: number\n\n // The video buffer offset created by VBE_DISPI_INDEX_Y_OFFSET (in bytes)\n svga_offset: number\n svga_offset_x: number\n svga_offset_y: number\n\n pci_space: number[]\n pci_id: number\n pci_bars: { size: number }[]\n pci_rom_size: number\n pci_rom_address: number\n name: string\n\n index_crtc: number\n dac_color_index_write: number\n dac_color_index_read: number\n dac_state: number\n dac_mask: number\n dac_map: Uint8Array\n\n attribute_controller_index: number\n palette_source: number\n attribute_mode: number\n color_plane_enable: number\n horizontal_panning: number\n color_select: number\n\n sequencer_index: number\n plane_write_bm: number\n sequencer_memory_mode: number\n clocking_mode: number\n graphics_index: number\n character_map_select: number\n\n plane_read: number\n planar_mode: number\n planar_rotate_reg: number\n planar_bitmap: number\n planar_setreset: number\n planar_setreset_enable: number\n miscellaneous_graphics_register: number\n\n color_compare: number\n color_dont_care: number\n max_scan_line: number\n miscellaneous_output_register: number\n port_3DA_value: number\n\n font_page_ab_enabled: boolean\n\n dispi_index: number\n dispi_enable_value: number\n\n svga_memory: Uint8Array\n diff_addr_min: number\n diff_addr_max: number\n diff_plot_min: number\n diff_plot_max: number\n\n image_data: ImageData | null\n dest_buffet_offset: number\n\n vga_memory: Uint8Array\n plane0: Uint8Array\n plane1: Uint8Array\n plane2: Uint8Array\n plane3: Uint8Array\n pixel_buffer: Uint8Array\n\n constructor(\n cpu: VGACpu,\n bus: BusConnector,\n screen: VGAScreenAdapter,\n vga_memory_size: number,\n ) {\n this.cpu = cpu\n this.bus = bus\n this.screen = screen\n this.vga_memory_size = vga_memory_size\n\n this.cursor_address = 0\n this.cursor_scanline_start = 0xe\n this.cursor_scanline_end = 0xf\n this.max_cols = 80\n this.max_rows = 25\n this.screen_width = 0\n this.screen_height = 0\n this.virtual_width = 0\n this.virtual_height = 0\n this.layers = []\n this.start_address = 0\n this.start_address_latched = 0\n this.crtc = new Uint8Array(0x19)\n this.crtc_mode = 0\n this.horizontal_display_enable_end = 0\n this.horizontal_blank_start = 0\n this.vertical_display_enable_end = 0\n this.vertical_blank_start = 0\n this.underline_location_register = 0\n this.preset_row_scan = 0\n this.offset_register = 0\n this.line_compare = 0\n this.graphical_mode = false\n this.vga256_palette = new Int32Array(256)\n this.latch_dword = 0\n this.svga_version = 0xb0c5\n this.svga_width = 0\n this.svga_height = 0\n this.svga_enabled = false\n this.svga_bpp = 32\n this.svga_bank_offset = 0\n this.svga_offset = 0\n this.svga_offset_x = 0\n this.svga_offset_y = 0\n\n if (\n this.vga_memory_size === undefined ||\n this.vga_memory_size < VGA_MIN_MEMORY_SIZE\n ) {\n this.vga_memory_size = VGA_MIN_MEMORY_SIZE\n } else if (this.vga_memory_size > VGA_MAX_MEMORY_SIZE) {\n this.vga_memory_size = VGA_MAX_MEMORY_SIZE\n } else {\n // required for pci code\n this.vga_memory_size = round_up_to_next_power_of_2(\n this.vga_memory_size,\n )\n }\n dbg_log('effective vga memory size: ' + this.vga_memory_size, LOG_VGA)\n\n const pci_revision = 0 // set to 2 for qemu extended registers\n\n // Experimental, could probably need some changes\n // 01:00.0 VGA compatible controller: NVIDIA Corporation GT216 [GeForce GT 220] (rev a2)\n this.pci_space = [\n 0x34,\n 0x12,\n 0x11,\n 0x11,\n 0x03,\n 0x01,\n 0x00,\n 0x00,\n pci_revision,\n 0x00,\n 0x00,\n 0x03,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x08,\n VGA_LFB_ADDRESS >>> 8,\n VGA_LFB_ADDRESS >>> 16,\n VGA_LFB_ADDRESS >>> 24,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0xbf,\n 0xfe,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0xf4,\n 0x1a,\n 0x00,\n 0x11,\n 0x00,\n 0x00,\n 0xbe,\n 0xfe,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n ]\n this.pci_id = 0x12 << 3\n this.pci_bars = [\n {\n size: this.vga_memory_size,\n },\n ]\n\n // TODO: Should be matched with vga bios size and mapping address\n // Seabios config for this device:\n // CONFIG_VGA_PCI=y\n // CONFIG_OVERRIDE_PCI_ID=y\n // CONFIG_VGA_VID=0x10de\n // CONFIG_VGA_DID=0x0a20\n\n this.pci_rom_size = 0x10000\n this.pci_rom_address = 0xfeb00000\n\n this.name = 'vga'\n\n this.index_crtc = 0\n\n // index for setting colors through port 3C9h\n this.dac_color_index_write = 0\n this.dac_color_index_read = 0\n this.dac_state = 0\n\n this.dac_mask = 0xff\n\n this.dac_map = new Uint8Array(0x10)\n\n this.attribute_controller_index = -1\n this.palette_source = 0x20\n this.attribute_mode = 0\n this.color_plane_enable = 0\n this.horizontal_panning = 0\n this.color_select = 0\n\n this.sequencer_index = -1\n\n // bitmap of planes 0-3\n this.plane_write_bm = 0xf\n this.sequencer_memory_mode = 0\n this.clocking_mode = 0\n this.graphics_index = -1\n this.character_map_select = 0\n\n this.plane_read = 0 // value 0-3, which plane to read\n this.planar_mode = 0\n this.planar_rotate_reg = 0\n this.planar_bitmap = 0xff\n this.planar_setreset = 0\n this.planar_setreset_enable = 0\n this.miscellaneous_graphics_register = 0\n\n this.color_compare = 0\n this.color_dont_care = 0\n\n this.max_scan_line = 0\n\n this.miscellaneous_output_register = 0xff\n this.port_3DA_value = 0xff\n\n this.font_page_ab_enabled = false\n\n this.dest_buffet_offset = 0\n\n const io = cpu.io\n\n io.register_write(0x3c0, this, this.port3C0_write)\n io.register_read(0x3c0, this, this.port3C0_read, this.port3C0_read16)\n\n io.register_read(0x3c1, this, this.port3C1_read)\n io.register_write(0x3c2, this, this.port3C2_write)\n\n io.register_write_consecutive(\n 0x3c4,\n this,\n this.port3C4_write,\n this.port3C5_write,\n )\n\n io.register_read(0x3c4, this, this.port3C4_read)\n io.register_read(0x3c5, this, this.port3C5_read)\n\n io.register_write_consecutive(\n 0x3ce,\n this,\n this.port3CE_write,\n this.port3CF_write,\n )\n\n io.register_read(0x3ce, this, this.port3CE_read)\n io.register_read(0x3cf, this, this.port3CF_read)\n\n io.register_read(0x3c6, this, this.port3C6_read)\n io.register_write(0x3c6, this, this.port3C6_write)\n io.register_write(0x3c7, this, this.port3C7_write)\n io.register_read(0x3c7, this, this.port3C7_read)\n io.register_write(0x3c8, this, this.port3C8_write)\n io.register_read(0x3c8, this, this.port3C8_read)\n io.register_write(0x3c9, this, this.port3C9_write)\n io.register_read(0x3c9, this, this.port3C9_read)\n\n io.register_read(0x3cc, this, this.port3CC_read)\n\n io.register_write(0x3d4, this, this.port3D4_write, this.port3D4_write16)\n io.register_write(0x3d5, this, this.port3D5_write, this.port3D5_write16)\n\n io.register_read(0x3d4, this, this.port3D4_read)\n io.register_read(0x3d5, this, this.port3D5_read, this.port3D5_read16)\n\n // use same handlers for monochrome text-mode's alternate port addresses 0x3B4/0x3B5 as for the regular addresses (0x3D4/0x3D5)\n io.register_write(0x3b4, this, this.port3D4_write, this.port3D4_write16)\n io.register_write(0x3b5, this, this.port3D5_write, this.port3D5_write16)\n\n io.register_read(0x3b4, this, this.port3D4_read)\n io.register_read(0x3b5, this, this.port3D5_read, this.port3D5_read16)\n\n io.register_read(0x3ca, this, function () {\n dbg_log('3CA read', LOG_VGA)\n return 0\n })\n\n // use same handler for monochrome text-mode's alternate port address 0x3BA as for its regular address (0x3DA)\n io.register_read(0x3da, this, this.port3DA_read)\n io.register_read(0x3ba, this, this.port3DA_read)\n\n // Bochs VBE Extensions\n // http://wiki.osdev.org/Bochs_VBE_Extensions\n this.dispi_index = -1\n this.dispi_enable_value = 0\n\n io.register_write(0x1ce, this, undefined, this.port1CE_write)\n\n io.register_write(0x1cf, this, undefined, this.port1CF_write)\n io.register_read(0x1cf, this, undefined, this.port1CF_read)\n\n const vga_offset = cpu.svga_allocate_memory(this.vga_memory_size) >>> 0\n this.svga_memory = view(\n Uint8Array,\n cpu.wasm_memory,\n vga_offset,\n this.vga_memory_size,\n )\n\n this.diff_addr_min = this.vga_memory_size\n this.diff_addr_max = 0\n this.diff_plot_min = this.vga_memory_size\n this.diff_plot_max = 0\n\n this.image_data = null\n\n this.vga_memory = new Uint8Array(4 * VGA_BANK_SIZE)\n this.plane0 = new Uint8Array(\n this.vga_memory.buffer,\n 0 * VGA_BANK_SIZE,\n VGA_BANK_SIZE,\n )\n this.plane1 = new Uint8Array(\n this.vga_memory.buffer,\n 1 * VGA_BANK_SIZE,\n VGA_BANK_SIZE,\n )\n this.plane2 = new Uint8Array(\n this.vga_memory.buffer,\n 2 * VGA_BANK_SIZE,\n VGA_BANK_SIZE,\n )\n this.plane3 = new Uint8Array(\n this.vga_memory.buffer,\n 3 * VGA_BANK_SIZE,\n VGA_BANK_SIZE,\n )\n this.pixel_buffer = new Uint8Array(VGA_PIXEL_BUFFER_SIZE)\n\n io.mmap_register(\n 0xa0000,\n 0x20000,\n (addr: number) => this.vga_memory_read(addr),\n (addr: number, value: number) => this.vga_memory_write(addr, value),\n )\n\n cpu.devices.pci.register_device(this)\n }\n\n get_state(): any[] {\n const state: any[] = []\n\n state[0] = this.vga_memory_size\n state[1] = this.cursor_address\n state[2] = this.cursor_scanline_start\n state[3] = this.cursor_scanline_end\n state[4] = this.max_cols\n state[5] = this.max_rows\n state[6] = this.vga_memory\n state[7] = this.dac_state\n state[8] = this.start_address\n state[9] = this.graphical_mode\n state[10] = this.vga256_palette\n state[11] = this.latch_dword\n state[12] = this.color_compare\n state[13] = this.color_dont_care\n state[14] = this.miscellaneous_graphics_register\n state[15] = this.svga_width\n state[16] = this.svga_height\n state[17] = this.crtc_mode\n state[18] = this.svga_enabled\n state[19] = this.svga_bpp\n state[20] = this.svga_bank_offset\n state[21] = this.svga_offset\n state[22] = this.index_crtc\n state[23] = this.dac_color_index_write\n state[24] = this.dac_color_index_read\n state[25] = this.dac_map\n state[26] = this.sequencer_index\n state[27] = this.plane_write_bm\n state[28] = this.sequencer_memory_mode\n state[29] = this.graphics_index\n state[30] = this.plane_read\n state[31] = this.planar_mode\n state[32] = this.planar_rotate_reg\n state[33] = this.planar_bitmap\n state[34] = this.max_scan_line\n state[35] = this.miscellaneous_output_register\n state[36] = this.port_3DA_value\n state[37] = this.dispi_index\n state[38] = this.dispi_enable_value\n state[39] = this.svga_memory\n // this.graphical_mode_is_linear\n state[41] = this.attribute_controller_index\n state[42] = this.offset_register\n state[43] = this.planar_setreset\n state[44] = this.planar_setreset_enable\n state[45] = this.start_address_latched\n state[46] = this.crtc\n state[47] = this.horizontal_display_enable_end\n state[48] = this.horizontal_blank_start\n state[49] = this.vertical_display_enable_end\n state[50] = this.vertical_blank_start\n state[51] = this.underline_location_register\n state[52] = this.preset_row_scan\n state[53] = this.offset_register\n state[54] = this.palette_source\n state[55] = this.attribute_mode\n state[56] = this.color_plane_enable\n state[57] = this.horizontal_panning\n state[58] = this.color_select\n state[59] = this.clocking_mode\n state[60] = this.line_compare\n state[61] = this.pixel_buffer\n state[62] = this.dac_mask\n state[63] = this.character_map_select\n state[64] = this.font_page_ab_enabled\n\n return state\n }\n\n set_state(state: any[]): void {\n this.vga_memory_size = state[0]\n this.cursor_address = state[1]\n this.cursor_scanline_start = state[2]\n this.cursor_scanline_end = state[3]\n this.max_cols = state[4]\n this.max_rows = state[5]\n if (state[6]) {\n this.vga_memory.set(state[6])\n }\n this.dac_state = state[7]\n this.start_address = state[8]\n this.graphical_mode = state[9]\n this.vga256_palette = state[10]\n this.latch_dword = state[11]\n this.color_compare = state[12]\n this.color_dont_care = state[13]\n this.miscellaneous_graphics_register = state[14]\n this.svga_width = state[15]\n this.svga_height = state[16]\n this.crtc_mode = state[17]\n this.svga_enabled = state[18]\n this.svga_bpp = state[19]\n this.svga_bank_offset = state[20]\n this.svga_offset = state[21]\n this.index_crtc = state[22]\n this.dac_color_index_write = state[23]\n this.dac_color_index_read = state[24]\n this.dac_map = state[25]\n this.sequencer_index = state[26]\n this.plane_write_bm = state[27]\n this.sequencer_memory_mode = state[28]\n this.graphics_index = state[29]\n this.plane_read = state[30]\n this.planar_mode = state[31]\n this.planar_rotate_reg = state[32]\n this.planar_bitmap = state[33]\n this.max_scan_line = state[34]\n this.miscellaneous_output_register = state[35]\n this.port_3DA_value = state[36]\n this.dispi_index = state[37]\n this.dispi_enable_value = state[38]\n this.svga_memory.set(state[39])\n // state[40];\n this.attribute_controller_index = state[41]\n this.offset_register = state[42]\n this.planar_setreset = state[43]\n this.planar_setreset_enable = state[44]\n this.start_address_latched = state[45]\n this.crtc.set(state[46])\n this.horizontal_display_enable_end = state[47]\n this.horizontal_blank_start = state[48]\n this.vertical_display_enable_end = state[49]\n this.vertical_blank_start = state[50]\n this.underline_location_register = state[51]\n this.preset_row_scan = state[52]\n this.offset_register = state[53]\n this.palette_source = state[54]\n this.attribute_mode = state[55]\n this.color_plane_enable = state[56]\n this.horizontal_panning = state[57]\n this.color_select = state[58]\n this.clocking_mode = state[59]\n this.line_compare = state[60]\n if (state[61]) {\n this.pixel_buffer.set(state[61])\n }\n this.dac_mask = state[62] === undefined ? 0xff : state[62]\n this.character_map_select = state[63] === undefined ? 0 : state[63]\n this.font_page_ab_enabled = state[64] === undefined ? false : state[64]\n\n this.screen.set_mode(this.graphical_mode)\n\n if (this.graphical_mode) {\n // Ensure set_size_graphical will update\n this.screen_width = 0\n this.screen_height = 0\n\n if (this.svga_enabled) {\n this.set_size_graphical(\n this.svga_width,\n this.svga_height,\n this.svga_width,\n this.svga_height,\n this.svga_bpp,\n )\n this.update_layers()\n } else {\n this.update_vga_size()\n this.update_layers()\n this.complete_replot()\n }\n } else {\n this.set_font_bitmap(true)\n this.set_size_text(this.max_cols, this.max_rows)\n this.set_font_page()\n this.update_cursor_scanline()\n this.update_cursor()\n }\n this.complete_redraw()\n }\n\n vga_memory_read(addr: number): number {\n if (this.svga_enabled) {\n // vbe banked mode (accessing svga memory through the regular vga memory range)\n return this.cpu.read8(\n (((addr - 0xa0000) | this.svga_bank_offset) + VGA_LFB_ADDRESS) |\n 0,\n )\n }\n\n const memory_space_select =\n (this.miscellaneous_graphics_register >> 2) & 0x3\n addr -= VGA_HOST_MEMORY_SPACE_START[memory_space_select]\n\n // VGA chip only decodes addresses within the selected memory space.\n if (\n addr < 0 ||\n addr >= VGA_HOST_MEMORY_SPACE_SIZE[memory_space_select]\n ) {\n dbg_log(\n 'vga read outside memory space: addr:' + h(addr >>> 0),\n LOG_VGA,\n )\n return 0\n }\n\n this.latch_dword = this.plane0[addr]\n this.latch_dword |= this.plane1[addr] << 8\n this.latch_dword |= this.plane2[addr] << 16\n this.latch_dword |= this.plane3[addr] << 24\n\n if (this.planar_mode & 0x08) {\n // read mode 1\n let reading = 0xff\n\n if (this.color_dont_care & 0x1) {\n reading &=\n this.plane0[addr] ^\n ~(this.color_compare & 0x1 ? 0xff : 0x00)\n }\n if (this.color_dont_care & 0x2) {\n reading &=\n this.plane1[addr] ^\n ~(this.color_compare & 0x2 ? 0xff : 0x00)\n }\n if (this.color_dont_care & 0x4) {\n reading &=\n this.plane2[addr] ^\n ~(this.color_compare & 0x4 ? 0xff : 0x00)\n }\n if (this.color_dont_care & 0x8) {\n reading &=\n this.plane3[addr] ^\n ~(this.color_compare & 0x8 ? 0xff : 0x00)\n }\n\n return reading\n } else {\n // read mode 0\n\n let plane = this.plane_read\n if (!this.graphical_mode) {\n // We store all text data linearly and font data in plane 2.\n // TODO: works well for planes 0 and 2, but what about plane 1?\n plane &= 0x3\n } else if (this.sequencer_memory_mode & 0x8) {\n // Chain 4\n plane = addr & 0x3\n addr &= ~0x3\n } else if (this.planar_mode & 0x10) {\n // Odd/Even host read\n plane = addr & 0x1\n addr &= ~0x1\n }\n return this.vga_memory[(plane << 16) | addr]\n }\n }\n\n vga_memory_write(addr: number, value: number): void {\n if (this.svga_enabled) {\n // vbe banked mode (accessing svga memory through the regular vga memory range)\n this.cpu.write8(\n (((addr - 0xa0000) | this.svga_bank_offset) + VGA_LFB_ADDRESS) |\n 0,\n value,\n )\n return\n }\n\n const memory_space_select =\n (this.miscellaneous_graphics_register >> 2) & 0x3\n addr -= VGA_HOST_MEMORY_SPACE_START[memory_space_select]\n\n if (\n addr < 0 ||\n addr >= VGA_HOST_MEMORY_SPACE_SIZE[memory_space_select]\n ) {\n dbg_log(\n 'vga write outside memory space: addr:' +\n h(addr >>> 0) +\n ', value:' +\n h(value),\n LOG_VGA,\n )\n return\n }\n\n if (this.graphical_mode) {\n this.vga_memory_write_graphical(addr, value)\n } else if (!(this.plane_write_bm & 0x3)) {\n if (this.plane_write_bm & 0x4) {\n // write to plane 2 (font-bitmap)\n this.plane2[addr] = value\n }\n } else {\n this.vga_memory_write_text_mode(addr, value)\n }\n }\n\n vga_memory_write_graphical(addr: number, value: number): void {\n let plane_dword: number = 0\n const write_mode = this.planar_mode & 3\n let bitmask = this.apply_feed(this.planar_bitmap)\n const setreset_dword = this.apply_expand(this.planar_setreset)\n const setreset_enable_dword = this.apply_expand(\n this.planar_setreset_enable,\n )\n\n // Write modes - see http://www.osdever.net/FreeVGA/vga/graphreg.htm#05\n switch (write_mode) {\n case 0:\n value = this.apply_rotate(value)\n plane_dword = this.apply_feed(value)\n plane_dword = this.apply_setreset(\n plane_dword,\n setreset_enable_dword,\n )\n plane_dword = this.apply_logical(plane_dword, this.latch_dword)\n plane_dword = this.apply_bitmask(plane_dword, bitmask)\n break\n case 1:\n plane_dword = this.latch_dword\n break\n case 2:\n plane_dword = this.apply_expand(value)\n plane_dword = this.apply_logical(plane_dword, this.latch_dword)\n plane_dword = this.apply_bitmask(plane_dword, bitmask)\n break\n case 3:\n value = this.apply_rotate(value)\n bitmask &= this.apply_feed(value)\n plane_dword = setreset_dword\n plane_dword = this.apply_bitmask(plane_dword, bitmask)\n break\n }\n\n let plane_select = 0xf\n\n switch (this.sequencer_memory_mode & 0xc) {\n // Odd/Even (aka chain 2)\n case 0x0:\n plane_select = 0x5 << (addr & 0x1)\n addr &= ~0x1\n break\n\n // Chain 4\n // Note: FreeVGA may have mistakenly stated that this bit field is\n // for system read only, yet the IBM Open Source Graphics Programmer's\n // Reference Manual explicitly states \"both read and write\".\n case 0x8:\n case 0xc:\n plane_select = 1 << (addr & 0x3)\n addr &= ~0x3\n break\n }\n\n // Plane masks take precedence\n // See: http://www.osdever.net/FreeVGA/vga/seqreg.htm#02\n plane_select &= this.plane_write_bm\n\n if (plane_select & 0x1) this.plane0[addr] = (plane_dword >> 0) & 0xff\n if (plane_select & 0x2) this.plane1[addr] = (plane_dword >> 8) & 0xff\n if (plane_select & 0x4) this.plane2[addr] = (plane_dword >> 16) & 0xff\n if (plane_select & 0x8) this.plane3[addr] = (plane_dword >> 24) & 0xff\n\n const pixel_addr = this.vga_addr_to_pixel(addr)\n this.partial_replot(pixel_addr, pixel_addr + 7)\n }\n\n // Copies data_byte into the four planes, with each plane\n // represented by an 8-bit field inside the dword.\n apply_feed(data_byte: number): number {\n let dword = data_byte\n dword |= data_byte << 8\n dword |= data_byte << 16\n dword |= data_byte << 24\n return dword\n }\n\n // Expands bits 0 to 3 to ocupy bits 0 to 31. Each\n // bit is expanded to 0xFF if set or 0x00 if clear.\n apply_expand(data_byte: number): number {\n let dword = data_byte & 0x1 ? 0xff : 0x00\n dword |= (data_byte & 0x2 ? 0xff : 0x00) << 8\n dword |= (data_byte & 0x4 ? 0xff : 0x00) << 16\n dword |= (data_byte & 0x8 ? 0xff : 0x00) << 24\n return dword\n }\n\n // Planar Write - Barrel Shifter\n // @see http://www.phatcode.net/res/224/files/html/ch25/25-01.html#Heading3\n // @see http://www.osdever.net/FreeVGA/vga/graphreg.htm#03\n apply_rotate(data_byte: number): number {\n const wrapped = data_byte | (data_byte << 8)\n const count = this.planar_rotate_reg & 0x7\n const shifted = wrapped >>> count\n return shifted & 0xff\n }\n\n // Planar Write - Set / Reset Circuitry\n // @see http://www.phatcode.net/res/224/files/html/ch25/25-03.html#Heading5\n // @see http://www.osdever.net/FreeVGA/vga/graphreg.htm#00\n apply_setreset(data_dword: number, enable_dword: number): number {\n const setreset_dword = this.apply_expand(this.planar_setreset)\n data_dword |= enable_dword & setreset_dword\n data_dword &= ~enable_dword | setreset_dword\n return data_dword\n }\n\n // Planar Write - ALU Unit\n // @see http://www.phatcode.net/res/224/files/html/ch24/24-01.html#Heading3\n // @see http://www.osdever.net/FreeVGA/vga/graphreg.htm#03\n apply_logical(data_dword: number, latch_dword: number): number {\n switch (this.planar_rotate_reg & 0x18) {\n case 0x08:\n return data_dword & latch_dword\n case 0x10:\n return data_dword | latch_dword\n case 0x18:\n return data_dword ^ latch_dword\n }\n return data_dword\n }\n\n // Planar Write - Bitmask Unit\n // @see http://www.phatcode.net/res/224/files/html/ch25/25-01.html#Heading2\n // @see http://www.osdever.net/FreeVGA/vga/graphreg.htm#08\n apply_bitmask(data_dword: number, bitmask_dword: number): number {\n let plane_dword = bitmask_dword & data_dword\n plane_dword |= ~bitmask_dword & this.latch_dword\n return plane_dword\n }\n\n text_mode_redraw(): void {\n const split_screen_row = this.scan_line_to_screen_row(this.line_compare)\n const row_offset = Math.max(\n 0,\n (this.offset_register * 2 - this.max_cols) * 2,\n )\n const blink_enabled = this.attribute_mode & (1 << 3)\n const fg_color_mask = this.font_page_ab_enabled ? 7 : 0xf\n const bg_color_mask = blink_enabled ? 7 : 0xf\n const FLAG_BLINKING = this.screen.FLAG_BLINKING\n const FLAG_FONT_PAGE_B = this.screen.FLAG_FONT_PAGE_B\n\n let addr = this.start_address << 1\n\n for (let row = 0; row < this.max_rows; row++) {\n if (row === split_screen_row) {\n addr = 0\n }\n\n for (let col = 0; col < this.max_cols; col++) {\n const chr = this.vga_memory[addr]\n const color = this.vga_memory[addr | 1]\n const blinking = blink_enabled && color & (1 << 7)\n const font_page_b =\n this.font_page_ab_enabled && !(color & (1 << 3))\n const flags =\n (blinking ? FLAG_BLINKING : 0) |\n (font_page_b ? FLAG_FONT_PAGE_B : 0)\n\n this.bus.send('screen-put-char', [row, col, chr])\n\n this.screen.put_char(\n row,\n col,\n chr,\n flags,\n this.vga256_palette[\n this.dac_mask &\n this.dac_map[(color >> 4) & bg_color_mask]\n ],\n this.vga256_palette[\n this.dac_mask & this.dac_map[color & fg_color_mask]\n ],\n )\n\n addr += 2\n }\n\n addr += row_offset\n }\n }\n\n vga_memory_write_text_mode(addr: number, value: number): void {\n this.vga_memory[addr] = value\n\n const max_cols = Math.max(this.max_cols, this.offset_register * 2)\n let row: number\n let col: number\n\n if (addr >> 1 >= this.start_address) {\n const memory_start = (addr >> 1) - this.start_address\n row = (memory_start / max_cols) | 0\n col = memory_start % max_cols\n } else {\n const memory_start = addr >> 1\n row =\n ((memory_start / max_cols) | 0) +\n this.scan_line_to_screen_row(this.line_compare)\n col = memory_start % max_cols\n }\n\n dbg_assert(row >= 0 && col >= 0)\n\n if (col >= this.max_cols || row >= this.max_rows) {\n return\n }\n\n let chr: number\n let color: number\n\n // XXX: Should handle 16 bit write if possible\n if (addr & 1) {\n color = value\n chr = this.vga_memory[addr & ~1]\n } else {\n chr = value\n color = this.vga_memory[addr | 1]\n }\n const blink_enabled = this.attribute_mode & (1 << 3)\n const blinking = blink_enabled && color & (1 << 7)\n const font_page_b = this.font_page_ab_enabled && !(color & (1 << 3))\n const flags =\n (blinking ? this.screen.FLAG_BLINKING : 0) |\n (font_page_b ? this.screen.FLAG_FONT_PAGE_B : 0)\n const fg_color_mask = this.font_page_ab_enabled ? 7 : 0xf\n const bg_color_mask = blink_enabled ? 7 : 0xf\n\n this.bus.send('screen-put-char', [row, col, chr])\n\n this.screen.put_char(\n row,\n col,\n chr,\n flags,\n this.vga256_palette[\n this.dac_mask & this.dac_map[(color >> 4) & bg_color_mask]\n ],\n this.vga256_palette[\n this.dac_mask & this.dac_map[color & fg_color_mask]\n ],\n )\n }\n\n update_cursor(): void {\n const max_cols = Math.max(this.max_cols, this.offset_register * 2)\n let row: number\n let col: number\n\n if (this.cursor_address >= this.start_address) {\n row = ((this.cursor_address - this.start_address) / max_cols) | 0\n col = (this.cursor_address - this.start_address) % max_cols\n } else {\n row =\n ((this.cursor_address / max_cols) | 0) +\n this.scan_line_to_screen_row(this.line_compare)\n col = this.cursor_address % max_cols\n }\n\n dbg_assert(row >= 0 && col >= 0)\n\n // NOTE: is allowed to be out of bounds\n this.screen.update_cursor(row, col)\n }\n\n complete_redraw(): void {\n dbg_log('complete redraw', LOG_VGA)\n\n if (this.graphical_mode) {\n if (this.svga_enabled) {\n this.cpu.svga_mark_dirty()\n } else {\n this.diff_addr_min = 0\n this.diff_addr_max = VGA_PIXEL_BUFFER_SIZE\n }\n } else {\n this.text_mode_redraw()\n }\n }\n\n complete_replot(): void {\n dbg_log('complete replot', LOG_VGA)\n\n if (!this.graphical_mode || this.svga_enabled) {\n return\n }\n\n this.diff_plot_min = 0\n this.diff_plot_max = VGA_PIXEL_BUFFER_SIZE\n\n this.complete_redraw()\n }\n\n partial_redraw(min: number, max: number): void {\n if (min < this.diff_addr_min) this.diff_addr_min = min\n if (max > this.diff_addr_max) this.diff_addr_max = max\n }\n\n partial_replot(min: number, max: number): void {\n if (min < this.diff_plot_min) this.diff_plot_min = min\n if (max > this.diff_plot_max) this.diff_plot_max = max\n\n this.partial_redraw(min, max)\n }\n\n reset_diffs(): void {\n this.diff_addr_min = this.vga_memory_size\n this.diff_addr_max = 0\n this.diff_plot_min = this.vga_memory_size\n this.diff_plot_max = 0\n }\n\n destroy(): void {}\n\n vga_bytes_per_line(): number {\n let bytes_per_line = this.offset_register << 2\n if (this.underline_location_register & 0x40) bytes_per_line <<= 1\n else if (this.crtc_mode & 0x40) bytes_per_line >>>= 1\n return bytes_per_line\n }\n\n vga_addr_shift_count(): number {\n // Count in multiples of 0x40 for convenience\n // Left shift 2 for word mode - 2 bytes per dot clock\n let shift_count = 0x80\n\n // Left shift 3 for byte mode - 1 byte per dot clock\n shift_count += ~this.underline_location_register & this.crtc_mode & 0x40\n\n // Left shift 1 for doubleword mode - 4 bytes per dot clock\n shift_count -= this.underline_location_register & 0x40\n\n // But shift one less if PEL width mode - 2 dot clocks per pixel\n shift_count -= this.attribute_mode & 0x40\n\n return shift_count >>> 6\n }\n\n vga_addr_to_pixel(addr: number): number {\n const shift_count = this.vga_addr_shift_count()\n\n // Undo effects of substituted bits 13 and 14\n // Assumptions:\n // - max_scan_line register is set to the values shown below\n // - Each scan line stays within the offset alignment\n // - No panning and no page flipping after drawing\n if (~this.crtc_mode & 0x3) {\n let pixel_addr = addr - this.start_address\n\n // Remove substituted bits\n pixel_addr &= (this.crtc_mode << 13) | ~0x6000\n\n // Convert to 1 pixel per address\n pixel_addr <<= shift_count\n\n // Decompose address\n let row = (pixel_addr / this.virtual_width) | 0\n const col = pixel_addr % this.virtual_width\n\n switch (this.crtc_mode & 0x3) {\n case 0x2:\n // Alternating rows using bit 13\n // Assumes max scan line = 1\n row = (row << 1) | ((addr >> 13) & 0x1)\n break\n case 0x1:\n // Alternating rows using bit 14\n // Assumes max scan line = 3\n row = (row << 1) | ((addr >> 14) & 0x1)\n break\n case 0x0:\n // Cycling through rows using bit 13 and 14\n // Assumes max scan line = 3\n row = (row << 2) | ((addr >> 13) & 0x3)\n break\n }\n\n // Reassemble address\n return (\n row * this.virtual_width +\n col +\n (this.start_address << shift_count)\n )\n } else {\n // Convert to 1 pixel per address\n return addr << shift_count\n }\n }\n\n scan_line_to_screen_row(scan_line: number): number {\n // Double scanning. The clock to the row scan counter is halved\n // so it is not affected by the memory address bit substitutions below\n if (this.max_scan_line & 0x80) {\n scan_line >>>= 1\n }\n\n // Maximum scan line, aka scan lines per character row\n // This is the number of repeats - 1 for graphic modes\n const repeat_factor = 1 + (this.max_scan_line & 0x1f)\n scan_line = Math.ceil(scan_line / repeat_factor)\n\n // Odd and Even Row Scan Counter\n // Despite repeated address counter values, because bit 13 of the shifted\n // address is substituted with bit 0 of the row scan counter, a different\n // display buffer address is generated instead of repeated\n // Assumes maximum scan line register is set to 2 or 4.\n // Note: can't assert this as register values may not be fully programmed.\n if (!(this.crtc_mode & 0x1)) {\n scan_line <<= 1\n }\n\n // Undo effects of substituted bit 14\n // Assumes maximum scan line register is set to 2 or 4\n // Note: can't assert this as register values may not be fully programmed.\n // Other maximum scan line register values would result in weird addressing\n // anyway\n if (!(this.crtc_mode & 0x2)) {\n scan_line <<= 1\n }\n\n return scan_line\n }\n\n set_size_text(cols_count: number, rows_count: number): void {\n dbg_assert(!this.graphical_mode)\n this.max_cols = cols_count\n this.max_rows = rows_count\n\n this.screen.set_size_text(cols_count, rows_count)\n this.bus.send('screen-set-size', [cols_count, rows_count, 0])\n }\n\n set_size_graphical(\n width: number,\n height: number,\n virtual_width: number,\n virtual_height: number,\n bpp: number,\n ): void {\n dbg_assert(this.graphical_mode)\n\n virtual_width = Math.max(virtual_width, 1)\n virtual_height = Math.max(virtual_height, 1)\n\n const needs_update =\n this.screen_width !== width ||\n this.screen_height !== height ||\n this.virtual_width !== virtual_width ||\n this.virtual_height !== virtual_height\n\n if (needs_update) {\n this.screen_width = width\n this.screen_height = height\n this.virtual_width = virtual_width\n this.virtual_height = virtual_height\n\n if (typeof ImageData !== 'undefined') {\n const size = virtual_width * virtual_height\n const offset = this.cpu.svga_allocate_dest_buffer(size) >>> 0\n\n this.dest_buffet_offset = offset\n this.image_data = new ImageData(\n new Uint8ClampedArray(\n this.cpu.wasm_memory.buffer,\n offset,\n 4 * size,\n ),\n virtual_width,\n virtual_height,\n )\n\n this.cpu.svga_mark_dirty()\n } else {\n // TODO: nodejs\n }\n\n this.screen.set_size_graphical(\n width,\n height,\n virtual_width,\n virtual_height,\n )\n this.bus.send('screen-set-size', [width, height, bpp])\n }\n }\n\n update_vga_size(): void {\n if (this.svga_enabled) {\n return\n }\n\n const horizontal_characters = Math.min(\n 1 + this.horizontal_display_enable_end,\n this.horizontal_blank_start,\n )\n let vertical_scans = Math.min(\n 1 + this.vertical_display_enable_end,\n this.vertical_blank_start,\n )\n\n if (!horizontal_characters || !vertical_scans) {\n // Don't update if width or height is zero.\n // These happen when registers are not fully configured yet.\n return\n }\n\n if (this.graphical_mode) {\n let screen_width = horizontal_characters << 3\n\n // Offset is half the number of bytes/words/dwords (depending on clocking mode)\n // of display memory that each logical line occupies.\n // However, the number of pixels latched, regardless of addressing mode,\n // should always 8 pixels per character clock (except for 8 bit PEL width, in which\n // case 4 pixels).\n let virtual_width = this.offset_register << 4\n let bpp = 4\n\n // Pixel Width / PEL Width / Clock Select\n if (this.attribute_mode & 0x40) {\n screen_width >>>= 1\n virtual_width >>>= 1\n bpp = 8\n } else if (this.attribute_mode & 0x2) {\n bpp = 1\n }\n\n const screen_height = this.scan_line_to_screen_row(vertical_scans)\n\n // The virtual buffer height is however many rows of data that can fit.\n // Previously drawn graphics outside of current memory address space can\n // still be drawn by setting start_address. The address at\n // VGA_HOST_MEMORY_SPACE_START[memory_space_select] is mapped to the first\n // byte of the frame buffer. Verified on some hardware.\n // Depended on by: Windows 98 start screen\n const available_bytes = VGA_HOST_MEMORY_SPACE_SIZE[0]\n\n const bytes_per_line = this.vga_bytes_per_line()\n const virtual_height = bytes_per_line\n ? Math.ceil(available_bytes / bytes_per_line)\n : screen_height\n\n this.set_size_graphical(\n screen_width,\n screen_height,\n virtual_width,\n virtual_height,\n bpp,\n )\n\n this.update_vertical_retrace()\n this.update_layers()\n } else {\n if (this.max_scan_line & 0x80) {\n // Double scanning means that half of those scan lines\n // are just repeats\n vertical_scans >>>= 1\n }\n\n const height =\n (vertical_scans / (1 + (this.max_scan_line & 0x1f))) | 0\n\n if (horizontal_characters && height) {\n this.set_size_text(horizontal_characters, height)\n }\n }\n }\n\n update_layers(): void {\n if (!this.graphical_mode) {\n this.text_mode_redraw()\n }\n\n if (this.svga_enabled) {\n this.layers = []\n return\n }\n\n if (!this.virtual_width || !this.screen_width) {\n // Avoid division by zero\n return\n }\n\n if (!this.palette_source || this.clocking_mode & 0x20) {\n // Palette source and screen disable bits = draw nothing\n // See http://www.phatcode.net/res/224/files/html/ch29/29-05.html#Heading6\n // and http://www.osdever.net/FreeVGA/vga/seqreg.htm#01\n this.layers = []\n this.screen.clear_screen()\n return\n }\n\n const start_addr = this.start_address_latched\n\n let pixel_panning = this.horizontal_panning\n if (this.attribute_mode & 0x40) {\n pixel_panning >>>= 1\n }\n\n const byte_panning = (this.preset_row_scan >> 5) & 0x3\n const pixel_addr_start = this.vga_addr_to_pixel(\n start_addr + byte_panning,\n )\n\n const start_buffer_row = (pixel_addr_start / this.virtual_width) | 0\n const start_buffer_col =\n (pixel_addr_start % this.virtual_width) + pixel_panning\n\n let split_screen_row = this.scan_line_to_screen_row(\n 1 + this.line_compare,\n )\n split_screen_row = Math.min(split_screen_row, this.screen_height)\n\n const split_buffer_height = this.screen_height - split_screen_row\n\n this.layers = []\n\n for (\n let x = -start_buffer_col, y = 0;\n x < this.screen_width;\n x += this.virtual_width, y++\n ) {\n this.layers.push({\n image_data: this.image_data,\n screen_x: x,\n screen_y: 0,\n buffer_x: 0,\n buffer_y: start_buffer_row + y,\n buffer_width: this.virtual_width,\n buffer_height: split_screen_row,\n })\n }\n\n let start_split_col = 0\n if (!(this.attribute_mode & 0x20)) {\n // Pixel panning mode. Allow panning for the lower split screen\n start_split_col =\n this.vga_addr_to_pixel(byte_panning) + pixel_panning\n }\n\n for (\n let x = -start_split_col, y = 0;\n x < this.screen_width;\n x += this.virtual_width, y++\n ) {\n this.layers.push({\n image_data: this.image_data,\n screen_x: x,\n screen_y: split_screen_row,\n buffer_x: 0,\n buffer_y: y,\n buffer_width: this.virtual_width,\n buffer_height: split_buffer_height,\n })\n }\n }\n\n update_vertical_retrace(): void {\n // Emulate behaviour during VSync/VRetrace\n this.port_3DA_value |= 0x8\n if (this.start_address_latched !== this.start_address) {\n this.start_address_latched = this.start_address\n this.update_layers()\n }\n }\n\n update_cursor_scanline(): void {\n const disabled = this.cursor_scanline_start & 0x20\n const max = this.max_scan_line & 0x1f\n const start = Math.min(max, this.cursor_scanline_start & 0x1f)\n const end = Math.min(max, this.cursor_scanline_end & 0x1f)\n const visible = !disabled && start < end\n this.screen.update_cursor_scanline(start, end, visible)\n }\n\n // Attribute controller register / index write\n // @see http://www.osdever.net/FreeVGA/vga/attrreg.htm\n // @see http://www.mcamafia.de/pdf/ibm_vgaxga_trm2.pdf page 89\n // @see https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-hsw-display_0.pdf page 48\n port3C0_write(value: number): void {\n if (this.attribute_controller_index === -1) {\n dbg_log('attribute controller index register: ' + h(value), LOG_VGA)\n this.attribute_controller_index = value & 0x1f\n dbg_log(\n 'attribute actual index: ' + h(this.attribute_controller_index),\n LOG_VGA,\n )\n\n if (this.palette_source !== (value & 0x20)) {\n // A method of blanking the screen.\n // See http://www.phatcode.net/res/224/files/html/ch29/29-05.html#Heading6\n this.palette_source = value & 0x20\n this.update_layers()\n }\n } else {\n if (this.attribute_controller_index < 0x10) {\n dbg_log(\n 'internal palette: ' +\n h(this.attribute_controller_index) +\n ' -> ' +\n h(value),\n LOG_VGA,\n )\n this.dac_map[this.attribute_controller_index] = value\n\n if (!(this.attribute_mode & 0x40)) {\n this.complete_redraw()\n }\n } else\n switch (this.attribute_controller_index) {\n case 0x10:\n dbg_log(\n '3C0 / attribute mode control: ' + h(value),\n LOG_VGA,\n )\n if (this.attribute_mode !== value) {\n const previous_mode = this.attribute_mode\n this.attribute_mode = value\n\n const is_graphical = (value & 0x1) !== 0\n if (\n !this.svga_enabled &&\n this.graphical_mode !== is_graphical\n ) {\n this.graphical_mode = is_graphical\n this.screen.set_mode(this.graphical_mode)\n }\n\n if ((previous_mode ^ value) & 0x40) {\n // PEL width changed. Pixel Buffer now invalidated\n this.complete_replot()\n }\n\n this.update_vga_size()\n\n // Data stored in image buffer are invalidated\n this.complete_redraw()\n\n this.set_font_bitmap(false)\n }\n break\n case 0x12:\n dbg_log(\n '3C0 / color plane enable: ' + h(value),\n LOG_VGA,\n )\n if (this.color_plane_enable !== value) {\n this.color_plane_enable = value\n\n // Data stored in image buffer are invalidated\n this.complete_redraw()\n }\n break\n case 0x13:\n dbg_log(\n '3C0 / horizontal panning: ' + h(value),\n LOG_VGA,\n )\n if (this.horizontal_panning !== value) {\n this.horizontal_panning = value & 0xf\n this.update_layers()\n }\n break\n case 0x14:\n dbg_log('3C0 / color select: ' + h(value), LOG_VGA)\n if (this.color_select !== value) {\n this.color_select = value\n\n // Data stored in image buffer are invalidated\n this.complete_redraw()\n }\n break\n default:\n dbg_log(\n '3C0 / attribute controller write ' +\n h(this.attribute_controller_index) +\n ': ' +\n h(value),\n LOG_VGA,\n )\n }\n\n this.attribute_controller_index = -1\n }\n }\n\n port3C0_read(): number {\n dbg_log('3C0 read', LOG_VGA)\n return (this.attribute_controller_index | this.palette_source) & 0xff\n }\n\n port3C0_read16(): number {\n dbg_log('3C0 read16', LOG_VGA)\n return this.port3C0_read() | ((this.port3C1_read() << 8) & 0xff00)\n }\n\n port3C1_read(): number {\n if (this.attribute_controller_index < 0x10) {\n dbg_log(\n '3C1 / internal palette read: ' +\n h(this.attribute_controller_index) +\n ' -> ' +\n h(this.dac_map[this.attribute_controller_index]),\n LOG_VGA,\n )\n return this.dac_map[this.attribute_controller_index] & 0xff\n }\n\n switch (this.attribute_controller_index) {\n case 0x10:\n dbg_log(\n '3C1 / attribute mode read: ' + h(this.attribute_mode),\n LOG_VGA,\n )\n return this.attribute_mode\n case 0x12:\n dbg_log(\n '3C1 / color plane enable read: ' +\n h(this.color_plane_enable),\n LOG_VGA,\n )\n return this.color_plane_enable\n case 0x13:\n dbg_log(\n '3C1 / horizontal panning read: ' +\n h(this.horizontal_panning),\n LOG_VGA,\n )\n return this.horizontal_panning\n case 0x14:\n dbg_log(\n '3C1 / color select read: ' + h(this.color_select),\n LOG_VGA,\n )\n return this.color_select\n default:\n dbg_log(\n '3C1 / attribute controller read ' +\n h(this.attribute_controller_index),\n LOG_VGA,\n )\n }\n return 0xff\n }\n\n port3C2_write(value: number): void {\n dbg_log('3C2 / miscellaneous output register = ' + h(value), LOG_VGA)\n this.miscellaneous_output_register = value\n }\n\n port3C4_write(value: number): void {\n this.sequencer_index = value\n }\n\n port3C4_read(): number {\n return this.sequencer_index\n }\n\n // Sequencer register writes\n // @see http://www.osdever.net/FreeVGA/vga/seqreg.htm\n // @see http://www.mcamafia.de/pdf/ibm_vgaxga_trm2.pdf page 47\n // @see https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-hsw-display_0.pdf page 19\n port3C5_write(value: number): void {\n switch (this.sequencer_index) {\n case 0x01: {\n dbg_log('clocking mode: ' + h(value), LOG_VGA)\n const previous_clocking_mode = this.clocking_mode\n this.clocking_mode = value\n if ((previous_clocking_mode ^ value) & 0x20) {\n // Screen disable bit modified\n this.update_layers()\n }\n this.set_font_bitmap(false)\n break\n }\n case 0x02: {\n dbg_log('plane write mask: ' + h(value), LOG_VGA)\n const previous_plane_write_bm = this.plane_write_bm\n this.plane_write_bm = value\n if (\n !this.graphical_mode &&\n previous_plane_write_bm & 0x4 &&\n !(this.plane_write_bm & 0x4)\n ) {\n // End of font plane 2 write access\n this.set_font_bitmap(true)\n }\n break\n }\n case 0x03: {\n dbg_log('character map select: ' + h(value), LOG_VGA)\n const previous_character_map_select = this.character_map_select\n this.character_map_select = value\n if (\n !this.graphical_mode &&\n previous_character_map_select !== value\n ) {\n this.set_font_page()\n }\n break\n }\n case 0x04:\n dbg_log('sequencer memory mode: ' + h(value), LOG_VGA)\n this.sequencer_memory_mode = value\n break\n default:\n dbg_log(\n '3C5 / sequencer write ' +\n h(this.sequencer_index) +\n ': ' +\n h(value),\n LOG_VGA,\n )\n }\n }\n\n port3C5_read(): number {\n dbg_log('3C5 / sequencer read ' + h(this.sequencer_index), LOG_VGA)\n\n switch (this.sequencer_index) {\n case 0x01:\n return this.clocking_mode\n case 0x02:\n return this.plane_write_bm\n case 0x03:\n return this.character_map_select\n case 0x04:\n return this.sequencer_memory_mode\n case 0x06:\n return 0x12\n default:\n }\n return 0\n }\n\n port3C6_write(data: number): void {\n if (this.dac_mask !== data) {\n this.dac_mask = data\n this.complete_redraw()\n }\n }\n\n port3C6_read(): number {\n return this.dac_mask\n }\n\n port3C7_write(index: number): void {\n // index for reading the DAC\n dbg_log('3C7 write: ' + h(index), LOG_VGA)\n this.dac_color_index_read = index * 3\n this.dac_state &= 0x0\n }\n\n port3C7_read(): number {\n // prepared to accept reads or writes\n return this.dac_state\n }\n\n port3C8_write(index: number): void {\n this.dac_color_index_write = index * 3\n this.dac_state |= 0x3\n }\n\n port3C8_read(): number {\n return (this.dac_color_index_write / 3) & 0xff\n }\n\n // DAC color palette register writes\n // @see http://www.osdever.net/FreeVGA/vga/colorreg.htm\n // @see http://www.mcamafia.de/pdf/ibm_vgaxga_trm2.pdf page 104\n // @see https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-hsw-display_0.pdf page 57\n port3C9_write(color_byte: number): void {\n const index = (this.dac_color_index_write / 3) | 0,\n offset = this.dac_color_index_write % 3\n let color = this.vga256_palette[index]\n\n if ((this.dispi_enable_value & 0x20) === 0) {\n color_byte &= 0x3f\n const b = color_byte & 1\n color_byte = (color_byte << 2) | (b << 1) | b\n }\n\n if (offset === 0) {\n color = (color & ~0xff0000) | (color_byte << 16)\n } else if (offset === 1) {\n color = (color & ~0xff00) | (color_byte << 8)\n } else {\n color = (color & ~0xff) | color_byte\n dbg_log(\n 'dac set color, index=' + h(index) + ' value=' + h(color),\n LOG_VGA,\n )\n }\n\n if (this.vga256_palette[index] !== color) {\n this.vga256_palette[index] = color\n this.complete_redraw()\n }\n this.dac_color_index_write++\n }\n\n port3C9_read(): number {\n dbg_log('3C9 read', LOG_VGA)\n\n const index = (this.dac_color_index_read / 3) | 0\n const offset = this.dac_color_index_read % 3\n const color = this.vga256_palette[index]\n const color8 = (color >> ((2 - offset) * 8)) & 0xff\n\n this.dac_color_index_read++\n\n if (this.dispi_enable_value & 0x20) {\n return color8\n } else {\n return color8 >> 2\n }\n }\n\n port3CC_read(): number {\n dbg_log('3CC read', LOG_VGA)\n return this.miscellaneous_output_register\n }\n\n port3CE_write(value: number): void {\n this.graphics_index = value\n }\n\n port3CE_read(): number {\n return this.graphics_index\n }\n\n // Graphics controller register writes\n // @see http://www.osdever.net/FreeVGA/vga/graphreg.htm\n // @see http://www.mcamafia.de/pdf/ibm_vgaxga_trm2.pdf page 78\n // @see https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-hsw-display_0.pdf page 29\n port3CF_write(value: number): void {\n switch (this.graphics_index) {\n case 0:\n this.planar_setreset = value\n dbg_log('plane set/reset: ' + h(value), LOG_VGA)\n break\n case 1:\n this.planar_setreset_enable = value\n dbg_log('plane set/reset enable: ' + h(value), LOG_VGA)\n break\n case 2:\n this.color_compare = value\n dbg_log('color compare: ' + h(value), LOG_VGA)\n break\n case 3:\n this.planar_rotate_reg = value\n dbg_log('plane rotate: ' + h(value), LOG_VGA)\n break\n case 4:\n this.plane_read = value\n dbg_log('plane read: ' + h(value), LOG_VGA)\n break\n case 5: {\n const previous_planar_mode = this.planar_mode\n this.planar_mode = value\n dbg_log('planar mode: ' + h(value), LOG_VGA)\n if ((previous_planar_mode ^ value) & 0x60) {\n // Shift mode modified. Pixel buffer invalidated\n this.complete_replot()\n }\n break\n }\n case 6:\n dbg_log('miscellaneous graphics register: ' + h(value), LOG_VGA)\n if (this.miscellaneous_graphics_register !== value) {\n this.miscellaneous_graphics_register = value\n this.update_vga_size()\n }\n break\n case 7:\n this.color_dont_care = value\n dbg_log(\"color don't care: \" + h(value), LOG_VGA)\n break\n case 8:\n this.planar_bitmap = value\n dbg_log('planar bitmap: ' + h(value), LOG_VGA)\n break\n default:\n dbg_log(\n '3CF / graphics write ' +\n h(this.graphics_index) +\n ': ' +\n h(value),\n LOG_VGA,\n )\n }\n }\n\n port3CF_read(): number {\n dbg_log('3CF / graphics read ' + h(this.graphics_index), LOG_VGA)\n\n switch (this.graphics_index) {\n case 0:\n return this.planar_setreset\n case 1:\n return this.planar_setreset_enable\n case 2:\n return this.color_compare\n case 3:\n return this.planar_rotate_reg\n case 4:\n return this.plane_read\n case 5:\n return this.planar_mode\n case 6:\n return this.miscellaneous_graphics_register\n case 7:\n return this.color_dont_care\n case 8:\n return this.planar_bitmap\n default:\n }\n return 0\n }\n\n port3D4_write(register: number): void {\n dbg_log('3D4 / crtc index: ' + register, LOG_VGA)\n this.index_crtc = register\n }\n\n port3D4_write16(register: number): void {\n this.port3D4_write(register & 0xff)\n this.port3D5_write((register >> 8) & 0xff)\n }\n\n port3D4_read(): number {\n dbg_log('3D4 read / crtc index: ' + this.index_crtc, LOG_VGA)\n return this.index_crtc\n }\n\n // CRT controller register writes\n // @see http://www.osdever.net/FreeVGA/vga/crtcreg.htm\n // @see http://www.mcamafia.de/pdf/ibm_vgaxga_trm2.pdf page 55\n // @see https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-hsw-display_0.pdf page 63\n port3D5_write(value: number): void {\n switch (this.index_crtc) {\n case 0x1:\n dbg_log('3D5 / hdisp enable end write: ' + h(value), LOG_VGA)\n if (this.horizontal_display_enable_end !== value) {\n this.horizontal_display_enable_end = value\n this.update_vga_size()\n }\n break\n case 0x2:\n if (this.horizontal_blank_start !== value) {\n this.horizontal_blank_start = value\n this.update_vga_size()\n }\n break\n case 0x7: {\n dbg_log('3D5 / overflow register write: ' + h(value), LOG_VGA)\n const previous_vertical_display_enable_end =\n this.vertical_display_enable_end\n this.vertical_display_enable_end &= 0xff\n this.vertical_display_enable_end |=\n ((value << 3) & 0x200) | ((value << 7) & 0x100)\n if (\n previous_vertical_display_enable_end !==\n this.vertical_display_enable_end\n ) {\n this.update_vga_size()\n }\n this.line_compare =\n (this.line_compare & 0x2ff) | ((value << 4) & 0x100)\n\n const previous_vertical_blank_start = this.vertical_blank_start\n this.vertical_blank_start =\n (this.vertical_blank_start & 0x2ff) | ((value << 5) & 0x100)\n if (\n previous_vertical_blank_start !== this.vertical_blank_start\n ) {\n this.update_vga_size()\n }\n this.update_layers()\n break\n }\n case 0x8:\n dbg_log('3D5 / preset row scan write: ' + h(value), LOG_VGA)\n this.preset_row_scan = value\n this.update_layers()\n break\n case 0x9: {\n dbg_log('3D5 / max scan line write: ' + h(value), LOG_VGA)\n const previous_max_scan_line = this.max_scan_line\n this.max_scan_line = value\n this.line_compare =\n (this.line_compare & 0x1ff) | ((value << 3) & 0x200)\n\n const previous_vertical_blank_start2 = this.vertical_blank_start\n this.vertical_blank_start =\n (this.vertical_blank_start & 0x1ff) | ((value << 4) & 0x200)\n if (\n (previous_max_scan_line ^ this.max_scan_line) & 0x9f ||\n previous_vertical_blank_start2 !== this.vertical_blank_start\n ) {\n this.update_vga_size()\n }\n\n this.update_cursor_scanline()\n this.update_layers()\n\n this.set_font_bitmap(false)\n break\n }\n case 0xa:\n dbg_log(\n '3D5 / cursor scanline start write: ' + h(value),\n LOG_VGA,\n )\n this.cursor_scanline_start = value\n this.update_cursor_scanline()\n break\n case 0xb:\n dbg_log('3D5 / cursor scanline end write: ' + h(value), LOG_VGA)\n this.cursor_scanline_end = value\n this.update_cursor_scanline()\n break\n case 0xc:\n if (((this.start_address >> 8) & 0xff) !== value) {\n this.start_address =\n (this.start_address & 0xff) | (value << 8)\n this.update_layers()\n if (~this.crtc_mode & 0x3) {\n // Address substitution implementation depends on the\n // starting row and column, so the pixel buffer is invalidated.\n this.complete_replot()\n }\n }\n dbg_log(\n '3D5 / start addr hi write: ' +\n h(value) +\n ' -> ' +\n h(this.start_address, 4),\n LOG_VGA,\n )\n break\n case 0xd:\n if ((this.start_address & 0xff) !== value) {\n this.start_address = (this.start_address & 0xff00) | value\n this.update_layers()\n if (~this.crtc_mode & 0x3) {\n // Address substitution implementation depends on the\n // starting row and column, so the pixel buffer is invalidated.\n this.complete_replot()\n }\n }\n dbg_log(\n '3D5 / start addr lo write: ' +\n h(value) +\n ' -> ' +\n h(this.start_address, 4),\n LOG_VGA,\n )\n break\n case 0xe:\n dbg_log('3D5 / cursor address hi write: ' + h(value), LOG_VGA)\n this.cursor_address =\n (this.cursor_address & 0xff) | (value << 8)\n this.update_cursor()\n break\n case 0xf:\n dbg_log('3D5 / cursor address lo write: ' + h(value), LOG_VGA)\n this.cursor_address = (this.cursor_address & 0xff00) | value\n this.update_cursor()\n break\n case 0x12:\n dbg_log('3D5 / vdisp enable end write: ' + h(value), LOG_VGA)\n if ((this.vertical_display_enable_end & 0xff) !== value) {\n this.vertical_display_enable_end =\n (this.vertical_display_enable_end & 0x300) | value\n this.update_vga_size()\n }\n break\n case 0x13:\n dbg_log('3D5 / offset register write: ' + h(value), LOG_VGA)\n if (this.offset_register !== value) {\n this.offset_register = value\n this.update_vga_size()\n\n if (~this.crtc_mode & 0x3) {\n // Address substitution implementation depends on the\n // virtual width, so the pixel buffer is invalidated.\n this.complete_replot()\n }\n }\n break\n case 0x14:\n dbg_log('3D5 / underline location write: ' + h(value), LOG_VGA)\n if (this.underline_location_register !== value) {\n const previous_underline = this.underline_location_register\n\n this.underline_location_register = value\n this.update_vga_size()\n\n if ((previous_underline ^ value) & 0x40) {\n // Doubleword addressing changed. Pixel buffer invalidated.\n this.complete_replot()\n }\n }\n break\n case 0x15:\n dbg_log(\n '3D5 / vertical blank start write: ' + h(value),\n LOG_VGA,\n )\n if ((this.vertical_blank_start & 0xff) !== value) {\n this.vertical_blank_start =\n (this.vertical_blank_start & 0x300) | value\n this.update_vga_size()\n }\n break\n case 0x17:\n dbg_log('3D5 / crtc mode write: ' + h(value), LOG_VGA)\n if (this.crtc_mode !== value) {\n const previous_mode = this.crtc_mode\n\n this.crtc_mode = value\n this.update_vga_size()\n\n if ((previous_mode ^ value) & 0x43) {\n // Word/byte addressing changed or address substitution changed.\n // Pixel buffer invalidated.\n this.complete_replot()\n }\n }\n break\n case 0x18:\n dbg_log('3D5 / line compare write: ' + h(value), LOG_VGA)\n this.line_compare = (this.line_compare & 0x300) | value\n this.update_layers()\n break\n default:\n if (this.index_crtc < this.crtc.length) {\n this.crtc[this.index_crtc] = value\n }\n dbg_log(\n '3D5 / CRTC write ' + h(this.index_crtc) + ': ' + h(value),\n LOG_VGA,\n )\n }\n }\n\n port3D5_write16(register: number): void {\n dbg_log('16-bit write to 3D5: ' + h(register, 4), LOG_VGA)\n this.port3D5_write(register & 0xff)\n }\n\n port3D5_read(): number {\n dbg_log('3D5 read ' + h(this.index_crtc), LOG_VGA)\n\n switch (this.index_crtc) {\n case 0x1:\n return this.horizontal_display_enable_end\n case 0x2:\n return this.horizontal_blank_start\n case 0x7:\n return (\n ((this.vertical_display_enable_end >> 7) & 0x2) |\n ((this.vertical_blank_start >> 5) & 0x8) |\n ((this.line_compare >> 4) & 0x10) |\n ((this.vertical_display_enable_end >> 3) & 0x40)\n )\n case 0x8:\n return this.preset_row_scan\n case 0x9:\n return this.max_scan_line\n case 0xa:\n return this.cursor_scanline_start\n case 0xb:\n return this.cursor_scanline_end\n case 0xc:\n return this.start_address & 0xff\n case 0xd:\n return this.start_address >> 8\n case 0xe:\n return this.cursor_address >> 8\n case 0xf:\n return this.cursor_address & 0xff\n case 0x12:\n return this.vertical_display_enable_end & 0xff\n case 0x13:\n return this.offset_register\n case 0x14:\n return this.underline_location_register\n case 0x15:\n return this.vertical_blank_start & 0xff\n case 0x17:\n return this.crtc_mode\n case 0x18:\n return this.line_compare & 0xff\n }\n\n if (this.index_crtc < this.crtc.length) {\n return this.crtc[this.index_crtc]\n } else {\n return 0\n }\n }\n\n port3D5_read16(): number {\n dbg_log('Warning: 16-bit read from 3D5', LOG_VGA)\n return this.port3D5_read()\n }\n\n port3DA_read(): number {\n dbg_log('3DA read - status 1 and clear attr index', LOG_VGA)\n\n const value = this.port_3DA_value\n\n // Status register, bit 3 set by update_vertical_retrace\n // during screen-fill-buffer\n if (!this.graphical_mode) {\n // But screen-fill-buffer may not get triggered in text mode\n // so toggle it manually here\n if (this.port_3DA_value & 1) {\n this.port_3DA_value ^= 8\n }\n this.port_3DA_value ^= 1\n } else {\n this.port_3DA_value ^= 1\n this.port_3DA_value &= 1\n }\n this.attribute_controller_index = -1\n return value\n }\n\n port1CE_write(value: number): void {\n this.dispi_index = value\n }\n\n port1CF_write(value: number): void {\n dbg_log(\n '1CF / dispi write ' + h(this.dispi_index) + ': ' + h(value),\n LOG_VGA,\n )\n\n const was_enabled = this.svga_enabled\n\n switch (this.dispi_index) {\n case 0:\n if (value >= 0xb0c0 && value <= 0xb0c5) {\n this.svga_version = value\n } else {\n dbg_log('Invalid version value: ' + h(value), LOG_VGA)\n }\n break\n case 1:\n this.svga_width = value\n if (this.svga_width > MAX_XRES) {\n dbg_log(\n 'svga_width reduced from ' +\n this.svga_width +\n ' to ' +\n MAX_XRES,\n LOG_VGA,\n )\n this.svga_width = MAX_XRES\n }\n break\n case 2:\n this.svga_height = value\n if (this.svga_height > MAX_YRES) {\n dbg_log(\n 'svga_height reduced from ' +\n this.svga_height +\n ' to ' +\n MAX_YRES,\n LOG_VGA,\n )\n this.svga_height = MAX_YRES\n }\n break\n case 3:\n this.svga_bpp = value\n break\n case 4:\n // enable, options\n this.svga_enabled = (value & 1) === 1\n if (this.svga_enabled && (value & 0x80) === 0) {\n this.svga_memory.fill(0)\n }\n this.dispi_enable_value = value\n break\n case 5:\n dbg_log('SVGA bank offset: ' + h(value << 16), LOG_VGA)\n this.svga_bank_offset = value << 16\n break\n case 8:\n // x offset\n dbg_log('SVGA X offset: ' + h(value), LOG_VGA)\n if (this.svga_offset_x !== value) {\n this.svga_offset_x = value\n this.svga_offset =\n this.svga_offset_y * this.svga_width +\n this.svga_offset_x\n this.complete_redraw()\n }\n break\n case 9:\n // y offset\n dbg_log(\n 'SVGA Y offset: ' +\n h(value * this.svga_width) +\n ' y=' +\n h(value),\n LOG_VGA,\n )\n if (this.svga_offset_y !== value) {\n this.svga_offset_y = value\n this.svga_offset =\n this.svga_offset_y * this.svga_width +\n this.svga_offset_x\n this.complete_redraw()\n }\n break\n default:\n dbg_log(\n 'Unimplemented dispi write index: ' + h(this.dispi_index),\n LOG_VGA,\n )\n }\n\n if (this.svga_enabled && (!this.svga_width || !this.svga_height)) {\n dbg_log(\n 'SVGA: disabled because of invalid width/height: ' +\n this.svga_width +\n 'x' +\n this.svga_height,\n LOG_VGA,\n )\n this.svga_enabled = false\n }\n\n dbg_assert(this.svga_bpp !== 4, 'unimplemented svga bpp: 4')\n dbg_assert(\n this.svga_bpp === 4 ||\n this.svga_bpp === 8 ||\n this.svga_bpp === 15 ||\n this.svga_bpp === 16 ||\n this.svga_bpp === 24 ||\n this.svga_bpp === 32,\n 'unexpected svga bpp: ' + this.svga_bpp,\n )\n\n if (this.svga_enabled) {\n dbg_log(\n 'SVGA: enabled, ' +\n this.svga_width +\n 'x' +\n this.svga_height +\n 'x' +\n this.svga_bpp,\n LOG_VGA,\n )\n } else {\n dbg_log('SVGA: disabled', LOG_VGA)\n }\n\n if (this.svga_enabled && !was_enabled) {\n this.svga_offset = 0\n this.svga_offset_x = 0\n this.svga_offset_y = 0\n\n this.graphical_mode = true\n this.screen.set_mode(this.graphical_mode)\n this.set_size_graphical(\n this.svga_width,\n this.svga_height,\n this.svga_width,\n this.svga_height,\n this.svga_bpp,\n )\n }\n\n if (was_enabled && !this.svga_enabled) {\n const is_graphical = (this.attribute_mode & 0x1) !== 0\n this.graphical_mode = is_graphical\n this.screen.set_mode(is_graphical)\n this.update_vga_size()\n this.set_font_bitmap(false)\n this.complete_redraw()\n }\n\n if (!this.svga_enabled) {\n this.svga_bank_offset = 0\n }\n\n this.update_layers()\n }\n\n port1CF_read(): number {\n dbg_log('1CF / dispi read ' + h(this.dispi_index), LOG_VGA)\n return this.svga_register_read(this.dispi_index)\n }\n\n svga_register_read(n: number): number {\n switch (n) {\n case 0:\n return this.svga_version\n case 1:\n return this.dispi_enable_value & 2 ? MAX_XRES : this.svga_width\n case 2:\n return this.dispi_enable_value & 2 ? MAX_YRES : this.svga_height\n case 3:\n return this.dispi_enable_value & 2 ? MAX_BPP : this.svga_bpp\n case 4:\n return this.dispi_enable_value\n case 5:\n return this.svga_bank_offset >>> 16\n case 6:\n // virtual width\n if (this.screen_width) {\n return this.screen_width\n } else {\n return 1 // seabios/windows98 divide exception\n }\n\n case 8:\n // x offset\n return this.svga_offset_x\n case 9:\n return this.svga_offset_y\n case 0x0a:\n // memory size in 64 kilobyte banks\n return (this.vga_memory_size / VGA_BANK_SIZE) | 0\n default:\n dbg_log(\n 'Unimplemented dispi read index: ' + h(this.dispi_index),\n LOG_VGA,\n )\n }\n\n return 0xff\n }\n\n // Transfers graphics from VGA Planes to the Pixel Buffer\n // VGA Planes represent data stored on actual hardware.\n // Pixel Buffer caches the 4-bit or 8-bit color indices for each pixel.\n vga_replot(): void {\n // Round to multiple of 8 towards extreme\n const start = this.diff_plot_min & ~0xf\n const end = Math.min(\n this.diff_plot_max | 0xf,\n VGA_PIXEL_BUFFER_SIZE - 1,\n )\n\n const addr_shift = this.vga_addr_shift_count()\n const addr_substitution = ~this.crtc_mode & 0x3\n\n const shift_mode = this.planar_mode & 0x60\n const pel_width = this.attribute_mode & 0x40\n\n for (let pixel_addr = start; pixel_addr <= end; ) {\n let addr = pixel_addr >>> addr_shift\n if (addr_substitution) {\n let row = (pixel_addr / this.virtual_width) | 0\n const col = pixel_addr - this.virtual_width * row\n\n switch (addr_substitution) {\n case 0x1:\n // Alternating rows using bit 13\n // Assumes max scan line = 1\n addr = (row & 0x1) << 13\n row >>>= 1\n break\n case 0x2:\n // Alternating rows using bit 14\n // Assumes max scan line = 3\n addr = (row & 0x1) << 14\n row >>>= 1\n break\n case 0x3:\n // Cycling through rows using bit 13 and 14\n // Assumes max scan line = 3\n addr = (row & 0x3) << 13\n row >>>= 2\n break\n }\n\n addr |=\n ((row * this.virtual_width + col) >>> addr_shift) +\n this.start_address\n }\n\n let byte0 = this.plane0[addr]\n let byte1 = this.plane1[addr]\n let byte2 = this.plane2[addr]\n let byte3 = this.plane3[addr]\n\n const shift_loads = new Uint8Array(8)\n switch (shift_mode) {\n // Planar Shift Mode\n // See http://www.osdever.net/FreeVGA/vga/vgaseq.htm\n case 0x00:\n // Shift these, so that the bits for the color are in\n // the correct position in the for loop\n byte0 <<= 0\n byte1 <<= 1\n byte2 <<= 2\n byte3 <<= 3\n\n for (let i = 7; i >= 0; i--) {\n shift_loads[7 - i] =\n ((byte0 >> i) & 1) |\n ((byte1 >> i) & 2) |\n ((byte2 >> i) & 4) |\n ((byte3 >> i) & 8)\n }\n break\n\n // Packed Shift Mode, aka Interleaved Shift Mode\n // Video Modes 4h and 5h\n case 0x20:\n shift_loads[0] = ((byte0 >> 6) & 0x3) | ((byte2 >> 4) & 0xc)\n shift_loads[1] = ((byte0 >> 4) & 0x3) | ((byte2 >> 2) & 0xc)\n shift_loads[2] = ((byte0 >> 2) & 0x3) | ((byte2 >> 0) & 0xc)\n shift_loads[3] = ((byte0 >> 0) & 0x3) | ((byte2 << 2) & 0xc)\n\n shift_loads[4] = ((byte1 >> 6) & 0x3) | ((byte3 >> 4) & 0xc)\n shift_loads[5] = ((byte1 >> 4) & 0x3) | ((byte3 >> 2) & 0xc)\n shift_loads[6] = ((byte1 >> 2) & 0x3) | ((byte3 >> 0) & 0xc)\n shift_loads[7] = ((byte1 >> 0) & 0x3) | ((byte3 << 2) & 0xc)\n break\n\n // 256-Color Shift Mode\n // Video Modes 13h and unchained 256 color\n case 0x40:\n case 0x60:\n shift_loads[0] = (byte0 >> 4) & 0xf\n shift_loads[1] = (byte0 >> 0) & 0xf\n shift_loads[2] = (byte1 >> 4) & 0xf\n shift_loads[3] = (byte1 >> 0) & 0xf\n shift_loads[4] = (byte2 >> 4) & 0xf\n shift_loads[5] = (byte2 >> 0) & 0xf\n shift_loads[6] = (byte3 >> 4) & 0xf\n shift_loads[7] = (byte3 >> 0) & 0xf\n break\n }\n\n if (pel_width) {\n // Assemble from two sets of 4 bits.\n for (let i = 0, j = 0; i < 4; i++, pixel_addr++, j += 2) {\n this.pixel_buffer[pixel_addr] =\n (shift_loads[j] << 4) | shift_loads[j + 1]\n }\n } else {\n for (let i = 0; i < 8; i++, pixel_addr++) {\n this.pixel_buffer[pixel_addr] = shift_loads[i]\n }\n }\n }\n }\n\n // Transfers graphics from Pixel Buffer to Destination Image Buffer.\n // The 4-bit/8-bit color indices in the Pixel Buffer are passed through\n // the internal palette (dac_map) and the DAC palette (vga256_palette) to\n // obtain the final 32 bit color that the Canvas API uses.\n vga_redraw(): void {\n const start = this.diff_addr_min\n const end = Math.min(this.diff_addr_max, VGA_PIXEL_BUFFER_SIZE - 1)\n const buffer = new Int32Array(\n this.cpu.wasm_memory.buffer,\n this.dest_buffet_offset,\n this.virtual_width * this.virtual_height,\n )\n\n let mask = 0xff\n let colorset = 0x00\n if (this.attribute_mode & 0x80) {\n // Palette bits 5/4 select\n mask &= 0xcf\n colorset |= (this.color_select << 4) & 0x30\n }\n\n if (this.attribute_mode & 0x40) {\n // 8 bit mode\n\n for (let pixel_addr = start; pixel_addr <= end; pixel_addr++) {\n const color256 =\n (this.pixel_buffer[pixel_addr] & mask) | colorset\n const color = this.vga256_palette[color256]\n\n buffer[pixel_addr] =\n (color & 0xff00) |\n (color << 16) |\n (color >> 16) |\n 0xff000000\n }\n } else {\n // 4 bit mode\n\n // Palette bits 7/6 select\n mask &= 0x3f\n colorset |= (this.color_select << 4) & 0xc0\n\n for (let pixel_addr = start; pixel_addr <= end; pixel_addr++) {\n const color16 =\n this.pixel_buffer[pixel_addr] & this.color_plane_enable\n const color256 = (this.dac_map[color16] & mask) | colorset\n const color = this.vga256_palette[color256]\n\n buffer[pixel_addr] =\n (color & 0xff00) |\n (color << 16) |\n (color >> 16) |\n 0xff000000\n }\n }\n }\n\n screen_fill_buffer(): void {\n if (!this.graphical_mode) {\n // text mode\n // Update retrace behaviour anyway - programs waiting for signal before\n // changing to graphical mode\n this.update_vertical_retrace()\n return\n }\n\n if (this.image_data!.data.byteLength === 0) {\n // wasm memory resized\n const buffer = new Uint8ClampedArray(\n this.cpu.wasm_memory.buffer,\n this.dest_buffet_offset,\n 4 * this.virtual_width * this.virtual_height,\n )\n this.image_data = new ImageData(\n buffer,\n this.virtual_width,\n this.virtual_height,\n )\n this.update_layers()\n }\n\n if (this.svga_enabled) {\n let min_y = 0\n let max_y = this.svga_height\n\n if (this.svga_bpp === 8) {\n // XXX: Slow, should be ported to rust, but it doesn't have access to vga256_palette\n // XXX: Doesn't take svga_offset into account\n const buffer = new Int32Array(\n this.cpu.wasm_memory.buffer,\n this.dest_buffet_offset,\n this.screen_width * this.screen_height,\n )\n const svga_memory = new Uint8Array(\n this.cpu.wasm_memory.buffer,\n this.svga_memory.byteOffset,\n this.vga_memory_size,\n )\n\n for (let i = 0; i < buffer.length; i++) {\n const color = this.vga256_palette[svga_memory[i]]\n buffer[i] =\n (color & 0xff00) |\n (color << 16) |\n (color >> 16) |\n 0xff000000\n }\n } else {\n this.cpu.svga_fill_pixel_buffer(this.svga_bpp, this.svga_offset)\n\n const bytes_per_pixel =\n this.svga_bpp === 15 ? 2 : this.svga_bpp / 8\n min_y =\n ((((this.cpu.svga_dirty_bitmap_min_offset[0] /\n bytes_per_pixel) |\n 0) -\n this.svga_offset) /\n this.svga_width) |\n 0\n max_y =\n (((((this.cpu.svga_dirty_bitmap_max_offset[0] /\n bytes_per_pixel) |\n 0) -\n this.svga_offset) /\n this.svga_width) |\n 0) +\n 1\n }\n\n if (min_y < max_y) {\n min_y = Math.max(min_y, 0)\n max_y = Math.min(max_y, this.svga_height)\n\n this.screen.update_buffer([\n {\n image_data: this.image_data,\n screen_x: 0,\n screen_y: min_y,\n buffer_x: 0,\n buffer_y: min_y,\n buffer_width: this.svga_width,\n buffer_height: max_y - min_y,\n },\n ])\n }\n } else {\n this.vga_replot()\n this.vga_redraw()\n this.screen.update_buffer(this.layers)\n }\n\n this.reset_diffs()\n this.update_vertical_retrace()\n }\n\n set_font_bitmap(font_plane_dirty: boolean): void {\n const height = this.max_scan_line & 0x1f\n if (height && !this.graphical_mode) {\n const width_dbl = !!(this.clocking_mode & 0x08)\n const width_9px = !width_dbl && !(this.clocking_mode & 0x01)\n const copy_8th_col = !!(this.attribute_mode & 0x04)\n this.screen.set_font_bitmap(\n height + 1, // int height, font height 1..32px\n width_9px, // bool width_9px, True: font width 9px, else 8px\n width_dbl, // bool width_dbl, True: font width 16px (overrides width_9px)\n copy_8th_col, // bool copy_8th_col, True: duplicate 8th into 9th column in ASCII chars 0xC0-0xDF\n this.plane2, // Uint8Array font_bitmap[64k], static\n font_plane_dirty, // bool bitmap_changed, True: content of this.plane2 has changed\n )\n }\n }\n\n set_font_page(): void {\n // bits 2, 3 and 5 (LSB to MSB): VGA font page index of font A\n // bits 0, 1 and 4: VGA font page index of font B\n // linear_index_map[] maps VGA's non-liner font page index to linear index\n const linear_index_map = [0, 2, 4, 6, 1, 3, 5, 7]\n const vga_index_A =\n ((this.character_map_select & 0b1100) >> 2) |\n ((this.character_map_select & 0b100000) >> 3)\n const vga_index_B =\n (this.character_map_select & 0b11) |\n ((this.character_map_select & 0b10000) >> 2)\n this.font_page_ab_enabled = vga_index_A !== vga_index_B\n this.screen.set_font_page(\n linear_index_map[vga_index_A],\n linear_index_map[vga_index_B],\n )\n this.complete_redraw()\n }\n}\n", "// https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-2900003\n\nimport { LOG_PCI } from './const.js'\nimport { dbg_log } from './log.js'\nimport { VirtIO, VIRTIO_F_VERSION_1 } from './virtio.js'\nimport * as marshall from '../lib/marshall.js'\nimport { BusConnector } from './bus.js'\n\n// Minimal interface for the CPU fields VirtioBalloon needs\ninterface VirtioBalloonCPU {\n io: {\n register_read(\n port: number,\n device: object,\n r8?: ((port: number) => number) | undefined,\n r16?: ((port: number) => number) | undefined,\n r32?: ((port: number) => number) | undefined,\n ): void\n register_write(\n port: number,\n device: object,\n w8?: ((port: number) => void) | undefined,\n w16?: ((port: number) => void) | undefined,\n w32?: ((port: number) => void) | undefined,\n ): void\n }\n devices: {\n pci: {\n register_device(device: VirtIO): void\n raise_irq(pci_id: number): void\n lower_irq(pci_id: number): void\n }\n }\n read16(addr: number): number\n read32s(addr: number): number\n write16(addr: number, value: number): void\n write32(addr: number, value: number): void\n read_blob(addr: number, length: number): Uint8Array\n write_blob(blob: Uint8Array, addr: number): void\n zero_memory(addr: number, length: number): void\n memory_size: Int32Array\n}\n\nconst _VIRTIO_BALLOON_F_MUST_TELL_HOST = 0\nconst VIRTIO_BALLOON_F_STATS_VQ = 1\nconst _VIRTIO_BALLOON_F_DEFLATE_ON_OOM = 2\nconst VIRTIO_BALLOON_F_FREE_PAGE_HINT = 3\n\nconst STAT_NAMES: string[] = [\n 'SWAP_IN',\n 'SWAP_OUT',\n 'MAJFLT',\n 'MINFLT',\n 'MEMFREE',\n 'MEMTOT',\n 'AVAIL',\n 'CACHES',\n 'HTLB_PGALLOC',\n 'HTLB_PGFAIL',\n]\n\nexport class VirtioBalloon {\n bus: BusConnector\n num_pages: number\n actual: number\n fp_cmd: number\n zeroed: number\n virtio: VirtIO\n stats_cb: ((result: Record<string, number>) => void) | null\n free_cb: ((zeroed: number) => void) | null\n\n constructor(cpu: VirtioBalloonCPU, bus: BusConnector) {\n this.bus = bus\n this.num_pages = 0\n this.actual = 0\n this.fp_cmd = 0\n this.zeroed = 0\n this.stats_cb = null\n this.free_cb = null\n\n const queues = [\n { size_supported: 32, notify_offset: 0 },\n { size_supported: 32, notify_offset: 0 },\n { size_supported: 2, notify_offset: 1 },\n { size_supported: 64, notify_offset: 2 },\n ]\n\n //setInterval(() => this.GetStats(console.log.bind(console, \"STATS\")), 10000);\n\n this.virtio = new VirtIO(cpu, {\n name: 'virtio-balloon',\n pci_id: 0x0b << 3,\n device_id: 0x1045,\n subsystem_device_id: 5,\n common: {\n initial_port: 0xd800,\n queues: queues,\n features: [\n VIRTIO_BALLOON_F_STATS_VQ,\n VIRTIO_BALLOON_F_FREE_PAGE_HINT,\n VIRTIO_F_VERSION_1,\n ],\n on_driver_ok: () => {\n dbg_log('Balloon setup', LOG_PCI)\n },\n },\n notification: {\n initial_port: 0xd900,\n single_handler: false,\n handlers: [\n (queue_id: number) => {\n const queue = this.virtio.queues[queue_id]\n while (queue.has_request()) {\n const bufchain = queue.pop_request()\n const buffer = new Uint8Array(\n bufchain.length_readable,\n )\n bufchain.get_next_blob(buffer)\n this.virtio.queues[queue_id].push_reply(bufchain)\n const n = buffer.byteLength / 4\n this.actual += queue_id === 0 ? n : -n\n //console.log(queue_id === 0 ? \"Inflate\" : \"Deflate\", this.num_pages, this.actual, bufchain.read_buffers);\n }\n this.virtio.queues[queue_id].flush_replies()\n },\n (queue_id: number) => {\n const queue = this.virtio.queues[queue_id]\n if (queue.has_request()) {\n const bufchain = queue.pop_request()\n const buffer = new Uint8Array(\n bufchain.length_readable,\n )\n bufchain.get_next_blob(buffer)\n const result: Record<string, number> = {}\n for (\n let i = 0;\n i < bufchain.length_readable;\n i += 10\n ) {\n const [cat, value] = marshall.Unmarshall(\n ['h', 'd'],\n buffer,\n { offset: i },\n )\n result[STAT_NAMES[cat]] = value\n }\n this.virtio.queues[queue_id].push_reply(bufchain)\n if (this.stats_cb) this.stats_cb(result)\n }\n },\n (queue_id: number) => {\n const queue = this.virtio.queues[queue_id]\n while (queue.has_request()) {\n const bufchain = queue.pop_request()\n if (bufchain.length_readable > 0) {\n const buffer = new Uint8Array(\n bufchain.length_readable,\n )\n bufchain.get_next_blob(buffer)\n const [cmd] = marshall.Unmarshall(\n ['w'],\n buffer,\n {\n offset: 0,\n },\n )\n if (cmd === 0) {\n if (this.free_cb) this.free_cb(this.zeroed)\n if (this.fp_cmd > 1) this.fp_cmd = 1 // Signal done\n this.virtio.notify_config_changes()\n }\n }\n if (bufchain.length_writable > 0) {\n // console.log(\"Free pages hinted\", bufchain.read_buffers, bufchain.write_buffers);\n for (\n let i = 0;\n i < bufchain.write_buffers.length;\n ++i\n ) {\n const b = bufchain.write_buffers[i]\n this.zeroed += b.len\n this.virtio.cpu.zero_memory(\n b.addr_low,\n b.len,\n )\n }\n }\n this.virtio.queues[queue_id].push_reply(bufchain)\n }\n this.virtio.queues[queue_id].flush_replies()\n },\n ],\n },\n isr_status: {\n initial_port: 0xd700,\n },\n device_specific: {\n initial_port: 0xd600,\n struct: [\n {\n bytes: 4,\n name: 'num_pages',\n read: () => this.num_pages,\n write: (_data: number) => {\n /* read only */\n },\n },\n {\n bytes: 4,\n name: 'actual',\n read: () => {\n return this.actual\n },\n write: (_data: number) => {\n /* read only */\n },\n },\n {\n bytes: 4,\n name: 'free_page_hint_cmd_id',\n read: () => this.fp_cmd,\n write: (_data: number) => {\n /* read only */\n },\n },\n ],\n },\n })\n }\n\n Inflate(amount: number): void {\n this.num_pages += amount\n this.virtio.notify_config_changes()\n }\n\n Deflate(amount: number): void {\n this.num_pages -= amount\n this.virtio.notify_config_changes()\n }\n\n Cleanup(cb: (zeroed: number) => void): void {\n this.fp_cmd = 2\n this.free_cb = cb\n this.zeroed = 0\n this.virtio.notify_config_changes()\n }\n\n get_state(): any[] {\n const state: any[] = []\n state[0] = this.virtio\n state[1] = this.num_pages\n state[2] = this.actual\n return state\n }\n\n set_state(state: any[]): void {\n this.virtio.set_state(state[0])\n this.num_pages = state[1]\n this.actual = state[2]\n }\n\n GetStats(data: (result: Record<string, number>) => void): void {\n this.stats_cb = data\n const queue = this.virtio.queues[2]\n while (queue.has_request()) {\n const bufchain = queue.pop_request()\n this.virtio.queues[2].push_reply(bufchain)\n }\n this.virtio.queues[2].flush_replies()\n }\n\n Reset(): void {}\n}\n", "// -------------------------------------------------\n// ----------------- FILESYSTEM---------------------\n// -------------------------------------------------\n// Implementation of a unix filesystem in memory.\n\nimport { LOG_9P } from '../src/const.js'\nimport { h } from '../src/lib.js'\nimport { dbg_assert, dbg_log } from '../src/log.js'\nimport * as marshall from '../lib/marshall.js'\nimport { EEXIST, ENOTEMPTY, ENOENT, EPERM } from './9p.js'\nimport {\n P9_LOCK_SUCCESS,\n P9_LOCK_BLOCKED,\n P9_LOCK_TYPE_UNLCK,\n P9_LOCK_TYPE_WRLCK,\n P9_LOCK_TYPE_RDLCK,\n} from './9p.js'\n\nimport type { QID } from '../lib/marshall.js'\n\n// FileStorageInterface describes a backend for reading/writing file data.\nexport interface FileStorageInterface {\n read(\n sha256sum: string,\n offset: number,\n count: number,\n file_size: number,\n ): Promise<Uint8Array | null>\n cache(sha256sum: string, data: Uint8Array): Promise<void>\n uncache(sha256sum: string): void\n}\n\nexport const S_IRWXUGO = 0x1ff\nexport const S_IFMT = 0xf000\nexport const S_IFSOCK = 0xc000\nexport const S_IFLNK = 0xa000\nexport const S_IFREG = 0x8000\nexport const S_IFBLK = 0x6000\nexport const S_IFDIR = 0x4000\nexport const S_IFCHR = 0x2000\n\n//var S_IFIFO 0010000\n//var S_ISUID 0004000\n//var S_ISGID 0002000\n//var S_ISVTX 0001000\n\nconst _O_RDONLY = 0x0000 // open for reading only\nconst _O_WRONLY = 0x0001 // open for writing only\nconst _O_RDWR = 0x0002 // open for reading and writing\nconst _O_ACCMODE = 0x0003 // mask for above modes\n\nexport const STATUS_INVALID = -0x1\nexport const STATUS_OK = 0x0\nexport const STATUS_ON_STORAGE = 0x2\nexport const STATUS_UNLINKED = 0x4\nexport const STATUS_FORWARDING = 0x5\n\nconst texten = new TextEncoder()\n\nconst JSONFS_VERSION = 3\n\nconst JSONFS_IDX_NAME = 0\nconst JSONFS_IDX_SIZE = 1\nconst JSONFS_IDX_MTIME = 2\nconst JSONFS_IDX_MODE = 3\nconst JSONFS_IDX_UID = 4\nconst JSONFS_IDX_GID = 5\nconst JSONFS_IDX_TARGET = 6\nconst JSONFS_IDX_SHA256 = 6\n\nexport interface QIDCounter {\n last_qidnumber: number\n}\n\nexport interface SearchPathResult {\n id: number\n parentid: number\n name: string\n forward_path: string | null\n}\n\nexport class FSLockRegion {\n type: number = P9_LOCK_TYPE_UNLCK\n start: number = 0\n length: number = Infinity\n proc_id: number = -1\n client_id: string = ''\n\n get_state(): any[] {\n const state: (number | string)[] = []\n\n state[0] = this.type\n state[1] = this.start\n // Infinity is not JSON.stringify-able\n state[2] = this.length === Infinity ? 0 : this.length\n state[3] = this.proc_id\n state[4] = this.client_id\n\n return state\n }\n\n set_state(state: any[]): void {\n this.type = state[0]\n this.start = state[1]\n this.length = state[2] === 0 ? Infinity : state[2]\n this.proc_id = state[3]\n this.client_id = state[4]\n }\n\n clone(): FSLockRegion {\n const new_region = new FSLockRegion()\n new_region.set_state(this.get_state())\n return new_region\n }\n\n conflicts_with(region: FSLockRegion): boolean {\n if (\n this.proc_id === region.proc_id &&\n this.client_id === region.client_id\n )\n return false\n if (\n this.type === P9_LOCK_TYPE_UNLCK ||\n region.type === P9_LOCK_TYPE_UNLCK\n )\n return false\n if (\n this.type !== P9_LOCK_TYPE_WRLCK &&\n region.type !== P9_LOCK_TYPE_WRLCK\n )\n return false\n if (this.start + this.length <= region.start) return false\n if (region.start + region.length <= this.start) return false\n return true\n }\n\n is_alike(region: FSLockRegion): boolean {\n return (\n region.proc_id === this.proc_id &&\n region.client_id === this.client_id &&\n region.type === this.type\n )\n }\n\n may_merge_after(region: FSLockRegion): boolean {\n return (\n this.is_alike(region) && region.start + region.length === this.start\n )\n }\n}\n\nexport class Inode {\n direntries: Map<string, number> = new Map()\n status: number = 0\n size: number = 0x0\n uid: number = 0x0\n gid: number = 0x0\n fid: number = 0\n ctime: number = 0\n atime: number = 0\n mtime: number = 0\n major: number = 0x0\n minor: number = 0x0\n symlink: string = ''\n mode: number = 0x01ed\n qid: QID\n caps: Uint8Array | undefined = undefined\n nlinks: number = 0\n sha256sum: string = ''\n locks: FSLockRegion[] = []\n\n // For forwarders:\n mount_id: number = -1\n foreign_id: number = -1\n\n constructor(qidnumber: number) {\n this.qid = {\n type: 0,\n version: 0,\n path: qidnumber,\n }\n }\n\n get_state(): any[] {\n const state: any[] = []\n state[0] = this.mode\n\n if ((this.mode & S_IFMT) === S_IFDIR) {\n state[1] = [...this.direntries]\n } else if ((this.mode & S_IFMT) === S_IFREG) {\n state[1] = this.sha256sum\n } else if ((this.mode & S_IFMT) === S_IFLNK) {\n state[1] = this.symlink\n } else if ((this.mode & S_IFMT) === S_IFSOCK) {\n state[1] = [this.minor, this.major]\n } else {\n state[1] = null\n }\n\n state[2] = this.locks\n state[3] = this.status\n state[4] = this.size\n state[5] = this.uid\n state[6] = this.gid\n state[7] = this.fid\n state[8] = this.ctime\n state[9] = this.atime\n state[10] = this.mtime\n state[11] = this.qid.version\n state[12] = this.qid.path\n state[13] = this.nlinks\n\n //state[23] = this.mount_id;\n //state[24] = this.foreign_id;\n //state[25] = this.caps; // currently not writable\n return state\n }\n\n set_state(state: any[]): void {\n this.mode = state[0]\n\n if ((this.mode & S_IFMT) === S_IFDIR) {\n this.direntries = new Map()\n for (const [name, entry] of state[1]) {\n this.direntries.set(name, entry)\n }\n } else if ((this.mode & S_IFMT) === S_IFREG) {\n this.sha256sum = state[1]\n } else if ((this.mode & S_IFMT) === S_IFLNK) {\n this.symlink = state[1]\n } else if ((this.mode & S_IFMT) === S_IFSOCK) {\n ;[this.minor, this.major] = state[1]\n } else {\n // Nothing\n }\n\n this.locks = []\n for (const lock_state of state[2]) {\n const lock = new FSLockRegion()\n lock.set_state(lock_state)\n this.locks.push(lock)\n }\n this.status = state[3]\n this.size = state[4]\n this.uid = state[5]\n this.gid = state[6]\n this.fid = state[7]\n this.ctime = state[8]\n this.atime = state[9]\n this.mtime = state[10]\n this.qid.type = (this.mode & S_IFMT) >> 8\n this.qid.version = state[11]\n this.qid.path = state[12]\n this.nlinks = state[13]\n\n //this.mount_id = state[23];\n //this.foreign_id = state[24];\n //this.caps = state[20];\n }\n}\n\nclass FSMountInfo {\n fs: FS\n backtrack: Map<number, number>\n\n constructor(filesystem: FS) {\n this.fs = filesystem\n this.backtrack = new Map()\n }\n\n get_state(): any[] {\n const state: any[] = []\n\n state[0] = this.fs\n state[1] = [...this.backtrack]\n\n return state\n }\n\n set_state(state: any[]): void {\n this.fs = state[0]\n this.backtrack = new Map(state[1])\n }\n}\n\ninterface JsonFS {\n version: number\n\n fsroot: any[]\n size: number\n}\n\nexport class FS {\n inodes: Inode[]\n storage: FileStorageInterface\n qidcounter: QIDCounter\n inodedata: Record<number, Uint8Array>\n total_size: number\n used_size: number\n mounts: FSMountInfo[]\n\n constructor(storage: FileStorageInterface, qidcounter?: QIDCounter) {\n this.inodes = []\n this.storage = storage\n this.qidcounter = qidcounter || { last_qidnumber: 0 }\n this.inodedata = {}\n this.total_size = 256 * 1024 * 1024 * 1024\n this.used_size = 0\n this.mounts = []\n\n // root entry\n this.CreateDirectory('', -1)\n }\n\n get_state(): any[] {\n let state: any[] = []\n\n state[0] = this.inodes\n state[1] = this.qidcounter.last_qidnumber\n state[2] = []\n for (const [id, data] of Object.entries(this.inodedata)) {\n if ((this.inodes[Number(id)].mode & S_IFDIR) === 0) {\n state[2].push([id, data])\n }\n }\n state[3] = this.total_size\n state[4] = this.used_size\n state = state.concat(this.mounts)\n\n return state\n }\n\n set_state(state: any[]): void {\n this.inodes = state[0].map((s: any) => {\n const inode = new Inode(0)\n inode.set_state(s)\n return inode\n })\n this.qidcounter.last_qidnumber = state[1]\n this.inodedata = {}\n for (const [key, rawValue] of state[2]) {\n let value = rawValue\n if (value.buffer.byteLength !== value.byteLength) {\n // make a copy if we didn't get one\n value = value.slice()\n }\n\n this.inodedata[key] = value\n }\n this.total_size = state[3]\n this.used_size = state[4]\n this.mounts = state.slice(5)\n }\n\n // -----------------------------------------------------\n\n load_from_json(fs: JsonFS): void {\n dbg_assert(!!fs, 'Invalid fs passed to load_from_json')\n\n if (fs['version'] !== JSONFS_VERSION) {\n throw 'The filesystem JSON format has changed. Please recreate the filesystem JSON.'\n }\n\n const fsroot = fs['fsroot']\n this.used_size = fs['size']\n\n for (let i = 0; i < fsroot.length; i++) {\n this.LoadRecursive(fsroot[i], 0)\n }\n }\n\n private LoadRecursive(data: any[], parentid: number): void {\n const inode = this.CreateInode()\n\n const name = data[JSONFS_IDX_NAME]\n inode.size = data[JSONFS_IDX_SIZE]\n inode.mtime = data[JSONFS_IDX_MTIME]\n inode.ctime = inode.mtime\n inode.atime = inode.mtime\n inode.mode = data[JSONFS_IDX_MODE]\n inode.uid = data[JSONFS_IDX_UID]\n inode.gid = data[JSONFS_IDX_GID]\n\n const ifmt = inode.mode & S_IFMT\n\n if (ifmt === S_IFDIR) {\n this.PushInode(inode, parentid, name)\n this.LoadDir(this.inodes.length - 1, data[JSONFS_IDX_TARGET])\n } else if (ifmt === S_IFREG) {\n inode.status = STATUS_ON_STORAGE\n inode.sha256sum = data[JSONFS_IDX_SHA256]\n dbg_assert(!!inode.sha256sum)\n this.PushInode(inode, parentid, name)\n } else if (ifmt === S_IFLNK) {\n inode.symlink = data[JSONFS_IDX_TARGET]\n this.PushInode(inode, parentid, name)\n } else if (ifmt === S_IFSOCK) {\n // socket: ignore\n } else {\n dbg_log('Unexpected ifmt: ' + h(ifmt) + ' (' + name + ')', LOG_9P)\n }\n }\n\n private LoadDir(parentid: number, children: any[]): void {\n for (let i = 0; i < children.length; i++) {\n this.LoadRecursive(children[i], parentid)\n }\n }\n\n // -----------------------------------------------------\n\n private should_be_linked(inode: Inode): boolean {\n // Note: Non-root forwarder inode could still have a non-forwarder parent, so don't use\n // parent inode to check.\n return !this.is_forwarder(inode) || inode.foreign_id === 0\n }\n\n private link_under_dir(parentid: number, idx: number, name: string): void {\n const inode = this.inodes[idx]\n const parent_inode = this.inodes[parentid]\n\n dbg_assert(\n !this.is_forwarder(parent_inode),\n \"Filesystem: Shouldn't link under fowarder parents\",\n )\n dbg_assert(\n this.IsDirectory(parentid),\n \"Filesystem: Can't link under non-directories\",\n )\n dbg_assert(\n this.should_be_linked(inode),\n \"Filesystem: Can't link across filesystems apart from their root\",\n )\n dbg_assert(\n inode.nlinks >= 0,\n 'Filesystem: Found negative nlinks value of ' + inode.nlinks,\n )\n dbg_assert(\n !parent_inode.direntries.has(name),\n \"Filesystem: Name '\" + name + \"' is already taken\",\n )\n\n parent_inode.direntries.set(name, idx)\n inode.nlinks++\n\n if (this.IsDirectory(idx)) {\n dbg_assert(\n !inode.direntries.has('..'),\n 'Filesystem: Cannot link a directory twice',\n )\n\n if (!inode.direntries.has('.')) inode.nlinks++\n inode.direntries.set('.', idx)\n\n inode.direntries.set('..', parentid)\n parent_inode.nlinks++\n }\n }\n\n private unlink_from_dir(parentid: number, name: string): void {\n const idx = this.Search(parentid, name)\n const inode = this.inodes[idx]\n const parent_inode = this.inodes[parentid]\n\n dbg_assert(\n !this.is_forwarder(parent_inode),\n \"Filesystem: Can't unlink from forwarders\",\n )\n dbg_assert(\n this.IsDirectory(parentid),\n \"Filesystem: Can't unlink from non-directories\",\n )\n\n const exists = parent_inode.direntries.delete(name)\n if (!exists) {\n dbg_assert(\n false,\n \"Filesystem: Can't unlink non-existent file: \" + name,\n )\n return\n }\n\n inode.nlinks--\n\n if (this.IsDirectory(idx)) {\n dbg_assert(\n inode.direntries.get('..') === parentid,\n 'Filesystem: Found directory with bad parent id',\n )\n\n inode.direntries.delete('..')\n parent_inode.nlinks--\n }\n\n dbg_assert(\n inode.nlinks >= 0,\n 'Filesystem: Found negative nlinks value of ' + inode.nlinks,\n )\n }\n\n PushInode(inode: Inode, parentid: number, name: string): void {\n if (parentid !== -1) {\n this.inodes.push(inode)\n inode.fid = this.inodes.length - 1\n this.link_under_dir(parentid, inode.fid, name)\n return\n } else {\n if (this.inodes.length === 0) {\n // if root directory\n this.inodes.push(inode)\n inode.direntries.set('.', 0)\n inode.direntries.set('..', 0)\n inode.nlinks = 2\n return\n }\n }\n\n dbg_assert(\n false,\n 'Error in Filesystem: Pushed inode with name = ' +\n name +\n ' has no parent',\n )\n }\n\n private divert(parentid: number, filename: string): number {\n const old_idx = this.Search(parentid, filename)\n const old_inode = this.inodes[old_idx]\n const new_inode = new Inode(-1)\n\n dbg_assert(\n !!old_inode,\n 'Filesystem divert: name (' + filename + ') not found',\n )\n dbg_assert(\n this.IsDirectory(old_idx) || old_inode.nlinks <= 1,\n \"Filesystem: can't divert hardlinked file '\" +\n filename +\n \"' with nlinks=\" +\n old_inode.nlinks,\n )\n\n // Shallow copy is alright.\n Object.assign(new_inode, old_inode)\n\n const idx = this.inodes.length\n this.inodes.push(new_inode)\n new_inode.fid = idx\n\n // Relink references\n if (this.is_forwarder(old_inode)) {\n this.mounts[old_inode.mount_id].backtrack.set(\n old_inode.foreign_id,\n idx,\n )\n }\n if (this.should_be_linked(old_inode)) {\n this.unlink_from_dir(parentid, filename)\n this.link_under_dir(parentid, idx, filename)\n }\n\n // Update children\n if (this.IsDirectory(old_idx) && !this.is_forwarder(old_inode)) {\n for (const [name, child_id] of new_inode.direntries) {\n if (name === '.' || name === '..') continue\n if (this.IsDirectory(child_id)) {\n this.inodes[child_id].direntries.set('..', idx)\n }\n }\n }\n\n // Relocate local data if any.\n this.inodedata[idx] = this.inodedata[old_idx]\n delete this.inodedata[old_idx]\n\n // Retire old reference information.\n old_inode.direntries = new Map()\n old_inode.nlinks = 0\n\n return idx\n }\n\n private copy_inode(src_inode: Inode, dest_inode: Inode): void {\n Object.assign(dest_inode, src_inode, {\n fid: dest_inode.fid,\n direntries: dest_inode.direntries,\n nlinks: dest_inode.nlinks,\n })\n }\n\n CreateInode(): Inode {\n const now = Math.round(Date.now() / 1000)\n const inode = new Inode(++this.qidcounter.last_qidnumber)\n inode.atime = inode.ctime = inode.mtime = now\n return inode\n }\n\n // Note: parentid = -1 for initial root directory.\n CreateDirectory(name: string, parentid: number): number {\n const parent_inode = this.inodes[parentid]\n if (parentid >= 0 && this.is_forwarder(parent_inode)) {\n const foreign_parentid = parent_inode.foreign_id\n const foreign_id = this.follow_fs(parent_inode).CreateDirectory(\n name,\n foreign_parentid,\n )\n return this.create_forwarder(parent_inode.mount_id, foreign_id)\n }\n const x = this.CreateInode()\n x.mode = 0x01ff | S_IFDIR\n if (parentid >= 0) {\n x.uid = this.inodes[parentid].uid\n x.gid = this.inodes[parentid].gid\n x.mode = (this.inodes[parentid].mode & 0x1ff) | S_IFDIR\n }\n x.qid.type = S_IFDIR >> 8\n this.PushInode(x, parentid, name)\n this.NotifyListeners(this.inodes.length - 1, 'newdir')\n return this.inodes.length - 1\n }\n\n CreateFile(filename: string, parentid: number): number {\n const parent_inode = this.inodes[parentid]\n if (this.is_forwarder(parent_inode)) {\n const foreign_parentid = parent_inode.foreign_id\n const foreign_id = this.follow_fs(parent_inode).CreateFile(\n filename,\n foreign_parentid,\n )\n return this.create_forwarder(parent_inode.mount_id, foreign_id)\n }\n const x = this.CreateInode()\n x.uid = this.inodes[parentid].uid\n x.gid = this.inodes[parentid].gid\n x.qid.type = S_IFREG >> 8\n x.mode = (this.inodes[parentid].mode & 0x1b6) | S_IFREG\n this.PushInode(x, parentid, filename)\n this.NotifyListeners(this.inodes.length - 1, 'newfile')\n return this.inodes.length - 1\n }\n\n CreateNode(\n filename: string,\n parentid: number,\n major: number,\n minor: number,\n ): number {\n const parent_inode = this.inodes[parentid]\n if (this.is_forwarder(parent_inode)) {\n const foreign_parentid = parent_inode.foreign_id\n const foreign_id = this.follow_fs(parent_inode).CreateNode(\n filename,\n foreign_parentid,\n major,\n minor,\n )\n return this.create_forwarder(parent_inode.mount_id, foreign_id)\n }\n const x = this.CreateInode()\n x.major = major\n x.minor = minor\n x.uid = this.inodes[parentid].uid\n x.gid = this.inodes[parentid].gid\n x.qid.type = S_IFSOCK >> 8\n x.mode = this.inodes[parentid].mode & 0x1b6\n this.PushInode(x, parentid, filename)\n return this.inodes.length - 1\n }\n\n CreateSymlink(filename: string, parentid: number, symlink: string): number {\n const parent_inode = this.inodes[parentid]\n if (this.is_forwarder(parent_inode)) {\n const foreign_parentid = parent_inode.foreign_id\n const foreign_id = this.follow_fs(parent_inode).CreateSymlink(\n filename,\n foreign_parentid,\n symlink,\n )\n return this.create_forwarder(parent_inode.mount_id, foreign_id)\n }\n const x = this.CreateInode()\n x.uid = this.inodes[parentid].uid\n x.gid = this.inodes[parentid].gid\n x.qid.type = S_IFLNK >> 8\n x.symlink = symlink\n x.mode = S_IFLNK\n this.PushInode(x, parentid, filename)\n return this.inodes.length - 1\n }\n\n async CreateTextFile(\n filename: string,\n parentid: number,\n str: string,\n ): Promise<number> {\n const parent_inode = this.inodes[parentid]\n if (this.is_forwarder(parent_inode)) {\n const foreign_parentid = parent_inode.foreign_id\n const foreign_id = await this.follow_fs(\n parent_inode,\n ).CreateTextFile(filename, foreign_parentid, str)\n return this.create_forwarder(parent_inode.mount_id, foreign_id)\n }\n const id = this.CreateFile(filename, parentid)\n const x = this.inodes[id]\n const data = new Uint8Array(str.length)\n x.size = str.length\n for (let j = 0; j < str.length; j++) {\n data[j] = str.charCodeAt(j)\n }\n await this.set_data(id, data)\n return id\n }\n\n async CreateBinaryFile(\n filename: string,\n parentid: number,\n buffer: Uint8Array,\n ): Promise<number> {\n const parent_inode = this.inodes[parentid]\n if (this.is_forwarder(parent_inode)) {\n const foreign_parentid = parent_inode.foreign_id\n const foreign_id = await this.follow_fs(\n parent_inode,\n ).CreateBinaryFile(filename, foreign_parentid, buffer)\n return this.create_forwarder(parent_inode.mount_id, foreign_id)\n }\n const id = this.CreateFile(filename, parentid)\n const x = this.inodes[id]\n const data = new Uint8Array(buffer.length)\n data.set(buffer)\n await this.set_data(id, data)\n x.size = buffer.length\n return id\n }\n\n async OpenInode(id: number, mode: number | undefined): Promise<void> {\n const inode = this.inodes[id]\n if (this.is_forwarder(inode)) {\n return await this.follow_fs(inode).OpenInode(inode.foreign_id, mode)\n }\n if ((inode.mode & S_IFMT) === S_IFDIR) {\n this.FillDirectory(id)\n }\n }\n\n async CloseInode(id: number): Promise<void> {\n const inode = this.inodes[id]\n if (this.is_forwarder(inode)) {\n return await this.follow_fs(inode).CloseInode(inode.foreign_id)\n }\n if (inode.status === STATUS_ON_STORAGE) {\n this.storage.uncache(inode.sha256sum)\n }\n if (inode.status === STATUS_UNLINKED) {\n inode.status = STATUS_INVALID\n await this.DeleteData(id)\n }\n }\n\n async Rename(\n olddirid: number,\n oldname: string,\n newdirid: number,\n newname: string,\n ): Promise<number> {\n if (olddirid === newdirid && oldname === newname) {\n return 0\n }\n const oldid = this.Search(olddirid, oldname)\n if (oldid === -1) {\n return -ENOENT\n }\n\n // For event notification near end of method.\n const oldpath = this.GetFullPath(olddirid) + '/' + oldname\n\n const newid = this.Search(newdirid, newname)\n if (newid !== -1) {\n const ret = this.Unlink(newdirid, newname)\n if (ret < 0) return ret\n }\n\n const idx = oldid // idx contains the id which we want to rename\n const inode = this.inodes[idx]\n const olddir = this.inodes[olddirid]\n const newdir = this.inodes[newdirid]\n\n if (!this.is_forwarder(olddir) && !this.is_forwarder(newdir)) {\n // Move inode within current filesystem.\n\n this.unlink_from_dir(olddirid, oldname)\n this.link_under_dir(newdirid, idx, newname)\n\n inode.qid.version++\n } else if (\n this.is_forwarder(olddir) &&\n olddir.mount_id === newdir.mount_id\n ) {\n // Move inode within the same child filesystem.\n\n const ret = await this.follow_fs(olddir).Rename(\n olddir.foreign_id,\n oldname,\n newdir.foreign_id,\n newname,\n )\n\n if (ret < 0) return ret\n } else if (this.is_a_root(idx)) {\n // The actual inode is a root of some descendant filesystem.\n // Moving mountpoint across fs not supported - needs to update all corresponding forwarders.\n dbg_log(\n 'XXX: Attempted to move mountpoint (' + oldname + ') - skipped',\n LOG_9P,\n )\n return -EPERM\n } else if (!this.IsDirectory(idx) && this.GetInode(idx).nlinks > 1) {\n // Move hardlinked inode vertically in mount tree.\n dbg_log(\n 'XXX: Attempted to move hardlinked file (' +\n oldname +\n ') ' +\n 'across filesystems - skipped',\n LOG_9P,\n )\n return -EPERM\n } else {\n // Jump between filesystems.\n\n // Can't work with both old and new inode information without first diverting the old\n // information into a new idx value.\n const diverted_old_idx = this.divert(olddirid, oldname)\n const old_real_inode = this.GetInode(idx)\n\n const data = await this.Read(\n diverted_old_idx,\n 0,\n old_real_inode.size,\n )\n\n if (this.is_forwarder(newdir)) {\n // Create new inode.\n const foreign_fs = this.follow_fs(newdir)\n const foreign_id = this.IsDirectory(diverted_old_idx)\n ? foreign_fs.CreateDirectory(newname, newdir.foreign_id)\n : foreign_fs.CreateFile(newname, newdir.foreign_id)\n\n const new_real_inode = foreign_fs.GetInode(foreign_id)\n this.copy_inode(old_real_inode, new_real_inode)\n\n // Point to this new location.\n this.set_forwarder(idx, newdir.mount_id, foreign_id)\n } else {\n // Replace current forwarder with real inode.\n this.delete_forwarder(inode)\n this.copy_inode(old_real_inode, inode)\n\n // Link into new location in this filesystem.\n this.link_under_dir(newdirid, idx, newname)\n }\n\n // Rewrite data to newly created destination.\n await this.ChangeSize(idx, old_real_inode.size)\n if (data && data.length) {\n await this.Write(idx, 0, data.length, data)\n }\n\n // Move children to newly created destination.\n if (this.IsDirectory(idx)) {\n for (const child_filename of this.GetChildren(\n diverted_old_idx,\n )) {\n const ret = await this.Rename(\n diverted_old_idx,\n child_filename,\n idx,\n child_filename,\n )\n if (ret < 0) return ret\n }\n }\n\n // Perform destructive changes only after migration succeeded.\n await this.DeleteData(diverted_old_idx)\n const ret = this.Unlink(olddirid, oldname)\n if (ret < 0) return ret\n }\n\n this.NotifyListeners(idx, 'rename', { oldpath: oldpath })\n\n return 0\n }\n\n async Write(\n id: number,\n offset: number,\n count: number,\n buffer: Uint8Array | null,\n ): Promise<void> {\n this.NotifyListeners(id, 'write')\n const inode = this.inodes[id]\n\n if (this.is_forwarder(inode)) {\n const foreign_id = inode.foreign_id\n await this.follow_fs(inode).Write(foreign_id, offset, count, buffer)\n return\n }\n\n let data = await this.get_buffer(id)\n\n if (!data || data.length < offset + count) {\n await this.ChangeSize(id, Math.floor(((offset + count) * 3) / 2))\n inode.size = offset + count\n data = await this.get_buffer(id)\n } else if (inode.size < offset + count) {\n inode.size = offset + count\n }\n if (buffer && data) {\n data.set(buffer.subarray(0, count), offset)\n }\n if (data) {\n await this.set_data(id, data)\n }\n }\n\n async Read(\n inodeid: number,\n offset: number,\n count: number,\n ): Promise<Uint8Array | null> {\n const inode = this.inodes[inodeid]\n if (this.is_forwarder(inode)) {\n const foreign_id = inode.foreign_id\n return await this.follow_fs(inode).Read(foreign_id, offset, count)\n }\n\n return await this.get_data(inodeid, offset, count)\n }\n\n Search(parentid: number, name: string): number {\n const parent_inode = this.inodes[parentid]\n\n if (this.is_forwarder(parent_inode)) {\n const foreign_parentid = parent_inode.foreign_id\n const foreign_id = this.follow_fs(parent_inode).Search(\n foreign_parentid,\n name,\n )\n if (foreign_id === -1) return -1\n return this.get_forwarder(parent_inode.mount_id, foreign_id)\n }\n\n const childid = parent_inode.direntries.get(name)\n return childid === undefined ? -1 : childid\n }\n\n CountUsedInodes(): number {\n let count = this.inodes.length\n for (const { fs, backtrack } of this.mounts) {\n count += fs.CountUsedInodes()\n\n // Forwarder inodes don't count.\n count -= backtrack.size\n }\n return count\n }\n\n CountFreeInodes(): number {\n let count = 1024 * 1024\n for (const { fs } of this.mounts) {\n count += fs.CountFreeInodes()\n }\n return count\n }\n\n GetTotalSize(): number {\n let size = this.used_size\n for (const { fs } of this.mounts) {\n size += fs.GetTotalSize()\n }\n return size\n }\n\n GetSpace(): number {\n let size = this.total_size\n for (const { fs } of this.mounts) {\n size += fs.GetSpace()\n }\n return size\n }\n\n GetDirectoryName(idx: number): string {\n const parent_inode = this.inodes[this.GetParent(idx)]\n\n if (this.is_forwarder(parent_inode)) {\n return this.follow_fs(parent_inode).GetDirectoryName(\n this.inodes[idx].foreign_id,\n )\n }\n\n // Root directory.\n if (!parent_inode) return ''\n\n for (const [name, childid] of parent_inode.direntries) {\n if (childid === idx) return name\n }\n\n dbg_assert(\n false,\n \"Filesystem: Found directory inode whose parent doesn't link to it\",\n )\n return ''\n }\n\n GetFullPath(idx: number): string {\n dbg_assert(\n this.IsDirectory(idx),\n 'Filesystem: Cannot get full path of non-directory inode',\n )\n\n let path = ''\n\n while (idx !== 0) {\n path = '/' + this.GetDirectoryName(idx) + path\n idx = this.GetParent(idx)\n }\n return path.substring(1)\n }\n\n Link(parentid: number, targetid: number, name: string): number {\n if (this.IsDirectory(targetid)) {\n return -EPERM\n }\n\n const parent_inode = this.inodes[parentid]\n const inode = this.inodes[targetid]\n\n if (this.is_forwarder(parent_inode)) {\n if (\n !this.is_forwarder(inode) ||\n inode.mount_id !== parent_inode.mount_id\n ) {\n dbg_log(\n 'XXX: Attempted to hardlink a file into a child filesystem - skipped',\n LOG_9P,\n )\n return -EPERM\n }\n return this.follow_fs(parent_inode).Link(\n parent_inode.foreign_id,\n inode.foreign_id,\n name,\n )\n }\n\n if (this.is_forwarder(inode)) {\n dbg_log(\n 'XXX: Attempted to hardlink file across filesystems - skipped',\n LOG_9P,\n )\n return -EPERM\n }\n\n this.link_under_dir(parentid, targetid, name)\n return 0\n }\n\n Unlink(parentid: number, name: string): number {\n if (name === '.' || name === '..') {\n // Also guarantees that root cannot be deleted.\n return -EPERM\n }\n const idx = this.Search(parentid, name)\n const inode = this.inodes[idx]\n const parent_inode = this.inodes[parentid]\n\n // forward if necessary\n if (this.is_forwarder(parent_inode)) {\n dbg_assert(\n this.is_forwarder(inode),\n 'Children of forwarders should be forwarders',\n )\n\n const foreign_parentid = parent_inode.foreign_id\n return this.follow_fs(parent_inode).Unlink(foreign_parentid, name)\n\n // Keep the forwarder dangling - file is still accessible.\n }\n\n if (this.IsDirectory(idx) && !this.IsEmpty(idx)) {\n return -ENOTEMPTY\n }\n\n this.unlink_from_dir(parentid, name)\n\n if (inode.nlinks === 0) {\n // don't delete the content. The file is still accessible\n inode.status = STATUS_UNLINKED\n this.NotifyListeners(idx, 'delete')\n }\n return 0\n }\n\n async DeleteData(idx: number): Promise<void> {\n const inode = this.inodes[idx]\n if (this.is_forwarder(inode)) {\n await this.follow_fs(inode).DeleteData(inode.foreign_id)\n return\n }\n inode.size = 0\n delete this.inodedata[idx]\n }\n\n private async get_buffer(idx: number): Promise<Uint8Array | null> {\n const inode = this.inodes[idx]\n dbg_assert(\n !!inode,\n `Filesystem get_buffer: idx ${idx} does not point to an inode`,\n )\n\n if (this.inodedata[idx]) {\n return this.inodedata[idx]\n } else if (inode.status === STATUS_ON_STORAGE) {\n dbg_assert(\n !!inode.sha256sum,\n 'Filesystem get_data: found inode on server without sha256sum',\n )\n return await this.storage.read(\n inode.sha256sum,\n 0,\n inode.size,\n inode.size,\n )\n } else {\n return null\n }\n }\n\n private async get_data(\n idx: number,\n offset: number,\n count: number,\n ): Promise<Uint8Array | null> {\n const inode = this.inodes[idx]\n dbg_assert(\n !!inode,\n `Filesystem get_data: idx ${idx} does not point to an inode`,\n )\n\n if (this.inodedata[idx]) {\n return this.inodedata[idx].subarray(offset, offset + count)\n } else if (inode.status === STATUS_ON_STORAGE) {\n dbg_assert(\n !!inode.sha256sum,\n 'Filesystem get_data: found inode on server without sha256sum',\n )\n return await this.storage.read(\n inode.sha256sum,\n offset,\n count,\n inode.size,\n )\n } else {\n return null\n }\n }\n\n private async set_data(idx: number, buffer: Uint8Array): Promise<void> {\n // Current scheme: Save all modified buffers into local inodedata.\n this.inodedata[idx] = buffer\n if (this.inodes[idx].status === STATUS_ON_STORAGE) {\n this.inodes[idx].status = STATUS_OK\n this.storage.uncache(this.inodes[idx].sha256sum)\n }\n }\n\n GetInode(idx: number): Inode {\n dbg_assert(!isNaN(idx), 'Filesystem GetInode: NaN idx')\n dbg_assert(\n idx >= 0 && idx < this.inodes.length,\n 'Filesystem GetInode: out of range idx:' + idx,\n )\n\n const inode = this.inodes[idx]\n if (this.is_forwarder(inode)) {\n return this.follow_fs(inode).GetInode(inode.foreign_id)\n }\n\n return inode\n }\n\n async ChangeSize(idx: number, newsize: number): Promise<void> {\n const inode = this.GetInode(idx)\n const temp = await this.get_data(idx, 0, inode.size)\n if (newsize === inode.size) return\n const data = new Uint8Array(newsize)\n inode.size = newsize\n if (temp) {\n const size = Math.min(temp.length, inode.size)\n data.set(temp.subarray(0, size), 0)\n }\n await this.set_data(idx, data)\n }\n\n SearchPath(path: string): SearchPathResult {\n path = path.replace('//', '/')\n const walk = path.split('/')\n if (walk.length > 0 && walk[walk.length - 1].length === 0) walk.pop()\n if (walk.length > 0 && walk[0].length === 0) walk.shift()\n const n = walk.length\n\n let parentid = -1\n let id = 0\n let forward_path: string | null = null\n let i = 0\n for (i = 0; i < n; i++) {\n parentid = id\n id = this.Search(parentid, walk[i])\n if (!forward_path && this.is_forwarder(this.inodes[parentid])) {\n forward_path = '/' + walk.slice(i).join('/')\n }\n if (id === -1) {\n if (i < n - 1)\n return {\n id: -1,\n parentid: -1,\n name: walk[i],\n forward_path,\n }\n return {\n id: -1,\n parentid: parentid,\n name: walk[i],\n forward_path,\n }\n }\n }\n return { id: id, parentid: parentid, name: walk[i], forward_path }\n }\n\n // -----------------------------------------------------\n\n GetRecursiveList(\n dirid: number,\n list: { parentid: number; name: string }[],\n ): void {\n if (this.is_forwarder(this.inodes[dirid])) {\n const foreign_fs = this.follow_fs(this.inodes[dirid])\n const foreign_dirid = this.inodes[dirid].foreign_id\n const mount_id = this.inodes[dirid].mount_id\n\n const foreign_start = list.length\n foreign_fs.GetRecursiveList(foreign_dirid, list)\n for (let i = foreign_start; i < list.length; i++) {\n list[i].parentid = this.get_forwarder(\n mount_id,\n list[i].parentid,\n )\n }\n return\n }\n for (const [name, id] of this.inodes[dirid].direntries) {\n if (name !== '.' && name !== '..') {\n list.push({ parentid: dirid, name })\n if (this.IsDirectory(id)) {\n this.GetRecursiveList(id, list)\n }\n }\n }\n }\n\n RecursiveDelete(path: string): void {\n const toDelete: { parentid: number; name: string }[] = []\n const ids = this.SearchPath(path)\n if (ids.id === -1) return\n\n this.GetRecursiveList(ids.id, toDelete)\n\n for (let i = toDelete.length - 1; i >= 0; i--) {\n const ret = this.Unlink(toDelete[i].parentid, toDelete[i].name)\n dbg_assert(\n ret === 0,\n 'Filesystem RecursiveDelete failed at parent=' +\n toDelete[i].parentid +\n \", name='\" +\n toDelete[i].name +\n \"' with error code: \" +\n -ret,\n )\n }\n }\n\n DeleteNode(path: string): void {\n const ids = this.SearchPath(path)\n if (ids.id === -1) return\n\n if ((this.inodes[ids.id].mode & S_IFMT) === S_IFREG) {\n const ret = this.Unlink(ids.parentid, ids.name)\n dbg_assert(\n ret === 0,\n 'Filesystem DeleteNode failed with error code: ' + -ret,\n )\n } else if ((this.inodes[ids.id].mode & S_IFMT) === S_IFDIR) {\n this.RecursiveDelete(path)\n const ret = this.Unlink(ids.parentid, ids.name)\n dbg_assert(\n ret === 0,\n 'Filesystem DeleteNode failed with error code: ' + -ret,\n )\n }\n }\n\n NotifyListeners(_id: number, _action: string, _info?: any): void {\n //if(info==undefined)\n // info = {};\n //var path = this.GetFullPath(id);\n //if (this.watchFiles[path] === true && action=='write') {\n // message.Send(\"WatchFileEvent\", path);\n //}\n //for (var directory of this.watchDirectories) {\n // if (this.watchDirectories.hasOwnProperty(directory)) {\n // var indexOf = path.indexOf(directory)\n // if(indexOf === 0 || indexOf === 1)\n // message.Send(\"WatchDirectoryEvent\", {path: path, event: action, info: info});\n // }\n //}\n }\n\n Check(): void {\n for (let i = 1; i < this.inodes.length; i++) {\n if (this.inodes[i].status === STATUS_INVALID) continue\n\n const inode = this.GetInode(i)\n if (inode.nlinks < 0) {\n dbg_log(\n 'Error in filesystem: negative nlinks=' +\n inode.nlinks +\n ' at id =' +\n i,\n LOG_9P,\n )\n }\n\n if (this.IsDirectory(i)) {\n const inode = this.GetInode(i)\n if (this.IsDirectory(i) && this.GetParent(i) < 0) {\n dbg_log(\n 'Error in filesystem: negative parent id ' + i,\n LOG_9P,\n )\n }\n for (const [name, id] of inode.direntries) {\n if (name.length === 0) {\n dbg_log(\n 'Error in filesystem: inode with no name and id ' +\n id,\n LOG_9P,\n )\n }\n\n for (const c of name) {\n if (c < ' ') {\n dbg_log(\n 'Error in filesystem: Unallowed char in filename',\n LOG_9P,\n )\n }\n }\n }\n }\n }\n }\n\n FillDirectory(dirid: number): void {\n const inode = this.inodes[dirid]\n if (this.is_forwarder(inode)) {\n // XXX: The \"..\" of a mountpoint should point back to an inode in this fs.\n // Otherwise, \"..\" gets the wrong qid and mode.\n this.follow_fs(inode).FillDirectory(inode.foreign_id)\n return\n }\n\n let size = 0\n for (const name of inode.direntries.keys()) {\n size += 13 + 8 + 1 + 2 + texten.encode(name).length\n }\n const data = (this.inodedata[dirid] = new Uint8Array(size))\n inode.size = size\n\n let offset = 0x0\n for (const [name, id] of inode.direntries) {\n const child = this.GetInode(id)\n offset += marshall.Marshall(\n ['Q', 'd', 'b', 's'],\n [\n child.qid,\n offset + 13 + 8 + 1 + 2 + texten.encode(name).length,\n child.mode >> 12,\n name,\n ],\n data,\n offset,\n )\n }\n }\n\n RoundToDirentry(dirid: number, offset_target: number): number {\n const data = this.inodedata[dirid]\n dbg_assert(\n !!data,\n `FS directory data for dirid=${dirid} should be generated`,\n )\n dbg_assert(\n data.length > 0,\n 'FS directory should have at least an entry',\n )\n\n if (offset_target >= data.length) {\n return data.length\n }\n\n let offset = 0\n while (true) {\n const next_offset = marshall.Unmarshall(['Q', 'd'], data, {\n offset,\n })[1]\n if (next_offset > offset_target) break\n offset = next_offset\n }\n\n return offset\n }\n\n IsDirectory(idx: number): boolean {\n const inode = this.inodes[idx]\n if (this.is_forwarder(inode)) {\n return this.follow_fs(inode).IsDirectory(inode.foreign_id)\n }\n return (inode.mode & S_IFMT) === S_IFDIR\n }\n\n IsEmpty(idx: number): boolean {\n const inode = this.inodes[idx]\n if (this.is_forwarder(inode)) {\n return this.follow_fs(inode).IsDirectory(inode.foreign_id)\n }\n for (const name of inode.direntries.keys()) {\n if (name !== '.' && name !== '..') return false\n }\n return true\n }\n\n GetChildren(idx: number): string[] {\n dbg_assert(\n this.IsDirectory(idx),\n 'Filesystem: cannot get children of non-directory inode',\n )\n const inode = this.inodes[idx]\n if (this.is_forwarder(inode)) {\n return this.follow_fs(inode).GetChildren(inode.foreign_id)\n }\n const children: string[] = []\n for (const name of inode.direntries.keys()) {\n if (name !== '.' && name !== '..') {\n children.push(name)\n }\n }\n return children\n }\n\n GetParent(idx: number): number {\n dbg_assert(\n this.IsDirectory(idx),\n 'Filesystem: cannot get parent of non-directory inode',\n )\n\n const inode = this.inodes[idx]\n\n if (this.should_be_linked(inode)) {\n return inode.direntries.get('..') ?? -1\n } else {\n const foreign_dirid = this.follow_fs(inode).GetParent(\n inode.foreign_id,\n )\n dbg_assert(\n foreign_dirid !== -1,\n 'Filesystem: should not have invalid parent ids',\n )\n return this.get_forwarder(inode.mount_id, foreign_dirid)\n }\n }\n\n // -----------------------------------------------------\n\n // only support for security.capabilities\n PrepareCAPs(id: number): number {\n const inode = this.GetInode(id)\n if (inode.caps) return inode.caps.length\n inode.caps = new Uint8Array(20)\n // format is little endian\n // note: getxattr returns -EINVAL if using revision 1 format.\n // note: getxattr presents revision 3 as revision 2 when revision 3 is not needed.\n // magic_etc (revision=0x02: 20 bytes)\n inode.caps[0] = 0x00\n inode.caps[1] = 0x00\n inode.caps[2] = 0x00\n inode.caps[3] = 0x02\n\n // lower\n // permitted (first 32 capabilities)\n inode.caps[4] = 0xff\n inode.caps[5] = 0xff\n inode.caps[6] = 0xff\n inode.caps[7] = 0xff\n // inheritable (first 32 capabilities)\n inode.caps[8] = 0xff\n inode.caps[9] = 0xff\n inode.caps[10] = 0xff\n inode.caps[11] = 0xff\n\n // higher\n // permitted (last 6 capabilities)\n inode.caps[12] = 0x3f\n inode.caps[13] = 0x00\n inode.caps[14] = 0x00\n inode.caps[15] = 0x00\n // inheritable (last 6 capabilities)\n inode.caps[16] = 0x3f\n inode.caps[17] = 0x00\n inode.caps[18] = 0x00\n inode.caps[19] = 0x00\n\n return inode.caps.length\n }\n\n // -----------------------------------------------------\n\n private set_forwarder(\n idx: number,\n mount_id: number,\n foreign_id: number,\n ): void {\n const inode = this.inodes[idx]\n\n dbg_assert(\n inode.nlinks === 0,\n 'Filesystem: attempted to convert an inode into forwarder before unlinking the inode',\n )\n\n if (this.is_forwarder(inode)) {\n this.mounts[inode.mount_id].backtrack.delete(inode.foreign_id)\n }\n\n inode.status = STATUS_FORWARDING\n inode.mount_id = mount_id\n inode.foreign_id = foreign_id\n\n this.mounts[mount_id].backtrack.set(foreign_id, idx)\n }\n\n private create_forwarder(mount_id: number, foreign_id: number): number {\n const inode = this.CreateInode()\n\n const idx = this.inodes.length\n this.inodes.push(inode)\n inode.fid = idx\n\n this.set_forwarder(idx, mount_id, foreign_id)\n return idx\n }\n\n private is_forwarder(inode: Inode): boolean {\n return inode.status === STATUS_FORWARDING\n }\n\n private is_a_root(idx: number): boolean {\n return this.GetInode(idx).fid === 0\n }\n\n private get_forwarder(mount_id: number, foreign_id: number): number {\n const mount = this.mounts[mount_id]\n\n dbg_assert(\n foreign_id >= 0,\n 'Filesystem get_forwarder: invalid foreign_id: ' + foreign_id,\n )\n dbg_assert(\n !!mount,\n 'Filesystem get_forwarder: invalid mount number: ' + mount_id,\n )\n\n const result = mount.backtrack.get(foreign_id)\n\n if (result === undefined) {\n // Create if not already exists.\n return this.create_forwarder(mount_id, foreign_id)\n }\n\n return result\n }\n\n private delete_forwarder(inode: Inode): void {\n dbg_assert(\n this.is_forwarder(inode),\n 'Filesystem delete_forwarder: expected forwarder',\n )\n\n inode.status = STATUS_INVALID\n this.mounts[inode.mount_id].backtrack.delete(inode.foreign_id)\n }\n\n private follow_fs(inode: Inode): FS {\n const mount = this.mounts[inode.mount_id]\n\n dbg_assert(\n this.is_forwarder(inode),\n 'Filesystem follow_fs: inode should be a forwarding inode',\n )\n dbg_assert(\n !!mount,\n 'Filesystem follow_fs: inode<id=' +\n inode.fid +\n '> should point to valid mounted FS',\n )\n\n return mount.fs\n }\n\n Mount(path: string, fs: FS): number {\n dbg_assert(\n fs.qidcounter === this.qidcounter,\n \"Cannot mount filesystem whose qid numbers aren't synchronised with current filesystem.\",\n )\n\n const path_infos = this.SearchPath(path)\n\n if (path_infos.parentid === -1) {\n dbg_log('Mount failed: parent for path not found: ' + path, LOG_9P)\n return -ENOENT\n }\n if (path_infos.id !== -1) {\n dbg_log(\n 'Mount failed: file already exists at path: ' + path,\n LOG_9P,\n )\n return -EEXIST\n }\n if (path_infos.forward_path) {\n const parent = this.inodes[path_infos.parentid]\n const ret = this.follow_fs(parent).Mount(\n path_infos.forward_path,\n fs,\n )\n if (ret < 0) return ret\n return this.get_forwarder(parent.mount_id, ret)\n }\n\n const mount_id = this.mounts.length\n this.mounts.push(new FSMountInfo(fs))\n\n const idx = this.create_forwarder(mount_id, 0)\n this.link_under_dir(path_infos.parentid, idx, path_infos.name)\n\n return idx\n }\n\n DescribeLock(\n type: number,\n start: number,\n length: number,\n proc_id: number,\n client_id: string,\n ): FSLockRegion {\n dbg_assert(\n type === P9_LOCK_TYPE_RDLCK ||\n type === P9_LOCK_TYPE_WRLCK ||\n type === P9_LOCK_TYPE_UNLCK,\n 'Filesystem: Invalid lock type: ' + type,\n )\n dbg_assert(\n start >= 0,\n 'Filesystem: Invalid negative lock starting offset: ' + start,\n )\n dbg_assert(\n length > 0,\n 'Filesystem: Invalid non-positive lock length: ' + length,\n )\n\n const lock = new FSLockRegion()\n lock.type = type\n lock.start = start\n lock.length = length\n lock.proc_id = proc_id\n lock.client_id = client_id\n\n return lock\n }\n\n GetLock(id: number, request: FSLockRegion): FSLockRegion | null {\n const inode = this.inodes[id]\n\n if (this.is_forwarder(inode)) {\n const foreign_id = inode.foreign_id\n return this.follow_fs(inode).GetLock(foreign_id, request)\n }\n\n for (const region of inode.locks) {\n if (request.conflicts_with(region)) {\n return region.clone()\n }\n }\n return null\n }\n\n Lock(id: number, request: FSLockRegion, flags: number): number {\n const inode = this.inodes[id]\n\n if (this.is_forwarder(inode)) {\n const foreign_id = inode.foreign_id\n return this.follow_fs(inode).Lock(foreign_id, request, flags)\n }\n\n request = request.clone()\n\n // (1) Check whether lock is possible before any modification.\n if (request.type !== P9_LOCK_TYPE_UNLCK && this.GetLock(id, request)) {\n return P9_LOCK_BLOCKED\n }\n\n // (2) Subtract requested region from locks of the same owner.\n for (let i = 0; i < inode.locks.length; i++) {\n const region = inode.locks[i]\n\n dbg_assert(\n region.length > 0,\n 'Filesystem: Found non-positive lock region length: ' +\n region.length,\n )\n dbg_assert(\n region.type === P9_LOCK_TYPE_RDLCK ||\n region.type === P9_LOCK_TYPE_WRLCK,\n 'Filesystem: Found invalid lock type: ' + region.type,\n )\n dbg_assert(\n !inode.locks[i - 1] || inode.locks[i - 1].start <= region.start,\n 'Filesystem: Locks should be sorted by starting offset',\n )\n\n // Skip to requested region.\n if (region.start + region.length <= request.start) continue\n\n // Check whether we've skipped past the requested region.\n if (request.start + request.length <= region.start) break\n\n // Skip over locks of different owners.\n if (\n region.proc_id !== request.proc_id ||\n region.client_id !== request.client_id\n ) {\n dbg_assert(\n !region.conflicts_with(request),\n 'Filesytem: Found conflicting lock region, despite already checked for conflicts',\n )\n continue\n }\n\n // Pretend region would be split into parts 1 and 2.\n const start1 = region.start\n const start2 = request.start + request.length\n const length1 = request.start - start1\n const length2 = region.start + region.length - start2\n\n if (length1 > 0 && length2 > 0 && region.type === request.type) {\n // Requested region is already locked with the required type.\n // Return early - no need to modify anything.\n return P9_LOCK_SUCCESS\n }\n\n if (length1 > 0) {\n // Shrink from right / first half of the split.\n region.length = length1\n }\n\n if (length1 <= 0 && length2 > 0) {\n // Shrink from left.\n region.start = start2\n region.length = length2\n } else if (length2 > 0) {\n // Add second half of the split.\n\n // Fast-forward to correct location.\n while (i < inode.locks.length && inode.locks[i].start < start2)\n i++\n\n inode.locks.splice(\n i,\n 0,\n this.DescribeLock(\n region.type,\n start2,\n length2,\n region.proc_id,\n region.client_id,\n ),\n )\n } else if (length1 <= 0) {\n // Requested region completely covers this region. Delete.\n inode.locks.splice(i, 1)\n i--\n }\n }\n\n // (3) Insert requested lock region as a whole.\n // No point in adding the requested lock region as fragmented bits in the above loop\n // and having to merge them all back into one.\n if (request.type !== P9_LOCK_TYPE_UNLCK) {\n let new_region = request\n let has_merged = false\n let i = 0\n\n // Fast-forward to requested position, and try merging with previous region.\n for (; i < inode.locks.length; i++) {\n if (new_region.may_merge_after(inode.locks[i])) {\n inode.locks[i].length += request.length\n new_region = inode.locks[i]\n has_merged = true\n }\n if (request.start <= inode.locks[i].start) break\n }\n\n if (!has_merged) {\n inode.locks.splice(i, 0, new_region)\n i++\n }\n\n // Try merging with the subsequent alike region.\n for (; i < inode.locks.length; i++) {\n if (!inode.locks[i].is_alike(new_region)) continue\n\n if (inode.locks[i].may_merge_after(new_region)) {\n new_region.length += inode.locks[i].length\n inode.locks.splice(i, 1)\n }\n\n // No more mergable regions after this.\n break\n }\n }\n\n return P9_LOCK_SUCCESS\n }\n\n read_dir(path: string): string[] | undefined {\n const p = this.SearchPath(path)\n\n if (p.id === -1) {\n return undefined\n }\n\n const dir = this.GetInode(p.id)\n\n return Array.from(dir.direntries.keys()).filter(\n (path) => path !== '.' && path !== '..',\n )\n }\n\n read_file(file: string): Promise<Uint8Array | null> {\n const p = this.SearchPath(file)\n\n if (p.id === -1) {\n return Promise.resolve(null)\n }\n\n const inode = this.GetInode(p.id)\n\n return this.Read(p.id, 0, inode.size)\n }\n}\n", "// -------------------------------------------------\n// --------------------- 9P ------------------------\n// -------------------------------------------------\n// Implementation of the 9p filesystem device following the\n// 9P2000.L protocol ( https://code.google.com/p/diod/wiki/protocol )\n\nimport { LOG_9P } from './../src/const.js'\nimport {\n VirtIO,\n VirtQueue,\n VirtQueueBufferChain,\n VIRTIO_F_VERSION_1,\n VIRTIO_F_RING_EVENT_IDX,\n VIRTIO_F_RING_INDIRECT_DESC,\n} from '../src/virtio.js'\nimport { S_IFREG, S_IFDIR, STATUS_UNLINKED } from './filesystem.js'\nimport * as marshall from '../lib/marshall.js'\nimport { dbg_log, dbg_assert } from '../src/log.js'\nimport { h } from '../src/lib.js'\n\nimport type { CPU } from '../src/cpu.js'\nimport type { BusConnector } from '../src/bus.js'\nimport type { FS } from './filesystem.js'\n\n// More accurate filenames in 9p debug messages at the cost of performance.\nconst TRACK_FILENAMES = false\n\n// Feature bit (bit position) for mount tag.\nconst VIRTIO_9P_F_MOUNT_TAG = 0\n// Assumed max tag length in bytes.\nconst VIRTIO_9P_MAX_TAGLEN = 254\n\nconst MAX_REPLYBUFFER_SIZE = 16 * 1024 * 1024\n\nexport const EPERM = 1 /* Operation not permitted */\nexport const ENOENT = 2 /* No such file or directory */\nexport const EEXIST = 17 /* File exists */\nexport const EINVAL = 22 /* Invalid argument */\nexport const EOPNOTSUPP = 95 /* Operation is not supported */\nexport const ENOTEMPTY = 39 /* Directory not empty */\nexport const EPROTO = 71 /* Protocol error */\n\nconst P9_SETATTR_MODE = 0x00000001\nconst P9_SETATTR_UID = 0x00000002\nconst P9_SETATTR_GID = 0x00000004\nconst P9_SETATTR_SIZE = 0x00000008\nconst P9_SETATTR_ATIME = 0x00000010\nconst P9_SETATTR_MTIME = 0x00000020\nconst P9_SETATTR_CTIME = 0x00000040\nconst P9_SETATTR_ATIME_SET = 0x00000080\nconst P9_SETATTR_MTIME_SET = 0x00000100\n\nconst _P9_STAT_MODE_DIR = 0x80000000\nconst _P9_STAT_MODE_APPEND = 0x40000000\nconst _P9_STAT_MODE_EXCL = 0x20000000\nconst _P9_STAT_MODE_MOUNT = 0x10000000\nconst _P9_STAT_MODE_AUTH = 0x08000000\nconst _P9_STAT_MODE_TMP = 0x04000000\nconst _P9_STAT_MODE_SYMLINK = 0x02000000\nconst _P9_STAT_MODE_LINK = 0x01000000\nconst _P9_STAT_MODE_DEVICE = 0x00800000\nconst _P9_STAT_MODE_NAMED_PIPE = 0x00200000\nconst _P9_STAT_MODE_SOCKET = 0x00100000\nconst _P9_STAT_MODE_SETUID = 0x00080000\nconst _P9_STAT_MODE_SETGID = 0x00040000\nconst _P9_STAT_MODE_SETVTX = 0x00010000\n\nexport const P9_LOCK_TYPE_RDLCK = 0\nexport const P9_LOCK_TYPE_WRLCK = 1\nexport const P9_LOCK_TYPE_UNLCK = 2\nconst P9_LOCK_TYPES = ['shared', 'exclusive', 'unlock']\n\nconst _P9_LOCK_FLAGS_BLOCK = 1\nconst _P9_LOCK_FLAGS_RECLAIM = 2\n\nexport const P9_LOCK_SUCCESS = 0\nexport const P9_LOCK_BLOCKED = 1\nexport const P9_LOCK_ERROR = 2\nexport const P9_LOCK_GRACE = 3\n\nconst FID_NONE = -1\nconst FID_INODE = 1\nconst FID_XATTR = 2\n\ninterface Fid {\n inodeid: number\n type: number\n uid: number\n dbg_name: string\n}\n\ntype P9Handler = (\n reqbuf: Uint8Array,\n reply: (replybuf: Uint8Array) => void,\n) => void\n\nfunction range(size: number): number[] {\n return Array.from(Array(size).keys())\n}\n\nfunction init_virtio(\n cpu: CPU,\n configspace_taglen: number,\n configspace_tagname: number[],\n receive: (bufchain: VirtQueueBufferChain) => void,\n): VirtIO {\n const virtio = new VirtIO(cpu, {\n name: 'virtio-9p',\n pci_id: 0x06 << 3,\n device_id: 0x1049,\n subsystem_device_id: 9,\n common: {\n initial_port: 0xa800,\n queues: [\n {\n size_supported: 32,\n notify_offset: 0,\n },\n ],\n features: [\n VIRTIO_9P_F_MOUNT_TAG,\n VIRTIO_F_VERSION_1,\n VIRTIO_F_RING_EVENT_IDX,\n VIRTIO_F_RING_INDIRECT_DESC,\n ],\n on_driver_ok: () => {},\n },\n notification: {\n initial_port: 0xa900,\n single_handler: false,\n handlers: [\n (queue_id: number) => {\n if (queue_id !== 0) {\n dbg_assert(\n false,\n 'Virtio9P Notified for non-existent queue: ' +\n queue_id +\n ' (expected queue_id of 0)',\n )\n return\n }\n const virtqueue = virtio.queues[0]\n while (virtqueue.has_request()) {\n const bufchain = virtqueue.pop_request()\n receive(bufchain)\n }\n virtqueue.notify_me_after(0)\n // Don't flush replies here: async replies are not completed yet.\n },\n ],\n },\n isr_status: {\n initial_port: 0xa700,\n },\n device_specific: {\n initial_port: 0xa600,\n struct: [\n {\n bytes: 2,\n name: 'mount tag length',\n read: () => configspace_taglen,\n write: (_data: number) => {\n /* read only */\n },\n },\n ].concat(\n range(VIRTIO_9P_MAX_TAGLEN).map((index) => ({\n bytes: 1,\n name: 'mount tag name ' + index,\n // Note: configspace_tagname may have changed after set_state\n read: () => configspace_tagname[index] || 0,\n write: (_data: number) => {\n /* read only */\n },\n })),\n ),\n },\n })\n return virtio\n}\n\nexport class Virtio9p {\n fs: FS\n bus: BusConnector\n configspace_tagname: number[]\n configspace_taglen: number\n virtio: VirtIO\n virtqueue: VirtQueue\n VERSION: string\n BLOCKSIZE: number\n msize: number\n replybuffer: Uint8Array\n replybuffersize: number\n fids: Fid[]\n\n constructor(filesystem: FS, cpu: CPU, bus: BusConnector) {\n this.fs = filesystem\n this.bus = bus\n\n this.configspace_tagname = [0x68, 0x6f, 0x73, 0x74, 0x39, 0x70] // \"host9p\" string\n this.configspace_taglen = this.configspace_tagname.length // num bytes\n\n this.virtio = init_virtio(\n cpu,\n this.configspace_taglen,\n this.configspace_tagname,\n this.ReceiveRequest.bind(this),\n )\n this.virtqueue = this.virtio.queues[0]\n\n this.VERSION = '9P2000.L'\n this.BLOCKSIZE = 8192 // Let's define one page.\n this.msize = 8192 // maximum message size\n this.replybuffer = new Uint8Array(this.msize * 2) // Twice the msize to stay on the safe site\n this.replybuffersize = 0\n this.fids = []\n }\n\n get_state(): any[] {\n const state: any[] = []\n\n state[0] = this.configspace_tagname\n state[1] = this.configspace_taglen\n state[2] = this.virtio\n state[3] = this.VERSION\n state[4] = this.BLOCKSIZE\n state[5] = this.msize\n state[6] = this.replybuffer\n state[7] = this.replybuffersize\n state[8] = this.fids.map(function (f) {\n return [f.inodeid, f.type, f.uid, f.dbg_name]\n })\n state[9] = this.fs\n\n return state\n }\n\n set_state(state: any[]): void {\n this.configspace_tagname = state[0]\n this.configspace_taglen = state[1]\n this.virtio.set_state(state[2])\n this.virtqueue = this.virtio.queues[0]\n this.VERSION = state[3]\n this.BLOCKSIZE = state[4]\n this.msize = state[5]\n this.replybuffer = state[6]\n this.replybuffersize = state[7]\n\n this.fids = state[8].map(function (f: any[]) {\n return { inodeid: f[0], type: f[1], uid: f[2], dbg_name: f[3] }\n })\n this.fs.set_state(state[9])\n }\n\n // Note: dbg_name is only used for debugging messages and may not be the same as the filename,\n // since it is not synchronised with renames done outside of 9p. Hard-links, linking and unlinking\n // operations also mean that having a single filename no longer makes sense.\n // Set TRACK_FILENAMES = true to sync dbg_name during 9p renames.\n Createfid(\n inodeid: number,\n type: number,\n uid: number,\n dbg_name: string,\n ): Fid {\n return { inodeid, type, uid, dbg_name }\n }\n\n update_dbg_name(idx: number, newname: string): void {\n for (const fid of this.fids) {\n if (fid.inodeid === idx) fid.dbg_name = newname\n }\n }\n\n reset(): void {\n this.fids = []\n this.virtio.reset()\n }\n\n BuildReply(id: number, tag: number, payloadsize: number): void {\n dbg_assert(payloadsize >= 0, '9P: Negative payload size')\n marshall.Marshall(\n ['w', 'b', 'h'],\n [payloadsize + 7, id + 1, tag],\n this.replybuffer,\n 0,\n )\n if (payloadsize + 7 >= this.replybuffer.length) {\n dbg_log('Error in 9p: payloadsize exceeds maximum length', LOG_9P)\n }\n this.replybuffersize = payloadsize + 7\n }\n\n SendError(tag: number, errormsg: string, errorcode: number): void {\n const size = marshall.Marshall(['w'], [errorcode], this.replybuffer, 7)\n this.BuildReply(6, tag, size)\n }\n\n SendReply(bufchain: VirtQueueBufferChain): void {\n dbg_assert(this.replybuffersize >= 0, '9P: Negative replybuffersize')\n bufchain.set_next_blob(\n this.replybuffer.subarray(0, this.replybuffersize),\n )\n this.virtqueue.push_reply(bufchain)\n this.virtqueue.flush_replies()\n }\n\n async ReceiveRequest(bufchain: VirtQueueBufferChain): Promise<void> {\n // TODO: split into header + data blobs to avoid unnecessary copying.\n const buffer = new Uint8Array(bufchain.length_readable)\n bufchain.get_next_blob(buffer)\n\n const state = { offset: 0 }\n const header = marshall.Unmarshall(['w', 'b', 'h'], buffer, state)\n let size = header[0]\n const id = header[1]\n const tag = header[2]\n\n switch (id) {\n case 8: {\n // statfs\n size = this.fs.GetTotalSize() // size used by all files\n const space = this.fs.GetSpace()\n\n const req: any[] = []\n req[0] = 0x01021997\n req[1] = this.BLOCKSIZE // optimal transfer block size\n req[2] = Math.floor(space / req[1]) // free blocks\n req[3] = req[2] - Math.floor(size / req[1]) // free blocks in fs\n req[4] = req[2] - Math.floor(size / req[1]) // free blocks avail to non-superuser\n req[5] = this.fs.CountUsedInodes() // total number of inodes\n req[6] = this.fs.CountFreeInodes()\n req[7] = 0 // file system id?\n req[8] = 256 // maximum length of filenames\n\n size = marshall.Marshall(\n ['w', 'w', 'd', 'd', 'd', 'd', 'd', 'd', 'w'],\n req,\n this.replybuffer,\n 7,\n )\n this.BuildReply(id, tag, size)\n this.SendReply(bufchain)\n break\n }\n\n case 112: // topen\n case 12: {\n // tlopen\n let req = marshall.Unmarshall(['w', 'w'], buffer, state)\n const fid = req[0]\n const mode = req[1]\n dbg_log('[open] fid=' + fid + ', mode=' + mode, LOG_9P)\n const idx = this.fids[fid].inodeid\n const inode = this.fs.GetInode(idx)\n dbg_log(\n 'file open ' + this.fids[fid].dbg_name + ' tag:' + tag,\n LOG_9P,\n )\n await this.fs.OpenInode(idx, mode)\n\n req = []\n req[0] = inode.qid\n req[1] = this.msize - 24\n marshall.Marshall(['Q', 'w'], req, this.replybuffer, 7)\n this.BuildReply(id, tag, 13 + 4)\n this.SendReply(bufchain)\n break\n }\n\n case 70: {\n // link\n const req = marshall.Unmarshall(['w', 'w', 's'], buffer, state)\n const dfid = req[0]\n const fid = req[1]\n const name = req[2]\n dbg_log('[link] dfid=' + dfid + ', name=' + name, LOG_9P)\n\n const ret = this.fs.Link(\n this.fids[dfid].inodeid,\n this.fids[fid].inodeid,\n name,\n )\n\n if (ret < 0) {\n let error_message = ''\n if (ret === -EPERM)\n error_message = 'Operation not permitted'\n else {\n error_message = 'Unknown error: ' + -ret\n dbg_assert(\n false,\n '[link]: Unexpected error code: ' + -ret,\n )\n }\n this.SendError(tag, error_message, -ret)\n this.SendReply(bufchain)\n break\n }\n\n this.BuildReply(id, tag, 0)\n this.SendReply(bufchain)\n break\n }\n\n case 16: {\n // symlink\n const req = marshall.Unmarshall(\n ['w', 's', 's', 'w'],\n buffer,\n state,\n )\n const fid = req[0]\n const name = req[1]\n const symgt = req[2]\n const gid = req[3]\n dbg_log(\n '[symlink] fid=' +\n fid +\n ', name=' +\n name +\n ', symgt=' +\n symgt +\n ', gid=' +\n gid,\n LOG_9P,\n )\n const idx = this.fs.CreateSymlink(\n name,\n this.fids[fid].inodeid,\n symgt,\n )\n const inode = this.fs.GetInode(idx)\n inode.uid = this.fids[fid].uid\n inode.gid = gid\n marshall.Marshall(['Q'], [inode.qid], this.replybuffer, 7)\n this.BuildReply(id, tag, 13)\n this.SendReply(bufchain)\n break\n }\n\n case 18: {\n // mknod\n const req = marshall.Unmarshall(\n ['w', 's', 'w', 'w', 'w', 'w'],\n buffer,\n state,\n )\n const fid = req[0]\n const name = req[1]\n const mode = req[2]\n const major = req[3]\n const minor = req[4]\n const gid = req[5]\n dbg_log(\n '[mknod] fid=' +\n fid +\n ', name=' +\n name +\n ', major=' +\n major +\n ', minor=' +\n minor +\n '',\n LOG_9P,\n )\n const idx = this.fs.CreateNode(\n name,\n this.fids[fid].inodeid,\n major,\n minor,\n )\n const inode = this.fs.GetInode(idx)\n inode.mode = mode\n //inode.mode = mode | S_IFCHR; // XXX: fails \"Mknod - fifo\" test\n inode.uid = this.fids[fid].uid\n inode.gid = gid\n marshall.Marshall(['Q'], [inode.qid], this.replybuffer, 7)\n this.BuildReply(id, tag, 13)\n this.SendReply(bufchain)\n break\n }\n\n case 22: {\n // TREADLINK\n const req = marshall.Unmarshall(['w'], buffer, state)\n const fid = req[0]\n const inode = this.fs.GetInode(this.fids[fid].inodeid)\n dbg_log(\n '[readlink] fid=' +\n fid +\n ' name=' +\n this.fids[fid].dbg_name +\n ' target=' +\n inode.symlink,\n LOG_9P,\n )\n size = marshall.Marshall(\n ['s'],\n [inode.symlink],\n this.replybuffer,\n 7,\n )\n this.BuildReply(id, tag, size)\n this.SendReply(bufchain)\n break\n }\n\n case 72: {\n // tmkdir\n const req = marshall.Unmarshall(\n ['w', 's', 'w', 'w'],\n buffer,\n state,\n )\n const fid = req[0]\n const name = req[1]\n const mode = req[2]\n const gid = req[3]\n dbg_log(\n '[mkdir] fid=' +\n fid +\n ', name=' +\n name +\n ', mode=' +\n mode +\n ', gid=' +\n gid,\n LOG_9P,\n )\n const idx = this.fs.CreateDirectory(\n name,\n this.fids[fid].inodeid,\n )\n const inode = this.fs.GetInode(idx)\n inode.mode = mode | S_IFDIR\n inode.uid = this.fids[fid].uid\n inode.gid = gid\n marshall.Marshall(['Q'], [inode.qid], this.replybuffer, 7)\n this.BuildReply(id, tag, 13)\n this.SendReply(bufchain)\n break\n }\n\n case 14: {\n // tlcreate\n const req = marshall.Unmarshall(\n ['w', 's', 'w', 'w', 'w'],\n buffer,\n state,\n )\n const fid = req[0]\n const name = req[1]\n const flags = req[2]\n const mode = req[3]\n const gid = req[4]\n this.bus.send('9p-create', [name, this.fids[fid].inodeid])\n dbg_log(\n '[create] fid=' +\n fid +\n ', name=' +\n name +\n ', flags=' +\n flags +\n ', mode=' +\n mode +\n ', gid=' +\n gid,\n LOG_9P,\n )\n const idx = this.fs.CreateFile(name, this.fids[fid].inodeid)\n this.fids[fid].inodeid = idx\n this.fids[fid].type = FID_INODE\n this.fids[fid].dbg_name = name\n const inode = this.fs.GetInode(idx)\n inode.uid = this.fids[fid].uid\n inode.gid = gid\n inode.mode = mode | S_IFREG\n marshall.Marshall(\n ['Q', 'w'],\n [inode.qid, this.msize - 24],\n this.replybuffer,\n 7,\n )\n this.BuildReply(id, tag, 13 + 4)\n this.SendReply(bufchain)\n break\n }\n\n case 52: {\n // lock\n const req = marshall.Unmarshall(\n ['w', 'b', 'w', 'd', 'd', 'w', 's'],\n buffer,\n state,\n )\n const fid = req[0]\n const flags = req[2]\n const lock_length = req[4] === 0 ? Infinity : req[4]\n const lock_request = this.fs.DescribeLock(\n req[1],\n req[3],\n lock_length,\n req[5],\n req[6],\n )\n dbg_log(\n '[lock] fid=' +\n fid +\n ', type=' +\n P9_LOCK_TYPES[lock_request.type] +\n ', start=' +\n lock_request.start +\n ', length=' +\n lock_request.length +\n ', proc_id=' +\n lock_request.proc_id,\n )\n\n const ret = this.fs.Lock(\n this.fids[fid].inodeid,\n lock_request,\n flags,\n )\n\n marshall.Marshall(['b'], [ret], this.replybuffer, 7)\n this.BuildReply(id, tag, 1)\n this.SendReply(bufchain)\n break\n }\n\n case 54: {\n // getlock\n const req = marshall.Unmarshall(\n ['w', 'b', 'd', 'd', 'w', 's'],\n buffer,\n state,\n )\n const fid = req[0]\n const lock_length = req[3] === 0 ? Infinity : req[3]\n const lock_request = this.fs.DescribeLock(\n req[1],\n req[2],\n lock_length,\n req[4],\n req[5],\n )\n dbg_log(\n '[getlock] fid=' +\n fid +\n ', type=' +\n P9_LOCK_TYPES[lock_request.type] +\n ', start=' +\n lock_request.start +\n ', length=' +\n lock_request.length +\n ', proc_id=' +\n lock_request.proc_id,\n )\n\n let ret_lock = this.fs.GetLock(\n this.fids[fid].inodeid,\n lock_request,\n )\n\n if (!ret_lock) {\n ret_lock = lock_request\n ret_lock.type = P9_LOCK_TYPE_UNLCK\n }\n\n const ret_length =\n ret_lock.length === Infinity ? 0 : ret_lock.length\n\n size = marshall.Marshall(\n ['b', 'd', 'd', 'w', 's'],\n [\n ret_lock.type,\n ret_lock.start,\n ret_length,\n ret_lock.proc_id,\n ret_lock.client_id,\n ],\n this.replybuffer,\n 7,\n )\n\n this.BuildReply(id, tag, size)\n this.SendReply(bufchain)\n break\n }\n\n case 24: {\n // getattr\n const req = marshall.Unmarshall(['w', 'd'], buffer, state)\n const fid = req[0]\n const inode = this.fs.GetInode(this.fids[fid].inodeid)\n dbg_log(\n '[getattr]: fid=' +\n fid +\n ' name=' +\n this.fids[fid].dbg_name +\n ' request mask=' +\n req[1],\n LOG_9P,\n )\n if (!inode || inode.status === STATUS_UNLINKED) {\n dbg_log('getattr: unlinked', LOG_9P)\n this.SendError(tag, 'No such file or directory', ENOENT)\n this.SendReply(bufchain)\n break\n }\n req[0] = req[1] // request mask\n req[1] = inode.qid\n\n req[2] = inode.mode\n req[3] = inode.uid // user id\n req[4] = inode.gid // group id\n\n req[5] = inode.nlinks // number of hard links\n req[6] = (inode.major << 8) | inode.minor // device id low\n req[7] = inode.size // size low\n req[8] = this.BLOCKSIZE\n req[9] = Math.floor(inode.size / 512 + 1) // blk size low\n req[10] = inode.atime // atime\n req[11] = 0x0\n req[12] = inode.mtime // mtime\n req[13] = 0x0\n req[14] = inode.ctime // ctime\n req[15] = 0x0\n req[16] = 0x0 // btime\n req[17] = 0x0\n req[18] = 0x0 // st_gen\n req[19] = 0x0 // data_version\n marshall.Marshall(\n [\n 'd',\n 'Q',\n 'w',\n 'w',\n 'w',\n 'd',\n 'd',\n 'd',\n 'd',\n 'd',\n 'd',\n 'd', // atime\n 'd',\n 'd', // mtime\n 'd',\n 'd', // ctime\n 'd',\n 'd', // btime\n 'd',\n 'd',\n ],\n req,\n this.replybuffer,\n 7,\n )\n this.BuildReply(id, tag, 8 + 13 + 4 + 4 + 4 + 8 * 15)\n this.SendReply(bufchain)\n break\n }\n\n case 26: {\n // setattr\n const req = marshall.Unmarshall(\n [\n 'w',\n 'w',\n 'w', // mode\n 'w',\n 'w', // uid, gid\n 'd', // size\n 'd',\n 'd', // atime\n 'd',\n 'd', // mtime\n ],\n buffer,\n state,\n )\n const fid = req[0]\n const inode = this.fs.GetInode(this.fids[fid].inodeid)\n dbg_log(\n '[setattr]: fid=' +\n fid +\n ' request mask=' +\n req[1] +\n ' name=' +\n this.fids[fid].dbg_name,\n LOG_9P,\n )\n if (req[1] & P9_SETATTR_MODE) {\n // XXX: check mode (S_IFREG or S_IFDIR or similar should be set)\n inode.mode = req[2]\n }\n if (req[1] & P9_SETATTR_UID) {\n inode.uid = req[3]\n }\n if (req[1] & P9_SETATTR_GID) {\n inode.gid = req[4]\n }\n if (req[1] & P9_SETATTR_ATIME) {\n inode.atime = Math.floor(new Date().getTime() / 1000)\n }\n if (req[1] & P9_SETATTR_MTIME) {\n inode.mtime = Math.floor(new Date().getTime() / 1000)\n }\n if (req[1] & P9_SETATTR_CTIME) {\n inode.ctime = Math.floor(new Date().getTime() / 1000)\n }\n if (req[1] & P9_SETATTR_ATIME_SET) {\n inode.atime = req[6]\n }\n if (req[1] & P9_SETATTR_MTIME_SET) {\n inode.mtime = req[8]\n }\n if (req[1] & P9_SETATTR_SIZE) {\n await this.fs.ChangeSize(this.fids[fid].inodeid, req[5])\n }\n this.BuildReply(id, tag, 0)\n this.SendReply(bufchain)\n break\n }\n\n case 50: {\n // fsync\n const req = marshall.Unmarshall(['w', 'd'], buffer, state)\n const _fid = req[0]\n this.BuildReply(id, tag, 0)\n this.SendReply(bufchain)\n break\n }\n\n case 40: // TREADDIR\n case 116: {\n // read\n const req = marshall.Unmarshall(['w', 'd', 'w'], buffer, state)\n const fid = req[0]\n const offset = req[1]\n let count = req[2]\n const inode = this.fs.GetInode(this.fids[fid].inodeid)\n if (id === 40)\n dbg_log(\n '[treaddir]: fid=' +\n fid +\n ' offset=' +\n offset +\n ' count=' +\n count,\n LOG_9P,\n )\n if (id === 116)\n dbg_log(\n '[read]: fid=' +\n fid +\n ' (' +\n this.fids[fid].dbg_name +\n ') offset=' +\n offset +\n ' count=' +\n count +\n ' fidtype=' +\n this.fids[fid].type,\n LOG_9P,\n )\n if (!inode || inode.status === STATUS_UNLINKED) {\n dbg_log('read/treaddir: unlinked', LOG_9P)\n this.SendError(tag, 'No such file or directory', ENOENT)\n this.SendReply(bufchain)\n break\n }\n if (this.fids[fid].type === FID_XATTR) {\n if (inode.caps!.length < offset + count)\n count = inode.caps!.length - offset\n for (let i = 0; i < count; i++)\n this.replybuffer[7 + 4 + i] = inode.caps![offset + i]\n marshall.Marshall(['w'], [count], this.replybuffer, 7)\n this.BuildReply(id, tag, 4 + count)\n this.SendReply(bufchain)\n } else {\n await this.fs.OpenInode(this.fids[fid].inodeid, undefined)\n const inodeid = this.fids[fid].inodeid\n\n count = Math.min(count, this.replybuffer.length - (7 + 4))\n\n if (inode.size < offset + count) count = inode.size - offset\n else if (id === 40) {\n // for directories, return whole number of dir-entries.\n count =\n this.fs.RoundToDirentry(inodeid, offset + count) -\n offset\n }\n if (offset > inode.size) {\n // offset can be greater than available - should return count of zero.\n // See http://ericvh.github.io/9p-rfc/rfc9p2000.html#anchor30\n count = 0\n }\n\n this.bus.send('9p-read-start', [this.fids[fid].dbg_name])\n\n const data = await this.fs.Read(inodeid, offset, count)\n\n this.bus.send('9p-read-end', [\n this.fids[fid].dbg_name,\n count,\n ])\n\n if (data) {\n this.replybuffer.set(data, 7 + 4)\n }\n marshall.Marshall(['w'], [count], this.replybuffer, 7)\n this.BuildReply(id, tag, 4 + count)\n this.SendReply(bufchain)\n }\n break\n }\n\n case 118: {\n // write\n const req = marshall.Unmarshall(['w', 'd', 'w'], buffer, state)\n const fid = req[0]\n const offset = req[1]\n const count = req[2]\n\n const filename = this.fids[fid].dbg_name\n\n dbg_log(\n '[write]: fid=' +\n fid +\n ' (' +\n filename +\n ') offset=' +\n offset +\n ' count=' +\n count +\n ' fidtype=' +\n this.fids[fid].type,\n LOG_9P,\n )\n if (this.fids[fid].type === FID_XATTR) {\n // XXX: xattr not supported yet. Ignore write.\n this.SendError(tag, 'Setxattr not supported', EOPNOTSUPP)\n this.SendReply(bufchain)\n break\n } else {\n // XXX: Size of the subarray is unchecked\n await this.fs.Write(\n this.fids[fid].inodeid,\n offset,\n count,\n buffer.subarray(state.offset),\n )\n }\n\n this.bus.send('9p-write-end', [filename, count])\n\n marshall.Marshall(['w'], [count], this.replybuffer, 7)\n this.BuildReply(id, tag, 4)\n this.SendReply(bufchain)\n break\n }\n\n case 74: {\n // RENAMEAT\n const req = marshall.Unmarshall(\n ['w', 's', 'w', 's'],\n buffer,\n state,\n )\n const olddirfid = req[0]\n const oldname = req[1]\n const newdirfid = req[2]\n const newname = req[3]\n dbg_log(\n '[renameat]: oldname=' + oldname + ' newname=' + newname,\n LOG_9P,\n )\n const ret = await this.fs.Rename(\n this.fids[olddirfid].inodeid,\n oldname,\n this.fids[newdirfid].inodeid,\n newname,\n )\n if (ret < 0) {\n let error_message = ''\n if (ret === -ENOENT)\n error_message = 'No such file or directory'\n else if (ret === -EPERM)\n error_message = 'Operation not permitted'\n else if (ret === -ENOTEMPTY)\n error_message = 'Directory not empty'\n else {\n error_message = 'Unknown error: ' + -ret\n dbg_assert(\n false,\n '[renameat]: Unexpected error code: ' + -ret,\n )\n }\n this.SendError(tag, error_message, -ret)\n this.SendReply(bufchain)\n break\n }\n if (TRACK_FILENAMES) {\n const newidx = this.fs.Search(\n this.fids[newdirfid].inodeid,\n newname,\n )\n this.update_dbg_name(newidx, newname)\n }\n this.BuildReply(id, tag, 0)\n this.SendReply(bufchain)\n break\n }\n\n case 76: {\n // TUNLINKAT\n const req = marshall.Unmarshall(['w', 's', 'w'], buffer, state)\n const dirfd = req[0]\n const name = req[1]\n const flags = req[2]\n dbg_log(\n '[unlink]: dirfd=' +\n dirfd +\n ' name=' +\n name +\n ' flags=' +\n flags,\n LOG_9P,\n )\n const fid_search = this.fs.Search(\n this.fids[dirfd].inodeid,\n name,\n )\n if (fid_search === -1) {\n this.SendError(tag, 'No such file or directory', ENOENT)\n this.SendReply(bufchain)\n break\n }\n const ret = this.fs.Unlink(this.fids[dirfd].inodeid, name)\n if (ret < 0) {\n let error_message = ''\n if (ret === -ENOTEMPTY)\n error_message = 'Directory not empty'\n else if (ret === -EPERM)\n error_message = 'Operation not permitted'\n else {\n error_message = 'Unknown error: ' + -ret\n dbg_assert(\n false,\n '[unlink]: Unexpected error code: ' + -ret,\n )\n }\n this.SendError(tag, error_message, -ret)\n this.SendReply(bufchain)\n break\n }\n this.BuildReply(id, tag, 0)\n this.SendReply(bufchain)\n break\n }\n\n case 100: {\n // version\n const version = marshall.Unmarshall(['w', 's'], buffer, state)\n dbg_log(\n '[version]: msize=' + version[0] + ' version=' + version[1],\n LOG_9P,\n )\n if (this.msize !== version[0]) {\n this.msize = version[0]\n this.replybuffer = new Uint8Array(\n Math.min(MAX_REPLYBUFFER_SIZE, this.msize * 2),\n )\n }\n size = marshall.Marshall(\n ['w', 's'],\n [this.msize, this.VERSION],\n this.replybuffer,\n 7,\n )\n this.BuildReply(id, tag, size)\n this.SendReply(bufchain)\n break\n }\n\n case 104: {\n // attach\n // return root directorie's QID\n const req = marshall.Unmarshall(\n ['w', 'w', 's', 's', 'w'],\n buffer,\n state,\n )\n const fid = req[0]\n const uid = req[4]\n dbg_log(\n '[attach]: fid=' +\n fid +\n ' afid=' +\n h(req[1]) +\n ' uname=' +\n req[2] +\n ' aname=' +\n req[3],\n LOG_9P,\n )\n this.fids[fid] = this.Createfid(0, FID_INODE, uid, '')\n const inode = this.fs.GetInode(this.fids[fid].inodeid)\n marshall.Marshall(['Q'], [inode.qid], this.replybuffer, 7)\n this.BuildReply(id, tag, 13)\n this.SendReply(bufchain)\n this.bus.send('9p-attach')\n break\n }\n\n case 108: {\n // tflush\n const req = marshall.Unmarshall(['h'], buffer, state)\n const _oldtag = req[0]\n dbg_log('[flush] ' + tag, LOG_9P)\n this.BuildReply(id, tag, 0)\n this.SendReply(bufchain)\n break\n }\n\n case 110: {\n // walk\n const req = marshall.Unmarshall(['w', 'w', 'h'], buffer, state)\n const fid = req[0]\n const nwfid = req[1]\n const nwname = req[2]\n dbg_log(\n '[walk]: fid=' +\n req[0] +\n ' nwfid=' +\n req[1] +\n ' nwname=' +\n nwname,\n LOG_9P,\n )\n if (nwname === 0) {\n this.fids[nwfid] = this.Createfid(\n this.fids[fid].inodeid,\n FID_INODE,\n this.fids[fid].uid,\n this.fids[fid].dbg_name,\n )\n marshall.Marshall(['h'], [0], this.replybuffer, 7)\n this.BuildReply(id, tag, 2)\n this.SendReply(bufchain)\n break\n }\n const wnames: string[] = []\n for (let i = 0; i < nwname; i++) {\n wnames.push('s')\n }\n const walk = marshall.Unmarshall(\n wnames as marshall.MarshallTypeCode[],\n buffer,\n state,\n )\n let idx = this.fids[fid].inodeid\n let offset = 7 + 2\n let nwidx = 0\n dbg_log(\n 'walk in dir ' +\n this.fids[fid].dbg_name +\n ' to: ' +\n walk.toString(),\n LOG_9P,\n )\n for (let i = 0; i < nwname; i++) {\n idx = this.fs.Search(idx, walk[i])\n\n if (idx === -1) {\n dbg_log('Could not find: ' + walk[i], LOG_9P)\n break\n }\n offset += marshall.Marshall(\n ['Q'],\n [this.fs.GetInode(idx).qid],\n this.replybuffer,\n offset,\n )\n nwidx++\n this.fids[nwfid] = this.Createfid(\n idx,\n FID_INODE,\n this.fids[fid].uid,\n walk[i],\n )\n }\n marshall.Marshall(['h'], [nwidx], this.replybuffer, 7)\n this.BuildReply(id, tag, offset - 7)\n this.SendReply(bufchain)\n break\n }\n\n case 120: {\n // clunk\n const req = marshall.Unmarshall(['w'], buffer, state)\n dbg_log('[clunk]: fid=' + req[0], LOG_9P)\n if (this.fids[req[0]] && this.fids[req[0]].inodeid >= 0) {\n await this.fs.CloseInode(this.fids[req[0]].inodeid)\n this.fids[req[0]].inodeid = -1\n this.fids[req[0]].type = FID_NONE\n }\n this.BuildReply(id, tag, 0)\n this.SendReply(bufchain)\n break\n }\n\n case 32: {\n // txattrcreate\n const req = marshall.Unmarshall(\n ['w', 's', 'd', 'w'],\n buffer,\n state,\n )\n const fid = req[0]\n const name = req[1]\n const attr_size = req[2]\n const flags = req[3]\n dbg_log(\n '[txattrcreate]: fid=' +\n fid +\n ' name=' +\n name +\n ' attr_size=' +\n attr_size +\n ' flags=' +\n flags,\n LOG_9P,\n )\n\n // XXX: xattr not supported yet. E.g. checks corresponding to the flags needed.\n this.fids[fid].type = FID_XATTR\n\n this.BuildReply(id, tag, 0)\n this.SendReply(bufchain)\n break\n }\n\n case 30: {\n // xattrwalk\n const req = marshall.Unmarshall(['w', 'w', 's'], buffer, state)\n const _fid = req[0]\n const _newfid = req[1]\n const _name = req[2]\n dbg_log(\n '[xattrwalk]: fid=' +\n req[0] +\n ' newfid=' +\n req[1] +\n ' name=' +\n req[2],\n LOG_9P,\n )\n\n // Workaround for Linux restarts writes until full blocksize\n this.SendError(tag, 'Setxattr not supported', EOPNOTSUPP)\n this.SendReply(bufchain)\n break\n }\n\n default:\n dbg_log(\n 'Error in Virtio9p: Unknown id ' + id + ' received',\n LOG_9P,\n )\n dbg_assert(false)\n break\n }\n }\n}\n\nexport class Virtio9pHandler {\n handle_fn: P9Handler\n tag_bufchain: Map<number, VirtQueueBufferChain>\n configspace_tagname: number[]\n configspace_taglen: number\n virtio: VirtIO\n virtqueue: VirtQueue\n\n constructor(handle_fn: P9Handler, cpu: CPU) {\n this.handle_fn = handle_fn\n this.tag_bufchain = new Map()\n\n this.configspace_tagname = [0x68, 0x6f, 0x73, 0x74, 0x39, 0x70] // \"host9p\" string\n this.configspace_taglen = this.configspace_tagname.length // num bytes\n\n this.virtio = init_virtio(\n cpu,\n this.configspace_taglen,\n this.configspace_tagname,\n async (bufchain: VirtQueueBufferChain) => {\n // TODO: split into header + data blobs to avoid unnecessary copying.\n const reqbuf = new Uint8Array(bufchain.length_readable)\n bufchain.get_next_blob(reqbuf)\n\n const reqheader = marshall.Unmarshall(['w', 'b', 'h'], reqbuf, {\n offset: 0,\n })\n const reqtag = reqheader[2]\n\n this.tag_bufchain.set(reqtag, bufchain)\n this.handle_fn(reqbuf, (replybuf: Uint8Array) => {\n const replyheader = marshall.Unmarshall(\n ['w', 'b', 'h'],\n replybuf,\n { offset: 0 },\n )\n const replytag = replyheader[2]\n\n const bufchain = this.tag_bufchain.get(replytag)\n if (!bufchain) {\n console.error('No bufchain found for tag: ' + replytag)\n return\n }\n\n bufchain.set_next_blob(replybuf)\n this.virtqueue.push_reply(bufchain)\n this.virtqueue.flush_replies()\n\n this.tag_bufchain.delete(replytag)\n })\n },\n )\n this.virtqueue = this.virtio.queues[0]\n }\n\n get_state(): any[] {\n const state: any[] = []\n\n state[0] = this.configspace_tagname\n state[1] = this.configspace_taglen\n state[2] = this.virtio\n state[3] = this.tag_bufchain\n\n return state\n }\n\n set_state(state: any[]): void {\n this.configspace_tagname = state[0]\n this.configspace_taglen = state[1]\n this.virtio.set_state(state[2])\n this.virtqueue = this.virtio.queues[0]\n this.tag_bufchain = state[3]\n }\n\n reset(): void {\n this.virtio.reset()\n }\n}\n\nexport class Virtio9pProxy {\n socket: WebSocket | undefined\n cpu: CPU\n send_queue: Uint8Array[]\n url: string\n reconnect_interval: number\n last_connect_attempt: number\n send_queue_limit: number\n destroyed: boolean\n tag_bufchain: Map<number, VirtQueueBufferChain>\n configspace_tagname: number[]\n configspace_taglen: number\n virtio: VirtIO\n virtqueue: VirtQueue\n\n constructor(url: string, cpu: CPU) {\n this.socket = undefined\n this.cpu = cpu\n\n // TODO: circular buffer?\n this.send_queue = []\n this.url = url\n\n this.reconnect_interval = 10000\n this.last_connect_attempt = Date.now() - this.reconnect_interval\n this.send_queue_limit = 64\n this.destroyed = false\n\n this.tag_bufchain = new Map()\n\n this.configspace_tagname = [0x68, 0x6f, 0x73, 0x74, 0x39, 0x70] // \"host9p\" string\n this.configspace_taglen = this.configspace_tagname.length // num bytes\n\n this.virtio = init_virtio(\n cpu,\n this.configspace_taglen,\n this.configspace_tagname,\n async (bufchain: VirtQueueBufferChain) => {\n // TODO: split into header + data blobs to avoid unnecessary copying.\n const reqbuf = new Uint8Array(bufchain.length_readable)\n bufchain.get_next_blob(reqbuf)\n\n const reqheader = marshall.Unmarshall(['w', 'b', 'h'], reqbuf, {\n offset: 0,\n })\n const reqtag = reqheader[2]\n\n this.tag_bufchain.set(reqtag, bufchain)\n this.send(reqbuf)\n },\n )\n this.virtqueue = this.virtio.queues[0]\n }\n\n get_state(): any[] {\n const state: any[] = []\n\n state[0] = this.configspace_tagname\n state[1] = this.configspace_taglen\n state[2] = this.virtio\n state[3] = this.tag_bufchain\n\n return state\n }\n\n set_state(state: any[]): void {\n this.configspace_tagname = state[0]\n this.configspace_taglen = state[1]\n this.virtio.set_state(state[2])\n this.virtqueue = this.virtio.queues[0]\n this.tag_bufchain = state[3]\n }\n\n reset(): void {\n this.virtio.reset()\n }\n\n handle_message(e: MessageEvent): void {\n const replybuf = new Uint8Array(e.data)\n const replyheader = marshall.Unmarshall(['w', 'b', 'h'], replybuf, {\n offset: 0,\n })\n const replytag = replyheader[2]\n\n const bufchain = this.tag_bufchain.get(replytag)\n if (!bufchain) {\n console.error(\n 'Virtio9pProxy: No bufchain found for tag: ' + replytag,\n )\n return\n }\n\n bufchain.set_next_blob(replybuf)\n this.virtqueue.push_reply(bufchain)\n this.virtqueue.flush_replies()\n\n this.tag_bufchain.delete(replytag)\n }\n\n handle_close(_e: CloseEvent): void {\n if (!this.destroyed) {\n this.connect()\n setTimeout(this.connect.bind(this), this.reconnect_interval)\n }\n }\n\n handle_open(_e: Event): void {\n for (let i = 0; i < this.send_queue.length; i++) {\n this.send(this.send_queue[i])\n }\n\n this.send_queue = []\n }\n\n handle_error(_e: Event): void {\n //console.log(\"onerror\", e);\n }\n\n destroy(): void {\n this.destroyed = true\n if (this.socket) {\n this.socket.close()\n }\n }\n\n connect(): void {\n if (typeof WebSocket === 'undefined') {\n return\n }\n\n if (this.socket) {\n const state = this.socket.readyState\n\n if (state === 0 || state === 1) {\n // already or almost there\n return\n }\n }\n\n const now = Date.now()\n\n if (this.last_connect_attempt + this.reconnect_interval > now) {\n return\n }\n\n this.last_connect_attempt = Date.now()\n\n try {\n this.socket = new WebSocket(this.url)\n } catch (e) {\n console.error(e)\n return\n }\n\n this.socket.binaryType = 'arraybuffer'\n\n this.socket.onopen = this.handle_open.bind(this)\n this.socket.onmessage = this.handle_message.bind(this)\n this.socket.onclose = this.handle_close.bind(this)\n this.socket.onerror = this.handle_error.bind(this)\n }\n\n send(data: Uint8Array): void {\n if (!this.socket || this.socket.readyState !== 1) {\n this.send_queue.push(data)\n\n if (this.send_queue.length > 2 * this.send_queue_limit) {\n this.send_queue = this.send_queue.slice(-this.send_queue_limit)\n }\n\n this.connect()\n } else {\n // Copy into a plain ArrayBuffer for WebSocket.send() compatibility\n const buf = new ArrayBuffer(data.byteLength)\n new Uint8Array(buf).set(data)\n this.socket.send(buf)\n }\n }\n\n change_proxy(url: string): void {\n this.url = url\n\n if (this.socket) {\n this.socket.onclose = function () {}\n this.socket.onerror = function () {}\n this.socket.close()\n this.socket = undefined\n }\n }\n}\n", "import { h } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\n\n// https://www.kernel.org/doc/Documentation/x86/boot.txt\n\nconst LINUX_BOOT_HDR_SETUP_SECTS = 0x1f1\nconst LINUX_BOOT_HDR_SYSSIZE = 0x1f4\nconst LINUX_BOOT_HDR_VIDMODE = 0x1fa\nconst LINUX_BOOT_HDR_BOOT_FLAG = 0x1fe\nconst LINUX_BOOT_HDR_HEADER = 0x202\nconst LINUX_BOOT_HDR_VERSION = 0x206\nconst LINUX_BOOT_HDR_TYPE_OF_LOADER = 0x210\nconst LINUX_BOOT_HDR_LOADFLAGS = 0x211\nconst LINUX_BOOT_HDR_CODE32_START = 0x214\nconst LINUX_BOOT_HDR_RAMDISK_IMAGE = 0x218\nconst LINUX_BOOT_HDR_RAMDISK_SIZE = 0x21c\nconst LINUX_BOOT_HDR_HEAP_END_PTR = 0x224\nconst LINUX_BOOT_HDR_CMD_LINE_PTR = 0x228\nconst LINUX_BOOT_HDR_INITRD_ADDR_MAX = 0x22c\nconst LINUX_BOOT_HDR_KERNEL_ALIGNMENT = 0x230\nconst LINUX_BOOT_HDR_RELOCATABLE_KERNEL = 0x234\nconst LINUX_BOOT_HDR_MIN_ALIGNMENT = 0x235\nconst LINUX_BOOT_HDR_XLOADFLAGS = 0x236\nconst LINUX_BOOT_HDR_CMDLINE_SIZE = 0x238\nconst LINUX_BOOT_HDR_PAYLOAD_OFFSET = 0x248\nconst LINUX_BOOT_HDR_PAYLOAD_LENGTH = 0x24c\nconst LINUX_BOOT_HDR_PREF_ADDRESS = 0x258\nconst LINUX_BOOT_HDR_INIT_SIZE = 0x260\n\nconst LINUX_BOOT_HDR_CHECKSUM1 = 0xaa55\nconst LINUX_BOOT_HDR_CHECKSUM2 = 0x53726448\n\nconst LINUX_BOOT_HDR_TYPE_OF_LOADER_NOT_ASSIGNED = 0xff\n\nconst LINUX_BOOT_HDR_LOADFLAGS_LOADED_HIGH = 1 << 0\nconst LINUX_BOOT_HDR_LOADFLAGS_QUIET_FLAG = 1 << 5\nconst LINUX_BOOT_HDR_LOADFLAGS_KEEP_SEGMENTS = 1 << 6\nconst LINUX_BOOT_HDR_LOADFLAGS_CAN_USE_HEAPS = 1 << 7\n\ninterface KernelBootRom {\n name: string\n data: Uint8Array\n}\n\nexport function load_kernel(\n mem8: Uint8Array,\n bzimage: ArrayBuffer,\n initrd: ArrayBuffer | undefined,\n cmdline: string,\n): KernelBootRom | undefined {\n dbg_log('Trying to load kernel of size ' + bzimage.byteLength)\n\n const KERNEL_HIGH_ADDRESS = 0x100000\n\n // Put the initrd at the 64 MB boundary. This means the minimum memory size\n // is 64 MB plus the size of the initrd.\n // Note: If set too low, kernel may fail to load the initrd with \"invalid magic at start of compressed archive\"\n const INITRD_ADDRESS = 64 << 20\n\n const quiet = false\n\n const bzimage8 = new Uint8Array(bzimage)\n const bzimage16 = new Uint16Array(bzimage)\n const bzimage32 = new Uint32Array(bzimage)\n\n const setup_sects = bzimage8[LINUX_BOOT_HDR_SETUP_SECTS] || 4\n const _syssize = bzimage32[LINUX_BOOT_HDR_SYSSIZE >> 2] << 4\n\n const _vidmode = bzimage16[LINUX_BOOT_HDR_VIDMODE >> 1]\n\n const checksum1 = bzimage16[LINUX_BOOT_HDR_BOOT_FLAG >> 1]\n if (checksum1 !== LINUX_BOOT_HDR_CHECKSUM1) {\n dbg_log('Bad checksum1: ' + h(checksum1))\n return\n }\n\n // Not aligned, so split into two 16-bit reads\n const checksum2 =\n bzimage16[LINUX_BOOT_HDR_HEADER >> 1] |\n (bzimage16[(LINUX_BOOT_HDR_HEADER + 2) >> 1] << 16)\n if (checksum2 !== LINUX_BOOT_HDR_CHECKSUM2) {\n dbg_log('Bad checksum2: ' + h(checksum2))\n return\n }\n\n const protocol = bzimage16[LINUX_BOOT_HDR_VERSION >> 1]\n dbg_assert(protocol >= 0x202) // older not supported by us\n\n const flags = bzimage8[LINUX_BOOT_HDR_LOADFLAGS]\n dbg_assert(!!(flags & LINUX_BOOT_HDR_LOADFLAGS_LOADED_HIGH)) // low kernels not supported by us\n\n // we don't relocate the kernel, so we don't care much about most of these\n\n const flags2 = bzimage16[LINUX_BOOT_HDR_XLOADFLAGS >> 1]\n const initrd_addr_max = bzimage32[LINUX_BOOT_HDR_INITRD_ADDR_MAX >> 2]\n const kernel_alignment = bzimage32[LINUX_BOOT_HDR_KERNEL_ALIGNMENT >> 2]\n const relocatable_kernel = bzimage8[LINUX_BOOT_HDR_RELOCATABLE_KERNEL]\n const min_alignment = bzimage8[LINUX_BOOT_HDR_MIN_ALIGNMENT]\n const cmdline_size =\n protocol >= 0x206 ? bzimage32[LINUX_BOOT_HDR_CMDLINE_SIZE >> 2] : 255\n const payload_offset = bzimage32[LINUX_BOOT_HDR_PAYLOAD_OFFSET >> 2]\n const payload_length = bzimage32[LINUX_BOOT_HDR_PAYLOAD_LENGTH >> 2]\n const pref_address = bzimage32[LINUX_BOOT_HDR_PREF_ADDRESS >> 2]\n const pref_address_high = bzimage32[(LINUX_BOOT_HDR_PREF_ADDRESS + 4) >> 2]\n const init_size = bzimage32[LINUX_BOOT_HDR_INIT_SIZE >> 2]\n\n dbg_log('kernel boot protocol version: ' + h(protocol))\n dbg_log('flags=' + h(flags) + ' xflags=' + h(flags2))\n dbg_log('code32_start=' + h(bzimage32[LINUX_BOOT_HDR_CODE32_START >> 2]))\n dbg_log('initrd_addr_max=' + h(initrd_addr_max))\n dbg_log('kernel_alignment=' + h(kernel_alignment))\n dbg_log('relocatable=' + relocatable_kernel)\n dbg_log('min_alignment=' + h(min_alignment))\n dbg_log('cmdline max=' + h(cmdline_size))\n dbg_log(\n 'payload offset=' + h(payload_offset) + ' size=' + h(payload_length),\n )\n dbg_log('pref_address=' + h(pref_address_high) + ':' + h(pref_address))\n dbg_log('init_size=' + h(init_size))\n\n const real_mode_segment = 0x8000\n const base_ptr = real_mode_segment << 4\n\n const heap_end = 0xe000\n const heap_end_ptr = heap_end - 0x200\n\n // fill in the kernel boot header with infos the kernel needs to know\n\n bzimage8[LINUX_BOOT_HDR_TYPE_OF_LOADER] =\n LINUX_BOOT_HDR_TYPE_OF_LOADER_NOT_ASSIGNED\n\n const new_flags =\n ((quiet\n ? flags | LINUX_BOOT_HDR_LOADFLAGS_QUIET_FLAG\n : flags & ~LINUX_BOOT_HDR_LOADFLAGS_QUIET_FLAG) &\n ~LINUX_BOOT_HDR_LOADFLAGS_KEEP_SEGMENTS) |\n LINUX_BOOT_HDR_LOADFLAGS_CAN_USE_HEAPS\n bzimage8[LINUX_BOOT_HDR_LOADFLAGS] = new_flags\n\n bzimage16[LINUX_BOOT_HDR_HEAP_END_PTR >> 1] = heap_end_ptr\n\n // should parse the vga=... paramter from cmdline here, but we don't really care\n bzimage16[LINUX_BOOT_HDR_VIDMODE >> 1] = 0xffff // normal\n\n dbg_log('heap_end_ptr=' + h(heap_end_ptr))\n\n cmdline += '\\x00'\n dbg_assert(cmdline.length < cmdline_size)\n\n const cmd_line_ptr = base_ptr + heap_end\n dbg_log('cmd_line_ptr=' + h(cmd_line_ptr))\n\n bzimage32[LINUX_BOOT_HDR_CMD_LINE_PTR >> 2] = cmd_line_ptr\n for (let i = 0; i < cmdline.length; i++) {\n mem8[cmd_line_ptr + i] = cmdline.charCodeAt(i)\n }\n\n const prot_mode_kernel_start = (setup_sects + 1) * 512\n dbg_log('prot_mode_kernel_start=' + h(prot_mode_kernel_start))\n\n const real_mode_kernel = new Uint8Array(bzimage, 0, prot_mode_kernel_start)\n const protected_mode_kernel = new Uint8Array(\n bzimage,\n prot_mode_kernel_start,\n )\n\n let ramdisk_address = 0\n let ramdisk_size = 0\n\n if (initrd) {\n ramdisk_address = INITRD_ADDRESS\n ramdisk_size = initrd.byteLength\n\n dbg_assert(\n KERNEL_HIGH_ADDRESS + protected_mode_kernel.length <\n ramdisk_address,\n )\n\n mem8.set(new Uint8Array(initrd), ramdisk_address)\n }\n\n bzimage32[LINUX_BOOT_HDR_RAMDISK_IMAGE >> 2] = ramdisk_address\n bzimage32[LINUX_BOOT_HDR_RAMDISK_SIZE >> 2] = ramdisk_size\n\n dbg_assert(base_ptr + real_mode_kernel.length < 0xa0000)\n\n mem8.set(real_mode_kernel, base_ptr)\n mem8.set(protected_mode_kernel, KERNEL_HIGH_ADDRESS)\n\n return {\n name: 'genroms/kernel.bin',\n data: make_linux_boot_rom(real_mode_segment, heap_end),\n }\n}\n\nfunction make_linux_boot_rom(\n real_mode_segment: number,\n heap_end: number,\n): Uint8Array {\n // This rom will be executed by seabios after its initialisation\n // It sets up segment registers, the stack and calls the kernel real mode entry point\n\n const SIZE = 0x200\n\n const data8 = new Uint8Array(SIZE)\n const data16 = new Uint16Array(data8.buffer)\n\n data16[0] = 0xaa55\n data8[2] = SIZE / 0x200\n\n let i = 3\n\n data8[i++] = 0xfa // cli\n data8[i++] = 0xb8 // mov ax, real_mode_segment\n data8[i++] = real_mode_segment >> 0\n data8[i++] = real_mode_segment >> 8\n data8[i++] = 0x8e // mov es, ax\n data8[i++] = 0xc0\n data8[i++] = 0x8e // mov ds, ax\n data8[i++] = 0xd8\n data8[i++] = 0x8e // mov fs, ax\n data8[i++] = 0xe0\n data8[i++] = 0x8e // mov gs, ax\n data8[i++] = 0xe8\n data8[i++] = 0x8e // mov ss, ax\n data8[i++] = 0xd0\n data8[i++] = 0xbc // mov sp, heap_end\n data8[i++] = heap_end >> 0\n data8[i++] = heap_end >> 8\n data8[i++] = 0xea // jmp (real_mode_segment+0x20):0x0\n data8[i++] = 0x00\n data8[i++] = 0x00\n data8[i++] = (real_mode_segment + 0x20) >> 0\n data8[i++] = (real_mode_segment + 0x20) >> 8\n\n dbg_assert(i < SIZE)\n\n const checksum_index = i\n data8[checksum_index] = 0\n\n let checksum = 0\n\n for (let i = 0; i < data8.length; i++) {\n checksum += data8[i]\n }\n\n data8[checksum_index] = -checksum\n\n return data8\n}\n", "declare const DEBUG: boolean\n\nimport {\n LOG_CPU,\n LOG_BIOS,\n FW_CFG_SIGNATURE,\n FW_CFG_SIGNATURE_QEMU,\n WASM_TABLE_SIZE,\n WASM_TABLE_OFFSET,\n FW_CFG_ID,\n FW_CFG_RAM_SIZE,\n FW_CFG_NB_CPUS,\n FW_CFG_MAX_CPUS,\n FW_CFG_NUMA,\n FW_CFG_FILE_DIR,\n FW_CFG_FILE_START,\n FW_CFG_CUSTOM_START,\n FLAGS_DEFAULT,\n MMAP_BLOCK_BITS,\n MMAP_BLOCK_SIZE,\n MMAP_MAX,\n REG_ESP,\n REG_EBP,\n REG_ESI,\n REG_EAX,\n REG_EBX,\n REG_ECX,\n REG_EDX,\n REG_EDI,\n REG_CS,\n REG_DS,\n REG_ES,\n REG_FS,\n REG_GS,\n REG_SS,\n CR0_PG,\n CR4_PAE,\n REG_LDTR,\n FLAG_VM,\n FLAG_INTERRUPT,\n FLAG_CARRY,\n FLAG_ADJUST,\n FLAG_ZERO,\n FLAG_SIGN,\n FLAG_TRAP,\n FLAG_DIRECTION,\n FLAG_OVERFLOW,\n FLAG_PARITY,\n} from './const.js'\nimport { h, view, pads, Bitmap, dump_file } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\n\nimport { SB16 } from './sb16.js'\nimport { ACPI } from './acpi.js'\nimport { PIT } from './pit.js'\nimport { DMA } from './dma.js'\nimport { UART } from './uart.js'\nimport { Ne2k } from './ne2k.js'\nimport { IO } from './io.js'\nimport { VirtioConsole } from './virtio_console.js'\nimport { PCI } from './pci.js'\nimport { PS2 } from './ps2.js'\nimport { read_elf } from './elf.js'\n\nimport { FloppyController } from './floppy.js'\nimport { IDEController } from './ide.js'\nimport { VirtioNet } from './virtio_net.js'\nimport { VGAScreen } from './vga.js'\nimport { VirtioBalloon } from './virtio_balloon.js'\nimport { Virtio9p, Virtio9pHandler, Virtio9pProxy } from '../lib/9p.js'\n\nimport { load_kernel } from './kernel.js'\n\nimport {\n RTC,\n CMOS_EQUIPMENT_INFO,\n CMOS_BIOS_SMP_COUNT,\n CMOS_MEM_HIGHMEM_HIGH,\n CMOS_MEM_HIGHMEM_MID,\n CMOS_MEM_HIGHMEM_LOW,\n BOOT_ORDER_CD_FIRST,\n CMOS_BIOS_BOOTFLAG1,\n CMOS_BIOS_BOOTFLAG2,\n CMOS_MEM_BASE_LOW,\n CMOS_MEM_BASE_HIGH,\n CMOS_MEM_OLD_EXT_LOW,\n CMOS_MEM_OLD_EXT_HIGH,\n CMOS_MEM_EXTMEM_LOW,\n CMOS_MEM_EXTMEM_HIGH,\n CMOS_MEM_EXTMEM2_LOW,\n CMOS_MEM_EXTMEM2_HIGH,\n} from './rtc.js'\n\n// For Types Only\n\nimport { BusConnector } from './bus.js'\n\n// Resources:\n// https://pdos.csail.mit.edu/6.828/2006/readings/i386/toc.htm\n// https://www-ssl.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html\n// http://ref.x86asm.net/geek32.html\n\nconst DUMP_GENERATED_WASM = false\nconst DUMP_UNCOMPILED_ASSEMBLY = false\n\ntype MmapReadFn = (addr: number) => number\ntype MmapWriteFn = (addr: number, value: number) => void\n\ninterface CPUDevices {\n pci: PCI\n acpi: ACPI\n rtc: RTC\n dma: DMA\n vga: VGAScreen\n ps2: PS2\n uart0: UART\n uart1: UART\n uart2: UART\n uart3: UART\n fdc: FloppyController\n ide: IDEController\n\n cdrom: any\n pit: PIT\n net: Ne2k\n sb16: SB16\n\n virtio_9p: any\n virtio_console: VirtioConsole\n virtio_net: VirtioNet\n virtio_balloon: VirtioBalloon\n}\n\ninterface OptionRom {\n name: string\n data: Uint8Array\n}\n\ninterface WasmModule {\n exports: Record<string, any>\n wasm_table: WebAssembly.Table\n}\n\nexport class CPU {\n stop_idling: () => void\n wm: WasmModule\n wasm_memory!: WebAssembly.Memory\n\n memory_size!: Int32Array\n\n mem8: Uint8Array\n mem32s: Int32Array\n\n segment_is_null!: Uint8Array\n segment_offsets!: Int32Array\n segment_limits!: Uint32Array\n segment_access_bytes!: Uint8Array\n\n protected_mode!: Int32Array\n\n idtr_size!: Int32Array\n idtr_offset!: Int32Array\n\n gdtr_size!: Int32Array\n gdtr_offset!: Int32Array\n\n tss_size_32!: Int32Array\n\n page_fault!: Uint32Array\n\n cr!: Int32Array\n\n cpl!: Uint8Array\n\n is_32!: Int32Array\n\n stack_size_32!: Int32Array\n\n in_hlt!: Uint8Array\n\n last_virt_eip!: Int32Array\n eip_phys!: Int32Array\n\n sysenter_cs!: Int32Array\n sysenter_esp!: Int32Array\n sysenter_eip!: Int32Array\n\n prefixes!: Int32Array\n\n flags!: Int32Array\n\n flags_changed!: Int32Array\n\n last_op_size!: Int32Array\n last_op1!: Int32Array\n last_result!: Int32Array\n\n current_tsc!: Uint32Array\n\n devices: CPUDevices\n\n instruction_pointer!: Int32Array\n previous_ip!: Int32Array\n\n apic_enabled!: Uint8Array\n acpi_enabled!: Uint8Array\n\n memory_map_read8: (MmapReadFn | undefined)[]\n memory_map_write8: (MmapWriteFn | undefined)[]\n memory_map_read32: (MmapReadFn | undefined)[]\n memory_map_write32: (MmapWriteFn | undefined)[]\n\n bios: { main: ArrayBuffer | null; vga: ArrayBuffer | null }\n\n instruction_counter!: Uint32Array\n\n reg32!: Int32Array\n\n fpu_st!: Int32Array\n fpu_stack_empty!: Uint8Array\n fpu_stack_ptr!: Uint8Array\n fpu_control_word!: Uint16Array\n fpu_status_word!: Uint16Array\n fpu_ip!: Int32Array\n fpu_ip_selector!: Int32Array\n fpu_opcode!: Int32Array\n fpu_dp!: Int32Array\n fpu_dp_selector!: Int32Array\n\n reg_xmm32s!: Int32Array\n\n mxcsr!: Int32Array\n\n sreg!: Uint16Array\n\n dreg!: Int32Array\n\n reg_pdpte!: Int32Array\n\n svga_dirty_bitmap_min_offset!: Int32Array\n svga_dirty_bitmap_max_offset!: Int32Array\n\n fw_value: any\n fw_pointer: number\n option_roms: OptionRom[]\n\n io!: IO\n\n bus: BusConnector\n\n jit_imports!: Record<string, any>\n\n // Debug-only properties\n seen_code!: Record<number, number>\n seen_code_uncompiled!: Record<number, number>\n\n capstone_decoder?: any\n\n wabt?: any\n\n // Test hooks (optional)\n test_hook_did_generate_wasm?: (code: Uint8Array) => void\n test_hook_did_finalize_wasm?: (code: Uint8Array) => void\n\n // WASM exports (assigned in wasm_patch)\n reset_cpu!: () => void\n getiopl!: () => number\n get_eflags!: () => number\n handle_irqs!: () => void\n main_loop!: () => number\n reboot_internal!: () => void\n set_jit_config!: (a: number, b: number) => void\n\n read8!: (addr: number) => number\n read16!: (addr: number) => number\n read32s!: (addr: number) => number\n write8!: (addr: number, value: number) => void\n write16!: (addr: number, value: number) => void\n write32!: (addr: number, value: number) => void\n in_mapped_range!: (addr: number) => boolean\n\n fpu_load_tag_word!: (word: number) => void\n fpu_load_status_word!: (word: number) => void\n fpu_get_sti_f64!: (i: number) => number\n\n translate_address_system_read!: (addr: number) => number\n\n get_seg_cs!: () => number\n get_real_eip!: () => number\n\n clear_tlb!: () => void\n full_clear_tlb!: () => void\n update_state_flags!: () => void\n\n set_tsc!: (low: number, high: number) => void\n store_current_tsc!: () => void\n\n set_cpuid_level!: (level: number) => void\n\n device_raise_irq!: (irq: number) => void\n device_lower_irq!: (irq: number) => void\n\n apic_timer!: (now: number) => number\n\n jit_force_generate_unsafe?: (addr: number) => void\n\n jit_clear_cache!: () => void\n jit_dirty_cache!: (start: number, end: number) => void\n codegen_finalize_finished!: (\n index: number,\n start: number,\n flags: number,\n ) => void\n\n allocate_memory!: (size: number) => number\n zero_memory!: (start: number, length: number) => void\n is_memory_zeroed!: (start: number, length: number) => boolean\n\n svga_allocate_memory!: (size: number) => number\n svga_allocate_dest_buffer!: (size: number) => number\n svga_fill_pixel_buffer!: (bpp: number, offset: number) => void\n svga_mark_dirty!: () => void\n\n get_pic_addr_master!: () => number\n get_pic_addr_slave!: () => number\n get_apic_addr!: () => number\n get_ioapic_addr!: () => number\n\n zstd_create_ctx!: (len: number) => number\n zstd_get_src_ptr!: (ctx: number) => number\n zstd_free_ctx!: (ctx: number) => void\n zstd_read!: (ctx: number, len: number) => number\n zstd_read_free!: (ptr: number, len: number) => void\n\n name: string\n\n constructor(bus: BusConnector, wm: WasmModule, stop_idling: () => void) {\n this.name = 'cpu'\n this.stop_idling = stop_idling\n this.wm = wm\n this.wasm_patch()\n this.create_jit_imports()\n\n const memory = this.wm.exports['memory']\n\n this.wasm_memory = memory\n\n this.memory_size = view(Uint32Array, memory, 812, 1)\n\n this.mem8 = new Uint8Array(0)\n this.mem32s = new Int32Array(this.mem8.buffer)\n\n this.segment_is_null = view(Uint8Array, memory, 724, 8)\n this.segment_offsets = view(Int32Array, memory, 736, 8)\n this.segment_limits = view(Uint32Array, memory, 768, 8)\n this.segment_access_bytes = view(Uint8Array, memory, 512, 8)\n\n // Whether or not in protected mode\n this.protected_mode = view(Int32Array, memory, 800, 1)\n\n this.idtr_size = view(Int32Array, memory, 564, 1)\n this.idtr_offset = view(Int32Array, memory, 568, 1)\n\n // global descriptor table register\n this.gdtr_size = view(Int32Array, memory, 572, 1)\n this.gdtr_offset = view(Int32Array, memory, 576, 1)\n\n this.tss_size_32 = view(Int32Array, memory, 1128, 1)\n\n // whether or not a page fault occured\n this.page_fault = view(Uint32Array, memory, 540, 8)\n\n this.cr = view(Int32Array, memory, 580, 8)\n\n // current privilege level\n this.cpl = view(Uint8Array, memory, 612, 1)\n\n // current operand/address size\n this.is_32 = view(Int32Array, memory, 804, 1)\n\n this.stack_size_32 = view(Int32Array, memory, 808, 1)\n\n // Was the last instruction a hlt?\n this.in_hlt = view(Uint8Array, memory, 616, 1)\n\n this.last_virt_eip = view(Int32Array, memory, 620, 1)\n this.eip_phys = view(Int32Array, memory, 624, 1)\n\n this.sysenter_cs = view(Int32Array, memory, 636, 1)\n\n this.sysenter_esp = view(Int32Array, memory, 640, 1)\n\n this.sysenter_eip = view(Int32Array, memory, 644, 1)\n\n this.prefixes = view(Int32Array, memory, 648, 1)\n\n this.flags = view(Int32Array, memory, 120, 1)\n\n // bitmap of flags which are not updated in the flags variable\n // changed by arithmetic instructions, so only relevant to arithmetic flags\n this.flags_changed = view(Int32Array, memory, 100, 1)\n\n // enough infos about the last arithmetic operation to compute eflags\n this.last_op_size = view(Int32Array, memory, 96, 1)\n this.last_op1 = view(Int32Array, memory, 104, 1)\n this.last_result = view(Int32Array, memory, 112, 1)\n\n this.current_tsc = view(Uint32Array, memory, 960, 2) // 64 bit\n\n // @ts-expect-error Devices are populated during init()\n this.devices = {}\n\n this.instruction_pointer = view(Int32Array, memory, 556, 1)\n this.previous_ip = view(Int32Array, memory, 560, 1)\n\n // configured by guest\n this.apic_enabled = view(Uint8Array, memory, 548, 1)\n // configured when the emulator starts (changes bios initialisation)\n this.acpi_enabled = view(Uint8Array, memory, 552, 1)\n\n // managed in io.js\n this.memory_map_read8 = []\n this.memory_map_write8 = []\n this.memory_map_read32 = []\n this.memory_map_write32 = []\n\n this.bios = {\n main: null,\n vga: null,\n }\n\n this.instruction_counter = view(Uint32Array, memory, 664, 1)\n\n // registers\n this.reg32 = view(Int32Array, memory, 64, 8)\n\n this.fpu_st = view(Int32Array, memory, 1152, 4 * 8)\n\n this.fpu_stack_empty = view(Uint8Array, memory, 816, 1)\n this.fpu_stack_empty[0] = 0xff\n this.fpu_stack_ptr = view(Uint8Array, memory, 1032, 1)\n this.fpu_stack_ptr[0] = 0\n\n this.fpu_control_word = view(Uint16Array, memory, 1036, 1)\n this.fpu_control_word[0] = 0x37f\n this.fpu_status_word = view(Uint16Array, memory, 1040, 1)\n this.fpu_status_word[0] = 0\n this.fpu_ip = view(Int32Array, memory, 1048, 1)\n this.fpu_ip[0] = 0\n this.fpu_ip_selector = view(Int32Array, memory, 1052, 1)\n this.fpu_ip_selector[0] = 0\n this.fpu_opcode = view(Int32Array, memory, 1044, 1)\n this.fpu_opcode[0] = 0\n this.fpu_dp = view(Int32Array, memory, 1056, 1)\n this.fpu_dp[0] = 0\n this.fpu_dp_selector = view(Int32Array, memory, 1060, 1)\n this.fpu_dp_selector[0] = 0\n\n this.reg_xmm32s = view(Int32Array, memory, 832, 8 * 4)\n\n this.mxcsr = view(Int32Array, memory, 824, 1)\n\n // segment registers, tr and ldtr\n this.sreg = view(Uint16Array, memory, 668, 8)\n\n // debug registers\n this.dreg = view(Int32Array, memory, 684, 8)\n\n this.reg_pdpte = view(Int32Array, memory, 968, 8)\n\n this.svga_dirty_bitmap_min_offset = view(Uint32Array, memory, 716, 1)\n this.svga_dirty_bitmap_max_offset = view(Uint32Array, memory, 720, 1)\n\n this.fw_value = []\n this.fw_pointer = 0\n this.option_roms = []\n\n this.io = undefined!\n\n this.bus = bus\n\n this.set_tsc(0, 0)\n\n if (DEBUG) {\n this.seen_code = {}\n this.seen_code_uncompiled = {}\n }\n }\n\n mmap_read8(addr: number): number {\n const value = this.memory_map_read8[addr >>> MMAP_BLOCK_BITS]!(addr)\n dbg_assert(value >= 0 && value <= 0xff)\n return value\n }\n\n mmap_write8(addr: number, value: number): void {\n dbg_assert(value >= 0 && value <= 0xff)\n this.memory_map_write8[addr >>> MMAP_BLOCK_BITS]!(addr, value)\n }\n\n mmap_write16(addr: number, value: number): void {\n const fn = this.memory_map_write8[addr >>> MMAP_BLOCK_BITS]!\n\n dbg_assert(value >= 0 && value <= 0xffff)\n fn(addr, value & 0xff)\n fn((addr + 1) | 0, value >> 8)\n }\n\n mmap_read32(addr: number): number {\n const aligned_addr = addr >>> MMAP_BLOCK_BITS\n\n return this.memory_map_read32[aligned_addr]!(addr)\n }\n\n mmap_write32(addr: number, value: number): void {\n const aligned_addr = addr >>> MMAP_BLOCK_BITS\n\n this.memory_map_write32[aligned_addr]!(addr, value)\n }\n\n mmap_write64(addr: number, value0: number, value1: number): void {\n const aligned_addr = addr >>> MMAP_BLOCK_BITS\n // This should hold since writes across pages are split up\n dbg_assert(aligned_addr === (addr + 7) >>> MMAP_BLOCK_BITS)\n\n const write_func32 = this.memory_map_write32[aligned_addr]!\n write_func32(addr, value0)\n write_func32(addr + 4, value1)\n }\n\n mmap_write128(\n addr: number,\n value0: number,\n value1: number,\n value2: number,\n value3: number,\n ): void {\n const aligned_addr = addr >>> MMAP_BLOCK_BITS\n // This should hold since writes across pages are split up\n dbg_assert(aligned_addr === (addr + 12) >>> MMAP_BLOCK_BITS)\n\n const write_func32 = this.memory_map_write32[aligned_addr]!\n write_func32(addr, value0)\n write_func32(addr + 4, value1)\n write_func32(addr + 8, value2)\n write_func32(addr + 12, value3)\n }\n\n write_blob(blob: Uint8Array | number[], offset: number): void {\n dbg_assert(blob && blob.length >= 0)\n\n if (blob.length) {\n dbg_assert(!this.in_mapped_range(offset))\n dbg_assert(!this.in_mapped_range(offset + blob.length - 1))\n\n this.jit_dirty_cache(offset, offset + blob.length)\n this.mem8.set(blob, offset)\n }\n }\n\n read_blob(offset: number, length: number): Uint8Array {\n if (length) {\n dbg_assert(!this.in_mapped_range(offset))\n dbg_assert(!this.in_mapped_range(offset + length - 1))\n }\n return this.mem8.subarray(offset, offset + length)\n }\n\n clear_opstats(): void {\n new Uint8Array(this.wasm_memory.buffer, 0x8000, 0x20000).fill(0)\n this.wm.exports['profiler_init']()\n }\n\n create_jit_imports(): void {\n // Set this.jit_imports as generated WASM modules will expect\n\n const jit_imports = Object.create(null)\n\n jit_imports['m'] = this.wm.exports['memory']\n\n for (const name of Object.keys(this.wm.exports)) {\n if (\n name.startsWith('_') ||\n name.startsWith('zstd') ||\n name.endsWith('_js')\n ) {\n continue\n }\n\n jit_imports[name] = this.wm.exports[name]\n }\n\n this.jit_imports = jit_imports\n }\n\n wasm_patch(): void {\n const get_optional_import = (name: string) => this.wm.exports[name]\n\n const get_import = (name: string) => {\n const f = get_optional_import(name)\n console.assert(f, 'Missing import: ' + name)\n return f\n }\n\n this.reset_cpu = get_import('reset_cpu')\n\n this.getiopl = get_import('getiopl')\n this.get_eflags = get_import('get_eflags')\n\n this.handle_irqs = get_import('handle_irqs')\n\n this.main_loop = get_import('main_loop')\n\n this.reboot_internal = get_import('reboot_internal')\n\n this.set_jit_config = get_import('set_jit_config')\n\n this.read8 = get_import('read8')\n this.read16 = get_import('read16')\n this.read32s = get_import('read32s')\n this.write8 = get_import('write8')\n this.write16 = get_import('write16')\n this.write32 = get_import('write32')\n this.in_mapped_range = get_import('in_mapped_range')\n\n // used by nasmtests\n this.fpu_load_tag_word = get_import('fpu_load_tag_word')\n this.fpu_load_status_word = get_import('fpu_load_status_word')\n this.fpu_get_sti_f64 = get_import('fpu_get_sti_f64')\n\n this.translate_address_system_read = get_import(\n 'translate_address_system_read_js',\n )\n\n this.get_seg_cs = get_import('get_seg_cs')\n this.get_real_eip = get_import('get_real_eip')\n\n this.clear_tlb = get_import('clear_tlb')\n this.full_clear_tlb = get_import('full_clear_tlb')\n this.update_state_flags = get_import('update_state_flags')\n\n this.set_tsc = get_import('set_tsc')\n this.store_current_tsc = get_import('store_current_tsc')\n\n this.set_cpuid_level = get_import('set_cpuid_level')\n\n this.device_raise_irq = get_import('device_raise_irq')\n this.device_lower_irq = get_import('device_lower_irq')\n\n this.apic_timer = get_import('apic_timer')\n\n if (DEBUG) {\n this.jit_force_generate_unsafe = get_optional_import(\n 'jit_force_generate_unsafe',\n )\n }\n\n this.jit_clear_cache = get_import('jit_clear_cache_js')\n this.jit_dirty_cache = get_import('jit_dirty_cache')\n this.codegen_finalize_finished = get_import('codegen_finalize_finished')\n\n this.allocate_memory = get_import('allocate_memory')\n this.zero_memory = get_import('zero_memory')\n this.is_memory_zeroed = get_import('is_memory_zeroed')\n\n this.svga_allocate_memory = get_import('svga_allocate_memory')\n this.svga_allocate_dest_buffer = get_import('svga_allocate_dest_buffer')\n this.svga_fill_pixel_buffer = get_import('svga_fill_pixel_buffer')\n this.svga_mark_dirty = get_import('svga_mark_dirty')\n\n this.get_pic_addr_master = get_import('get_pic_addr_master')\n this.get_pic_addr_slave = get_import('get_pic_addr_slave')\n this.get_apic_addr = get_import('get_apic_addr')\n this.get_ioapic_addr = get_import('get_ioapic_addr')\n\n this.zstd_create_ctx = get_import('zstd_create_ctx')\n this.zstd_get_src_ptr = get_import('zstd_get_src_ptr')\n this.zstd_free_ctx = get_import('zstd_free_ctx')\n this.zstd_read = get_import('zstd_read')\n this.zstd_read_free = get_import('zstd_read_free')\n }\n\n jit_force_generate(addr: number): void {\n if (!this.jit_force_generate_unsafe) {\n dbg_assert(\n false,\n 'Not supported in this wasm build: jit_force_generate_unsafe',\n )\n return\n }\n\n this.jit_force_generate_unsafe(addr)\n }\n\n jit_clear_func(index: number): void {\n dbg_assert(index >= 0 && index < WASM_TABLE_SIZE)\n this.wm.wasm_table.set(index + WASM_TABLE_OFFSET, null)\n }\n\n jit_clear_all_funcs(): void {\n const table = this.wm.wasm_table\n\n for (let i = 0; i < WASM_TABLE_SIZE; i++) {\n table.set(WASM_TABLE_OFFSET + i, null)\n }\n }\n\n get_state(): any[] {\n const state: any[] = []\n\n state[0] = this.memory_size[0]\n state[1] = new Uint8Array([\n ...this.segment_is_null,\n ...this.segment_access_bytes,\n ])\n state[2] = this.segment_offsets\n state[3] = this.segment_limits\n state[4] = this.protected_mode[0]\n state[5] = this.idtr_offset[0]\n state[6] = this.idtr_size[0]\n state[7] = this.gdtr_offset[0]\n state[8] = this.gdtr_size[0]\n state[9] = this.page_fault[0]\n state[10] = this.cr\n state[11] = this.cpl[0]\n\n state[13] = this.is_32[0]\n\n state[16] = this.stack_size_32[0]\n state[17] = this.in_hlt[0]\n state[18] = this.last_virt_eip[0]\n state[19] = this.eip_phys[0]\n\n state[22] = this.sysenter_cs[0]\n state[23] = this.sysenter_eip[0]\n state[24] = this.sysenter_esp[0]\n state[25] = this.prefixes[0]\n state[26] = this.flags[0]\n state[27] = this.flags_changed[0]\n state[28] = this.last_op1[0]\n\n state[30] = this.last_op_size[0]\n\n state[37] = this.instruction_pointer[0]\n state[38] = this.previous_ip[0]\n state[39] = this.reg32\n state[40] = this.sreg\n state[41] = this.dreg\n state[42] = this.reg_pdpte\n\n this.store_current_tsc()\n state[43] = this.current_tsc\n\n state[45] = this.devices.virtio_9p\n state[46] = this.get_state_apic()\n state[47] = this.devices.rtc\n state[48] = this.devices.pci\n state[49] = this.devices.dma\n state[50] = this.devices.acpi\n // 51 (formerly hpet)\n state[52] = this.devices.vga\n state[53] = this.devices.ps2\n state[54] = this.devices.uart0\n state[55] = this.devices.fdc\n\n if (!this.devices.ide.secondary) {\n if (this.devices.ide.primary?.master.is_atapi) {\n state[56] = this.devices.ide.primary\n } else {\n state[57] = this.devices.ide.primary\n }\n } else {\n state[85] = this.devices.ide\n }\n\n state[58] = this.devices.pit\n state[59] = this.devices.net\n state[60] = this.get_state_pic()\n state[61] = this.devices.sb16\n\n state[62] = this.fw_value\n\n state[63] = this.get_state_ioapic()\n\n state[64] = this.tss_size_32[0]\n\n state[66] = this.reg_xmm32s\n\n state[67] = this.fpu_st\n state[68] = this.fpu_stack_empty[0]\n state[69] = this.fpu_stack_ptr[0]\n state[70] = this.fpu_control_word[0]\n state[71] = this.fpu_ip[0]\n state[72] = this.fpu_ip_selector[0]\n state[73] = this.fpu_dp[0]\n state[74] = this.fpu_dp_selector[0]\n state[75] = this.fpu_opcode[0]\n\n const { packed_memory, bitmap } = this.pack_memory()\n state[77] = packed_memory\n state[78] = new Uint8Array(bitmap.get_buffer())\n\n state[79] = this.devices.uart1\n state[80] = this.devices.uart2\n state[81] = this.devices.uart3\n state[82] = this.devices.virtio_console\n state[83] = this.devices.virtio_net\n state[84] = this.devices.virtio_balloon\n\n // state[85] new ide set above\n\n state[86] = this.last_result\n state[87] = this.fpu_status_word\n state[88] = this.mxcsr\n\n return state\n }\n\n get_state_pic(): any[] {\n const pic_size = 13\n const pic = new Uint8Array(\n this.wasm_memory.buffer,\n this.get_pic_addr_master(),\n pic_size,\n )\n const pic_slave = new Uint8Array(\n this.wasm_memory.buffer,\n this.get_pic_addr_slave(),\n pic_size,\n )\n\n const state: any[] = []\n\n const state_slave: any[] = []\n\n state[0] = pic[0] // irq_mask\n state[1] = pic[1] // irq_map\n state[2] = pic[2] // isr\n state[3] = pic[3] // irr\n state[4] = pic[4] // is_master\n state[5] = state_slave\n state[6] = pic[6] // expect_icw4\n state[7] = pic[7] // state\n state[8] = pic[8] // read_isr\n state[9] = pic[9] // auto_eoi\n state[10] = pic[10] // elcr\n state[11] = pic[11] // irq_value\n state[12] = pic[12] // special_mask_mode\n\n state_slave[0] = pic_slave[0] // irq_mask\n state_slave[1] = pic_slave[1] // irq_map\n state_slave[2] = pic_slave[2] // isr\n state_slave[3] = pic_slave[3] // irr\n state_slave[4] = pic_slave[4] // is_master\n state_slave[5] = null\n state_slave[6] = pic_slave[6] // expect_icw4\n state_slave[7] = pic_slave[7] // state\n state_slave[8] = pic_slave[8] // read_isr\n state_slave[9] = pic_slave[9] // auto_eoi\n state_slave[10] = pic_slave[10] // elcr\n state_slave[11] = pic_slave[11] // irq_value\n state_slave[12] = pic_slave[12] // special_mask_mode\n\n return state\n }\n\n get_state_apic(): Uint8Array {\n const APIC_STRUCT_SIZE = 4 * 46 // keep in sync with apic.rs\n return new Uint8Array(\n this.wasm_memory.buffer,\n this.get_apic_addr(),\n APIC_STRUCT_SIZE,\n )\n }\n\n get_state_ioapic(): Uint8Array {\n const IOAPIC_STRUCT_SIZE = 4 * 52 // keep in sync with ioapic.rs\n return new Uint8Array(\n this.wasm_memory.buffer,\n this.get_ioapic_addr(),\n IOAPIC_STRUCT_SIZE,\n )\n }\n\n set_state(state: any[]): void {\n this.memory_size[0] = state[0]\n\n if (this.mem8.length !== this.memory_size[0]) {\n console.warn(\n 'Note: Memory size mismatch. we=' +\n this.mem8.length +\n ' state=' +\n this.memory_size[0],\n )\n }\n\n if (state[1].length === 8) {\n // NOTE: support for old state images; delete this when bumping STATE_VERSION\n this.segment_is_null.set(state[1])\n this.segment_access_bytes.fill(0x80 | (3 << 5) | 0x10 | 0x02)\n this.segment_access_bytes[REG_CS] =\n 0x80 | (3 << 5) | 0x10 | 0x08 | 0x02\n } else if (state[1].length === 16) {\n this.segment_is_null.set(state[1].subarray(0, 8))\n this.segment_access_bytes.set(state[1].subarray(8, 16))\n } else {\n dbg_assert(\n false,\n 'Unexpected cpu segment state length:' + state[1].length,\n )\n }\n this.segment_offsets.set(state[2])\n this.segment_limits.set(state[3])\n\n this.protected_mode[0] = state[4]\n this.idtr_offset[0] = state[5]\n this.idtr_size[0] = state[6]\n this.gdtr_offset[0] = state[7]\n this.gdtr_size[0] = state[8]\n this.page_fault[0] = state[9]\n this.cr.set(state[10])\n this.cpl[0] = state[11]\n\n this.is_32[0] = state[13]\n\n this.stack_size_32[0] = state[16]\n\n this.in_hlt[0] = state[17]\n this.last_virt_eip[0] = state[18]\n this.eip_phys[0] = state[19]\n\n this.sysenter_cs[0] = state[22]\n this.sysenter_eip[0] = state[23]\n this.sysenter_esp[0] = state[24]\n this.prefixes[0] = state[25]\n\n this.flags[0] = state[26]\n this.flags_changed[0] = state[27]\n this.last_op1[0] = state[28]\n\n this.last_op_size[0] = state[30]\n\n this.instruction_pointer[0] = state[37]\n this.previous_ip[0] = state[38]\n this.reg32.set(state[39])\n this.sreg.set(state[40])\n this.dreg.set(state[41])\n if (state[42]) this.reg_pdpte.set(state[42])\n\n this.set_tsc(state[43][0], state[43][1])\n\n if (this.devices.virtio_9p) this.devices.virtio_9p.set_state(state[45])\n if (state[46]) this.set_state_apic(state[46])\n if (this.devices.rtc) this.devices.rtc.set_state(state[47])\n if (this.devices.dma) this.devices.dma.set_state(state[49])\n if (this.devices.acpi) this.devices.acpi.set_state(state[50])\n // 51 (formerly hpet)\n if (this.devices.vga) this.devices.vga.set_state(state[52])\n if (this.devices.ps2) this.devices.ps2.set_state(state[53])\n if (this.devices.uart0) this.devices.uart0.set_state(state[54])\n if (this.devices.fdc) this.devices.fdc.set_state(state[55])\n\n if (state[56] || state[57]) {\n // ide device from older version of v86, only primary: state[56] contains cdrom, state[57] contains hard drive\n\n const ide_config: any = [\n [undefined, undefined],\n [undefined, undefined],\n ]\n if (state[56]) {\n ide_config[0][0] = {\n is_cdrom: true,\n buffer: this.devices.cdrom.buffer,\n }\n } else {\n ide_config[0][0] = {\n is_cdrom: false,\n buffer: this.devices.ide.primary!.master.buffer,\n }\n }\n this.devices.ide = new IDEController(\n this,\n this.devices.ide.bus,\n ide_config,\n )\n this.devices.cdrom = state[56]\n ? this.devices.ide.primary!.master\n : undefined\n this.devices.ide.primary!.set_state(state[56] || state[57])\n } else if (state[85]) {\n this.devices.ide.set_state(state[85])\n }\n\n if (this.devices.pci) this.devices.pci.set_state(state[48])\n\n if (this.devices.pit) this.devices.pit.set_state(state[58])\n if (this.devices.net) this.devices.net.set_state(state[59])\n this.set_state_pic(state[60])\n if (this.devices.sb16) this.devices.sb16.set_state(state[61])\n\n if (this.devices.uart1) this.devices.uart1.set_state(state[79])\n if (this.devices.uart2) this.devices.uart2.set_state(state[80])\n if (this.devices.uart3) this.devices.uart3.set_state(state[81])\n if (this.devices.virtio_console)\n this.devices.virtio_console.set_state(state[82])\n if (this.devices.virtio_net)\n this.devices.virtio_net.set_state(state[83])\n if (this.devices.virtio_balloon)\n this.devices.virtio_balloon.set_state(state[84])\n\n this.fw_value = state[62]\n\n if (state[63]) this.set_state_ioapic(state[63])\n\n this.tss_size_32[0] = state[64]\n\n this.reg_xmm32s.set(state[66])\n\n this.fpu_st.set(state[67])\n this.fpu_stack_empty[0] = state[68]\n this.fpu_stack_ptr[0] = state[69]\n this.fpu_control_word[0] = state[70]\n this.fpu_ip[0] = state[71]\n this.fpu_ip_selector[0] = state[72]\n this.fpu_dp[0] = state[73]\n this.fpu_dp_selector[0] = state[74]\n this.fpu_opcode[0] = state[75]\n\n if (state[86] !== undefined) this.last_result = state[86]\n if (state[87] !== undefined) this.fpu_status_word = state[87]\n if (state[88] !== undefined) this.mxcsr = state[88]\n\n const bitmap = new Bitmap(state[78].buffer)\n const packed_memory = state[77]\n this.unpack_memory(bitmap, packed_memory)\n\n this.update_state_flags()\n\n this.full_clear_tlb()\n\n this.jit_clear_cache()\n }\n\n set_state_pic(state: any[]): void {\n // Note: This could exists for compatibility with old state images\n // It should be deleted when the state version changes\n\n const pic_size = 13\n const pic = new Uint8Array(\n this.wasm_memory.buffer,\n this.get_pic_addr_master(),\n pic_size,\n )\n const pic_slave = new Uint8Array(\n this.wasm_memory.buffer,\n this.get_pic_addr_slave(),\n pic_size,\n )\n\n pic[0] = state[0] // irq_mask\n pic[1] = state[1] // irq_map\n pic[2] = state[2] // isr\n pic[3] = state[3] // irr\n pic[4] = state[4] // is_master\n const state_slave = state[5]\n pic[6] = state[6] // expect_icw4\n pic[7] = state[7] // state\n pic[8] = state[8] // read_isr\n pic[9] = state[9] // auto_eoi\n pic[10] = state[10] // elcr\n pic[11] = state[11] // irq_value (undefined in old state images)\n pic[12] = state[12] // special_mask_mode (undefined in old state images)\n\n pic_slave[0] = state_slave[0] // irq_mask\n pic_slave[1] = state_slave[1] // irq_map\n pic_slave[2] = state_slave[2] // isr\n pic_slave[3] = state_slave[3] // irr\n pic_slave[4] = state_slave[4] // is_master\n // dummy\n pic_slave[6] = state_slave[6] // expect_icw4\n pic_slave[7] = state_slave[7] // state\n pic_slave[8] = state_slave[8] // read_isr\n pic_slave[9] = state_slave[9] // auto_eoi\n pic_slave[10] = state_slave[10] // elcr\n pic_slave[11] = state_slave[11] // irq_value (undefined in old state images)\n pic_slave[12] = state_slave[12] // special_mask_mode (undefined in old state images)\n }\n\n set_state_apic(state: any): void {\n const APIC_STRUCT_SIZE = 4 * 46 // keep in sync with apic.rs\n const IOAPIC_CONFIG_MASKED = 1 << 16\n\n if (state instanceof Array) {\n // old js state image; delete this code path when the state version changes\n const apic = new Int32Array(\n this.wasm_memory.buffer,\n this.get_apic_addr(),\n APIC_STRUCT_SIZE >> 2,\n )\n apic[0] = state[0] // apic_id\n apic[1] = state[1] // timer_divier\n apic[2] = state[2] // timer_divider_shift\n apic[3] = state[3] // timer_initial_count\n apic[4] = state[4] // timer_current_count\n // skip next_tick (in js: state[4]; in rust: apic[6] and apic[7])\n apic[8] = state[6] // lvt_timer\n apic[9] = state[7] // lvt_perf_counter\n apic[10] = state[8] // lvt_int0\n apic[11] = state[9] // lvt_int1\n apic[12] = state[10] // lvt_error\n apic[13] = state[11] // tpr\n apic[14] = state[12] // icr0\n apic[15] = state[13] // icr1\n apic.set(state[15], 16) // irr\n apic.set(state[15], 24) // isr\n apic.set(state[16], 32) // tmr\n apic[40] = state[17] // spurious_vector\n apic[41] = state[18] // destination_format\n apic[42] = state[19] // local_destination\n apic[43] = state[20] // error\n apic[44] = state[21] // read_error\n apic[45] = state[22] || IOAPIC_CONFIG_MASKED // lvt_thermal_sensor\n } else {\n const apic = new Uint8Array(\n this.wasm_memory.buffer,\n this.get_apic_addr(),\n APIC_STRUCT_SIZE,\n )\n dbg_assert(state instanceof Uint8Array)\n dbg_assert(state.length === apic.length) // later versions might need to handle state upgrades here\n apic.set(state)\n }\n }\n\n set_state_ioapic(state: any): void {\n const IOAPIC_STRUCT_SIZE = 4 * 52 // keep in sync with ioapic.rs\n\n if (state instanceof Array) {\n // old js state image; delete this code path when the state version changes\n dbg_assert(state[0].length === 24)\n dbg_assert(state[1].length === 24)\n dbg_assert(state.length === 6)\n const ioapic = new Int32Array(\n this.wasm_memory.buffer,\n this.get_ioapic_addr(),\n IOAPIC_STRUCT_SIZE >> 2,\n )\n ioapic.set(state[0], 0) // ioredtbl_config\n ioapic.set(state[1], 24) // ioredtbl_destination\n ioapic[48] = state[2] // ioregsel\n ioapic[49] = state[3] // ioapic_id\n ioapic[50] = state[4] // irr\n ioapic[51] = state[5] // irq_value\n } else {\n const ioapic = new Uint8Array(\n this.wasm_memory.buffer,\n this.get_ioapic_addr(),\n IOAPIC_STRUCT_SIZE,\n )\n dbg_assert(state instanceof Uint8Array)\n dbg_assert(state.length === ioapic.length) // later versions might need to handle state upgrades here\n ioapic.set(state)\n }\n }\n\n pack_memory(): { bitmap: Bitmap; packed_memory: Uint8Array } {\n dbg_assert((this.mem8.length & 0xfff) === 0)\n\n const page_count = this.mem8.length >> 12\n const nonzero_pages: number[] = []\n for (let page = 0; page < page_count; page++) {\n if (!this.is_memory_zeroed(page << 12, 0x1000)) {\n nonzero_pages.push(page)\n }\n }\n\n const bitmap = new Bitmap(page_count)\n const packed_memory = new Uint8Array(nonzero_pages.length << 12)\n\n for (const [i, page] of nonzero_pages.entries()) {\n bitmap.set(page, 1)\n\n const offset = page << 12\n const page_contents = this.mem8.subarray(offset, offset + 0x1000)\n packed_memory.set(page_contents, i << 12)\n }\n\n return { bitmap, packed_memory }\n }\n\n unpack_memory(bitmap: Bitmap, packed_memory: Uint8Array): void {\n this.zero_memory(0, this.memory_size[0])\n\n const page_count = this.memory_size[0] >> 12\n let packed_page = 0\n\n for (let page = 0; page < page_count; page++) {\n if (bitmap.get(page)) {\n const offset = packed_page << 12\n const v = packed_memory.subarray(offset, offset + 0x1000)\n this.mem8.set(v, page << 12)\n packed_page++\n }\n }\n }\n\n reboot(): void {\n this.reset_cpu()\n\n this.fw_value = []\n\n if (this.devices.virtio_9p) {\n this.devices.virtio_9p.reset()\n }\n if (this.devices.virtio_console) {\n this.devices.virtio_console.reset()\n }\n if (this.devices.virtio_net) {\n this.devices.virtio_net.reset()\n }\n if (this.devices.ps2) {\n this.devices.ps2.reset()\n }\n\n this.load_bios()\n }\n\n reset_memory(): void {\n this.mem8.fill(0)\n }\n\n create_memory(size: number, minimum_size: number): void {\n if (size < minimum_size) {\n size = minimum_size\n dbg_log('Rounding memory size up to ' + size, LOG_CPU)\n } else if ((size | 0) < 0) {\n size = Math.pow(2, 31) - MMAP_BLOCK_SIZE\n dbg_log('Rounding memory size down to ' + size, LOG_CPU)\n }\n\n size = (((size - 1) | (MMAP_BLOCK_SIZE - 1)) + 1) | 0\n dbg_assert((size | 0) > 0)\n dbg_assert((size & (MMAP_BLOCK_SIZE - 1)) === 0)\n\n console.assert(\n this.memory_size[0] === 0,\n 'Expected uninitialised memory',\n )\n\n this.memory_size[0] = size\n\n const memory_offset = this.allocate_memory(size)\n\n this.mem8 = view(Uint8Array, this.wasm_memory, memory_offset, size)\n this.mem32s = view(\n Uint32Array,\n this.wasm_memory,\n memory_offset,\n size >> 2,\n )\n }\n\n init(settings: any, device_bus: BusConnector): void {\n this.create_memory(\n settings.memory_size || 64 * 1024 * 1024,\n settings.initrd ? 64 * 1024 * 1024 : 1024 * 1024,\n )\n\n if (settings.disable_jit) {\n this.set_jit_config(0, 1)\n }\n\n if (settings.cpuid_level) this.set_cpuid_level(settings.cpuid_level)\n\n this.acpi_enabled[0] = +settings.acpi\n\n this.reset_cpu()\n\n const io = new IO(this)\n this.io = io\n\n this.bios.main = settings.bios\n this.bios.vga = settings.vga_bios\n\n this.load_bios()\n\n if (settings.bzimage) {\n const option_rom = load_kernel(\n this.mem8,\n settings.bzimage,\n settings.initrd,\n settings.cmdline || '',\n )\n\n if (option_rom) {\n this.option_roms.push(option_rom)\n }\n }\n\n io.register_read(0xb3, this, function (this: CPU) {\n // seabios smm_relocate_and_restore\n dbg_log('port 0xB3 read')\n return 0\n })\n\n let a20_byte = 0\n\n io.register_read(0x92, this, function () {\n return a20_byte\n })\n\n io.register_write(0x92, this, function (_out_byte: number) {\n a20_byte = _out_byte\n })\n\n io.register_read(0x511, this, function (this: CPU) {\n // bios config port (used by seabios and kvm-unit-test)\n if (this.fw_pointer < this.fw_value.length) {\n return this.fw_value[this.fw_pointer++]\n } else {\n dbg_assert(false, 'config port: Read past value')\n return 0\n }\n })\n io.register_write(\n 0x510,\n this,\n undefined,\n function (this: CPU, value: number) {\n // https://wiki.osdev.org/QEMU_fw_cfg\n // https://github.com/qemu/qemu/blob/master/docs/specs/fw_cfg.txt\n\n dbg_log('bios config port, index=' + h(value))\n\n function i32(x: number): Uint8Array {\n return new Uint8Array(Int32Array.of(x).buffer)\n }\n\n function to_be16(x: number): number {\n return (x >> 8) | ((x << 8) & 0xff00)\n }\n\n function to_be32(x: number): number {\n return (\n (x << 24) |\n ((x << 8) & 0xff0000) |\n ((x >> 8) & 0xff00) |\n (x >>> 24)\n )\n }\n\n this.fw_pointer = 0\n\n if (value === FW_CFG_SIGNATURE) {\n // Pretend to be qemu (for seabios)\n this.fw_value = i32(FW_CFG_SIGNATURE_QEMU)\n } else if (value === FW_CFG_ID) {\n this.fw_value = i32(0)\n } else if (value === FW_CFG_RAM_SIZE) {\n this.fw_value = i32(this.memory_size[0])\n } else if (value === FW_CFG_NB_CPUS) {\n this.fw_value = i32(1)\n } else if (value === FW_CFG_MAX_CPUS) {\n this.fw_value = i32(1)\n } else if (value === FW_CFG_NUMA) {\n this.fw_value = new Uint8Array(16)\n } else if (value === FW_CFG_FILE_DIR) {\n const buffer_size = 4 + 64 * this.option_roms.length\n const buffer32 = new Int32Array(buffer_size)\n const buffer8 = new Uint8Array(buffer32.buffer)\n\n buffer32[0] = to_be32(this.option_roms.length)\n\n for (let i = 0; i < this.option_roms.length; i++) {\n const { name, data } = this.option_roms[i]\n const file_struct_ptr = 4 + 64 * i\n\n dbg_assert(FW_CFG_FILE_START + i < 0x10000)\n buffer32[(file_struct_ptr + 0) >> 2] = to_be32(\n data.length,\n )\n buffer32[(file_struct_ptr + 4) >> 2] = to_be16(\n FW_CFG_FILE_START + i,\n )\n\n dbg_assert(name.length < 64 - 8)\n\n for (let j = 0; j < name.length; j++) {\n buffer8[file_struct_ptr + 8 + j] =\n name.charCodeAt(j)\n }\n }\n\n this.fw_value = buffer8\n } else if (\n value >= FW_CFG_CUSTOM_START &&\n value < FW_CFG_FILE_START\n ) {\n this.fw_value = i32(0)\n } else if (\n value >= FW_CFG_FILE_START &&\n value - FW_CFG_FILE_START < this.option_roms.length\n ) {\n const i = value - FW_CFG_FILE_START\n this.fw_value = this.option_roms[i].data\n } else {\n dbg_log('Warning: Unimplemented fw index: ' + h(value))\n this.fw_value = i32(0)\n }\n },\n )\n\n if (DEBUG) {\n // Avoid logging noisey ports\n io.register_write(0x80, this, function (_out_byte: number) {})\n io.register_read(0x80, this, function () {\n return 0xff\n })\n io.register_write(0xe9, this, function (_out_byte: number) {})\n }\n\n // @ts-expect-error Devices are populated below\n this.devices = {}\n\n // TODO: Make this more configurable\n if (settings.load_devices) {\n this.devices.pci = new PCI(this)\n\n if (this.acpi_enabled[0]) {\n this.devices.acpi = new ACPI(this)\n }\n\n this.devices.rtc = new RTC(this)\n this.fill_cmos(this.devices.rtc, settings)\n\n this.devices.dma = new DMA(this)\n\n this.devices.vga = new VGAScreen(\n this,\n device_bus,\n settings.screen,\n settings.vga_memory_size || 8 * 1024 * 1024,\n )\n\n this.devices.ps2 = new PS2(this, device_bus)\n\n this.devices.uart0 = new UART(this, 0x3f8, device_bus)\n\n if (settings.uart1) {\n this.devices.uart1 = new UART(this, 0x2f8, device_bus)\n }\n if (settings.uart2) {\n this.devices.uart2 = new UART(this, 0x3e8, device_bus)\n }\n if (settings.uart3) {\n this.devices.uart3 = new UART(this, 0x2e8, device_bus)\n }\n\n this.devices.fdc = new FloppyController(\n this,\n settings.fda,\n settings.fdb,\n )\n\n const ide_config: any = [\n [undefined, undefined],\n [undefined, undefined],\n ]\n if (settings.hda) {\n ide_config[0][0] = { buffer: settings.hda }\n ide_config[0][1] = { buffer: settings.hdb }\n }\n ide_config[1][0] = { is_cdrom: true, buffer: settings.cdrom }\n this.devices.ide = new IDEController(this, device_bus, ide_config)\n this.devices.cdrom = this.devices.ide.secondary!.master\n\n this.devices.pit = new PIT(this, device_bus)\n\n if (settings.net_device.type === 'ne2k') {\n this.devices.net = new Ne2k(\n this,\n device_bus,\n settings.preserve_mac_from_state_image,\n settings.mac_address_translation,\n )\n } else if (settings.net_device.type === 'virtio') {\n this.devices.virtio_net = new VirtioNet(\n this,\n device_bus,\n settings.preserve_mac_from_state_image,\n settings.net_device.mtu,\n )\n }\n\n if (settings.fs9p) {\n this.devices.virtio_9p = new Virtio9p(\n settings.fs9p,\n this,\n device_bus,\n )\n } else if (settings.handle9p) {\n this.devices.virtio_9p = new Virtio9pHandler(\n settings.handle9p,\n this,\n )\n } else if (settings.proxy9p) {\n this.devices.virtio_9p = new Virtio9pProxy(\n settings.proxy9p,\n this,\n )\n }\n if (settings.virtio_console) {\n this.devices.virtio_console = new VirtioConsole(\n this,\n device_bus,\n )\n }\n if (settings.virtio_balloon) {\n this.devices.virtio_balloon = new VirtioBalloon(\n this,\n device_bus,\n )\n }\n\n this.devices.sb16 = new SB16(this, device_bus)\n }\n\n if (settings.multiboot) {\n dbg_log('loading multiboot', LOG_CPU)\n const option_rom = this.load_multiboot_option_rom(\n settings.multiboot,\n settings.initrd,\n settings.cmdline,\n )\n\n if (option_rom) {\n if (this.bios.main) {\n dbg_log('adding option rom for multiboot', LOG_CPU)\n this.option_roms.push(option_rom)\n } else {\n dbg_log('loaded multiboot without bios', LOG_CPU)\n this.reg32[REG_EAX] = this.io.port_read32(0xf4)\n }\n }\n }\n\n this.debug_init()\n }\n\n load_multiboot(buffer: ArrayBuffer): void {\n if (this.bios.main) {\n dbg_assert(false, 'load_multiboot not supported with BIOS')\n }\n\n const option_rom = this.load_multiboot_option_rom(buffer, undefined, '')\n if (option_rom) {\n dbg_log('loaded multiboot', LOG_CPU)\n this.reg32[REG_EAX] = this.io.port_read32(0xf4)\n }\n }\n\n load_multiboot_option_rom(\n buffer: ArrayBuffer,\n initrd: ArrayBuffer | undefined,\n cmdline: string | undefined,\n ): OptionRom | undefined {\n // https://www.gnu.org/software/grub/manual/multiboot/multiboot.html\n\n dbg_log(\n 'Trying multiboot from buffer of size ' + buffer.byteLength,\n LOG_CPU,\n )\n\n const ELF_MAGIC = 0x464c457f\n const MULTIBOOT_HEADER_MAGIC = 0x1badb002\n const MULTIBOOT_HEADER_MEMORY_INFO = 0x2\n const MULTIBOOT_HEADER_ADDRESS = 0x10000\n const MULTIBOOT_BOOTLOADER_MAGIC = 0x2badb002\n const MULTIBOOT_SEARCH_BYTES = 8192\n const MULTIBOOT_INFO_STRUCT_LEN = 116\n const MULTIBOOT_INFO_CMDLINE = 0x4\n const MULTIBOOT_INFO_MODS = 0x8\n const MULTIBOOT_INFO_MEM_MAP = 0x40\n\n let buf32: Int32Array\n if (buffer.byteLength < MULTIBOOT_SEARCH_BYTES) {\n buf32 = new Int32Array(MULTIBOOT_SEARCH_BYTES / 4)\n new Uint8Array(buf32.buffer).set(new Uint8Array(buffer))\n } else {\n buf32 = new Int32Array(buffer, 0, MULTIBOOT_SEARCH_BYTES / 4)\n }\n\n for (let offset = 0; offset < MULTIBOOT_SEARCH_BYTES; offset += 4) {\n let flags: number\n if (buf32[offset >> 2] === MULTIBOOT_HEADER_MAGIC) {\n flags = buf32[(offset + 4) >> 2]\n const checksum = buf32[(offset + 8) >> 2]\n const total = (MULTIBOOT_HEADER_MAGIC + flags + checksum) | 0\n\n if (total) {\n dbg_log('Multiboot checksum check failed', LOG_CPU)\n continue\n }\n } else {\n continue\n }\n\n dbg_log(\n 'Multiboot magic found, flags: ' + h(flags >>> 0, 8),\n LOG_CPU,\n )\n // bit 0 : load modules on page boundaries (may as well, if we load modules)\n // bit 1 : provide a memory map (which we always will)\n dbg_assert((flags & ~MULTIBOOT_HEADER_ADDRESS & ~3) === 0, 'TODO')\n\n // do this in a io register hook, so it can happen after BIOS does its work\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const cpu = this\n\n this.io.register_read(\n 0xf4,\n this,\n function () {\n return 0\n },\n function () {\n return 0\n },\n function () {\n // actually do the load and return the multiboot magic\n const multiboot_info_addr = 0x7c00\n let multiboot_data =\n multiboot_info_addr + MULTIBOOT_INFO_STRUCT_LEN\n let info = 0\n\n // command line\n if (cmdline) {\n info |= MULTIBOOT_INFO_CMDLINE\n\n cpu.write32(multiboot_info_addr + 16, multiboot_data)\n\n cmdline += '\\x00'\n const encoder = new TextEncoder()\n const cmdline_utf8 = encoder.encode(cmdline)\n cpu.write_blob(cmdline_utf8, multiboot_data)\n multiboot_data += cmdline_utf8.length\n }\n\n // memory map\n if (flags & MULTIBOOT_HEADER_MEMORY_INFO) {\n info |= MULTIBOOT_INFO_MEM_MAP\n let multiboot_mmap_count = 0\n cpu.write32(multiboot_info_addr + 44, 0)\n cpu.write32(multiboot_info_addr + 48, multiboot_data)\n\n // Create a memory map for the multiboot kernel\n // does not exclude traditional bios exclusions\n let start = 0\n let was_memory = false\n for (\n let addr = 0;\n addr < MMAP_MAX;\n addr += MMAP_BLOCK_SIZE\n ) {\n if (\n was_memory &&\n cpu.memory_map_read8[\n addr >>> MMAP_BLOCK_BITS\n ] !== undefined\n ) {\n cpu.write32(multiboot_data, 20) // size\n cpu.write32(multiboot_data + 4, start) //addr (64-bit)\n cpu.write32(multiboot_data + 8, 0)\n cpu.write32(multiboot_data + 12, addr - start) // len (64-bit)\n cpu.write32(multiboot_data + 16, 0)\n cpu.write32(multiboot_data + 20, 1) // type (MULTIBOOT_MEMORY_AVAILABLE)\n multiboot_data += 24\n multiboot_mmap_count += 24\n was_memory = false\n } else if (\n !was_memory &&\n cpu.memory_map_read8[\n addr >>> MMAP_BLOCK_BITS\n ] === undefined\n ) {\n start = addr\n was_memory = true\n }\n }\n dbg_assert(\n !was_memory,\n \"top of 4GB shouldn't have memory\",\n )\n cpu.write32(\n multiboot_info_addr + 44,\n multiboot_mmap_count,\n )\n }\n\n let entrypoint = 0\n let top_of_load = 0\n\n if (flags & MULTIBOOT_HEADER_ADDRESS) {\n dbg_log(\n 'Multiboot specifies its own address table',\n LOG_CPU,\n )\n\n const header_addr = buf32[(offset + 12) >> 2]\n const load_addr = buf32[(offset + 16) >> 2]\n const load_end_addr = buf32[(offset + 20) >> 2]\n const bss_end_addr = buf32[(offset + 24) >> 2]\n const entry_addr = buf32[(offset + 28) >> 2]\n\n dbg_log(\n 'header=' +\n h(header_addr, 8) +\n ' load=' +\n h(load_addr, 8) +\n ' load_end=' +\n h(load_end_addr, 8) +\n ' bss_end=' +\n h(bss_end_addr, 8) +\n ' entry=' +\n h(entry_addr, 8),\n )\n\n dbg_assert(load_addr <= header_addr)\n\n const file_start = offset - (header_addr - load_addr)\n\n let length: number | undefined\n if (load_end_addr === 0) {\n length = undefined\n } else {\n dbg_assert(load_end_addr >= load_addr)\n length = load_end_addr - load_addr\n }\n\n const blob = new Uint8Array(buffer, file_start, length)\n cpu.write_blob(blob, load_addr)\n\n entrypoint = entry_addr | 0\n top_of_load = Math.max(load_end_addr, bss_end_addr)\n } else if (buf32[0] === ELF_MAGIC) {\n dbg_log('Multiboot image is in elf format', LOG_CPU)\n\n const elf = read_elf(buffer)\n\n entrypoint = elf.header.entry\n\n for (const program of elf.program_headers) {\n if (program.type === 0) {\n // null\n } else if (program.type === 1) {\n // load\n\n dbg_assert(program.filesz <= program.memsz)\n\n if (\n program.paddr + program.memsz <\n cpu.memory_size[0]\n ) {\n if (\n program.filesz\n ) // offset might be outside of buffer if filesz is 0\n {\n const blob = new Uint8Array(\n buffer,\n program.offset,\n program.filesz,\n )\n cpu.write_blob(blob, program.paddr)\n }\n top_of_load = Math.max(\n top_of_load,\n program.paddr + program.memsz,\n )\n dbg_log(\n 'prg load ' +\n program.paddr +\n ' to ' +\n (program.paddr + program.memsz),\n LOG_CPU,\n )\n\n // Since multiboot specifies that paging is disabled, we load to the physical address;\n // but the entry point is specified in virtual addresses so adjust the entrypoint if needed\n\n if (\n entrypoint === elf.header.entry &&\n program.vaddr <= entrypoint &&\n program.vaddr + program.memsz >\n entrypoint\n ) {\n entrypoint =\n entrypoint -\n program.vaddr +\n program.paddr\n }\n } else {\n dbg_log(\n 'Warning: Skipped loading section, paddr=' +\n h(program.paddr) +\n ' memsz=' +\n program.memsz,\n LOG_CPU,\n )\n }\n } else if (\n program.type === 2 || // dynamic\n program.type === 3 || // interp\n program.type === 4 || // note\n program.type === 6 || // phdr\n program.type === 7 || // tls\n program.type === 0x6474e550 || // gnu_eh_frame\n program.type === 0x6474e551 || // gnu_stack\n program.type === 0x6474e552 || // gnu_relro\n program.type === 0x6474e553\n ) // gnu_property\n {\n dbg_log(\n 'skip load type ' +\n program.type +\n ' ' +\n program.paddr +\n ' to ' +\n (program.paddr + program.memsz),\n LOG_CPU,\n )\n // ignore for now\n } else {\n dbg_assert(\n false,\n 'unimplemented elf section type: ' +\n h(program.type),\n )\n }\n }\n } else {\n dbg_assert(false, 'Not a bootable multiboot format')\n }\n\n if (initrd) {\n info |= MULTIBOOT_INFO_MODS\n\n cpu.write32(multiboot_info_addr + 20, 1) // mods_count\n cpu.write32(multiboot_info_addr + 24, multiboot_data) // mods_addr;\n\n let ramdisk_address = top_of_load\n if ((ramdisk_address & 4095) !== 0) {\n ramdisk_address = (ramdisk_address & ~4095) + 4096\n }\n dbg_log('ramdisk address ' + ramdisk_address)\n const ramdisk_top = ramdisk_address + initrd.byteLength\n\n cpu.write32(multiboot_data, ramdisk_address) // mod_start\n cpu.write32(multiboot_data + 4, ramdisk_top) // mod_end\n cpu.write32(multiboot_data + 8, 0) // string\n cpu.write32(multiboot_data + 12, 0) // reserved\n multiboot_data += 16\n\n dbg_assert(ramdisk_top < cpu.memory_size[0])\n\n cpu.write_blob(new Uint8Array(initrd), ramdisk_address)\n }\n\n cpu.write32(multiboot_info_addr, info)\n\n // set state for multiboot\n\n cpu.reg32[REG_EBX] = multiboot_info_addr\n cpu.cr[0] = 1\n cpu.protected_mode[0] = +true\n cpu.flags[0] = FLAGS_DEFAULT\n cpu.is_32[0] = +true\n cpu.stack_size_32[0] = +true\n\n for (let i = 0; i < 6; i++) {\n cpu.segment_is_null[i] = 0\n cpu.segment_offsets[i] = 0\n cpu.segment_limits[i] = 0xffffffff\n // cpu.segment_access_bytes[i]\n // Value doesn't matter, OS isn't allowed to reload without setting\n // up a proper GDT\n cpu.sreg[i] = 0xb002\n }\n cpu.instruction_pointer[0] =\n (cpu.get_seg_cs() + entrypoint) | 0\n cpu.update_state_flags()\n dbg_log('Starting multiboot kernel at:', LOG_CPU)\n cpu.dump_state()\n cpu.dump_regs_short()\n\n return MULTIBOOT_BOOTLOADER_MAGIC\n },\n )\n\n // only for kvm-unit-test\n this.io.register_write_consecutive(\n 0xf4,\n this,\n function (value: number) {\n console.log('Test exited with code ' + h(value, 2))\n throw 'HALT'\n },\n function () {},\n function () {},\n function () {},\n )\n\n // only for kvm-unit-test\n for (let i = 0; i <= 0xf; i++) {\n function handle_write(this: CPU, value: number) {\n dbg_log(\n 'kvm-unit-test: Set irq ' + h(i) + ' to ' + h(value, 2),\n )\n if (value) {\n this.device_raise_irq(i)\n } else {\n this.device_lower_irq(i)\n }\n }\n\n this.io.register_write(\n 0x2000 + i,\n this,\n handle_write,\n handle_write,\n handle_write,\n )\n }\n\n // This rom will be executed by seabios after its initialisation\n // It sets up the multiboot environment.\n const SIZE = 0x200\n\n const data8 = new Uint8Array(SIZE)\n const data16 = new Uint16Array(data8.buffer)\n\n data16[0] = 0xaa55\n data8[2] = SIZE / 0x200\n let i = 3\n // trigger load\n data8[i++] = 0x66 // in 0xF4\n data8[i++] = 0xe5\n data8[i++] = 0xf4\n\n dbg_assert(i < SIZE)\n\n const checksum_index = i\n data8[checksum_index] = 0\n\n let rom_checksum = 0\n\n for (let i = 0; i < data8.length; i++) {\n rom_checksum += data8[i]\n }\n\n data8[checksum_index] = -rom_checksum\n\n return {\n name: 'genroms/multiboot.bin',\n data: data8,\n }\n }\n dbg_log('Multiboot header not found', LOG_CPU)\n return undefined\n }\n\n fill_cmos(rtc: RTC, settings: any): void {\n const boot_order = settings.boot_order || BOOT_ORDER_CD_FIRST\n\n // Used by seabios to determine the boot order\n // Nibble\n // 1: FloppyPrio\n // 2: HDPrio\n // 3: CDPrio\n // 4: BEVPrio\n // bootflag 1, high nibble, lowest priority\n // Low nibble: Disable floppy signature check (1)\n rtc.cmos_write(CMOS_BIOS_BOOTFLAG1, 1 | ((boot_order >> 4) & 0xf0))\n\n // bootflag 2, both nibbles, high and middle priority\n rtc.cmos_write(CMOS_BIOS_BOOTFLAG2, boot_order & 0xff)\n\n // 640k or less if less memory is used\n rtc.cmos_write(CMOS_MEM_BASE_LOW, 640 & 0xff)\n rtc.cmos_write(CMOS_MEM_BASE_HIGH, 640 >> 8)\n\n let memory_above_1m = 0 // in k\n if (this.memory_size[0] >= 1024 * 1024) {\n memory_above_1m = (this.memory_size[0] - 1024 * 1024) >> 10\n memory_above_1m = Math.min(memory_above_1m, 0xffff)\n }\n\n rtc.cmos_write(CMOS_MEM_OLD_EXT_LOW, memory_above_1m & 0xff)\n rtc.cmos_write(CMOS_MEM_OLD_EXT_HIGH, (memory_above_1m >> 8) & 0xff)\n rtc.cmos_write(CMOS_MEM_EXTMEM_LOW, memory_above_1m & 0xff)\n rtc.cmos_write(CMOS_MEM_EXTMEM_HIGH, (memory_above_1m >> 8) & 0xff)\n\n let memory_above_16m = 0 // in 64k blocks\n if (this.memory_size[0] >= 16 * 1024 * 1024) {\n memory_above_16m = (this.memory_size[0] - 16 * 1024 * 1024) >> 16\n memory_above_16m = Math.min(memory_above_16m, 0xffff)\n }\n rtc.cmos_write(CMOS_MEM_EXTMEM2_LOW, memory_above_16m & 0xff)\n rtc.cmos_write(CMOS_MEM_EXTMEM2_HIGH, (memory_above_16m >> 8) & 0xff)\n\n // memory above 4G (not supported by this emulator)\n rtc.cmos_write(CMOS_MEM_HIGHMEM_LOW, 0)\n rtc.cmos_write(CMOS_MEM_HIGHMEM_MID, 0)\n rtc.cmos_write(CMOS_MEM_HIGHMEM_HIGH, 0)\n\n rtc.cmos_write(CMOS_EQUIPMENT_INFO, 0x2f)\n\n rtc.cmos_write(CMOS_BIOS_SMP_COUNT, 0)\n\n // Used by bochs BIOS to skip the boot menu delay.\n if (settings.fastboot) rtc.cmos_write(0x3f, 0x01)\n }\n\n load_bios(): void {\n const bios = this.bios.main\n const vga_bios = this.bios.vga\n\n if (!bios) {\n dbg_log('Warning: No BIOS')\n return\n }\n\n dbg_assert(bios instanceof ArrayBuffer)\n\n // load bios\n const data = new Uint8Array(bios),\n start = 0x100000 - bios.byteLength\n\n this.write_blob(data, start)\n\n if (vga_bios) {\n dbg_assert(vga_bios instanceof ArrayBuffer)\n\n // load vga bios\n const vga_bios8 = new Uint8Array(vga_bios)\n\n // older versions of seabios\n this.write_blob(vga_bios8, 0xc0000)\n\n // newer versions of seabios (needs to match pci rom address, see vga.js)\n this.io.mmap_register(\n 0xfeb00000,\n 0x100000,\n function (addr: number) {\n addr = (addr - 0xfeb00000) | 0\n if (addr < vga_bios8.length) {\n return vga_bios8[addr]\n } else {\n return 0\n }\n },\n function (_addr: number, _value: number) {\n dbg_assert(false, 'Unexpected write to VGA rom')\n },\n )\n } else {\n dbg_log('Warning: No VGA BIOS')\n }\n\n // seabios expects the bios to be mapped to 0xFFF00000 also\n this.io.mmap_register(\n 0xfff00000,\n 0x100000,\n (addr: number) => {\n addr &= 0xfffff\n return this.mem8[addr]\n },\n (addr: number, value: number) => {\n addr &= 0xfffff\n this.mem8[addr] = value\n },\n )\n }\n\n codegen_finalize(\n wasm_table_index: number,\n start: number,\n state_flags: number,\n ptr: number,\n len: number,\n ): void {\n ptr >>>= 0\n len >>>= 0\n\n dbg_assert(wasm_table_index >= 0 && wasm_table_index < WASM_TABLE_SIZE)\n\n const code = new Uint8Array(this.wasm_memory.buffer, ptr, len)\n\n if (DEBUG) {\n if (DUMP_GENERATED_WASM && !this.seen_code[start]) {\n this.dump_wasm(code)\n\n const DUMP_ASSEMBLY = false\n\n if (DUMP_ASSEMBLY) {\n let end = 0\n\n if ((start ^ end) & ~0xfff) {\n dbg_log(\n 'truncated disassembly start=' +\n h(start >>> 0) +\n ' end=' +\n h(end >>> 0),\n )\n end = (start | 0xfff) + 1 // until the end of the page\n }\n\n dbg_assert(end >= start)\n\n const buffer = new Uint8Array(end - start)\n\n for (let i = start; i < end; i++) {\n buffer[i - start] = this.read8(i)\n }\n\n this.debug_dump_code(this.is_32[0] ? 1 : 0, buffer, start)\n }\n }\n\n this.seen_code[start] = (this.seen_code[start] || 0) + 1\n\n if (this.test_hook_did_generate_wasm) {\n this.test_hook_did_generate_wasm(code)\n }\n }\n\n const SYNC_COMPILATION = false\n\n if (SYNC_COMPILATION) {\n const module = new WebAssembly.Module(code)\n const result = new WebAssembly.Instance(module, {\n e: this.jit_imports,\n })\n const f = result.exports['f']\n\n this.wm.wasm_table.set(wasm_table_index + WASM_TABLE_OFFSET, f)\n this.codegen_finalize_finished(wasm_table_index, start, state_flags)\n\n if (this.test_hook_did_finalize_wasm) {\n this.test_hook_did_finalize_wasm(code)\n }\n\n return\n }\n\n const result = WebAssembly.instantiate(code, {\n e: this.jit_imports,\n }).then((result) => {\n const f = result.instance.exports['f']\n\n this.wm.wasm_table.set(wasm_table_index + WASM_TABLE_OFFSET, f)\n this.codegen_finalize_finished(wasm_table_index, start, state_flags)\n\n if (this.test_hook_did_finalize_wasm) {\n this.test_hook_did_finalize_wasm(code)\n }\n })\n\n if (DEBUG) {\n result.catch((e) => {\n console.log(e)\n throw e\n })\n }\n }\n\n log_uncompiled_code(start: number, end: number): void {\n if (!DEBUG || !DUMP_UNCOMPILED_ASSEMBLY) {\n return\n }\n\n if ((this.seen_code_uncompiled[start] || 0) < 100) {\n this.seen_code_uncompiled[start] =\n (this.seen_code_uncompiled[start] || 0) + 1\n\n end += 8 // final jump is not included\n\n if ((start ^ end) & ~0xfff) {\n dbg_log(\n 'truncated disassembly start=' +\n h(start >>> 0) +\n ' end=' +\n h(end >>> 0),\n )\n end = (start | 0xfff) + 1 // until the end of the page\n }\n\n if (end < start) end = start\n\n dbg_assert(end >= start)\n\n const buffer = new Uint8Array(end - start)\n\n for (let i = start; i < end; i++) {\n buffer[i - start] = this.read8(i)\n }\n\n dbg_log('Uncompiled code:')\n this.debug_dump_code(this.is_32[0] ? 1 : 0, buffer, start)\n }\n }\n\n dump_function_code(block_ptr: number, count: number): void {\n if (!DEBUG || !DUMP_GENERATED_WASM) {\n return\n }\n\n const SIZEOF_BASIC_BLOCK_IN_DWORDS = 7\n\n const mem32 = new Int32Array(this.wasm_memory.buffer)\n\n dbg_assert((block_ptr & 3) === 0)\n\n const is_32 = this.is_32[0]\n\n for (let i = 0; i < count; i++) {\n const struct_start =\n (block_ptr >> 2) + i * SIZEOF_BASIC_BLOCK_IN_DWORDS\n const start = mem32[struct_start + 0]\n const end = mem32[struct_start + 1]\n const is_entry_block = mem32[struct_start + 6] & 0xff00\n\n const buffer = new Uint8Array(end - start)\n\n for (let j = start; j < end; j++) {\n buffer[j - start] = this.read8(\n this.translate_address_system_read(j),\n )\n }\n\n dbg_log('---' + (is_entry_block ? ' entry' : ''))\n this.debug_dump_code(is_32 ? 1 : 0, buffer, start)\n }\n }\n\n run_hardware_timers(acpi_enabled: number, now: number): number {\n const pit_time = this.devices.pit.timer(now, false)\n const rtc_time = this.devices.rtc.timer(now, false)\n\n let acpi_time = 100\n let apic_time = 100\n if (acpi_enabled) {\n acpi_time = this.devices.acpi.timer(now)\n apic_time = this.apic_timer(now)\n }\n\n return Math.min(pit_time, rtc_time, acpi_time, apic_time)\n }\n\n debug_init(): void {\n if (!DEBUG) return\n\n if (this.io) {\n // write seabios debug output to console\n let seabios_debug = ''\n\n function handle(_out_byte: number) {\n if (_out_byte === 10) {\n dbg_log(seabios_debug, LOG_BIOS)\n seabios_debug = ''\n } else {\n seabios_debug += String.fromCharCode(_out_byte)\n }\n }\n\n this.io.register_write(0x402, this, handle) // seabios\n this.io.register_write(0x500, this, handle) // vgabios\n }\n }\n\n dump_stack(start?: number, end?: number): void {\n if (!DEBUG) return\n\n const esp = this.reg32[REG_ESP]\n dbg_log('========= STACK ==========')\n\n if (end === undefined || end >= start!) {\n start = 5\n end = -5\n }\n\n for (let i = start!; i > end; i--) {\n let line = ' '\n\n if (!i) line = '=> '\n\n line += h(i, 2) + ' | '\n\n dbg_log(\n line +\n h(esp + 4 * i, 8) +\n ' | ' +\n h(this.read32s(esp + 4 * i) >>> 0),\n )\n }\n }\n\n debug_get_state(where?: string): string | undefined {\n if (!DEBUG) return undefined\n\n const mode = this.protected_mode[0] ? 'prot' : 'real'\n const _vm = this.flags[0] & FLAG_VM ? 1 : 0\n const flags = this.get_eflags()\n const iopl = this.getiopl()\n const cpl = this.cpl[0]\n const cs_eip =\n h(this.sreg[REG_CS], 4) + ':' + h(this.get_real_eip() >>> 0, 8)\n const ss_esp =\n h(this.sreg[REG_SS], 4) + ':' + h(this.reg32[REG_ES] >>> 0, 8)\n const op_size = this.is_32[0] ? '32' : '16'\n const if_ = this.flags[0] & FLAG_INTERRUPT ? 1 : 0\n\n const flag_names: Record<number, string> = {\n [FLAG_CARRY]: 'c',\n [FLAG_PARITY]: 'p',\n [FLAG_ADJUST]: 'a',\n [FLAG_ZERO]: 'z',\n [FLAG_SIGN]: 's',\n [FLAG_TRAP]: 't',\n [FLAG_INTERRUPT]: 'i',\n [FLAG_DIRECTION]: 'd',\n [FLAG_OVERFLOW]: 'o',\n }\n let flag_string = ''\n\n for (let i = 0; i < 16; i++) {\n if (flag_names[1 << i]) {\n if (flags & (1 << i)) {\n flag_string += flag_names[1 << i]\n } else {\n flag_string += ' '\n }\n }\n }\n\n return (\n 'mode=' +\n mode +\n '/' +\n op_size +\n ' paging=' +\n +((this.cr[0] & CR0_PG) !== 0) +\n ' pae=' +\n +((this.cr[4] & CR4_PAE) !== 0) +\n ' iopl=' +\n iopl +\n ' cpl=' +\n cpl +\n ' if=' +\n if_ +\n ' cs:eip=' +\n cs_eip +\n ' cs_off=' +\n h(this.get_seg_cs() >>> 0, 8) +\n ' flgs=' +\n h(this.get_eflags() >>> 0, 6) +\n ' (' +\n flag_string +\n ')' +\n ' ss:esp=' +\n ss_esp +\n ' ssize=' +\n +this.stack_size_32[0] +\n (where ? ' in ' + where : '')\n )\n }\n\n dump_state(where?: string): void {\n if (!DEBUG) return\n\n dbg_log(this.debug_get_state(where)!, LOG_CPU)\n }\n\n get_regs_short(): [string, string] | undefined {\n if (!DEBUG) return undefined\n\n const r32: Record<string, number> = {\n eax: REG_EAX,\n ecx: REG_ECX,\n edx: REG_EDX,\n ebx: REG_EBX,\n esp: REG_ESP,\n ebp: REG_EBP,\n esi: REG_ESI,\n edi: REG_EDI,\n }\n const r32_names = [\n 'eax',\n 'ecx',\n 'edx',\n 'ebx',\n 'esp',\n 'ebp',\n 'esi',\n 'edi',\n ]\n let line1 = ''\n let line2 = ''\n\n for (let i = 0; i < 4; i++) {\n line1 +=\n r32_names[i] +\n '=' +\n h(this.reg32[r32[r32_names[i]]] >>> 0, 8) +\n ' '\n line2 +=\n r32_names[i + 4] +\n '=' +\n h(this.reg32[r32[r32_names[i + 4]]] >>> 0, 8) +\n ' '\n }\n\n line1 +=\n ' ds=' +\n h(this.sreg[REG_DS], 4) +\n ' es=' +\n h(this.sreg[REG_ES], 4) +\n ' fs=' +\n h(this.sreg[REG_FS], 4)\n line2 +=\n ' gs=' +\n h(this.sreg[REG_GS], 4) +\n ' cs=' +\n h(this.sreg[REG_CS], 4) +\n ' ss=' +\n h(this.sreg[REG_SS], 4)\n\n return [line1, line2]\n }\n\n dump_regs_short(): void {\n if (!DEBUG) return\n\n const lines = this.get_regs_short()!\n\n dbg_log(lines[0], LOG_CPU)\n dbg_log(lines[1], LOG_CPU)\n }\n\n dump_gdt_ldt(): void {\n if (!DEBUG) return\n\n dbg_log('gdt: (len = ' + h(this.gdtr_size[0]) + ')')\n const dump_table = (addr: number, size: number) => {\n for (let i = 0; i < size; i += 8, addr += 8) {\n const base =\n this.read16(addr + 2) |\n (this.read8(addr + 4) << 16) |\n (this.read8(addr + 7) << 24)\n let limit =\n this.read16(addr) | ((this.read8(addr + 6) & 0xf) << 16)\n const access = this.read8(addr + 5)\n const flags = this.read8(addr + 6) >> 4\n let flags_str = ''\n const dpl = (access >> 5) & 3\n\n if (!(access & 128)) {\n // present bit not set\n //continue;\n flags_str += 'NP '\n } else {\n flags_str += ' P '\n }\n\n if (access & 16) {\n if (flags & 4) {\n flags_str += '32b '\n } else {\n flags_str += '16b '\n }\n\n if (access & 8) {\n // executable\n flags_str += 'X '\n\n if (access & 4) {\n flags_str += 'C '\n }\n } else {\n // data\n flags_str += 'R '\n }\n\n flags_str += 'RW '\n } else {\n // system\n flags_str += 'sys: ' + h(access & 15)\n }\n\n if (flags & 8) {\n limit = (limit << 12) | 0xfff\n }\n\n dbg_log(\n h(i & ~7, 4) +\n ' ' +\n h(base >>> 0, 8) +\n ' (' +\n h(limit >>> 0, 8) +\n ' bytes) ' +\n flags_str +\n '; dpl = ' +\n dpl +\n ', a = ' +\n access.toString(2) +\n ', f = ' +\n flags.toString(2),\n )\n }\n }\n\n dump_table(\n this.translate_address_system_read(this.gdtr_offset[0]),\n this.gdtr_size[0],\n )\n\n dbg_log('\\nldt: (len = ' + h(this.segment_limits[REG_LDTR]) + ')')\n dump_table(\n this.translate_address_system_read(this.segment_offsets[REG_LDTR]),\n this.segment_limits[REG_LDTR],\n )\n }\n\n dump_idt(): void {\n if (!DEBUG) return\n\n for (let i = 0; i < this.idtr_size[0]; i += 8) {\n const addr = this.translate_address_system_read(\n this.idtr_offset[0] + i,\n )\n const base = this.read16(addr) | (this.read16(addr + 6) << 16)\n const selector = this.read16(addr + 2)\n const type = this.read8(addr + 5)\n let line: string\n const dpl = (type >> 5) & 3\n\n if ((type & 31) === 5) {\n line = 'task gate '\n } else if ((type & 31) === 14) {\n line = 'intr gate '\n } else if ((type & 31) === 15) {\n line = 'trap gate '\n } else {\n line = 'invalid '\n }\n\n if (type & 128) {\n line += ' P'\n } else {\n // present bit not set\n //continue;\n line += 'NP'\n }\n\n dbg_log(\n h(i >> 3, 4) +\n ' ' +\n h(base >>> 0, 8) +\n ', ' +\n h(selector, 4) +\n '; ' +\n line +\n '; dpl = ' +\n dpl +\n ', t = ' +\n type.toString(2),\n )\n }\n }\n\n dump_page_structures(): void {\n const pae = !!(this.cr[4] & CR4_PAE)\n if (pae) {\n dbg_log('PAE enabled')\n\n for (let i = 0; i < 4; i++) {\n const addr = this.cr[3] + 8 * i\n const dword = this.read32s(addr)\n if (dword & 1) {\n this.dump_page_directory(dword & 0xfffff000, true, i << 30)\n }\n }\n } else {\n dbg_log('PAE disabled')\n this.dump_page_directory(this.cr[3], false, 0)\n }\n }\n\n // NOTE: PAE entries are 64-bits, we ignore the high half here.\n dump_page_directory(pd_addr: number, pae: boolean, start: number): void {\n if (!DEBUG) return\n\n function load_page_entry(\n dword_entry: number,\n pae: boolean,\n is_directory: boolean,\n ):\n | false\n | {\n size: boolean\n global: boolean\n accessed: boolean\n dirty: boolean\n cache_disable: boolean\n user: boolean\n read_write: boolean\n address: number\n } {\n if (!DEBUG) return false\n\n if (!(dword_entry & 1)) {\n // present bit not set\n return false\n }\n\n const size = (dword_entry & 128) === 128\n let address: number\n\n if (size && !is_directory) {\n address = dword_entry & (pae ? 0xffe00000 : 0xffc00000)\n } else {\n address = dword_entry & 0xfffff000\n }\n\n return {\n size: size,\n global: (dword_entry & 256) === 256,\n accessed: (dword_entry & 0x20) === 0x20,\n dirty: (dword_entry & 0x40) === 0x40,\n cache_disable: (dword_entry & 16) === 16,\n user: (dword_entry & 4) === 4,\n read_write: (dword_entry & 2) === 2,\n address: address >>> 0,\n }\n }\n\n const n = pae ? 512 : 1024\n const entry_size = pae ? 8 : 4\n const pd_shift = pae ? 21 : 22\n\n for (let i = 0; i < n; i++) {\n const addr = pd_addr + i * entry_size\n let dword = this.read32s(addr)\n const entry = load_page_entry(dword, pae, true)\n\n if (!entry) {\n continue\n }\n\n let flags = ''\n\n flags += entry.size ? 'S ' : ' '\n flags += entry.accessed ? 'A ' : ' '\n flags += entry.cache_disable ? 'Cd ' : ' '\n flags += entry.user ? 'U ' : ' '\n flags += entry.read_write ? 'Rw ' : ' '\n\n if (entry.size) {\n dbg_log(\n '=== ' +\n h((start + (i << pd_shift)) >>> 0, 8) +\n ' -> ' +\n h(entry.address >>> 0, 8) +\n ' | ' +\n flags,\n )\n continue\n } else {\n dbg_log(\n '=== ' +\n h((start + (i << pd_shift)) >>> 0, 8) +\n ' | ' +\n flags,\n )\n }\n\n for (let j = 0; j < n; j++) {\n const sub_addr = entry.address + j * entry_size\n dword = this.read32s(sub_addr)\n\n const subentry = load_page_entry(dword, pae, false)\n\n if (subentry) {\n flags = ''\n\n flags += subentry.cache_disable ? 'Cd ' : ' '\n flags += subentry.user ? 'U ' : ' '\n flags += subentry.read_write ? 'Rw ' : ' '\n flags += subentry.global ? 'G ' : ' '\n flags += subentry.accessed ? 'A ' : ' '\n flags += subentry.dirty ? 'Di ' : ' '\n\n dbg_log(\n '# ' +\n h(\n (start + ((i << pd_shift) | (j << 12))) >>> 0,\n 8,\n ) +\n ' -> ' +\n h(subentry.address, 8) +\n ' | ' +\n flags +\n ' (at ' +\n h(sub_addr, 8) +\n ')',\n )\n }\n }\n }\n }\n\n get_memory_dump(start?: number, count?: number): ArrayBuffer | undefined {\n if (!DEBUG) return undefined\n\n if (start === undefined) {\n start = 0\n count = this.memory_size[0]\n } else if (count === undefined) {\n count = start\n start = 0\n }\n\n return this.mem8.slice(start, start + count!).buffer\n }\n\n memory_hex_dump(addr: number, length?: number): void {\n if (!DEBUG) return\n\n length = length || 4 * 0x10\n let line: string, byt: number\n\n for (let i = 0; i < length >> 4; i++) {\n line = h(addr + (i << 4), 5) + ' '\n\n for (let j = 0; j < 0x10; j++) {\n byt = this.read8(addr + (i << 4) + j)\n line += h(byt, 2) + ' '\n }\n\n line += ' '\n\n for (let j = 0; j < 0x10; j++) {\n byt = this.read8(addr + (i << 4) + j)\n line += byt < 33 || byt > 126 ? '.' : String.fromCharCode(byt)\n }\n\n dbg_log(line)\n }\n }\n\n used_memory_dump(): void {\n if (!DEBUG) return\n\n const width = 0x80\n const height = 0x10\n const block_size = (this.memory_size[0] / width / height) | 0\n let row: string\n\n for (let i = 0; i < height; i++) {\n row = h(i * width * block_size, 8) + ' | '\n\n for (let j = 0; j < width; j++) {\n const used = this.mem32s[(i * width + j) * block_size] > 0\n\n row += used ? 'X' : ' '\n }\n\n dbg_log(row)\n }\n }\n\n debug_interrupt(_interrupt_nr: number): void {\n // Debug interrupt handler (commented out implementations in original)\n }\n\n debug_dump_code(\n is_32: number,\n buffer: Uint8Array | number[],\n start: number,\n ): void {\n if (!DEBUG) return\n\n if (!this.capstone_decoder) {\n let cs = (globalThis as any).cs\n\n if (typeof require === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n cs = require('./capstone-x86.min.js')\n }\n\n if (cs === undefined) {\n dbg_log(\n 'Warning: Missing capstone library, disassembly not available',\n )\n return\n }\n\n this.capstone_decoder = [\n new cs.Capstone(cs.ARCH_X86, cs.MODE_16),\n new cs.Capstone(cs.ARCH_X86, cs.MODE_32),\n ]\n }\n\n if (buffer instanceof Array) {\n buffer = new Uint8Array(buffer)\n }\n\n try {\n const instructions = this.capstone_decoder[+is_32].disasm(\n buffer,\n start,\n )\n\n instructions.forEach(function (instr: any) {\n dbg_log(\n h(instr.address >>> 0) +\n ': ' +\n pads(\n instr.bytes\n .map((x: number) => h(x, 2).slice(-2))\n .join(' '),\n 20,\n ) +\n ' ' +\n instr.mnemonic +\n ' ' +\n instr.op_str,\n )\n })\n dbg_log('')\n } catch {\n dbg_log(\n 'Could not disassemble: ' +\n Array.from(buffer)\n .map((x) => h(x, 2))\n .join(' '),\n )\n }\n }\n\n dump_wasm(buffer: Uint8Array): void {\n if (!DEBUG) return\n\n if (this.wabt === undefined) {\n if (typeof require === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n this.wabt = require('./libwabt.cjs')\n } else {\n this.wabt = new (globalThis as any).WabtModule()\n }\n\n if (this.wabt === undefined) {\n dbg_log('Warning: Missing libwabt, wasm dump not available')\n return\n }\n }\n\n // Need to make a small copy otherwise libwabt goes nuts trying to copy\n // the whole underlying buffer\n buffer = buffer.slice()\n\n let module: any\n try {\n module = this.wabt.readWasm(buffer, { readDebugNames: false })\n module.generateNames()\n module.applyNames()\n const result = module.toText({\n foldExprs: true,\n inlineExport: true,\n })\n dbg_log(result)\n } catch (e) {\n // @ts-expect-error Uint8Array is a valid BlobPart\n dump_file(buffer, 'failed.wasm')\n console.log(String(e))\n } finally {\n if (module) {\n module.destroy()\n }\n }\n }\n}\n", "declare let DEBUG: boolean\n\nimport { h } from './lib.js'\nimport { dbg_assert, dbg_log } from './log.js'\n\nconst STATE_VERSION = 6\nconst STATE_MAGIC = 0x86768676 | 0\nconst STATE_INDEX_MAGIC = 0\nconst STATE_INDEX_VERSION = 1\nconst STATE_INDEX_TOTAL_LEN = 2\nconst STATE_INDEX_INFO_LEN = 3\nconst STATE_INFO_BLOCK_START = 16\n\nconst ZSTD_MAGIC = 0xfd2fb528\n\nexport class StateLoadError extends Error {\n constructor(msg: string) {\n super(msg)\n }\n}\n\n// Minimal interface for the CPU fields state needs\ninterface StateCpu {\n get_state(): any[]\n\n set_state(state: any[]): void\n wasm_memory: WebAssembly.Memory\n zstd_create_ctx(len: number): number\n zstd_get_src_ptr(ctx: number): number\n zstd_read(ctx: number, len: number): number\n zstd_read_free(ptr: number, len: number): void\n zstd_free_ctx(ctx: number): void\n}\n\nconst CONSTRUCTOR_TABLE: Record<string, any> = {\n Map: Map,\n Uint8Array: Uint8Array,\n Int8Array: Int8Array,\n Uint16Array: Uint16Array,\n Int16Array: Int16Array,\n Uint32Array: Uint32Array,\n Int32Array: Int32Array,\n Float32Array: Float32Array,\n Float64Array: Float64Array,\n}\n\nfunction save_object(obj: any, saved_buffers: Uint8Array[]): any {\n if (typeof obj !== 'object' || obj === null) {\n dbg_assert(typeof obj !== 'function')\n return obj\n }\n\n if (Array.isArray(obj)) {\n return obj.map((x) => save_object(x, saved_buffers))\n }\n\n if (obj instanceof Map) {\n return {\n __state_type__: 'Map',\n\n args: Array.from(obj.entries()).map(([k, v]: [any, any]) => [\n save_object(k, saved_buffers),\n save_object(v, saved_buffers),\n ]),\n }\n }\n\n if (obj.constructor === Object) {\n console.log(obj)\n dbg_assert(obj.constructor !== Object, 'Expected non-object')\n }\n\n if (obj.BYTES_PER_ELEMENT) {\n // Uint8Array, etc.\n const buffer = new Uint8Array(\n obj.buffer,\n obj.byteOffset,\n obj.length * obj.BYTES_PER_ELEMENT,\n )\n\n const constructor = obj.constructor.name.replace('bound ', '')\n\n dbg_assert(CONSTRUCTOR_TABLE[constructor])\n\n return {\n __state_type__: constructor,\n buffer_id: saved_buffers.push(buffer) - 1,\n }\n }\n\n if (DEBUG && !obj.get_state) {\n console.log('Object without get_state: ', obj)\n }\n\n const state = obj.get_state()\n\n const result: any[] = []\n\n for (let i = 0; i < state.length; i++) {\n const value = state[i]\n\n dbg_assert(typeof value !== 'function')\n\n result[i] = save_object(value, saved_buffers)\n }\n\n return result\n}\n\nfunction restore_buffers(obj: any, buffers: ArrayBuffer[]): any {\n if (typeof obj !== 'object' || obj === null) {\n dbg_assert(typeof obj !== 'function')\n return obj\n }\n\n if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; i++) {\n obj[i] = restore_buffers(obj[i], buffers)\n }\n\n return obj\n }\n\n const type = obj['__state_type__']\n dbg_assert(type !== undefined)\n\n const constructor = CONSTRUCTOR_TABLE[type]\n dbg_assert(constructor, 'Unkown type: ' + type)\n\n if (obj['args'] !== undefined) {\n return new constructor(obj['args'])\n }\n\n const buffer = buffers[obj['buffer_id']]\n return new constructor(buffer)\n}\n\nexport function save_state(cpu: StateCpu): ArrayBuffer {\n const saved_buffers: Uint8Array[] = []\n const state = save_object(cpu, saved_buffers)\n\n const buffer_infos: { offset: number; length: number }[] = []\n let total_buffer_size = 0\n\n for (let i = 0; i < saved_buffers.length; i++) {\n const len = saved_buffers[i].byteLength\n\n buffer_infos[i] = {\n offset: total_buffer_size,\n length: len,\n }\n\n total_buffer_size += len\n\n // align\n total_buffer_size = (total_buffer_size + 3) & ~3\n }\n\n const info_object = JSON.stringify({\n buffer_infos: buffer_infos,\n state: state,\n })\n const info_block = new TextEncoder().encode(info_object)\n\n let buffer_block_start = STATE_INFO_BLOCK_START + info_block.length\n buffer_block_start = (buffer_block_start + 3) & ~3\n const total_size = buffer_block_start + total_buffer_size\n\n const result = new ArrayBuffer(total_size)\n\n const header_block = new Int32Array(result, 0, STATE_INFO_BLOCK_START / 4)\n new Uint8Array(result, STATE_INFO_BLOCK_START, info_block.length).set(\n info_block,\n )\n const buffer_block = new Uint8Array(result, buffer_block_start)\n\n header_block[STATE_INDEX_MAGIC] = STATE_MAGIC\n header_block[STATE_INDEX_VERSION] = STATE_VERSION\n header_block[STATE_INDEX_TOTAL_LEN] = total_size\n header_block[STATE_INDEX_INFO_LEN] = info_block.length\n\n for (let i = 0; i < saved_buffers.length; i++) {\n const buf = saved_buffers[i]\n dbg_assert(buf.constructor === Uint8Array)\n buffer_block.set(buf, buffer_infos[i].offset)\n }\n\n dbg_log('State: json size ' + (info_block.byteLength >> 10) + 'k')\n dbg_log(\n 'State: Total buffers size ' + (buffer_block.byteLength >> 10) + 'k',\n )\n\n return result\n}\n\nexport function restore_state(cpu: StateCpu, state: ArrayBuffer): void {\n const state_bytes = new Uint8Array(state)\n\n function read_state_header(\n data: Uint8Array,\n check_length: boolean,\n ): number {\n const len = data.length\n\n if (len < STATE_INFO_BLOCK_START) {\n throw new StateLoadError('Invalid length: ' + len)\n }\n\n const header_block = new Int32Array(data.buffer, data.byteOffset, 4)\n\n if (header_block[STATE_INDEX_MAGIC] !== STATE_MAGIC) {\n throw new StateLoadError(\n 'Invalid header: ' + h(header_block[STATE_INDEX_MAGIC] >>> 0),\n )\n }\n\n if (header_block[STATE_INDEX_VERSION] !== STATE_VERSION) {\n throw new StateLoadError(\n 'Version mismatch: dump=' +\n header_block[STATE_INDEX_VERSION] +\n ' we=' +\n STATE_VERSION,\n )\n }\n\n if (check_length && header_block[STATE_INDEX_TOTAL_LEN] !== len) {\n throw new StateLoadError(\n \"Length doesn't match header: \" +\n 'real=' +\n len +\n ' header=' +\n header_block[STATE_INDEX_TOTAL_LEN],\n )\n }\n\n return header_block[STATE_INDEX_INFO_LEN]\n }\n\n function read_info_block(info_block_buffer: Uint8Array) {\n const info_block = new TextDecoder().decode(info_block_buffer)\n return JSON.parse(info_block)\n }\n\n if (new Uint32Array(state_bytes.buffer, 0, 1)[0] === ZSTD_MAGIC) {\n const ctx = cpu.zstd_create_ctx(state_bytes.length)\n\n new Uint8Array(\n cpu.wasm_memory.buffer,\n cpu.zstd_get_src_ptr(ctx) >>> 0,\n state_bytes.length,\n ).set(state_bytes)\n\n let ptr = cpu.zstd_read(ctx, 16)\n const header_block = new Uint8Array(\n cpu.wasm_memory.buffer,\n ptr >>> 0,\n 16,\n )\n const info_block_len = read_state_header(header_block, false)\n cpu.zstd_read_free(ptr, 16)\n\n ptr = cpu.zstd_read(ctx, info_block_len)\n const info_block_buffer = new Uint8Array(\n cpu.wasm_memory.buffer,\n ptr >>> 0,\n info_block_len,\n )\n const info_block_obj = read_info_block(info_block_buffer)\n cpu.zstd_read_free(ptr, info_block_len)\n\n let state_object = info_block_obj['state']\n const buffer_infos = info_block_obj['buffer_infos']\n const buffers: ArrayBuffer[] = []\n\n let position = STATE_INFO_BLOCK_START + info_block_len\n\n for (const buffer_info of buffer_infos) {\n const front_padding = ((position + 3) & ~3) - position\n const CHUNK_SIZE = 1 * 1024 * 1024\n\n if (buffer_info.length > CHUNK_SIZE) {\n const chunk_ptr = cpu.zstd_read(ctx, front_padding) >>> 0\n cpu.zstd_read_free(chunk_ptr, front_padding)\n\n const buffer = new Uint8Array(buffer_info.length)\n buffers.push(buffer.buffer)\n\n let have = 0\n while (have < buffer_info.length) {\n const remaining = buffer_info.length - have\n dbg_assert(remaining >= 0)\n const to_read = Math.min(remaining, CHUNK_SIZE)\n\n const read_ptr = cpu.zstd_read(ctx, to_read)\n buffer.set(\n new Uint8Array(\n cpu.wasm_memory.buffer,\n read_ptr >>> 0,\n to_read,\n ),\n have,\n )\n cpu.zstd_read_free(read_ptr, to_read)\n\n have += to_read\n }\n } else {\n const chunk_ptr = cpu.zstd_read(\n ctx,\n front_padding + buffer_info.length,\n )\n const offset = (chunk_ptr >>> 0) + front_padding\n buffers.push(\n cpu.wasm_memory.buffer.slice(\n offset,\n offset + buffer_info.length,\n ),\n )\n cpu.zstd_read_free(\n chunk_ptr,\n front_padding + buffer_info.length,\n )\n }\n\n position += front_padding + buffer_info.length\n }\n\n state_object = restore_buffers(state_object, buffers)\n cpu.set_state(state_object)\n\n cpu.zstd_free_ctx(ctx)\n } else {\n const info_block_len = read_state_header(state_bytes, true)\n\n if (info_block_len < 0 || info_block_len + 12 >= state_bytes.length) {\n throw new StateLoadError(\n 'Invalid info block length: ' + info_block_len,\n )\n }\n\n const info_block_buffer = state_bytes.subarray(\n STATE_INFO_BLOCK_START,\n STATE_INFO_BLOCK_START + info_block_len,\n )\n const info_block_obj = read_info_block(info_block_buffer)\n let state_object = info_block_obj['state']\n const buffer_infos = info_block_obj['buffer_infos']\n let buffer_block_start = STATE_INFO_BLOCK_START + info_block_len\n buffer_block_start = (buffer_block_start + 3) & ~3\n\n const buffers = buffer_infos.map((buffer_info: any) => {\n const offset = buffer_block_start + buffer_info.offset\n return state_bytes.buffer.slice(offset, offset + buffer_info.length)\n })\n\n state_object = restore_buffers(state_object, buffers)\n cpu.set_state(state_object)\n }\n}\n", "import { pads } from '../lib.js'\n\ninterface CPU {\n wm: {\n exports: Record<string, (...args: any[]) => any>\n }\n wasm_memory: WebAssembly.Memory\n}\n\nexport function stats_to_string(cpu: CPU): string {\n return print_misc_stats(cpu) + print_instruction_counts(cpu)\n}\n\nfunction print_misc_stats(cpu: CPU): string {\n let text = ''\n\n const stat_names = [\n 'COMPILE',\n 'COMPILE_SKIPPED_NO_NEW_ENTRY_POINTS',\n 'COMPILE_WRONG_ADDRESS_SPACE',\n 'COMPILE_CUT_OFF_AT_END_OF_PAGE',\n 'COMPILE_WITH_LOOP_SAFETY',\n 'COMPILE_PAGE',\n 'COMPILE_PAGE/COMPILE',\n 'COMPILE_BASIC_BLOCK',\n 'COMPILE_DUPLICATED_BASIC_BLOCK',\n 'COMPILE_WASM_BLOCK',\n 'COMPILE_WASM_LOOP',\n 'COMPILE_DISPATCHER',\n 'COMPILE_ENTRY_POINT',\n 'COMPILE_WASM_TOTAL_BYTES',\n 'COMPILE_WASM_TOTAL_BYTES/COMPILE_PAGE',\n 'RUN_INTERPRETED',\n 'RUN_INTERPRETED_NEW_PAGE',\n 'RUN_INTERPRETED_PAGE_HAS_CODE',\n 'RUN_INTERPRETED_PAGE_HAS_ENTRY_AFTER_PAGE_WALK',\n 'RUN_INTERPRETED_NEAR_END_OF_PAGE',\n 'RUN_INTERPRETED_DIFFERENT_STATE',\n 'RUN_INTERPRETED_DIFFERENT_STATE_CPL3',\n 'RUN_INTERPRETED_DIFFERENT_STATE_FLAT',\n 'RUN_INTERPRETED_DIFFERENT_STATE_IS32',\n 'RUN_INTERPRETED_DIFFERENT_STATE_SS32',\n 'RUN_INTERPRETED_MISSED_COMPILED_ENTRY_RUN_INTERPRETED',\n 'RUN_INTERPRETED_STEPS',\n 'RUN_FROM_CACHE',\n 'RUN_FROM_CACHE_STEPS',\n 'RUN_FROM_CACHE_STEPS/RUN_FROM_CACHE',\n 'RUN_FROM_CACHE_STEPS/RUN_INTERPRETED_STEPS',\n 'DIRECT_EXIT',\n 'INDIRECT_JUMP',\n 'INDIRECT_JUMP_NO_ENTRY',\n 'NORMAL_PAGE_CHANGE',\n 'NORMAL_FALLTHRU',\n 'NORMAL_FALLTHRU_WITH_TARGET_BLOCK',\n 'NORMAL_BRANCH',\n 'NORMAL_BRANCH_WITH_TARGET_BLOCK',\n 'CONDITIONAL_JUMP',\n 'CONDITIONAL_JUMP_PAGE_CHANGE',\n 'CONDITIONAL_JUMP_EXIT',\n 'CONDITIONAL_JUMP_FALLTHRU',\n 'CONDITIONAL_JUMP_FALLTHRU_WITH_TARGET_BLOCK',\n 'CONDITIONAL_JUMP_BRANCH',\n 'CONDITIONAL_JUMP_BRANCH_WITH_TARGET_BLOCK',\n 'DISPATCHER_SMALL',\n 'DISPATCHER_LARGE',\n 'LOOP',\n 'LOOP_SAFETY',\n 'CONDITION_OPTIMISED',\n 'CONDITION_UNOPTIMISED',\n 'CONDITION_UNOPTIMISED_PF',\n 'CONDITION_UNOPTIMISED_UNHANDLED_L',\n 'CONDITION_UNOPTIMISED_UNHANDLED_LE',\n 'FAILED_PAGE_CHANGE',\n 'SAFE_READ_FAST',\n 'SAFE_READ_SLOW_PAGE_CROSSED',\n 'SAFE_READ_SLOW_NOT_VALID',\n 'SAFE_READ_SLOW_NOT_USER',\n 'SAFE_READ_SLOW_IN_MAPPED_RANGE',\n 'SAFE_WRITE_FAST',\n 'SAFE_WRITE_SLOW_PAGE_CROSSED',\n 'SAFE_WRITE_SLOW_NOT_VALID',\n 'SAFE_WRITE_SLOW_NOT_USER',\n 'SAFE_WRITE_SLOW_IN_MAPPED_RANGE',\n 'SAFE_WRITE_SLOW_READ_ONLY',\n 'SAFE_WRITE_SLOW_HAS_CODE',\n 'SAFE_READ_WRITE_FAST',\n 'SAFE_READ_WRITE_SLOW_PAGE_CROSSED',\n 'SAFE_READ_WRITE_SLOW_NOT_VALID',\n 'SAFE_READ_WRITE_SLOW_NOT_USER',\n 'SAFE_READ_WRITE_SLOW_IN_MAPPED_RANGE',\n 'SAFE_READ_WRITE_SLOW_READ_ONLY',\n 'SAFE_READ_WRITE_SLOW_HAS_CODE',\n 'PAGE_FAULT',\n 'TLB_MISS',\n 'MAIN_LOOP',\n 'MAIN_LOOP_IDLE',\n 'DO_MANY_CYCLES',\n 'CYCLE_INTERNAL',\n 'INVALIDATE_ALL_MODULES_NO_FREE_WASM_INDICES',\n 'INVALIDATE_MODULE_WRITTEN_WHILE_COMPILED',\n 'INVALIDATE_MODULE_UNUSED_AFTER_OVERWRITE',\n 'INVALIDATE_MODULE_DIRTY_PAGE',\n 'INVALIDATE_PAGE_HAD_CODE',\n 'INVALIDATE_PAGE_HAD_ENTRY_POINTS',\n 'DIRTY_PAGE_DID_NOT_HAVE_CODE',\n 'RUN_FROM_CACHE_EXIT_SAME_PAGE',\n 'RUN_FROM_CACHE_EXIT_NEAR_END_OF_PAGE',\n 'RUN_FROM_CACHE_EXIT_DIFFERENT_PAGE',\n 'CLEAR_TLB',\n 'FULL_CLEAR_TLB',\n 'TLB_FULL',\n 'TLB_GLOBAL_FULL',\n 'MODRM_SIMPLE_REG',\n 'MODRM_SIMPLE_REG_WITH_OFFSET',\n 'MODRM_SIMPLE_CONST_OFFSET',\n 'MODRM_COMPLEX',\n 'SEG_OFFSET_OPTIMISED',\n 'SEG_OFFSET_NOT_OPTIMISED',\n 'SEG_OFFSET_NOT_OPTIMISED_ES',\n 'SEG_OFFSET_NOT_OPTIMISED_FS',\n 'SEG_OFFSET_NOT_OPTIMISED_GS',\n 'SEG_OFFSET_NOT_OPTIMISED_NOT_FLAT',\n ]\n\n let j = 0\n const stat_values: Record<string, number> = {}\n for (let i = 0; i < stat_names.length; i++) {\n const name = stat_names[i]\n let value: number | string\n if (name.includes('/')) {\n j++ // skip profiler_stat_get\n const [left, right] = name.split('/')\n value = stat_values[left] / stat_values[right]\n } else {\n const stat = (stat_values[name] = cpu.wm.exports[\n 'profiler_stat_get'\n ](i - j) as number)\n value =\n stat >= 100e6\n ? Math.round(stat / 1e6) + 'm'\n : stat >= 100e3\n ? Math.round(stat / 1e3) + 'k'\n : stat\n }\n text += name + '=' + value + '\\n'\n }\n\n text += '\\n'\n\n const tlb_entries = cpu.wm.exports[\n 'get_valid_tlb_entries_count'\n ]() as number\n const global_tlb_entries = cpu.wm.exports[\n 'get_valid_global_tlb_entries_count'\n ]() as number\n const nonglobal_tlb_entries = tlb_entries - global_tlb_entries\n\n text +=\n 'TLB_ENTRIES=' +\n tlb_entries +\n ' (' +\n global_tlb_entries +\n ' global, ' +\n nonglobal_tlb_entries +\n ' non-global)\\n'\n text +=\n 'WASM_TABLE_FREE=' +\n cpu.wm.exports['jit_get_wasm_table_index_free_list_count']() +\n '\\n'\n text += 'JIT_CACHE_SIZE=' + cpu.wm.exports['jit_get_cache_size']() + '\\n'\n text += 'FLAT_SEGMENTS=' + cpu.wm.exports['has_flat_segmentation']() + '\\n'\n\n text +=\n 'wasm memory size: ' + (cpu.wasm_memory.buffer.byteLength >> 20) + 'm\\n'\n\n text += 'Config:\\n'\n text += 'JIT_DISABLED=' + cpu.wm.exports['get_jit_config'](0) + '\\n'\n text += 'MAX_PAGES=' + cpu.wm.exports['get_jit_config'](1) + '\\n'\n text +=\n 'JIT_USE_LOOP_SAFETY=' +\n Boolean(cpu.wm.exports['get_jit_config'](2)) +\n '\\n'\n text +=\n 'MAX_EXTRA_BASIC_BLOCKS=' + cpu.wm.exports['get_jit_config'](3) + '\\n'\n\n return text\n}\n\nfunction print_instruction_counts(cpu: CPU): string {\n return [\n print_instruction_counts_offset(cpu, false, false, false, false),\n print_instruction_counts_offset(cpu, true, false, false, false),\n print_instruction_counts_offset(cpu, false, true, false, false),\n print_instruction_counts_offset(cpu, false, false, true, false),\n print_instruction_counts_offset(cpu, false, false, false, true),\n ].join('\\n\\n')\n}\n\ninterface InstructionCount {\n opcode: number\n count: number\n is_mem: boolean\n fixed_g: number\n}\n\nfunction print_instruction_counts_offset(\n cpu: CPU,\n compiled: boolean,\n jit_exit: boolean,\n unguarded_register: boolean,\n wasm_size: boolean,\n): string {\n let text = ''\n\n const counts: InstructionCount[] = []\n\n const label = compiled\n ? 'compiled'\n : jit_exit\n ? 'jit exit'\n : unguarded_register\n ? 'unguarded register'\n : wasm_size\n ? 'wasm size'\n : 'executed'\n\n for (let opcode = 0; opcode < 0x100; opcode++) {\n for (let fixed_g = 0; fixed_g < 8; fixed_g++) {\n for (const is_mem of [false, true]) {\n const count = cpu.wm.exports['get_opstats_buffer'](\n compiled,\n jit_exit,\n unguarded_register,\n wasm_size,\n opcode,\n false,\n is_mem,\n fixed_g,\n ) as number\n counts.push({ opcode, count, is_mem, fixed_g })\n\n const count_0f = cpu.wm.exports['get_opstats_buffer'](\n compiled,\n jit_exit,\n unguarded_register,\n wasm_size,\n opcode,\n true,\n is_mem,\n fixed_g,\n ) as number\n counts.push({\n opcode: 0x0f00 | opcode,\n count: count_0f,\n is_mem,\n fixed_g,\n })\n }\n }\n }\n\n let total = 0\n const prefixes = new Set([\n 0x26, 0x2e, 0x36, 0x3e, 0x64, 0x65, 0x66, 0x67, 0xf0, 0xf2, 0xf3,\n ])\n for (const { count, opcode } of counts) {\n if (!prefixes.has(opcode)) {\n total += count\n }\n }\n\n if (total === 0) {\n return ''\n }\n\n const per_opcode = new Uint32Array(0x100)\n const per_opcode0f = new Uint32Array(0x100)\n\n for (const { opcode, count } of counts) {\n if ((opcode & 0xff00) === 0x0f00) {\n per_opcode0f[opcode & 0xff] += count\n } else {\n per_opcode[opcode & 0xff] += count\n }\n }\n\n text += '------------------\\n'\n text += 'Total: ' + total + '\\n'\n\n const factor = total > 1e7 ? 1000 : 1\n\n const max_count = Math.max(\n ...counts.map(({ count }) => Math.round(count / factor)),\n )\n const pad_length = String(max_count).length\n\n text += `Instruction counts ${label} (in ${factor}):\\n`\n\n for (let i = 0; i < 0x100; i++) {\n text +=\n i.toString(16).padStart(2, '0') +\n ':' +\n pads(Math.round(per_opcode[i] / factor), pad_length)\n\n if (i % 16 === 15) text += '\\n'\n else text += ' '\n }\n\n text += '\\n'\n text += `Instruction counts ${label} (0f, in ${factor}):\\n`\n\n for (let i = 0; i < 0x100; i++) {\n text +=\n (i & 0xff).toString(16).padStart(2, '0') +\n ':' +\n pads(Math.round(per_opcode0f[i] / factor), pad_length)\n\n if (i % 16 === 15) text += '\\n'\n else text += ' '\n }\n text += '\\n'\n\n const top_counts = counts\n .filter(({ count }) => count)\n .sort(({ count: count1 }, { count: count2 }) => count2 - count1)\n\n for (const { opcode, is_mem, fixed_g, count } of top_counts.slice(0, 200)) {\n const opcode_description =\n opcode.toString(16) + '_' + fixed_g + (is_mem ? '_m' : '_r')\n text +=\n opcode_description + ':' + ((count / total) * 100).toFixed(2) + ' '\n }\n text += '\\n'\n\n return text\n}\n", "import { dbg_assert } from './log.js'\n\ninterface BusListener {\n fn: (...args: any[]) => any\n this_value: unknown\n}\n\nexport class BusConnector {\n listeners: Record<string, BusListener[]> = {}\n pair: BusConnector | undefined = undefined\n\n register(\n name: string,\n fn: (...args: any[]) => any,\n this_value: unknown,\n ): void {\n let listeners = this.listeners[name]\n\n if (listeners === undefined) {\n listeners = this.listeners[name] = []\n }\n\n listeners.push({\n fn: fn,\n this_value: this_value,\n })\n }\n\n unregister(name: string, fn: (...args: any[]) => any): void {\n const listeners = this.listeners[name]\n\n if (listeners === undefined) {\n return\n }\n\n this.listeners[name] = listeners.filter(function (l) {\n return l.fn !== fn\n })\n }\n\n send(name: string, value?: unknown, _unused_transfer?: unknown): void {\n if (!this.pair) {\n return\n }\n\n const listeners = this.pair.listeners[name]\n\n if (listeners === undefined) {\n return\n }\n\n for (let i = 0; i < listeners.length; i++) {\n const listener = listeners[i]\n listener.fn.call(listener.this_value, value)\n }\n }\n\n send_async(name: string, value?: unknown): void {\n dbg_assert(arguments.length === 1 || arguments.length === 2)\n\n setTimeout(this.send.bind(this, name, value), 0)\n }\n}\n\nexport function create_bus(): [BusConnector, BusConnector] {\n const c0 = new BusConnector()\n const c1 = new BusConnector()\n\n c0.pair = c1\n c1.pair = c0\n\n return [c0, c1]\n}\n\n// Backwards compatibility: Bus namespace\nexport const Bus = {\n create: create_bus,\n}\n", "declare let DEBUG: boolean\n\n// AudioWorkletProcessor is available in AudioWorklet scope but not in main thread scope.\n\ndeclare let AudioWorkletProcessor: any\n\nimport {\n MIXER_CHANNEL_BOTH,\n MIXER_CHANNEL_LEFT,\n MIXER_CHANNEL_RIGHT,\n MIXER_SRC_PCSPEAKER,\n MIXER_SRC_DAC,\n MIXER_SRC_MASTER,\n} from '../const.js'\nimport { dbg_assert, dbg_log } from '../log.js'\nimport { OSCILLATOR_FREQ } from '../pit.js'\nimport { dump_file } from '../lib.js'\nimport { BusConnector } from '../bus.js'\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ndeclare const registerProcessor: any\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ndeclare const sampleRate: number\n\nconst DAC_QUEUE_RESERVE = 0.2\n\nconst AUDIOBUFFER_MINIMUM_SAMPLING_RATE = 8000\n\ninterface _SpeakerDACInterface {\n node_processor: AudioWorkletNode | null\n pump(): void\n}\n\nexport class SpeakerAdapter {\n bus: BusConnector\n audio_context: AudioContext | null\n mixer: SpeakerMixer\n pcspeaker: PCSpeaker\n dac: SpeakerWorkletDAC | SpeakerBufferSourceDAC\n\n constructor(bus: BusConnector) {\n if (typeof window === 'undefined') {\n this.bus = bus\n this.audio_context = null\n this.mixer = undefined!\n this.pcspeaker = undefined!\n this.dac = undefined!\n return\n }\n if (!window.AudioContext) {\n console.warn(\"Web browser doesn't support Web Audio API\")\n this.bus = bus\n this.audio_context = null\n this.mixer = undefined!\n this.pcspeaker = undefined!\n this.dac = undefined!\n return\n }\n\n const SpeakerDAC = window.AudioWorklet\n ? SpeakerWorkletDAC\n : SpeakerBufferSourceDAC\n\n this.bus = bus\n\n this.audio_context = new AudioContext()\n\n this.mixer = new SpeakerMixer(bus, this.audio_context)\n\n this.pcspeaker = new PCSpeaker(bus, this.audio_context, this.mixer)\n\n this.dac = new SpeakerDAC(bus, this.audio_context, this.mixer)\n\n this.pcspeaker.start()\n\n bus.register(\n 'emulator-stopped',\n function (this: SpeakerAdapter) {\n this.audio_context?.suspend()\n },\n this,\n )\n\n bus.register(\n 'emulator-started',\n function (this: SpeakerAdapter) {\n this.audio_context?.resume()\n },\n this,\n )\n\n bus.register(\n 'speaker-confirm-initialized',\n function () {\n bus.send('speaker-has-initialized')\n },\n this,\n )\n bus.send('speaker-has-initialized')\n }\n\n destroy(): void {\n if (this.audio_context) {\n this.audio_context.close()\n }\n this.audio_context = null\n if (this.dac && this.dac.node_processor) {\n this.dac.node_processor.port.close()\n }\n this.dac = undefined!\n }\n}\n\nclass SpeakerMixer {\n audio_context: AudioContext\n sources: Map<number, SpeakerMixerSource> = new Map()\n\n volume_both = 1\n volume_left = 1\n volume_right = 1\n gain_left = 1\n gain_right = 1\n\n node_treble_left: BiquadFilterNode\n node_treble_right: BiquadFilterNode\n node_bass_left: BiquadFilterNode\n node_bass_right: BiquadFilterNode\n node_gain_left: GainNode\n node_gain_right: GainNode\n node_merger: ChannelMergerNode\n\n input_left: BiquadFilterNode\n input_right: BiquadFilterNode\n\n constructor(bus: BusConnector, audio_context: AudioContext) {\n this.audio_context = audio_context\n\n this.node_treble_left = this.audio_context.createBiquadFilter()\n this.node_treble_right = this.audio_context.createBiquadFilter()\n this.node_treble_left.type = 'highshelf'\n this.node_treble_right.type = 'highshelf'\n this.node_treble_left.frequency.setValueAtTime(\n 2000,\n this.audio_context.currentTime,\n )\n this.node_treble_right.frequency.setValueAtTime(\n 2000,\n this.audio_context.currentTime,\n )\n\n this.node_bass_left = this.audio_context.createBiquadFilter()\n this.node_bass_right = this.audio_context.createBiquadFilter()\n this.node_bass_left.type = 'lowshelf'\n this.node_bass_right.type = 'lowshelf'\n this.node_bass_left.frequency.setValueAtTime(\n 200,\n this.audio_context.currentTime,\n )\n this.node_bass_right.frequency.setValueAtTime(\n 200,\n this.audio_context.currentTime,\n )\n\n this.node_gain_left = this.audio_context.createGain()\n this.node_gain_right = this.audio_context.createGain()\n\n this.node_merger = this.audio_context.createChannelMerger(2)\n\n this.input_left = this.node_treble_left\n this.input_right = this.node_treble_right\n\n this.node_treble_left.connect(this.node_bass_left)\n this.node_bass_left.connect(this.node_gain_left)\n this.node_gain_left.connect(this.node_merger, 0, 0)\n\n this.node_treble_right.connect(this.node_bass_right)\n this.node_bass_right.connect(this.node_gain_right)\n this.node_gain_right.connect(this.node_merger, 0, 1)\n\n this.node_merger.connect(this.audio_context.destination)\n\n bus.register(\n 'mixer-connect',\n function (this: SpeakerMixer, data: [number, number]) {\n const source_id = data[0]\n const channel = data[1]\n this.connect_source(source_id, channel)\n },\n this,\n )\n\n bus.register(\n 'mixer-disconnect',\n function (this: SpeakerMixer, data: [number, number]) {\n const source_id = data[0]\n const channel = data[1]\n this.disconnect_source(source_id, channel)\n },\n this,\n )\n\n bus.register(\n 'mixer-volume',\n function (this: SpeakerMixer, data: [number, number, number]) {\n const source_id = data[0]\n const channel = data[1]\n const decibels = data[2]\n\n const gain = Math.pow(10, decibels / 20)\n\n const source: SpeakerMixer | SpeakerMixerSource | undefined =\n source_id === MIXER_SRC_MASTER\n ? this\n : this.sources.get(source_id)\n\n if (source === undefined) {\n dbg_assert(\n false,\n 'Mixer set volume - cannot set volume for undefined source: ' +\n source_id,\n )\n return\n }\n\n source.set_volume(gain, channel)\n },\n this,\n )\n\n bus.register(\n 'mixer-gain-left',\n function (this: SpeakerMixer, decibels: number) {\n this.gain_left = Math.pow(10, decibels / 20)\n this.update()\n },\n this,\n )\n\n bus.register(\n 'mixer-gain-right',\n function (this: SpeakerMixer, decibels: number) {\n this.gain_right = Math.pow(10, decibels / 20)\n this.update()\n },\n this,\n )\n\n const create_gain_handler = (audio_node: BiquadFilterNode) => {\n return function (this: SpeakerMixer, decibels: number) {\n audio_node.gain.setValueAtTime(\n decibels,\n this.audio_context.currentTime,\n )\n }\n }\n bus.register(\n 'mixer-treble-left',\n create_gain_handler(this.node_treble_left),\n this,\n )\n bus.register(\n 'mixer-treble-right',\n create_gain_handler(this.node_treble_right),\n this,\n )\n bus.register(\n 'mixer-bass-left',\n create_gain_handler(this.node_bass_left),\n this,\n )\n bus.register(\n 'mixer-bass-right',\n create_gain_handler(this.node_bass_right),\n this,\n )\n }\n\n add_source(source_node: AudioNode, source_id: number): SpeakerMixerSource {\n const source = new SpeakerMixerSource(\n this.audio_context,\n source_node,\n this.input_left,\n this.input_right,\n )\n\n dbg_assert(\n !this.sources.has(source_id),\n 'Mixer add source - overwritting source: ' + source_id,\n )\n\n this.sources.set(source_id, source)\n return source\n }\n\n connect_source(source_id: number, channel?: number): void {\n const source = this.sources.get(source_id)\n\n if (source === undefined) {\n dbg_assert(\n false,\n 'Mixer connect - cannot connect undefined source: ' + source_id,\n )\n return\n }\n\n source.connect(channel)\n }\n\n disconnect_source(source_id: number, channel?: number): void {\n const source = this.sources.get(source_id)\n\n if (source === undefined) {\n dbg_assert(\n false,\n 'Mixer disconnect - cannot disconnect undefined source: ' +\n source_id,\n )\n return\n }\n\n source.disconnect(channel)\n }\n\n set_volume(value: number, channel?: number): void {\n if (channel === undefined) {\n channel = MIXER_CHANNEL_BOTH\n }\n\n switch (channel) {\n case MIXER_CHANNEL_LEFT:\n this.volume_left = value\n break\n case MIXER_CHANNEL_RIGHT:\n this.volume_right = value\n break\n case MIXER_CHANNEL_BOTH:\n this.volume_both = value\n break\n default:\n dbg_assert(\n false,\n 'Mixer set master volume - unknown channel: ' + channel,\n )\n return\n }\n\n this.update()\n }\n\n update(): void {\n const net_gain_left =\n this.volume_both * this.volume_left * this.gain_left\n const net_gain_right =\n this.volume_both * this.volume_right * this.gain_right\n\n this.node_gain_left.gain.setValueAtTime(\n net_gain_left,\n this.audio_context.currentTime,\n )\n this.node_gain_right.gain.setValueAtTime(\n net_gain_right,\n this.audio_context.currentTime,\n )\n }\n}\n\nclass SpeakerMixerSource {\n audio_context: AudioContext\n\n connected_left = true\n connected_right = true\n gain_hidden = 1\n volume_both = 1\n volume_left = 1\n volume_right = 1\n\n node_splitter: ChannelSplitterNode\n node_gain_left: GainNode\n node_gain_right: GainNode\n\n constructor(\n audio_context: AudioContext,\n source_node: AudioNode,\n destination_left: AudioNode,\n destination_right: AudioNode,\n ) {\n this.audio_context = audio_context\n\n this.node_splitter = audio_context.createChannelSplitter(2)\n this.node_gain_left = audio_context.createGain()\n this.node_gain_right = audio_context.createGain()\n\n source_node.connect(this.node_splitter)\n\n this.node_splitter.connect(this.node_gain_left, 0)\n this.node_gain_left.connect(destination_left)\n\n this.node_splitter.connect(this.node_gain_right, 1)\n this.node_gain_right.connect(destination_right)\n }\n\n update(): void {\n const net_gain_left =\n +this.connected_left *\n this.gain_hidden *\n this.volume_both *\n this.volume_left\n const net_gain_right =\n +this.connected_right *\n this.gain_hidden *\n this.volume_both *\n this.volume_right\n\n this.node_gain_left.gain.setValueAtTime(\n net_gain_left,\n this.audio_context.currentTime,\n )\n this.node_gain_right.gain.setValueAtTime(\n net_gain_right,\n this.audio_context.currentTime,\n )\n }\n\n connect(channel?: number): void {\n const both = !channel || channel === MIXER_CHANNEL_BOTH\n if (both || channel === MIXER_CHANNEL_LEFT) {\n this.connected_left = true\n }\n if (both || channel === MIXER_CHANNEL_RIGHT) {\n this.connected_right = true\n }\n this.update()\n }\n\n disconnect(channel?: number): void {\n const both = !channel || channel === MIXER_CHANNEL_BOTH\n if (both || channel === MIXER_CHANNEL_LEFT) {\n this.connected_left = false\n }\n if (both || channel === MIXER_CHANNEL_RIGHT) {\n this.connected_right = false\n }\n this.update()\n }\n\n set_volume(value: number, channel?: number): void {\n if (channel === undefined) {\n channel = MIXER_CHANNEL_BOTH\n }\n\n switch (channel) {\n case MIXER_CHANNEL_LEFT:\n this.volume_left = value\n break\n case MIXER_CHANNEL_RIGHT:\n this.volume_right = value\n break\n case MIXER_CHANNEL_BOTH:\n this.volume_both = value\n break\n default:\n dbg_assert(\n false,\n 'Mixer set volume - unknown channel: ' + channel,\n )\n return\n }\n\n this.update()\n }\n\n set_gain_hidden(value: number): void {\n this.gain_hidden = value\n }\n}\n\nclass PCSpeaker {\n node_oscillator: OscillatorNode\n mixer_connection: SpeakerMixerSource\n\n constructor(\n bus: BusConnector,\n audio_context: AudioContext,\n mixer: SpeakerMixer,\n ) {\n this.node_oscillator = audio_context.createOscillator()\n this.node_oscillator.type = 'square'\n this.node_oscillator.frequency.setValueAtTime(\n 440,\n audio_context.currentTime,\n )\n\n this.mixer_connection = mixer.add_source(\n this.node_oscillator,\n MIXER_SRC_PCSPEAKER,\n )\n this.mixer_connection.disconnect()\n\n bus.register(\n 'pcspeaker-enable',\n function () {\n mixer.connect_source(MIXER_SRC_PCSPEAKER)\n },\n this,\n )\n\n bus.register(\n 'pcspeaker-disable',\n function () {\n mixer.disconnect_source(MIXER_SRC_PCSPEAKER)\n },\n this,\n )\n\n bus.register(\n 'pcspeaker-update',\n function (this: PCSpeaker, data: [number, number]) {\n const counter_mode = data[0]\n const counter_reload = data[1]\n\n let frequency = 0\n const beep_enabled = counter_mode === 3\n\n if (beep_enabled) {\n frequency = (OSCILLATOR_FREQ * 1000) / counter_reload\n frequency = Math.min(\n frequency,\n this.node_oscillator.frequency.maxValue,\n )\n frequency = Math.max(frequency, 0)\n }\n\n this.node_oscillator.frequency.setValueAtTime(\n frequency,\n audio_context.currentTime,\n )\n },\n this,\n )\n }\n\n start(): void {\n this.node_oscillator.start()\n }\n}\n\nclass SpeakerWorkletDAC {\n bus: BusConnector\n audio_context: AudioContext\n enabled = false\n sampling_rate = 48000\n node_processor: AudioWorkletNode | null = null\n node_output: GainNode\n mixer_connection: SpeakerMixerSource\n debugger: SpeakerDACDebugger | undefined\n\n constructor(\n bus: BusConnector,\n audio_context: AudioContext,\n mixer: SpeakerMixer,\n ) {\n this.bus = bus\n this.audio_context = audio_context\n\n // The worklet function body is extracted as a string and loaded as a Blob URL.\n // It runs in a separate AudioWorklet scope, not in the main thread.\n function worklet() {\n const RENDER_QUANTUM = 128\n const MINIMUM_BUFFER_SIZE = 2 * RENDER_QUANTUM\n const QUEUE_RESERVE = 1024\n\n function sinc(x: number): number {\n if (x === 0) return 1\n x *= Math.PI\n return Math.sin(x) / x\n }\n\n const EMPTY_BUFFER: [Float32Array, Float32Array] = [\n new Float32Array(MINIMUM_BUFFER_SIZE),\n new Float32Array(MINIMUM_BUFFER_SIZE),\n ]\n\n function DACProcessor(this: any) {\n const self = Reflect.construct(\n AudioWorkletProcessor,\n [],\n DACProcessor,\n )\n\n self.kernel_size = 3\n\n self.queue_data = new Array(1024)\n self.queue_start = 0\n self.queue_end = 0\n self.queue_length = 0\n self.queue_size = self.queue_data.length\n self.queued_samples = 0\n\n self.source_buffer_previous = EMPTY_BUFFER\n self.source_buffer_current = EMPTY_BUFFER\n\n self.source_samples_per_destination = 1.0\n\n self.source_block_start = 0\n\n self.source_time = 0.0\n\n self.source_offset = 0\n\n self.port.onmessage = (event: any) => {\n switch (event.data.type) {\n case 'queue':\n self.queue_push(event.data.value)\n break\n case 'sampling-rate':\n self.source_samples_per_destination =\n event.data.value /\n (globalThis as any).sampleRate\n break\n }\n }\n\n return self\n }\n\n Reflect.setPrototypeOf(\n DACProcessor.prototype,\n AudioWorkletProcessor.prototype,\n )\n Reflect.setPrototypeOf(DACProcessor, AudioWorkletProcessor)\n\n DACProcessor.prototype['process'] = DACProcessor.prototype.process =\n function (\n this: any,\n _inputs: any,\n outputs: any,\n _parameters: any,\n ) {\n for (let i = 0; i < outputs[0][0].length; i++) {\n let sum0 = 0\n let sum1 = 0\n\n const start = this.source_offset - this.kernel_size + 1\n const end = this.source_offset + this.kernel_size\n\n for (let j = start; j <= end; j++) {\n const convolute_index = this.source_block_start + j\n sum0 +=\n this.get_sample(convolute_index, 0) *\n this.kernel(this.source_time - j)\n sum1 +=\n this.get_sample(convolute_index, 1) *\n this.kernel(this.source_time - j)\n }\n\n if (isNaN(sum0) || isNaN(sum1)) {\n sum0 = sum1 = 0\n this.dbg_log('ERROR: NaN values! Ignoring for now.')\n }\n\n outputs[0][0][i] = sum0\n outputs[0][1][i] = sum1\n\n this.source_time += this.source_samples_per_destination\n this.source_offset = Math.floor(this.source_time)\n }\n\n let samples_needed_per_block = this.source_offset\n samples_needed_per_block += this.kernel_size + 2\n\n this.source_time -= this.source_offset\n this.source_block_start += this.source_offset\n this.source_offset = 0\n\n this.ensure_enough_data(samples_needed_per_block)\n\n return true\n }\n\n DACProcessor.prototype.kernel = function (this: any, x: number) {\n return sinc(x) * sinc(x / this.kernel_size)\n }\n\n DACProcessor.prototype.get_sample = function (\n this: any,\n index: number,\n channel: number,\n ) {\n if (index < 0) {\n index += this.source_buffer_previous[0].length\n return this.source_buffer_previous[channel][index]\n }\n return this.source_buffer_current[channel][index]\n }\n\n DACProcessor.prototype.ensure_enough_data = function (\n this: any,\n needed: number,\n ) {\n const current_length = this.source_buffer_current[0].length\n const remaining = current_length - this.source_block_start\n\n if (remaining < needed) {\n this.prepare_next_buffer()\n this.source_block_start -= current_length\n }\n }\n\n DACProcessor.prototype.prepare_next_buffer = function (this: any) {\n if (\n this.queued_samples < MINIMUM_BUFFER_SIZE &&\n this.queue_length\n ) {\n this.dbg_log(\n 'Not enough samples - should not happen during midway of playback',\n )\n }\n\n this.source_buffer_previous = this.source_buffer_current\n this.source_buffer_current = this.queue_shift()\n\n let sample_count = this.source_buffer_current[0].length\n\n if (sample_count < MINIMUM_BUFFER_SIZE) {\n let queue_pos = this.queue_start\n let buffer_count = 0\n\n while (\n sample_count < MINIMUM_BUFFER_SIZE &&\n buffer_count < this.queue_length\n ) {\n sample_count += this.queue_data[queue_pos][0].length\n\n queue_pos = (queue_pos + 1) & (this.queue_size - 1)\n buffer_count++\n }\n\n const new_big_buffer_size = Math.max(\n sample_count,\n MINIMUM_BUFFER_SIZE,\n )\n const new_big_buffer = [\n new Float32Array(new_big_buffer_size),\n new Float32Array(new_big_buffer_size),\n ]\n\n new_big_buffer[0].set(this.source_buffer_current[0])\n new_big_buffer[1].set(this.source_buffer_current[1])\n let new_big_buffer_pos =\n this.source_buffer_current[0].length\n\n for (let i = 0; i < buffer_count; i++) {\n const small_buffer = this.queue_shift()\n new_big_buffer[0].set(\n small_buffer[0],\n new_big_buffer_pos,\n )\n new_big_buffer[1].set(\n small_buffer[1],\n new_big_buffer_pos,\n )\n new_big_buffer_pos += small_buffer[0].length\n }\n\n this.source_buffer_current = new_big_buffer\n }\n\n this.pump()\n }\n\n DACProcessor.prototype.pump = function (this: any) {\n if (\n this.queued_samples / this.source_samples_per_destination <\n QUEUE_RESERVE\n ) {\n this.port.postMessage({\n type: 'pump',\n })\n }\n }\n\n DACProcessor.prototype.queue_push = function (\n this: any,\n item: [Float32Array, Float32Array],\n ) {\n if (this.queue_length < this.queue_size) {\n this.queue_data[this.queue_end] = item\n this.queue_end =\n (this.queue_end + 1) & (this.queue_size - 1)\n this.queue_length++\n\n this.queued_samples += item[0].length\n\n this.pump()\n }\n }\n\n DACProcessor.prototype.queue_shift = function (this: any) {\n if (!this.queue_length) {\n return EMPTY_BUFFER\n }\n\n const item = this.queue_data[this.queue_start]\n\n this.queue_data[this.queue_start] = null\n this.queue_start =\n (this.queue_start + 1) & (this.queue_size - 1)\n this.queue_length--\n\n this.queued_samples -= item[0].length\n\n return item\n }\n\n DACProcessor.prototype.dbg_log = function (\n this: any,\n message: string,\n ) {\n if (DEBUG) {\n this.port.postMessage({\n type: 'debug-log',\n value: message,\n })\n }\n }\n ;(globalThis as any).registerProcessor(\n 'dac-processor',\n DACProcessor,\n )\n }\n\n const worklet_string = worklet.toString()\n\n const worklet_code_start = worklet_string.indexOf('{') + 1\n const worklet_code_end = worklet_string.lastIndexOf('}')\n let worklet_code = worklet_string.substring(\n worklet_code_start,\n worklet_code_end,\n )\n\n if (DEBUG) {\n worklet_code = 'var DEBUG = true;\\n' + worklet_code\n }\n\n const worklet_blob = new Blob([worklet_code], {\n type: 'application/javascript',\n })\n const worklet_url = URL.createObjectURL(worklet_blob)\n\n this.node_output = this.audio_context.createGain()\n\n this.audio_context.audioWorklet.addModule(worklet_url).then(() => {\n URL.revokeObjectURL(worklet_url)\n\n this.node_processor = new AudioWorkletNode(\n this.audio_context,\n 'dac-processor',\n {\n numberOfInputs: 0,\n numberOfOutputs: 1,\n outputChannelCount: [2],\n parameterData: {},\n processorOptions: {},\n },\n )\n\n this.node_processor.port.postMessage({\n type: 'sampling-rate',\n value: this.sampling_rate,\n })\n\n this.node_processor.port.onmessage = (event) => {\n switch (event.data.type) {\n case 'pump':\n this.pump()\n break\n case 'debug-log':\n dbg_log(\n 'SpeakerWorkletDAC - Worklet: ' + event.data.value,\n )\n break\n }\n }\n\n this.node_processor.connect(this.node_output)\n })\n\n this.mixer_connection = mixer.add_source(\n this.node_output,\n MIXER_SRC_DAC,\n )\n this.mixer_connection.set_gain_hidden(3)\n\n bus.register(\n 'dac-send-data',\n function (\n this: SpeakerWorkletDAC,\n data: [Float32Array, Float32Array],\n ) {\n this.queue(data)\n },\n this,\n )\n\n bus.register(\n 'dac-enable',\n function (this: SpeakerWorkletDAC) {\n this.enabled = true\n },\n this,\n )\n\n bus.register(\n 'dac-disable',\n function (this: SpeakerWorkletDAC) {\n this.enabled = false\n },\n this,\n )\n\n bus.register(\n 'dac-tell-sampling-rate',\n function (this: SpeakerWorkletDAC, rate: number) {\n dbg_assert(rate > 0, 'Sampling rate should be nonzero')\n this.sampling_rate = rate\n\n if (!this.node_processor) {\n return\n }\n\n this.node_processor.port.postMessage({\n type: 'sampling-rate',\n value: rate,\n })\n },\n this,\n )\n\n if (DEBUG) {\n this.debugger = new SpeakerDACDebugger(\n this.audio_context,\n this.node_output,\n )\n }\n }\n\n queue(data: [Float32Array, Float32Array]): void {\n if (!this.node_processor) {\n return\n }\n\n if (DEBUG) {\n this.debugger!.push_queued_data(data)\n }\n\n this.node_processor.port.postMessage(\n {\n type: 'queue',\n value: data,\n },\n [data[0].buffer, data[1].buffer],\n )\n }\n\n pump(): void {\n if (!this.enabled) {\n return\n }\n this.bus.send('dac-request-data')\n }\n}\n\nclass SpeakerBufferSourceDAC {\n bus: BusConnector\n audio_context: AudioContext\n enabled = false\n sampling_rate = 22050\n buffered_time = 0\n rate_ratio = 1\n node_lowpass: BiquadFilterNode\n node_output: BiquadFilterNode\n node_processor: AudioWorkletNode | null = null\n mixer_connection: SpeakerMixerSource\n debugger: SpeakerDACDebugger | undefined\n\n constructor(\n bus: BusConnector,\n audio_context: AudioContext,\n mixer: SpeakerMixer,\n ) {\n this.bus = bus\n this.audio_context = audio_context\n\n this.node_lowpass = this.audio_context.createBiquadFilter()\n this.node_lowpass.type = 'lowpass'\n\n this.node_output = this.node_lowpass\n\n this.mixer_connection = mixer.add_source(\n this.node_output,\n MIXER_SRC_DAC,\n )\n this.mixer_connection.set_gain_hidden(3)\n\n bus.register(\n 'dac-send-data',\n function (\n this: SpeakerBufferSourceDAC,\n data: [Float32Array, Float32Array],\n ) {\n this.queue(data)\n },\n this,\n )\n\n bus.register(\n 'dac-enable',\n function (this: SpeakerBufferSourceDAC) {\n this.enabled = true\n this.pump()\n },\n this,\n )\n\n bus.register(\n 'dac-disable',\n function (this: SpeakerBufferSourceDAC) {\n this.enabled = false\n },\n this,\n )\n\n bus.register(\n 'dac-tell-sampling-rate',\n function (this: SpeakerBufferSourceDAC, rate: number) {\n dbg_assert(rate > 0, 'Sampling rate should be nonzero')\n this.sampling_rate = rate\n this.rate_ratio = Math.ceil(\n AUDIOBUFFER_MINIMUM_SAMPLING_RATE / rate,\n )\n this.node_lowpass.frequency.setValueAtTime(\n rate / 2,\n this.audio_context.currentTime,\n )\n },\n this,\n )\n\n if (DEBUG) {\n this.debugger = new SpeakerDACDebugger(\n this.audio_context,\n this.node_output,\n )\n }\n }\n\n queue(data: [Float32Array, Float32Array]): void {\n if (DEBUG) {\n this.debugger!.push_queued_data(data)\n }\n\n const sample_count = data[0].length\n const block_duration = sample_count / this.sampling_rate\n\n let buffer: AudioBuffer\n if (this.rate_ratio > 1) {\n const new_sample_count = sample_count * this.rate_ratio\n const new_sampling_rate = this.sampling_rate * this.rate_ratio\n buffer = this.audio_context.createBuffer(\n 2,\n new_sample_count,\n new_sampling_rate,\n )\n const buffer_data0 = buffer.getChannelData(0)\n const buffer_data1 = buffer.getChannelData(1)\n\n let buffer_index = 0\n for (let i = 0; i < sample_count; i++) {\n for (let j = 0; j < this.rate_ratio; j++, buffer_index++) {\n buffer_data0[buffer_index] = data[0][i]\n buffer_data1[buffer_index] = data[1][i]\n }\n }\n } else {\n buffer = this.audio_context.createBuffer(\n 2,\n sample_count,\n this.sampling_rate,\n )\n if (buffer.copyToChannel) {\n buffer.copyToChannel(new Float32Array(data[0]), 0)\n buffer.copyToChannel(new Float32Array(data[1]), 1)\n } else {\n buffer.getChannelData(0).set(data[0])\n buffer.getChannelData(1).set(data[1])\n }\n }\n\n const source = this.audio_context.createBufferSource()\n source.buffer = buffer\n source.connect(this.node_lowpass)\n source.addEventListener('ended', this.pump.bind(this))\n\n const current_time = this.audio_context.currentTime\n\n if (this.buffered_time < current_time) {\n dbg_log(\n \"Speaker DAC - Creating/Recreating reserve - shouldn't occur frequently during playback\",\n )\n\n this.buffered_time = current_time\n const target_silence_duration = DAC_QUEUE_RESERVE - block_duration\n let current_silence_duration = 0\n while (current_silence_duration <= target_silence_duration) {\n current_silence_duration += block_duration\n this.buffered_time += block_duration\n setTimeout(() => this.pump(), current_silence_duration * 1000)\n }\n }\n\n source.start(this.buffered_time)\n this.buffered_time += block_duration\n\n setTimeout(() => this.pump(), 0)\n }\n\n pump(): void {\n if (!this.enabled) {\n return\n }\n if (\n this.buffered_time - this.audio_context.currentTime >\n DAC_QUEUE_RESERVE\n ) {\n return\n }\n this.bus.send('dac-request-data')\n }\n}\n\nclass SpeakerDACDebugger {\n audio_context: AudioContext\n node_source: AudioNode\n node_processor: ScriptProcessorNode | null = null\n node_gain: GainNode\n is_active = false\n queued_history: [Float32Array[], Float32Array[]][] = []\n output_history: [Float32Array[], Float32Array[]][] = []\n queued: [Float32Array[], Float32Array[]] = [[], []]\n output: [Float32Array[], Float32Array[]] = [[], []]\n\n constructor(audio_context: AudioContext, source_node: AudioNode) {\n this.audio_context = audio_context\n this.node_source = source_node\n\n this.node_gain = this.audio_context.createGain()\n this.node_gain.gain.setValueAtTime(0, this.audio_context.currentTime)\n\n this.node_gain.connect(this.audio_context.destination)\n }\n\n start(duration_ms: number): void {\n this.is_active = true\n this.queued = [[], []]\n this.output = [[], []]\n this.queued_history.push(this.queued)\n this.output_history.push(this.output)\n\n this.node_processor = this.audio_context.createScriptProcessor(\n 1024,\n 2,\n 2,\n )\n this.node_processor.onaudioprocess = (event) => {\n this.output[0].push(event.inputBuffer.getChannelData(0).slice())\n this.output[1].push(event.inputBuffer.getChannelData(1).slice())\n }\n\n this.node_source.connect(this.node_processor)\n this.node_processor.connect(this.node_gain)\n\n setTimeout(() => {\n this.stop()\n }, duration_ms)\n }\n\n stop(): void {\n this.is_active = false\n if (this.node_processor) {\n this.node_source.disconnect(this.node_processor)\n this.node_processor.disconnect()\n this.node_processor = null\n }\n }\n\n push_queued_data(data: [Float32Array, Float32Array]): void {\n if (this.is_active) {\n this.queued[0].push(data[0].slice())\n this.queued[1].push(data[1].slice())\n }\n }\n\n download_txt(history_id: number, channel: number): void {\n const txt = this.output_history[history_id][channel]\n .map((v) => v.join(' '))\n .join(' ')\n\n dump_file(txt, 'dacdata.txt')\n }\n\n download_csv(history_id: number): void {\n const buffers = this.output_history[history_id]\n const csv_rows: string[] = []\n for (let buffer_id = 0; buffer_id < buffers[0].length; buffer_id++) {\n for (let i = 0; i < buffers[0][buffer_id].length; i++) {\n csv_rows.push(\n `${buffers[0][buffer_id][i]},${buffers[1][buffer_id][i]}`,\n )\n }\n }\n dump_file(csv_rows.join('\\n'), 'dacdata.csv')\n }\n}\n", "import { BusConnector } from '../bus.js'\n\n/**\n * An ethernet-through-websocket adapter, to be used with\n * https://github.com/benjamincburns/websockproxy\n *\n * emulated ethernet card <--> this <--> websocket proxy <--> network\n */\nexport class NetworkAdapter {\n bus: BusConnector\n socket: WebSocket | undefined\n id: number\n send_queue: Uint8Array[]\n url: string\n reconnect_interval: number\n last_connect_attempt: number\n send_queue_limit: number\n destroyed: boolean\n\n constructor(url: string, bus: BusConnector, id?: number) {\n this.bus = bus\n this.socket = undefined\n this.id = id || 0\n\n // TODO: circular buffer?\n this.send_queue = []\n this.url = url\n\n this.reconnect_interval = 10000\n this.last_connect_attempt = Date.now() - this.reconnect_interval\n this.send_queue_limit = 64\n this.destroyed = false\n\n this.bus.register(\n 'net' + this.id + '-send',\n function (this: NetworkAdapter, data: Uint8Array) {\n this.send(data)\n },\n this,\n )\n }\n\n handle_message(e: MessageEvent): void {\n if (this.bus) {\n this.bus.send('net' + this.id + '-receive', new Uint8Array(e.data))\n }\n }\n\n handle_close(_e: CloseEvent): void {\n //console.log(\"onclose\", e);\n\n if (!this.destroyed) {\n this.connect()\n setTimeout(this.connect.bind(this), this.reconnect_interval)\n }\n }\n\n handle_open(_e: Event): void {\n //console.log(\"open\", e);\n\n for (let i = 0; i < this.send_queue.length; i++) {\n this.send(this.send_queue[i])\n }\n\n this.send_queue = []\n }\n\n handle_error(_e: Event): void {\n //console.log(\"onerror\", e);\n }\n\n destroy(): void {\n this.destroyed = true\n if (this.socket) {\n this.socket.close()\n }\n }\n\n connect(): void {\n if (typeof WebSocket === 'undefined') {\n return\n }\n\n if (this.socket) {\n const state = this.socket.readyState\n\n if (state === 0 || state === 1) {\n // already or almost there\n return\n }\n }\n\n const now = Date.now()\n\n if (this.last_connect_attempt + this.reconnect_interval > now) {\n return\n }\n\n this.last_connect_attempt = Date.now()\n\n try {\n this.socket = new WebSocket(this.url)\n } catch (e) {\n console.error(e)\n return\n }\n\n this.socket.binaryType = 'arraybuffer'\n\n this.socket.onopen = this.handle_open.bind(this)\n this.socket.onmessage = this.handle_message.bind(this)\n this.socket.onclose = this.handle_close.bind(this)\n this.socket.onerror = this.handle_error.bind(this)\n }\n\n send(data: Uint8Array): void {\n //console.log(\"send\", data);\n\n if (!this.socket || this.socket.readyState !== 1) {\n this.send_queue.push(data)\n\n if (this.send_queue.length > 2 * this.send_queue_limit) {\n this.send_queue = this.send_queue.slice(-this.send_queue_limit)\n }\n\n this.connect()\n } else {\n this.socket.send(new Uint8Array(data))\n }\n }\n\n change_proxy(url: string): void {\n this.url = url\n\n if (this.socket) {\n this.socket.onclose = function () {}\n this.socket.onerror = function () {}\n this.socket.close()\n this.socket = undefined\n }\n }\n}\n", "import { LOG_FETCH } from '../const.js'\nimport { h } from '../lib.js'\nimport { dbg_assert, dbg_log } from '../log.js'\n\n// https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml\nconst ETHERTYPE_IPV4 = 0x0800\nconst ETHERTYPE_ARP = 0x0806\nconst ETHERTYPE_IPV6 = 0x86dd\n\nconst IPV4_PROTO_ICMP = 1\nconst IPV4_PROTO_TCP = 6\nconst IPV4_PROTO_UDP = 17\n\nconst UNIX_EPOCH = new Date('1970-01-01T00:00:00Z').getTime()\nconst NTP_EPOCH = new Date('1900-01-01T00:00:00Z').getTime()\nconst NTP_EPOC_DIFF = UNIX_EPOCH - NTP_EPOCH\nconst TWO_TO_32 = Math.pow(2, 32)\n\nconst DHCP_MAGIC_COOKIE = 0x63825363\nconst V86_ASCII = [118, 56, 54]\n\n/* For the complete TCP state diagram see:\n *\n * https://en.wikipedia.org/wiki/File:Tcp_state_diagram_fixed_new.svg\n *\n * State TIME_WAIT is not needed, we can skip it and transition directly to CLOSED instead.\n */\nexport const TCP_STATE_CLOSED = 'closed'\nexport const TCP_STATE_SYN_RECEIVED = 'syn-received'\nexport const TCP_STATE_SYN_SENT = 'syn-sent'\nexport const TCP_STATE_SYN_PROBE = 'syn-probe'\n//const TCP_STATE_LISTEN = \"listen\";\nexport const TCP_STATE_ESTABLISHED = 'established'\nexport const TCP_STATE_FIN_WAIT_1 = 'fin-wait-1'\nexport const TCP_STATE_CLOSE_WAIT = 'close-wait'\nexport const TCP_STATE_FIN_WAIT_2 = 'fin-wait-2'\nexport const TCP_STATE_LAST_ACK = 'last-ack'\nexport const TCP_STATE_CLOSING = 'closing'\n//const TCP_STATE_TIME_WAIT = \"time-wait\";\n\n// source: RFC6335, 6. Port Number Ranges\nconst TCP_DYNAMIC_PORT_START = 49152\nconst TCP_DYNAMIC_PORT_END = 65535\nconst TCP_DYNAMIC_PORT_RANGE = TCP_DYNAMIC_PORT_END - TCP_DYNAMIC_PORT_START\n\nconst ETH_HEADER_SIZE = 14\nconst ETH_PAYLOAD_OFFSET = ETH_HEADER_SIZE\nconst MTU_DEFAULT = 1500\nconst ETH_TRAILER_SIZE = 4\nconst IPV4_HEADER_SIZE = 20\nconst IPV4_PAYLOAD_OFFSET = ETH_PAYLOAD_OFFSET + IPV4_HEADER_SIZE\nconst UDP_HEADER_SIZE = 8\nconst UDP_PAYLOAD_OFFSET = IPV4_PAYLOAD_OFFSET + UDP_HEADER_SIZE\nconst TCP_HEADER_SIZE = 20\nconst TCP_PAYLOAD_OFFSET = IPV4_PAYLOAD_OFFSET + TCP_HEADER_SIZE\nconst ICMP_HEADER_SIZE = 4\n\nconst DEFAULT_DOH_SERVER = 'cloudflare-dns.com'\n\n// Suppress unused variable warnings for protocol offset constants\nvoid TCP_PAYLOAD_OFFSET\n\nexport interface EthEncoderBuf {\n eth_frame: Uint8Array\n eth_frame_view: DataView\n eth_payload_view: DataView\n ipv4_payload_view: DataView\n udp_payload_view: DataView\n text_encoder: TextEncoder\n}\n\ninterface EthHeader {\n ethertype: number\n src: Uint8Array\n dest: Uint8Array\n dest_s?: string\n src_s?: string\n}\n\ninterface ArpHeader {\n htype: number\n ptype: number\n oper: number\n sha: Uint8Array\n spa: Uint8Array\n tha: Uint8Array\n tpa: Uint8Array\n}\n\ninterface Ipv4Header {\n version?: number\n ihl?: number\n tos?: number\n len?: number\n id?: number\n ttl?: number\n proto: number\n ip_checksum?: number\n src: Uint8Array\n dest: Uint8Array\n}\n\ninterface IcmpHeader {\n type: number\n code: number\n checksum?: number\n data: Uint8Array\n}\n\ninterface TcpHeader {\n sport: number\n dport: number\n seq: number\n ackn: number\n doff?: number\n winsize: number\n checksum?: number\n urgent?: number\n fin?: boolean\n syn?: boolean\n rst?: boolean\n psh?: boolean\n ack?: boolean\n urg?: boolean\n ece?: boolean\n cwr?: boolean\n options?: {\n mss?: number\n }\n}\n\ninterface UdpHeader {\n sport: number\n dport: number\n len?: number\n checksum?: number\n data?: Uint8Array\n data_s?: string\n}\n\ninterface DnsQuestion {\n name: string[]\n type: number\n class: number\n}\n\ninterface DnsAnswer {\n name: string[]\n type: number\n class: number\n ttl: number\n data: Uint8Array | number[]\n}\n\ninterface DnsHeader {\n id: number\n flags: number\n questions: DnsQuestion[]\n answers: DnsAnswer[]\n}\n\ninterface DhcpHeader {\n op: number\n htype: number\n hlen: number\n hops: number\n xid: number\n secs: number\n flags: number\n ciaddr: number\n yiaddr: number\n siaddr: number\n giaddr: number\n chaddr: Uint8Array\n magic?: number\n options: Uint8Array[]\n}\n\ninterface NtpHeader {\n flags: number\n stratum: number\n poll: number\n precision: number\n root_delay: number\n root_disp: number\n ref_id: number\n ref_ts_i: number\n ref_ts_f: number\n ori_ts_i: number\n ori_ts_f: number\n rec_ts_i: number\n rec_ts_f: number\n trans_ts_i: number\n trans_ts_f: number\n}\n\nexport interface PacketSpec {\n eth: EthHeader\n arp?: ArpHeader\n ipv4?: Ipv4Header\n icmp?: IcmpHeader\n tcp?: TcpHeader\n tcp_data?: Uint8Array\n udp?: UdpHeader\n dns?: DnsHeader\n dhcp?: DhcpHeader\n ntp?: NtpHeader\n dhcp_options?: Uint8Array[]\n}\n\nexport interface NetworkAdapterLike {\n bus: { pair?: { send(name: string, value: unknown): void } }\n router_mac: Uint8Array\n router_ip: Uint8Array\n vm_ip: Uint8Array\n vm_mac: Uint8Array\n masquerade: boolean\n dns_method: string\n doh_server?: string\n tcp_conn: Record<string, TCPConnection>\n mtu?: number\n eth_encoder_buf: EthEncoderBuf\n receive(data: Uint8Array): void\n on_tcp_connection?(conn: TCPConnection, packet: PacketSpec): boolean | void\n}\n\nfunction a2ethaddr(bytes: Uint8Array): string {\n return [0, 1, 2, 3, 4, 5]\n .map((i) => bytes[i].toString(16))\n .map((x) => (x.length === 1 ? '0' + x : x))\n .join(':')\n}\n\nfunction iptolong(parts: Uint8Array): number {\n return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]\n}\n\nclass GrowableRingbuffer {\n maximum_capacity: number\n tail: number\n head: number\n length: number\n buffer: Uint8Array\n\n constructor(initial_capacity: number, maximum_capacity: number) {\n initial_capacity = Math.min(initial_capacity, 16)\n this.maximum_capacity = maximum_capacity\n ? Math.max(maximum_capacity, initial_capacity)\n : 0\n this.tail = 0\n this.head = 0\n this.length = 0\n this.buffer = new Uint8Array(initial_capacity)\n }\n\n write(src_array: Uint8Array): void {\n const src_length = src_array.length\n const total_length = this.length + src_length\n let capacity = this.buffer.length\n if (capacity < total_length) {\n dbg_assert(capacity > 0)\n while (capacity < total_length) {\n capacity *= 2\n }\n if (this.maximum_capacity && capacity > this.maximum_capacity) {\n throw new Error(\n 'stream capacity overflow in GrowableRingbuffer.write(), package dropped',\n )\n }\n const new_buffer = new Uint8Array(capacity)\n this.peek(new_buffer)\n this.tail = 0\n this.head = this.length\n this.buffer = new_buffer\n }\n const buffer = this.buffer\n\n const new_head = this.head + src_length\n if (new_head > capacity) {\n const i_split = capacity - this.head\n buffer.set(src_array.subarray(0, i_split), this.head)\n buffer.set(src_array.subarray(i_split))\n } else {\n buffer.set(src_array, this.head)\n }\n this.head = new_head % capacity\n this.length += src_length\n }\n\n peek(dst_array: Uint8Array): number {\n const length = Math.min(this.length, dst_array.length)\n if (length) {\n const buffer = this.buffer\n const capacity = buffer.length\n const new_tail = this.tail + length\n if (new_tail > capacity) {\n const buf_len_left = new_tail % capacity\n const buf_len_right = capacity - this.tail\n dst_array.set(buffer.subarray(this.tail))\n dst_array.set(buffer.subarray(0, buf_len_left), buf_len_right)\n } else {\n dst_array.set(buffer.subarray(this.tail, new_tail))\n }\n }\n return length\n }\n\n remove(length: number): number {\n if (length > this.length) {\n length = this.length\n }\n if (length) {\n this.tail = (this.tail + length) % this.buffer.length\n this.length -= length\n }\n return length\n }\n}\n\nexport function create_eth_encoder_buf(\n mtu: number = MTU_DEFAULT,\n): EthEncoderBuf {\n const ETH_FRAME_SIZE = ETH_HEADER_SIZE + mtu + ETH_TRAILER_SIZE\n const IPV4_PAYLOAD_SIZE = mtu - IPV4_HEADER_SIZE\n const UDP_PAYLOAD_SIZE = IPV4_PAYLOAD_SIZE - UDP_HEADER_SIZE\n\n const eth_frame = new Uint8Array(ETH_FRAME_SIZE)\n const buffer = eth_frame.buffer\n const offset = eth_frame.byteOffset\n return {\n eth_frame: eth_frame,\n eth_frame_view: new DataView(buffer),\n eth_payload_view: new DataView(\n buffer,\n offset + ETH_PAYLOAD_OFFSET,\n mtu,\n ),\n ipv4_payload_view: new DataView(\n buffer,\n offset + IPV4_PAYLOAD_OFFSET,\n IPV4_PAYLOAD_SIZE,\n ),\n udp_payload_view: new DataView(\n buffer,\n offset + UDP_PAYLOAD_OFFSET,\n UDP_PAYLOAD_SIZE,\n ),\n text_encoder: new TextEncoder(),\n }\n}\n\n/**\n * Copy given data array into view starting at offset, return number of bytes written.\n */\nfunction view_set_array(\n offset: number,\n data: Uint8Array | number[],\n view: DataView,\n out: EthEncoderBuf,\n): number {\n out.eth_frame.set(data, view.byteOffset + offset)\n return data.length\n}\n\n/**\n * Write zeros into the view starting at offset\n */\nfunction view_set_zeros(\n offset: number,\n length: number,\n view: DataView,\n out: EthEncoderBuf,\n): void {\n out.eth_frame.fill(\n 0,\n view.byteOffset + offset,\n view.byteOffset + offset + length,\n )\n}\n\n/**\n * UTF8-encode given string into view starting at offset, return number of bytes written.\n */\nfunction view_set_string(\n offset: number,\n str: string,\n view: DataView,\n out: EthEncoderBuf,\n): number {\n return out.text_encoder.encodeInto(\n str,\n out.eth_frame.subarray(view.byteOffset + offset),\n ).written\n}\n\n/**\n * Calculate internet checksum for view[0 : length] and return the 16-bit result.\n * Source: RFC768 and RFC1071 (chapter 4.1).\n */\nfunction calc_inet_checksum(\n length: number,\n checksum: number,\n view: DataView,\n out: EthEncoderBuf,\n): number {\n const uint16_end = view.byteOffset + (length & ~1)\n const eth_frame = out.eth_frame\n for (let i = view.byteOffset; i < uint16_end; i += 2) {\n checksum += (eth_frame[i] << 8) | eth_frame[i + 1]\n }\n if (length & 1) {\n checksum += eth_frame[uint16_end] << 8\n }\n while (checksum >>> 16) {\n checksum = (checksum & 0xffff) + (checksum >>> 16)\n }\n return ~checksum & 0xffff\n}\n\nfunction make_packet(out: EthEncoderBuf, spec: PacketSpec): Uint8Array {\n dbg_assert(!!spec.eth)\n out.eth_frame.fill(0)\n return out.eth_frame.subarray(0, write_eth(spec, out))\n}\n\nfunction handle_fake_tcp(\n packet: PacketSpec,\n adapter: NetworkAdapterLike,\n): boolean | undefined {\n const tuple = `${packet.ipv4!.src.join('.')}:${packet.tcp!.sport}:${packet.ipv4!.dest.join('.')}:${packet.tcp!.dport}`\n\n if (packet.tcp!.syn && !packet.tcp!.ack) {\n if (adapter.tcp_conn[tuple]) {\n dbg_log('SYN to already opened port', LOG_FETCH)\n delete adapter.tcp_conn[tuple]\n }\n\n const conn = new TCPConnection(adapter)\n conn.state = TCP_STATE_SYN_RECEIVED\n conn.tuple = tuple\n conn.last = packet\n\n conn.hsrc = packet.eth.dest\n conn.psrc = packet.ipv4!.dest\n conn.sport = packet.tcp!.dport\n conn.hdest = packet.eth.src\n conn.dport = packet.tcp!.sport\n conn.pdest = packet.ipv4!.src\n\n adapter.bus.pair?.send('tcp-connection', conn)\n\n if (adapter.on_tcp_connection) {\n adapter.on_tcp_connection(conn, packet)\n }\n if (adapter.tcp_conn[tuple]) return\n }\n\n if (!adapter.tcp_conn[tuple]) {\n dbg_log(`I dont know about ${tuple}, so resetting`, LOG_FETCH)\n let bop = packet.tcp!.ackn\n if (packet.tcp!.fin || packet.tcp!.syn) bop += 1\n const reply: PacketSpec = {\n eth: {\n ethertype: ETHERTYPE_IPV4,\n src: adapter.router_mac,\n dest: packet.eth.src,\n },\n ipv4: {\n proto: IPV4_PROTO_TCP,\n src: packet.ipv4!.dest,\n dest: packet.ipv4!.src,\n },\n tcp: {\n sport: packet.tcp!.dport,\n dport: packet.tcp!.sport,\n seq: bop,\n ackn: packet.tcp!.seq + (packet.tcp!.syn ? 1 : 0),\n winsize: packet.tcp!.winsize,\n rst: true,\n ack: packet.tcp!.syn,\n },\n }\n adapter.receive(make_packet(adapter.eth_encoder_buf, reply))\n return true\n }\n\n adapter.tcp_conn[tuple].process(packet)\n return undefined\n}\n\nfunction handle_fake_dns_static(\n packet: PacketSpec,\n adapter: NetworkAdapterLike,\n): boolean {\n const reply: PacketSpec = {\n eth: {\n ethertype: ETHERTYPE_IPV4,\n src: adapter.router_mac,\n dest: packet.eth.src,\n },\n ipv4: {\n proto: IPV4_PROTO_UDP,\n src: adapter.router_ip,\n dest: packet.ipv4!.src,\n },\n udp: { sport: 53, dport: packet.udp!.sport },\n }\n\n const answers: DnsAnswer[] = []\n let flags = 0x8000 //Response,\n flags |= 0x0180 // Recursion\n // flags |= 0x0400; Authoritative\n\n for (let i = 0; i < packet.dns!.questions.length; ++i) {\n const q = packet.dns!.questions[i]\n\n switch (q.type) {\n case 1: // A record\n answers.push({\n name: q.name,\n type: q.type,\n class: q.class,\n ttl: 600,\n data: [192, 168, 87, 1],\n })\n break\n default:\n }\n }\n\n reply.dns = {\n id: packet.dns!.id,\n flags: flags,\n questions: packet.dns!.questions,\n answers: answers,\n }\n adapter.receive(make_packet(adapter.eth_encoder_buf, reply))\n return true\n}\n\nfunction handle_fake_dns_doh(\n packet: PacketSpec,\n adapter: NetworkAdapterLike,\n): boolean {\n const fetch_url = `https://${adapter.doh_server || DEFAULT_DOH_SERVER}/dns-query`\n const udp_data = packet.udp!.data\n const fetch_opts: RequestInit = {\n method: 'POST',\n headers: [['content-type', 'application/dns-message']],\n body: udp_data ? udp_data.slice() : undefined,\n }\n fetch(fetch_url, fetch_opts).then(async (resp) => {\n const reply: PacketSpec = {\n eth: {\n ethertype: ETHERTYPE_IPV4,\n src: adapter.router_mac,\n dest: packet.eth.src,\n },\n ipv4: {\n proto: IPV4_PROTO_UDP,\n src: adapter.router_ip,\n dest: packet.ipv4!.src,\n },\n udp: {\n sport: 53,\n dport: packet.udp!.sport,\n data: new Uint8Array(await resp.arrayBuffer()),\n },\n }\n adapter.receive(make_packet(adapter.eth_encoder_buf, reply))\n })\n return true\n}\n\nfunction handle_fake_dns(\n packet: PacketSpec,\n adapter: NetworkAdapterLike,\n): boolean {\n if (adapter.dns_method === 'static') {\n return handle_fake_dns_static(packet, adapter)\n } else {\n return handle_fake_dns_doh(packet, adapter)\n }\n}\n\nfunction handle_fake_ntp(\n packet: PacketSpec,\n adapter: NetworkAdapterLike,\n): boolean {\n const now = Date.now() // - 1000 * 60 * 60 * 24 * 7;\n const now_n = now + NTP_EPOC_DIFF\n const now_n_f = TWO_TO_32 * ((now_n % 1000) / 1000)\n\n const reply: PacketSpec = {\n eth: {\n ethertype: ETHERTYPE_IPV4,\n src: adapter.router_mac,\n dest: packet.eth.src,\n },\n ipv4: {\n proto: IPV4_PROTO_UDP,\n src: packet.ipv4!.dest,\n dest: packet.ipv4!.src,\n },\n udp: { sport: 123, dport: packet.udp!.sport },\n }\n const flags = (0 << 6) | (4 << 3) | 4\n reply.ntp = Object.assign({}, packet.ntp!)\n reply.ntp.flags = flags\n reply.ntp.poll = 10\n reply.ntp.ori_ts_i = packet.ntp!.trans_ts_i\n reply.ntp.ori_ts_f = packet.ntp!.trans_ts_f\n\n reply.ntp.rec_ts_i = now_n / 1000\n reply.ntp.rec_ts_f = now_n_f\n\n reply.ntp.trans_ts_i = now_n / 1000\n reply.ntp.trans_ts_f = now_n_f\n\n reply.ntp.stratum = 2\n adapter.receive(make_packet(adapter.eth_encoder_buf, reply))\n return true\n}\n\nfunction handle_fake_dhcp(\n packet: PacketSpec,\n adapter: NetworkAdapterLike,\n): void {\n const reply: PacketSpec = {\n eth: {\n ethertype: ETHERTYPE_IPV4,\n src: adapter.router_mac,\n dest: packet.eth.src,\n },\n ipv4: {\n proto: IPV4_PROTO_UDP,\n src: adapter.router_ip,\n dest: adapter.vm_ip,\n },\n udp: { sport: 67, dport: 68 },\n }\n reply.dhcp = {\n htype: 1,\n hlen: 6,\n hops: 0,\n xid: packet.dhcp!.xid,\n secs: 0,\n flags: 0,\n ciaddr: 0,\n yiaddr: iptolong(adapter.vm_ip),\n siaddr: iptolong(adapter.router_ip),\n giaddr: iptolong(adapter.router_ip),\n chaddr: packet.dhcp!.chaddr,\n op: 0,\n options: [],\n }\n\n const options: Uint8Array[] = []\n\n // idk, it seems like op should be 3, but udhcpc sends 1\n const fix = packet.dhcp!.options.find(function (x: Uint8Array) {\n return x[0] === 53\n })\n if (fix && fix[2] === 3) packet.dhcp!.op = 3\n\n if (packet.dhcp!.op === 1) {\n reply.dhcp.op = 2\n options.push(new Uint8Array([53, 1, 2]))\n }\n\n if (packet.dhcp!.op === 3) {\n reply.dhcp.op = 2\n options.push(new Uint8Array([53, 1, 5]))\n options.push(new Uint8Array([51, 4, 8, 0, 0, 0])) // Lease Time\n }\n\n const router_ip: number[] = [\n adapter.router_ip[0],\n adapter.router_ip[1],\n adapter.router_ip[2],\n adapter.router_ip[3],\n ]\n options.push(new Uint8Array([1, 4, 255, 255, 255, 0])) // Netmask\n if (adapter.masquerade) {\n options.push(new Uint8Array([3, 4].concat(router_ip))) // Router\n options.push(new Uint8Array([6, 4].concat(router_ip))) // DNS\n }\n options.push(new Uint8Array([54, 4].concat(router_ip))) // DHCP Server\n options.push(new Uint8Array([60, 3].concat(V86_ASCII))) // Vendor\n options.push(new Uint8Array([255, 0]))\n\n reply.dhcp.options = options\n adapter.receive(make_packet(adapter.eth_encoder_buf, reply))\n}\n\nexport function handle_fake_networking(\n data: Uint8Array,\n adapter: NetworkAdapterLike,\n): void {\n const packet: PacketSpec = {\n eth: { ethertype: 0, src: new Uint8Array(6), dest: new Uint8Array(6) },\n }\n parse_eth(data, packet)\n\n if (packet.ipv4) {\n if (packet.tcp) {\n handle_fake_tcp(packet, adapter)\n } else if (packet.udp) {\n if (packet.dns) {\n handle_fake_dns(packet, adapter)\n } else if (packet.dhcp) {\n handle_fake_dhcp(packet, adapter)\n } else if (packet.ntp) {\n handle_fake_ntp(packet, adapter)\n } else if (packet.udp.dport === 8) {\n handle_udp_echo(packet, adapter)\n }\n } else if (packet.icmp && packet.icmp.type === 8) {\n handle_fake_ping(packet, adapter)\n }\n } else if (\n packet.arp &&\n packet.arp.oper === 1 &&\n packet.arp.ptype === ETHERTYPE_IPV4\n ) {\n arp_whohas(packet, adapter)\n }\n}\n\nfunction parse_eth(data: Uint8Array, o: PacketSpec): void {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n\n const ethertype = view.getUint16(12)\n const eth: EthHeader = {\n ethertype: ethertype,\n dest: data.subarray(0, 6),\n dest_s: a2ethaddr(data.subarray(0, 6)),\n src: data.subarray(6, 12),\n src_s: a2ethaddr(data.subarray(6, 12)),\n }\n\n o.eth = eth\n\n // TODO: Remove CRC from the end of the packet maybe?\n const payload = data.subarray(ETH_HEADER_SIZE, data.length)\n\n if (ethertype === ETHERTYPE_IPV4) {\n parse_ipv4(payload, o)\n } else if (ethertype === ETHERTYPE_ARP) {\n parse_arp(payload, o)\n } else if (ethertype === ETHERTYPE_IPV6) {\n dbg_log('Unimplemented: ipv6')\n } else {\n dbg_log('Unknown ethertype: ' + h(ethertype), LOG_FETCH)\n }\n}\n\nfunction write_eth(spec: PacketSpec, out: EthEncoderBuf): number {\n const view = out.eth_frame_view\n view_set_array(0, spec.eth.dest, view, out)\n view_set_array(6, spec.eth.src, view, out)\n view.setUint16(12, spec.eth.ethertype)\n let len = ETH_HEADER_SIZE\n if (spec.arp) {\n len += write_arp(spec, out)\n } else if (spec.ipv4) {\n len += write_ipv4(spec, out)\n }\n return len\n}\n\nfunction parse_arp(data: Uint8Array, o: PacketSpec): void {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n\n const arp: ArpHeader = {\n htype: view.getUint16(0),\n ptype: view.getUint16(2),\n oper: view.getUint16(6),\n sha: data.subarray(8, 14),\n spa: data.subarray(14, 18),\n tha: data.subarray(18, 24),\n tpa: data.subarray(24, 28),\n }\n o.arp = arp\n}\n\nfunction write_arp(spec: PacketSpec, out: EthEncoderBuf): number {\n const view = out.eth_payload_view\n view.setUint16(0, spec.arp!.htype)\n view.setUint16(2, spec.arp!.ptype)\n view.setUint8(4, spec.arp!.sha.length)\n view.setUint8(5, spec.arp!.spa.length)\n view.setUint16(6, spec.arp!.oper)\n view_set_array(8, spec.arp!.sha, view, out)\n view_set_array(14, spec.arp!.spa, view, out)\n view_set_array(18, spec.arp!.tha, view, out)\n view_set_array(24, spec.arp!.tpa, view, out)\n return 28\n}\n\nfunction parse_ipv4(data: Uint8Array, o: PacketSpec): void {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n\n const version = (data[0] >> 4) & 0x0f\n const ihl = data[0] & 0x0f\n\n const tos = view.getUint8(1)\n const len = view.getUint16(2)\n\n const ttl = view.getUint8(8)\n const proto = view.getUint8(9)\n const ip_checksum = view.getUint16(10)\n\n const ipv4: Ipv4Header = {\n version,\n ihl,\n tos,\n len,\n ttl,\n proto,\n ip_checksum,\n src: data.subarray(12, 12 + 4),\n dest: data.subarray(16, 16 + 4),\n }\n\n // Ethernet minmum packet size.\n if (Math.max(len, 46) !== data.length) {\n dbg_log(`ipv4 Length mismatch: ${len} != ${data.length}`, LOG_FETCH)\n }\n\n o.ipv4 = ipv4\n const ipdata = data.subarray(ihl * 4, len)\n if (proto === IPV4_PROTO_ICMP) {\n parse_icmp(ipdata, o)\n } else if (proto === IPV4_PROTO_TCP) {\n parse_tcp(ipdata, o)\n } else if (proto === IPV4_PROTO_UDP) {\n parse_udp(ipdata, o)\n }\n}\n\nfunction write_ipv4(spec: PacketSpec, out: EthEncoderBuf): number {\n const view = out.eth_payload_view\n const ihl = IPV4_HEADER_SIZE >> 2 // header length in 32-bit words\n const version = 4\n\n let len = IPV4_HEADER_SIZE\n if (spec.icmp) {\n len += write_icmp(spec, out)\n } else if (spec.udp) {\n len += write_udp(spec, out)\n } else if (spec.tcp) {\n len += write_tcp(spec, out)\n }\n\n view.setUint8(0, (version << 4) | (ihl & 0x0f))\n view.setUint8(1, spec.ipv4!.tos || 0)\n view.setUint16(2, len)\n view.setUint16(4, spec.ipv4!.id || 0)\n view.setUint8(6, 2 << 5) // DF Flag\n view.setUint8(8, spec.ipv4!.ttl || 32)\n view.setUint8(9, spec.ipv4!.proto)\n view.setUint16(10, 0) // checksum initially zero before calculation\n view_set_array(12, spec.ipv4!.src, view, out)\n view_set_array(16, spec.ipv4!.dest, view, out)\n view.setUint16(10, calc_inet_checksum(IPV4_HEADER_SIZE, 0, view, out))\n return len\n}\n\nfunction parse_icmp(data: Uint8Array, o: PacketSpec): void {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n const icmp: IcmpHeader = {\n type: view.getUint8(0),\n code: view.getUint8(1),\n checksum: view.getUint16(2),\n data: data.subarray(4),\n }\n o.icmp = icmp\n}\n\nfunction write_icmp(spec: PacketSpec, out: EthEncoderBuf): number {\n const view = out.ipv4_payload_view\n view.setUint8(0, spec.icmp!.type)\n view.setUint8(1, spec.icmp!.code)\n view.setUint16(2, 0) // checksum initially zero before calculation\n const data_length = view_set_array(\n ICMP_HEADER_SIZE,\n spec.icmp!.data,\n view,\n out,\n )\n const total_length = ICMP_HEADER_SIZE + data_length\n view.setUint16(2, calc_inet_checksum(total_length, 0, view, out))\n return total_length\n}\n\nfunction parse_udp(data: Uint8Array, o: PacketSpec): void {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n const udp: UdpHeader = {\n sport: view.getUint16(0),\n dport: view.getUint16(2),\n len: view.getUint16(4),\n checksum: view.getUint16(6),\n data: data.subarray(8),\n data_s: new TextDecoder().decode(data.subarray(8)),\n }\n\n //dbg_assert(udp.data.length + 8 == udp.len);\n if (udp.dport === 67 || udp.sport === 67) {\n //DHCP\n parse_dhcp(data.subarray(8), o)\n } else if (udp.dport === 53 || udp.sport === 53) {\n parse_dns(data.subarray(8), o)\n } else if (udp.dport === 123) {\n parse_ntp(data.subarray(8), o)\n }\n o.udp = udp\n}\n\nfunction write_udp(spec: PacketSpec, out: EthEncoderBuf): number {\n const view = out.ipv4_payload_view\n let total_length = UDP_HEADER_SIZE\n if (spec.dhcp) {\n total_length += write_dhcp(spec, out)\n } else if (spec.dns) {\n total_length += write_dns(spec, out)\n } else if (spec.ntp) {\n total_length += write_ntp(spec, out)\n } else {\n total_length += view_set_array(\n 0,\n spec.udp!.data!,\n out.udp_payload_view,\n out,\n )\n }\n\n view.setUint16(0, spec.udp!.sport)\n view.setUint16(2, spec.udp!.dport)\n view.setUint16(4, total_length)\n view.setUint16(6, 0) // checksum initially zero before calculation\n\n const pseudo_header =\n ((spec.ipv4!.src[0] << 8) | spec.ipv4!.src[1]) +\n ((spec.ipv4!.src[2] << 8) | spec.ipv4!.src[3]) +\n ((spec.ipv4!.dest[0] << 8) | spec.ipv4!.dest[1]) +\n ((spec.ipv4!.dest[2] << 8) | spec.ipv4!.dest[3]) +\n IPV4_PROTO_UDP +\n total_length\n view.setUint16(\n 6,\n calc_inet_checksum(total_length, pseudo_header, view, out),\n )\n return total_length\n}\n\nfunction parse_dns(data: Uint8Array, o: PacketSpec): void {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n const dns: DnsHeader = {\n id: view.getUint16(0),\n flags: view.getUint16(2),\n questions: [],\n answers: [],\n }\n\n const qdcount = view.getUint16(4)\n const ancount = view.getUint16(6)\n\n let offset = 12\n function read_dstr(): string[] {\n const o: string[] = []\n let len: number\n do {\n len = view.getUint8(offset)\n o.push(\n new TextDecoder().decode(\n data.subarray(offset + 1, offset + 1 + len),\n ),\n )\n offset += len + 1\n } while (len > 0)\n return o\n }\n\n for (let i = 0; i < qdcount; i++) {\n dns.questions.push({\n name: read_dstr(),\n type: view.getInt16(offset),\n class: view.getInt16(offset + 2),\n })\n offset += 4\n }\n for (let i = 0; i < ancount; i++) {\n const ans: DnsAnswer = {\n name: read_dstr(),\n type: view.getInt16(offset),\n class: view.getUint16(offset + 2),\n ttl: view.getUint32(offset + 4),\n data: new Uint8Array(0),\n }\n offset += 8\n const rdlen = view.getUint16(offset)\n offset += 2\n ans.data = data.subarray(offset, offset + rdlen)\n offset += rdlen\n dns.answers.push(ans)\n }\n o.dns = dns\n}\n\nfunction write_dns(spec: PacketSpec, out: EthEncoderBuf): number {\n const view = out.udp_payload_view\n view.setUint16(0, spec.dns!.id)\n view.setUint16(2, spec.dns!.flags)\n view.setUint16(4, spec.dns!.questions.length)\n view.setUint16(6, spec.dns!.answers.length)\n\n let offset = 12\n for (let i = 0; i < spec.dns!.questions.length; ++i) {\n const q = spec.dns!.questions[i]\n for (const s of q.name) {\n const n_written = view_set_string(offset + 1, s, view, out)\n view.setUint8(offset, n_written)\n offset += 1 + n_written\n }\n view.setUint16(offset, q.type)\n offset += 2\n view.setUint16(offset, q.class)\n offset += 2\n }\n\n function write_reply(a: DnsAnswer): void {\n for (const s of a.name) {\n const n_written = view_set_string(offset + 1, s, view, out)\n view.setUint8(offset, n_written)\n offset += 1 + n_written\n }\n view.setUint16(offset, a.type)\n offset += 2\n view.setUint16(offset, a.class)\n offset += 2\n view.setUint32(offset, a.ttl)\n offset += 4\n view.setUint16(offset, a.data.length)\n offset += 2\n offset += view_set_array(offset, a.data, view, out)\n }\n\n for (let i = 0; i < spec.dns!.answers.length; ++i) {\n const a = spec.dns!.answers[i]\n write_reply(a)\n }\n\n return offset\n}\n\nfunction parse_dhcp(data: Uint8Array, o: PacketSpec): void {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n const dhcp: DhcpHeader = {\n op: view.getUint8(0),\n htype: view.getUint8(1),\n hlen: view.getUint8(2),\n hops: view.getUint8(3),\n xid: view.getUint32(4),\n secs: view.getUint16(8),\n flags: view.getUint16(10),\n ciaddr: view.getUint32(12),\n yiaddr: view.getUint32(16),\n siaddr: view.getUint32(20),\n giaddr: view.getUint32(24),\n chaddr: data.subarray(28, 28 + 16),\n magic: view.getUint32(236),\n options: [],\n }\n\n const options = data.subarray(240)\n for (let i = 0; i < options.length; ++i) {\n const start = i\n const op = options[i]\n if (op === 0) continue\n ++i\n const len = options[i]\n i += len\n dhcp.options.push(options.subarray(start, start + len + 2))\n }\n\n o.dhcp = dhcp\n o.dhcp_options = dhcp.options\n}\n\nfunction write_dhcp(spec: PacketSpec, out: EthEncoderBuf): number {\n const view = out.udp_payload_view\n view.setUint8(0, spec.dhcp!.op)\n view.setUint8(1, spec.dhcp!.htype)\n view.setUint8(2, spec.dhcp!.hlen)\n view.setUint8(3, spec.dhcp!.hops)\n view.setUint32(4, spec.dhcp!.xid)\n view.setUint16(8, spec.dhcp!.secs)\n view.setUint16(10, spec.dhcp!.flags)\n view.setUint32(12, spec.dhcp!.ciaddr)\n view.setUint32(16, spec.dhcp!.yiaddr)\n view.setUint32(20, spec.dhcp!.siaddr)\n view.setUint32(24, spec.dhcp!.giaddr)\n view_set_array(28, spec.dhcp!.chaddr, view, out)\n\n view.setUint32(236, DHCP_MAGIC_COOKIE)\n\n let offset = 240\n for (const o of spec.dhcp!.options) {\n offset += view_set_array(offset, o, view, out)\n }\n return offset\n}\n\nfunction parse_ntp(data: Uint8Array, o: PacketSpec): void {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n o.ntp = {\n flags: view.getUint8(0),\n stratum: view.getUint8(1),\n poll: view.getUint8(2),\n precision: view.getUint8(3),\n root_delay: view.getUint32(4),\n root_disp: view.getUint32(8),\n ref_id: view.getUint32(12),\n ref_ts_i: view.getUint32(16),\n ref_ts_f: view.getUint32(20),\n ori_ts_i: view.getUint32(24),\n ori_ts_f: view.getUint32(28),\n rec_ts_i: view.getUint32(32),\n rec_ts_f: view.getUint32(36),\n trans_ts_i: view.getUint32(40),\n trans_ts_f: view.getUint32(44),\n }\n}\n\nfunction write_ntp(spec: PacketSpec, out: EthEncoderBuf): number {\n const view = out.udp_payload_view\n view.setUint8(0, spec.ntp!.flags)\n view.setUint8(1, spec.ntp!.stratum)\n view.setUint8(2, spec.ntp!.poll)\n view.setUint8(3, spec.ntp!.precision)\n view.setUint32(4, spec.ntp!.root_delay)\n view.setUint32(8, spec.ntp!.root_disp)\n view.setUint32(12, spec.ntp!.ref_id)\n view.setUint32(16, spec.ntp!.ref_ts_i)\n view.setUint32(20, spec.ntp!.ref_ts_f)\n view.setUint32(24, spec.ntp!.ori_ts_i)\n view.setUint32(28, spec.ntp!.ori_ts_f)\n view.setUint32(32, spec.ntp!.rec_ts_i)\n view.setUint32(36, spec.ntp!.rec_ts_f)\n view.setUint32(40, spec.ntp!.trans_ts_i)\n view.setUint32(44, spec.ntp!.trans_ts_f)\n return 48\n}\n\nfunction parse_tcp(data: Uint8Array, o: PacketSpec): void {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n\n const tcp: TcpHeader = {\n sport: view.getUint16(0),\n dport: view.getUint16(2),\n seq: view.getUint32(4),\n ackn: view.getUint32(8),\n doff: view.getUint8(12) >> 4,\n winsize: view.getUint16(14),\n checksum: view.getUint16(16),\n urgent: view.getUint16(18),\n }\n\n const flags = view.getUint8(13)\n\n tcp.fin = !!(flags & 0x01)\n tcp.syn = !!(flags & 0x02)\n tcp.rst = !!(flags & 0x04)\n tcp.psh = !!(flags & 0x08)\n tcp.ack = !!(flags & 0x10)\n tcp.urg = !!(flags & 0x20)\n tcp.ece = !!(flags & 0x40)\n tcp.cwr = !!(flags & 0x80)\n\n o.tcp = tcp\n\n const offset = tcp.doff! * 4\n o.tcp_data = data.subarray(offset)\n}\n\nfunction write_tcp(spec: PacketSpec, out: EthEncoderBuf): number {\n const view = out.ipv4_payload_view\n let flags = 0\n const tcp = spec.tcp!\n\n if (tcp.fin) flags |= 0x01\n if (tcp.syn) flags |= 0x02\n if (tcp.rst) flags |= 0x04\n if (tcp.psh) flags |= 0x08\n if (tcp.ack) flags |= 0x10\n if (tcp.urg) flags |= 0x20\n if (tcp.ece) flags |= 0x40\n if (tcp.cwr) flags |= 0x80\n\n let doff = TCP_HEADER_SIZE\n if (tcp.options) {\n if (tcp.options.mss) {\n view.setUint8(doff, 0x02) //mss option type\n view.setUint8(doff + 1, 0x04) //option length\n view.setUint16(doff + 2, tcp.options.mss)\n doff += 4\n }\n }\n\n let total_length = Math.ceil(doff / 4) * 4 // needs to a multiple of 4 bytes\n if (tcp.options && total_length - doff > 0) {\n view_set_zeros(doff, total_length - doff, view, out) //write zeros into remaining space for options\n }\n\n view.setUint16(0, tcp.sport)\n view.setUint16(2, tcp.dport)\n view.setUint32(4, tcp.seq)\n view.setUint32(8, tcp.ackn)\n view.setUint8(12, (total_length >> 2) << 4) // header length in 32-bit words\n view.setUint8(13, flags)\n view.setUint16(14, tcp.winsize)\n view.setUint16(16, 0) // checksum initially zero before calculation\n view.setUint16(18, tcp.urgent || 0)\n\n if (spec.tcp_data) {\n total_length += view_set_array(\n TCP_HEADER_SIZE,\n spec.tcp_data,\n view,\n out,\n )\n }\n\n const pseudo_header =\n ((spec.ipv4!.src[0] << 8) | spec.ipv4!.src[1]) +\n ((spec.ipv4!.src[2] << 8) | spec.ipv4!.src[3]) +\n ((spec.ipv4!.dest[0] << 8) | spec.ipv4!.dest[1]) +\n ((spec.ipv4!.dest[2] << 8) | spec.ipv4!.dest[3]) +\n IPV4_PROTO_TCP +\n total_length\n view.setUint16(\n 16,\n calc_inet_checksum(total_length, pseudo_header, view, out),\n )\n return total_length\n}\n\nexport function fake_tcp_connect(\n dport: number,\n adapter: NetworkAdapterLike,\n): TCPConnection {\n const vm_ip_str = adapter.vm_ip.join('.')\n const router_ip_str = adapter.router_ip.join('.')\n const sport_0 = (Math.random() * TCP_DYNAMIC_PORT_RANGE) | 0\n let sport: number,\n tuple: string,\n sport_i = 0\n do {\n sport =\n TCP_DYNAMIC_PORT_START +\n ((sport_0 + sport_i) % TCP_DYNAMIC_PORT_RANGE)\n tuple = `${vm_ip_str}:${dport}:${router_ip_str}:${sport}`\n } while (++sport_i < TCP_DYNAMIC_PORT_RANGE && adapter.tcp_conn[tuple])\n if (adapter.tcp_conn[tuple]) {\n throw new Error(\n 'pool of dynamic TCP port numbers exhausted, connection aborted',\n )\n }\n\n const conn = new TCPConnection(adapter)\n\n conn.tuple = tuple\n conn.hsrc = adapter.router_mac\n conn.psrc = adapter.router_ip\n conn.sport = sport\n conn.hdest = adapter.vm_mac\n conn.dport = dport\n conn.pdest = adapter.vm_ip\n adapter.tcp_conn[tuple] = conn\n conn.connect()\n return conn\n}\n\nexport function fake_tcp_probe(\n dport: number,\n adapter: NetworkAdapterLike,\n): Promise<boolean> {\n return new Promise((res, _rej) => {\n const handle = fake_tcp_connect(dport, adapter)\n handle.state = TCP_STATE_SYN_PROBE\n handle.on('probe', res)\n })\n}\n\nexport class TCPConnection {\n mtu: number\n state: string\n net: NetworkAdapterLike\n send_buffer: GrowableRingbuffer\n send_chunk_buf: Uint8Array\n in_active_close: boolean\n delayed_send_fin: boolean\n delayed_state: string | undefined\n\n events_handlers: Record<string, (...args: any[]) => void>\n tuple: string = ''\n last: PacketSpec | undefined = undefined\n hsrc: Uint8Array = new Uint8Array(6)\n psrc: Uint8Array = new Uint8Array(4)\n sport: number = 0\n hdest: Uint8Array = new Uint8Array(6)\n dport: number = 0\n pdest: Uint8Array = new Uint8Array(4)\n seq: number = 0\n ack: number = 0\n start_seq: number = 0\n winsize: number = 0\n last_received_ackn: number | undefined = undefined\n pending: boolean = false\n name: string = ''\n\n read: any = undefined\n stream_id: number = 0\n on_close: () => void = () => {\n this.emit('close')\n }\n on_shutdown: () => void = () => {\n this.emit('shutdown')\n }\n\n constructor(adapter: NetworkAdapterLike) {\n this.mtu = adapter.mtu || MTU_DEFAULT\n const IPV4_PAYLOAD_SIZE = this.mtu - IPV4_HEADER_SIZE\n const TCP_PAYLOAD_SIZE = IPV4_PAYLOAD_SIZE - TCP_HEADER_SIZE\n\n this.state = TCP_STATE_CLOSED\n this.net = adapter\n this.send_buffer = new GrowableRingbuffer(2048, 0)\n this.send_chunk_buf = new Uint8Array(TCP_PAYLOAD_SIZE)\n this.in_active_close = false\n this.delayed_send_fin = false\n this.delayed_state = undefined\n this.events_handlers = {}\n }\n\n on(event: string, handler: (...args: any[]) => void): void {\n this.events_handlers[event] = handler\n }\n\n emit(event: string, ...args: any[]): void {\n if (!this.events_handlers[event]) return\n this.events_handlers[event].apply(this, args)\n }\n\n ipv4_reply(): PacketSpec {\n const reply: PacketSpec = {\n eth: {\n ethertype: ETHERTYPE_IPV4,\n src: this.hsrc,\n dest: this.hdest,\n },\n ipv4: {\n proto: IPV4_PROTO_TCP,\n src: this.psrc,\n dest: this.pdest,\n },\n tcp: {\n sport: this.sport,\n dport: this.dport,\n winsize: this.winsize,\n ackn: this.ack,\n seq: this.seq,\n ack: true,\n },\n }\n return reply\n }\n\n packet_reply(\n packet: PacketSpec,\n tcp_options: Partial<TcpHeader>,\n ): PacketSpec {\n const reply_tcp: TcpHeader = {\n sport: packet.tcp!.dport,\n dport: packet.tcp!.sport,\n winsize: packet.tcp!.winsize,\n ackn: this.ack,\n seq: this.seq,\n }\n for (const opt in tcp_options) {\n ;(reply_tcp as Record<string, any>)[opt] = (\n tcp_options as Record<string, any>\n )[opt]\n }\n const reply = this.ipv4_reply()\n reply.tcp = reply_tcp\n return reply\n }\n\n connect(): void {\n // dbg_log(`TCP[${this.tuple}]: connect(): sending SYN+ACK in state \"${this.state}\", next \"${TCP_STATE_SYN_SENT}\"`, LOG_FETCH);\n this.seq = 1338\n this.ack = 1\n this.start_seq = 0\n this.winsize = 64240\n if (this.state !== TCP_STATE_SYN_PROBE) {\n this.state = TCP_STATE_SYN_SENT\n }\n\n const reply = this.ipv4_reply()\n reply.ipv4!.id = 2345\n reply.tcp = {\n sport: this.sport,\n dport: this.dport,\n seq: 1337,\n ackn: 0,\n winsize: 0,\n syn: true,\n }\n this.net.receive(make_packet(this.net.eth_encoder_buf, reply))\n }\n\n accept(packet?: PacketSpec): void {\n packet = packet || this.last!\n this.net.tcp_conn[this.tuple] = this\n this.seq = 1338\n this.ack = packet.tcp!.seq + 1\n this.start_seq = packet.tcp!.seq\n this.winsize = packet.tcp!.winsize\n\n const reply = this.ipv4_reply()\n reply.tcp = {\n sport: this.sport,\n dport: this.dport,\n seq: 1337,\n ackn: this.ack,\n winsize: packet.tcp!.winsize,\n syn: true,\n ack: true,\n options: {\n mss: this.mtu - TCP_HEADER_SIZE - IPV4_HEADER_SIZE,\n },\n }\n // dbg_log(`TCP[${this.tuple}]: accept(): sending SYN+ACK in state \"${this.state}\", next \"${TCP_STATE_ESTABLISHED}\"`, LOG_FETCH);\n this.state = TCP_STATE_ESTABLISHED\n this.net.receive(make_packet(this.net.eth_encoder_buf, reply))\n }\n\n process(packet: PacketSpec): void {\n this.last = packet\n if (this.state === TCP_STATE_CLOSED) {\n // dbg_log(`TCP[${this.tuple}]: WARNING: connection already closed, packet dropped`, LOG_FETCH);\n const reply = this.packet_reply(packet, { rst: true })\n this.net.receive(make_packet(this.net.eth_encoder_buf, reply))\n return\n } else if (packet.tcp!.rst) {\n if (this.state === TCP_STATE_SYN_PROBE) {\n this.emit('probe', false)\n this.release()\n return\n }\n // dbg_log(`TCP[${this.tuple}]: received RST in state \"${this.state}\"`, LOG_FETCH);\n this.on_close()\n this.release()\n return\n } else if (packet.tcp!.syn) {\n if (this.state === TCP_STATE_SYN_SENT && packet.tcp!.ack) {\n this.ack = packet.tcp!.seq + 1\n this.start_seq = packet.tcp!.seq\n this.last_received_ackn = packet.tcp!.ackn\n\n const reply = this.ipv4_reply()\n this.net.receive(make_packet(this.net.eth_encoder_buf, reply))\n // dbg_log(`TCP[${this.tuple}]: received SYN+ACK in state \"${this.state}\", next \"${TCP_STATE_ESTABLISHED}\"`, LOG_FETCH);\n this.state = TCP_STATE_ESTABLISHED\n this.emit('connect')\n } else if (this.state === TCP_STATE_SYN_PROBE && packet.tcp!.ack) {\n this.emit('probe', true)\n const reply = this.packet_reply(packet, { rst: true })\n this.net.receive(make_packet(this.net.eth_encoder_buf, reply))\n this.release()\n } else {\n dbg_log(\n `TCP[${this.tuple}]: WARNING: unexpected SYN packet dropped`,\n LOG_FETCH,\n )\n }\n if (packet.tcp_data!.length) {\n dbg_log(\n `TCP[${this.tuple}]: WARNING: ${packet.tcp_data!.length} bytes of unexpected SYN packet payload dropped`,\n LOG_FETCH,\n )\n }\n return\n }\n\n if (packet.tcp!.ack) {\n if (this.state === TCP_STATE_SYN_RECEIVED) {\n // dbg_log(`TCP[${this.tuple}]: received ACK in state \"${this.state}\", next \"${TCP_STATE_ESTABLISHED}\"`, LOG_FETCH);\n this.state = TCP_STATE_ESTABLISHED\n } else if (this.state === TCP_STATE_FIN_WAIT_1) {\n if (!packet.tcp!.fin) {\n // handle FIN+ACK in FIN_WAIT_1 separately further down below\n // dbg_log(`TCP[${this.tuple}]: received ACK in state \"${this.state}\", next \"${TCP_STATE_FIN_WAIT_2}\"`, LOG_FETCH);\n this.state = TCP_STATE_FIN_WAIT_2\n }\n } else if (\n this.state === TCP_STATE_CLOSING ||\n this.state === TCP_STATE_LAST_ACK\n ) {\n // dbg_log(`TCP[${this.tuple}]: received ACK in state \"${this.state}\"`, LOG_FETCH);\n this.release()\n return\n }\n }\n\n if (this.last_received_ackn === undefined) {\n this.last_received_ackn = packet.tcp!.ackn\n } else {\n const n_ack = packet.tcp!.ackn - this.last_received_ackn\n //console.log(\"Read \", n_ack, \"(\", this.last_received_ackn, \") \", packet.tcp.ackn, packet.tcp.winsize)\n if (n_ack > 0) {\n this.last_received_ackn = packet.tcp!.ackn\n this.send_buffer.remove(n_ack)\n this.seq += n_ack\n this.pending = false\n\n if (this.delayed_send_fin && !this.send_buffer.length) {\n // dbg_log(`TCP[${this.tuple}]: sending delayed FIN from active close in state \"${this.state}\", next \"${this.delayed_state}\"`, LOG_FETCH);\n this.delayed_send_fin = false\n this.state = this.delayed_state!\n const reply = this.ipv4_reply()\n reply.tcp!.fin = true\n this.net.receive(\n make_packet(this.net.eth_encoder_buf, reply),\n )\n return\n }\n } else if (n_ack < 0) {\n // TODO: could this just be a 32-bit sequence number overflow?\n dbg_log(\n `TCP[${this.tuple}]: ERROR: ack underflow (pkt=${packet.tcp!.ackn} last=${this.last_received_ackn}), resetting`,\n LOG_FETCH,\n )\n const reply = this.packet_reply(packet, { rst: true })\n this.net.receive(make_packet(this.net.eth_encoder_buf, reply))\n this.on_close()\n this.release()\n return\n }\n }\n\n if (packet.tcp!.fin) {\n if (this.ack !== packet.tcp!.seq) {\n dbg_log(\n `TCP[${this.tuple}]: WARNING: closing connection in state \"${this.state}\" with invalid seq (${this.ack} != ${packet.tcp!.seq})`,\n LOG_FETCH,\n )\n }\n ++this.ack // FIN increases seqnr\n const reply = this.packet_reply(packet, {})\n if (this.state === TCP_STATE_ESTABLISHED) {\n // dbg_log(`TCP[${this.tuple}]: received FIN in state \"${this.state}, next \"${TCP_STATE_CLOSE_WAIT}\"\"`, LOG_FETCH);\n reply.tcp!.ack = true\n this.state = TCP_STATE_CLOSE_WAIT\n this.on_shutdown()\n } else if (this.state === TCP_STATE_FIN_WAIT_1) {\n if (packet.tcp!.ack) {\n // dbg_log(`TCP[${this.tuple}]: received ACK+FIN in state \"${this.state}\"`, LOG_FETCH);\n this.release()\n } else {\n // dbg_log(`TCP[${this.tuple}]: received ACK in state \"${this.state}\", next \"${TCP_STATE_CLOSING}\"`, LOG_FETCH);\n this.state = TCP_STATE_CLOSING\n }\n reply.tcp!.ack = true\n } else if (this.state === TCP_STATE_FIN_WAIT_2) {\n // dbg_log(`TCP[${this.tuple}]: received FIN in state \"${this.state}\"`, LOG_FETCH);\n this.release()\n reply.tcp!.ack = true\n } else {\n // dbg_log(`TCP[${this.tuple}]: ERROR: received FIN in unexpected TCP state \"${this.state}\", resetting`, LOG_FETCH);\n this.release()\n this.on_close()\n reply.tcp!.rst = true\n }\n this.net.receive(make_packet(this.net.eth_encoder_buf, reply))\n } else if (this.ack !== packet.tcp!.seq) {\n // Handle TCP Keep-Alives silently.\n // Excerpt from RFC 9293, 3.8.4. TCP Keep-Alives:\n // To confirm that an idle connection is still active, these\n // implementations send a probe segment designed to elicit a response\n // from the TCP peer. Such a segment generally contains SEG.SEQ =\n // SND.NXT-1 and may or may not contain one garbage octet of data.\n if (this.ack !== packet.tcp!.seq + 1) {\n dbg_log(\n `Packet seq was wrong ex: ${this.ack} ~${this.ack - this.start_seq} ` +\n `pk: ${packet.tcp!.seq} ~${this.start_seq - packet.tcp!.seq} ` +\n `(${this.ack - packet.tcp!.seq}) = ${this.name}`,\n LOG_FETCH,\n )\n }\n const reply = this.packet_reply(packet, { ack: true })\n this.net.receive(make_packet(this.net.eth_encoder_buf, reply))\n } else if (packet.tcp!.ack && packet.tcp_data!.length > 0) {\n this.ack += packet.tcp_data!.length\n const reply = this.ipv4_reply()\n this.net.receive(make_packet(this.net.eth_encoder_buf, reply))\n this.emit('data', packet.tcp_data)\n }\n\n this.pump()\n }\n\n write(data: Uint8Array): void {\n if (!this.in_active_close) {\n this.send_buffer.write(data)\n }\n this.pump()\n }\n\n writev(data_array: Uint8Array[]): void {\n if (!this.in_active_close) {\n for (const data of data_array) {\n this.send_buffer.write(data)\n }\n }\n this.pump()\n }\n\n close(): void {\n if (!this.in_active_close) {\n this.in_active_close = true\n let next_state: string\n if (\n this.state === TCP_STATE_ESTABLISHED ||\n this.state === TCP_STATE_SYN_RECEIVED\n ) {\n next_state = TCP_STATE_FIN_WAIT_1\n } else if (this.state === TCP_STATE_CLOSE_WAIT) {\n next_state = TCP_STATE_LAST_ACK\n } else {\n if (this.state !== TCP_STATE_SYN_SENT) {\n dbg_log(\n `TCP[${this.tuple}]: active close in unexpected state \"${this.state}\"`,\n LOG_FETCH,\n )\n }\n this.release()\n return\n }\n\n if (this.send_buffer.length || this.pending) {\n // dbg_log(`TCP[${this.tuple}]: active close, delaying FIN in state \"${this.state}\", delayed next \"${next_state}\"`, LOG_FETCH);\n this.delayed_send_fin = true\n this.delayed_state = next_state\n } else {\n // dbg_log(`TCP[${this.tuple}]: active close, sending FIN in state \"${this.state}\", next \"${next_state}\"`, LOG_FETCH);\n this.state = next_state\n const reply = this.ipv4_reply()\n reply.tcp!.fin = true\n this.net.receive(make_packet(this.net.eth_encoder_buf, reply))\n }\n }\n this.pump()\n }\n\n release(): void {\n if (this.net.tcp_conn[this.tuple]) {\n // dbg_log(`TCP[${this.tuple}]: connection closed in state \"${this.state}\"`, LOG_FETCH);\n this.state = TCP_STATE_CLOSED\n delete this.net.tcp_conn[this.tuple]\n }\n }\n\n pump(): void {\n if (this.send_buffer.length && !this.pending) {\n const data = this.send_chunk_buf\n const n_ready = this.send_buffer.peek(data)\n const reply = this.ipv4_reply()\n reply.tcp!.psh = true\n reply.tcp_data = data.subarray(0, n_ready)\n this.net.receive(make_packet(this.net.eth_encoder_buf, reply))\n this.pending = true\n }\n }\n}\n\nfunction arp_whohas(packet: PacketSpec, adapter: NetworkAdapterLike): void {\n const packet_subnet = iptolong(packet.arp!.tpa) & 0xffffff00\n const router_subnet = iptolong(adapter.router_ip) & 0xffffff00\n\n if (!adapter.masquerade) {\n if (packet_subnet !== router_subnet) {\n return\n }\n }\n\n if (packet_subnet === router_subnet) {\n // Ignore the DHCP client area\n if (packet.arp!.tpa[3] > 99) return\n }\n\n // Reply to ARP Whohas\n const reply: PacketSpec = {\n eth: {\n ethertype: ETHERTYPE_ARP,\n src: adapter.router_mac,\n dest: packet.eth.src,\n },\n arp: {\n htype: 1,\n ptype: ETHERTYPE_IPV4,\n oper: 2,\n sha: adapter.router_mac,\n spa: packet.arp!.tpa,\n tha: packet.eth.src,\n tpa: packet.arp!.spa,\n },\n }\n adapter.receive(make_packet(adapter.eth_encoder_buf, reply))\n}\n\nfunction handle_fake_ping(\n packet: PacketSpec,\n adapter: NetworkAdapterLike,\n): void {\n const reply: PacketSpec = {\n eth: {\n ethertype: ETHERTYPE_IPV4,\n src: adapter.router_mac,\n dest: packet.eth.src,\n },\n ipv4: {\n proto: IPV4_PROTO_ICMP,\n src: packet.ipv4!.dest,\n dest: packet.ipv4!.src,\n },\n icmp: {\n type: 0,\n code: packet.icmp!.code,\n data: packet.icmp!.data,\n },\n }\n adapter.receive(make_packet(adapter.eth_encoder_buf, reply))\n}\n\nfunction handle_udp_echo(\n packet: PacketSpec,\n adapter: NetworkAdapterLike,\n): void {\n // UDP Echo Server\n const reply: PacketSpec = {\n eth: {\n ethertype: ETHERTYPE_IPV4,\n src: adapter.router_mac,\n dest: packet.eth.src,\n },\n ipv4: {\n proto: IPV4_PROTO_UDP,\n src: packet.ipv4!.dest,\n dest: packet.ipv4!.src,\n },\n udp: {\n sport: packet.udp!.dport,\n dport: packet.udp!.sport,\n data: new TextEncoder().encode(packet.udp!.data_s),\n },\n }\n adapter.receive(make_packet(adapter.eth_encoder_buf, reply))\n}\n", "import { LOG_FETCH } from '../const.js'\nimport { dbg_log } from '../log.js'\n\nimport {\n create_eth_encoder_buf,\n handle_fake_networking,\n TCPConnection,\n fake_tcp_connect,\n fake_tcp_probe,\n} from './fake_network.js'\n\nimport type { EthEncoderBuf, NetworkAdapterLike } from './fake_network.js'\n\nimport { BusConnector } from '../bus.js'\n\ninterface FetchNetworkConfig {\n id?: number\n router_mac?: string\n router_ip?: string\n vm_ip?: string\n masquerade?: boolean\n dns_method?: string\n doh_server?: string\n mtu?: number\n cors_proxy?: string\n}\n\nexport class FetchNetworkAdapter implements NetworkAdapterLike {\n bus: BusConnector\n id: number\n router_mac: Uint8Array\n router_ip: Uint8Array\n vm_ip: Uint8Array\n masquerade: boolean\n vm_mac: Uint8Array\n dns_method: string\n doh_server: string | undefined\n tcp_conn: Record<string, TCPConnection>\n mtu: number | undefined\n eth_encoder_buf: EthEncoderBuf\n cors_proxy: string | undefined\n\n constructor(bus: BusConnector, config?: FetchNetworkConfig) {\n config = config || {}\n this.bus = bus\n this.id = config.id || 0\n this.router_mac = new Uint8Array(\n (config.router_mac || '52:54:0:1:2:3').split(':').map(function (x) {\n return parseInt(x, 16)\n }),\n )\n this.router_ip = new Uint8Array(\n (config.router_ip || '192.168.86.1').split('.').map(function (x) {\n return parseInt(x, 10)\n }),\n )\n this.vm_ip = new Uint8Array(\n (config.vm_ip || '192.168.86.100').split('.').map(function (x) {\n return parseInt(x, 10)\n }),\n )\n this.masquerade = config.masquerade === undefined || !!config.masquerade\n this.vm_mac = new Uint8Array(6)\n this.dns_method = config.dns_method || 'static'\n this.doh_server = config.doh_server\n this.tcp_conn = {}\n this.mtu = config.mtu\n this.eth_encoder_buf = create_eth_encoder_buf(this.mtu)\n\n // Ex: 'https://corsproxy.io/?'\n this.cors_proxy = config.cors_proxy\n\n this.bus.register(\n 'net' + this.id + '-mac',\n function (this: FetchNetworkAdapter, mac: string) {\n this.vm_mac = new Uint8Array(\n mac.split(':').map(function (x) {\n return parseInt(x, 16)\n }),\n )\n },\n this,\n )\n this.bus.register(\n 'net' + this.id + '-send',\n function (this: FetchNetworkAdapter, data: Uint8Array) {\n this.send(data)\n },\n this,\n )\n this.bus.register(\n 'tcp-connection',\n (conn: TCPConnection) => {\n if (conn.sport === 80) {\n conn.on('data', on_data_http.bind(conn))\n conn.accept()\n }\n },\n this,\n )\n }\n\n destroy(): void {}\n\n connect(port: number): TCPConnection {\n return fake_tcp_connect(port, this)\n }\n\n tcp_probe(port: number): Promise<boolean> {\n return fake_tcp_probe(port, this)\n }\n\n async fetch_resource(\n url: string,\n options?: RequestInit,\n ): Promise<\n [\n Response | { status: number; statusText: string; headers: Headers },\n ArrayBuffer,\n ]\n > {\n if (this.cors_proxy) url = this.cors_proxy + encodeURIComponent(url)\n\n try {\n const resp = await fetch(url, options)\n const ab = await resp.arrayBuffer()\n return [resp, ab]\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e))\n console.warn('Fetch Failed: ' + url + '\\n' + e)\n return [\n {\n status: 502,\n statusText: 'Fetch Error',\n headers: new Headers({ 'Content-Type': 'text/plain' }),\n },\n new TextEncoder().encode(`Fetch ${url} failed:\\n\\n${err.stack}`)\n .buffer,\n ]\n }\n }\n\n form_response_head(\n status_code: number,\n status_text: string,\n headers: Headers,\n ): Uint8Array {\n const lines = [`HTTP/1.1 ${status_code} ${status_text}`]\n\n for (const [key, value] of headers.entries()) {\n lines.push(`${key}: ${value}`)\n }\n\n return new TextEncoder().encode(lines.join('\\r\\n') + '\\r\\n\\r\\n')\n }\n\n respond_text_and_close(\n conn: TCPConnection,\n status_code: number,\n status_text: string,\n body: string,\n ): void {\n const headers = new Headers({\n 'content-type': 'text/plain',\n 'content-length': body.length.toString(10),\n connection: 'close',\n })\n conn.writev([\n this.form_response_head(status_code, status_text, headers),\n new TextEncoder().encode(body),\n ])\n conn.close()\n }\n\n parse_http_header(\n header: string,\n ): { key: string; value: string } | undefined {\n const parts = header.match(/^([^:]*):(.*)$/)\n if (!parts) {\n dbg_log('Unable to parse HTTP header', LOG_FETCH)\n return\n }\n\n const key = parts[1]\n const value = parts[2].trim()\n\n if (key.length === 0) {\n dbg_log('Header key is empty, raw header', LOG_FETCH)\n return\n }\n if (value.length === 0) {\n dbg_log('Header value is empty', LOG_FETCH)\n return\n }\n if (!/^[\\w-]+$/.test(key)) {\n dbg_log('Header key contains forbidden characters', LOG_FETCH)\n return\n }\n if (!/^[\\x20-\\x7E]+$/.test(value)) {\n dbg_log('Header value contains forbidden characters', LOG_FETCH)\n return\n }\n\n return { key, value }\n }\n\n send(data: Uint8Array): void {\n handle_fake_networking(data, this)\n }\n\n receive(data: Uint8Array): void {\n this.bus.send('net' + this.id + '-receive', new Uint8Array(data))\n }\n}\n\n/**\n * HTTP data handler bound to a TCPConnection context.\n */\nasync function on_data_http(\n this: TCPConnection,\n data: ArrayBuffer,\n): Promise<void> {\n this.read = this.read || ''\n this.read += new TextDecoder().decode(data)\n if (this.read && this.read.indexOf('\\r\\n\\r\\n') !== -1) {\n const offset = this.read.indexOf('\\r\\n\\r\\n')\n const headers = this.read.substring(0, offset).split(/\\r\\n/)\n const body = this.read.substring(offset + 4)\n this.read = ''\n\n const first_line = headers[0].split(' ')\n let target: URL\n if (/^https?:/.test(first_line[1])) {\n // HTTP proxy\n target = new URL(first_line[1])\n } else {\n target = new URL('http://host' + first_line[1])\n }\n if (\n typeof window !== 'undefined' &&\n target.protocol === 'http:' &&\n window.location.protocol === 'https:'\n ) {\n // fix \"Mixed Content\" errors\n target.protocol = 'https:'\n }\n\n const net = this.net as FetchNetworkAdapter\n\n const req_headers = new Headers()\n for (let i = 1; i < headers.length; ++i) {\n const header = net.parse_http_header(headers[i])\n if (!header) {\n console.warn(\n 'The request contains an invalid header: \"%s\"',\n headers[i],\n )\n net.respond_text_and_close(\n this,\n 400,\n 'Bad Request',\n `Invalid header in request: ${headers[i]}`,\n )\n return\n }\n if (header.key.toLowerCase() === 'host') target.host = header.value\n else req_headers.append(header.key, header.value)\n }\n\n if (!net.cors_proxy && /^\\d+\\.external$/.test(target.hostname)) {\n dbg_log('Request to localhost: ' + target.href, LOG_FETCH)\n const localport = parseInt(target.hostname.split('.')[0], 10)\n if (!isNaN(localport) && localport > 0 && localport < 65536) {\n target.protocol = 'http:'\n target.hostname = 'localhost'\n target.port = localport.toString(10)\n } else {\n console.warn('Unknown port for localhost: \"%s\"', target.href)\n net.respond_text_and_close(\n this,\n 400,\n 'Bad Request',\n `Unknown port for localhost: ${target.href}`,\n )\n return\n }\n }\n\n dbg_log('HTTP Dispatch: ' + target.href, LOG_FETCH)\n this.name = target.href\n const opts: RequestInit = {\n method: first_line[0],\n headers: req_headers,\n }\n if (['put', 'post'].indexOf(opts.method!.toLowerCase()) !== -1) {\n opts.body = body\n }\n\n const fetch_url = net.cors_proxy\n ? net.cors_proxy + encodeURIComponent(target.href)\n : target.href\n let response_started = false\n const handler = (resp: Response) => {\n const resp_headers = new Headers(resp.headers)\n resp_headers.delete('content-encoding')\n resp_headers.delete('keep-alive')\n resp_headers.delete('content-length')\n resp_headers.delete('transfer-encoding')\n resp_headers.set('x-was-fetch-redirected', `${!!resp.redirected}`)\n resp_headers.set('x-fetch-resp-url', resp.url)\n resp_headers.set('connection', 'close')\n\n this.write(\n net.form_response_head(\n resp.status,\n resp.statusText,\n resp_headers,\n ),\n )\n response_started = true\n\n if (resp.body && resp.body.getReader) {\n const resp_reader = resp.body.getReader()\n const pump = ({\n value,\n done,\n }: ReadableStreamReadResult<Uint8Array>): void | Promise<void> => {\n if (value) {\n this.write(value)\n }\n if (done) {\n this.close()\n } else {\n return resp_reader.read().then(pump)\n }\n }\n resp_reader.read().then(pump)\n } else {\n resp.arrayBuffer().then((buffer) => {\n this.write(new Uint8Array(buffer))\n this.close()\n })\n }\n }\n\n fetch(fetch_url, opts)\n .then(handler)\n .catch((e) => {\n console.warn('Fetch Failed: ' + fetch_url + '\\n' + e)\n if (!response_started) {\n net.respond_text_and_close(\n this,\n 502,\n 'Fetch Error',\n `Fetch ${fetch_url} failed:\\n\\n${e.stack || e.message}`,\n )\n }\n this.close()\n })\n }\n}\n", "import { LOG_NET } from '../const.js'\nimport { dbg_log } from '../log.js'\n\nimport {\n create_eth_encoder_buf,\n handle_fake_networking,\n TCPConnection,\n} from './fake_network.js'\n\nimport type {\n EthEncoderBuf,\n NetworkAdapterLike,\n PacketSpec,\n} from './fake_network.js'\n\nimport { BusConnector } from '../bus.js'\n\ninterface WispNetworkConfig {\n id?: number\n router_mac?: string\n router_ip?: string\n vm_ip?: string\n masquerade?: boolean\n dns_method?: string\n doh_server?: string\n mtu?: number\n}\n\ninterface WispConnection {\n data_callback: (data: Uint8Array) => void\n close_callback: (reason: number) => void\n congestion: number\n congested?: boolean\n}\n\ninterface WispFrameConnect {\n type: 'CONNECT'\n stream_id: number\n hostname: string\n port: number\n data_callback: (data: Uint8Array) => void\n close_callback: (reason: number) => void\n}\n\ninterface WispFrameData {\n type: 'DATA'\n stream_id: number\n data: Uint8Array\n}\n\ninterface WispFrameClose {\n type: 'CLOSE'\n stream_id: number\n reason: number\n}\n\ntype WispFrame = WispFrameConnect | WispFrameData | WispFrameClose\n\ninterface CongestedPacket {\n data: Uint8Array\n type: string\n}\n\nexport class WispNetworkAdapter implements NetworkAdapterLike {\n wispws: WebSocket | null\n last_stream: number\n connections: Record<number, WispConnection>\n congested_buffer: CongestedPacket[]\n bus: BusConnector\n id: number\n router_mac: Uint8Array\n router_ip: Uint8Array\n vm_ip: Uint8Array\n masquerade: boolean\n vm_mac: Uint8Array\n dns_method: string\n doh_server: string | undefined\n tcp_conn: Record<string, TCPConnection>\n mtu: number | undefined\n eth_encoder_buf: EthEncoderBuf\n\n constructor(\n wisp_url: string,\n bus: BusConnector,\n config?: WispNetworkConfig,\n ) {\n this.wispws = null\n this.register_ws(wisp_url)\n this.last_stream = 1\n this.connections = {\n 0: {\n congestion: 0,\n data_callback: () => {},\n close_callback: () => {},\n },\n }\n this.congested_buffer = []\n\n config = config || {}\n this.bus = bus\n this.id = config.id || 0\n this.router_mac = new Uint8Array(\n (config.router_mac || '52:54:0:1:2:3').split(':').map(function (x) {\n return parseInt(x, 16)\n }),\n )\n this.router_ip = new Uint8Array(\n (config.router_ip || '192.168.86.1').split('.').map(function (x) {\n return parseInt(x, 10)\n }),\n )\n this.vm_ip = new Uint8Array(\n (config.vm_ip || '192.168.86.100').split('.').map(function (x) {\n return parseInt(x, 10)\n }),\n )\n this.masquerade = config.masquerade === undefined || !!config.masquerade\n this.vm_mac = new Uint8Array(6)\n this.dns_method = config.dns_method || 'doh'\n this.doh_server = config.doh_server\n this.tcp_conn = {}\n this.mtu = config.mtu\n this.eth_encoder_buf = create_eth_encoder_buf(this.mtu)\n\n this.bus.register(\n 'net' + this.id + '-mac',\n function (this: WispNetworkAdapter, mac: string) {\n this.vm_mac = new Uint8Array(\n mac.split(':').map(function (x) {\n return parseInt(x, 16)\n }),\n )\n },\n this,\n )\n this.bus.register(\n 'net' + this.id + '-send',\n function (this: WispNetworkAdapter, data: Uint8Array) {\n this.send(data)\n },\n this,\n )\n }\n\n register_ws(wisp_url: string): void {\n this.wispws = new WebSocket(\n wisp_url.replace('wisp://', 'ws://').replace('wisps://', 'wss://'),\n )\n this.wispws.binaryType = 'arraybuffer'\n this.wispws.onmessage = (event: MessageEvent) => {\n this.process_incoming_wisp_frame(new Uint8Array(event.data))\n }\n this.wispws.onclose = () => {\n setTimeout(() => {\n this.register_ws(wisp_url)\n }, 10000) // wait 10s before reconnecting\n }\n }\n\n send_packet(data: Uint8Array, type: string, stream_id: number): void {\n if (this.connections[stream_id]) {\n if (this.connections[stream_id].congestion > 0) {\n if (type === 'DATA') {\n this.connections[stream_id].congestion--\n }\n this.wispws!.send(new Uint8Array(data))\n } else {\n this.connections[stream_id].congested = true\n this.congested_buffer.push({ data: data, type: type })\n }\n }\n }\n\n process_incoming_wisp_frame(frame: Uint8Array): void {\n const view = new DataView(frame.buffer)\n const stream_id = view.getUint32(1, true)\n switch (frame[0]) {\n case 1: // CONNECT\n // The server should never send this actually\n dbg_log('Server sent client-only packet CONNECT', LOG_NET)\n break\n case 2: // DATA\n if (this.connections[stream_id])\n this.connections[stream_id].data_callback(frame.slice(5))\n else\n throw new Error(\n 'Got a DATA packet but stream not registered. ID: ' +\n stream_id,\n )\n break\n case 3: // CONTINUE\n if (this.connections[stream_id]) {\n this.connections[stream_id].congestion = view.getUint32(\n 5,\n true,\n )\n }\n\n if (this.connections[stream_id].congested) {\n const buffer = this.congested_buffer.slice(0)\n this.congested_buffer.length = 0\n this.connections[stream_id].congested = false\n for (const packet of buffer) {\n this.send_packet(packet.data, packet.type, stream_id)\n }\n }\n break\n case 4: // CLOSE\n if (this.connections[stream_id])\n this.connections[stream_id].close_callback(view.getUint8(5))\n delete this.connections[stream_id]\n break\n case 5: // PROTOEXT\n dbg_log('got a wisp V2 upgrade request, ignoring', LOG_NET)\n // Not responding, this is wisp v1 client not wisp v2;\n break\n default:\n dbg_log(\n 'Wisp server returned unknown packet: ' + frame[0],\n LOG_NET,\n )\n }\n }\n\n send_wisp_frame(frame_obj: WispFrame): void {\n let full_packet: Uint8Array\n let view: DataView\n switch (frame_obj.type) {\n case 'CONNECT': {\n const hostname_buffer = new TextEncoder().encode(\n frame_obj.hostname,\n )\n full_packet = new Uint8Array(5 + 1 + 2 + hostname_buffer.length)\n view = new DataView(full_packet.buffer)\n view.setUint8(0, 0x01) // TYPE\n view.setUint32(1, frame_obj.stream_id, true) // Stream ID\n view.setUint8(5, 0x01) // TCP\n view.setUint16(6, frame_obj.port, true) // PORT\n full_packet.set(hostname_buffer, 8) // hostname\n\n // Setting callbacks\n this.connections[frame_obj.stream_id] = {\n data_callback: frame_obj.data_callback,\n close_callback: frame_obj.close_callback,\n congestion: this.connections[0].congestion,\n }\n break\n }\n case 'DATA':\n full_packet = new Uint8Array(5 + frame_obj.data.length)\n view = new DataView(full_packet.buffer)\n view.setUint8(0, 0x02) // TYPE\n view.setUint32(1, frame_obj.stream_id, true) // Stream ID\n full_packet.set(frame_obj.data, 5) // Actual data\n break\n case 'CLOSE':\n full_packet = new Uint8Array(5 + 1)\n view = new DataView(full_packet.buffer)\n view.setUint8(0, 0x04) // TYPE\n view.setUint32(1, frame_obj.stream_id, true) // Stream ID\n view.setUint8(5, frame_obj.reason) // Packet size\n break\n default:\n dbg_log(\n 'Client tried to send unknown packet: ' +\n (frame_obj as WispFrame).type,\n LOG_NET,\n )\n return\n }\n this.send_packet(full_packet, frame_obj.type, frame_obj.stream_id)\n }\n\n destroy(): void {\n if (this.wispws) {\n this.wispws.onmessage = null\n this.wispws.onclose = null\n this.wispws.close()\n this.wispws = null\n }\n }\n\n on_tcp_connection(conn: TCPConnection, packet: PacketSpec): boolean {\n conn.stream_id = this.last_stream++\n\n conn.on('data', (data: Uint8Array) => {\n if (data.length !== 0) {\n this.send_wisp_frame({\n type: 'DATA',\n stream_id: conn.stream_id,\n data: data,\n })\n }\n })\n\n conn.on_close = () => {\n this.send_wisp_frame({\n type: 'CLOSE',\n stream_id: conn.stream_id,\n reason: 0x02, // 0x02: Voluntary stream closure\n })\n }\n\n // WISP doesn't implement shutdown, use close as workaround\n conn.on_shutdown = conn.on_close\n\n this.send_wisp_frame({\n type: 'CONNECT',\n stream_id: conn.stream_id,\n hostname: packet.ipv4!.dest.join('.'),\n port: conn.sport,\n data_callback: (data: Uint8Array) => {\n conn.write(data)\n },\n close_callback: (_data: number) => {\n conn.close()\n },\n })\n\n conn.accept()\n return true\n }\n\n send(data: Uint8Array): void {\n // TODO: forward UDP traffic to WISP server once this WISP client supports UDP\n handle_fake_networking(data, this)\n }\n\n receive(data: Uint8Array): void {\n this.bus.send('net' + this.id + '-receive', new Uint8Array(data))\n }\n}\n", "import { BusConnector } from '../bus.js'\n\nconst SHIFT_SCAN_CODE = 0x2a\nconst SCAN_CODE_RELEASE = 0x80\n\nconst PLATFORM_WINDOWS =\n typeof window !== 'undefined' &&\n window.navigator.platform.toString().toLowerCase().search('win') >= 0\n\nexport class KeyboardAdapter {\n emu_enabled = true\n bus: BusConnector\n\n private keys_pressed: Record<number, boolean> = {}\n private deferred_event: KeyboardEvent | null = null\n private deferred_keydown = false\n private deferred_timeout_id: ReturnType<typeof setTimeout> | 0 = 0\n\n // Format:\n // Javascript event.keyCode -> make code\n private charmap = new Uint16Array([\n 0, 0, 0, 0, 0, 0, 0, 0,\n // 0x08: backspace, tab, enter\n 0x0e, 0x0f, 0, 0, 0, 0x1c, 0, 0,\n\n // 0x10: shift, ctrl, alt, pause, caps lock\n 0x2a, 0x1d, 0x38, 0, 0x3a, 0, 0, 0,\n\n // 0x18: escape\n 0, 0, 0, 0x01, 0, 0, 0, 0,\n\n // 0x20: spacebar, page down/up, end, home, arrow keys, ins, del\n 0x39, 0xe049, 0xe051, 0xe04f, 0xe047, 0xe04b, 0xe048, 0xe04d, 0x50, 0,\n 0, 0, 0, 0x52, 0x53, 0,\n\n // 0x30: numbers\n 0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,\n\n // 0x3B: ;= (firefox only)\n 0, 0x27, 0, 0x0d, 0, 0,\n\n // 0x40\n 0,\n\n // 0x41: letters\n 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26,\n 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11, 0x2d,\n 0x15, 0x2c,\n\n // 0x5B: Left Win, Right Win, Menu\n 0xe05b, 0xe05c, 0xe05d, 0, 0,\n\n // 0x60: keypad\n 0x52, 0x4f, 0x50, 0x51, 0x4b, 0x4c, 0x4d, 0x47, 0x48, 0x49, 0, 0, 0, 0,\n 0, 0,\n\n // 0x70: F1 to F12\n 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x57, 0x58,\n\n 0, 0, 0, 0,\n\n // 0x80\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\n // 0x90: Numlock\n 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\n // 0xA0: - (firefox only)\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0c, 0, 0,\n\n // 0xB0\n // ,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x27, 0x0d, 0x33, 0x0c, 0x34, 0x35,\n\n // 0xC0\n // `\n 0x29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\n // 0xD0\n // [']\\\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1a, 0x2b, 0x1b, 0x28, 0,\n\n // 0xE0\n // Apple key on Gecko, Right alt\n 0xe05b, 0xe038, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n ])\n\n // ascii -> javascript event code (US layout)\n private asciimap: Record<number, number> = {\n 8: 8,\n 10: 13,\n 32: 32,\n 39: 222,\n 44: 188,\n 45: 189,\n 46: 190,\n 47: 191,\n 48: 48,\n 49: 49,\n 50: 50,\n 51: 51,\n 52: 52,\n 53: 53,\n 54: 54,\n 55: 55,\n 56: 56,\n 57: 57,\n 59: 186,\n 61: 187,\n 91: 219,\n 92: 220,\n 93: 221,\n 96: 192,\n 97: 65,\n 98: 66,\n 99: 67,\n 100: 68,\n 101: 69,\n 102: 70,\n 103: 71,\n 104: 72,\n 105: 73,\n 106: 74,\n 107: 75,\n 108: 76,\n 109: 77,\n 110: 78,\n 111: 79,\n 112: 80,\n 113: 81,\n 114: 82,\n 115: 83,\n 116: 84,\n 117: 85,\n 118: 86,\n 119: 87,\n 120: 88,\n 121: 89,\n 122: 90,\n }\n private asciimap_shift: Record<number, number> = {\n 33: 49,\n 34: 222,\n 35: 51,\n 36: 52,\n 37: 53,\n 38: 55,\n 40: 57,\n 41: 48,\n 42: 56,\n 43: 187,\n 58: 186,\n 60: 188,\n 62: 190,\n 63: 191,\n 64: 50,\n 65: 65,\n 66: 66,\n 67: 67,\n 68: 68,\n 69: 69,\n 70: 70,\n 71: 71,\n 72: 72,\n 73: 73,\n 74: 74,\n 75: 75,\n 76: 76,\n 77: 77,\n 78: 78,\n 79: 79,\n 80: 80,\n 81: 81,\n 82: 82,\n 83: 83,\n 84: 84,\n 85: 85,\n 86: 86,\n 87: 87,\n 88: 88,\n 89: 89,\n 90: 90,\n 94: 54,\n 95: 189,\n 123: 219,\n 124: 220,\n 125: 221,\n 126: 192,\n }\n\n // Mapping from event.code to scancode\n private codemap: Record<string, number> = {\n Escape: 0x0001,\n Digit1: 0x0002,\n Digit2: 0x0003,\n Digit3: 0x0004,\n Digit4: 0x0005,\n Digit5: 0x0006,\n Digit6: 0x0007,\n Digit7: 0x0008,\n Digit8: 0x0009,\n Digit9: 0x000a,\n Digit0: 0x000b,\n Minus: 0x000c,\n Equal: 0x000d,\n Backspace: 0x000e,\n Tab: 0x000f,\n KeyQ: 0x0010,\n KeyW: 0x0011,\n KeyE: 0x0012,\n KeyR: 0x0013,\n KeyT: 0x0014,\n KeyY: 0x0015,\n KeyU: 0x0016,\n KeyI: 0x0017,\n KeyO: 0x0018,\n KeyP: 0x0019,\n BracketLeft: 0x001a,\n BracketRight: 0x001b,\n Enter: 0x001c,\n ControlLeft: 0x001d,\n KeyA: 0x001e,\n KeyS: 0x001f,\n KeyD: 0x0020,\n KeyF: 0x0021,\n KeyG: 0x0022,\n KeyH: 0x0023,\n KeyJ: 0x0024,\n KeyK: 0x0025,\n KeyL: 0x0026,\n Semicolon: 0x0027,\n Quote: 0x0028,\n Backquote: 0x0029,\n ShiftLeft: 0x002a,\n Backslash: 0x002b,\n KeyZ: 0x002c,\n KeyX: 0x002d,\n KeyC: 0x002e,\n KeyV: 0x002f,\n KeyB: 0x0030,\n KeyN: 0x0031,\n KeyM: 0x0032,\n Comma: 0x0033,\n Period: 0x0034,\n Slash: 0x0035,\n IntlRo: 0x0035,\n ShiftRight: 0x0036,\n NumpadMultiply: 0x0037,\n AltLeft: 0x0038,\n Space: 0x0039,\n CapsLock: 0x003a,\n F1: 0x003b,\n F2: 0x003c,\n F3: 0x003d,\n F4: 0x003e,\n F5: 0x003f,\n F6: 0x0040,\n F7: 0x0041,\n F8: 0x0042,\n F9: 0x0043,\n F10: 0x0044,\n NumLock: 0x0045,\n ScrollLock: 0x0046,\n Numpad7: 0x0047,\n Numpad8: 0x0048,\n Numpad9: 0x0049,\n NumpadSubtract: 0x004a,\n Numpad4: 0x004b,\n Numpad5: 0x004c,\n Numpad6: 0x004d,\n NumpadAdd: 0x004e,\n Numpad1: 0x004f,\n Numpad2: 0x0050,\n Numpad3: 0x0051,\n Numpad0: 0x0052,\n NumpadDecimal: 0x0053,\n IntlBackslash: 0x0056,\n F11: 0x0057,\n F12: 0x0058,\n\n NumpadEnter: 0xe01c,\n ControlRight: 0xe01d,\n NumpadDivide: 0xe035,\n AltRight: 0xe038,\n Home: 0xe047,\n ArrowUp: 0xe048,\n PageUp: 0xe049,\n ArrowLeft: 0xe04b,\n ArrowRight: 0xe04d,\n End: 0xe04f,\n ArrowDown: 0xe050,\n PageDown: 0xe051,\n Insert: 0xe052,\n Delete: 0xe053,\n\n MetaLeft: 0xe05b,\n OSLeft: 0xe05b,\n MetaRight: 0xe05c,\n OSRight: 0xe05c,\n ContextMenu: 0xe05d,\n }\n\n private keyup_handler: (e: KeyboardEvent) => void\n private keydown_handler: (e: KeyboardEvent) => void\n private blur_handler: (e: FocusEvent) => void\n private input_handler: (e: InputEvent) => void\n\n constructor(bus: BusConnector) {\n this.bus = bus\n\n this.keyup_handler = (e: KeyboardEvent) => {\n if (!e.altKey && this.keys_pressed[0x38]) {\n this.handle_code(0x38, false)\n }\n return this.handler(e, false)\n }\n\n this.keydown_handler = (e: KeyboardEvent) => {\n if (!e.altKey && this.keys_pressed[0x38]) {\n this.handle_code(0x38, false)\n }\n return this.handler(e, true)\n }\n\n this.blur_handler = (_e: FocusEvent) => {\n const keys = Object.keys(this.keys_pressed)\n\n for (let i = 0; i < keys.length; i++) {\n const key = +keys[i]\n\n if (this.keys_pressed[key]) {\n this.handle_code(key, false)\n }\n }\n\n this.keys_pressed = {}\n }\n\n this.input_handler = (e: InputEvent) => {\n if (!this.bus) {\n return\n }\n\n if (!this.may_handle(e)) {\n return\n }\n\n switch (e.inputType) {\n case 'insertText':\n if (e.data) {\n for (let i = 0; i < e.data.length; i++) {\n this.simulate_char(e.data[i])\n }\n }\n break\n\n case 'insertLineBreak':\n this.simulate_press(13) // enter\n break\n\n case 'deleteContentBackward':\n this.simulate_press(8) // backspace\n break\n }\n }\n\n this.init()\n }\n\n destroy(): void {\n if (typeof window !== 'undefined') {\n window.removeEventListener('keyup', this.keyup_handler, false)\n window.removeEventListener('keydown', this.keydown_handler, false)\n window.removeEventListener('blur', this.blur_handler, false)\n\n window.removeEventListener(\n 'input',\n this.input_handler as any,\n false,\n )\n }\n }\n\n init(): void {\n if (typeof window === 'undefined') {\n return\n }\n this.destroy()\n\n window.addEventListener('keyup', this.keyup_handler, false)\n window.addEventListener('keydown', this.keydown_handler, false)\n window.addEventListener('blur', this.blur_handler, false)\n\n window.addEventListener('input', this.input_handler as any, false)\n }\n\n simulate_press(code: number): void {\n const ev = { keyCode: code } as KeyboardEvent\n this.handler(ev, true)\n this.handler(ev, false)\n }\n\n simulate_char(chr: string): void {\n const code = chr.charCodeAt(0)\n\n if (code in this.asciimap) {\n this.simulate_press(this.asciimap[code])\n } else if (code in this.asciimap_shift) {\n this.send_to_controller(SHIFT_SCAN_CODE)\n this.simulate_press(this.asciimap_shift[code])\n this.send_to_controller(SHIFT_SCAN_CODE | SCAN_CODE_RELEASE)\n } else {\n console.log('ascii -> keyCode not found: ', code, chr)\n }\n }\n\n private may_handle(e: Event): boolean {\n const ke = e as KeyboardEvent\n if (\n ke.shiftKey &&\n ke.ctrlKey &&\n (ke.keyCode === 73 || ke.keyCode === 74 || ke.keyCode === 75)\n ) {\n return false\n }\n\n if (!this.emu_enabled) {\n return false\n }\n\n if (e.target) {\n const target = e.target as HTMLElement\n return (\n target.classList.contains('phone_keyboard') ||\n (target.nodeName !== 'INPUT' && target.nodeName !== 'TEXTAREA')\n )\n }\n\n return true\n }\n\n private translate(e: KeyboardEvent): number {\n if (e.code !== undefined) {\n const code = this.codemap[e.code]\n\n if (code !== undefined) {\n return code\n }\n }\n\n return this.charmap[e.keyCode]\n }\n\n private handler(e: KeyboardEvent, keydown: boolean): false | undefined {\n if (!this.bus) {\n return\n }\n\n if (!this.may_handle(e)) {\n return\n }\n\n if (\n e.code === '' ||\n e.key === 'Process' ||\n e.key === 'Unidentified' ||\n e.keyCode === 229\n ) {\n return\n }\n\n if (e.preventDefault) {\n e.preventDefault()\n }\n\n if (PLATFORM_WINDOWS) {\n if (this.deferred_event) {\n clearTimeout(this.deferred_timeout_id)\n if (\n !(\n e.getModifierState &&\n e.getModifierState('AltGraph') &&\n this.deferred_keydown === keydown &&\n this.deferred_event.code === 'ControlLeft' &&\n e.code === 'AltRight'\n )\n ) {\n this.handle_event(\n this.deferred_event,\n this.deferred_keydown,\n )\n }\n this.deferred_event = null\n }\n\n if (e.code === 'ControlLeft') {\n this.deferred_event = e\n this.deferred_keydown = keydown\n this.deferred_timeout_id = setTimeout(() => {\n if (this.deferred_event) {\n this.handle_event(\n this.deferred_event,\n this.deferred_keydown,\n )\n this.deferred_event = null\n }\n }, 10)\n return false\n }\n }\n\n this.handle_event(e, keydown)\n return false\n }\n\n private handle_event(e: KeyboardEvent, keydown: boolean): void {\n const code = this.translate(e)\n\n if (!code) {\n console.log(\n 'Missing char in map: keyCode=' +\n (e.keyCode || -1).toString(16) +\n ' code=' +\n e.code,\n )\n return\n }\n\n this.handle_code(code, keydown, e.repeat)\n }\n\n private handle_code(\n code: number,\n keydown: boolean,\n is_repeat?: boolean,\n ): void {\n if (keydown) {\n if (this.keys_pressed[code] && !is_repeat) {\n this.handle_code(code, false)\n }\n } else {\n if (!this.keys_pressed[code]) {\n return\n }\n }\n\n this.keys_pressed[code] = keydown\n\n if (!keydown) {\n code |= 0x80\n }\n\n if (code > 0xff) {\n this.send_to_controller(code >> 8)\n this.send_to_controller(code & 0xff)\n } else {\n this.send_to_controller(code)\n }\n }\n\n private send_to_controller(code: number): void {\n this.bus.send('keyboard-code', code)\n }\n}\n", "import { dbg_log } from '../log.js'\nimport { BusConnector } from '../bus.js'\n\nexport class MouseAdapter {\n enabled = false\n emu_enabled = true\n bus: BusConnector\n is_running = false\n\n private left_down = false\n private right_down = false\n private middle_down = false\n private last_x = 0\n private last_y = 0\n private screen_container: HTMLElement | undefined\n\n private SPEED_FACTOR = 1\n\n private touch_start_handler: (e: TouchEvent) => void\n private touch_end_handler: (e: TouchEvent) => void\n private mousemove_handler: (e: MouseEvent | TouchEvent) => void\n private mousedown_handler: (e: MouseEvent) => void\n private mouseup_handler: (e: MouseEvent) => void\n private mousewheel_handler: (e: WheelEvent) => void\n\n constructor(bus: BusConnector, screen_container?: HTMLElement) {\n this.bus = bus\n this.screen_container = screen_container\n\n this.touch_start_handler = (e: TouchEvent) => {\n if (this.may_handle(e)) {\n const touches = e.changedTouches\n\n if (touches && touches.length) {\n const touch = touches[touches.length - 1]\n this.last_x = touch.clientX\n this.last_y = touch.clientY\n }\n }\n }\n\n this.touch_end_handler = (_e: TouchEvent) => {\n if (this.left_down || this.middle_down || this.right_down) {\n this.bus.send('mouse-click', [false, false, false])\n this.left_down = this.middle_down = this.right_down = false\n }\n }\n\n this.mousemove_handler = (e: MouseEvent | TouchEvent) => {\n if (!this.bus) {\n return\n }\n\n if (!this.may_handle(e)) {\n return\n }\n\n if (!this.is_running) {\n return\n }\n\n let delta_x = 0\n let delta_y = 0\n\n if ('changedTouches' in e) {\n const touches = e.changedTouches\n if (touches.length) {\n const touch = touches[touches.length - 1]\n delta_x = touch.clientX - this.last_x\n delta_y = touch.clientY - this.last_y\n\n this.last_x = touch.clientX\n this.last_y = touch.clientY\n\n e.preventDefault()\n }\n } else {\n if (typeof e.movementX === 'number') {\n delta_x = e.movementX\n delta_y = e.movementY\n } else {\n delta_x = e.clientX - this.last_x\n delta_y = e.clientY - this.last_y\n\n this.last_x = e.clientX\n this.last_y = e.clientY\n }\n }\n\n delta_x *= this.SPEED_FACTOR\n delta_y *= this.SPEED_FACTOR\n\n delta_y = -delta_y\n\n this.bus.send('mouse-delta', [delta_x, delta_y])\n\n if (this.screen_container) {\n const me = e instanceof MouseEvent ? e : e.changedTouches[0]\n const absolute_x = me.pageX - this.screen_container.offsetLeft\n const absolute_y = me.pageY - this.screen_container.offsetTop\n this.bus.send('mouse-absolute', [\n absolute_x,\n absolute_y,\n this.screen_container.offsetWidth,\n this.screen_container.offsetHeight,\n ])\n }\n }\n\n this.mousedown_handler = (e: MouseEvent) => {\n if (this.may_handle(e)) {\n this.click_event(e, true)\n }\n }\n\n this.mouseup_handler = (e: MouseEvent) => {\n if (this.may_handle(e)) {\n this.click_event(e, false)\n }\n }\n\n this.mousewheel_handler = (e: WheelEvent) => {\n if (!this.may_handle(e)) {\n return\n }\n\n let delta_x = -e.deltaY\n const delta_y = 0\n\n if (delta_x < 0) {\n delta_x = -1\n } else if (delta_x > 0) {\n delta_x = 1\n }\n\n this.bus.send('mouse-wheel', [delta_x, delta_y])\n e.preventDefault()\n }\n\n this.bus.register(\n 'mouse-enable',\n function (this: MouseAdapter, enabled: boolean) {\n this.enabled = enabled\n },\n this,\n )\n\n this.bus.register(\n 'emulator-stopped',\n function (this: MouseAdapter) {\n this.is_running = false\n },\n this,\n )\n this.bus.register(\n 'emulator-started',\n function (this: MouseAdapter) {\n this.is_running = true\n },\n this,\n )\n\n this.init()\n }\n\n destroy(): void {\n if (typeof window === 'undefined') {\n return\n }\n window.removeEventListener(\n 'touchstart',\n this.touch_start_handler,\n false,\n )\n window.removeEventListener('touchend', this.touch_end_handler, false)\n window.removeEventListener('touchmove', this.mousemove_handler, false)\n window.removeEventListener('mousemove', this.mousemove_handler, false)\n window.removeEventListener('mousedown', this.mousedown_handler, false)\n window.removeEventListener('mouseup', this.mouseup_handler, false)\n window.removeEventListener('wheel', this.mousewheel_handler)\n }\n\n init(): void {\n if (typeof window === 'undefined') {\n return\n }\n this.destroy()\n\n window.addEventListener('touchstart', this.touch_start_handler, false)\n window.addEventListener('touchend', this.touch_end_handler, false)\n window.addEventListener('touchmove', this.mousemove_handler, false)\n window.addEventListener('mousemove', this.mousemove_handler, false)\n window.addEventListener('mousedown', this.mousedown_handler, false)\n window.addEventListener('mouseup', this.mouseup_handler, false)\n window.addEventListener('wheel', this.mousewheel_handler, {\n passive: false,\n })\n }\n\n private is_child(child: Node, parent: Node): boolean {\n let node: Node | null = child\n while (node && node.parentNode) {\n if (node === parent) {\n return true\n }\n node = node.parentNode\n }\n\n return false\n }\n\n private may_handle(e: Event): boolean {\n if (!this.enabled || !this.emu_enabled) {\n return false\n }\n\n const MOVE_MOUSE_WHEN_OVER_SCREEN_ONLY = true\n\n if (MOVE_MOUSE_WHEN_OVER_SCREEN_ONLY) {\n const parent = this.screen_container || document.body\n const target = e.target\n if (!target) {\n return false\n }\n return (\n !!document.pointerLockElement ||\n this.is_child(target as Node, parent)\n )\n }\n\n return true\n }\n\n private click_event(e: MouseEvent, down: boolean): void {\n if (!this.bus) {\n return\n }\n\n if (e.button === 0) {\n this.left_down = down\n } else if (e.button === 1) {\n this.middle_down = down\n } else if (e.button === 2) {\n this.right_down = down\n } else {\n dbg_log('Unknown event.button: ' + e.button)\n }\n this.bus.send('mouse-click', [\n this.left_down,\n this.middle_down,\n this.right_down,\n ])\n e.preventDefault()\n }\n}\n", "declare let DEBUG: boolean\n\nimport { dbg_assert } from '../log.js'\nimport { get_charmap } from '../lib.js'\n\n// Draws entire buffer and visualizes the layers that would be drawn\nexport const DEBUG_SCREEN_LAYERS = DEBUG && false\n\ninterface ScreenOptions {\n container: HTMLElement\n scale?: number\n use_graphical_text?: boolean\n encoding?: string\n}\n\ninterface ScreenLayer {\n image_data: ImageData\n screen_x: number\n screen_y: number\n buffer_x: number\n buffer_y: number\n buffer_width: number\n buffer_height: number\n}\n\nconst MODE_TEXT = 0\nconst MODE_GRAPHICAL = 1\nconst MODE_GRAPHICAL_TEXT = 2\n\nconst CHARACTER_INDEX = 0\nconst FLAGS_INDEX = 1\nconst BG_COLOR_INDEX = 2\nconst FG_COLOR_INDEX = 3\nconst TEXT_BUF_COMPONENT_SIZE = 4\n\nconst FLAG_BLINKING = 0x01\nconst FLAG_FONT_PAGE_B = 0x02\n\nexport class ScreenAdapter {\n FLAG_BLINKING = FLAG_BLINKING\n FLAG_FONT_PAGE_B = FLAG_FONT_PAGE_B\n\n screen_fill_buffer: () => void\n\n private graphic_screen: HTMLCanvasElement\n private graphic_context: CanvasRenderingContext2D\n private text_screen: HTMLDivElement\n private cursor_element: HTMLDivElement\n\n private cursor_row = 0\n private cursor_col = 0\n private scale_x: number\n private scale_y: number\n private base_scale = 1\n private changed_rows: Int8Array | undefined\n private mode = MODE_TEXT\n private text_mode_data: Int32Array | undefined\n private text_mode_width = 0\n private text_mode_height = 0\n private offscreen_context: OffscreenCanvasRenderingContext2D | null = null\n private offscreen_extra_context: OffscreenCanvasRenderingContext2D | null =\n null\n private font_context: OffscreenCanvasRenderingContext2D | null = null\n private font_image_data: ImageData | null = null\n private font_is_visible = new Int8Array(8 * 256)\n private font_height = 0\n private font_width = 0\n private font_width_9px = false\n private font_width_dbl = false\n private font_copy_8th_col = false\n private font_page_a = 0\n private font_page_b = 0\n private blink_visible = false\n private tm_last_update = 0\n private cursor_start = 0\n private cursor_end = 0\n private cursor_enabled = false\n private charmap: string\n private timer_id = 0\n private paused = false\n private options: ScreenOptions\n\n constructor(options: ScreenOptions, screen_fill_buffer: () => void) {\n const screen_container = options.container\n this.screen_fill_buffer = screen_fill_buffer\n this.options = options\n\n console.assert(!!screen_container, 'options.container must be provided')\n\n this.scale_x = options.scale !== undefined ? options.scale : 1\n this.scale_y = options.scale !== undefined ? options.scale : 1\n this.charmap = get_charmap(options.encoding || '')\n\n let graphic_screen = screen_container.getElementsByTagName('canvas')[0]\n if (!graphic_screen) {\n graphic_screen = document.createElement('canvas')\n screen_container.appendChild(graphic_screen)\n }\n this.graphic_screen = graphic_screen\n this.graphic_context = graphic_screen.getContext('2d', {\n alpha: false,\n })!\n\n let text_screen = screen_container.getElementsByTagName('div')[0] as\n | HTMLDivElement\n | undefined\n if (!text_screen) {\n text_screen = document.createElement('div')\n screen_container.appendChild(text_screen)\n }\n this.text_screen = text_screen\n\n this.cursor_element = document.createElement('div')\n\n this.init()\n }\n\n private number_as_color(n: number): string {\n const s = n.toString(16)\n return '#' + '0'.repeat(6 - s.length) + s\n }\n\n private render_font_bitmap(vga_bitmap: Uint8Array): void {\n const bitmap_width = this.font_width * 256\n const bitmap_height = this.font_height * 8\n\n let font_canvas = this.font_context ? this.font_context.canvas : null\n if (\n !font_canvas ||\n font_canvas.width !== bitmap_width ||\n font_canvas.height !== bitmap_height\n ) {\n if (!font_canvas) {\n font_canvas = new OffscreenCanvas(bitmap_width, bitmap_height)\n this.font_context = font_canvas.getContext('2d')!\n } else {\n font_canvas.width = bitmap_width\n font_canvas.height = bitmap_height\n }\n this.font_image_data = this.font_context!.createImageData(\n bitmap_width,\n bitmap_height,\n )\n }\n\n const font_bitmap = this.font_image_data!.data\n let i_dst = 0\n let is_visible = false\n const font_width_dbl = this.font_width_dbl\n const font_width = this.font_width\n const font_height = this.font_height\n const font_width_9px = this.font_width_9px\n const font_copy_8th_col = this.font_copy_8th_col\n\n const put_bit = font_width_dbl\n ? (value: number) => {\n is_visible = is_visible || !!value\n font_bitmap[i_dst + 3] = value\n font_bitmap[i_dst + 7] = value\n i_dst += 8\n }\n : (value: number) => {\n is_visible = is_visible || !!value\n font_bitmap[i_dst + 3] = value\n i_dst += 4\n }\n\n const vga_inc_chr = 32 - font_height\n const dst_inc_row = bitmap_width * (font_height - 1) * 4\n const dst_inc_col = (font_width - bitmap_width * font_height) * 4\n const dst_inc_line = font_width * 255 * 4\n\n for (\n let i_chr_all = 0, i_vga = 0;\n i_chr_all < 2048;\n ++i_chr_all, i_vga += vga_inc_chr, i_dst += dst_inc_col\n ) {\n const i_chr = i_chr_all % 256\n if (i_chr_all && !i_chr) {\n i_dst += dst_inc_row\n }\n is_visible = false\n for (\n let i_line = 0;\n i_line < font_height;\n ++i_line, ++i_vga, i_dst += dst_inc_line\n ) {\n const line_bits = vga_bitmap[i_vga]\n for (let i_bit = 0x80; i_bit > 0; i_bit >>= 1) {\n put_bit(line_bits & i_bit ? 255 : 0)\n }\n if (font_width_9px) {\n put_bit(\n font_copy_8th_col &&\n i_chr >= 0xc0 &&\n i_chr <= 0xdf &&\n line_bits & 1\n ? 255\n : 0,\n )\n }\n }\n this.font_is_visible[i_chr_all] = is_visible ? 1 : 0\n }\n\n this.font_context!.putImageData(this.font_image_data!, 0, 0)\n }\n\n private render_changed_rows(): number {\n const font_context = this.font_context!\n const offscreen_context = this.offscreen_context!\n const offscreen_extra_context = this.offscreen_extra_context!\n const font_canvas = font_context.canvas\n const offscreen_extra_canvas = offscreen_extra_context.canvas\n const text_mode_width = this.text_mode_width\n const font_width = this.font_width\n const font_height = this.font_height\n const text_mode_data = this.text_mode_data!\n const changed_rows = this.changed_rows!\n const txt_row_size = text_mode_width * TEXT_BUF_COMPONENT_SIZE\n const gfx_width = text_mode_width * font_width\n const row_extra_1_y = 0\n const row_extra_2_y = font_height\n\n let n_rows_rendered = 0\n for (\n let row_i = 0, row_y = 0, txt_i = 0;\n row_i < this.text_mode_height;\n ++row_i, row_y += font_height\n ) {\n if (!changed_rows[row_i]) {\n txt_i += txt_row_size\n continue\n }\n ++n_rows_rendered\n\n offscreen_extra_context.clearRect(\n 0,\n row_extra_2_y,\n gfx_width,\n font_height,\n )\n\n let fg_rgba: number | undefined\n let fg_x = 0\n let bg_rgba: number | undefined\n let bg_x = 0\n for (\n let col_x = 0;\n col_x < gfx_width;\n col_x += font_width, txt_i += TEXT_BUF_COMPONENT_SIZE\n ) {\n const chr = text_mode_data[txt_i + CHARACTER_INDEX]\n const chr_flags = text_mode_data[txt_i + FLAGS_INDEX]\n const chr_bg_rgba = text_mode_data[txt_i + BG_COLOR_INDEX]\n const chr_fg_rgba = text_mode_data[txt_i + FG_COLOR_INDEX]\n const chr_font_page =\n chr_flags & FLAG_FONT_PAGE_B\n ? this.font_page_b\n : this.font_page_a\n const chr_visible =\n (!(chr_flags & FLAG_BLINKING) || this.blink_visible) &&\n !!this.font_is_visible[(chr_font_page << 8) + chr]\n\n if (bg_rgba !== chr_bg_rgba) {\n if (bg_rgba !== undefined) {\n offscreen_context.fillStyle =\n this.number_as_color(bg_rgba)\n offscreen_context.fillRect(\n bg_x,\n row_y,\n col_x - bg_x,\n font_height,\n )\n }\n bg_rgba = chr_bg_rgba\n bg_x = col_x\n }\n\n if (fg_rgba !== chr_fg_rgba) {\n if (fg_rgba !== undefined) {\n offscreen_extra_context.fillStyle =\n this.number_as_color(fg_rgba)\n offscreen_extra_context.fillRect(\n fg_x,\n row_extra_1_y,\n col_x - fg_x,\n font_height,\n )\n }\n fg_rgba = chr_fg_rgba\n fg_x = col_x\n }\n\n if (chr_visible) {\n offscreen_extra_context.drawImage(\n font_canvas,\n chr * font_width,\n chr_font_page * font_height,\n font_width,\n font_height,\n col_x,\n row_extra_2_y,\n font_width,\n font_height,\n )\n }\n }\n\n offscreen_extra_context.fillStyle = this.number_as_color(fg_rgba!)\n offscreen_extra_context.fillRect(\n fg_x,\n row_extra_1_y,\n gfx_width - fg_x,\n font_height,\n )\n\n offscreen_extra_context.globalCompositeOperation = 'destination-in'\n offscreen_extra_context.drawImage(\n offscreen_extra_canvas,\n 0,\n row_extra_2_y,\n gfx_width,\n font_height,\n 0,\n row_extra_1_y,\n gfx_width,\n font_height,\n )\n offscreen_extra_context.globalCompositeOperation = 'source-over'\n\n offscreen_context.fillStyle = this.number_as_color(bg_rgba!)\n offscreen_context.fillRect(\n bg_x,\n row_y,\n gfx_width - bg_x,\n font_height,\n )\n\n offscreen_context.drawImage(\n offscreen_extra_canvas,\n 0,\n row_extra_1_y,\n gfx_width,\n font_height,\n 0,\n row_y,\n gfx_width,\n font_height,\n )\n }\n\n if (n_rows_rendered) {\n if (\n this.blink_visible &&\n this.cursor_enabled &&\n changed_rows[this.cursor_row]\n ) {\n const cursor_txt_i =\n (this.cursor_row * text_mode_width + this.cursor_col) *\n TEXT_BUF_COMPONENT_SIZE\n const cursor_rgba =\n text_mode_data[cursor_txt_i + FG_COLOR_INDEX]\n offscreen_context.fillStyle = this.number_as_color(cursor_rgba)\n offscreen_context.fillRect(\n this.cursor_col * font_width,\n this.cursor_row * font_height + this.cursor_start,\n font_width,\n this.cursor_end - this.cursor_start + 1,\n )\n }\n changed_rows.fill(0)\n }\n\n return n_rows_rendered\n }\n\n private mark_blinking_rows_dirty(): void {\n const txt_row_size = this.text_mode_width * TEXT_BUF_COMPONENT_SIZE\n const text_mode_data = this.text_mode_data!\n const changed_rows = this.changed_rows!\n for (let row_i = 0, txt_i = 0; row_i < this.text_mode_height; ++row_i) {\n if (changed_rows[row_i]) {\n txt_i += txt_row_size\n continue\n }\n for (\n let col_i = 0;\n col_i < this.text_mode_width;\n ++col_i, txt_i += TEXT_BUF_COMPONENT_SIZE\n ) {\n if (text_mode_data[txt_i + FLAGS_INDEX] & FLAG_BLINKING) {\n changed_rows[row_i] = 1\n txt_i += txt_row_size - col_i * TEXT_BUF_COMPONENT_SIZE\n break\n }\n }\n }\n }\n\n init(): void {\n this.cursor_element.classList.add('cursor')\n this.cursor_element.style.position = 'absolute'\n this.cursor_element.style.backgroundColor = '#ccc'\n this.cursor_element.style.width = '7px'\n this.cursor_element.style.display = 'inline-block'\n\n this.set_mode(false)\n this.set_size_text(80, 25)\n if (this.mode === MODE_GRAPHICAL_TEXT) {\n this.set_size_graphical(720, 400, 720, 400)\n }\n\n this.set_scale(this.scale_x, this.scale_y)\n\n this.timer()\n }\n\n make_screenshot(): HTMLImageElement {\n const image = new Image()\n\n if (this.mode === MODE_GRAPHICAL || this.mode === MODE_GRAPHICAL_TEXT) {\n image.src = this.graphic_screen.toDataURL('image/png')\n } else {\n const char_size = [9, 16]\n\n const canvas = document.createElement('canvas')\n canvas.width = this.text_mode_width * char_size[0]\n canvas.height = this.text_mode_height * char_size[1]\n const context = canvas.getContext('2d')!\n context.imageSmoothingEnabled = false\n context.font = window.getComputedStyle(this.text_screen).font\n context.textBaseline = 'top'\n\n for (let y = 0; y < this.text_mode_height; y++) {\n for (let x = 0; x < this.text_mode_width; x++) {\n const index =\n (y * this.text_mode_width + x) * TEXT_BUF_COMPONENT_SIZE\n const character =\n this.text_mode_data![index + CHARACTER_INDEX]\n const bg_color =\n this.text_mode_data![index + BG_COLOR_INDEX]\n const fg_color =\n this.text_mode_data![index + FG_COLOR_INDEX]\n\n context.fillStyle = this.number_as_color(bg_color)\n context.fillRect(\n x * char_size[0],\n y * char_size[1],\n char_size[0],\n char_size[1],\n )\n context.fillStyle = this.number_as_color(fg_color)\n context.fillText(\n this.charmap[character],\n x * char_size[0],\n y * char_size[1],\n )\n }\n }\n\n if (\n this.cursor_element.style.display !== 'none' &&\n this.cursor_row < this.text_mode_height &&\n this.cursor_col < this.text_mode_width\n ) {\n context.fillStyle = this.cursor_element.style.backgroundColor\n context.fillRect(\n this.cursor_col * char_size[0],\n this.cursor_row * char_size[1] +\n parseInt(this.cursor_element.style.marginTop, 10),\n parseInt(this.cursor_element.style.width, 10),\n parseInt(this.cursor_element.style.height, 10),\n )\n }\n\n image.src = canvas.toDataURL('image/png')\n }\n return image\n }\n\n put_char(\n row: number,\n col: number,\n chr: number,\n flags: number,\n bg_color: number,\n fg_color: number,\n ): void {\n dbg_assert(row >= 0 && row < this.text_mode_height)\n dbg_assert(col >= 0 && col < this.text_mode_width)\n dbg_assert(chr >= 0 && chr < 0x100)\n\n const p = TEXT_BUF_COMPONENT_SIZE * (row * this.text_mode_width + col)\n\n this.text_mode_data![p + CHARACTER_INDEX] = chr\n this.text_mode_data![p + FLAGS_INDEX] = flags\n this.text_mode_data![p + BG_COLOR_INDEX] = bg_color\n this.text_mode_data![p + FG_COLOR_INDEX] = fg_color\n\n this.changed_rows![row] = 1\n }\n\n timer(): void {\n this.timer_id = requestAnimationFrame(() => this.update_screen())\n }\n\n update_screen(): void {\n if (!this.paused) {\n if (this.mode === MODE_TEXT) {\n this.update_text()\n } else if (this.mode === MODE_GRAPHICAL) {\n this.update_graphical()\n } else {\n this.update_graphical_text()\n }\n }\n this.timer()\n }\n\n update_text(): void {\n for (let i = 0; i < this.text_mode_height; i++) {\n if (this.changed_rows![i]) {\n this.text_update_row(i)\n this.changed_rows![i] = 0\n }\n }\n }\n\n update_graphical(): void {\n this.screen_fill_buffer()\n }\n\n update_graphical_text(): void {\n if (this.offscreen_context) {\n const tm_now = performance.now()\n if (tm_now - this.tm_last_update > 266) {\n this.blink_visible = !this.blink_visible\n if (this.cursor_enabled) {\n this.changed_rows![this.cursor_row] = 1\n }\n this.mark_blinking_rows_dirty()\n this.tm_last_update = tm_now\n }\n if (this.render_changed_rows()) {\n this.graphic_context.drawImage(\n this.offscreen_context.canvas,\n 0,\n 0,\n )\n }\n }\n }\n\n destroy(): void {\n if (this.timer_id) {\n cancelAnimationFrame(this.timer_id)\n this.timer_id = 0\n }\n }\n\n pause(): void {\n this.paused = true\n this.cursor_element.classList.remove('blinking-cursor')\n }\n\n continue(): void {\n this.paused = false\n this.cursor_element.classList.add('blinking-cursor')\n }\n\n set_mode(graphical: boolean): void {\n this.mode = graphical\n ? MODE_GRAPHICAL\n : this.options.use_graphical_text\n ? MODE_GRAPHICAL_TEXT\n : MODE_TEXT\n\n if (this.mode === MODE_TEXT) {\n this.text_screen.style.display = 'block'\n this.graphic_screen.style.display = 'none'\n } else {\n this.text_screen.style.display = 'none'\n this.graphic_screen.style.display = 'block'\n\n if (this.mode === MODE_GRAPHICAL_TEXT && this.changed_rows) {\n this.changed_rows.fill(1)\n }\n }\n }\n\n set_font_bitmap(\n height: number,\n width_9px: boolean,\n width_dbl: boolean,\n copy_8th_col: boolean,\n vga_bitmap: Uint8Array,\n vga_bitmap_changed: boolean,\n ): void {\n const width = width_dbl ? 16 : width_9px ? 9 : 8\n if (\n this.font_height !== height ||\n this.font_width !== width ||\n this.font_width_9px !== width_9px ||\n this.font_width_dbl !== width_dbl ||\n this.font_copy_8th_col !== copy_8th_col ||\n vga_bitmap_changed\n ) {\n const size_changed =\n this.font_width !== width || this.font_height !== height\n this.font_height = height\n this.font_width = width\n this.font_width_9px = width_9px\n this.font_width_dbl = width_dbl\n this.font_copy_8th_col = copy_8th_col\n if (this.mode === MODE_GRAPHICAL_TEXT) {\n this.render_font_bitmap(vga_bitmap)\n this.changed_rows!.fill(1)\n if (size_changed) {\n this.set_size_graphical_text()\n }\n }\n }\n }\n\n set_font_page(page_a: number, page_b: number): void {\n if (this.font_page_a !== page_a || this.font_page_b !== page_b) {\n this.font_page_a = page_a\n this.font_page_b = page_b\n this.changed_rows!.fill(1)\n }\n }\n\n clear_screen(): void {\n this.graphic_context.fillStyle = '#000'\n this.graphic_context.fillRect(\n 0,\n 0,\n this.graphic_screen.width,\n this.graphic_screen.height,\n )\n }\n\n set_size_graphical_text(): void {\n if (!this.font_context) {\n return\n }\n\n const gfx_width = this.font_width * this.text_mode_width\n const gfx_height = this.font_height * this.text_mode_height\n const offscreen_extra_height = this.font_height * 2\n\n if (\n !this.offscreen_context ||\n this.offscreen_context.canvas.width !== gfx_width ||\n this.offscreen_context.canvas.height !== gfx_height ||\n this.offscreen_extra_context!.canvas.height !==\n offscreen_extra_height\n ) {\n if (!this.offscreen_context) {\n const offscreen_canvas = new OffscreenCanvas(\n gfx_width,\n gfx_height,\n )\n this.offscreen_context = offscreen_canvas.getContext('2d', {\n alpha: false,\n })!\n const offscreen_extra_canvas = new OffscreenCanvas(\n gfx_width,\n offscreen_extra_height,\n )\n this.offscreen_extra_context =\n offscreen_extra_canvas.getContext('2d')!\n } else {\n this.offscreen_context.canvas.width = gfx_width\n this.offscreen_context.canvas.height = gfx_height\n this.offscreen_extra_context!.canvas.width = gfx_width\n this.offscreen_extra_context!.canvas.height =\n offscreen_extra_height\n }\n\n this.set_size_graphical(\n gfx_width,\n gfx_height,\n gfx_width,\n gfx_height,\n )\n\n this.changed_rows!.fill(1)\n }\n }\n\n set_size_text(cols: number, rows: number): void {\n if (cols === this.text_mode_width && rows === this.text_mode_height) {\n return\n }\n\n this.changed_rows = new Int8Array(rows)\n this.text_mode_data = new Int32Array(\n cols * rows * TEXT_BUF_COMPONENT_SIZE,\n )\n\n this.text_mode_width = cols\n this.text_mode_height = rows\n\n if (this.mode === MODE_TEXT) {\n while (this.text_screen.childNodes.length > rows) {\n this.text_screen.removeChild(this.text_screen.firstChild!)\n }\n\n while (this.text_screen.childNodes.length < rows) {\n this.text_screen.appendChild(document.createElement('div'))\n }\n\n for (let i = 0; i < rows; i++) {\n this.text_update_row(i)\n }\n\n this.update_scale_text()\n } else if (this.mode === MODE_GRAPHICAL_TEXT) {\n this.set_size_graphical_text()\n }\n }\n\n set_size_graphical(\n width: number,\n height: number,\n buffer_width: number,\n buffer_height: number,\n ): void {\n if (DEBUG_SCREEN_LAYERS) {\n width = buffer_width\n height = buffer_height\n }\n\n this.graphic_screen.style.display = 'block'\n\n this.graphic_screen.width = width\n this.graphic_screen.height = height\n\n this.graphic_context.imageSmoothingEnabled = false\n\n if (\n width <= 640 &&\n width * 2 < window.innerWidth * window.devicePixelRatio &&\n height * 2 < window.innerHeight * window.devicePixelRatio\n ) {\n this.base_scale = 2\n } else {\n this.base_scale = 1\n }\n\n this.update_scale_graphic()\n }\n\n set_scale(s_x: number, s_y: number): void {\n this.scale_x = s_x\n this.scale_y = s_y\n\n this.update_scale_text()\n this.update_scale_graphic()\n }\n\n private update_scale_text(): void {\n this.elem_set_scale(this.text_screen, this.scale_x, this.scale_y, true)\n }\n\n private update_scale_graphic(): void {\n this.elem_set_scale(\n this.graphic_screen,\n this.scale_x * this.base_scale,\n this.scale_y * this.base_scale,\n false,\n )\n }\n\n private elem_set_scale(\n elem: HTMLElement,\n sx: number,\n sy: number,\n use_scale: boolean,\n ): void {\n if (!sx || !sy) {\n return\n }\n\n elem.style.width = ''\n elem.style.height = ''\n\n if (use_scale) {\n elem.style.transform = ''\n }\n\n const rectangle = elem.getBoundingClientRect()\n\n if (use_scale) {\n let scale_str = ''\n\n scale_str += sx === 1 ? '' : ' scaleX(' + sx + ')'\n scale_str += sy === 1 ? '' : ' scaleY(' + sy + ')'\n\n elem.style.transform = scale_str\n } else {\n if (sx % 1 === 0 && sy % 1 === 0) {\n this.graphic_screen.style.imageRendering = 'crisp-edges' // firefox\n this.graphic_screen.style.imageRendering = 'pixelated'\n } else {\n this.graphic_screen.style.imageRendering = ''\n }\n\n const device_pixel_ratio = window.devicePixelRatio || 1\n if (device_pixel_ratio % 1 !== 0) {\n sx /= device_pixel_ratio\n sy /= device_pixel_ratio\n }\n }\n\n if (sx !== 1) {\n elem.style.width = rectangle.width * sx + 'px'\n }\n if (sy !== 1) {\n elem.style.height = rectangle.height * sy + 'px'\n }\n }\n\n update_cursor_scanline(start: number, end: number, enabled: boolean): void {\n if (\n start !== this.cursor_start ||\n end !== this.cursor_end ||\n enabled !== this.cursor_enabled\n ) {\n if (this.mode === MODE_TEXT) {\n if (enabled) {\n this.cursor_element.style.display = 'inline'\n this.cursor_element.style.height = end - start + 'px'\n this.cursor_element.style.marginTop = start + 'px'\n } else {\n this.cursor_element.style.display = 'none'\n }\n } else if (this.mode === MODE_GRAPHICAL_TEXT) {\n if (this.cursor_row < this.text_mode_height) {\n this.changed_rows![this.cursor_row] = 1\n }\n }\n\n this.cursor_start = start\n this.cursor_end = end\n this.cursor_enabled = enabled\n }\n }\n\n update_cursor(row: number, col: number): void {\n if (row !== this.cursor_row || col !== this.cursor_col) {\n if (row < this.text_mode_height) {\n this.changed_rows![row] = 1\n }\n if (this.cursor_row < this.text_mode_height) {\n this.changed_rows![this.cursor_row] = 1\n }\n\n this.cursor_row = row\n this.cursor_col = col\n }\n }\n\n text_update_row(row: number): void {\n let offset = TEXT_BUF_COMPONENT_SIZE * row * this.text_mode_width\n\n let blinking: number\n let bg_color: number\n let fg_color: number\n let text: string\n\n const row_element = this.text_screen.childNodes[row]\n const fragment = document.createElement('div')\n\n for (let i = 0; i < this.text_mode_width; ) {\n const color_element = document.createElement('span')\n\n blinking =\n this.text_mode_data![offset + FLAGS_INDEX] & FLAG_BLINKING\n bg_color = this.text_mode_data![offset + BG_COLOR_INDEX]\n fg_color = this.text_mode_data![offset + FG_COLOR_INDEX]\n\n if (blinking) {\n color_element.classList.add('blink')\n }\n\n color_element.style.backgroundColor = this.number_as_color(bg_color)\n color_element.style.color = this.number_as_color(fg_color)\n\n text = ''\n\n while (\n i < this.text_mode_width &&\n (this.text_mode_data![offset + FLAGS_INDEX] & FLAG_BLINKING) ===\n blinking &&\n this.text_mode_data![offset + BG_COLOR_INDEX] === bg_color &&\n this.text_mode_data![offset + FG_COLOR_INDEX] === fg_color\n ) {\n const chr =\n this.charmap[this.text_mode_data![offset + CHARACTER_INDEX]]\n\n text += chr\n dbg_assert(!!chr)\n\n i++\n offset += TEXT_BUF_COMPONENT_SIZE\n\n if (row === this.cursor_row) {\n if (i === this.cursor_col) {\n break\n } else if (i === this.cursor_col + 1) {\n this.cursor_element.style.backgroundColor =\n color_element.style.color\n fragment.appendChild(this.cursor_element)\n break\n }\n }\n }\n\n color_element.textContent = text\n fragment.appendChild(color_element)\n }\n\n row_element.parentNode!.replaceChild(fragment, row_element)\n }\n\n update_buffer(layers: ScreenLayer[]): void {\n if (DEBUG_SCREEN_LAYERS) {\n this.graphic_context.strokeStyle = '#0F0'\n this.graphic_context.lineWidth = 4\n for (const layer of layers) {\n this.graphic_context.strokeRect(\n layer.buffer_x,\n layer.buffer_y,\n layer.buffer_width,\n layer.buffer_height,\n )\n }\n this.graphic_context.lineWidth = 1\n return\n }\n\n for (const layer of layers) {\n this.graphic_context.putImageData(\n layer.image_data,\n layer.screen_x - layer.buffer_x,\n layer.screen_y - layer.buffer_y,\n layer.buffer_x,\n layer.buffer_y,\n layer.buffer_width,\n layer.buffer_height,\n )\n }\n }\n\n get_text_screen(): string[] {\n const screen: string[] = []\n\n for (let i = 0; i < this.text_mode_height; i++) {\n screen.push(this.get_text_row(i))\n }\n\n return screen\n }\n\n get_text_row(y: number): string {\n const begin =\n y * this.text_mode_width * TEXT_BUF_COMPONENT_SIZE + CHARACTER_INDEX\n const end = begin + this.text_mode_width * TEXT_BUF_COMPONENT_SIZE\n let row = ''\n for (let i = begin; i < end; i += TEXT_BUF_COMPONENT_SIZE) {\n row += this.charmap[this.text_mode_data![i]]\n }\n return row\n }\n}\n", "import { dbg_assert } from '../log.js'\nimport { get_charmap } from '../lib.js'\n\ninterface DummyScreenOptions {\n encoding?: string\n}\n\nexport class DummyScreenAdapter {\n FLAG_BLINKING = 0x01\n FLAG_FONT_PAGE_B = 0x02\n\n private cursor_row = 0\n private cursor_col = 0\n private graphical_mode_width = 0\n private graphical_mode_height = 0\n private is_graphical = false\n private text_mode_data: Uint8Array\n private text_mode_width = 0\n private text_mode_height = 0\n private charmap: string\n\n constructor(options?: DummyScreenOptions) {\n this.charmap = get_charmap(options?.encoding || '')\n this.text_mode_data = new Uint8Array(0)\n this.set_size_text(80, 25)\n }\n\n put_char(\n row: number,\n col: number,\n chr: number,\n _blinking: number,\n _bg_color: number,\n _fg_color: number,\n ): void {\n dbg_assert(row >= 0 && row < this.text_mode_height)\n dbg_assert(col >= 0 && col < this.text_mode_width)\n this.text_mode_data[row * this.text_mode_width + col] = chr\n }\n\n destroy(): void {}\n pause(): void {}\n continue(): void {}\n\n set_mode(graphical: boolean): void {\n this.is_graphical = graphical\n }\n\n set_font_bitmap(\n _height: number,\n _width_9px: boolean,\n _width_dbl: boolean,\n _copy_8th_col: boolean,\n _bitmap: Uint8Array,\n _bitmap_changed: boolean,\n ): void {}\n\n set_font_page(_page_a: number, _page_b: number): void {}\n\n clear_screen(): void {}\n\n set_size_text(cols: number, rows: number): void {\n if (cols === this.text_mode_width && rows === this.text_mode_height) {\n return\n }\n\n this.text_mode_data = new Uint8Array(cols * rows)\n this.text_mode_width = cols\n this.text_mode_height = rows\n }\n\n set_size_graphical(width: number, height: number): void {\n this.graphical_mode_width = width\n this.graphical_mode_height = height\n }\n\n set_scale(_s_x: number, _s_y: number): void {}\n\n update_cursor_scanline(_start: number, _end: number, _max: number): void {}\n\n update_cursor(row: number, col: number): void {\n this.cursor_row = row\n this.cursor_col = col\n }\n\n update_buffer(_layers: any[]): void {}\n\n get_text_screen(): string[] {\n const screen: string[] = []\n\n for (let i = 0; i < this.text_mode_height; i++) {\n screen.push(this.get_text_row(i))\n }\n\n return screen\n }\n\n get_text_row(y: number): string {\n const begin = y * this.text_mode_width\n const end = begin + this.text_mode_width\n return Array.from(\n this.text_mode_data.subarray(begin, end),\n (chr) => this.charmap[chr],\n ).join('')\n }\n}\n", "import { dbg_assert } from '../log.js'\nimport { BusConnector } from '../bus.js'\n\nclass TextAreaAdapter {\n enabled = true\n text = ''\n text_new_line = false\n last_update = 0\n update_timer: ReturnType<typeof setTimeout> | undefined = undefined\n\n protected element: HTMLTextAreaElement\n\n private keypress_handler: (e: KeyboardEvent) => void\n private keydown_handler: (e: KeyboardEvent) => void\n private paste_handler: (e: ClipboardEvent) => void\n private window_click_handler: (e: MouseEvent) => void\n\n constructor(element: HTMLTextAreaElement) {\n this.element = element\n\n this.keypress_handler = (e: KeyboardEvent) => {\n if (!this.may_handle(e)) {\n return\n }\n\n const chr = e.which\n this.send_char(chr)\n e.preventDefault()\n }\n\n this.keydown_handler = (e: KeyboardEvent) => {\n const chr = e.which\n\n if (chr === 8) {\n this.send_char(127)\n e.preventDefault()\n } else if (chr === 9) {\n this.send_char(9)\n e.preventDefault()\n }\n }\n\n this.paste_handler = (e: ClipboardEvent) => {\n if (!this.may_handle(e)) {\n return\n }\n\n const data = e.clipboardData?.getData('text/plain') || ''\n\n for (let i = 0; i < data.length; i++) {\n this.send_char(data.charCodeAt(i))\n }\n\n e.preventDefault()\n }\n\n this.window_click_handler = (e: MouseEvent) => {\n if (e.target !== element) {\n element.blur()\n }\n }\n\n this.init()\n }\n\n destroy(): void {\n this.enabled = false\n\n this.element.removeEventListener(\n 'keypress',\n this.keypress_handler,\n false,\n )\n this.element.removeEventListener('keydown', this.keydown_handler, false)\n this.element.removeEventListener('paste', this.paste_handler, false)\n window.removeEventListener(\n 'mousedown',\n this.window_click_handler,\n false,\n )\n }\n\n init(): void {\n this.destroy()\n this.enabled = true\n\n this.element.style.display = 'block'\n this.element.addEventListener('keypress', this.keypress_handler, false)\n this.element.addEventListener('keydown', this.keydown_handler, false)\n this.element.addEventListener('paste', this.paste_handler, false)\n window.addEventListener('mousedown', this.window_click_handler, false)\n }\n\n show_char(chr: string): void {\n if (chr === '\\x08') {\n this.text = this.text.slice(0, -1)\n this.update()\n } else if (chr === '\\r') {\n // do nothing\n } else {\n this.text += chr\n\n if (chr === '\\n') {\n this.text_new_line = true\n }\n\n this.update()\n }\n }\n\n update(): void {\n const now = Date.now()\n const delta = now - this.last_update\n\n if (delta < 16) {\n if (this.update_timer === undefined) {\n this.update_timer = setTimeout(() => {\n this.update_timer = undefined\n const now = Date.now()\n dbg_assert(now - this.last_update >= 15)\n this.last_update = now\n this.render()\n }, 16 - delta)\n }\n } else {\n if (this.update_timer !== undefined) {\n clearTimeout(this.update_timer)\n this.update_timer = undefined\n }\n\n this.last_update = now\n this.render()\n }\n }\n\n render(): void {\n this.element.value = this.text\n\n if (this.text_new_line) {\n this.text_new_line = false\n this.element.scrollTop = 1e9\n }\n }\n\n send_char(_chr_code: number): void {\n // placeholder, overridden by subclasses\n }\n\n private may_handle(_e: Event): boolean {\n if (!this.enabled) {\n return false\n }\n\n return true\n }\n}\n\nexport class SerialAdapter extends TextAreaAdapter {\n private bus: BusConnector\n\n constructor(element: HTMLTextAreaElement, bus: BusConnector) {\n super(element)\n this.bus = bus\n\n bus.register(\n 'serial0-output-byte',\n function (this: SerialAdapter, byte: number) {\n const chr = String.fromCharCode(byte)\n this.show_char(chr)\n },\n this,\n )\n }\n\n override send_char(chr_code: number): void {\n this.bus.send('serial0-input', chr_code)\n }\n}\n\nexport class VirtioConsoleAdapter extends TextAreaAdapter {\n private bus: BusConnector\n\n constructor(element: HTMLTextAreaElement, bus: BusConnector) {\n super(element)\n this.bus = bus\n\n const decoder = new TextDecoder()\n bus.register(\n 'virtio-console0-output-bytes',\n function (this: VirtioConsoleAdapter, bytes: Uint8Array) {\n for (const chr of decoder.decode(bytes)) {\n this.show_char(chr)\n }\n },\n this,\n )\n }\n\n override send_char(chr_code: number): void {\n this.bus.send('virtio-console0-input-bytes', new Uint8Array([chr_code]))\n }\n}\n\nclass _SerialRecordingAdapter {\n text = ''\n\n constructor(bus: BusConnector) {\n bus.register(\n 'serial0-output-byte',\n function (this: _SerialRecordingAdapter, byte: number) {\n const chr = String.fromCharCode(byte)\n this.text += chr\n },\n this,\n )\n }\n}\n\ninterface XtermTerminal {\n open(element: HTMLElement): void\n write(data: Uint8Array): void\n\n onData(callback: (data: string) => void): any\n dispose(): void\n}\n\ntype XtermConstructor = new (options: any) => XtermTerminal\n\nclass XtermJSAdapter {\n element: HTMLElement\n term: XtermTerminal\n\n on_data_disposable: any\n\n constructor(element: HTMLElement, xterm_lib: XtermConstructor) {\n this.element = element\n\n this.term = new xterm_lib({\n logLevel: 'off',\n convertEol: 'true',\n })\n }\n\n destroy(): void {\n if (this.on_data_disposable) {\n this.on_data_disposable.dispose()\n }\n this.term.dispose()\n }\n\n show(): void {\n if (this.term) {\n this.term.open(this.element)\n }\n }\n}\n\nexport class SerialAdapterXtermJS extends XtermJSAdapter {\n private bus: BusConnector | undefined\n\n constructor(\n element: HTMLElement,\n bus: BusConnector,\n xterm_lib: XtermConstructor,\n ) {\n super(element, xterm_lib)\n this.bus = bus\n\n bus.register(\n 'serial0-output-byte',\n function (this: SerialAdapterXtermJS, utf8_byte: number) {\n this.term.write(Uint8Array.of(utf8_byte))\n },\n this,\n )\n\n const utf8_encoder = new TextEncoder()\n this.on_data_disposable = this.term.onData(function (data_str: string) {\n for (const utf8_byte of utf8_encoder.encode(data_str)) {\n bus.send('serial0-input', utf8_byte)\n }\n })\n }\n}\n\nexport class VirtioConsoleAdapterXtermJS extends XtermJSAdapter {\n private bus: BusConnector | undefined\n\n constructor(\n element: HTMLElement,\n bus: BusConnector,\n xterm_lib: XtermConstructor,\n ) {\n super(element, xterm_lib)\n this.bus = bus\n\n bus.register(\n 'virtio-console0-output-bytes',\n function (\n this: VirtioConsoleAdapterXtermJS,\n utf8_bytes: Uint8Array,\n ) {\n this.term.write(utf8_bytes)\n },\n this,\n )\n\n const utf8_encoder = new TextEncoder()\n this.on_data_disposable = this.term.onData(function (data_str: string) {\n bus.send(\n 'virtio-console0-input-bytes',\n utf8_encoder.encode(data_str),\n )\n })\n }\n}\n", "import { BusConnector } from '../bus.js'\n\ninterface InBrowserNetworkConfig {\n id?: number\n}\n\n/**\n * Network adapter \"inbrowser\" which connects the emulated NIC\n * to a shared in-browser BroadcastChannel.\n *\n * NOTE: BroadcastChannel.postMessage() sends the given message to\n * *other* BroadcastChannel objects set up for the same channel.\n * Since we use the same BroadcastChannel instance for both\n * sending and receiving we do not receive copies of our\n * own sent messages.\n * Source: https://html.spec.whatwg.org/multipage/web-messaging.html#broadcasting-to-other-browsing-contexts\n */\nexport class InBrowserNetworkAdapter {\n bus: BusConnector\n bus_send_msgid: string\n bus_recv_msgid: string\n channel: BroadcastChannel\n is_open: boolean\n nic_to_hub_fn: (eth_frame: Uint8Array) => void\n hub_to_nic_fn: (ev: MessageEvent) => void\n\n constructor(bus: BusConnector, config: InBrowserNetworkConfig) {\n const id = config.id || 0\n\n this.bus = bus\n this.bus_send_msgid = `net${id}-send`\n this.bus_recv_msgid = `net${id}-receive`\n this.channel = new BroadcastChannel(`v86-inbrowser-${id}`)\n this.is_open = true\n\n // forward ethernet frames from emulated NIC to hub\n this.nic_to_hub_fn = (eth_frame: Uint8Array) => {\n this.channel.postMessage(eth_frame)\n }\n this.bus.register(this.bus_send_msgid, this.nic_to_hub_fn, this)\n\n // forward ethernet frames from hub to emulated NIC\n this.hub_to_nic_fn = (ev: MessageEvent) => {\n this.bus.send(this.bus_recv_msgid, ev.data)\n }\n this.channel.addEventListener('message', this.hub_to_nic_fn)\n }\n\n destroy(): void {\n if (this.is_open) {\n this.bus.unregister(this.bus_send_msgid, this.nic_to_hub_fn)\n this.channel.removeEventListener('message', this.hub_to_nic_fn)\n this.channel.close()\n this.is_open = false\n }\n }\n}\n", "import { dbg_assert } from '../log.js'\nimport { load_file } from '../lib.js'\n\nexport interface FileStorageInterface {\n read(\n sha256sum: string,\n offset: number,\n count: number,\n file_size: number,\n ): Promise<Uint8Array | null>\n cache(sha256sum: string, data: Uint8Array): Promise<void>\n uncache(sha256sum: string): void\n}\n\nexport class MemoryFileStorage implements FileStorageInterface {\n filedata: Map<string, Uint8Array>\n\n constructor() {\n this.filedata = new Map()\n }\n\n async read(\n sha256sum: string,\n offset: number,\n count: number,\n _file_size: number,\n ): Promise<Uint8Array | null> {\n dbg_assert(\n !!sha256sum,\n 'MemoryFileStorage read: sha256sum should be a non-empty string',\n )\n const data = this.filedata.get(sha256sum)\n\n if (!data) {\n return null\n }\n\n return data.subarray(offset, offset + count)\n }\n\n async cache(sha256sum: string, data: Uint8Array): Promise<void> {\n dbg_assert(\n !!sha256sum,\n 'MemoryFileStorage cache: sha256sum should be a non-empty string',\n )\n this.filedata.set(sha256sum, data)\n }\n\n uncache(sha256sum: string): void {\n this.filedata.delete(sha256sum)\n }\n}\n\nexport class ServerFileStorageWrapper implements FileStorageInterface {\n storage: FileStorageInterface\n baseurl: string\n zstd_decompress: (file_size: number, data: Uint8Array) => ArrayBuffer\n\n constructor(\n file_storage: FileStorageInterface,\n baseurl: string,\n zstd_decompress: (file_size: number, data: Uint8Array) => ArrayBuffer,\n ) {\n dbg_assert(\n !!baseurl,\n 'ServerMemoryFileStorage: baseurl should not be empty',\n )\n\n if (!baseurl.endsWith('/')) {\n baseurl += '/'\n }\n\n this.storage = file_storage\n this.baseurl = baseurl\n this.zstd_decompress = zstd_decompress\n }\n\n load_from_server(\n sha256sum: string,\n file_size: number,\n ): Promise<Uint8Array> {\n return new Promise((resolve, _reject) => {\n load_file(this.baseurl + sha256sum, {\n done: async (buffer: ArrayBuffer) => {\n let data = new Uint8Array(buffer)\n if (sha256sum.endsWith('.zst')) {\n data = new Uint8Array(\n this.zstd_decompress(file_size, data),\n )\n }\n await this.cache(sha256sum, data)\n resolve(data)\n },\n })\n })\n }\n\n async read(\n sha256sum: string,\n offset: number,\n count: number,\n file_size: number,\n ): Promise<Uint8Array | null> {\n const data = await this.storage.read(\n sha256sum,\n offset,\n count,\n file_size,\n )\n if (!data) {\n const full_file = await this.load_from_server(sha256sum, file_size)\n return full_file.subarray(offset, offset + count)\n }\n return data\n }\n\n async cache(sha256sum: string, data: Uint8Array): Promise<void> {\n return await this.storage.cache(sha256sum, data)\n }\n\n uncache(sha256sum: string): void {\n this.storage.uncache(sha256sum)\n }\n}\n", "declare let DEBUG: boolean\n\nimport { v86 } from '../main.js'\nimport { LOG_CPU, WASM_TABLE_OFFSET, WASM_TABLE_SIZE } from '../const.js'\nimport { get_rand_int, load_file, read_sized_string_from_mem } from '../lib.js'\nimport { dbg_assert, dbg_trace, dbg_log, set_log_level } from '../log.js'\nimport * as print_stats from './print_stats.js'\nimport { Bus } from '../bus.js'\nimport {\n BOOT_ORDER_FD_FIRST,\n BOOT_ORDER_HD_FIRST,\n BOOT_ORDER_CD_FIRST,\n} from '../rtc.js'\nimport { SpeakerAdapter } from './speaker.js'\nimport { NetworkAdapter } from './network.js'\nimport { FetchNetworkAdapter } from './fetch_network.js'\nimport { WispNetworkAdapter } from './wisp_network.js'\nimport { KeyboardAdapter } from './keyboard.js'\nimport { MouseAdapter } from './mouse.js'\nimport { ScreenAdapter } from './screen.js'\nimport { DummyScreenAdapter } from './dummy_screen.js'\nimport {\n SerialAdapter,\n VirtioConsoleAdapter,\n SerialAdapterXtermJS,\n VirtioConsoleAdapterXtermJS,\n} from './serial.js'\nimport { InBrowserNetworkAdapter } from './inbrowser_network.js'\n\nimport {\n FileStorageInterface,\n MemoryFileStorage,\n ServerFileStorageWrapper,\n} from './filestorage.js'\nimport { SyncBuffer, buffer_from_object } from '../buffer.js'\nimport { FS } from '../../lib/filesystem.js'\n\ntype WasmExports = any\n\ntype EmulatorSettings = any\n\ntype V86Options = any\n\ntype FileDescriptor = any\n\ntype AutoStep = any\n\nclass FileExistsError {\n message: string\n constructor(message?: string) {\n this.message = message || 'File already exists'\n }\n}\nFileExistsError.prototype = Error.prototype\n\nclass FileNotFoundError {\n message: string\n constructor(message?: string) {\n this.message = message || 'File not found'\n }\n}\nFileNotFoundError.prototype = Error.prototype\n\n/**\n * Constructor for emulator instances.\n *\n * For API usage, see v86.d.ts in the root of this repository.\n */\nexport class V86 {\n cpu_is_running = false\n\n cpu_exception_hook: (n: number) => void = function (_n: number) {}\n\n bus: any\n\n emulator_bus: any\n\n v86: any\n\n wasm_source: any\n\n zstd_worker: Worker | null = null\n zstd_worker_request_id = 0\n\n zstd_context: any = null\n\n keyboard_adapter: any\n\n mouse_adapter: any\n\n screen_adapter: any\n\n network_adapter: any\n\n serial_adapter: any\n\n speaker_adapter: any\n\n virtio_console_adapter: any\n\n fs9p: any\n\n constructor(options: V86Options) {\n if (typeof options.log_level === 'number') {\n // XXX: Shared between all emulator instances\n set_log_level(options.log_level)\n }\n\n //var worker = new Worker(\"src/browser/worker.js\");\n //var adapter_bus = this.bus = WorkerBus.init(worker);\n\n const bus = Bus.create()\n this.bus = bus[0]\n this.emulator_bus = bus[1]\n\n let cpu: any\n\n let wasm_memory: any\n\n const wasm_table = new WebAssembly.Table({\n element: 'anyfunc',\n initial: WASM_TABLE_SIZE + WASM_TABLE_OFFSET,\n })\n\n const wasm_shared_funcs = {\n cpu_exception_hook: (n: number) => this.cpu_exception_hook(n),\n\n run_hardware_timers: function (a: any, t: any) {\n return cpu.run_hardware_timers(a, t)\n },\n cpu_event_halt: () => {\n this.emulator_bus.send('cpu-event-halt')\n },\n abort: function () {\n dbg_assert(false)\n },\n microtick: v86.microtick,\n get_rand_int: function () {\n return get_rand_int()\n },\n stop_idling: function () {\n return cpu.stop_idling()\n },\n\n io_port_read8: function (addr: number) {\n return cpu.io.port_read8(addr)\n },\n io_port_read16: function (addr: number) {\n return cpu.io.port_read16(addr)\n },\n io_port_read32: function (addr: number) {\n return cpu.io.port_read32(addr)\n },\n io_port_write8: function (addr: number, value: number) {\n cpu.io.port_write8(addr, value)\n },\n io_port_write16: function (addr: number, value: number) {\n cpu.io.port_write16(addr, value)\n },\n io_port_write32: function (addr: number, value: number) {\n cpu.io.port_write32(addr, value)\n },\n\n mmap_read8: function (addr: number) {\n return cpu.mmap_read8(addr)\n },\n mmap_read32: function (addr: number) {\n return cpu.mmap_read32(addr)\n },\n mmap_write8: function (addr: number, value: number) {\n cpu.mmap_write8(addr, value)\n },\n mmap_write16: function (addr: number, value: number) {\n cpu.mmap_write16(addr, value)\n },\n mmap_write32: function (addr: number, value: number) {\n cpu.mmap_write32(addr, value)\n },\n mmap_write64: function (\n addr: number,\n value0: number,\n value1: number,\n ) {\n cpu.mmap_write64(addr, value0, value1)\n },\n mmap_write128: function (\n addr: number,\n value0: number,\n value1: number,\n value2: number,\n value3: number,\n ) {\n cpu.mmap_write128(addr, value0, value1, value2, value3)\n },\n\n log_from_wasm: function (offset: number, len: number) {\n const str = read_sized_string_from_mem(wasm_memory, offset, len)\n dbg_log(str, LOG_CPU)\n },\n console_log_from_wasm: function (offset: number, len: number) {\n const str = read_sized_string_from_mem(wasm_memory, offset, len)\n console.error(str)\n },\n dbg_trace_from_wasm: function () {\n dbg_trace(LOG_CPU)\n },\n\n codegen_finalize: (\n wasm_table_index: number,\n start: number,\n state_flags: number,\n ptr: number,\n len: number,\n ) => {\n cpu.codegen_finalize(\n wasm_table_index,\n start,\n state_flags,\n ptr,\n len,\n )\n },\n jit_clear_func: (wasm_table_index: number) =>\n cpu.jit_clear_func(wasm_table_index),\n jit_clear_all_funcs: () => cpu.jit_clear_all_funcs(),\n\n __indirect_function_table: wasm_table,\n }\n\n let wasm_fn = options.wasm_fn\n\n if (!wasm_fn) {\n wasm_fn = (env: any) => {\n /* global __dirname */\n\n return new Promise((resolve) => {\n let v86_bin = DEBUG ? 'v86-debug.wasm' : 'v86.wasm'\n let v86_bin_fallback = 'v86-fallback.wasm'\n\n if (options.wasm_path) {\n v86_bin = options.wasm_path\n v86_bin_fallback = v86_bin.replace(\n 'v86.wasm',\n 'v86-fallback.wasm',\n )\n } else if (\n typeof window === 'undefined' &&\n typeof __dirname === 'string'\n ) {\n v86_bin = __dirname + '/' + v86_bin\n v86_bin_fallback = __dirname + '/' + v86_bin_fallback\n } else {\n v86_bin = 'build/' + v86_bin\n v86_bin_fallback = 'build/' + v86_bin_fallback\n }\n\n load_file(v86_bin, {\n done: async (bytes: any) => {\n try {\n const { instance } =\n await WebAssembly.instantiate(bytes, env)\n this.wasm_source = bytes\n resolve(instance.exports)\n } catch {\n load_file(v86_bin_fallback, {\n done: async (bytes: any) => {\n const { instance } =\n await WebAssembly.instantiate(\n bytes,\n env,\n )\n this.wasm_source = bytes\n resolve(instance.exports)\n },\n })\n }\n },\n\n progress: (e: any) => {\n this.emulator_bus.send('download-progress', {\n file_index: 0,\n file_count: 1,\n file_name: v86_bin,\n\n lengthComputable: e.lengthComputable,\n total: e.total,\n loaded: e.loaded,\n })\n },\n })\n })\n }\n }\n\n wasm_fn({ env: wasm_shared_funcs }).then((exports: WasmExports) => {\n wasm_memory = exports.memory\n exports['rust_init']()\n\n const emulator = (this.v86 = new v86(this.emulator_bus, {\n exports,\n wasm_table,\n }))\n cpu = emulator.cpu\n\n this.continue_init(emulator, options)\n })\n }\n\n private async continue_init(\n emulator: any,\n options: V86Options,\n ): Promise<void> {\n this.bus.register(\n 'emulator-stopped',\n function (this: V86) {\n this.cpu_is_running = false\n this.screen_adapter.pause()\n },\n this,\n )\n\n this.bus.register(\n 'emulator-started',\n function (this: V86) {\n this.cpu_is_running = true\n this.screen_adapter.continue()\n },\n this,\n )\n\n const settings: EmulatorSettings = {}\n\n const boot_order = options.boot_order\n ? options.boot_order\n : options.fda\n ? BOOT_ORDER_FD_FIRST\n : options.hda\n ? BOOT_ORDER_HD_FIRST\n : BOOT_ORDER_CD_FIRST\n\n settings.acpi = options.acpi\n settings.disable_jit = options.disable_jit\n settings.load_devices = true\n settings.memory_size = options.memory_size || 64 * 1024 * 1024\n settings.vga_memory_size = options.vga_memory_size || 8 * 1024 * 1024\n settings.boot_order = boot_order\n settings.fastboot = options.fastboot || false\n settings.fda = undefined\n settings.fdb = undefined\n settings.uart1 = options.uart1\n settings.uart2 = options.uart2\n settings.uart3 = options.uart3\n settings.cmdline = options.cmdline\n settings.preserve_mac_from_state_image =\n options.preserve_mac_from_state_image\n settings.mac_address_translation = options.mac_address_translation\n settings.cpuid_level = options.cpuid_level\n settings.virtio_balloon = options.virtio_balloon\n settings.virtio_console = !!options.virtio_console\n\n const relay_url =\n options.network_relay_url ||\n (options.net_device && options.net_device.relay_url)\n if (relay_url) {\n // TODO: remove bus, use direct calls instead\n if (relay_url === 'fetch') {\n this.network_adapter = new FetchNetworkAdapter(\n this.bus,\n options.net_device,\n )\n } else if (relay_url === 'inbrowser') {\n // NOTE: experimental, will change when usage of options.net_device gets refactored in favour of emulator.bus\n this.network_adapter = new InBrowserNetworkAdapter(\n this.bus,\n options.net_device,\n )\n } else if (\n relay_url.startsWith('wisp://') ||\n relay_url.startsWith('wisps://')\n ) {\n this.network_adapter = new WispNetworkAdapter(\n relay_url,\n this.bus,\n options.net_device,\n )\n } else {\n this.network_adapter = new NetworkAdapter(relay_url, this.bus)\n }\n }\n\n // Enable unconditionally, so that state images don't miss hardware\n // TODO: Should be properly fixed in restore_state\n settings.net_device = options.net_device || { type: 'ne2k' }\n\n const screen_options = options.screen || {}\n if (options.screen_container) {\n screen_options.container = options.screen_container\n }\n\n if (!options.disable_keyboard) {\n this.keyboard_adapter = new KeyboardAdapter(this.bus)\n }\n if (!options.disable_mouse) {\n this.mouse_adapter = new MouseAdapter(\n this.bus,\n screen_options.container,\n )\n }\n\n if (screen_options.container) {\n this.screen_adapter = new ScreenAdapter(\n screen_options,\n () =>\n this.v86.cpu.devices.vga &&\n this.v86.cpu.devices.vga.screen_fill_buffer(),\n )\n } else {\n this.screen_adapter = new DummyScreenAdapter(screen_options)\n }\n settings.screen = this.screen_adapter\n settings.screen_options = screen_options\n\n settings.serial_console = options.serial_console || { type: 'none' }\n\n // NOTE: serial_container_xtermjs and serial_container are deprecated\n if (options.serial_container_xtermjs) {\n settings.serial_console.type = 'xtermjs'\n settings.serial_console.container = options.serial_container_xtermjs\n } else if (options.serial_container) {\n settings.serial_console.type = 'textarea'\n settings.serial_console.container = options.serial_container\n }\n\n if (settings.serial_console?.type === 'xtermjs') {\n const xterm_lib =\n settings.serial_console.xterm_lib || (window as any)['Terminal']\n this.serial_adapter = new SerialAdapterXtermJS(\n settings.serial_console.container,\n this.bus,\n xterm_lib,\n )\n } else if (settings.serial_console?.type === 'textarea') {\n this.serial_adapter = new SerialAdapter(\n settings.serial_console.container,\n this.bus,\n )\n //this.recording_adapter = new SerialRecordingAdapter(this.bus);\n }\n\n const virtio_console_settings =\n options.virtio_console &&\n typeof options.virtio_console === 'boolean'\n ? { type: 'none' }\n : options.virtio_console\n\n if (virtio_console_settings?.type === 'xtermjs') {\n const xterm_lib =\n virtio_console_settings.xterm_lib || (window as any)['Terminal']\n this.virtio_console_adapter = new VirtioConsoleAdapterXtermJS(\n virtio_console_settings.container,\n this.bus,\n xterm_lib,\n )\n } else if (virtio_console_settings?.type === 'textarea') {\n this.virtio_console_adapter = new VirtioConsoleAdapter(\n virtio_console_settings.container,\n this.bus,\n )\n }\n\n if (!options.disable_speaker) {\n this.speaker_adapter = new SpeakerAdapter(this.bus)\n }\n\n // ugly, but required for closure compiler compilation\n\n function put_on_settings(name: string, buffer: any) {\n switch (name) {\n case 'hda':\n settings.hda = buffer\n break\n case 'hdb':\n settings.hdb = buffer\n break\n case 'cdrom':\n settings.cdrom = buffer\n break\n case 'fda':\n settings.fda = buffer\n break\n case 'fdb':\n settings.fdb = buffer\n break\n\n case 'multiboot':\n settings.multiboot = buffer.buffer\n break\n case 'bzimage':\n settings.bzimage = buffer.buffer\n break\n case 'initrd':\n settings.initrd = buffer.buffer\n break\n\n case 'bios':\n settings.bios = buffer.buffer\n break\n case 'vga_bios':\n settings.vga_bios = buffer.buffer\n break\n case 'initial_state':\n settings.initial_state = buffer.buffer\n break\n case 'fs9p_json':\n settings.fs9p_json = buffer\n break\n default:\n dbg_assert(false, name)\n }\n }\n\n const files_to_load: any[] = []\n\n const add_file = (name: string, file: any) => {\n if (!file) {\n return\n }\n\n if (file.get && file.set && file.load) {\n files_to_load.push({\n name: name,\n loadable: file,\n })\n return\n }\n\n if (\n name === 'bios' ||\n name === 'vga_bios' ||\n name === 'initial_state' ||\n name === 'multiboot' ||\n name === 'bzimage' ||\n name === 'initrd'\n ) {\n // Ignore async for these because they must be available before boot.\n // This should make result.buffer available after the object is loaded\n file.async = false\n }\n\n if (name === 'fda' || name === 'fdb') {\n // small, doesn't make sense loading asynchronously\n file.async = false\n }\n\n if (file.url && !file.async) {\n files_to_load.push({\n name: name,\n url: file.url,\n size: file.size,\n })\n } else {\n files_to_load.push({\n name,\n loadable: buffer_from_object(\n file,\n this.zstd_decompress_worker.bind(this),\n ),\n })\n }\n }\n\n if (options.state) {\n console.warn(\n \"Warning: Unknown option 'state'. Did you mean 'initial_state'?\",\n )\n }\n\n add_file('bios', options.bios)\n add_file('vga_bios', options.vga_bios)\n add_file('cdrom', options.cdrom)\n add_file('hda', options.hda)\n add_file('hdb', options.hdb)\n add_file('fda', options.fda)\n add_file('fdb', options.fdb)\n add_file('initial_state', options.initial_state)\n add_file('multiboot', options.multiboot)\n add_file('bzimage', options.bzimage)\n add_file('initrd', options.initrd)\n\n if (options.filesystem && options.filesystem.handle9p) {\n settings.handle9p = options.filesystem.handle9p\n } else if (options.filesystem && options.filesystem.proxy_url) {\n settings.proxy9p = options.filesystem.proxy_url\n } else if (options.filesystem) {\n let fs_url = options.filesystem.basefs\n const base_url = options.filesystem.baseurl\n\n let file_storage: FileStorageInterface = new MemoryFileStorage()\n\n if (base_url) {\n file_storage = new ServerFileStorageWrapper(\n file_storage,\n base_url,\n this.zstd_decompress.bind(this),\n )\n }\n settings.fs9p = this.fs9p = new FS(file_storage)\n\n if (fs_url) {\n dbg_assert(base_url, 'Filesystem: baseurl must be specified')\n\n let size: number | undefined\n\n if (typeof fs_url === 'object') {\n size = fs_url.size\n fs_url = fs_url.url\n }\n dbg_assert(typeof fs_url === 'string')\n\n files_to_load.push({\n name: 'fs9p_json',\n url: fs_url,\n size: size,\n as_json: true,\n })\n }\n }\n\n const total = files_to_load.length\n\n const cont = (index: number) => {\n if (index === total) {\n setTimeout(() => done.call(this), 0)\n return\n }\n\n const f = files_to_load[index]\n\n if (f.loadable) {\n f.loadable.onload = () => {\n put_on_settings(f.name, f.loadable)\n cont(index + 1)\n }\n f.loadable.load()\n } else {\n load_file(f.url, {\n done: (result: any) => {\n if (\n f.url.endsWith('.zst') &&\n f.name !== 'initial_state'\n ) {\n dbg_assert(\n f.size,\n 'A size must be provided for compressed images',\n )\n result = this.zstd_decompress(\n f.size,\n new Uint8Array(result),\n )\n }\n\n put_on_settings(\n f.name,\n f.as_json ? result : new SyncBuffer(result),\n )\n cont(index + 1)\n },\n\n progress: (e: any) => {\n if (e.target.status === 200) {\n this.emulator_bus.send('download-progress', {\n file_index: index,\n file_count: total,\n file_name: f.url,\n\n lengthComputable: e.lengthComputable,\n total: e.total || f.size,\n loaded: e.loaded,\n })\n } else {\n this.emulator_bus.send('download-error', {\n file_index: index,\n file_count: total,\n file_name: f.url,\n request: e.target,\n })\n }\n },\n as_json: f.as_json,\n })\n }\n }\n cont(0)\n\n const done = async function (this: V86) {\n //if(settings.initial_state)\n //{\n // // avoid large allocation now, memory will be restored later anyway\n // settings.memory_size = 0;\n //}\n\n if (settings.fs9p && settings.fs9p_json) {\n if (!settings.initial_state) {\n settings.fs9p.load_from_json(settings.fs9p_json)\n\n if (options.bzimage_initrd_from_filesystem) {\n const { bzimage_path, initrd_path } =\n this.get_bzimage_initrd_from_filesystem(\n settings.fs9p,\n )\n\n dbg_log(\n 'Found bzimage: ' +\n bzimage_path +\n ' and initrd: ' +\n initrd_path,\n )\n\n const [initrd, bzimage] = await Promise.all([\n settings.fs9p.read_file(initrd_path),\n settings.fs9p.read_file(bzimage_path),\n ])\n put_on_settings('initrd', new SyncBuffer(initrd.buffer))\n put_on_settings(\n 'bzimage',\n new SyncBuffer(bzimage.buffer),\n )\n }\n } else {\n dbg_log(\n 'Filesystem basefs ignored: Overridden by state image',\n )\n }\n } else {\n dbg_assert(\n !options.bzimage_initrd_from_filesystem ||\n settings.initial_state,\n 'bzimage_initrd_from_filesystem: Requires a filesystem',\n )\n }\n\n if (this.serial_adapter && this.serial_adapter.show) {\n this.serial_adapter.show()\n }\n if (\n this.virtio_console_adapter &&\n this.virtio_console_adapter.show\n ) {\n this.virtio_console_adapter.show()\n }\n\n this.v86.init(settings)\n\n if (settings.initial_state) {\n emulator.restore_state(settings.initial_state)\n\n // The GC can't free settings, since it is referenced from\n // several closures. This isn't needed anymore, so we delete it\n // here\n settings.initial_state = undefined\n }\n\n if (options.autostart) {\n this.v86.run()\n }\n\n this.emulator_bus.send('emulator-loaded')\n }\n }\n\n /**\n * Decompress zstd data synchronously.\n */\n zstd_decompress(decompressed_size: number, src: Uint8Array): ArrayBuffer {\n const cpu = this.v86.cpu\n\n dbg_assert(!this.zstd_context)\n this.zstd_context = cpu.zstd_create_ctx(src.length)\n\n new Uint8Array(cpu.wasm_memory.buffer).set(\n src,\n cpu.zstd_get_src_ptr(this.zstd_context),\n )\n\n const ptr = cpu.zstd_read(this.zstd_context, decompressed_size)\n const result = cpu.wasm_memory.buffer.slice(\n ptr,\n ptr + decompressed_size,\n )\n cpu.zstd_read_free(ptr, decompressed_size)\n\n cpu.zstd_free_ctx(this.zstd_context)\n this.zstd_context = null\n\n return result\n }\n\n /**\n * Decompress zstd data asynchronously using a web worker.\n */\n async zstd_decompress_worker(\n decompressed_size: number,\n src: Uint8Array,\n ): Promise<ArrayBuffer> {\n if (!this.zstd_worker) {\n function the_worker() {\n let wasm: any\n\n globalThis.onmessage = function (e: any) {\n if (!wasm) {\n const env: Record<string, any> = Object.fromEntries(\n [\n 'cpu_exception_hook',\n 'run_hardware_timers',\n 'cpu_event_halt',\n 'microtick',\n 'get_rand_int',\n 'stop_idling',\n 'io_port_read8',\n 'io_port_read16',\n 'io_port_read32',\n 'io_port_write8',\n 'io_port_write16',\n 'io_port_write32',\n 'mmap_read8',\n 'mmap_read32',\n 'mmap_write8',\n 'mmap_write16',\n 'mmap_write32',\n 'mmap_write64',\n 'mmap_write128',\n 'codegen_finalize',\n 'jit_clear_func',\n 'jit_clear_all_funcs',\n ].map((f) => [\n f,\n () =>\n console.error(\n 'zstd worker unexpectedly called ' + f,\n ),\n ]),\n )\n\n env['__indirect_function_table'] =\n new WebAssembly.Table({\n element: 'anyfunc',\n initial: 1024,\n })\n env['abort'] = () => {\n throw new Error('zstd worker aborted')\n }\n env['log_from_wasm'] = env['console_log_from_wasm'] = (\n off: number,\n len: number,\n ) => {\n console.log(\n read_sized_string_from_mem(\n wasm.exports.memory.buffer,\n off,\n len,\n ),\n )\n }\n env['dbg_trace_from_wasm'] = () => console.trace()\n\n wasm = new WebAssembly.Instance(\n new WebAssembly.Module(e.data),\n { env: env },\n )\n return\n }\n\n const { src, decompressed_size, id } = e.data\n const exports = wasm.exports\n\n const zstd_context = exports['zstd_create_ctx'](src.length)\n new Uint8Array(exports.memory.buffer).set(\n src,\n exports['zstd_get_src_ptr'](zstd_context),\n )\n\n const ptr = exports['zstd_read'](\n zstd_context,\n decompressed_size,\n )\n const result = exports.memory.buffer.slice(\n ptr,\n ptr + decompressed_size,\n )\n exports['zstd_read_free'](ptr, decompressed_size)\n\n exports['zstd_free_ctx'](zstd_context)\n\n postMessage({ result, id }, [result])\n }\n }\n\n const url = URL.createObjectURL(\n new Blob(['(' + the_worker.toString() + ')()'], {\n type: 'text/javascript',\n }),\n )\n this.zstd_worker = new Worker(url)\n URL.revokeObjectURL(url)\n this.zstd_worker.postMessage(this.wasm_source, [this.wasm_source])\n }\n\n return new Promise((resolve) => {\n const id = this.zstd_worker_request_id++\n const done = async (e: MessageEvent) => {\n if (e.data.id === id) {\n this.zstd_worker!.removeEventListener('message', done)\n dbg_assert(decompressed_size === e.data.result.byteLength)\n resolve(e.data.result)\n }\n }\n this.zstd_worker!.addEventListener('message', done)\n this.zstd_worker!.postMessage({ src, decompressed_size, id }, [\n src.buffer,\n ])\n })\n }\n\n get_bzimage_initrd_from_filesystem(filesystem: any): {\n initrd_path: string | undefined\n bzimage_path: string | undefined\n } {\n const root = (filesystem.read_dir('/') || []).map(\n (x: string) => '/' + x,\n )\n const boot = (filesystem.read_dir('/boot/') || []).map(\n (x: string) => '/boot/' + x,\n )\n\n let initrd_path: string | undefined\n let bzimage_path: string | undefined\n\n for (const f of ([] as string[]).concat(root, boot)) {\n const old = /old/i.test(f) || /fallback/i.test(f)\n const is_bzimage = /vmlinuz/i.test(f) || /bzimage/i.test(f)\n const is_initrd = /initrd/i.test(f) || /initramfs/i.test(f)\n\n if (is_bzimage && (!bzimage_path || !old)) {\n bzimage_path = f\n }\n\n if (is_initrd && (!initrd_path || !old)) {\n initrd_path = f\n }\n }\n\n if (!initrd_path || !bzimage_path) {\n console.log(\n 'Failed to find bzimage or initrd in filesystem. Files:',\n )\n console.log(root.join(' '))\n console.log(boot.join(' '))\n }\n\n return { initrd_path, bzimage_path }\n }\n\n /**\n * Start emulation. Do nothing if emulator is running already. Can be asynchronous.\n */\n async run(): Promise<void> {\n this.v86.run()\n }\n\n /**\n * Stop emulation. Do nothing if emulator is not running. Can be asynchronous.\n */\n async stop(): Promise<void> {\n if (!this.cpu_is_running) {\n return\n }\n\n await new Promise<void>((resolve) => {\n const listener = () => {\n this.remove_listener('emulator-stopped', listener)\n resolve()\n }\n this.add_listener('emulator-stopped', listener)\n this.v86.stop()\n })\n }\n\n /**\n * Free resources associated with this instance.\n */\n async destroy(): Promise<void> {\n await this.stop()\n\n this.v86.destroy()\n if (this.keyboard_adapter) {\n this.keyboard_adapter.destroy()\n }\n if (this.network_adapter) {\n this.network_adapter.destroy()\n }\n if (this.mouse_adapter) {\n this.mouse_adapter.destroy()\n }\n if (this.screen_adapter) {\n this.screen_adapter.destroy()\n }\n if (this.serial_adapter) {\n this.serial_adapter.destroy()\n }\n if (this.speaker_adapter) {\n this.speaker_adapter.destroy()\n }\n if (this.virtio_console_adapter) {\n this.virtio_console_adapter.destroy()\n }\n }\n\n /**\n * Restart (force a reboot).\n */\n restart(): void {\n this.v86.restart()\n }\n\n /**\n * Add an event listener (the emulator is an event emitter).\n *\n * The callback function gets a single argument which depends on the event.\n */\n add_listener(event: string, listener: (...args: any[]) => any): void {\n this.bus.register(event, listener, this)\n }\n\n /**\n * Remove an event listener.\n */\n remove_listener(event: string, listener: (...args: any[]) => any): void {\n this.bus.unregister(event, listener)\n }\n\n /**\n * Restore the emulator state from the given state, which must be an\n * ArrayBuffer returned by save_state.\n *\n * Note that the state can only be restored correctly if this constructor has\n * been created with the same options as the original instance (e.g., same disk\n * images, memory size, etc.).\n *\n * Different versions of the emulator might use a different format for the\n * state buffer.\n */\n async restore_state(state: ArrayBuffer): Promise<void> {\n dbg_assert(arguments.length === 1)\n this.v86.restore_state(state)\n }\n\n /**\n * Asynchronously save the current state of the emulator.\n */\n async save_state(): Promise<ArrayBuffer> {\n dbg_assert(arguments.length === 0)\n return this.v86.save_state()\n }\n\n /**\n * Get the instruction counter value.\n */\n get_instruction_counter(): number {\n if (this.v86) {\n return this.v86.cpu.instruction_counter[0] >>> 0\n } else {\n // TODO: Should be handled using events\n return 0\n }\n }\n\n /**\n * Check if the emulator is running.\n */\n is_running(): boolean {\n return this.cpu_is_running\n }\n\n /**\n * Set the image inserted in the floppy drive. Can be changed at runtime, as\n * when physically changing the floppy disk.\n */\n async set_fda(file: FileDescriptor): Promise<void> {\n const fda = this.v86.cpu.devices.fdc.drives[0]\n if (file.url && !file.async) {\n await new Promise<void>((resolve) => {\n load_file(file.url, {\n done: (result: any) => {\n fda.insert_disk(new SyncBuffer(result))\n resolve()\n },\n })\n })\n } else {\n const image = buffer_from_object(\n file,\n this.zstd_decompress_worker.bind(this),\n )\n\n ;(image as any).onload = () => {\n fda.insert_disk(image)\n }\n\n await (image as any).load()\n }\n }\n\n /**\n * Set the image inserted in the second floppy drive, also at runtime.\n */\n async set_fdb(file: FileDescriptor): Promise<void> {\n const fdb = this.v86.cpu.devices.fdc.drives[1]\n if (file.url && !file.async) {\n await new Promise<void>((resolve) => {\n load_file(file.url, {\n done: (result: any) => {\n fdb.insert_disk(new SyncBuffer(result))\n resolve()\n },\n })\n })\n } else {\n const image = buffer_from_object(\n file,\n this.zstd_decompress_worker.bind(this),\n )\n\n ;(image as any).onload = () => {\n fdb.insert_disk(image)\n }\n\n await (image as any).load()\n }\n }\n\n /**\n * Eject floppy drive fda.\n */\n eject_fda(): void {\n this.v86.cpu.devices.fdc.drives[0].eject_disk()\n }\n\n /**\n * Eject second floppy drive fdb.\n */\n eject_fdb(): void {\n this.v86.cpu.devices.fdc.drives[1].eject_disk()\n }\n\n /**\n * Return buffer object of floppy disk of drive fda or null if the drive is empty.\n */\n get_disk_fda(): Uint8Array | null {\n return this.v86.cpu.devices.fdc.drives[0].get_buffer()\n }\n\n /**\n * Return buffer object of second floppy disk of drive fdb or null if the drive is empty.\n */\n get_disk_fdb(): Uint8Array | null {\n return this.v86.cpu.devices.fdc.drives[1].get_buffer()\n }\n\n /**\n * Set the image inserted in the CD-ROM drive. Can be changed at runtime, as\n * when physically changing the CD-ROM.\n */\n async set_cdrom(file: FileDescriptor): Promise<void> {\n if (file.url && !file.async) {\n load_file(file.url, {\n done: (result: any) => {\n this.v86.cpu.devices.cdrom.set_cdrom(new SyncBuffer(result))\n },\n })\n } else {\n const image = buffer_from_object(\n file,\n this.zstd_decompress_worker.bind(this),\n )\n\n ;(image as any).onload = () => {\n this.v86.cpu.devices.cdrom.set_cdrom(image)\n }\n\n await (image as any).load()\n }\n }\n\n /**\n * Eject the CD-ROM.\n */\n eject_cdrom(): void {\n this.v86.cpu.devices.cdrom.eject()\n }\n\n /**\n * Send a sequence of scan codes to the emulated PS2 controller. A list of\n * codes can be found at http://stanislavs.org/helppc/make_codes.html.\n * Do nothing if there is no keyboard controller.\n */\n async keyboard_send_scancodes(\n codes: number[],\n delay?: number,\n ): Promise<void> {\n for (let i = 0; i < codes.length; i++) {\n this.bus.send('keyboard-code', codes[i])\n if (delay)\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n }\n\n /**\n * Send translated keys.\n */\n async keyboard_send_keys(codes: number[], delay?: number): Promise<void> {\n for (let i = 0; i < codes.length; i++) {\n this.keyboard_adapter.simulate_press(codes[i])\n if (delay)\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n }\n\n /**\n * Send text, assuming the guest OS uses a US keyboard layout.\n */\n async keyboard_send_text(string: string, delay?: number): Promise<void> {\n for (let i = 0; i < string.length; i++) {\n this.keyboard_adapter.simulate_char(string[i])\n if (delay)\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n }\n\n /**\n * Download a screenshot (returns an img element, only works in browsers).\n */\n screen_make_screenshot(): HTMLImageElement | null {\n if (this.screen_adapter) {\n return this.screen_adapter.make_screenshot()\n }\n return null\n }\n\n /**\n * Set the scaling level of the emulated screen.\n */\n screen_set_scale(sx: number, sy: number): void {\n if (this.screen_adapter) {\n this.screen_adapter.set_scale(sx, sy)\n }\n }\n\n /**\n * Go fullscreen (only browsers).\n */\n screen_go_fullscreen(): void {\n if (!this.screen_adapter) {\n return\n }\n\n const elem = document.getElementById('screen_container')\n\n if (!elem) {\n return\n }\n\n // bracket notation because otherwise they get renamed by closure compiler\n\n const fn =\n (elem as any)['requestFullScreen'] ||\n (elem as any)['webkitRequestFullscreen'] ||\n (elem as any)['mozRequestFullScreen'] ||\n (elem as any)['msRequestFullScreen']\n\n if (fn) {\n fn.call(elem)\n\n // This is necessary, because otherwise chromium keyboard doesn't work anymore.\n // Might (but doesn't seem to) break something else\n const focus_element = document.getElementsByClassName(\n 'phone_keyboard',\n )[0] as HTMLElement | undefined\n if (focus_element) {\n focus_element.focus()\n }\n }\n\n try {\n ;(navigator as any).keyboard.lock()\n } catch {\n // intentionally empty\n }\n\n this.lock_mouse()\n }\n\n /**\n * Lock the mouse cursor: It becomes invisible and is not moved out of the\n * browser window.\n */\n async lock_mouse(): Promise<void> {\n const elem = document.body\n\n try {\n await elem.requestPointerLock({\n unadjustedMovement: true,\n })\n } catch {\n // as per MDN, retry without unadjustedMovement option\n await elem.requestPointerLock()\n }\n }\n\n /**\n * Enable or disable sending mouse events to the emulated PS2 controller.\n */\n mouse_set_enabled(enabled: boolean): void {\n if (this.mouse_adapter) {\n this.mouse_adapter.emu_enabled = enabled\n }\n }\n\n /**\n * Alias for mouse_set_enabled.\n */\n mouse_set_status(enabled: boolean): void {\n this.mouse_set_enabled(enabled)\n }\n\n /**\n * Enable or disable sending keyboard events to the emulated PS2 controller.\n */\n keyboard_set_enabled(enabled: boolean): void {\n if (this.keyboard_adapter) {\n this.keyboard_adapter.emu_enabled = enabled\n }\n }\n\n /**\n * Alias for keyboard_set_enabled.\n */\n keyboard_set_status(enabled: boolean): void {\n this.keyboard_set_enabled(enabled)\n }\n\n /**\n * Send a string to the first emulated serial terminal.\n */\n serial0_send(data: string): void {\n for (let i = 0; i < data.length; i++) {\n this.bus.send('serial0-input', data.charCodeAt(i))\n }\n }\n\n /**\n * Send bytes to a serial port (to be received by the emulated PC).\n */\n serial_send_bytes(serial: number, data: Uint8Array): void {\n for (let i = 0; i < data.length; i++) {\n this.bus.send('serial' + serial + '-input', data[i])\n }\n }\n\n /**\n * Set the modem status of a serial port.\n */\n serial_set_modem_status(serial: number, status: number): void {\n this.bus.send('serial' + serial + '-modem-status-input', status)\n }\n\n /**\n * Set the carrier detect status of a serial port.\n */\n serial_set_carrier_detect(serial: number, status: number): void {\n this.bus.send('serial' + serial + '-carrier-detect-input', status)\n }\n\n /**\n * Set the ring indicator status of a serial port.\n */\n serial_set_ring_indicator(serial: number, status: number): void {\n this.bus.send('serial' + serial + '-ring-indicator-input', status)\n }\n\n /**\n * Set the data set ready status of a serial port.\n */\n serial_set_data_set_ready(serial: number, status: number): void {\n this.bus.send('serial' + serial + '-data-set-ready-input', status)\n }\n\n /**\n * Set the clear to send status of a serial port.\n */\n serial_set_clear_to_send(serial: number, status: number): void {\n this.bus.send('serial' + serial + '-clear-to-send-input', status)\n }\n\n /**\n * Write to a file in the 9p filesystem. Nothing happens if no filesystem has\n * been initialized.\n */\n async create_file(file: string, data: Uint8Array): Promise<void> {\n dbg_assert(arguments.length === 2)\n const fs = this.fs9p\n\n if (!fs) {\n return\n }\n\n const parts = file.split('/')\n const filename = parts[parts.length - 1]\n\n const path_infos = fs.SearchPath(file)\n const parent_id = path_infos.parentid\n const not_found = filename === '' || parent_id === -1\n\n if (!not_found) {\n await fs.CreateBinaryFile(filename, parent_id, data)\n } else {\n return Promise.reject(new FileNotFoundError())\n }\n }\n\n /**\n * Read a file in the 9p filesystem. Nothing happens if no filesystem has been\n * initialized.\n */\n async read_file(file: string): Promise<Uint8Array | undefined> {\n dbg_assert(arguments.length === 1)\n const fs = this.fs9p\n\n if (!fs) {\n return\n }\n\n const result = await fs.read_file(file)\n\n if (result) {\n return result\n } else {\n return Promise.reject(new FileNotFoundError())\n }\n }\n\n /**\n * Run a sequence of automated steps.\n * @deprecated Use wait_until_vga_screen_contains etc.\n */\n automatically(steps: AutoStep[]): void {\n const run = (steps: AutoStep[]) => {\n const step = steps[0]\n\n if (!step) {\n return\n }\n\n const remaining_steps = steps.slice(1)\n\n if (step.sleep) {\n setTimeout(() => run(remaining_steps), step.sleep * 1000)\n return\n }\n\n if (step.vga_text) {\n this.wait_until_vga_screen_contains(step.vga_text).then(() =>\n run(remaining_steps),\n )\n return\n }\n\n if (step.keyboard_send) {\n if (Array.isArray(step.keyboard_send)) {\n this.keyboard_send_scancodes(step.keyboard_send)\n } else {\n dbg_assert(typeof step.keyboard_send === 'string')\n this.keyboard_send_text(step.keyboard_send)\n }\n\n run(remaining_steps)\n return\n }\n\n if (step.call) {\n step.call()\n run(remaining_steps)\n return\n }\n\n dbg_assert(false, step)\n }\n\n run(steps)\n }\n\n /**\n * Wait until expected text is present on the VGA text screen.\n *\n * Returns immediately if the expected text is already present on screen\n * at the time this function is called.\n *\n * An optional timeout may be specified in options.timeout_msec, returns\n * false if the timeout expires before the expected text could be detected.\n *\n * Expected text (or texts, see below) must be of type string or RegExp,\n * strings are tested against the beginning of a screen line, regular\n * expressions against the full line but may use wildcards for partial\n * matching.\n *\n * Two methods of text detection are supported depending on the type of the\n * argument expected:\n *\n * 1. If expected is a string or RegExp then the given text string or\n * regular expression may match any line on screen for this function\n * to succeed.\n *\n * 2. If expected is an array of strings and/or RegExp objects then the\n * list of expected lines must match exactly at \"the bottom\" of the\n * screen. The \"bottom\" line is the first non-empty line starting from\n * the screen's end.\n * Expected lines should not contain any trailing whitespace and/or\n * newline characters. Expecting an empty line is valid.\n *\n * Returns true on success and false when the timeout has expired.\n */\n async wait_until_vga_screen_contains(\n expected: string | RegExp | Array<string | RegExp>,\n options?: { timeout_msec?: number },\n ): Promise<boolean> {\n const match_multi = Array.isArray(expected)\n const timeout_msec = options?.timeout_msec || 0\n const changed_rows = new Set<number>()\n\n const screen_put_char = (args: any) => changed_rows.add(args[0])\n const contains_expected = (\n screen_line: string,\n pattern: string | RegExp,\n ) =>\n (pattern as RegExp).test\n ? (pattern as RegExp).test(screen_line)\n : screen_line.startsWith(pattern as string)\n const screen_lines: string[] = []\n\n this.add_listener('screen-put-char', screen_put_char)\n\n for (const screen_line of this.screen_adapter.get_text_screen()) {\n if (match_multi) {\n screen_lines.push(screen_line.trimRight())\n } else if (\n contains_expected(screen_line, expected as string | RegExp)\n ) {\n this.remove_listener('screen-put-char', screen_put_char)\n return true\n }\n }\n\n let succeeded = false\n const end = timeout_msec ? performance.now() + timeout_msec : 0\n loop: while (!end || performance.now() < end) {\n if (match_multi) {\n let screen_height = screen_lines.length\n while (\n screen_height > 0 &&\n screen_lines[screen_height - 1] === ''\n ) {\n screen_height--\n }\n const screen_offset =\n screen_height - (expected as Array<string | RegExp>).length\n if (screen_offset >= 0) {\n let matches = true\n for (\n let i = 0;\n i < (expected as Array<string | RegExp>).length &&\n matches;\n i++\n ) {\n matches = contains_expected(\n screen_lines[screen_offset + i],\n (expected as Array<string | RegExp>)[i],\n )\n }\n if (matches) {\n succeeded = true\n break\n }\n }\n }\n\n await new Promise((resolve) => setTimeout(resolve, 100))\n\n for (const row of changed_rows) {\n const screen_line = this.screen_adapter.get_text_row(row)\n if (match_multi) {\n screen_lines[row] = screen_line.trimRight()\n } else if (\n contains_expected(screen_line, expected as string | RegExp)\n ) {\n succeeded = true\n break loop\n }\n }\n changed_rows.clear()\n }\n\n this.remove_listener('screen-put-char', screen_put_char)\n return succeeded\n }\n\n /**\n * Reads data from memory at specified offset.\n */\n\n read_memory(offset: number, length: number): any {\n return this.v86.cpu.read_blob(offset, length)\n }\n\n /**\n * Writes data to memory at specified offset.\n */\n write_memory(blob: number[] | Uint8Array, offset: number): void {\n this.v86.cpu.write_blob(blob, offset)\n }\n\n /**\n * Set the serial container to an xterm.js terminal.\n */\n\n set_serial_container_xtermjs(\n element: HTMLElement,\n xterm_lib: any = (window as any)['Terminal'],\n ): void {\n if (this.serial_adapter && this.serial_adapter.destroy) {\n this.serial_adapter.destroy()\n }\n this.serial_adapter = new SerialAdapterXtermJS(\n element,\n this.bus,\n xterm_lib,\n )\n this.serial_adapter.show()\n }\n\n /**\n * Set the virtio console container to an xterm.js terminal.\n */\n\n set_virtio_console_container_xtermjs(\n element: HTMLElement,\n xterm_lib: any = (window as any)['Terminal'],\n ): void {\n if (\n this.virtio_console_adapter &&\n this.virtio_console_adapter.destroy\n ) {\n this.virtio_console_adapter.destroy()\n }\n this.virtio_console_adapter = new VirtioConsoleAdapterXtermJS(\n element,\n this.bus,\n xterm_lib,\n )\n this.virtio_console_adapter.show()\n }\n\n get_instruction_stats(): string {\n return print_stats.stats_to_string(this.v86.cpu)\n }\n}\n\ndeclare let module: any\ndeclare let importScripts: any\ndeclare let self: any\n\nif (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {\n module.exports['V86'] = V86\n} else if (typeof window !== 'undefined') {\n ;(window as any)['V86'] = V86\n} else if (typeof importScripts === 'function') {\n // web worker\n\n ;(self as any)['V86'] = V86\n}\n", "import { CPU } from './cpu.js'\nimport { save_state, restore_state } from './state.js'\nexport { V86 } from './browser/starter.js'\n\nimport { BusConnector } from './bus.js'\n\n// CPU is a constructor function (not a TS class), so it lacks a construct\n// signature. We alias it through an untyped binding to call with `new`.\n\nconst CPUConstructor: any = CPU\n\ntype CPUInstance = any\n\nfunction the_worker() {\n let timeout: ReturnType<typeof setTimeout> | undefined\n globalThis.onmessage = function (e: MessageEvent) {\n const t = e.data.t\n if (timeout) {\n clearTimeout(timeout)\n timeout = undefined\n }\n if (t < 1) postMessage(e.data.tick)\n else timeout = setTimeout(() => postMessage(e.data.tick), t)\n }\n}\n\nexport class v86 {\n running: boolean = false\n stopping: boolean = false\n idle: boolean = true\n tick_counter: number = 0\n worker: Worker | null = null\n cpu: CPUInstance\n bus: BusConnector\n\n static microtick: () => number\n\n constructor(bus: BusConnector, wasm: any) {\n this.cpu = new CPUConstructor(bus, wasm, () => {\n if (this.idle) {\n this.next_tick(0)\n }\n })\n this.bus = bus\n this.register_yield()\n }\n\n run(): void {\n this.stopping = false\n\n if (!this.running) {\n this.running = true\n this.bus.send('emulator-started')\n }\n\n this.next_tick(0)\n }\n\n do_tick(): void {\n if (this.stopping || !this.running) {\n this.stopping = this.running = false\n this.bus.send('emulator-stopped')\n return\n }\n\n this.idle = false\n const t = this.cpu.main_loop()\n\n this.next_tick(t)\n }\n\n next_tick(t: number): void {\n const tick = ++this.tick_counter\n this.idle = true\n this.yield(t, tick)\n }\n\n yield_callback(tick: number): void {\n if (tick === this.tick_counter) {\n this.do_tick()\n }\n }\n\n stop(): void {\n if (this.running) {\n this.stopping = true\n }\n }\n\n destroy(): void {\n this.unregister_yield()\n }\n\n restart(): void {\n this.cpu.reset_cpu()\n this.cpu.load_bios()\n }\n\n init(settings: any): void {\n this.cpu.init(settings, this.bus)\n this.bus.send('emulator-ready')\n }\n\n save_state(): ArrayBuffer {\n return save_state(this.cpu)\n }\n\n restore_state(state: any): void {\n return restore_state(this.cpu, state)\n }\n\n yield(t: number, _tick: number): void {\n // Default fallback: setTimeout\n setTimeout(() => {\n this.do_tick()\n }, t)\n }\n\n register_yield(): void {\n // no-op by default\n }\n\n unregister_yield(): void {\n // no-op by default\n }\n}\n\nconst _global: any = globalThis\n\n// Environment-specific yield strategy overrides\nif (typeof process !== 'undefined') {\n v86.prototype.yield = function (t: number, tick: number): void {\n if (t < 1) {\n _global.setImmediate(\n (tick: number) => this.yield_callback(tick),\n tick,\n )\n } else {\n setTimeout((tick: number) => this.yield_callback(tick), t, tick)\n }\n }\n\n v86.prototype.register_yield = function (): void {}\n v86.prototype.unregister_yield = function (): void {}\n} else if (\n _global['scheduler'] &&\n typeof _global['scheduler']['postTask'] === 'function' &&\n location.href.includes('use-scheduling-api')\n) {\n v86.prototype.yield = function (t: number, tick: number): void {\n t = Math.max(0, t)\n _global['scheduler']['postTask'](() => this.yield_callback(tick), {\n delay: t,\n })\n }\n\n v86.prototype.register_yield = function (): void {}\n v86.prototype.unregister_yield = function (): void {}\n} else if (typeof Worker !== 'undefined') {\n // XXX: This has a slightly lower throughput compared to window.postMessage\n\n v86.prototype.register_yield = function (): void {\n const url = URL.createObjectURL(\n new Blob(['(' + the_worker.toString() + ')()'], {\n type: 'text/javascript',\n }),\n )\n this.worker = new Worker(url)\n this.worker.onmessage = (e: MessageEvent) => this.yield_callback(e.data)\n URL.revokeObjectURL(url)\n }\n\n v86.prototype.yield = function (t: number, tick: number): void {\n this.worker!.postMessage({ t, tick })\n }\n\n v86.prototype.unregister_yield = function (): void {\n if (this.worker) {\n this.worker.terminate()\n }\n this.worker = null\n }\n}\n\n// Static microtick initialization\nif (typeof performance === 'object' && performance.now) {\n v86.microtick = performance.now.bind(performance)\n} else if (typeof require === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { performance } = require('perf_hooks')\n v86.microtick = performance.now.bind(performance)\n} else if (typeof process === 'object' && process.hrtime) {\n v86.microtick = function () {\n const t = process.hrtime()\n return t[0] * 1000 + t[1] / 1e6\n }\n} else {\n v86.microtick = Date.now\n}\n"],
5
+ "mappings": "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ACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN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B,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AAEjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UAAM,EAAE,IAAI,KAAK;AACjB,UA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",
6
+ "names": ["line", "block", "cap_len", "view", "dbg_log", "h", "view", "FLAG_BLINKING", "FLAG_FONT_PAGE_B", "texten", "ret", "inode", "path", "bufchain", "i", "ELF_MAGIC", "i", "handle_write", "module", "result", "handle", "pae", "self", "MTU_DEFAULT", "MTU_DEFAULT", "view", "o", "view", "now", "bytes", "the_worker", "src", "decompressed_size", "steps", "tick", "performance"]
7
+ }