OSDN Git Service

[VM] Add vm_template.h . This class, VM_TEMPLATE:: must be mother of VM:: .See fm7...
[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 void save_state(FILEIO* state_fio);
286         virtual bool load_state(FILEIO* state_fio);
287         virtual void decl_state(void);
288         
289         void write_signal(int id, uint32_t data, uint32_t mask);
290         void set_intr_line(bool line, bool pending, uint32_t bit)
291         {
292                 uint32_t mask = 1 << bit;
293                 intr_req_bit = line ? (intr_req_bit | mask) : (intr_req_bit & ~mask);
294                 intr_pend_bit = pending ? (intr_pend_bit | mask) : (intr_pend_bit & ~mask);
295                 if(line) irq_count++;
296         }
297         void set_extra_clock(int clock)
298         {
299                 extra_icount += clock;
300         }
301         int get_extra_clock()
302         {
303                 return extra_icount;
304         }
305         uint32_t get_pc()
306         {
307                 return prevpc;
308         }
309         uint32_t get_next_pc()
310         {
311                 return pc.w.l;
312         }
313 //#ifdef USE_DEBUGGER
314         void *get_debugger()
315         {
316                 return d_debugger;
317         }
318         uint32_t get_debug_prog_addr_mask()
319         {
320                 return 0xffff;
321         }
322         uint32_t get_debug_data_addr_mask()
323         {
324                 return 0xffff;
325         }
326         bool write_debug_reg(const _TCHAR *reg, uint32_t data);
327         void get_debug_regs_info(_TCHAR *buffer, size_t buffer_len);
328         virtual int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len);
329 //#endif
330         // unique functions
331         void set_context_mem(DEVICE* device)
332         {
333                 d_mem = device;
334         }
335         void set_context_io(DEVICE* device)
336         {
337                 d_io = device;
338         }
339         void set_context_intr(DEVICE* device)
340         {
341                 d_pic = device;
342         }
343         void set_context_busack(DEVICE* device, int id, uint32_t mask)
344         {
345                 register_output_signal(&outputs_busack, device, id, mask);
346         }
347         void set_pc(uint16_t value)
348         {
349                 pc.w.l = value;
350         }
351         void set_sp(uint16_t value)
352         {
353                 sp.w.l = value;
354         }
355 };
356
357 class Z80 : public Z80_BASE 
358 {
359 protected:
360         void check_interrupt();
361         void run_one_opecode() override;
362         void debugger_hook(void) override;
363 public:
364         Z80(VM_TEMPLATE* parent_vm, EMU* parent_emu);
365         ~Z80();
366         void initialize();
367         void reset();
368         int run(int clock) override;
369         void save_state(FILEIO* state_fio) override;
370         bool load_state(FILEIO* state_fio) override;
371         void decl_state(void) override;
372
373         int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len);
374 #ifdef USE_DEBUGGER
375         void write_debug_data8(uint32_t addr, uint32_t data);
376         uint32_t read_debug_data8(uint32_t addr);
377         void write_debug_io8(uint32_t addr, uint32_t data);
378         uint32_t read_debug_io8(uint32_t addr);
379 #endif
380 #ifdef Z80_PSEUDO_BIOS
381         void set_context_bios(DEVICE* device)
382         {
383                 d_bios = device;
384         }
385 #endif
386 #ifdef SINGLE_MODE_DMA
387         void set_context_dma(DEVICE* device)
388         {
389                 d_dma = device;
390         }
391 #endif
392 #ifdef USE_DEBUGGER
393         void set_context_debugger(DEBUGGER* device)
394         {
395                 d_debugger = device;
396         }
397 #endif
398 };
399
400
401 #endif
402