2 Skelton for retropc emulator
4 Origin : np21/w i386c core
5 Author : Takeda.Toshiya
14 #include "vm_template.h"
18 #define SIG_I386_A20 1
19 #define SIG_I386_NOTIFY_RESET 2
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
54 class DLL_PREFIX I386 : public DEVICE
58 outputs_t outputs_extreset;
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;
67 int remained_cycles, extra_cycles;
69 bool nmi_pending, irq_pending;
70 uint32_t PREV_CS_BASE;
75 bool _I86_PSEUDO_BIOS;
76 bool _SINGLE_MODE_DMA;
77 uint32_t address_mask;
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);
84 I386(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu)
87 total_cycles = prev_total_cycles = 0;
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;
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();
109 uint32_t get_next_pc();
110 //#ifdef USE_DEBUGGER
115 bool is_debugger_available()
119 void *get_debugger();
121 // return device_debugger;
123 uint32_t get_debug_prog_addr_mask()
127 uint32_t get_debug_data_addr_mask()
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);
150 bool process_state(FILEIO* state_fio, bool loading);
153 void set_context_mem(DEVICE* device);
155 // device_mem = device;
157 void set_context_io(DEVICE* device);
159 // device_io = device;
161 void set_context_intr(DEVICE* device, uint32_t bit = 0xffffffff);
162 //#ifdef I386_PSEUDO_BIOS
163 void set_context_bios(DEVICE* device);
165 // device_bios = device;
168 //#ifdef SINGLE_MODE_DMA
169 void set_context_dma(DEVICE* device);
171 // device_dma = device;
174 //#ifdef USE_DEBUGGER
175 void set_context_debugger(DEBUGGER* device);
177 void set_context_extreset(DEVICE *dev, int id, uint32_t mask)
179 register_output_signal(&outputs_extreset, dev, id, mask);
181 bool check_interrupts();
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;
193 inline void __FASTCALL I386::cpu_wait(int clocks, int64_t& memory_wait)
195 __UNLIKELY_IF(clocks < 0) {
198 __LIKELY_IF(waitfactor <= 65536) {
201 int64_t wfactor = waitfactor;
202 int64_t wcount = waitcount;
203 int64_t mwait = memory_wait;
205 __UNLIKELY_IF(wfactor > 65536) {
206 wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock.
207 wcount += (wfactor * mwait); // memory wait
209 wcount += (mwait << 16);
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) {