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