OSDN Git Service

[VM][STATE] Apply new framework to some VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / z80.h
1 /*
2         Skelton for retropc emulator
3
4         Origin : MAME 0.145
5         Author : Takeda.Toshiya
6         Date   : 2012.02.15-
7
8         [ Z80 ]
9 */
10
11 #ifndef _Z80_H_ 
12 #define _Z80_H_
13
14 #include "device.h"
15
16 //#ifdef HAS_NSC800
17 #define SIG_NSC800_INT  0
18 #define SIG_NSC800_RSTA 1
19 #define SIG_NSC800_RSTB 2
20 #define SIG_NSC800_RSTC 3
21 //#endif
22 //#if defined(USE_SHARED_DLL) || defined(USE_QT)
23 #define Z80_INLINE
24 //#else
25 //#define Z80_INLINE inline
26 //#endif
27 //#ifdef USE_DEBUGGER
28 class DEBUGGER;
29 //#endif
30 class csp_state_utils;
31 class Z80_BASE : public DEVICE
32 {
33 protected:
34         /* ---------------------------------------------------------------------------
35         contexts
36         --------------------------------------------------------------------------- */
37         
38         DEVICE *d_mem, *d_io, *d_pic;
39 //#ifdef Z80_PSEUDO_BIOS
40         DEVICE *d_bios;
41 //#endif
42 //#ifdef SINGLE_MODE_DMA
43         DEVICE *d_dma;
44 //#endif
45 //#ifdef USE_DEBUGGER
46         DEBUGGER *d_debugger;
47         DEVICE *d_mem_stored, *d_io_stored;
48 //#endif
49         outputs_t outputs_busack;
50
51         bool has_nsc800;
52         bool has_memory_wait;
53         bool has_io_wait;
54         bool has_pseudo_bios;
55         bool has_ldair_quirk;
56         bool has_single_mode_dma;
57         bool flags_initialized;
58         
59         
60         /* ---------------------------------------------------------------------------
61         registers
62         --------------------------------------------------------------------------- */
63         
64         uint64_t total_icount;
65         uint64_t prev_total_icount;
66         int icount;
67         int extra_icount;
68         uint16_t prevpc;
69         pair_t pc, sp, af, bc, de, hl, ix, iy, wz;
70         pair_t af2, bc2, de2, hl2;
71         uint8_t I, R, R2;
72         uint32_t ea;
73         
74         bool busreq, after_halt;
75         uint8_t im, iff1, iff2, icr;
76         bool after_ei, after_ldair;
77         uint32_t intr_req_bit, intr_pend_bit;
78         
79         Z80_INLINE uint8_t RM8(uint32_t addr);
80         Z80_INLINE void WM8(uint32_t addr, uint8_t val);
81         Z80_INLINE void RM16(uint32_t addr, pair_t *r);
82         Z80_INLINE void WM16(uint32_t addr, pair_t *r);
83         Z80_INLINE uint8_t FETCHOP();
84         Z80_INLINE uint8_t FETCH8();
85         Z80_INLINE uint32_t FETCH16();
86         Z80_INLINE uint8_t IN8(uint32_t addr);
87         Z80_INLINE void OUT8(uint32_t addr, uint8_t val);
88         
89         Z80_INLINE uint8_t INC(uint8_t value);
90         Z80_INLINE uint8_t DEC(uint8_t value);
91         
92         Z80_INLINE uint8_t RLC(uint8_t value);
93         Z80_INLINE uint8_t RRC(uint8_t value);
94         Z80_INLINE uint8_t RL(uint8_t value);
95         Z80_INLINE uint8_t RR(uint8_t value);
96         Z80_INLINE uint8_t SLA(uint8_t value);
97         Z80_INLINE uint8_t SRA(uint8_t value);
98         Z80_INLINE uint8_t SLL(uint8_t value);
99         Z80_INLINE uint8_t SRL(uint8_t value);
100         
101         Z80_INLINE uint8_t RES(uint8_t bit, uint8_t value);
102         Z80_INLINE uint8_t SET(uint8_t bit, uint8_t value);
103         
104         void OP_CB(uint8_t code);
105         void OP_XY(uint8_t code);
106         void OP_DD(uint8_t code);
107         void OP_FD(uint8_t code);
108         void OP_ED(uint8_t code);
109         void OP(uint8_t code);
110         virtual void run_one_opecode();
111         virtual void debugger_hook(void);
112         
113         uint8_t SZ[256];                /* zero and sign flags */
114         uint8_t SZ_BIT[256];    /* zero, sign and parity/overflow (=zero) flags for BIT opcode */
115         uint8_t SZP[256];               /* zero, sign and parity flags */
116         uint8_t SZHV_inc[256];  /* zero, sign, half carry and overflow flags INC r8 */
117         uint8_t SZHV_dec[256];  /* zero, sign, half carry and overflow flags DEC r8 */
118
119         uint8_t SZHVC_add[2 * 256 * 256];
120         uint8_t SZHVC_sub[2 * 256 * 256];
121
122         const uint8_t cc_op[0x100] = {
123                 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4,
124                 8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4,
125                 7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4,
126                 7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4,
127                 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
128                 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
129                 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
130                 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4,
131                 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
132                 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
133                 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
134                 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
135                 5,10,10,10,10,11, 7,11, 5,10,10, 0,10,17, 7,11,
136                 5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 0, 7,11,
137                 5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 0, 7,11,
138                 5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11
139         };
140
141          const uint8_t cc_cb[0x100] = {
142                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
143                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
144                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
145                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
146                 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
147                 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
148                 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
149                 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
150                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
151                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
152                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
153                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
154                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
155                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
156                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
157                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8
158         };
159         
160          const uint8_t cc_ed[0x100] = {
161                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
162                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
163                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
164                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
165                 12,12,15,20, 8,14, 8, 9,12,12,15,20, 8,14, 8, 9,
166                 12,12,15,20, 8,14, 8, 9,12,12,15,20, 8,14, 8, 9,
167                 12,12,15,20, 8,14, 8,18,12,12,15,20, 8,14, 8,18,
168                 12,12,15,20, 8,14, 8, 8,12,12,15,20, 8,14, 8, 8,
169                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
170                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
171                 16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8,
172                 16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8,
173                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
174                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
175                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
176                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
177         };
178         
179          const uint8_t cc_xy[0x100] = {
180                 4, 4, 4, 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4,
181                 4, 4, 4, 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4,
182                 4,14,20,10, 9, 9,11, 4, 4,15,20,10, 9, 9,11, 4,
183                 4, 4, 4, 4,23,23,19, 4, 4,15, 4, 4, 4, 4, 4, 4,
184                 4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
185                 4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
186                 9, 9, 9, 9, 9, 9,19, 9, 9, 9, 9, 9, 9, 9,19, 9,
187                 19,19,19,19,19,19, 4,19, 4, 4, 4, 4, 9, 9,19, 4,
188                 4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
189                 4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
190                 4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
191                 4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
192                 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4,
193                 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
194                 4,14, 4,23, 4,15, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4,
195                 4, 4, 4, 4, 4, 4, 4, 4, 4,10, 4, 4, 4, 4, 4, 4
196         };
197
198          const uint8_t cc_xycb[0x100] = {
199                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
200                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
201                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
202                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
203                 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
204                 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
205                 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
206                 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
207                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
208                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
209                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
210                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
211                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
212                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
213                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
214                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23
215         };
216         
217         const uint8_t cc_ex[0x100] = {
218                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
219                 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DJNZ */
220                 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NZ/JR Z */
221                 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NC/JR C */
222                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
223                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
225                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
226                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
227                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
228                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
229                 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */
230                 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
231                 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
232                 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
233                 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2
234         };
235
236         /* ---------------------------------------------------------------------------
237         debug
238         --------------------------------------------------------------------------- */
239         // Collect counters
240         uint64_t cycles_tmp_count;
241         uint64_t extra_tmp_count;
242         uint32_t insns_count;
243         int frames_count;
244         int nmi_count;
245         int     irq_count;
246         int     nsc800_int_count;
247         int     nsc800_rsta_count;
248         int     nsc800_rstb_count;
249         int     nsc800_rstc_count;
250
251 public:
252         Z80_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
253         {
254                 flags_initialized = false;
255                 busreq = false;
256 //#ifdef Z80_PSEUDO_BIOS
257                 d_bios = NULL;
258 //#endif
259 //#ifdef SINGLE_MODE_DMA
260                 d_dma = NULL;
261 //#endif
262                 d_debugger = NULL;
263                 d_mem_stored = NULL;
264                 d_io_stored = NULL;
265                 d_pic = NULL;
266                 has_nsc800 = false;
267                 has_io_wait = false;
268                 has_memory_wait = false;
269                 has_pseudo_bios = false;
270                 has_ldair_quirk = false;
271                 has_single_mode_dma = false;
272                 total_icount = prev_total_icount = 0;
273                 initialize_output_signals(&outputs_busack);
274                 set_device_name(_T("Z80 CPU"));
275
276         }
277         ~Z80_BASE() {}
278         
279         // common functions
280         virtual void initialize();
281         virtual void reset();
282         void event_frame();
283         int run(int clock);
284
285         virtual bool process_state(FILEIO* state_fio, bool loading);
286         
287         void write_signal(int id, uint32_t data, uint32_t mask);
288         void set_intr_line(bool line, bool pending, uint32_t bit)
289         {
290                 uint32_t mask = 1 << bit;
291                 intr_req_bit = line ? (intr_req_bit | mask) : (intr_req_bit & ~mask);
292                 intr_pend_bit = pending ? (intr_pend_bit | mask) : (intr_pend_bit & ~mask);
293                 if(line) irq_count++;
294         }
295         void set_extra_clock(int clock)
296         {
297                 extra_icount += clock;
298         }
299         int get_extra_clock()
300         {
301                 return extra_icount;
302         }
303         uint32_t get_pc()
304         {
305                 return prevpc;
306         }
307         uint32_t get_next_pc()
308         {
309                 return pc.w.l;
310         }
311 //#ifdef USE_DEBUGGER
312         void *get_debugger()
313         {
314                 return d_debugger;
315         }
316         uint32_t get_debug_prog_addr_mask()
317         {
318                 return 0xffff;
319         }
320         uint32_t get_debug_data_addr_mask()
321         {
322                 return 0xffff;
323         }
324         bool write_debug_reg(const _TCHAR *reg, uint32_t data);
325         void get_debug_regs_info(_TCHAR *buffer, size_t buffer_len);
326         virtual int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len);
327 //#endif
328         // unique functions
329         void set_context_mem(DEVICE* device)
330         {
331                 d_mem = device;
332         }
333         void set_context_io(DEVICE* device)
334         {
335                 d_io = device;
336         }
337         void set_context_intr(DEVICE* device)
338         {
339                 d_pic = device;
340         }
341         void set_context_busack(DEVICE* device, int id, uint32_t mask)
342         {
343                 register_output_signal(&outputs_busack, device, id, mask);
344         }
345         void set_pc(uint16_t value)
346         {
347                 pc.w.l = value;
348         }
349         void set_sp(uint16_t value)
350         {
351                 sp.w.l = value;
352         }
353 };
354
355 class Z80 : public Z80_BASE 
356 {
357 protected:
358         void check_interrupt();
359         void run_one_opecode() override;
360         void debugger_hook(void) override;
361 public:
362         Z80(VM_TEMPLATE* parent_vm, EMU* parent_emu);
363         ~Z80();
364         void initialize();
365         void reset();
366         int run(int clock) override;
367
368         int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len);
369 #ifdef USE_DEBUGGER
370         void write_debug_data8(uint32_t addr, uint32_t data);
371         uint32_t read_debug_data8(uint32_t addr);
372         void write_debug_io8(uint32_t addr, uint32_t data);
373         uint32_t read_debug_io8(uint32_t addr);
374 #endif
375 #ifdef Z80_PSEUDO_BIOS
376         void set_context_bios(DEVICE* device)
377         {
378                 d_bios = device;
379         }
380 #endif
381 #ifdef SINGLE_MODE_DMA
382         void set_context_dma(DEVICE* device)
383         {
384                 d_dma = device;
385         }
386 #endif
387 #ifdef USE_DEBUGGER
388         void set_context_debugger(DEBUGGER* device)
389         {
390                 d_debugger = device;
391         }
392 #endif
393 };
394
395
396 #endif
397