@aptre/v86 0.6.1 → 0.6.3
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.
- package/dist/v86.browser.js +43 -76
- package/dist/v86.browser.js.map +3 -3
- package/dist/v86.js +43 -76
- package/dist/v86.js.map +3 -3
- package/package.json +1 -1
- package/src/browser/starter.ts +6 -2
- package/src/cpu.ts +87 -93
package/package.json
CHANGED
package/src/browser/starter.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
declare let DEBUG: boolean
|
|
2
2
|
|
|
3
3
|
import { v86 } from '../main.js'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
LOG_CPU,
|
|
6
|
+
WASM_PAGE_SIZE,
|
|
7
|
+
WASM_TABLE_OFFSET,
|
|
8
|
+
WASM_TABLE_SIZE,
|
|
9
|
+
} from '../const.js'
|
|
5
10
|
import { get_rand_int, load_file, read_sized_string_from_mem } from '../lib.js'
|
|
6
11
|
import { dbg_assert, dbg_trace, dbg_log, set_log_level } from '../log.js'
|
|
7
12
|
import * as print_stats from './print_stats.js'
|
|
@@ -112,7 +117,6 @@ export class V86 {
|
|
|
112
117
|
const vga_memory_size = options.vga_memory_size || 8 * 1024 * 1024
|
|
113
118
|
const memory_max =
|
|
114
119
|
options.memory_max || (memory_size + vga_memory_size) * 4
|
|
115
|
-
const WASM_PAGE_SIZE = 65536
|
|
116
120
|
const wasm_initial_pages = 256
|
|
117
121
|
const wasm_max_pages = Math.max(
|
|
118
122
|
wasm_initial_pages,
|
package/src/cpu.ts
CHANGED
|
@@ -155,7 +155,6 @@ export class CPU {
|
|
|
155
155
|
memory_size!: Int32Array
|
|
156
156
|
|
|
157
157
|
mem8: Uint8Array
|
|
158
|
-
mem8_offset: number = 0
|
|
159
158
|
mem32s: Int32Array
|
|
160
159
|
|
|
161
160
|
segment_is_null!: Uint8Array
|
|
@@ -348,111 +347,134 @@ export class CPU {
|
|
|
348
347
|
this.wasm_patch()
|
|
349
348
|
this.create_jit_imports()
|
|
350
349
|
|
|
351
|
-
|
|
352
|
-
this.mem32s = new Int32Array(this.mem8.buffer)
|
|
353
|
-
|
|
354
|
-
this.rebuild_wasm_views()
|
|
355
|
-
|
|
356
|
-
// @ts-expect-error Devices are populated during init()
|
|
357
|
-
this.devices = {}
|
|
358
|
-
|
|
359
|
-
// managed in io.js
|
|
360
|
-
this.memory_map_read8 = []
|
|
361
|
-
this.memory_map_write8 = []
|
|
362
|
-
this.memory_map_read32 = []
|
|
363
|
-
this.memory_map_write32 = []
|
|
364
|
-
|
|
365
|
-
this.bios = {
|
|
366
|
-
main: null,
|
|
367
|
-
vga: null,
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
this.fpu_stack_empty[0] = 0xff
|
|
371
|
-
this.fpu_stack_ptr[0] = 0
|
|
372
|
-
|
|
373
|
-
this.fpu_control_word[0] = 0x37f
|
|
374
|
-
this.fpu_status_word[0] = 0
|
|
375
|
-
this.fpu_ip[0] = 0
|
|
376
|
-
this.fpu_ip_selector[0] = 0
|
|
377
|
-
this.fpu_opcode[0] = 0
|
|
378
|
-
this.fpu_dp[0] = 0
|
|
379
|
-
this.fpu_dp_selector[0] = 0
|
|
380
|
-
|
|
381
|
-
this.fw_value = []
|
|
382
|
-
this.fw_pointer = 0
|
|
383
|
-
this.option_roms = []
|
|
384
|
-
|
|
385
|
-
this.io = undefined!
|
|
386
|
-
|
|
387
|
-
this.bus = bus
|
|
350
|
+
const memory = this.wasm_memory
|
|
388
351
|
|
|
389
|
-
this.
|
|
352
|
+
this.memory_size = view(Uint32Array, memory, 812, 1)
|
|
390
353
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
this.seen_code_uncompiled = {}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
354
|
+
this.mem8 = new Uint8Array(0)
|
|
355
|
+
this.mem32s = new Int32Array(this.mem8.buffer)
|
|
396
356
|
|
|
397
|
-
/**
|
|
398
|
-
* Rebuild all TypedArray views into WASM linear memory.
|
|
399
|
-
* Must be called after any wasm_memory.grow() since growth
|
|
400
|
-
* detaches the old ArrayBuffer, invalidating all views.
|
|
401
|
-
*/
|
|
402
|
-
rebuild_wasm_views(): void {
|
|
403
|
-
const memory = this.wasm_memory
|
|
404
|
-
this.memory_size = view(Uint32Array, memory, 812, 1)
|
|
405
357
|
this.segment_is_null = view(Uint8Array, memory, 724, 8)
|
|
406
358
|
this.segment_offsets = view(Int32Array, memory, 736, 8)
|
|
407
359
|
this.segment_limits = view(Uint32Array, memory, 768, 8)
|
|
408
360
|
this.segment_access_bytes = view(Uint8Array, memory, 512, 8)
|
|
361
|
+
|
|
409
362
|
this.protected_mode = view(Int32Array, memory, 800, 1)
|
|
363
|
+
|
|
410
364
|
this.idtr_size = view(Int32Array, memory, 564, 1)
|
|
411
365
|
this.idtr_offset = view(Int32Array, memory, 568, 1)
|
|
366
|
+
|
|
412
367
|
this.gdtr_size = view(Int32Array, memory, 572, 1)
|
|
413
368
|
this.gdtr_offset = view(Int32Array, memory, 576, 1)
|
|
369
|
+
|
|
414
370
|
this.tss_size_32 = view(Int32Array, memory, 1128, 1)
|
|
371
|
+
|
|
415
372
|
this.page_fault = view(Uint32Array, memory, 540, 8)
|
|
373
|
+
|
|
416
374
|
this.cr = view(Int32Array, memory, 580, 8)
|
|
375
|
+
|
|
417
376
|
this.cpl = view(Uint8Array, memory, 612, 1)
|
|
377
|
+
|
|
418
378
|
this.is_32 = view(Int32Array, memory, 804, 1)
|
|
379
|
+
|
|
419
380
|
this.stack_size_32 = view(Int32Array, memory, 808, 1)
|
|
381
|
+
|
|
420
382
|
this.in_hlt = view(Uint8Array, memory, 616, 1)
|
|
383
|
+
|
|
421
384
|
this.last_virt_eip = view(Int32Array, memory, 620, 1)
|
|
422
385
|
this.eip_phys = view(Int32Array, memory, 624, 1)
|
|
386
|
+
|
|
423
387
|
this.sysenter_cs = view(Int32Array, memory, 636, 1)
|
|
388
|
+
|
|
424
389
|
this.sysenter_esp = view(Int32Array, memory, 640, 1)
|
|
390
|
+
|
|
425
391
|
this.sysenter_eip = view(Int32Array, memory, 644, 1)
|
|
392
|
+
|
|
426
393
|
this.prefixes = view(Int32Array, memory, 648, 1)
|
|
394
|
+
|
|
427
395
|
this.flags = view(Int32Array, memory, 120, 1)
|
|
396
|
+
|
|
428
397
|
this.flags_changed = view(Int32Array, memory, 100, 1)
|
|
398
|
+
|
|
429
399
|
this.last_op_size = view(Int32Array, memory, 96, 1)
|
|
430
400
|
this.last_op1 = view(Int32Array, memory, 104, 1)
|
|
431
401
|
this.last_result = view(Int32Array, memory, 112, 1)
|
|
402
|
+
|
|
432
403
|
this.current_tsc = view(Uint32Array, memory, 960, 2)
|
|
404
|
+
|
|
405
|
+
// @ts-expect-error Devices are populated during init()
|
|
406
|
+
this.devices = {}
|
|
407
|
+
|
|
433
408
|
this.instruction_pointer = view(Int32Array, memory, 556, 1)
|
|
434
409
|
this.previous_ip = view(Int32Array, memory, 560, 1)
|
|
410
|
+
|
|
435
411
|
this.apic_enabled = view(Uint8Array, memory, 548, 1)
|
|
436
412
|
this.acpi_enabled = view(Uint8Array, memory, 552, 1)
|
|
413
|
+
|
|
414
|
+
// managed in io.js
|
|
415
|
+
this.memory_map_read8 = []
|
|
416
|
+
this.memory_map_write8 = []
|
|
417
|
+
this.memory_map_read32 = []
|
|
418
|
+
this.memory_map_write32 = []
|
|
419
|
+
|
|
420
|
+
this.bios = {
|
|
421
|
+
main: null,
|
|
422
|
+
vga: null,
|
|
423
|
+
}
|
|
424
|
+
|
|
437
425
|
this.instruction_counter = view(Uint32Array, memory, 664, 1)
|
|
426
|
+
|
|
438
427
|
this.reg32 = view(Int32Array, memory, 64, 8)
|
|
428
|
+
|
|
439
429
|
this.fpu_st = view(Int32Array, memory, 1152, 4 * 8)
|
|
430
|
+
|
|
440
431
|
this.fpu_stack_empty = view(Uint8Array, memory, 816, 1)
|
|
432
|
+
this.fpu_stack_empty[0] = 0xff
|
|
441
433
|
this.fpu_stack_ptr = view(Uint8Array, memory, 1032, 1)
|
|
434
|
+
this.fpu_stack_ptr[0] = 0
|
|
435
|
+
|
|
442
436
|
this.fpu_control_word = view(Uint16Array, memory, 1036, 1)
|
|
437
|
+
this.fpu_control_word[0] = 0x37f
|
|
443
438
|
this.fpu_status_word = view(Uint16Array, memory, 1040, 1)
|
|
439
|
+
this.fpu_status_word[0] = 0
|
|
444
440
|
this.fpu_ip = view(Int32Array, memory, 1048, 1)
|
|
441
|
+
this.fpu_ip[0] = 0
|
|
445
442
|
this.fpu_ip_selector = view(Int32Array, memory, 1052, 1)
|
|
443
|
+
this.fpu_ip_selector[0] = 0
|
|
446
444
|
this.fpu_opcode = view(Int32Array, memory, 1044, 1)
|
|
445
|
+
this.fpu_opcode[0] = 0
|
|
447
446
|
this.fpu_dp = view(Int32Array, memory, 1056, 1)
|
|
447
|
+
this.fpu_dp[0] = 0
|
|
448
448
|
this.fpu_dp_selector = view(Int32Array, memory, 1060, 1)
|
|
449
|
+
this.fpu_dp_selector[0] = 0
|
|
450
|
+
|
|
449
451
|
this.reg_xmm32s = view(Int32Array, memory, 832, 8 * 4)
|
|
452
|
+
|
|
450
453
|
this.mxcsr = view(Int32Array, memory, 824, 1)
|
|
454
|
+
|
|
451
455
|
this.sreg = view(Uint16Array, memory, 668, 8)
|
|
456
|
+
|
|
452
457
|
this.dreg = view(Int32Array, memory, 684, 8)
|
|
458
|
+
|
|
453
459
|
this.reg_pdpte = view(Int32Array, memory, 968, 8)
|
|
460
|
+
|
|
454
461
|
this.svga_dirty_bitmap_min_offset = view(Uint32Array, memory, 716, 1)
|
|
455
462
|
this.svga_dirty_bitmap_max_offset = view(Uint32Array, memory, 720, 1)
|
|
463
|
+
|
|
464
|
+
this.fw_value = []
|
|
465
|
+
this.fw_pointer = 0
|
|
466
|
+
this.option_roms = []
|
|
467
|
+
|
|
468
|
+
this.io = undefined!
|
|
469
|
+
|
|
470
|
+
this.bus = bus
|
|
471
|
+
|
|
472
|
+
this.set_tsc(0, 0)
|
|
473
|
+
|
|
474
|
+
if (DEBUG) {
|
|
475
|
+
this.seen_code = {}
|
|
476
|
+
this.seen_code_uncompiled = {}
|
|
477
|
+
}
|
|
456
478
|
}
|
|
457
479
|
|
|
458
480
|
mmap_read8(addr: number): number {
|
|
@@ -704,7 +726,7 @@ export class CPU {
|
|
|
704
726
|
state[26] = this.flags[0]
|
|
705
727
|
state[27] = this.flags_changed[0]
|
|
706
728
|
state[28] = this.last_op1[0]
|
|
707
|
-
|
|
729
|
+
state[29] = this.last_result[0]
|
|
708
730
|
state[30] = this.last_op_size[0]
|
|
709
731
|
|
|
710
732
|
state[37] = this.instruction_pointer[0]
|
|
@@ -851,23 +873,15 @@ export class CPU {
|
|
|
851
873
|
}
|
|
852
874
|
|
|
853
875
|
resize_memory(new_size: number): void {
|
|
854
|
-
const
|
|
855
|
-
const
|
|
856
|
-
const
|
|
857
|
-
if (
|
|
858
|
-
const
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
}
|
|
864
|
-
this.mem8 = view(Uint8Array, this.wasm_memory, mem8_offset, new_size)
|
|
865
|
-
this.mem32s = view(
|
|
866
|
-
Int32Array,
|
|
867
|
-
this.wasm_memory,
|
|
868
|
-
mem8_offset,
|
|
869
|
-
new_size >> 2,
|
|
870
|
-
)
|
|
876
|
+
const offset = this.mem8.byteOffset
|
|
877
|
+
const needed = offset + new_size
|
|
878
|
+
const current = this.wasm_memory.buffer.byteLength
|
|
879
|
+
if (needed > current) {
|
|
880
|
+
const pages = Math.ceil((needed - current) / WASM_PAGE_SIZE)
|
|
881
|
+
this.wasm_memory.grow(pages)
|
|
882
|
+
}
|
|
883
|
+
this.mem8 = view(Uint8Array, this.wasm_memory, offset, new_size)
|
|
884
|
+
this.mem32s = view(Uint32Array, this.wasm_memory, offset, new_size >> 2)
|
|
871
885
|
this.memory_size[0] = new_size
|
|
872
886
|
}
|
|
873
887
|
|
|
@@ -931,7 +945,7 @@ export class CPU {
|
|
|
931
945
|
this.flags[0] = state[26]
|
|
932
946
|
this.flags_changed[0] = state[27]
|
|
933
947
|
this.last_op1[0] = state[28]
|
|
934
|
-
|
|
948
|
+
if (state[29] !== undefined) this.last_result[0] = state[29]
|
|
935
949
|
this.last_op_size[0] = state[30]
|
|
936
950
|
|
|
937
951
|
this.instruction_pointer[0] = state[37]
|
|
@@ -1245,10 +1259,9 @@ export class CPU {
|
|
|
1245
1259
|
'Expected uninitialised memory',
|
|
1246
1260
|
)
|
|
1247
1261
|
|
|
1248
|
-
const memory_offset = this.allocate_memory(size)
|
|
1249
|
-
this.rebuild_wasm_views()
|
|
1250
1262
|
this.memory_size[0] = size
|
|
1251
|
-
|
|
1263
|
+
|
|
1264
|
+
const memory_offset = this.allocate_memory(size)
|
|
1252
1265
|
|
|
1253
1266
|
this.mem8 = view(Uint8Array, this.wasm_memory, memory_offset, size)
|
|
1254
1267
|
this.mem32s = view(
|
|
@@ -1557,25 +1570,6 @@ export class CPU {
|
|
|
1557
1570
|
}
|
|
1558
1571
|
|
|
1559
1572
|
this.debug_init()
|
|
1560
|
-
|
|
1561
|
-
// Rebuild all WASM memory views. During init, allocate_memory
|
|
1562
|
-
// and svga_allocate_memory may trigger memory.grow (from Rust),
|
|
1563
|
-
// which detaches the old ArrayBuffer and invalidates all views.
|
|
1564
|
-
this.rebuild_wasm_views()
|
|
1565
|
-
if (this.mem8_offset > 0) {
|
|
1566
|
-
this.mem8 = view(
|
|
1567
|
-
Uint8Array,
|
|
1568
|
-
this.wasm_memory,
|
|
1569
|
-
this.mem8_offset,
|
|
1570
|
-
this.memory_size[0],
|
|
1571
|
-
)
|
|
1572
|
-
this.mem32s = view(
|
|
1573
|
-
Uint32Array,
|
|
1574
|
-
this.wasm_memory,
|
|
1575
|
-
this.mem8_offset,
|
|
1576
|
-
this.memory_size[0] >> 2,
|
|
1577
|
-
)
|
|
1578
|
-
}
|
|
1579
1573
|
}
|
|
1580
1574
|
|
|
1581
1575
|
load_multiboot(buffer: ArrayBuffer): void {
|