OSDN Git Service

[VM] Fix crash when end of emulation at various(!) VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / libcpu_newdev / i386.cpp
1
2
3 #include "vm.h"
4 #include "../emu.h"
5 #include "./i386.h"
6 #include "./libcpu_i386/i386_real.h"
7 #ifdef USE_DEBUGGER
8 #include "debugger.h"
9 #endif
10
11 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
12 #pragma warning( disable : 4018 )
13 #pragma warning( disable : 4065 )
14 #pragma warning( disable : 4146 )
15 #pragma warning( disable : 4244 )
16 #pragma warning( disable : 4996 )
17 #endif
18
19 #if defined(HAS_I386)
20         #define CPU_MODEL i386
21 #elif defined(HAS_I486)
22         #define CPU_MODEL i486
23 #elif defined(HAS_PENTIUM)
24         #define CPU_MODEL pentium
25 #elif defined(HAS_MEDIAGX)
26         #define CPU_MODEL mediagx
27 #elif defined(HAS_PENTIUM_PRO)
28         #define CPU_MODEL pentium_pro
29 #elif defined(HAS_PENTIUM_MMX)
30         #define CPU_MODEL pentium_mmx
31 #elif defined(HAS_PENTIUM2)
32         #define CPU_MODEL pentium2
33 #elif defined(HAS_PENTIUM3)
34         #define CPU_MODEL pentium3
35 #elif defined(HAS_PENTIUM4)
36         #define CPU_MODEL pentium4
37 #endif
38
39 void I386::initialize()
40 {
41         DEVICE::initialize();
42         cpucore = new I386_OPS;
43 #if defined(HAS_I386)
44         cpucore->cpu_init_i386();
45 #elif defined(HAS_I486)
46         cpucore->cpu_init_i486();
47 #elif defined(HAS_PENTIUM)
48         cpucore->cpu_init_pentium();
49 #elif defined(HAS_MEDIAGX)
50         cpucore->cpu_init_mediagx();
51 #elif defined(HAS_PENTIUM_PRO)
52         cpucore->cpu_init_pentium_pro();
53 #elif defined(HAS_PENTIUM_MMX)
54         cpucore->cpu_init_pentium_mmx();
55 #elif defined(HAS_PENTIUM2)
56         cpucore->cpu_init_pentium2();
57 #elif defined(HAS_PENTIUM3)
58         cpucore->cpu_init_pentium3();
59 #elif defined(HAS_PENTIUM4)
60         cpucore->cpu_init_pentium4();
61 #endif
62         cpucore->set_context_pic(d_pic);
63         cpucore->set_context_progmem(d_mem);
64         cpucore->set_context_io(d_io);
65 #ifdef I386_PSEUDO_BIOS
66         cpucore->set_context_pseudo_bios(d_bios);
67 #endif
68 #ifdef SINGLE_MODE_DMA
69         cpucore->set_context_dma(d_dma);
70 #endif
71         
72 #ifdef USE_DEBUGGER
73         cpucore->set_context_emu(emu);
74         cpucore->set_context_debugger(d_debugger);
75         cpucore->set_context_progmem_stored(d_mem);
76         cpucore->set_context_io_stored(d_io);
77         
78         d_debugger->set_context_mem(d_mem);
79         d_debugger->set_context_io(d_io);
80 #endif
81         cpucore->set_shutdown_flag(0);
82 }
83
84 void I386::reset()
85 {
86 #if defined(HAS_I386)
87         cpucore->cpu_reset_i386();
88 #elif defined(HAS_I486)
89         cpucore->cpu_reset_i486();
90 #elif defined(HAS_PENTIUM)
91         cpucore->cpu_reset_pentium();
92 #elif defined(HAS_MEDIAGX)
93         cpucore->cpu_reset_mediagx();
94 #elif defined(HAS_PENTIUM_PRO)
95         cpucore->cpu_reset_pentium_pro();
96 #elif defined(HAS_PENTIUM_MMX)
97         cpucore->cpu_reset_pentium_mmx();
98 #elif defined(HAS_PENTIUM2)
99         cpucore->cpu_reset_pentium2();
100 #elif defined(HAS_PENTIUM3)
101         cpucore->cpu_reset_pentium3();
102 #elif defined(HAS_PENTIUM4)
103         cpucore->cpu_reset_pentium4();
104 #endif
105 }
106
107 int I386::run(int cycles)
108 {
109         return cpucore->cpu_execute_i386(cycles);
110 }
111
112
113 #ifdef USE_DEBUGGER
114 void I386::write_debug_data8(uint32_t addr, uint32_t data)
115 {
116         int wait;
117         d_mem->write_data8w(addr, data, &wait);
118 }
119
120 uint32_t I386::read_debug_data8(uint32_t addr)
121 {
122         int wait;
123         return d_mem->read_data8w(addr, &wait);
124 }
125
126 void I386::write_debug_data16(uint32_t addr, uint32_t data)
127 {
128         int wait;
129         d_mem->write_data16w(addr, data, &wait);
130 }
131
132 uint32_t I386::read_debug_data16(uint32_t addr)
133 {
134         int wait;
135         return d_mem->read_data16w(addr, &wait);
136 }
137
138 void I386::write_debug_data32(uint32_t addr, uint32_t data)
139 {
140         int wait;
141         d_mem->write_data32w(addr, data, &wait);
142 }
143
144 uint32_t I386::read_debug_data32(uint32_t addr)
145 {
146         int wait;
147         return d_mem->read_data32w(addr, &wait);
148 }
149
150 void I386::write_debug_io8(uint32_t addr, uint32_t data)
151 {
152         int wait;
153         d_io->write_io8w(addr, data, &wait);
154 }
155
156 uint32_t I386::read_debug_io8(uint32_t addr) {
157         int wait;
158         return d_io->read_io8w(addr, &wait);
159 }
160
161 void I386::write_debug_io16(uint32_t addr, uint32_t data)
162 {
163         int wait;
164         d_io->write_io16w(addr, data, &wait);
165 }
166
167 uint32_t I386::read_debug_io16(uint32_t addr) {
168         int wait;
169         return d_io->read_io16w(addr, &wait);
170 }
171
172 void I386::write_debug_io32(uint32_t addr, uint32_t data)
173 {
174         int wait;
175         d_io->write_io32w(addr, data, &wait);
176 }
177
178 uint32_t I386::read_debug_io32(uint32_t addr) {
179         int wait;
180         return d_io->read_io32w(addr, &wait);
181 }
182
183 bool I386::write_debug_reg(const _TCHAR *reg, uint32_t data)
184 {
185         return cpucore->write_debug_reg(reg, data);
186 }
187
188 uint32_t I386::read_debug_reg(const _TCHAR *reg)
189 {
190         return cpucore->read_debug_reg(reg);
191 }
192
193 bool I386::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
194 {
195         i386_state *cpustate = cpucore->get_cpu_state();
196         my_stprintf_s(buffer, buffer_len,
197         _T("AX=%04X  BX=%04X CX=%04X DX=%04X SP=%04X  BP=%04X  SI=%04X  DI=%04X\n")
198         _T("DS=%04X  ES=%04X SS=%04X CS=%04X IP=%04X  FLAG=[%c%c%c%c%c%c%c%c%c]\n")
199         _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"),
200         REG16(AX), REG16(BX), REG16(CX), REG16(DX), REG16(SP), REG16(BP), REG16(SI), REG16(DI),
201         cpustate->sreg[DS].selector, cpustate->sreg[ES].selector, cpustate->sreg[SS].selector, cpustate->sreg[CS].selector, cpustate->eip,
202         cpustate->OF ? _T('O') : _T('-'), cpustate->DF ? _T('D') : _T('-'), cpustate->IF ? _T('I') : _T('-'), cpustate->TF ? _T('T') : _T('-'),
203         cpustate->SF ? _T('S') : _T('-'), cpustate->ZF ? _T('Z') : _T('-'), cpustate->AF ? _T('A') : _T('-'), cpustate->PF ? _T('P') : _T('-'), cpustate->CF ? _T('C') : _T('-'),
204         cpustate->total_cycles, cpustate->total_cycles - cpustate->prev_total_cycles,
205         get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame());
206         cpustate->prev_total_cycles = cpustate->total_cycles;
207         return true;
208 }
209
210 int I386::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
211 {
212         return cpucore->debug_dasm(pc, buffer, buffer_len);
213 }
214 #endif
215
216 void I386::set_context_bios(DEVICE* device)
217 {
218 #ifdef I386_PSEUDO_BIOS
219         d_bios = device;
220         if(cpucore != NULL) cpucore->set_context_pseudo_bios(d_bios);
221 #endif
222 }
223 void I386::set_context_dma(DEVICE* device)
224 {
225 #ifdef SINGLE_MODE_DMA
226         d_dma = device;
227         if(cpucore != NULL) cpucore->set_context_dma(d_dma);
228 #endif
229 }
230
231 #ifdef USE_DEBUGGER
232 void I386::set_context_debugger(DEBUGGER* device)
233 {
234         d_debugger = device;
235         if(cpucore != NULL) {
236                 cpucore->set_context_emu(emu);
237                 cpucore->set_context_debugger(d_debugger);
238                 cpucore->set_context_progmem_stored(d_mem);
239                 cpucore->set_context_io_stored(d_io);
240         }
241 }
242 #endif
243
244
245
246 bool I386::process_state(FILEIO* state_fio, bool loading)
247 {
248         i386_state *cpustate = cpucore->get_cpu_state();
249         if(!(I386_BASE::process_state(state_fio, loading))) return false;
250 //      if(save != NULL && save_size > 0) {
251 //              state_fio->StateBuffer(save, save_size, 1);
252 //      }
253
254  #ifdef USE_DEBUGGER
255         // post process
256         if(loading) {
257                 cpustate->prev_total_cycles = cpustate->total_cycles;
258         }
259 #endif
260         return true;
261 }