OSDN Git Service

[VM][WIP] Merging upstream 2022-09-09.Still be imcompleted.
[csp-qt/common_source_project-fm7.git] / source / src / vm / i386_np21.h
1 /*
2         Skelton for retropc emulator
3
4         Origin : np21/w i386c core
5         Author : Takeda.Toshiya
6         Date   : 2020.01.25-
7
8         [ i386/i486/Pentium ]
9 */
10
11 #ifndef _I386_NP21_H_
12 #define _I386_NP21_H_
13
14 #include "vm_template.h"
15 //#include "../emu.h"
16 #include "device.h"
17
18 #define SIG_I386_A20            1
19 #define SIG_I386_NOTIFY_RESET   2
20
21 #define I386_TRACE_DATA_BIT_USERDATA_SET        0x80000000
22 #define I386_TRACE_DATA_BIT_OP32                        0x00000001
23 #define I386_TRACE_DATA_BIT_RET                         0x00000040
24 #define I386_TRACE_DATA_BIT_RETF                        0x00000050
25 #define I386_TRACE_DATA_BIT_IRET                        0x00000060
26 #define I386_TRACE_DATA_BIT_JMP                         0x00000080
27 #define I386_TRACE_DATA_BIT_JMP_COND            0x00000090
28 #define I386_TRACE_DATA_BIT_CALL                        0x00000100
29 #define I386_TRACE_DATA_BIT_INT                         0x10000000
30 #define I386_TRACE_DATA_BIT_IRQ                         0x20000000
31 #define I386_TRACE_DATA_BIT_EXCEPTION           0x40000000
32
33 enum {
34         DEFAULT = -1,
35         INTEL_80386 = 0,
36         INTEL_I486SX,
37         INTEL_I486DX,
38         INTEL_PENTIUM,
39         INTEL_MMX_PENTIUM,
40         INTEL_PENTIUM_PRO,
41         INTEL_PENTIUM_II,
42         INTEL_PENTIUM_III,
43         INTEL_PENTIUM_M,
44         INTEL_PENTIUM_4,
45         AMD_K6_2,
46         AMD_K6_III,
47         AMD_K7_ATHLON,
48         AMD_K7_ATHLON_XP,
49 };
50
51 //#ifdef USE_DEBUGGER
52 class DEBUGGER;
53 //#endif
54 class  DLL_PREFIX I386 : public DEVICE
55 {
56 private:
57         DEVICE *device_pic;
58         outputs_t outputs_extreset;
59
60 //#ifdef USE_DEBUGGER
61 //      DEBUGGER *device_debugger;
62         DEVICE *device_mem_stored;
63         DEVICE *device_io_stored;
64         uint64_t total_cycles;
65         uint64_t prev_total_cycles;
66 //#endif
67         int remained_cycles, extra_cycles;
68         bool busreq;
69         bool nmi_pending, irq_pending;
70         uint32_t PREV_CS_BASE;
71         uint32_t waitfactor;
72         int64_t waitcount;
73
74         bool _USE_DEBUGGER;
75         bool _I86_PSEUDO_BIOS;
76         bool _SINGLE_MODE_DMA;
77         uint32_t address_mask;
78
79         int run_one_opecode();
80         uint32_t __FASTCALL convert_address(uint32_t cs, uint32_t eip);
81         inline void __FASTCALL cpu_wait(int clocks, int64_t& memory_wait);
82
83 public:
84         I386(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu)
85         {
86 //#ifdef USE_DEBUGGER
87                 total_cycles = prev_total_cycles = 0;
88 //#endif
89                 busreq = false;
90                 initialize_output_signals(&outputs_extreset);
91                 _USE_DEBUGGER = false;
92                 _I86_PSEUDO_BIOS = false;
93                 _SINGLE_MODE_DMA = false;
94                 address_mask = 0x000fffff; // OK?
95                 device_model = DEFAULT;
96         }
97         ~I386() {}
98
99         // common functions
100         void initialize();
101         void release();
102         void reset();
103         int __FASTCALL run(int cycles);
104         void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask);
105         void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit);
106         void __FASTCALL set_extra_clock(int cycles);
107         int get_extra_clock();
108         uint32_t get_pc();
109         uint32_t get_next_pc();
110 //#ifdef USE_DEBUGGER
111         bool is_cpu()
112         {
113                 return true;
114         }
115         bool is_debugger_available()
116         {
117                 return true;
118         }
119         void *get_debugger();
120 //      {
121 //              return device_debugger;
122 //      }
123         uint32_t get_debug_prog_addr_mask()
124         {
125                 return 0xffffffff;
126         }
127         uint32_t get_debug_data_addr_mask()
128         {
129                 return 0xffffffff;
130         }
131         void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data);
132         uint32_t __FASTCALL read_debug_data8(uint32_t addr);
133         void __FASTCALL write_debug_data16(uint32_t addr, uint32_t data);
134         uint32_t __FASTCALL read_debug_data16(uint32_t addr);
135         void __FASTCALL write_debug_data32(uint32_t addr, uint32_t data);
136         uint32_t __FASTCALL read_debug_data32(uint32_t addr);
137         void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data);
138         uint32_t __FASTCALL read_debug_io8(uint32_t addr);
139         void __FASTCALL write_debug_io16(uint32_t addr, uint32_t data);
140         uint32_t __FASTCALL read_debug_io32(uint32_t addr);
141         void __FASTCALL write_debug_io32(uint32_t addr, uint32_t data);
142         uint32_t __FASTCALL read_debug_io16(uint32_t addr);
143         virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data);
144         uint32_t __FASTCALL read_debug_reg(const _TCHAR *reg);
145         virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len);
146         virtual bool get_debug_regs_description(_TCHAR *buffer, size_t buffer_len);
147         int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0);
148         virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0);
149 //#endif
150         bool process_state(FILEIO* state_fio, bool loading);
151
152         // unique function
153         void set_context_mem(DEVICE* device);
154 //      {
155 //              device_mem = device;
156 //      }
157         void set_context_io(DEVICE* device);
158 //      {
159 //              device_io = device;
160 //      }
161         void set_context_intr(DEVICE* device, uint32_t bit = 0xffffffff);
162 //#ifdef I386_PSEUDO_BIOS
163         void set_context_bios(DEVICE* device);
164 //      {
165 //              device_bios = device;
166 //      }
167 //#endif
168 //#ifdef SINGLE_MODE_DMA
169         void set_context_dma(DEVICE* device);
170 //      {
171 //              device_dma = device;
172 //      }
173 //#endif
174 //#ifdef USE_DEBUGGER
175         void set_context_debugger(DEBUGGER* device);
176 //#endif
177         void set_context_extreset(DEVICE *dev, int id, uint32_t mask)
178         {
179                 register_output_signal(&outputs_extreset, dev, id, mask);
180         }
181         bool check_interrupts();
182
183         void set_address_mask(uint32_t mask);
184         uint32_t get_address_mask();
185         void set_shutdown_flag(int shutdown);
186         int get_shutdown_flag();
187         // These is using from NP21 core.
188         int64_t i386_memory_wait;
189         uint32_t realclock;
190         int device_model;
191 };
192
193 inline void __FASTCALL I386::cpu_wait(int clocks, int64_t& memory_wait)
194 {
195         __UNLIKELY_IF(clocks < 0) {
196                 return;
197         }
198         __LIKELY_IF(waitfactor <= 65536) {
199                 return;
200         }
201         int64_t wfactor = waitfactor;
202         int64_t wcount = waitcount;
203         int64_t mwait = memory_wait;
204         int64_t ncount;
205         __UNLIKELY_IF(wfactor > 65536) {
206                 wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock.
207                 wcount += (wfactor * mwait);  // memory wait
208         } else {
209                 wcount += (mwait << 16);
210         }
211         __LIKELY_IF(wcount >= 65536) {
212                 ncount = wcount >> 16;
213                 wcount = wcount - (ncount << 16);
214                 extra_cycles += (int)ncount;
215         } else __UNLIKELY_IF(wcount < 0) {
216                 wcount = 0;
217         }
218         waitcount = wcount;
219         memory_wait = 0;
220 }
221
222 #endif