OSDN Git Service

[General] Completely merge upstream 2019-01-11.
[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 Z80_BASE : public DEVICE
31 {
32 protected:
33         /* ---------------------------------------------------------------------------
34         contexts
35         --------------------------------------------------------------------------- */
36         
37         DEVICE *d_mem, *d_io, *d_pic;
38 //#ifdef Z80_PSEUDO_BIOS
39         DEVICE *d_bios;
40 //#endif
41 //#ifdef SINGLE_MODE_DMA
42         DEVICE *d_dma;
43 //#endif
44 //#ifdef USE_DEBUGGER
45         DEBUGGER *d_debugger;
46         DEVICE *d_mem_stored, *d_io_stored;
47 //#endif
48         outputs_t outputs_busack;
49
50         bool has_nsc800;
51         bool has_memory_wait;
52         bool has_io_wait;
53         bool has_pseudo_bios;
54         bool has_ldair_quirk;
55         bool has_single_mode_dma;
56         bool flags_initialized;
57         
58         
59         /* ---------------------------------------------------------------------------
60         registers
61         --------------------------------------------------------------------------- */
62         
63         uint64_t total_icount;
64         uint64_t prev_total_icount;
65         int icount;
66         int extra_icount;
67         uint16_t prevpc;
68         pair32_t pc, sp, af, bc, de, hl, ix, iy, wz;
69         pair32_t af2, bc2, de2, hl2;
70         uint8_t I, R, R2;
71         uint32_t ea;
72         
73         bool busreq, after_halt;
74         uint8_t im, iff1, iff2, icr;
75         bool after_ei, after_ldair;
76         uint32_t intr_req_bit, intr_pend_bit;
77         
78         Z80_INLINE uint8_t RM8(uint32_t addr);
79         Z80_INLINE void WM8(uint32_t addr, uint8_t val);
80         Z80_INLINE void RM16(uint32_t addr, pair32_t *r);
81         Z80_INLINE void WM16(uint32_t addr, pair32_t *r);
82         Z80_INLINE uint8_t FETCHOP();
83         Z80_INLINE uint8_t FETCH8();
84         Z80_INLINE uint32_t FETCH16();
85         Z80_INLINE uint8_t IN8(uint32_t addr);
86         Z80_INLINE void OUT8(uint32_t addr, uint8_t val);
87         
88         Z80_INLINE uint8_t INC(uint8_t value);
89         Z80_INLINE uint8_t DEC(uint8_t value);
90         
91         Z80_INLINE uint8_t RLC(uint8_t value);
92         Z80_INLINE uint8_t RRC(uint8_t value);
93         Z80_INLINE uint8_t RL(uint8_t value);
94         Z80_INLINE uint8_t RR(uint8_t value);
95         Z80_INLINE uint8_t SLA(uint8_t value);
96         Z80_INLINE uint8_t SRA(uint8_t value);
97         Z80_INLINE uint8_t SLL(uint8_t value);
98         Z80_INLINE uint8_t SRL(uint8_t value);
99         
100         Z80_INLINE uint8_t RES(uint8_t bit, uint8_t value);
101         Z80_INLINE uint8_t SET(uint8_t bit, uint8_t value);
102         
103         void OP_CB(uint8_t code);
104         void OP_XY(uint8_t code);
105         void OP_DD(uint8_t code);
106         void OP_FD(uint8_t code);
107         void OP_ED(uint8_t code);
108         void OP(uint8_t code);
109         virtual void run_one_opecode();
110         virtual void debugger_hook(void);
111         
112         uint8_t SZ[256];                /* zero and sign flags */
113         uint8_t SZ_BIT[256];    /* zero, sign and parity/overflow (=zero) flags for BIT opcode */
114         uint8_t SZP[256];               /* zero, sign and parity flags */
115         uint8_t SZHV_inc[256];  /* zero, sign, half carry and overflow flags INC r8 */
116         uint8_t SZHV_dec[256];  /* zero, sign, half carry and overflow flags DEC r8 */
117
118         uint8_t SZHVC_add[2 * 256 * 256];
119         uint8_t SZHVC_sub[2 * 256 * 256];
120
121         const uint8_t cc_op[0x100] = {
122                 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4,
123                 8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4,
124                 7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4,
125                 7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4,
126                 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 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                 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4,
130                 4, 4, 4, 4, 4, 4, 7, 4, 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                 5,10,10,10,10,11, 7,11, 5,10,10, 0,10,17, 7,11,
135                 5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 0, 7,11,
136                 5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 0, 7,11,
137                 5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11
138         };
139
140          const uint8_t cc_cb[0x100] = {
141                 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
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,12, 8, 8, 8, 8, 8, 8, 8,12, 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,15, 8, 8, 8, 8, 8, 8, 8,15, 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         };
158         
159          const uint8_t cc_ed[0x100] = {
160                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
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                 12,12,15,20, 8,14, 8, 9,12,12,15,20, 8,14, 8, 9,
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,18,12,12,15,20, 8,14, 8,18,
167                 12,12,15,20, 8,14, 8, 8,12,12,15,20, 8,14, 8, 8,
168                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
169                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
170                 16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8,
171                 16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8,
172                 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 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         };
177         
178          const uint8_t cc_xy[0x100] = {
179                 4, 4, 4, 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4,
180                 4, 4, 4, 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4,
181                 4,14,20,10, 9, 9,11, 4, 4,15,20,10, 9, 9,11, 4,
182                 4, 4, 4, 4,23,23,19, 4, 4,15, 4, 4, 4, 4, 4, 4,
183                 4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
184                 4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
185                 9, 9, 9, 9, 9, 9,19, 9, 9, 9, 9, 9, 9, 9,19, 9,
186                 19,19,19,19,19,19, 4,19, 4, 4, 4, 4, 9, 9,19, 4,
187                 4, 4, 4, 4, 9, 9,19, 4, 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, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4,
192                 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
193                 4,14, 4,23, 4,15, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4,
194                 4, 4, 4, 4, 4, 4, 4, 4, 4,10, 4, 4, 4, 4, 4, 4
195         };
196
197          const uint8_t cc_xycb[0x100] = {
198                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
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                 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
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                 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
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         };
215         
216         const uint8_t cc_ex[0x100] = {
217                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218                 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DJNZ */
219                 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NZ/JR Z */
220                 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NC/JR C */
221                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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                 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */
229                 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
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         };
234
235         /* ---------------------------------------------------------------------------
236         debug
237         --------------------------------------------------------------------------- */
238         // Collect counters
239         uint64_t cycles_tmp_count;
240         uint64_t extra_tmp_count;
241         uint32_t insns_count;
242         int frames_count;
243         int nmi_count;
244         int     irq_count;
245         int     nsc800_int_count;
246         int     nsc800_rsta_count;
247         int     nsc800_rstb_count;
248         int     nsc800_rstc_count;
249
250 public:
251         Z80_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
252         {
253                 flags_initialized = false;
254                 busreq = false;
255 //#ifdef Z80_PSEUDO_BIOS
256                 d_bios = NULL;
257 //#endif
258 //#ifdef SINGLE_MODE_DMA
259                 d_dma = NULL;
260 //#endif
261                 d_debugger = NULL;
262                 d_mem_stored = NULL;
263                 d_io_stored = NULL;
264                 d_pic = NULL;
265                 has_nsc800 = false;
266                 has_io_wait = false;
267                 has_memory_wait = false;
268                 has_pseudo_bios = false;
269                 has_ldair_quirk = false;
270                 has_single_mode_dma = false;
271                 total_icount = prev_total_icount = 0;
272                 initialize_output_signals(&outputs_busack);
273                 set_device_name(_T("Z80 CPU"));
274
275         }
276         ~Z80_BASE() {}
277         
278         // common functions
279         virtual void initialize();
280         virtual void reset();
281         void event_frame();
282         int run(int clock);
283
284         virtual bool process_state(FILEIO* state_fio, bool loading);
285         
286         void write_signal(int id, uint32_t data, uint32_t mask);
287         uint32_t read_signal(int id);
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