1 /*** m6800: Portable 6800 class  emulator *************************************
2 
3 	m6800.c
4 
5 	References:
6 
7 		6809 Simulator V09, By L.C. Benschop, Eidnhoven The Netherlands.
8 
9 		m6809: Portable 6809 emulator, DS (6809 code in MAME, derived from
10 			the 6809 Simulator V09)
11 
12 		6809 Microcomputer Programming & Interfacing with Experiments"
13 			by Andrew C. Staugaard, Jr.; Howard W. Sams & Co., Inc.
14 
15 	System dependencies:	UINT16 must be 16 bit unsigned int
16 							UINT8 must be 8 bit unsigned int
17 							UINT32 must be more than 16 bits
18 							arrays up to 65536 bytes must be supported
19 							machine must be twos complement
20 
21 History
22 991031	ZV
23 	Added NSC-8105 support
24 
25 990319	HJB
26     Fixed wrong LSB/MSB order for push/pull word.
27 	Subtract .extra_cycles at the beginning/end of the exectuion loops.
28 
29 990316  HJB
30 	Renamed to 6800, since that's the basic CPU.
31 	Added different cycle count tables for M6800/2/8, M6801/3 and HD63701.
32 
33 990314  HJB
34 	Also added the M6800 subtype.
35 
36 990311  HJB
37 	Added _info functions. Now uses static m6808_Regs struct instead
38 	of single statics. Changed the 16 bit registers to use the generic
39 	PAIR union. Registers defined using macros. Split the core into
40 	four execution loops for M6802, M6803, M6808 and HD63701.
41 	TST, TSTA and TSTB opcodes reset carry flag.
42 TODO:
43 	Verify invalid opcodes for the different CPU types.
44 	Add proper credits to _info functions.
45 	Integrate m6808_Flags into the registers (multiple m6808 type CPUs?)
46 
47 990301	HJB
48 	Modified the interrupt handling. No more pending interrupt checks.
49 	WAI opcode saves state, when an interrupt is taken (IRQ or OCI),
50 	the state is only saved if not already done by WAI.
51 
52 *****************************************************************************/
53 
54 
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 #include "cpuintrf.h"
59 #include "state.h"
60 #include "m6800.h"
61 #include "osdepend.h"
62 
63 /* 6800 Registers */
64 typedef struct
65 {
66 //	int 	subtype;		/* CPU subtype */
67 	PAIR	ppc;			/* Previous program counter */
68 	PAIR	pc; 			/* Program counter */
69 	PAIR	s;				/* Stack pointer */
70 	PAIR	x;				/* Index register */
71 	PAIR	d;				/* Accumulators */
72 	UINT8	cc; 			/* Condition codes */
73 	UINT8	wai_state;		/* WAI opcode state ,(or sleep opcode state) */
74 	UINT8	nmi_state;		/* NMI line state */
75 	UINT8	irq_state[2];	/* IRQ line state [IRQ1,TIN] */
76 	UINT8	ic_eddge;		/* InputCapture eddge , b.0=fall,b.1=raise */
77 
78 	int		(*irq_callback)(int irqline);
79 	int 	extra_cycles;	/* cycles used for interrupts */
80 	void	(* const * insn)(void);	/* instruction table */
81 	const UINT8 *cycles;			/* clock cycle of instruction table */
82 	/* internal registers */
83 	UINT8	port1_ddr;
84 	UINT8	port2_ddr;
85 	UINT8	port1_data;
86 	UINT8	port2_data;
87 	UINT8	tcsr;			/* Timer Control and Status Register */
88 	UINT8	pending_tcsr;	/* pending IRQ flag for clear IRQflag process */
89 	UINT8	irq2;			/* IRQ2 flags */
90 	UINT8	ram_ctrl;
91 	PAIR	counter;		/* free running counter */
92 	PAIR	output_compare;	/* output compare       */
93 	UINT16	input_capture;	/* input capture        */
94 
95 	PAIR	timer_over;
96 }   m6800_Regs;
97 
98 /* 680x registers */
99 static m6800_Regs m6800;
100 
101 #define m6801   m6800
102 #define m6802   m6800
103 #define m6803	m6800
104 #define m6808	m6800
105 #define hd63701 m6800
106 #define nsc8105 m6800
107 
108 #define	pPPC	m6800.ppc
109 #define pPC 	m6800.pc
110 #define pS		m6800.s
111 #define pX		m6800.x
112 #define pD		m6800.d
113 
114 #define PC		m6800.pc.w.l
115 #define PCD		m6800.pc.d
116 #define S		m6800.s.w.l
117 #define SD		m6800.s.d
118 #define X		m6800.x.w.l
119 #define D		m6800.d.w.l
120 #define A		m6800.d.b.h
121 #define B		m6800.d.b.l
122 #define CC		m6800.cc
123 
124 #define CT		m6800.counter.w.l
125 #define CTH		m6800.counter.w.h
126 #define CTD		m6800.counter.d
127 #define OC		m6800.output_compare.w.l
128 #define OCH		m6800.output_compare.w.h
129 #define OCD		m6800.output_compare.d
130 #define TOH		m6800.timer_over.w.l
131 #define TOD		m6800.timer_over.d
132 
133 static PAIR ea; 		/* effective address */
134 #define EAD ea.d
135 #define EA	ea.w.l
136 
137 /* public globals */
138 int m6800_ICount=50000;
139 
140 /* point of next timer event */
141 static UINT32 timer_next;
142 
143 /* DS -- THESE ARE RE-DEFINED IN m6800.h TO RAM, ROM or FUNCTIONS IN cpuintrf.c */
144 #define RM				M6800_RDMEM
145 #define WM				M6800_WRMEM
146 #define M_RDOP			M6800_RDOP
147 #define M_RDOP_ARG		M6800_RDOP_ARG
148 
149 /* macros to access memory */
150 #define IMMBYTE(b)	b = M_RDOP_ARG(PCD); PC++
151 #define IMMWORD(w)	w.d = (M_RDOP_ARG(PCD)<<8) | M_RDOP_ARG((PCD+1)&0xffff); PC+=2
152 
153 #define PUSHBYTE(b) WM(SD,b); --S
154 #define PUSHWORD(w) WM(SD,w.b.l); --S; WM(SD,w.b.h); --S
155 #define PULLBYTE(b) S++; b = RM(SD)
156 #define PULLWORD(w) S++; w.d = RM(SD)<<8; S++; w.d |= RM(SD)
157 
158 #define MODIFIED_tcsr {	\
159 	m6800.irq2 = (m6800.tcsr&(m6800.tcsr<<3))&(TCSR_ICF|TCSR_OCF|TCSR_TOF); \
160 }
161 
162 #define SET_TIMRE_EVENT {					\
163 	timer_next = (OCD - CTD < TOD - CTD) ? OCD : TOD;	\
164 }
165 
166 /* cleanup high-word of counters */
167 #define CLEANUP_conters {						\
168 	OCH -= CTH;									\
169 	TOH -= CTH;									\
170 	CTH = 0;									\
171 	SET_TIMRE_EVENT;							\
172 }
173 
174 /* when change freerunningcounter or outputcapture */
175 #define MODIFIED_counters {						\
176 	OCH = (OC >= CT) ? CTH : CTH+1;				\
177 	SET_TIMRE_EVENT;							\
178 }
179 
180 /* take interrupt */
181 #define TAKE_ICI ENTER_INTERRUPT(0xfff6)
182 #define TAKE_OCI ENTER_INTERRUPT(0xfff4)
183 #define TAKE_TOI ENTER_INTERRUPT(0xfff2)
184 #define TAKE_SCI ENTER_INTERRUPT(0xfff0)
185 #define TAKE_TRAP ENTER_INTERRUPT(0xffee)
186 
187 /* check IRQ2 (internal irq) */
188 #define CHECK_IRQ2 {											\
189 	if(m6800.irq2&(TCSR_ICF|TCSR_OCF|TCSR_TOF))					\
190 	{															\
191 		if(m6800.irq2&TCSR_ICF)									\
192 		{														\
193 			TAKE_ICI;											\
194 			if( m6800.irq_callback )							\
195 				(void)(*m6800.irq_callback)(M6800_TIN_LINE);	\
196 		}														\
197 		else if(m6800.irq2&TCSR_OCF)							\
198 		{														\
199 			TAKE_OCI;											\
200 		}														\
201 		else if(m6800.irq2&TCSR_TOF)							\
202 		{														\
203 			TAKE_TOI;											\
204 		}														\
205 	}															\
206 }
207 
208 /* operate one instruction for */
209 #define ONE_MORE_INSN() {		\
210 	UINT8 ireg; 							\
211 	pPPC = pPC; 							\
212 	ireg=M_RDOP(PCD);						\
213 	PC++;									\
214 	(*m6800.insn[ireg])();					\
215 	INCREMENT_COUNTER(m6800.cycles[ireg]);	\
216 }
217 
218 /* check the IRQ lines for pending interrupts */
219 #define CHECK_IRQ_LINES() {										\
220 	if( !(CC & 0x10) )											\
221 	{															\
222 		if( m6800.irq_state[M6800_IRQ_LINE] != CLEAR_LINE )		\
223 		{	/* standard IRQ */									\
224 			ENTER_INTERRUPT(0xfff8);		\
225 			if( m6800.irq_callback )							\
226 				(void)(*m6800.irq_callback)(M6800_IRQ_LINE);	\
227 		}														\
228 		else													\
229 			CHECK_IRQ2;											\
230 	}															\
231 }
232 
233 /* CC masks                       HI NZVC
234 								7654 3210	*/
235 #define CLR_HNZVC	CC&=0xd0
236 #define CLR_NZV 	CC&=0xf1
237 #define CLR_HNZC	CC&=0xd2
238 #define CLR_NZVC	CC&=0xf0
239 #define CLR_Z		CC&=0xfb
240 #define CLR_NZC 	CC&=0xf2
241 #define CLR_ZC		CC&=0xfa
242 #define CLR_C		CC&=0xfe
243 
244 /* macros for CC -- CC bits affected should be reset before calling */
245 #define SET_Z(a)		if(!a)SEZ
246 #define SET_Z8(a)		SET_Z((UINT8)a)
247 #define SET_Z16(a)		SET_Z((UINT16)a)
248 #define SET_N8(a)		CC|=((a&0x80)>>4)
249 #define SET_N16(a)		CC|=((a&0x8000)>>12)
250 #define SET_H(a,b,r)	CC|=(((a^b^r)&0x10)<<1)
251 #define SET_C8(a)		CC|=((a&0x100)>>8)
252 #define SET_C16(a)		CC|=((a&0x10000)>>16)
253 #define SET_V8(a,b,r)	CC|=(((a^b^r^(r>>1))&0x80)>>6)
254 #define SET_V16(a,b,r)	CC|=(((a^b^r^(r>>1))&0x8000)>>14)
255 
256 static const UINT8 flags8i[256]=	 /* increment */
257 {
258 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
259 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
260 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
261 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
262 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
263 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
264 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
265 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
266 0x0a,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
267 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
268 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
269 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
270 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
271 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
272 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
273 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08
274 };
275 static const UINT8 flags8d[256]= /* decrement */
276 {
277 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
278 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
279 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
280 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
281 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
282 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
283 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
284 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,
285 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
286 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
287 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
288 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
289 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
290 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
291 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
292 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08
293 };
294 #define SET_FLAGS8I(a)		{CC|=flags8i[(a)&0xff];}
295 #define SET_FLAGS8D(a)		{CC|=flags8d[(a)&0xff];}
296 
297 /* combos */
298 #define SET_NZ8(a)			{SET_N8(a);SET_Z(a);}
299 #define SET_NZ16(a)			{SET_N16(a);SET_Z(a);}
300 #define SET_FLAGS8(a,b,r)	{SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);}
301 #define SET_FLAGS16(a,b,r)	{SET_N16(r);SET_Z16(r);SET_V16(a,b,r);SET_C16(r);}
302 
303 /* for treating an UINT8 as a signed INT16 */
304 #define SIGNED(b) ((INT16)(b&0x80?b|0xff00:b))
305 
306 /* Macros for addressing modes */
307 #define DIRECT IMMBYTE(EAD)
308 #define IMM8 EA=PC++
309 #define IMM16 {EA=PC;PC+=2;}
310 #define EXTENDED IMMWORD(ea)
311 #define INDEXED {EA=X+(UINT8)M_RDOP_ARG(PCD);PC++;}
312 
313 /* macros to set status flags */
314 #define SEC CC|=0x01
315 #define CLC CC&=0xfe
316 #define SEZ CC|=0x04
317 #define CLZ CC&=0xfb
318 #define SEN CC|=0x08
319 #define CLN CC&=0xf7
320 #define SEV CC|=0x02
321 #define CLV CC&=0xfd
322 #define SEH CC|=0x20
323 #define CLH CC&=0xdf
324 #define SEI CC|=0x10
325 #define CLI CC&=~0x10
326 
327 /* mnemonicos for the Timer Control and Status Register bits */
328 #define TCSR_OLVL 0x01
329 #define TCSR_IEDG 0x02
330 #define TCSR_ETOI 0x04
331 #define TCSR_EOCI 0x08
332 #define TCSR_EICI 0x10
333 #define TCSR_TOF  0x20
334 #define TCSR_OCF  0x40
335 #define TCSR_ICF  0x80
336 
337 #define INCREMENT_COUNTER(amount)	\
338 {									\
339 	m6800_ICount -= amount;			\
340 	CTD += amount;					\
341 	if( CTD >= timer_next)			\
342 		check_timer_event();		\
343 }
344 
345 #define EAT_CYCLES													\
346 {																	\
347 	int cycles_to_eat;												\
348 																	\
349 	cycles_to_eat = timer_next - CTD;								\
350 	if( cycles_to_eat > m6800_ICount) cycles_to_eat = m6800_ICount;	\
351 	if (cycles_to_eat > 0)											\
352 	{																\
353 		INCREMENT_COUNTER(cycles_to_eat);							\
354 	}																\
355 }
356 
357 /* macros for convenience */
358 #define DIRBYTE(b) {DIRECT;b=RM(EAD);}
359 #define DIRWORD(w) {DIRECT;w.d=RM16(EAD);}
360 #define EXTBYTE(b) {EXTENDED;b=RM(EAD);}
361 #define EXTWORD(w) {EXTENDED;w.d=RM16(EAD);}
362 
363 #define IDXBYTE(b) {INDEXED;b=RM(EAD);}
364 #define IDXWORD(w) {INDEXED;w.d=RM16(EAD);}
365 
366 /* Macros for branch instructions */
367 #define CHANGE_PC() change_pc16(PCD)
368 #define BRANCH(f) {IMMBYTE(t);if(f){PC+=SIGNED(t);CHANGE_PC();}}
369 #define NXORV  ((CC&0x08)^((CC&0x02)<<2))
370 
371 static const UINT8 cycles_6800[] =
372 {
373 		/* 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
374 	/*0*/  0, 2, 0, 0, 0, 0, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2,
375 	/*1*/  2, 2, 0, 0, 0, 0, 2, 2, 0, 2, 0, 2, 0, 0, 0, 0,
376 	/*2*/  4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
377 	/*3*/  4, 4, 4, 4, 4, 4, 4, 4, 0, 5, 0,10, 0, 0, 9,12,
378 	/*4*/  2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 0, 2,
379 	/*5*/  2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 0, 2,
380 	/*6*/  7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 4, 7,
381 	/*7*/  6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 6, 3, 6,
382 	/*8*/  2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 3, 8, 3, 0,
383 	/*9*/  3, 3, 3, 0, 3, 3, 3, 4, 3, 3, 3, 3, 4, 0, 4, 5,
384 	/*A*/  5, 5, 5, 0, 5, 5, 5, 6, 5, 5, 5, 5, 6, 8, 6, 7,
385 	/*B*/  4, 4, 4, 0, 4, 4, 4, 5, 4, 4, 4, 4, 5, 9, 5, 6,
386 	/*C*/  2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 0, 3, 0,
387 	/*D*/  3, 3, 3, 0, 3, 3, 3, 4, 3, 3, 3, 3, 0, 0, 4, 5,
388 	/*E*/  5, 5, 5, 0, 5, 5, 5, 6, 5, 5, 5, 5, 0, 0, 6, 7,
389 	/*F*/  4, 4, 4, 0, 4, 4, 4, 5, 4, 4, 4, 4, 0, 0, 5, 6
390 };
391 
392 static const UINT8 cycles_6803[] =
393 {
394 		/* 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
395 	/*0*/  0, 2, 0, 0, 3, 3, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2,
396 	/*1*/  2, 2, 0, 0, 0, 0, 2, 2, 0, 2, 0, 2, 0, 0, 0, 0,
397 	/*2*/  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
398 	/*3*/  3, 3, 4, 4, 3, 3, 3, 3, 5, 5, 3,10, 4,10, 9,12,
399 	/*4*/  2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 0, 2,
400 	/*5*/  2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 0, 2,
401 	/*6*/  6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 6, 3, 6,
402 	/*7*/  6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 6, 3, 6,
403 	/*8*/  2, 2, 2, 4, 2, 2, 2, 0, 2, 2, 2, 2, 4, 6, 3, 0,
404 	/*9*/  3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 4, 4,
405 	/*A*/  4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 5, 5,
406 	/*B*/  4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 5, 5,
407 	/*C*/  2, 2, 2, 4, 2, 2, 2, 0, 2, 2, 2, 2, 3, 0, 3, 0,
408 	/*D*/  3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
409 	/*E*/  4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
410 	/*F*/  4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5
411 };
412 
413 static const UINT8 cycles_63701[] =
414 {
415 		/* 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
416 	/*0*/  0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
417 	/*1*/  1, 1, 0, 0, 0, 0, 1, 1, 2, 2, 4, 1, 0, 0, 0, 0,
418 	/*2*/  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
419 	/*3*/  1, 1, 3, 3, 1, 1, 4, 4, 4, 5, 1,10, 5, 7, 9,12,
420 	/*4*/  1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,
421 	/*5*/  1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,
422 	/*6*/  6, 7, 7, 6, 6, 7, 6, 6, 6, 6, 6, 5, 6, 4, 3, 5,
423 	/*7*/  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 6, 4, 3, 5,
424 	/*8*/  2, 2, 2, 3, 2, 2, 2, 0, 2, 2, 2, 2, 3, 5, 3, 0,
425 	/*9*/  3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 4, 4,
426 	/*A*/  4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
427 	/*B*/  4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
428 	/*C*/  2, 2, 2, 3, 2, 2, 2, 0, 2, 2, 2, 2, 3, 0, 3, 0,
429 	/*D*/  3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
430 	/*E*/  4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
431 	/*F*/  4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5
432 };
433 
434 static const UINT8 cycles_nsc8105[] =
435 {
436 		/* 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
437 	/*0*/  0, 0, 2, 0, 0, 2, 0, 2, 4, 2, 4, 2, 2, 2, 2, 2,
438 	/*1*/  2, 0, 2, 0, 0, 2, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0,
439 	/*2*/  4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
440 	/*3*/  4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 5,10, 0, 9, 0,12,
441 	/*4*/  2, 0, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 0, 2, 2,
442 	/*5*/  2, 0, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 0, 2, 2,
443 	/*6*/  7, 0, 0, 7, 7, 7, 0, 7, 7, 7, 7, 0, 7, 4, 7, 7,
444 	/*7*/  6, 0, 0, 6, 6, 6, 0, 6, 6, 6, 6, 0, 6, 3, 6, 6,
445 	/*8*/  2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 3, 3, 8, 0,
446 	/*9*/  3, 3, 3, 0, 3, 3, 3, 4, 3, 3, 3, 3, 4, 4, 0, 5,
447 	/*A*/  5, 5, 5, 0, 5, 5, 5, 6, 5, 5, 5, 5, 6, 6, 8, 7,
448 	/*B*/  4, 4, 4, 0, 4, 4, 4, 5, 4, 4, 4, 4, 5, 5, 9, 6,
449 	/*C*/  2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 3, 0, 0,
450 	/*D*/  3, 3, 3, 0, 3, 3, 3, 4, 3, 3, 3, 3, 0, 4, 0, 5,
451 	/*E*/  5, 5, 5, 0, 5, 5, 5, 6, 5, 5, 5, 5, 0, 6, 0, 7,
452 	/*F*/  4, 4, 4, 0, 4, 4, 4, 5, 4, 4, 4, 4, 4, 5, 0, 6
453 };
454 
RM16(UINT32 Addr)455 static INLINE UINT32 RM16( UINT32 Addr )
456 {
457 	UINT32 result = RM(Addr) << 8;
458 	return result | RM((Addr+1)&0xffff);
459 }
460 
WM16(UINT32 Addr,PAIR * p)461 static INLINE void WM16( UINT32 Addr, PAIR *p )
462 {
463 	WM( Addr, p->b.h );
464 	WM( (Addr+1)&0xffff, p->b.l );
465 }
466 
467 /* IRQ enter */
ENTER_INTERRUPT(UINT16 irq_vector)468 static void ENTER_INTERRUPT(UINT16 irq_vector)
469 {
470 	if( m6800.wai_state & (M6800_WAI|M6800_SLP) )
471 	{
472 		if( m6800.wai_state & M6800_WAI )
473 			m6800.extra_cycles += 4;
474 		m6800.wai_state &= ~(M6800_WAI|M6800_SLP);
475 	}
476 	else
477 	{
478 		PUSHWORD(pPC);
479 		PUSHWORD(pX);
480 		PUSHBYTE(A);
481 		PUSHBYTE(B);
482 		PUSHBYTE(CC);
483 		m6800.extra_cycles += 12;
484 	}
485 	SEI;
486 	PCD = RM16( irq_vector );
487 	CHANGE_PC();
488 }
489 
490 /* check OCI or TOI */
check_timer_event(void)491 static void check_timer_event(void)
492 {
493 	/* OCI */
494 	if( CTD >= OCD)
495 	{
496 		OCH++;	// next IRQ point
497 		m6800.tcsr |= TCSR_OCF;
498 		m6800.pending_tcsr |= TCSR_OCF;
499 		MODIFIED_tcsr;
500 		if ( !(CC & 0x10) && (m6800.tcsr & TCSR_EOCI))
501 			TAKE_OCI;
502 	}
503 	/* TOI */
504 	if( CTD >= TOD)
505 	{
506 		TOH++;	// next IRQ point
507 #if 0
508 		CLEANUP_conters;
509 #endif
510 		m6800.tcsr |= TCSR_TOF;
511 		m6800.pending_tcsr |= TCSR_TOF;
512 		MODIFIED_tcsr;
513 		if ( !(CC & 0x10) && (m6800.tcsr & TCSR_ETOI))
514 			TAKE_TOI;
515 	}
516 	/* set next event */
517 	SET_TIMRE_EVENT;
518 }
519 
520 /* include the opcode prototypes and function pointer tables */
521 #include "6800tbl.c"
522 
523 /* include the opcode functions */
524 #include "6800ops.c"
525 
526 /****************************************************************************
527  * Reset registers to their initial values
528  ****************************************************************************/
m6800_reset(void * param)529 void m6800_reset(void *param)
530 {
531 	SEI;				/* IRQ disabled */
532 	PCD = RM16( 0xfffe );
533 	CHANGE_PC();
534 
535 	/* HJB 990417 set CPU subtype (other reset functions override this) */
536 //	m6800.subtype   = SUBTYPE_M6800;
537 	m6800.insn = m6800_insn;
538 	m6800.cycles = cycles_6800;
539 
540 	m6800.wai_state = 0;
541 	m6800.nmi_state = 0;
542 	m6800.irq_state[M6800_IRQ_LINE] = 0;
543 	m6800.irq_state[M6800_TIN_LINE] = 0;
544 	m6800.ic_eddge = 0;
545 
546 	m6800.port1_ddr = 0x00;
547 	m6800.port2_ddr = 0x00;
548 	/* TODO: on reset port 2 should be read to determine the operating mode (bits 0-2) */
549 	m6800.tcsr = 0x00;
550 	m6800.pending_tcsr = 0x00;
551 	m6800.irq2 = 0;
552 	CTD = 0x0000;
553 	OCD = 0xffff;
554 	TOD = 0xffff;
555 	m6800.ram_ctrl |= 0x40;
556 }
557 
558 /****************************************************************************
559  * Shut down CPU emulatio
560  ****************************************************************************/
m6800_exit(void)561 void m6800_exit(void)
562 {
563 	/* nothing to do */
564 }
565 
566 /****************************************************************************
567  * Get all registers in given buffer
568  ****************************************************************************/
m6800_get_context(void * dst)569 unsigned m6800_get_context(void *dst)
570 {
571 	if( dst )
572 		*(m6800_Regs*)dst = m6800;
573 	return sizeof(m6800_Regs);
574 }
575 
576 
577 /****************************************************************************
578  * Set all registers to given values
579  ****************************************************************************/
m6800_set_context(void * src)580 void m6800_set_context(void *src)
581 {
582 	if( src )
583 		m6800 = *(m6800_Regs*)src;
584 	CHANGE_PC();
585 	CHECK_IRQ_LINES(); /* HJB 990417 */
586 }
587 
588 
589 /****************************************************************************
590  * Return program counter
591  ****************************************************************************/
m6800_get_pc(void)592 unsigned m6800_get_pc(void)
593 {
594 	return PC;
595 }
596 
597 
598 /****************************************************************************
599  * Set program counter
600  ****************************************************************************/
m6800_set_pc(unsigned val)601 void m6800_set_pc(unsigned val)
602 {
603 	PC = val;
604 	CHANGE_PC();
605 }
606 
607 
608 /****************************************************************************
609  * Return stack pointer
610  ****************************************************************************/
m6800_get_sp(void)611 unsigned m6800_get_sp(void)
612 {
613 	return S;
614 }
615 
616 
617 /****************************************************************************
618  * Set stack pointer
619  ****************************************************************************/
m6800_set_sp(unsigned val)620 void m6800_set_sp(unsigned val)
621 {
622 	S = val;
623 }
624 
625 
626 /****************************************************************************
627  * Return a specific register
628  ****************************************************************************/
m6800_get_reg(int regnum)629 unsigned m6800_get_reg(int regnum)
630 {
631 	switch( regnum )
632 	{
633 		case M6800_PC: return m6800.pc.w.l;
634 		case M6800_S: return m6800.s.w.l;
635 		case M6800_CC: return m6800.cc;
636 		case M6800_A: return m6800.d.b.h;
637 		case M6800_B: return m6800.d.b.l;
638 		case M6800_X: return m6800.x.w.l;
639 		case M6800_NMI_STATE: return m6800.nmi_state;
640 		case M6800_IRQ_STATE: return m6800.irq_state[M6800_IRQ_LINE];
641 		case REG_PREVIOUSPC: return m6800.ppc.w.l;
642 		default:
643 			if( regnum <= REG_SP_CONTENTS )
644 			{
645 				unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
646 				if( offset < 0xffff )
647 					return ( RM( offset ) << 8 ) | RM( offset+1 );
648 			}
649 	}
650 	return 0;
651 }
652 
653 
654 /****************************************************************************
655  * Set a specific register
656  ****************************************************************************/
m6800_set_reg(int regnum,unsigned val)657 void m6800_set_reg(int regnum, unsigned val)
658 {
659 	switch( regnum )
660 	{
661 		case M6800_PC: m6800.pc.w.l = val; break;
662 		case M6800_S: m6800.s.w.l = val; break;
663 		case M6800_CC: m6800.cc = val; break;
664 		case M6800_A: m6800.d.b.h = val; break;
665 		case M6800_B: m6800.d.b.l = val; break;
666 		case M6800_X: m6800.x.w.l = val; break;
667 		case M6800_NMI_STATE: m6800_set_nmi_line(val); break;
668 		case M6800_IRQ_STATE: m6800_set_irq_line(M6800_IRQ_LINE,val); break;
669 		default:
670 			if( regnum <= REG_SP_CONTENTS )
671 			{
672 				unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
673 				if( offset < 0xffff )
674 				{
675 					WM( offset, (val >> 8) & 0xff );
676 					WM( offset+1, val & 0xff );
677 				}
678 			}
679 	}
680 }
681 
682 
m6800_set_nmi_line(int state)683 void m6800_set_nmi_line(int state)
684 {
685 	if (m6800.nmi_state == state) return;
686 	m6800.nmi_state = state;
687 	if (state == CLEAR_LINE) return;
688 
689 	/* NMI */
690 	ENTER_INTERRUPT(0xfffc);
691 }
692 
m6800_set_irq_line(int irqline,int state)693 void m6800_set_irq_line(int irqline, int state)
694 {
695 	int eddge;
696 
697 	if (m6800.irq_state[irqline] == state) return;
698 	m6800.irq_state[irqline] = state;
699 
700 	switch(irqline)
701 	{
702 	case M6800_IRQ_LINE:
703 		if (state == CLEAR_LINE) return;
704 		break;
705 	case M6800_TIN_LINE:
706 		eddge = (state == CLEAR_LINE ) ? 2 : 0;
707 		if( ((m6800.tcsr&TCSR_IEDG) ^ (state==CLEAR_LINE ? TCSR_IEDG : 0))==0 )
708 			return;
709 		/* active edge in */
710 		m6800.tcsr |= TCSR_ICF;
711 		m6800.pending_tcsr |= TCSR_ICF;
712 		m6800.input_capture = CT;
713 		MODIFIED_tcsr;
714 		if( !(CC & 0x10) )
715 			CHECK_IRQ2
716 		break;
717 	default:
718 		return;
719 	}
720 	CHECK_IRQ_LINES(); /* HJB 990417 */
721 }
722 
m6800_set_irq_callback(int (* callback)(int irqline))723 void m6800_set_irq_callback(int (*callback)(int irqline))
724 {
725 	m6800.irq_callback = callback;
726 }
727 
state_save(void * file,const char * module)728 static void state_save(void *file, const char *module)
729 {
730 	int cpu = cpu_getactivecpu();
731 	state_save_UINT8(file,module,cpu,"A", &m6800.d.b.h, 1);
732 	state_save_UINT8(file,module,cpu,"B", &m6800.d.b.l, 1);
733 	state_save_UINT16(file,module,cpu,"PC", &m6800.pc.w.l, 1);
734 	state_save_UINT16(file,module,cpu,"S", &m6800.s.w.l, 1);
735 	state_save_UINT16(file,module,cpu,"X", &m6800.x.w.l, 1);
736 	state_save_UINT8(file,module,cpu,"CC", &m6800.cc, 1);
737 	state_save_UINT8(file,module,cpu,"NMI_STATE", &m6800.nmi_state, 1);
738 	state_save_UINT8(file,module,cpu,"IRQ_STATE", &m6800.irq_state[M6800_IRQ_LINE], 1);
739 	state_save_UINT8(file,module,cpu,"TIN_STATE", &m6800.irq_state[M6800_TIN_LINE], 1);
740 }
741 
state_load(void * file,const char * module)742 static void state_load(void *file, const char *module)
743 {
744 	int cpu = cpu_getactivecpu();
745 	state_load_UINT8(file,module,cpu,"A", &m6800.d.b.h, 1);
746 	state_load_UINT8(file,module,cpu,"B", &m6800.d.b.l, 1);
747 	state_load_UINT16(file,module,cpu,"PC", &m6800.pc.w.l, 1);
748 	state_load_UINT16(file,module,cpu,"S", &m6800.s.w.l, 1);
749 	state_load_UINT16(file,module,cpu,"X", &m6800.x.w.l, 1);
750 	state_load_UINT8(file,module,cpu,"CC", &m6800.cc, 1);
751 	state_load_UINT8(file,module,cpu,"NMI_STATE", &m6800.nmi_state, 1);
752 	state_load_UINT8(file,module,cpu,"IRQ_STATE", &m6800.irq_state[M6800_IRQ_LINE], 1);
753 	state_load_UINT8(file,module,cpu,"TIN_STATE", &m6800.irq_state[M6800_TIN_LINE], 1);
754 }
755 
m6800_state_save(void * file)756 void m6800_state_save(void *file) { state_save(file,"m6800"); }
m6800_state_load(void * file)757 void m6800_state_load(void *file) { state_load(file,"m6800"); }
758 
759 /****************************************************************************
760  * Execute cycles CPU cycles. Return number of cycles really executed
761  ****************************************************************************/
m6800_execute(int cycles)762 int m6800_execute(int cycles)
763 {
764 	UINT8 ireg;
765 	m6800_ICount = cycles;
766 
767 	CLEANUP_conters;
768 	INCREMENT_COUNTER(m6800.extra_cycles);
769 	m6800.extra_cycles = 0;
770 
771 	do
772 	{
773 		if( m6800.wai_state & M6800_WAI )
774 		{
775 			EAT_CYCLES;
776 		}
777 		else
778 		{
779 			pPPC = pPC;
780 			ireg=M_RDOP(PCD);
781 			PC++;
782 
783 			switch( ireg )
784 			{
785 				case 0x00: illegal(); break;
786 				case 0x01: nop(); break;
787 				case 0x02: illegal(); break;
788 				case 0x03: illegal(); break;
789 				case 0x04: illegal(); break;
790 				case 0x05: illegal(); break;
791 				case 0x06: tap(); break;
792 				case 0x07: tpa(); break;
793 				case 0x08: inx(); break;
794 				case 0x09: dex(); break;
795 				case 0x0A: CLV; break;
796 				case 0x0B: SEV; break;
797 				case 0x0C: CLC; break;
798 				case 0x0D: SEC; break;
799 				case 0x0E: cli(); break;
800 				case 0x0F: sei(); break;
801 				case 0x10: sba(); break;
802 				case 0x11: cba(); break;
803 				case 0x12: illegal(); break;
804 				case 0x13: illegal(); break;
805 				case 0x14: illegal(); break;
806 				case 0x15: illegal(); break;
807 				case 0x16: tab(); break;
808 				case 0x17: tba(); break;
809 				case 0x18: illegal(); break;
810 				case 0x19: daa(); break;
811 				case 0x1a: illegal(); break;
812 				case 0x1b: aba(); break;
813 				case 0x1c: illegal(); break;
814 				case 0x1d: illegal(); break;
815 				case 0x1e: illegal(); break;
816 				case 0x1f: illegal(); break;
817 				case 0x20: bra(); break;
818 				case 0x21: brn(); break;
819 				case 0x22: bhi(); break;
820 				case 0x23: bls(); break;
821 				case 0x24: bcc(); break;
822 				case 0x25: bcs(); break;
823 				case 0x26: bne(); break;
824 				case 0x27: beq(); break;
825 				case 0x28: bvc(); break;
826 				case 0x29: bvs(); break;
827 				case 0x2a: bpl(); break;
828 				case 0x2b: bmi(); break;
829 				case 0x2c: bge(); break;
830 				case 0x2d: blt(); break;
831 				case 0x2e: bgt(); break;
832 				case 0x2f: ble(); break;
833 				case 0x30: tsx(); break;
834 				case 0x31: ins(); break;
835 				case 0x32: pula(); break;
836 				case 0x33: pulb(); break;
837 				case 0x34: des(); break;
838 				case 0x35: txs(); break;
839 				case 0x36: psha(); break;
840 				case 0x37: pshb(); break;
841 				case 0x38: illegal(); break;
842 				case 0x39: rts(); break;
843 				case 0x3a: illegal(); break;
844 				case 0x3b: rti(); break;
845 				case 0x3c: illegal(); break;
846 				case 0x3d: illegal(); break;
847 				case 0x3e: wai(); break;
848 				case 0x3f: swi(); break;
849 				case 0x40: nega(); break;
850 				case 0x41: illegal(); break;
851 				case 0x42: illegal(); break;
852 				case 0x43: coma(); break;
853 				case 0x44: lsra(); break;
854 				case 0x45: illegal(); break;
855 				case 0x46: rora(); break;
856 				case 0x47: asra(); break;
857 				case 0x48: asla(); break;
858 				case 0x49: rola(); break;
859 				case 0x4a: deca(); break;
860 				case 0x4b: illegal(); break;
861 				case 0x4c: inca(); break;
862 				case 0x4d: tsta(); break;
863 				case 0x4e: illegal(); break;
864 				case 0x4f: clra(); break;
865 				case 0x50: negb(); break;
866 				case 0x51: illegal(); break;
867 				case 0x52: illegal(); break;
868 				case 0x53: comb(); break;
869 				case 0x54: lsrb(); break;
870 				case 0x55: illegal(); break;
871 				case 0x56: rorb(); break;
872 				case 0x57: asrb(); break;
873 				case 0x58: aslb(); break;
874 				case 0x59: rolb(); break;
875 				case 0x5a: decb(); break;
876 				case 0x5b: illegal(); break;
877 				case 0x5c: incb(); break;
878 				case 0x5d: tstb(); break;
879 				case 0x5e: illegal(); break;
880 				case 0x5f: clrb(); break;
881 				case 0x60: neg_ix(); break;
882 				case 0x61: illegal(); break;
883 				case 0x62: illegal(); break;
884 				case 0x63: com_ix(); break;
885 				case 0x64: lsr_ix(); break;
886 				case 0x65: illegal(); break;
887 				case 0x66: ror_ix(); break;
888 				case 0x67: asr_ix(); break;
889 				case 0x68: asl_ix(); break;
890 				case 0x69: rol_ix(); break;
891 				case 0x6a: dec_ix(); break;
892 				case 0x6b: illegal(); break;
893 				case 0x6c: inc_ix(); break;
894 				case 0x6d: tst_ix(); break;
895 				case 0x6e: jmp_ix(); break;
896 				case 0x6f: clr_ix(); break;
897 				case 0x70: neg_ex(); break;
898 				case 0x71: illegal(); break;
899 				case 0x72: illegal(); break;
900 				case 0x73: com_ex(); break;
901 				case 0x74: lsr_ex(); break;
902 				case 0x75: illegal(); break;
903 				case 0x76: ror_ex(); break;
904 				case 0x77: asr_ex(); break;
905 				case 0x78: asl_ex(); break;
906 				case 0x79: rol_ex(); break;
907 				case 0x7a: dec_ex(); break;
908 				case 0x7b: illegal(); break;
909 				case 0x7c: inc_ex(); break;
910 				case 0x7d: tst_ex(); break;
911 				case 0x7e: jmp_ex(); break;
912 				case 0x7f: clr_ex(); break;
913 				case 0x80: suba_im(); break;
914 				case 0x81: cmpa_im(); break;
915 				case 0x82: sbca_im(); break;
916 				case 0x83: illegal(); break;
917 				case 0x84: anda_im(); break;
918 				case 0x85: bita_im(); break;
919 				case 0x86: lda_im(); break;
920 				case 0x87: sta_im(); break;
921 				case 0x88: eora_im(); break;
922 				case 0x89: adca_im(); break;
923 				case 0x8a: ora_im(); break;
924 				case 0x8b: adda_im(); break;
925 				case 0x8c: cmpx_im(); break;
926 				case 0x8d: bsr(); break;
927 				case 0x8e: lds_im(); break;
928 				case 0x8f: sts_im(); /* orthogonality */ break;
929 				case 0x90: suba_di(); break;
930 				case 0x91: cmpa_di(); break;
931 				case 0x92: sbca_di(); break;
932 				case 0x93: illegal(); break;
933 				case 0x94: anda_di(); break;
934 				case 0x95: bita_di(); break;
935 				case 0x96: lda_di(); break;
936 				case 0x97: sta_di(); break;
937 				case 0x98: eora_di(); break;
938 				case 0x99: adca_di(); break;
939 				case 0x9a: ora_di(); break;
940 				case 0x9b: adda_di(); break;
941 				case 0x9c: cmpx_di(); break;
942 				case 0x9d: jsr_di(); break;
943 				case 0x9e: lds_di(); break;
944 				case 0x9f: sts_di(); break;
945 				case 0xa0: suba_ix(); break;
946 				case 0xa1: cmpa_ix(); break;
947 				case 0xa2: sbca_ix(); break;
948 				case 0xa3: illegal(); break;
949 				case 0xa4: anda_ix(); break;
950 				case 0xa5: bita_ix(); break;
951 				case 0xa6: lda_ix(); break;
952 				case 0xa7: sta_ix(); break;
953 				case 0xa8: eora_ix(); break;
954 				case 0xa9: adca_ix(); break;
955 				case 0xaa: ora_ix(); break;
956 				case 0xab: adda_ix(); break;
957 				case 0xac: cmpx_ix(); break;
958 				case 0xad: jsr_ix(); break;
959 				case 0xae: lds_ix(); break;
960 				case 0xaf: sts_ix(); break;
961 				case 0xb0: suba_ex(); break;
962 				case 0xb1: cmpa_ex(); break;
963 				case 0xb2: sbca_ex(); break;
964 				case 0xb3: illegal(); break;
965 				case 0xb4: anda_ex(); break;
966 				case 0xb5: bita_ex(); break;
967 				case 0xb6: lda_ex(); break;
968 				case 0xb7: sta_ex(); break;
969 				case 0xb8: eora_ex(); break;
970 				case 0xb9: adca_ex(); break;
971 				case 0xba: ora_ex(); break;
972 				case 0xbb: adda_ex(); break;
973 				case 0xbc: cmpx_ex(); break;
974 				case 0xbd: jsr_ex(); break;
975 				case 0xbe: lds_ex(); break;
976 				case 0xbf: sts_ex(); break;
977 				case 0xc0: subb_im(); break;
978 				case 0xc1: cmpb_im(); break;
979 				case 0xc2: sbcb_im(); break;
980 				case 0xc3: illegal(); break;
981 				case 0xc4: andb_im(); break;
982 				case 0xc5: bitb_im(); break;
983 				case 0xc6: ldb_im(); break;
984 				case 0xc7: stb_im(); break;
985 				case 0xc8: eorb_im(); break;
986 				case 0xc9: adcb_im(); break;
987 				case 0xca: orb_im(); break;
988 				case 0xcb: addb_im(); break;
989 				case 0xcc: illegal(); break;
990 				case 0xcd: illegal(); break;
991 				case 0xce: ldx_im(); break;
992 				case 0xcf: stx_im(); break;
993 				case 0xd0: subb_di(); break;
994 				case 0xd1: cmpb_di(); break;
995 				case 0xd2: sbcb_di(); break;
996 				case 0xd3: illegal(); break;
997 				case 0xd4: andb_di(); break;
998 				case 0xd5: bitb_di(); break;
999 				case 0xd6: ldb_di(); break;
1000 				case 0xd7: stb_di(); break;
1001 				case 0xd8: eorb_di(); break;
1002 				case 0xd9: adcb_di(); break;
1003 				case 0xda: orb_di(); break;
1004 				case 0xdb: addb_di(); break;
1005 				case 0xdc: illegal(); break;
1006 				case 0xdd: illegal(); break;
1007 				case 0xde: ldx_di(); break;
1008 				case 0xdf: stx_di(); break;
1009 				case 0xe0: subb_ix(); break;
1010 				case 0xe1: cmpb_ix(); break;
1011 				case 0xe2: sbcb_ix(); break;
1012 				case 0xe3: illegal(); break;
1013 				case 0xe4: andb_ix(); break;
1014 				case 0xe5: bitb_ix(); break;
1015 				case 0xe6: ldb_ix(); break;
1016 				case 0xe7: stb_ix(); break;
1017 				case 0xe8: eorb_ix(); break;
1018 				case 0xe9: adcb_ix(); break;
1019 				case 0xea: orb_ix(); break;
1020 				case 0xeb: addb_ix(); break;
1021 				case 0xec: illegal(); break;
1022 				case 0xed: illegal(); break;
1023 				case 0xee: ldx_ix(); break;
1024 				case 0xef: stx_ix(); break;
1025 				case 0xf0: subb_ex(); break;
1026 				case 0xf1: cmpb_ex(); break;
1027 				case 0xf2: sbcb_ex(); break;
1028 				case 0xf3: illegal(); break;
1029 				case 0xf4: andb_ex(); break;
1030 				case 0xf5: bitb_ex(); break;
1031 				case 0xf6: ldb_ex(); break;
1032 				case 0xf7: stb_ex(); break;
1033 				case 0xf8: eorb_ex(); break;
1034 				case 0xf9: adcb_ex(); break;
1035 				case 0xfa: orb_ex(); break;
1036 				case 0xfb: addb_ex(); break;
1037 				case 0xfc: addx_ex(); break;
1038 				case 0xfd: illegal(); break;
1039 				case 0xfe: ldx_ex(); break;
1040 				case 0xff: stx_ex(); break;
1041 			}
1042 			INCREMENT_COUNTER(cycles_6800[ireg]);
1043 		}
1044 	} while( m6800_ICount>0 );
1045 
1046 	INCREMENT_COUNTER(m6800.extra_cycles);
1047 	m6800.extra_cycles = 0;
1048 
1049 	return cycles - m6800_ICount;
1050 }
1051 
1052 /****************************************************************************
1053  * Return a formatted string for a register
1054  ****************************************************************************/
m6800_info(void * context,int regnum)1055 const char *m6800_info(void *context, int regnum)
1056 {
1057 	switch( regnum )
1058 	{
1059 		case CPU_INFO_NAME: return "M6800";
1060 		case CPU_INFO_FAMILY: return "Motorola 6800";
1061 		case CPU_INFO_VERSION: return "1.1";
1062 		case CPU_INFO_FILE: return __FILE__;
1063 		case CPU_INFO_CREDITS: return "The MAME team.";
1064 	}
1065 	return "";
1066 }
1067 
m6800_dasm(char * buffer,unsigned pc)1068 unsigned m6800_dasm(char *buffer, unsigned pc)
1069 {
1070 	sprintf( buffer, "$%02X", cpu_readop(pc) );
1071 	return 1;
1072 }
1073 
1074 /****************************************************************************
1075  * M6801 almost (fully?) equal to the M6803
1076  ****************************************************************************/
1077 #if (HAS_M6801)
m6801_reset(void * param)1078 void m6801_reset(void *param)
1079 {
1080 	m6800_reset(param);
1081 //	m6800.subtype = SUBTYPE_M6801;
1082 	m6800.insn = m6803_insn;
1083 	m6800.cycles = cycles_6803;
1084 }
m6801_exit(void)1085 void m6801_exit(void) { m6800_exit(); }
m6801_execute(int cycles)1086 int  m6801_execute(int cycles) { return m6803_execute(cycles); }
m6801_get_context(void * dst)1087 unsigned m6801_get_context(void *dst) { return m6800_get_context(dst); }
m6801_set_context(void * src)1088 void m6801_set_context(void *src) { m6800_set_context(src); }
m6801_get_pc(void)1089 unsigned m6801_get_pc(void) { return m6800_get_pc(); }
m6801_set_pc(unsigned val)1090 void m6801_set_pc(unsigned val) { m6800_set_pc(val); }
m6801_get_sp(void)1091 unsigned m6801_get_sp(void) { return m6800_get_sp(); }
m6801_set_sp(unsigned val)1092 void m6801_set_sp(unsigned val) { m6800_set_sp(val); }
m6801_get_reg(int regnum)1093 unsigned m6801_get_reg(int regnum) { return m6800_get_reg(regnum); }
m6801_set_reg(int regnum,unsigned val)1094 void m6801_set_reg(int regnum, unsigned val) { m6800_set_reg(regnum,val); }
m6801_set_nmi_line(int state)1095 void m6801_set_nmi_line(int state) { m6800_set_nmi_line(state); }
m6801_set_irq_line(int irqline,int state)1096 void m6801_set_irq_line(int irqline, int state) { m6800_set_irq_line(irqline,state); }
m6801_set_irq_callback(int (* callback)(int irqline))1097 void m6801_set_irq_callback(int (*callback)(int irqline)) { m6800_set_irq_callback(callback); }
m6801_state_save(void * file)1098 void m6801_state_save(void *file) { state_save(file,"m6801"); }
m6801_state_load(void * file)1099 void m6801_state_load(void *file) { state_load(file,"m6801"); }
m6801_info(void * context,int regnum)1100 const char *m6801_info(void *context, int regnum)
1101 {
1102 	switch( regnum )
1103 	{
1104 		case CPU_INFO_NAME: return "M6801";
1105 	}
1106 	return m6800_info(context,regnum);
1107 }
m6801_dasm(char * buffer,unsigned pc)1108 unsigned m6801_dasm(char *buffer, unsigned pc)
1109 {
1110 	sprintf( buffer, "$%02X", cpu_readmem16(pc) );
1111 	return 1;
1112 }
1113 
1114 #endif
1115 
1116 /****************************************************************************
1117  * M6802 almost (fully?) equal to the M6800
1118  ****************************************************************************/
1119 #if (HAS_M6802)
m6802_reset(void * param)1120 void m6802_reset(void *param)
1121 {
1122 	m6800_reset(param);
1123 //	m6800.subtype = SUBTYPE_M6802;
1124 }
m6802_exit(void)1125 void m6802_exit(void) { m6800_exit(); }
m6802_execute(int cycles)1126 int  m6802_execute(int cycles) { return m6800_execute(cycles); }
m6802_get_context(void * dst)1127 unsigned m6802_get_context(void *dst) { return m6800_get_context(dst); }
m6802_set_context(void * src)1128 void m6802_set_context(void *src) { m6800_set_context(src); }
m6802_get_pc(void)1129 unsigned m6802_get_pc(void) { return m6800_get_pc(); }
m6802_set_pc(unsigned val)1130 void m6802_set_pc(unsigned val) { m6800_set_pc(val); }
m6802_get_sp(void)1131 unsigned m6802_get_sp(void) { return m6800_get_sp(); }
m6802_set_sp(unsigned val)1132 void m6802_set_sp(unsigned val) { m6800_set_sp(val); }
m6802_get_reg(int regnum)1133 unsigned m6802_get_reg(int regnum) { return m6800_get_reg(regnum); }
m6802_set_reg(int regnum,unsigned val)1134 void m6802_set_reg(int regnum, unsigned val) { m6800_set_reg(regnum,val); }
m6802_set_nmi_line(int state)1135 void m6802_set_nmi_line(int state) { m6800_set_nmi_line(state); }
m6802_set_irq_line(int irqline,int state)1136 void m6802_set_irq_line(int irqline, int state) { m6800_set_irq_line(irqline,state); }
m6802_set_irq_callback(int (* callback)(int irqline))1137 void m6802_set_irq_callback(int (*callback)(int irqline)) { m6800_set_irq_callback(callback); }
m6802_state_save(void * file)1138 void m6802_state_save(void *file) { state_save(file,"m6802"); }
m6802_state_load(void * file)1139 void m6802_state_load(void *file) { state_load(file,"m6802"); }
m6802_info(void * context,int regnum)1140 const char *m6802_info(void *context, int regnum)
1141 {
1142 	switch( regnum )
1143 	{
1144 		case CPU_INFO_NAME: return "M6802";
1145 	}
1146 	return m6800_info(context,regnum);
1147 }
1148 
m6802_dasm(char * buffer,unsigned pc)1149 unsigned m6802_dasm(char *buffer, unsigned pc)
1150 {
1151 	sprintf( buffer, "$%02X", cpu_readmem16(pc) );
1152 	return 1;
1153 }
1154 
1155 #endif
1156 
1157 /****************************************************************************
1158  * M6803 almost (fully?) equal to the M6801
1159  ****************************************************************************/
1160 #if (HAS_M6803)
m6803_reset(void * param)1161 void m6803_reset(void *param)
1162 {
1163 	m6800_reset(param);
1164 //	m6800.subtype = SUBTYPE_M6803;
1165 	m6800.insn = m6803_insn;
1166 	m6800.cycles = cycles_6803;
1167 }
m6803_exit(void)1168 void m6803_exit(void) { m6800_exit(); }
1169 #endif
1170 /****************************************************************************
1171  * Execute cycles CPU cycles. Return number of cycles really executed
1172  ****************************************************************************/
1173 #if (HAS_M6803||HAS_M6801)
m6803_execute(int cycles)1174 int m6803_execute(int cycles)
1175 {
1176 	UINT8 ireg;
1177 	m6803_ICount = cycles;
1178 
1179 	CLEANUP_conters;
1180 	INCREMENT_COUNTER(m6803.extra_cycles);
1181 	m6803.extra_cycles = 0;
1182 
1183 	if( m6803.wai_state & M6800_WAI )
1184 	{
1185 		EAT_CYCLES;
1186 		goto getout;
1187 	}
1188 
1189 	do
1190 	{
1191 
1192 		pPPC = pPC;
1193 		ireg=M_RDOP(PCD);
1194 		PC++;
1195 
1196 		switch( ireg )
1197 		{
1198 			case 0x00: illegal(); break;
1199 			case 0x01: nop(); break;
1200 			case 0x02: illegal(); break;
1201 			case 0x03: illegal(); break;
1202 			case 0x04: lsrd(); /* 6803 only */; break;
1203 			case 0x05: asld(); /* 6803 only */; break;
1204 			case 0x06: tap(); break;
1205 			case 0x07: tpa(); break;
1206 			case 0x08: inx(); break;
1207 			case 0x09: dex(); break;
1208 			case 0x0A: CLV; break;
1209 			case 0x0B: SEV; break;
1210 			case 0x0C: CLC; break;
1211 			case 0x0D: SEC; break;
1212 			case 0x0E: cli(); break;
1213 			case 0x0F: sei(); break;
1214 			case 0x10: sba(); break;
1215 			case 0x11: cba(); break;
1216 			case 0x12: illegal(); break;
1217 			case 0x13: illegal(); break;
1218 			case 0x14: illegal(); break;
1219 			case 0x15: illegal(); break;
1220 			case 0x16: tab(); break;
1221 			case 0x17: tba(); break;
1222 			case 0x18: illegal(); break;
1223 			case 0x19: daa(); break;
1224 			case 0x1a: illegal(); break;
1225 			case 0x1b: aba(); break;
1226 			case 0x1c: illegal(); break;
1227 			case 0x1d: illegal(); break;
1228 			case 0x1e: illegal(); break;
1229 			case 0x1f: illegal(); break;
1230 			case 0x20: bra(); break;
1231 			case 0x21: brn(); break;
1232 			case 0x22: bhi(); break;
1233 			case 0x23: bls(); break;
1234 			case 0x24: bcc(); break;
1235 			case 0x25: bcs(); break;
1236 			case 0x26: bne(); break;
1237 			case 0x27: beq(); break;
1238 			case 0x28: bvc(); break;
1239 			case 0x29: bvs(); break;
1240 			case 0x2a: bpl(); break;
1241 			case 0x2b: bmi(); break;
1242 			case 0x2c: bge(); break;
1243 			case 0x2d: blt(); break;
1244 			case 0x2e: bgt(); break;
1245 			case 0x2f: ble(); break;
1246 			case 0x30: tsx(); break;
1247 			case 0x31: ins(); break;
1248 			case 0x32: pula(); break;
1249 			case 0x33: pulb(); break;
1250 			case 0x34: des(); break;
1251 			case 0x35: txs(); break;
1252 			case 0x36: psha(); break;
1253 			case 0x37: pshb(); break;
1254 			case 0x38: pulx(); /* 6803 only */ break;
1255 			case 0x39: rts(); break;
1256 			case 0x3a: abx(); /* 6803 only */ break;
1257 			case 0x3b: rti(); break;
1258 			case 0x3c: pshx(); /* 6803 only */ break;
1259 			case 0x3d: mul(); /* 6803 only */ break;
1260 			case 0x3e: wai(); break;
1261 			case 0x3f: swi(); break;
1262 			case 0x40: nega(); break;
1263 			case 0x41: illegal(); break;
1264 			case 0x42: illegal(); break;
1265 			case 0x43: coma(); break;
1266 			case 0x44: lsra(); break;
1267 			case 0x45: illegal(); break;
1268 			case 0x46: rora(); break;
1269 			case 0x47: asra(); break;
1270 			case 0x48: asla(); break;
1271 			case 0x49: rola(); break;
1272 			case 0x4a: deca(); break;
1273 			case 0x4b: illegal(); break;
1274 			case 0x4c: inca(); break;
1275 			case 0x4d: tsta(); break;
1276 			case 0x4e: illegal(); break;
1277 			case 0x4f: clra(); break;
1278 			case 0x50: negb(); break;
1279 			case 0x51: illegal(); break;
1280 			case 0x52: illegal(); break;
1281 			case 0x53: comb(); break;
1282 			case 0x54: lsrb(); break;
1283 			case 0x55: illegal(); break;
1284 			case 0x56: rorb(); break;
1285 			case 0x57: asrb(); break;
1286 			case 0x58: aslb(); break;
1287 			case 0x59: rolb(); break;
1288 			case 0x5a: decb(); break;
1289 			case 0x5b: illegal(); break;
1290 			case 0x5c: incb(); break;
1291 			case 0x5d: tstb(); break;
1292 			case 0x5e: illegal(); break;
1293 			case 0x5f: clrb(); break;
1294 			case 0x60: neg_ix(); break;
1295 			case 0x61: illegal(); break;
1296 			case 0x62: illegal(); break;
1297 			case 0x63: com_ix(); break;
1298 			case 0x64: lsr_ix(); break;
1299 			case 0x65: illegal(); break;
1300 			case 0x66: ror_ix(); break;
1301 			case 0x67: asr_ix(); break;
1302 			case 0x68: asl_ix(); break;
1303 			case 0x69: rol_ix(); break;
1304 			case 0x6a: dec_ix(); break;
1305 			case 0x6b: illegal(); break;
1306 			case 0x6c: inc_ix(); break;
1307 			case 0x6d: tst_ix(); break;
1308 			case 0x6e: jmp_ix(); break;
1309 			case 0x6f: clr_ix(); break;
1310 			case 0x70: neg_ex(); break;
1311 			case 0x71: illegal(); break;
1312 			case 0x72: illegal(); break;
1313 			case 0x73: com_ex(); break;
1314 			case 0x74: lsr_ex(); break;
1315 			case 0x75: illegal(); break;
1316 			case 0x76: ror_ex(); break;
1317 			case 0x77: asr_ex(); break;
1318 			case 0x78: asl_ex(); break;
1319 			case 0x79: rol_ex(); break;
1320 			case 0x7a: dec_ex(); break;
1321 			case 0x7b: illegal(); break;
1322 			case 0x7c: inc_ex(); break;
1323 			case 0x7d: tst_ex(); break;
1324 			case 0x7e: jmp_ex(); break;
1325 			case 0x7f: clr_ex(); break;
1326 			case 0x80: suba_im(); break;
1327 			case 0x81: cmpa_im(); break;
1328 			case 0x82: sbca_im(); break;
1329 			case 0x83: subd_im(); /* 6803 only */ break;
1330 			case 0x84: anda_im(); break;
1331 			case 0x85: bita_im(); break;
1332 			case 0x86: lda_im(); break;
1333 			case 0x87: sta_im(); break;
1334 			case 0x88: eora_im(); break;
1335 			case 0x89: adca_im(); break;
1336 			case 0x8a: ora_im(); break;
1337 			case 0x8b: adda_im(); break;
1338 			case 0x8c: cpx_im(); /* 6803 difference */ break;
1339 			case 0x8d: bsr(); break;
1340 			case 0x8e: lds_im(); break;
1341 			case 0x8f: sts_im(); /* orthogonality */ break;
1342 			case 0x90: suba_di(); break;
1343 			case 0x91: cmpa_di(); break;
1344 			case 0x92: sbca_di(); break;
1345 			case 0x93: subd_di(); /* 6803 only */ break;
1346 			case 0x94: anda_di(); break;
1347 			case 0x95: bita_di(); break;
1348 			case 0x96: lda_di(); break;
1349 			case 0x97: sta_di(); break;
1350 			case 0x98: eora_di(); break;
1351 			case 0x99: adca_di(); break;
1352 			case 0x9a: ora_di(); break;
1353 			case 0x9b: adda_di(); break;
1354 			case 0x9c: cpx_di(); /* 6803 difference */ break;
1355 			case 0x9d: jsr_di(); break;
1356 			case 0x9e: lds_di(); break;
1357 			case 0x9f: sts_di(); break;
1358 			case 0xa0: suba_ix(); break;
1359 			case 0xa1: cmpa_ix(); break;
1360 			case 0xa2: sbca_ix(); break;
1361 			case 0xa3: subd_ix(); /* 6803 only */ break;
1362 			case 0xa4: anda_ix(); break;
1363 			case 0xa5: bita_ix(); break;
1364 			case 0xa6: lda_ix(); break;
1365 			case 0xa7: sta_ix(); break;
1366 			case 0xa8: eora_ix(); break;
1367 			case 0xa9: adca_ix(); break;
1368 			case 0xaa: ora_ix(); break;
1369 			case 0xab: adda_ix(); break;
1370 			case 0xac: cpx_ix(); /* 6803 difference */ break;
1371 			case 0xad: jsr_ix(); break;
1372 			case 0xae: lds_ix(); break;
1373 			case 0xaf: sts_ix(); break;
1374 			case 0xb0: suba_ex(); break;
1375 			case 0xb1: cmpa_ex(); break;
1376 			case 0xb2: sbca_ex(); break;
1377 			case 0xb3: subd_ex(); /* 6803 only */ break;
1378 			case 0xb4: anda_ex(); break;
1379 			case 0xb5: bita_ex(); break;
1380 			case 0xb6: lda_ex(); break;
1381 			case 0xb7: sta_ex(); break;
1382 			case 0xb8: eora_ex(); break;
1383 			case 0xb9: adca_ex(); break;
1384 			case 0xba: ora_ex(); break;
1385 			case 0xbb: adda_ex(); break;
1386 			case 0xbc: cpx_ex(); /* 6803 difference */ break;
1387 			case 0xbd: jsr_ex(); break;
1388 			case 0xbe: lds_ex(); break;
1389 			case 0xbf: sts_ex(); break;
1390 			case 0xc0: subb_im(); break;
1391 			case 0xc1: cmpb_im(); break;
1392 			case 0xc2: sbcb_im(); break;
1393 			case 0xc3: addd_im(); /* 6803 only */ break;
1394 			case 0xc4: andb_im(); break;
1395 			case 0xc5: bitb_im(); break;
1396 			case 0xc6: ldb_im(); break;
1397 			case 0xc7: stb_im(); break;
1398 			case 0xc8: eorb_im(); break;
1399 			case 0xc9: adcb_im(); break;
1400 			case 0xca: orb_im(); break;
1401 			case 0xcb: addb_im(); break;
1402 			case 0xcc: ldd_im(); /* 6803 only */ break;
1403 			case 0xcd: std_im(); /* 6803 only -- orthogonality */ break;
1404 			case 0xce: ldx_im(); break;
1405 			case 0xcf: stx_im(); break;
1406 			case 0xd0: subb_di(); break;
1407 			case 0xd1: cmpb_di(); break;
1408 			case 0xd2: sbcb_di(); break;
1409 			case 0xd3: addd_di(); /* 6803 only */ break;
1410 			case 0xd4: andb_di(); break;
1411 			case 0xd5: bitb_di(); break;
1412 			case 0xd6: ldb_di(); break;
1413 			case 0xd7: stb_di(); break;
1414 			case 0xd8: eorb_di(); break;
1415 			case 0xd9: adcb_di(); break;
1416 			case 0xda: orb_di(); break;
1417 			case 0xdb: addb_di(); break;
1418 			case 0xdc: ldd_di(); /* 6803 only */ break;
1419 			case 0xdd: std_di(); /* 6803 only */ break;
1420 			case 0xde: ldx_di(); break;
1421 			case 0xdf: stx_di(); break;
1422 			case 0xe0: subb_ix(); break;
1423 			case 0xe1: cmpb_ix(); break;
1424 			case 0xe2: sbcb_ix(); break;
1425 			case 0xe3: addd_ix(); /* 6803 only */ break;
1426 			case 0xe4: andb_ix(); break;
1427 			case 0xe5: bitb_ix(); break;
1428 			case 0xe6: ldb_ix(); break;
1429 			case 0xe7: stb_ix(); break;
1430 			case 0xe8: eorb_ix(); break;
1431 			case 0xe9: adcb_ix(); break;
1432 			case 0xea: orb_ix(); break;
1433 			case 0xeb: addb_ix(); break;
1434 			case 0xec: ldd_ix(); /* 6803 only */ break;
1435 			case 0xed: std_ix(); /* 6803 only */ break;
1436 			case 0xee: ldx_ix(); break;
1437 			case 0xef: stx_ix(); break;
1438 			case 0xf0: subb_ex(); break;
1439 			case 0xf1: cmpb_ex(); break;
1440 			case 0xf2: sbcb_ex(); break;
1441 			case 0xf3: addd_ex(); /* 6803 only */ break;
1442 			case 0xf4: andb_ex(); break;
1443 			case 0xf5: bitb_ex(); break;
1444 			case 0xf6: ldb_ex(); break;
1445 			case 0xf7: stb_ex(); break;
1446 			case 0xf8: eorb_ex(); break;
1447 			case 0xf9: adcb_ex(); break;
1448 			case 0xfa: orb_ex(); break;
1449 			case 0xfb: addb_ex(); break;
1450 			case 0xfc: ldd_ex(); /* 6803 only */ break;
1451 			case 0xfd: std_ex(); /* 6803 only */ break;
1452 			case 0xfe: ldx_ex(); break;
1453 			case 0xff: stx_ex(); break;
1454 		}
1455 		INCREMENT_COUNTER(cycles_6803[ireg]);
1456 	} while( m6803_ICount>0 );
1457 
1458 getout:
1459 	INCREMENT_COUNTER(m6803.extra_cycles);
1460 	m6803.extra_cycles = 0;
1461 
1462 	return cycles - m6803_ICount;
1463 }
1464 #endif
1465 
1466 #if (HAS_M6803)
m6803_get_context(void * dst)1467 unsigned m6803_get_context(void *dst) { return m6800_get_context(dst); }
m6803_set_context(void * src)1468 void m6803_set_context(void *src) { m6800_set_context(src); }
m6803_get_pc(void)1469 unsigned m6803_get_pc(void) { return m6800_get_pc(); }
m6803_set_pc(unsigned val)1470 void m6803_set_pc(unsigned val) { m6800_set_pc(val); }
m6803_get_sp(void)1471 unsigned m6803_get_sp(void) { return m6800_get_sp(); }
m6803_set_sp(unsigned val)1472 void m6803_set_sp(unsigned val) { m6800_set_sp(val); }
m6803_get_reg(int regnum)1473 unsigned m6803_get_reg(int regnum) { return m6800_get_reg(regnum); }
m6803_set_reg(int regnum,unsigned val)1474 void m6803_set_reg(int regnum, unsigned val) { m6800_set_reg(regnum,val); }
m6803_set_nmi_line(int state)1475 void m6803_set_nmi_line(int state) { m6800_set_nmi_line(state); }
m6803_set_irq_line(int irqline,int state)1476 void m6803_set_irq_line(int irqline, int state) { m6800_set_irq_line(irqline,state); }
m6803_set_irq_callback(int (* callback)(int irqline))1477 void m6803_set_irq_callback(int (*callback)(int irqline)) { m6800_set_irq_callback(callback); }
m6803_state_save(void * file)1478 void m6803_state_save(void *file) { state_save(file,"m6803"); }
m6803_state_load(void * file)1479 void m6803_state_load(void *file) { state_load(file,"m6803"); }
m6803_info(void * context,int regnum)1480 const char *m6803_info(void *context, int regnum)
1481 {
1482 	switch( regnum )
1483 	{
1484 		case CPU_INFO_NAME: return "M6803";
1485 	}
1486 	return m6800_info(context,regnum);
1487 }
1488 
m6803_dasm(char * buffer,unsigned pc)1489 unsigned m6803_dasm(char *buffer, unsigned pc)
1490 {
1491 	sprintf( buffer, "$%02X", cpu_readmem16(pc) );
1492 	return 1;
1493 }
1494 #endif
1495 
1496 /****************************************************************************
1497  * M6808 almost (fully?) equal to the M6800
1498  ****************************************************************************/
1499 #if (HAS_M6808)
m6808_reset(void * param)1500 void m6808_reset(void *param)
1501 {
1502 	m6800_reset(param);
1503 //	m6800.subtype = SUBTYPE_M6808;
1504 }
m6808_exit(void)1505 void m6808_exit(void) { m6800_exit(); }
m6808_execute(int cycles)1506 int  m6808_execute(int cycles) { return m6800_execute(cycles); }
m6808_get_context(void * dst)1507 unsigned m6808_get_context(void *dst) { return m6800_get_context(dst); }
m6808_set_context(void * src)1508 void m6808_set_context(void *src) { m6800_set_context(src); }
m6808_get_pc(void)1509 unsigned m6808_get_pc(void) { return m6800_get_pc(); }
m6808_set_pc(unsigned val)1510 void m6808_set_pc(unsigned val) { m6800_set_pc(val); }
m6808_get_sp(void)1511 unsigned m6808_get_sp(void) { return m6800_get_sp(); }
m6808_set_sp(unsigned val)1512 void m6808_set_sp(unsigned val) { m6800_set_sp(val); }
m6808_get_reg(int regnum)1513 unsigned m6808_get_reg(int regnum) { return m6800_get_reg(regnum); }
m6808_set_reg(int regnum,unsigned val)1514 void m6808_set_reg(int regnum, unsigned val) { m6800_set_reg(regnum,val); }
m6808_set_nmi_line(int state)1515 void m6808_set_nmi_line(int state) { m6800_set_nmi_line(state); }
m6808_set_irq_line(int irqline,int state)1516 void m6808_set_irq_line(int irqline, int state) { m6800_set_irq_line(irqline,state); }
m6808_set_irq_callback(int (* callback)(int irqline))1517 void m6808_set_irq_callback(int (*callback)(int irqline)) { m6800_set_irq_callback(callback); }
m6808_state_save(void * file)1518 void m6808_state_save(void *file) { state_save(file,"m6808"); }
m6808_state_load(void * file)1519 void m6808_state_load(void *file) { state_load(file,"m6808"); }
m6808_info(void * context,int regnum)1520 const char *m6808_info(void *context, int regnum)
1521 {
1522 	switch( regnum )
1523 	{
1524 		case CPU_INFO_NAME: return "M6808";
1525 	}
1526 	return m6800_info(context,regnum);
1527 }
1528 
m6808_dasm(char * buffer,unsigned pc)1529 unsigned m6808_dasm(char *buffer, unsigned pc)
1530 {
1531 	sprintf( buffer, "$%02X", cpu_readmem16(pc) );
1532 	return 1;
1533 }
1534 #endif
1535 
1536 /****************************************************************************
1537  * HD63701 similiar to the M6800
1538  ****************************************************************************/
1539 #if (HAS_HD63701)
hd63701_reset(void * param)1540 void hd63701_reset(void *param)
1541 {
1542 	m6800_reset(param);
1543 //	m6800.subtype = SUBTYPE_HD63701;
1544 	m6800.insn = hd63701_insn;
1545 	m6800.cycles = cycles_63701;
1546 }
hd63701_exit(void)1547 void hd63701_exit(void) { m6800_exit(); }
1548 /****************************************************************************
1549  * Execute cycles CPU cycles. Return number of cycles really executed
1550  ****************************************************************************/
hd63701_execute(int cycles)1551 int hd63701_execute(int cycles)
1552 {
1553 	UINT8 ireg;
1554 	hd63701_ICount = cycles;
1555 
1556 	CLEANUP_conters;
1557 	INCREMENT_COUNTER(hd63701.extra_cycles);
1558 	hd63701.extra_cycles = 0;
1559 
1560 	if( hd63701.wai_state & (HD63701_WAI|HD63701_SLP) )
1561 	{
1562 		EAT_CYCLES;
1563 		goto getout;
1564 	}
1565 
1566 	do
1567 	{
1568 		pPPC = pPC;
1569 		ireg=M_RDOP(PCD);
1570 		PC++;
1571 
1572 		switch( ireg )
1573 		{
1574 			case 0x00: trap(); break;
1575 			case 0x01: nop(); break;
1576 			case 0x02: trap(); break;
1577 			case 0x03: trap(); break;
1578 			case 0x04: lsrd(); /* 6803 only */; break;
1579 			case 0x05: asld(); /* 6803 only */; break;
1580 			case 0x06: tap(); break;
1581 			case 0x07: tpa(); break;
1582 			case 0x08: inx(); break;
1583 			case 0x09: dex(); break;
1584 			case 0x0A: CLV; break;
1585 			case 0x0B: SEV; break;
1586 			case 0x0C: CLC; break;
1587 			case 0x0D: SEC; break;
1588 			case 0x0E: cli(); break;
1589 			case 0x0F: sei(); break;
1590 			case 0x10: sba(); break;
1591 			case 0x11: cba(); break;
1592 			case 0x12: undoc1(); break;
1593 			case 0x13: undoc2(); break;
1594 			case 0x14: trap(); break;
1595 			case 0x15: trap(); break;
1596 			case 0x16: tab(); break;
1597 			case 0x17: tba(); break;
1598 			case 0x18: xgdx(); /* HD63701YO only */; break;
1599 			case 0x19: daa(); break;
1600 			case 0x1a: slp(); break;
1601 			case 0x1b: aba(); break;
1602 			case 0x1c: trap(); break;
1603 			case 0x1d: trap(); break;
1604 			case 0x1e: trap(); break;
1605 			case 0x1f: trap(); break;
1606 			case 0x20: bra(); break;
1607 			case 0x21: brn(); break;
1608 			case 0x22: bhi(); break;
1609 			case 0x23: bls(); break;
1610 			case 0x24: bcc(); break;
1611 			case 0x25: bcs(); break;
1612 			case 0x26: bne(); break;
1613 			case 0x27: beq(); break;
1614 			case 0x28: bvc(); break;
1615 			case 0x29: bvs(); break;
1616 			case 0x2a: bpl(); break;
1617 			case 0x2b: bmi(); break;
1618 			case 0x2c: bge(); break;
1619 			case 0x2d: blt(); break;
1620 			case 0x2e: bgt(); break;
1621 			case 0x2f: ble(); break;
1622 			case 0x30: tsx(); break;
1623 			case 0x31: ins(); break;
1624 			case 0x32: pula(); break;
1625 			case 0x33: pulb(); break;
1626 			case 0x34: des(); break;
1627 			case 0x35: txs(); break;
1628 			case 0x36: psha(); break;
1629 			case 0x37: pshb(); break;
1630 			case 0x38: pulx(); /* 6803 only */ break;
1631 			case 0x39: rts(); break;
1632 			case 0x3a: abx(); /* 6803 only */ break;
1633 			case 0x3b: rti(); break;
1634 			case 0x3c: pshx(); /* 6803 only */ break;
1635 			case 0x3d: mul(); /* 6803 only */ break;
1636 			case 0x3e: wai(); break;
1637 			case 0x3f: swi(); break;
1638 			case 0x40: nega(); break;
1639 			case 0x41: trap(); break;
1640 			case 0x42: trap(); break;
1641 			case 0x43: coma(); break;
1642 			case 0x44: lsra(); break;
1643 			case 0x45: trap(); break;
1644 			case 0x46: rora(); break;
1645 			case 0x47: asra(); break;
1646 			case 0x48: asla(); break;
1647 			case 0x49: rola(); break;
1648 			case 0x4a: deca(); break;
1649 			case 0x4b: trap(); break;
1650 			case 0x4c: inca(); break;
1651 			case 0x4d: tsta(); break;
1652 			case 0x4e: trap(); break;
1653 			case 0x4f: clra(); break;
1654 			case 0x50: negb(); break;
1655 			case 0x51: trap(); break;
1656 			case 0x52: trap(); break;
1657 			case 0x53: comb(); break;
1658 			case 0x54: lsrb(); break;
1659 			case 0x55: trap(); break;
1660 			case 0x56: rorb(); break;
1661 			case 0x57: asrb(); break;
1662 			case 0x58: aslb(); break;
1663 			case 0x59: rolb(); break;
1664 			case 0x5a: decb(); break;
1665 			case 0x5b: trap(); break;
1666 			case 0x5c: incb(); break;
1667 			case 0x5d: tstb(); break;
1668 			case 0x5e: trap(); break;
1669 			case 0x5f: clrb(); break;
1670 			case 0x60: neg_ix(); break;
1671 			case 0x61: aim_ix(); /* HD63701YO only */; break;
1672 			case 0x62: oim_ix(); /* HD63701YO only */; break;
1673 			case 0x63: com_ix(); break;
1674 			case 0x64: lsr_ix(); break;
1675 			case 0x65: eim_ix(); /* HD63701YO only */; break;
1676 			case 0x66: ror_ix(); break;
1677 			case 0x67: asr_ix(); break;
1678 			case 0x68: asl_ix(); break;
1679 			case 0x69: rol_ix(); break;
1680 			case 0x6a: dec_ix(); break;
1681 			case 0x6b: tim_ix(); /* HD63701YO only */; break;
1682 			case 0x6c: inc_ix(); break;
1683 			case 0x6d: tst_ix(); break;
1684 			case 0x6e: jmp_ix(); break;
1685 			case 0x6f: clr_ix(); break;
1686 			case 0x70: neg_ex(); break;
1687 			case 0x71: aim_di(); /* HD63701YO only */; break;
1688 			case 0x72: oim_di(); /* HD63701YO only */; break;
1689 			case 0x73: com_ex(); break;
1690 			case 0x74: lsr_ex(); break;
1691 			case 0x75: eim_di(); /* HD63701YO only */; break;
1692 			case 0x76: ror_ex(); break;
1693 			case 0x77: asr_ex(); break;
1694 			case 0x78: asl_ex(); break;
1695 			case 0x79: rol_ex(); break;
1696 			case 0x7a: dec_ex(); break;
1697 			case 0x7b: tim_di(); /* HD63701YO only */; break;
1698 			case 0x7c: inc_ex(); break;
1699 			case 0x7d: tst_ex(); break;
1700 			case 0x7e: jmp_ex(); break;
1701 			case 0x7f: clr_ex(); break;
1702 			case 0x80: suba_im(); break;
1703 			case 0x81: cmpa_im(); break;
1704 			case 0x82: sbca_im(); break;
1705 			case 0x83: subd_im(); /* 6803 only */ break;
1706 			case 0x84: anda_im(); break;
1707 			case 0x85: bita_im(); break;
1708 			case 0x86: lda_im(); break;
1709 			case 0x87: sta_im(); break;
1710 			case 0x88: eora_im(); break;
1711 			case 0x89: adca_im(); break;
1712 			case 0x8a: ora_im(); break;
1713 			case 0x8b: adda_im(); break;
1714 			case 0x8c: cpx_im(); /* 6803 difference */ break;
1715 			case 0x8d: bsr(); break;
1716 			case 0x8e: lds_im(); break;
1717 			case 0x8f: sts_im(); /* orthogonality */ break;
1718 			case 0x90: suba_di(); break;
1719 			case 0x91: cmpa_di(); break;
1720 			case 0x92: sbca_di(); break;
1721 			case 0x93: subd_di(); /* 6803 only */ break;
1722 			case 0x94: anda_di(); break;
1723 			case 0x95: bita_di(); break;
1724 			case 0x96: lda_di(); break;
1725 			case 0x97: sta_di(); break;
1726 			case 0x98: eora_di(); break;
1727 			case 0x99: adca_di(); break;
1728 			case 0x9a: ora_di(); break;
1729 			case 0x9b: adda_di(); break;
1730 			case 0x9c: cpx_di(); /* 6803 difference */ break;
1731 			case 0x9d: jsr_di(); break;
1732 			case 0x9e: lds_di(); break;
1733 			case 0x9f: sts_di(); break;
1734 			case 0xa0: suba_ix(); break;
1735 			case 0xa1: cmpa_ix(); break;
1736 			case 0xa2: sbca_ix(); break;
1737 			case 0xa3: subd_ix(); /* 6803 only */ break;
1738 			case 0xa4: anda_ix(); break;
1739 			case 0xa5: bita_ix(); break;
1740 			case 0xa6: lda_ix(); break;
1741 			case 0xa7: sta_ix(); break;
1742 			case 0xa8: eora_ix(); break;
1743 			case 0xa9: adca_ix(); break;
1744 			case 0xaa: ora_ix(); break;
1745 			case 0xab: adda_ix(); break;
1746 			case 0xac: cpx_ix(); /* 6803 difference */ break;
1747 			case 0xad: jsr_ix(); break;
1748 			case 0xae: lds_ix(); break;
1749 			case 0xaf: sts_ix(); break;
1750 			case 0xb0: suba_ex(); break;
1751 			case 0xb1: cmpa_ex(); break;
1752 			case 0xb2: sbca_ex(); break;
1753 			case 0xb3: subd_ex(); /* 6803 only */ break;
1754 			case 0xb4: anda_ex(); break;
1755 			case 0xb5: bita_ex(); break;
1756 			case 0xb6: lda_ex(); break;
1757 			case 0xb7: sta_ex(); break;
1758 			case 0xb8: eora_ex(); break;
1759 			case 0xb9: adca_ex(); break;
1760 			case 0xba: ora_ex(); break;
1761 			case 0xbb: adda_ex(); break;
1762 			case 0xbc: cpx_ex(); /* 6803 difference */ break;
1763 			case 0xbd: jsr_ex(); break;
1764 			case 0xbe: lds_ex(); break;
1765 			case 0xbf: sts_ex(); break;
1766 			case 0xc0: subb_im(); break;
1767 			case 0xc1: cmpb_im(); break;
1768 			case 0xc2: sbcb_im(); break;
1769 			case 0xc3: addd_im(); /* 6803 only */ break;
1770 			case 0xc4: andb_im(); break;
1771 			case 0xc5: bitb_im(); break;
1772 			case 0xc6: ldb_im(); break;
1773 			case 0xc7: stb_im(); break;
1774 			case 0xc8: eorb_im(); break;
1775 			case 0xc9: adcb_im(); break;
1776 			case 0xca: orb_im(); break;
1777 			case 0xcb: addb_im(); break;
1778 			case 0xcc: ldd_im(); /* 6803 only */ break;
1779 			case 0xcd: std_im(); /* 6803 only -- orthogonality */ break;
1780 			case 0xce: ldx_im(); break;
1781 			case 0xcf: stx_im(); break;
1782 			case 0xd0: subb_di(); break;
1783 			case 0xd1: cmpb_di(); break;
1784 			case 0xd2: sbcb_di(); break;
1785 			case 0xd3: addd_di(); /* 6803 only */ break;
1786 			case 0xd4: andb_di(); break;
1787 			case 0xd5: bitb_di(); break;
1788 			case 0xd6: ldb_di(); break;
1789 			case 0xd7: stb_di(); break;
1790 			case 0xd8: eorb_di(); break;
1791 			case 0xd9: adcb_di(); break;
1792 			case 0xda: orb_di(); break;
1793 			case 0xdb: addb_di(); break;
1794 			case 0xdc: ldd_di(); /* 6803 only */ break;
1795 			case 0xdd: std_di(); /* 6803 only */ break;
1796 			case 0xde: ldx_di(); break;
1797 			case 0xdf: stx_di(); break;
1798 			case 0xe0: subb_ix(); break;
1799 			case 0xe1: cmpb_ix(); break;
1800 			case 0xe2: sbcb_ix(); break;
1801 			case 0xe3: addd_ix(); /* 6803 only */ break;
1802 			case 0xe4: andb_ix(); break;
1803 			case 0xe5: bitb_ix(); break;
1804 			case 0xe6: ldb_ix(); break;
1805 			case 0xe7: stb_ix(); break;
1806 			case 0xe8: eorb_ix(); break;
1807 			case 0xe9: adcb_ix(); break;
1808 			case 0xea: orb_ix(); break;
1809 			case 0xeb: addb_ix(); break;
1810 			case 0xec: ldd_ix(); /* 6803 only */ break;
1811 			case 0xed: std_ix(); /* 6803 only */ break;
1812 			case 0xee: ldx_ix(); break;
1813 			case 0xef: stx_ix(); break;
1814 			case 0xf0: subb_ex(); break;
1815 			case 0xf1: cmpb_ex(); break;
1816 			case 0xf2: sbcb_ex(); break;
1817 			case 0xf3: addd_ex(); /* 6803 only */ break;
1818 			case 0xf4: andb_ex(); break;
1819 			case 0xf5: bitb_ex(); break;
1820 			case 0xf6: ldb_ex(); break;
1821 			case 0xf7: stb_ex(); break;
1822 			case 0xf8: eorb_ex(); break;
1823 			case 0xf9: adcb_ex(); break;
1824 			case 0xfa: orb_ex(); break;
1825 			case 0xfb: addb_ex(); break;
1826 			case 0xfc: ldd_ex(); /* 6803 only */ break;
1827 			case 0xfd: std_ex(); /* 6803 only */ break;
1828 			case 0xfe: ldx_ex(); break;
1829 			case 0xff: stx_ex(); break;
1830 		}
1831 		INCREMENT_COUNTER(cycles_63701[ireg]);
1832 	} while( hd63701_ICount>0 );
1833 
1834 getout:
1835 	INCREMENT_COUNTER(hd63701.extra_cycles);
1836 	hd63701.extra_cycles = 0;
1837 
1838 	return cycles - hd63701_ICount;
1839 }
1840 
hd63701_get_context(void * dst)1841 unsigned hd63701_get_context(void *dst) { return m6800_get_context(dst); }
hd63701_set_context(void * src)1842 void hd63701_set_context(void *src) { m6800_set_context(src); }
hd63701_get_pc(void)1843 unsigned hd63701_get_pc(void) { return m6800_get_pc(); }
hd63701_set_pc(unsigned val)1844 void hd63701_set_pc(unsigned val) { m6800_set_pc(val); }
hd63701_get_sp(void)1845 unsigned hd63701_get_sp(void) { return m6800_get_sp(); }
hd63701_set_sp(unsigned val)1846 void hd63701_set_sp(unsigned val) { m6800_set_sp(val); }
hd63701_get_reg(int regnum)1847 unsigned hd63701_get_reg(int regnum) { return m6800_get_reg(regnum); }
hd63701_set_reg(int regnum,unsigned val)1848 void hd63701_set_reg(int regnum, unsigned val) { m6800_set_reg(regnum,val); }
hd63701_set_nmi_line(int state)1849 void hd63701_set_nmi_line(int state) { m6800_set_nmi_line(state); }
hd63701_set_irq_line(int irqline,int state)1850 void hd63701_set_irq_line(int irqline, int state) { m6800_set_irq_line(irqline,state); }
hd63701_set_irq_callback(int (* callback)(int irqline))1851 void hd63701_set_irq_callback(int (*callback)(int irqline)) { m6800_set_irq_callback(callback); }
hd63701_state_save(void * file)1852 void hd63701_state_save(void *file) { state_save(file,"hd63701"); }
hd63701_state_load(void * file)1853 void hd63701_state_load(void *file) { state_load(file,"hd63701"); }
hd63701_info(void * context,int regnum)1854 const char *hd63701_info(void *context, int regnum)
1855 {
1856 	switch( regnum )
1857 	{
1858 		case CPU_INFO_NAME: return "HD63701";
1859 	}
1860 	return m6800_info(context,regnum);
1861 }
1862 
1863 /*
1864 	if change_pc() direccted these areas ,Call hd63701_trap_pc().
1865 	'mode' is selected by the sense of p2.0,p2.1,and p2.3 at reset timming.
1866 	mode 0,1,2,4,6 : $0000-$001f
1867 	mode 5         : $0000-$001f,$0200-$efff
1868 	mode 7         : $0000-$001f,$0100-$efff
1869 */
hd63701_trap_pc(void)1870 void hd63701_trap_pc(void)
1871 {
1872 	TAKE_TRAP;
1873 }
1874 
READ_HANDLER(hd63701_internal_registers_r)1875 READ_HANDLER( hd63701_internal_registers_r )
1876 {
1877 	return m6803_internal_registers_r(offset);
1878 }
1879 
WRITE_HANDLER(hd63701_internal_registers_w)1880 WRITE_HANDLER( hd63701_internal_registers_w )
1881 {
1882 	m6803_internal_registers_w(offset,data);
1883 }
1884 
hd63701_dasm(char * buffer,unsigned pc)1885 unsigned hd63701_dasm(char *buffer, unsigned pc)
1886 {
1887 	sprintf( buffer, "$%02X", cpu_readmem16(pc) );
1888 	return 1;
1889 }
1890 #endif
1891 
1892 /****************************************************************************
1893  * NSC-8105 similiar to the M6800, but the opcodes are scrambled and there
1894  * is at least one new opcode ($fc)
1895  ****************************************************************************/
1896 #if (HAS_NSC8105)
nsc8105_reset(void * param)1897 void nsc8105_reset(void *param)
1898 {
1899 	m6800_reset(param);
1900 //	m6800.subtype = SUBTYPE_NSC8105;
1901 	m6800.insn = nsc8105_insn;
1902 	m6800.cycles = cycles_nsc8105;
1903 }
nsc8105_exit(void)1904 void nsc8105_exit(void) { m6800_exit(); }
1905 /****************************************************************************
1906  * Execute cycles CPU cycles. Return number of cycles really executed
1907  ****************************************************************************/
nsc8105_execute(int cycles)1908 int nsc8105_execute(int cycles)
1909 {
1910 	UINT8 ireg;
1911 	nsc8105_ICount = cycles;
1912 
1913 	CLEANUP_conters;
1914 	INCREMENT_COUNTER(nsc8105.extra_cycles);
1915 	nsc8105.extra_cycles = 0;
1916 
1917 	if( nsc8105.wai_state & NSC8105_WAI )
1918 	{
1919 		EAT_CYCLES;
1920 		goto getout;
1921 	}
1922 
1923 	do
1924 	{
1925 		pPPC = pPC;
1926 		ireg=M_RDOP(PCD);
1927 		PC++;
1928 
1929 		switch( ireg )
1930 		{
1931 			case 0x00: illegal(); break;
1932 			case 0x01: illegal(); break;
1933 			case 0x02: nop(); break;
1934 			case 0x03: illegal(); break;
1935 			case 0x04: illegal(); break;
1936 			case 0x05: tap(); break;
1937 			case 0x06: illegal(); break;
1938 			case 0x07: tpa(); break;
1939 			case 0x08: inx(); break;
1940 			case 0x09: CLV; break;
1941 			case 0x0a: dex(); break;
1942 			case 0x0b: SEV; break;
1943 			case 0x0c: CLC; break;
1944 			case 0x0d: cli(); break;
1945 			case 0x0e: SEC; break;
1946 			case 0x0f: sei(); break;
1947 			case 0x10: sba(); break;
1948 			case 0x11: illegal(); break;
1949 			case 0x12: cba(); break;
1950 			case 0x13: illegal(); break;
1951 			case 0x14: illegal(); break;
1952 			case 0x15: tab(); break;
1953 			case 0x16: illegal(); break;
1954 			case 0x17: tba(); break;
1955 			case 0x18: illegal(); break;
1956 			case 0x19: illegal(); break;
1957 			case 0x1a: daa(); break;
1958 			case 0x1b: aba(); break;
1959 			case 0x1c: illegal(); break;
1960 			case 0x1d: illegal(); break;
1961 			case 0x1e: illegal(); break;
1962 			case 0x1f: illegal(); break;
1963 			case 0x20: bra(); break;
1964 			case 0x21: bhi(); break;
1965 			case 0x22: brn(); break;
1966 			case 0x23: bls(); break;
1967 			case 0x24: bcc(); break;
1968 			case 0x25: bne(); break;
1969 			case 0x26: bcs(); break;
1970 			case 0x27: beq(); break;
1971 			case 0x28: bvc(); break;
1972 			case 0x29: bpl(); break;
1973 			case 0x2a: bvs(); break;
1974 			case 0x2b: bmi(); break;
1975 			case 0x2c: bge(); break;
1976 			case 0x2d: bgt(); break;
1977 			case 0x2e: blt(); break;
1978 			case 0x2f: ble(); break;
1979 			case 0x30: tsx(); break;
1980 			case 0x31: pula(); break;
1981 			case 0x32: ins(); break;
1982 			case 0x33: pulb(); break;
1983 			case 0x34: des(); break;
1984 			case 0x35: psha(); break;
1985 			case 0x36: txs(); break;
1986 			case 0x37: pshb(); break;
1987 			case 0x38: illegal(); break;
1988 			case 0x39: illegal(); break;
1989 			case 0x3a: rts(); break;
1990 			case 0x3b: rti(); break;
1991 			case 0x3c: illegal(); break;
1992 			case 0x3d: wai(); break;
1993 			case 0x3e: illegal(); break;
1994 			case 0x3f: swi(); break;
1995 			case 0x40: suba_im(); break;
1996 			case 0x41: sbca_im(); break;
1997 			case 0x42: cmpa_im(); break;
1998 			case 0x43: illegal(); break;
1999 			case 0x44: anda_im(); break;
2000 			case 0x45: lda_im(); break;
2001 			case 0x46: bita_im(); break;
2002 			case 0x47: sta_im(); break;
2003 			case 0x48: eora_im(); break;
2004 			case 0x49: ora_im(); break;
2005 			case 0x4a: adca_im(); break;
2006 			case 0x4b: adda_im(); break;
2007 			case 0x4c: cmpx_im(); break;
2008 			case 0x4d: lds_im(); break;
2009 			case 0x4e: bsr(); break;
2010 			case 0x4f: sts_im(); /* orthogonality */ break;
2011 			case 0x50: suba_di(); break;
2012 			case 0x51: sbca_di(); break;
2013 			case 0x52: cmpa_di(); break;
2014 			case 0x53: illegal(); break;
2015 			case 0x54: anda_di(); break;
2016 			case 0x55: lda_di(); break;
2017 			case 0x56: bita_di(); break;
2018 			case 0x57: sta_di(); break;
2019 			case 0x58: eora_di(); break;
2020 			case 0x59: ora_di(); break;
2021 			case 0x5a: adca_di(); break;
2022 			case 0x5b: adda_di(); break;
2023 			case 0x5c: cmpx_di(); break;
2024 			case 0x5d: lds_di(); break;
2025 			case 0x5e: jsr_di(); break;
2026 			case 0x5f: sts_di(); break;
2027 			case 0x60: suba_ix(); break;
2028 			case 0x61: sbca_ix(); break;
2029 			case 0x62: cmpa_ix(); break;
2030 			case 0x63: illegal(); break;
2031 			case 0x64: anda_ix(); break;
2032 			case 0x65: lda_ix(); break;
2033 			case 0x66: bita_ix(); break;
2034 			case 0x67: sta_ix(); break;
2035 			case 0x68: eora_ix(); break;
2036 			case 0x69: ora_ix(); break;
2037 			case 0x6a: adca_ix(); break;
2038 			case 0x6b: adda_ix(); break;
2039 			case 0x6c: cmpx_ix(); break;
2040 			case 0x6d: lds_ix(); break;
2041 			case 0x6e: jsr_ix(); break;
2042 			case 0x6f: sts_ix(); break;
2043 			case 0x70: suba_ex(); break;
2044 			case 0x71: sbca_ex(); break;
2045 			case 0x72: cmpa_ex(); break;
2046 			case 0x73: illegal(); break;
2047 			case 0x74: anda_ex(); break;
2048 			case 0x75: lda_ex(); break;
2049 			case 0x76: bita_ex(); break;
2050 			case 0x77: sta_ex(); break;
2051 			case 0x78: eora_ex(); break;
2052 			case 0x79: ora_ex(); break;
2053 			case 0x7a: adca_ex(); break;
2054 			case 0x7b: adda_ex(); break;
2055 			case 0x7c: cmpx_ex(); break;
2056 			case 0x7d: lds_ex(); break;
2057 			case 0x7e: jsr_ex(); break;
2058 			case 0x7f: sts_ex(); break;
2059 			case 0x80: nega(); break;
2060 			case 0x81: illegal(); break;
2061 			case 0x82: illegal(); break;
2062 			case 0x83: coma(); break;
2063 			case 0x84: lsra(); break;
2064 			case 0x85: rora(); break;
2065 			case 0x86: illegal(); break;
2066 			case 0x87: asra(); break;
2067 			case 0x88: asla(); break;
2068 			case 0x89: deca(); break;
2069 			case 0x8a: rola(); break;
2070 			case 0x8b: illegal(); break;
2071 			case 0x8c: inca(); break;
2072 			case 0x8d: illegal(); break;
2073 			case 0x8e: tsta(); break;
2074 			case 0x8f: clra(); break;
2075 			case 0x90: negb(); break;
2076 			case 0x91: illegal(); break;
2077 			case 0x92: illegal(); break;
2078 			case 0x93: comb(); break;
2079 			case 0x94: lsrb(); break;
2080 			case 0x95: rorb(); break;
2081 			case 0x96: illegal(); break;
2082 			case 0x97: asrb(); break;
2083 			case 0x98: aslb(); break;
2084 			case 0x99: decb(); break;
2085 			case 0x9a: rolb(); break;
2086 			case 0x9b: illegal(); break;
2087 			case 0x9c: incb(); break;
2088 			case 0x9d: illegal(); break;
2089 			case 0x9e: tstb(); break;
2090 			case 0x9f: clrb(); break;
2091 			case 0xa0: neg_ix(); break;
2092 			case 0xa1: illegal(); break;
2093 			case 0xa2: illegal(); break;
2094 			case 0xa3: com_ix(); break;
2095 			case 0xa4: lsr_ix(); break;
2096 			case 0xa5: ror_ix(); break;
2097 			case 0xa6: illegal(); break;
2098 			case 0xa7: asr_ix(); break;
2099 			case 0xa8: asl_ix(); break;
2100 			case 0xa9: dec_ix(); break;
2101 			case 0xaa: rol_ix(); break;
2102 			case 0xab: illegal(); break;
2103 			case 0xac: inc_ix(); break;
2104 			case 0xad: jmp_ix(); break;
2105 			case 0xae: tst_ix(); break;
2106 			case 0xaf: clr_ix(); break;
2107 			case 0xb0: neg_ex(); break;
2108 			case 0xb1: illegal(); break;
2109 			case 0xb2: illegal(); break;
2110 			case 0xb3: com_ex(); break;
2111 			case 0xb4: lsr_ex(); break;
2112 			case 0xb5: ror_ex(); break;
2113 			case 0xb6: illegal(); break;
2114 			case 0xb7: asr_ex(); break;
2115 			case 0xb8: asl_ex(); break;
2116 			case 0xb9: dec_ex(); break;
2117 			case 0xba: rol_ex(); break;
2118 			case 0xbb: illegal(); break;
2119 			case 0xbc: inc_ex(); break;
2120 			case 0xbd: jmp_ex(); break;
2121 			case 0xbe: tst_ex(); break;
2122 			case 0xbf: clr_ex(); break;
2123 			case 0xc0: subb_im(); break;
2124 			case 0xc1: sbcb_im(); break;
2125 			case 0xc2: cmpb_im(); break;
2126 			case 0xc3: illegal(); break;
2127 			case 0xc4: andb_im(); break;
2128 			case 0xc5: ldb_im(); break;
2129 			case 0xc6: bitb_im(); break;
2130 			case 0xc7: stb_im(); break;
2131 			case 0xc8: eorb_im(); break;
2132 			case 0xc9: orb_im(); break;
2133 			case 0xca: adcb_im(); break;
2134 			case 0xcb: addb_im(); break;
2135 			case 0xcc: illegal(); break;
2136 			case 0xcd: ldx_im(); break;
2137 			case 0xce: illegal(); break;
2138 			case 0xcf: stx_im(); break;
2139 			case 0xd0: subb_di(); break;
2140 			case 0xd1: sbcb_di(); break;
2141 			case 0xd2: cmpb_di(); break;
2142 			case 0xd3: illegal(); break;
2143 			case 0xd4: andb_di(); break;
2144 			case 0xd5: ldb_di(); break;
2145 			case 0xd6: bitb_di(); break;
2146 			case 0xd7: stb_di(); break;
2147 			case 0xd8: eorb_di(); break;
2148 			case 0xd9: orb_di(); break;
2149 			case 0xda: adcb_di(); break;
2150 			case 0xdb: addb_di(); break;
2151 			case 0xdc: illegal(); break;
2152 			case 0xdd: ldx_di(); break;
2153 			case 0xde: illegal(); break;
2154 			case 0xdf: stx_di(); break;
2155 			case 0xe0: subb_ix(); break;
2156 			case 0xe1: sbcb_ix(); break;
2157 			case 0xe2: cmpb_ix(); break;
2158 			case 0xe3: illegal(); break;
2159 			case 0xe4: andb_ix(); break;
2160 			case 0xe5: ldb_ix(); break;
2161 			case 0xe6: bitb_ix(); break;
2162 			case 0xe7: stb_ix(); break;
2163 			case 0xe8: eorb_ix(); break;
2164 			case 0xe9: orb_ix(); break;
2165 			case 0xea: adcb_ix(); break;
2166 			case 0xeb: addb_ix(); break;
2167 			case 0xec: illegal(); break;
2168 			case 0xed: ldx_ix(); break;
2169 			case 0xee: illegal(); break;
2170 			case 0xef: stx_ix(); break;
2171 			case 0xf0: subb_ex(); break;
2172 			case 0xf1: sbcb_ex(); break;
2173 			case 0xf2: cmpb_ex(); break;
2174 			case 0xf3: illegal(); break;
2175 			case 0xf4: andb_ex(); break;
2176 			case 0xf5: ldb_ex(); break;
2177 			case 0xf6: bitb_ex(); break;
2178 			case 0xf7: stb_ex(); break;
2179 			case 0xf8: eorb_ex(); break;
2180 			case 0xf9: orb_ex(); break;
2181 			case 0xfa: adcb_ex(); break;
2182 			case 0xfb: addb_ex(); break;
2183 			case 0xfc: addx_ex(); break;
2184 			case 0xfd: ldx_ex(); break;
2185 			case 0xfe: illegal(); break;
2186 			case 0xff: stx_ex(); break;
2187 		}
2188 		INCREMENT_COUNTER(cycles_nsc8105[ireg]);
2189 	} while( nsc8105_ICount>0 );
2190 
2191 getout:
2192 	INCREMENT_COUNTER(nsc8105.extra_cycles);
2193 	nsc8105.extra_cycles = 0;
2194 
2195 	return cycles - nsc8105_ICount;
2196 }
2197 
nsc8105_get_context(void * dst)2198 unsigned nsc8105_get_context(void *dst) { return m6800_get_context(dst); }
nsc8105_set_context(void * src)2199 void nsc8105_set_context(void *src) { m6800_set_context(src); }
nsc8105_get_pc(void)2200 unsigned nsc8105_get_pc(void) { return m6800_get_pc(); }
nsc8105_set_pc(unsigned val)2201 void nsc8105_set_pc(unsigned val) { m6800_set_pc(val); }
nsc8105_get_sp(void)2202 unsigned nsc8105_get_sp(void) { return m6800_get_sp(); }
nsc8105_set_sp(unsigned val)2203 void nsc8105_set_sp(unsigned val) { m6800_set_sp(val); }
nsc8105_get_reg(int regnum)2204 unsigned nsc8105_get_reg(int regnum) { return m6800_get_reg(regnum); }
nsc8105_set_reg(int regnum,unsigned val)2205 void nsc8105_set_reg(int regnum, unsigned val) { m6800_set_reg(regnum,val); }
nsc8105_set_nmi_line(int state)2206 void nsc8105_set_nmi_line(int state) { m6800_set_nmi_line(state); }
nsc8105_set_irq_line(int irqline,int state)2207 void nsc8105_set_irq_line(int irqline, int state) { m6800_set_irq_line(irqline,state); }
nsc8105_set_irq_callback(int (* callback)(int irqline))2208 void nsc8105_set_irq_callback(int (*callback)(int irqline)) { m6800_set_irq_callback(callback); }
nsc8105_state_save(void * file)2209 void nsc8105_state_save(void *file) { state_save(file,"nsc8105"); }
nsc8105_state_load(void * file)2210 void nsc8105_state_load(void *file) { state_load(file,"nsc8105"); }
nsc8105_info(void * context,int regnum)2211 const char *nsc8105_info(void *context, int regnum)
2212 {
2213 	switch( regnum )
2214 	{
2215 		case CPU_INFO_NAME: return "NSC8105";
2216 	}
2217 	return m6800_info(context,regnum);
2218 }
2219 
nsc8105_dasm(char * buffer,unsigned pc)2220 unsigned nsc8105_dasm(char *buffer, unsigned pc)
2221 {
2222 	sprintf( buffer, "$%02X", cpu_readmem16(pc) );
2223 	return 1;
2224 }
2225 #endif
2226 
2227 
2228 #if (HAS_M6803||HAS_HD63701)
2229 
READ_HANDLER(m6803_internal_registers_r)2230 READ_HANDLER( m6803_internal_registers_r )
2231 {
2232 	switch (offset)
2233 	{
2234 		case 0x00:
2235 			return m6800.port1_ddr;
2236 		case 0x01:
2237 			return m6800.port2_ddr;
2238 		case 0x02:
2239 			return (cpu_readport(M6803_PORT1) & (m6800.port1_ddr ^ 0xff))
2240 					| (m6800.port1_data & m6800.port1_ddr);
2241 		case 0x03:
2242 			return (cpu_readport(M6803_PORT2) & (m6800.port2_ddr ^ 0xff))
2243 					| (m6800.port2_data & m6800.port2_ddr);
2244 		case 0x04:
2245 		case 0x05:
2246 		case 0x06:
2247 		case 0x07:
2248 			return 0;
2249 		case 0x08:
2250 			m6800.pending_tcsr = 0;
2251 			return m6800.tcsr;
2252 		case 0x09:
2253 			if(!(m6800.pending_tcsr&TCSR_TOF))
2254 			{
2255 				m6800.tcsr &= ~TCSR_TOF;
2256 				MODIFIED_tcsr;
2257 			}
2258 			return m6800.counter.b.h;
2259 		case 0x0a:
2260 			return m6800.counter.b.l;
2261 		case 0x0b:
2262 			if(!(m6800.pending_tcsr&TCSR_OCF))
2263 			{
2264 				m6800.tcsr &= ~TCSR_OCF;
2265 				MODIFIED_tcsr;
2266 			}
2267 			return m6800.output_compare.b.h;
2268 		case 0x0c:
2269 			if(!(m6800.pending_tcsr&TCSR_OCF))
2270 			{
2271 				m6800.tcsr &= ~TCSR_OCF;
2272 				MODIFIED_tcsr;
2273 			}
2274 			return m6800.output_compare.b.l;
2275 		case 0x0d:
2276 			if(!(m6800.pending_tcsr&TCSR_ICF))
2277 			{
2278 				m6800.tcsr &= ~TCSR_ICF;
2279 				MODIFIED_tcsr;
2280 			}
2281 			return (m6800.input_capture >> 0) & 0xff;
2282 		case 0x0e:
2283 			return (m6800.input_capture >> 8) & 0xff;
2284 		case 0x0f:
2285 		case 0x10:
2286 		case 0x11:
2287 		case 0x12:
2288 		case 0x13:
2289 			return 0;
2290 		case 0x14:
2291 			return m6800.ram_ctrl;
2292 		case 0x15:
2293 		case 0x16:
2294 		case 0x17:
2295 		case 0x18:
2296 		case 0x19:
2297 		case 0x1a:
2298 		case 0x1b:
2299 		case 0x1c:
2300 		case 0x1d:
2301 		case 0x1e:
2302 		case 0x1f:
2303 		default:
2304 			return 0;
2305 	}
2306 }
2307 
WRITE_HANDLER(m6803_internal_registers_w)2308 WRITE_HANDLER( m6803_internal_registers_w )
2309 {
2310 	static int latch09;
2311 
2312 	switch (offset)
2313 	{
2314 		case 0x00:
2315 			if (m6800.port1_ddr != data)
2316 			{
2317 				m6800.port1_ddr = data;
2318 				if(m6800.port1_ddr == 0xff)
2319 					cpu_writeport(M6803_PORT1,m6800.port1_data);
2320 				else
2321 					cpu_writeport(M6803_PORT1,(m6800.port1_data & m6800.port1_ddr)
2322 						| (cpu_readport(M6803_PORT1) & (m6800.port1_ddr ^ 0xff)));
2323 			}
2324 			break;
2325 		case 0x01:
2326 			if (m6800.port2_ddr != data)
2327 			{
2328 				m6800.port2_ddr = data;
2329 				if(m6800.port2_ddr == 0xff)
2330 					cpu_writeport(M6803_PORT2,m6800.port2_data);
2331 				else
2332 					cpu_writeport(M6803_PORT2,(m6800.port2_data & m6800.port2_ddr)
2333 						| (cpu_readport(M6803_PORT2) & (m6800.port2_ddr ^ 0xff)));
2334 			}
2335 			break;
2336 		case 0x02:
2337 			m6800.port1_data = data;
2338 			if(m6800.port1_ddr == 0xff)
2339 				cpu_writeport(M6803_PORT1,m6800.port1_data);
2340 			else
2341 				cpu_writeport(M6803_PORT1,(m6800.port1_data & m6800.port1_ddr)
2342 					| (cpu_readport(M6803_PORT1) & (m6800.port1_ddr ^ 0xff)));
2343 			break;
2344 		case 0x03:
2345 			m6800.port2_data = data;
2346 			m6800.port2_ddr = data;
2347 			if(m6800.port2_ddr == 0xff)
2348 				cpu_writeport(M6803_PORT2,m6800.port2_data);
2349 			else
2350 				cpu_writeport(M6803_PORT2,(m6800.port2_data & m6800.port2_ddr)
2351 					| (cpu_readport(M6803_PORT2) & (m6800.port2_ddr ^ 0xff)));
2352 			break;
2353 		case 0x04:
2354 		case 0x05:
2355 		case 0x06:
2356 		case 0x07:
2357 			break;
2358 		case 0x08:
2359 			m6800.tcsr = data;
2360 			m6800.pending_tcsr &= m6800.tcsr;
2361 			MODIFIED_tcsr;
2362 			if( !(CC & 0x10) )
2363 				CHECK_IRQ2;
2364 			break;
2365 		case 0x09:
2366 			latch09 = data & 0xff;	/* 6301 only */
2367 			CT  = 0xfff8;
2368 			TOH = CTH;
2369 			MODIFIED_counters;
2370 			break;
2371 		case 0x0a:	/* 6301 only */
2372 			CT = (latch09 << 8) | (data & 0xff);
2373 			TOH = CTH;
2374 			MODIFIED_counters;
2375 			break;
2376 		case 0x0b:
2377 			if( m6800.output_compare.b.h != data)
2378 			{
2379 				m6800.output_compare.b.h = data;
2380 				MODIFIED_counters;
2381 			}
2382 			break;
2383 		case 0x0c:
2384 			if( m6800.output_compare.b.l != data)
2385 			{
2386 				m6800.output_compare.b.l = data;
2387 				MODIFIED_counters;
2388 			}
2389 			break;
2390 		case 0x0d:
2391 		case 0x0e:
2392 			break;
2393 		case 0x0f:
2394 		case 0x10:
2395 		case 0x11:
2396 		case 0x12:
2397 		case 0x13:
2398 			break;
2399 		case 0x14:
2400 			m6800.ram_ctrl = data;
2401 			break;
2402 		case 0x15:
2403 		case 0x16:
2404 		case 0x17:
2405 		case 0x18:
2406 		case 0x19:
2407 		case 0x1a:
2408 		case 0x1b:
2409 		case 0x1c:
2410 		case 0x1d:
2411 		case 0x1e:
2412 		case 0x1f:
2413 		default:
2414 			break;
2415 	}
2416 }
2417 #endif
2418 
2419