1 /*** m6800: Portable 6800 class emulator *************************************/
2 
3 #define HAS_M6801		1
4 #define HAS_M6802		0
5 #define HAS_M6803		1
6 #define HAS_M6808		0
7 #define HAS_HD63701		1
8 #define HAS_NSC8105     1
9 
10 #ifndef _M6800_H
11 #define _M6800_H
12 
13 //#include "cpuintrf.h"
14 
15 /* 6800 Registers */
16 typedef struct
17 {
18 //  int     subtype;        /* CPU subtype */
19 	PAIR    ea;				/* effective address */
20 	INT32   m6800_ICount;
21 	UINT32 timer_next;
22 	PAIR	ppc;			/* Previous program counter */
23 	PAIR	pc; 			/* Program counter */
24 	PAIR	s;				/* Stack pointer */
25 	PAIR	x;				/* Index register */
26 	PAIR	d;				/* Accumulators */
27 	UINT8	cc; 			/* Condition codes */
28 	UINT8	wai_state;		/* WAI opcode state ,(or sleep opcode state) */
29 	UINT8	nmi_state;		/* NMI line state */
30 	UINT8	irq_state[2];	/* IRQ line state [IRQ1,TIN] */
31 	UINT8	irq_hold[2];
32 	UINT8	ic_eddge;		/* InputCapture eddge , b.0=fall,b.1=raise */
33 
34 	INT32 	extra_cycles;	/* cycles used for interrupts */
35 	/* internal registers */
36 	UINT8	port1_ddr;
37 	UINT8	port2_ddr;
38 	UINT8	port3_ddr;
39 	UINT8	port4_ddr;
40 	UINT8	port1_data;
41 	UINT8	port2_data;
42 	UINT8	port3_data;
43 	UINT8	port4_data;
44 	UINT8	tcsr, rmcr;			/* Timer Control and Status Register */
45 	UINT8	pending_tcsr;	/* pending IRQ flag for clear IRQflag process */
46 	UINT8	irq2;			/* IRQ2 flags */
47 	UINT8	ram_ctrl;
48 	PAIR	counter;		/* free running counter */
49 	PAIR	output_compare;	/* output compare       */
50 	UINT16	input_capture;	/* input capture        */
51 	INT32   latch09;
52 	INT32   segmentcycles;
53 
54 	PAIR	timer_over;
55 
56 	//int		(*irq_callback)(int irqline);
57 	void	(* const * insn)(void);	/* instruction table */
58 	const UINT8 *cycles;			/* clock cycle of instruction table */
59 } m6800_Regs;
60 
61 enum {
62 	M6800_PC=1, M6800_S, M6800_A, M6800_B, M6800_X, M6800_CC,
63 	M6800_WAI_STATE };
64 
65 #define M6800_WAI		8			/* set when WAI is waiting for an interrupt */
66 #define M6800_SLP		0x10		/* HD63701 only */
67 
68 
69 #define M6800_IRQ_LINE	0			/* IRQ line number */
70 #define M6800_TIN_LINE	1			/* P20/Tin Input Capture line (eddge sense)     */
71 									/* Active eddge is selecrable by internal reg.  */
72 									/* raise eddge : CLEAR_LINE  -> ASSERT_LINE     */
73 									/* fall  eddge : ASSERT_LINE -> CLEAR_LINE      */
74 									/* it is usuali to use PULSE_LINE state         */
75 #define M6800_INPUT_LINE_NMI	32
76 
77 unsigned char M6800ReadByte(unsigned short Address);
78 void M6800WriteByte(unsigned short Address, unsigned char Data);
79 unsigned char M6800ReadOp(unsigned short Address);
80 unsigned char M6800ReadOpArg(unsigned short Address);
81 unsigned char M6800ReadPort(unsigned short Address);
82 void M6800WritePort(unsigned short Address, unsigned char Data);
83 
84 void m6800_init();
85 void hd63701_init();
86 void m6803_init();
87 void m6801_init();
88 void nsc8105_init();
89 
90 int m6800_get_segmentcycles();
91 
92 void m6800_reset(void);
93 int m6800_get_pc();
94 void m6800_get_context(void *dst);
95 void m6800_set_context(void *src);
96 int m6800_execute(int cycles);
97 int m6803_execute(int cycles);
98 int hd63701_execute(int cycles);
99 int nsc8105_execute(int cycles);
100 
101 void m6800_set_irq_line(int irqline, int state);
102 
103 void m6803_internal_registers_w(unsigned short offset, unsigned char data);
104 unsigned char m6803_internal_registers_r(unsigned short offset);
105 
106 //extern void m6800_get_info(UINT32 state, cpuinfo *info);
107 
108 /****************************************************************************
109  * For now make the 6801 using the m6800 variables and functions
110  ****************************************************************************/
111 #if (HAS_M6801)
112 #define M6801_A 					M6800_A
113 #define M6801_B 					M6800_B
114 #define M6801_PC					M6800_PC
115 #define M6801_S 					M6800_S
116 #define M6801_X 					M6800_X
117 #define M6801_CC					M6800_CC
118 #define M6801_WAI_STATE 			M6800_WAI_STATE
119 #define M6801_NMI_STATE 			M6800_NMI_STATE
120 #define M6801_IRQ_STATE 			M6800_IRQ_STATE
121 
122 #define M6801_WAI					M6800_WAI
123 #define M6801_IRQ_LINE				M6800_IRQ_LINE
124 
125 //extern void m6801_get_info(UINT32 state, cpuinfo *info);
126 #endif
127 
128 /****************************************************************************
129  * For now make the 6802 using the m6800 variables and functions
130  ****************************************************************************/
131 #if (HAS_M6802)
132 #define M6802_A 					M6800_A
133 #define M6802_B 					M6800_B
134 #define M6802_PC					M6800_PC
135 #define M6802_S 					M6800_S
136 #define M6802_X 					M6800_X
137 #define M6802_CC					M6800_CC
138 #define M6802_WAI_STATE 			M6800_WAI_STATE
139 #define M6802_NMI_STATE 			M6800_NMI_STATE
140 #define M6802_IRQ_STATE 			M6800_IRQ_STATE
141 
142 #define M6802_WAI					M6800_WAI
143 #define M6802_IRQ_LINE				M6800_IRQ_LINE
144 
145 //extern void m6802_get_info(UINT32 state, cpuinfo *info);
146 #endif
147 
148 /****************************************************************************
149  * For now make the 6803 using the m6800 variables and functions
150  ****************************************************************************/
151 #if (HAS_M6803)
152 #define M6803_A 					M6800_A
153 #define M6803_B 					M6800_B
154 #define M6803_PC					M6800_PC
155 #define M6803_S 					M6800_S
156 #define M6803_X 					M6800_X
157 #define M6803_CC					M6800_CC
158 #define M6803_WAI_STATE 			M6800_WAI_STATE
159 #define M6803_NMI_STATE 			M6800_NMI_STATE
160 #define M6803_IRQ_STATE 			M6800_IRQ_STATE
161 
162 #define M6803_WAI					M6800_WAI
163 #define M6803_IRQ_LINE				M6800_IRQ_LINE
164 #define M6803_TIN_LINE				M6800_TIN_LINE
165 
166 //extern void m6803_get_info(UINT32 state, cpuinfo *info);
167 #endif
168 
169 #if (HAS_M6803||HAS_HD63701)
170 /* By default, on a port write port bits which are not set as output in the DDR */
171 /* are set to the value returned by a read from the same port. If you need to */
172 /* know the DDR for e.g. port 1, do m6803_internal_registers_r(M6801_DDR1) */
173 
174 #define M6803_DDR1	0x00
175 #define M6803_DDR2	0x01
176 #define M6803_DDR3	0x04
177 #define M6803_DDR4	0x05
178 
179 #define M6803_PORT1 0x100
180 #define M6803_PORT2 0x101
181 #define M6803_PORT3 0x102
182 #define M6803_PORT4 0x103
183 #endif
184 
185 /****************************************************************************
186  * For now make the 6808 using the m6800 variables and functions
187  ****************************************************************************/
188 #if (HAS_M6808)
189 #define M6808_A 					M6800_A
190 #define M6808_B 					M6800_B
191 #define M6808_PC					M6800_PC
192 #define M6808_S 					M6800_S
193 #define M6808_X 					M6800_X
194 #define M6808_CC					M6800_CC
195 #define M6808_WAI_STATE 			M6800_WAI_STATE
196 #define M6808_NMI_STATE 			M6800_NMI_STATE
197 #define M6808_IRQ_STATE 			M6800_IRQ_STATE
198 
199 #define M6808_WAI                   M6800_WAI
200 #define M6808_IRQ_LINE              M6800_IRQ_LINE
201 
202 extern void m6808_get_info(UINT32 state, cpuinfo *info);
203 #endif
204 
205 /****************************************************************************
206  * For now make the HD63701 using the m6800 variables and functions
207  ****************************************************************************/
208 #if (HAS_HD63701)
209 #define HD63701_A					 M6800_A
210 #define HD63701_B					 M6800_B
211 #define HD63701_PC					 M6800_PC
212 #define HD63701_S					 M6800_S
213 #define HD63701_X					 M6800_X
214 #define HD63701_CC					 M6800_CC
215 #define HD63701_WAI_STATE			 M6800_WAI_STATE
216 #define HD63701_NMI_STATE			 M6800_NMI_STATE
217 #define HD63701_IRQ_STATE			 M6800_IRQ_STATE
218 
219 #define HD63701_WAI 				 M6800_WAI
220 #define HD63701_SLP 				 M6800_SLP
221 #define HD63701_IRQ_LINE			 M6800_IRQ_LINE
222 #define HD63701_TIN_LINE			 M6800_TIN_LINE
223 
224 //extern void hd63701_get_info(UINT32 state, cpuinfo *info);
225 
226 void hd63701_trap_pc(void);
227 
228 #define HD63701_DDR1 M6803_DDR1
229 #define HD63701_DDR2 M6803_DDR2
230 #define HD63701_DDR3 M6803_DDR3
231 #define HD63701_DDR4 M6803_DDR4
232 
233 #define HD63701_PORT1 M6803_PORT1
234 #define HD63701_PORT2 M6803_PORT2
235 #define HD63701_PORT3 M6803_PORT3
236 #define HD63701_PORT4 M6803_PORT4
237 
238 //READ8_HANDLER( hd63701_internal_registers_r );
239 //WRITE8_HANDLER( hd63701_internal_registers_w );
240 
241 #endif
242 
243 /****************************************************************************
244  * For now make the NSC8105 using the m6800 variables and functions
245  ****************************************************************************/
246 #if (HAS_NSC8105)
247 #define NSC8105_A					 M6800_A
248 #define NSC8105_B					 M6800_B
249 #define NSC8105_PC					 M6800_PC
250 #define NSC8105_S					 M6800_S
251 #define NSC8105_X					 M6800_X
252 #define NSC8105_CC					 M6800_CC
253 #define NSC8105_WAI_STATE			 M6800_WAI_STATE
254 #define NSC8105_NMI_STATE			 M6800_NMI_STATE
255 #define NSC8105_IRQ_STATE			 M6800_IRQ_STATE
256 
257 #define NSC8105_WAI 				 M6800_WAI
258 #define NSC8105_IRQ_LINE			 M6800_IRQ_LINE
259 #define NSC8105_TIN_LINE			 M6800_TIN_LINE
260 
261 //extern void nsc8105_get_info(UINT32 state, cpuinfo *info);
262 #endif
263 
264 /****************************************************************************/
265 /* Read a byte from given memory location                                   */
266 /****************************************************************************/
267 /* ASG 971005 -- changed to program_read_byte_8/program_write_byte_8 */
268 #define M6800_RDMEM(Addr) ((unsigned)M6800ReadByte(Addr))
269 
270 /****************************************************************************/
271 /* Write a byte to given memory location                                    */
272 /****************************************************************************/
273 #define M6800_WRMEM(Addr,Value) (M6800WriteByte(Addr,Value))
274 
275 /****************************************************************************/
276 /* M6800_RDOP() is identical to M6800_RDMEM() except it is used for reading */
277 /* opcodes. In case of system with memory mapped I/O, this function can be  */
278 /* used to greatly speed up emulation                                       */
279 /****************************************************************************/
280 #define M6800_RDOP(Addr) ((unsigned)M6800ReadOp(Addr))
281 
282 /****************************************************************************/
283 /* M6800_RDOP_ARG() is identical to M6800_RDOP() but it's used for reading  */
284 /* opcode arguments. This difference can be used to support systems that    */
285 /* use different encoding mechanisms for opcodes and opcode arguments       */
286 /****************************************************************************/
287 #define M6800_RDOP_ARG(Addr) ((unsigned)M6800ReadOpArg(Addr))
288 
289 #define M6800_io_read_byte_8(Port)		((unsigned)M6800ReadPort(Port))
290 #define M6800_io_write_byte_8(Port,Value)	(M6800WritePort(Port, Value))
291 
292 #ifndef FALSE
293 #    define FALSE 0
294 #endif
295 #ifndef TRUE
296 #    define TRUE (!FALSE)
297 #endif
298 
299 #ifdef	MAME_DEBUG
300 offs_t m6800_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
301 offs_t m6801_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
302 offs_t m6802_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
303 ffs_t m6803_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
304 offs_t m6808_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
305 offs_t hd63701_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
306 offs_t nsc8105_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
307 #endif
308 
309 #endif /* _M6800_H */
310