1 /*
2  *  KCemu -- The emulator for the KC85 homecomputer series and much more.
3  *  Copyright (C) 1997-2010 Torsten Paul
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef __kc_z80_h
21 #define __kc_z80_h
22 
23 #include <list>
24 
25 #include <z80ex/z80ex.h>
26 
27 #include "kc/system.h"
28 
29 #include "kc/ic.h"
30 #include "kc/cb.h"
31 #include "kc/cb_list.h"
32 
33 class Z80
34 {
35   public:
36         Z80EX_CONTEXT *_context;
37 
38 	bool _debug;
39 	bool _trace;
40 	bool _singlestep;
41 	bool _executestep;
42         bool _enable_floppy_cpu;
43 	long _tracedelay;
44 
45         byte_t  _next_irq;
46 	dword_t _irq_line;
47 	dword_t _irq_mask;
48 
49 	typedef std::list<InterfaceCircuit *> ic_list_t;
50 
51 	static const int I_PERIOD;
52 
53 	bool _do_quit;
54 	unsigned long long _counter;
55 	ic_list_t _ic_list;
56 
57         CallbackList _cb_list;
58 
59   private:
60         void reset(word_t pc, bool power_on);
61 
62         /*callback that returns byte for a given adress*/
63         static Z80EX_BYTE z80ex_dasm_readbyte_cb(Z80EX_WORD addr, void *user_data);
64 
65         /*read byte from memory <addr> -- called when RD & MREQ goes active.
66         m1_state will be 1 if M1 signal is active*/
67         static Z80EX_BYTE z80ex_mread_cb(Z80EX_CONTEXT *cpu, Z80EX_WORD addr, int m1_state, void *user_data);
68 
69         /*write <value> to memory <addr> -- called when WR & MREQ goes active*/
70         static void z80ex_mwrite_cb(Z80EX_CONTEXT *cpu, Z80EX_WORD addr, Z80EX_BYTE value, void *user_data);
71 
72         /*read byte from <port> -- called when RD & IORQ goes active*/
73         static Z80EX_BYTE z80ex_pread_cb(Z80EX_CONTEXT *cpu, Z80EX_WORD port, void *user_data);
74 
75         /*write <value> to <port> -- called when WR & IORQ goes active*/
76         static void z80ex_pwrite_cb(Z80EX_CONTEXT *cpu, Z80EX_WORD port, Z80EX_BYTE value, void *user_data);
77 
78         /*read byte of interrupt vector -- called when M1 and IORQ goes active*/
79         static Z80EX_BYTE z80ex_intread_cb(Z80EX_CONTEXT *cpu, void *user_data);
80 
81         /*called when the reti instruction is executed*/
82         static void z80ex_reti_cb(Z80EX_CONTEXT *cpu, void *user_data);
83 
84   public:
85 	Z80(void);
~Z80(void)86 	~Z80(void) {}
87 	bool run(void);
88 
89 	void executestep(void);
90 	bool debug(void);
91 	void debug(bool value);
92 	bool trace(void);
93 	void trace(bool value);
94 	void tracedelay(long delay);
95 	bool singlestep();
96 	void singlestep(bool value);
97 
98 	void nmi(void);
99 	void reset(void);
100 	void power_on(void);
101 	void jump(word_t pc);
102 	void reti(void);
103 	void register_ic(InterfaceCircuit *h);
104 	void unregister_ic(InterfaceCircuit *h);
105 
106 	void addCallback(unsigned long long offset, Callback *cb, void *data);
107 	void remove_callback_listener(Callback *cb);
getCounter(void)108 	inline unsigned long long getCounter(void) { return _counter; }
109 
110 	dword_t get_irq_mask(void);
111 	void set_irq_line(dword_t mask);
112 	void reset_irq_line(dword_t mask);
113 
114         void printPC(void);
115 
116 	void quit(void);
117 
getAF(void)118         word_t getAF(void) { return z80ex_get_reg(_context, regAF); }
getBC(void)119         word_t getBC(void) { return z80ex_get_reg(_context, regBC); }
getDE(void)120         word_t getDE(void) { return z80ex_get_reg(_context, regDE); }
getHL(void)121         word_t getHL(void) { return z80ex_get_reg(_context, regHL); }
getIX(void)122         word_t getIX(void) { return z80ex_get_reg(_context, regIX); }
getIY(void)123         word_t getIY(void) { return z80ex_get_reg(_context, regIY); }
getPC(void)124 	word_t getPC(void) { return z80ex_get_reg(_context, regPC); }
getSP(void)125         word_t getSP(void) { return z80ex_get_reg(_context, regSP); }
126 
getAFs(void)127         word_t getAFs(void) { return z80ex_get_reg(_context, regAF_); }
getBCs(void)128         word_t getBCs(void) { return z80ex_get_reg(_context, regBC_); }
getDEs(void)129         word_t getDEs(void) { return z80ex_get_reg(_context, regDE_); }
getHLs(void)130         word_t getHLs(void) { return z80ex_get_reg(_context, regHL_); }
131 
getIFF(void)132         byte_t getIFF(void) { return z80ex_get_reg(_context, regIFF1); }
getI(void)133         byte_t getI(void)   { return z80ex_get_reg(_context, regI); }
134 
get_halt(void)135 	bool get_halt(void) { return z80ex_doing_halt(_context); }
136 
137         void start_floppy_cpu(void);
138         void halt_floppy_cpu(bool power_on);
139 };
140 
141 #endif /* __kc_z80_h */
142