Skip to main content

native_v86_core/cpu/
global_pointers.rs

1#![allow(non_upper_case_globals)]
2
3use crate::cpu::cpu::reg128;
4use crate::softfloat::F80;
5use crate::state_flags::CachedStateFlags;
6use std::ptr;
7
8// v86 stores CPU scalar state in a compact fixed layout. WASM used address 0 as
9// the linear-memory base; native builds initialize these pointers against an
10// owned heap allocation instead.
11pub static mut reg8: *mut u8 = ptr::null_mut();
12pub static mut reg16: *mut u16 = ptr::null_mut();
13pub static mut reg32: *mut i32 = ptr::null_mut();
14pub static mut last_op_size: *mut i32 = ptr::null_mut();
15pub static mut flags_changed: *mut i32 = ptr::null_mut();
16pub static mut last_op1: *mut i32 = ptr::null_mut();
17pub static mut state_flags: *mut CachedStateFlags = ptr::null_mut();
18pub static mut last_result: *mut i32 = ptr::null_mut();
19pub static mut flags: *mut i32 = ptr::null_mut();
20pub static mut segment_access_bytes: *mut u8 = ptr::null_mut();
21pub static mut apic_enabled: *mut bool = ptr::null_mut();
22pub static mut acpi_enabled: *mut bool = ptr::null_mut();
23pub static mut instruction_pointer: *mut i32 = ptr::null_mut();
24pub static mut previous_ip: *mut i32 = ptr::null_mut();
25pub static mut idtr_size: *mut i32 = ptr::null_mut();
26pub static mut idtr_offset: *mut i32 = ptr::null_mut();
27pub static mut gdtr_size: *mut i32 = ptr::null_mut();
28pub static mut gdtr_offset: *mut i32 = ptr::null_mut();
29pub static mut cr: *mut i32 = ptr::null_mut();
30pub static mut cpl: *mut u8 = ptr::null_mut();
31pub static mut in_hlt: *mut bool = ptr::null_mut();
32pub static mut last_virt_eip: *mut i32 = ptr::null_mut();
33pub static mut eip_phys: *mut i32 = ptr::null_mut();
34pub static mut sysenter_cs: *mut i32 = ptr::null_mut();
35pub static mut sysenter_esp: *mut i32 = ptr::null_mut();
36pub static mut sysenter_eip: *mut i32 = ptr::null_mut();
37pub static mut prefixes: *mut u8 = ptr::null_mut();
38pub static mut instruction_counter: *mut u32 = ptr::null_mut();
39pub static mut sreg: *mut u16 = ptr::null_mut();
40pub static mut dreg: *mut i32 = ptr::null_mut();
41pub static mut svga_dirty_bitmap_min_offset: *mut u32 = ptr::null_mut();
42pub static mut svga_dirty_bitmap_max_offset: *mut u32 = ptr::null_mut();
43pub static mut segment_is_null: *mut bool = ptr::null_mut();
44pub static mut segment_offsets: *mut i32 = ptr::null_mut();
45pub static mut segment_limits: *mut u32 = ptr::null_mut();
46pub static mut protected_mode: *mut bool = ptr::null_mut();
47pub static mut is_32: *mut bool = ptr::null_mut();
48pub static mut stack_size_32: *mut bool = ptr::null_mut();
49pub static mut memory_size: *mut u32 = ptr::null_mut();
50pub static mut fpu_stack_empty: *mut u8 = ptr::null_mut();
51pub static mut mxcsr: *mut i32 = ptr::null_mut();
52pub static mut reg_xmm: *mut reg128 = ptr::null_mut();
53pub static mut current_tsc: *mut u64 = ptr::null_mut();
54pub static mut reg_pdpte: *mut u64 = ptr::null_mut();
55pub static mut fpu_stack_ptr: *mut u8 = ptr::null_mut();
56pub static mut fpu_control_word: *mut u16 = ptr::null_mut();
57pub static mut fpu_status_word: *mut u16 = ptr::null_mut();
58pub static mut fpu_opcode: *mut i32 = ptr::null_mut();
59pub static mut fpu_ip: *mut i32 = ptr::null_mut();
60pub static mut fpu_ip_selector: *mut i32 = ptr::null_mut();
61pub static mut fpu_dp: *mut i32 = ptr::null_mut();
62pub static mut fpu_dp_selector: *mut i32 = ptr::null_mut();
63pub static mut tss_size_32: *mut bool = ptr::null_mut();
64pub static mut sse_scratch_register: *mut reg128 = ptr::null_mut();
65pub static mut fpu_st: *mut F80 = ptr::null_mut();
66
67#[inline]
68unsafe fn at<T>(base: *mut u8, offset: usize) -> *mut T {
69    base.add(offset) as *mut T
70}
71
72/// Initialize the v86 CPU state pointer table against a native allocation.
73/// The first 4 KiB must remain available for the scalar state layout.
74pub unsafe fn init(base: *mut u8) {
75    reg8 = at(base, 64);
76    reg16 = at(base, 64);
77    reg32 = at(base, 64);
78    last_op_size = at(base, 96);
79    flags_changed = at(base, 100);
80    last_op1 = at(base, 104);
81    state_flags = at(base, 108);
82    last_result = at(base, 112);
83    flags = at(base, 120);
84    segment_access_bytes = at(base, 512);
85    apic_enabled = at(base, 548);
86    acpi_enabled = at(base, 552);
87    instruction_pointer = at(base, 556);
88    previous_ip = at(base, 560);
89    idtr_size = at(base, 564);
90    idtr_offset = at(base, 568);
91    gdtr_size = at(base, 572);
92    gdtr_offset = at(base, 576);
93    cr = at(base, 580);
94    cpl = at(base, 612);
95    in_hlt = at(base, 616);
96    last_virt_eip = at(base, 620);
97    eip_phys = at(base, 624);
98    sysenter_cs = at(base, 636);
99    sysenter_esp = at(base, 640);
100    sysenter_eip = at(base, 644);
101    prefixes = at(base, 648);
102    instruction_counter = at(base, 664);
103    sreg = at(base, 668);
104    dreg = at(base, 684);
105    svga_dirty_bitmap_min_offset = at(base, 716);
106    svga_dirty_bitmap_max_offset = at(base, 720);
107    segment_is_null = at(base, 724);
108    segment_offsets = at(base, 736);
109    segment_limits = at(base, 768);
110    protected_mode = at(base, 800);
111    is_32 = at(base, 804);
112    stack_size_32 = at(base, 808);
113    memory_size = at(base, 812);
114    fpu_stack_empty = at(base, 816);
115    mxcsr = at(base, 824);
116    reg_xmm = at(base, 832);
117    current_tsc = at(base, 960);
118    reg_pdpte = at(base, 968);
119    fpu_stack_ptr = at(base, 1032);
120    fpu_control_word = at(base, 1036);
121    fpu_status_word = at(base, 1040);
122    fpu_opcode = at(base, 1044);
123    fpu_ip = at(base, 1048);
124    fpu_ip_selector = at(base, 1052);
125    fpu_dp = at(base, 1056);
126    fpu_dp_selector = at(base, 1060);
127    tss_size_32 = at(base, 1128);
128    sse_scratch_register = at(base, 1136);
129    fpu_st = at(base, 1152);
130}
131
132pub fn get_reg32_offset(r: u32) -> u32 {
133    dbg_assert!(r < 8);
134    unsafe { reg32.add(r as usize) as u32 }
135}
136
137pub fn get_reg_mmx_offset(r: u32) -> u32 {
138    dbg_assert!(r < 8);
139    unsafe { fpu_st.add(r as usize) as u32 }
140}
141
142pub fn get_reg_xmm_offset(r: u32) -> u32 {
143    dbg_assert!(r < 8);
144    unsafe { reg_xmm.add(r as usize) as u32 }
145}
146
147pub fn get_sreg_offset(s: u32) -> u32 {
148    dbg_assert!(s < 6);
149    unsafe { sreg.add(s as usize) as u32 }
150}
151
152pub fn get_seg_offset(s: u32) -> u32 {
153    dbg_assert!(s < 8);
154    unsafe { segment_offsets.add(s as usize) as u32 }
155}
156
157pub fn get_segment_is_null_offset(s: u32) -> u32 {
158    dbg_assert!(s < 8);
159    unsafe { segment_is_null.add(s as usize) as u32 }
160}
161
162pub fn get_creg_offset(i: u32) -> u32 {
163    dbg_assert!(i < 8);
164    unsafe { cr.add(i as usize) as u32 }
165}