libscemu/emu/
context32.rs

1use crate::emu::fpu::FPU;
2use crate::emu::maps::Maps;
3use crate::emu::regs64::Regs64;
4
5pub struct Context32 {
6    ctx_flags: u32,
7    dr0: u32,
8    dr1: u32,
9    dr2: u32,
10    dr3: u32,
11    dr6: u32,
12    dr7: u32,
13    fpu: FPU,
14    seg_gs: u32,
15    seg_fd: u32,
16    seg_es: u32,
17    seg_ds: u32,
18    edi: u32,    // +9c
19    esi: u32,    // +a0
20    ebx: u32,    // +a4
21    edx: u32,    // +a8
22    ecx: u32,    // +ac
23    eax: u32,    // +b0
24    ebp: u32,    // +b4
25    eip: u32,    // +b8
26    seg_cs: u32, // +bc
27    eflags: u32, // +c0
28    esp: u32,    // +c4
29    seg_ss: u32,
30}
31
32impl Context32 {
33    pub fn new(regs: &Regs64) -> Context32 {
34        Context32 {
35            ctx_flags: 0,
36            dr0: 0,
37            dr1: 0,
38            dr2: 0,
39            dr3: 0,
40            dr6: 0,
41            dr7: 0,
42            fpu: FPU::new(),
43            seg_gs: 0,
44            seg_fd: 0,
45            seg_es: 0,
46            seg_ds: 0,
47            edi: regs.get_edi() as u32,
48            esi: regs.get_esi() as u32,
49            ebx: regs.get_ebx() as u32,
50            edx: regs.get_edx() as u32,
51            ecx: regs.get_ecx() as u32,
52            eax: regs.get_eax() as u32,
53            ebp: regs.get_ebp() as u32,
54            eip: regs.get_eip() as u32,
55            seg_cs: 0,
56            eflags: 0,
57            esp: regs.get_esp() as u32,
58            seg_ss: 0,
59        }
60    }
61
62    pub fn save(&self, addr: u32, maps: &mut Maps) {
63        maps.write_dword((addr + 4) as u64, self.dr0);
64        maps.write_dword((addr + 8) as u64, self.dr1);
65        maps.write_dword((addr + 12) as u64, self.dr2);
66        maps.write_dword((addr + 16) as u64, self.dr3);
67        maps.write_dword((addr + 20) as u64, self.dr6);
68        maps.write_dword((addr + 24) as u64, self.dr7);
69
70        maps.write_dword((addr + 0x9c) as u64, self.edi);
71        maps.write_dword((addr + 0xa0) as u64, self.esi);
72        maps.write_dword((addr + 0xa4) as u64, self.ebx);
73        maps.write_dword((addr + 0xa8) as u64, self.edx);
74        maps.write_dword((addr + 0xac) as u64, self.ecx);
75        maps.write_dword((addr + 0xb0) as u64, self.eax);
76        maps.write_dword((addr + 0xb4) as u64, self.ebp);
77        maps.write_dword((addr + 0xb8) as u64, self.eip);
78        maps.write_dword((addr + 0xc4) as u64, self.esp);
79    }
80
81    pub fn load(&mut self, addr: u32, maps: &mut Maps) {
82        self.dr0 = maps
83            .read_dword((addr + 4) as u64)
84            .expect("cannot read dr0 from ctx");
85        self.dr1 = maps
86            .read_dword((addr + 8) as u64)
87            .expect("cannot read dr1 from ctx");
88        self.dr2 = maps
89            .read_dword((addr + 12) as u64)
90            .expect("cannot read dr2 from ctx");
91        self.dr3 = maps
92            .read_dword((addr + 16) as u64)
93            .expect("cannot read dr3 from ctx");
94        self.dr6 = maps
95            .read_dword((addr + 20) as u64)
96            .expect("cannot read dr6 from ctx");
97        self.dr7 = maps
98            .read_dword((addr + 24) as u64)
99            .expect("cannot read dr7 from ctx");
100
101        self.edi = maps
102            .read_dword((addr + 0x9c) as u64)
103            .expect("cannot read edi from ctx");
104        self.esi = maps
105            .read_dword((addr + 0xa0) as u64)
106            .expect("cannot read esi from ctx");
107        self.ebx = maps
108            .read_dword((addr + 0xa4) as u64)
109            .expect("cannot read ebx from ctx");
110        self.edx = maps
111            .read_dword((addr + 0xa8) as u64)
112            .expect("cannot read edx from ctx");
113        self.ecx = maps
114            .read_dword((addr + 0xac) as u64)
115            .expect("cannot read ecx from ctx");
116        self.eax = maps
117            .read_dword((addr + 0xb0) as u64)
118            .expect("cannot read eax from ctx");
119        self.ebp = maps
120            .read_dword((addr + 0xb4) as u64)
121            .expect("cannot read ebp from ctx");
122        self.eip = maps
123            .read_dword((addr + 0xb8) as u64)
124            .expect("cannot read eip from ctx");
125        self.esp = maps
126            .read_dword((addr + 0xc4) as u64)
127            .expect("cannot read esp from ctx");
128    }
129
130    pub fn sync(&self, regs: &mut Regs64) {
131        regs.set_eax(self.eax as u64);
132        regs.set_ebx(self.ebx as u64);
133        regs.set_ecx(self.ecx as u64);
134        regs.set_edx(self.edx as u64);
135        regs.set_esi(self.esi as u64);
136        regs.set_edi(self.edi as u64);
137        regs.set_esp(self.esp as u64);
138        regs.set_ebp(self.ebp as u64);
139        regs.set_eip(self.eip as u64);
140    }
141}