1 /*** m6805: Portable 6805 emulator ******************************************
2 
3     m6805.c (Also supports hd68705 and hd63705 variants)
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   Additional Notes:
22 
23   K.Wilkins 18/03/99 - Added 63705 functonality and modified all CPU functions
24                        necessary to support:
25                            Variable width address bus
26                            Different stack pointer
27                            Alternate boot vectors
28                            Alternate interrups vectors
29 
30 
31 *****************************************************************************/
32 
33 #include "burnint.h"
34 #include "driver.h"
35 #include "m6805_intf.h"
36 #include <stddef.h>
37 
38 #define IRQ_LEVEL_DETECT 0
39 
40 #define M6805_INLINE static
41 
42 enum
43 {
44 	SUBTYPE_M6805,
45 	SUBTYPE_M68705,
46 	SUBTYPE_HD63705
47 };
48 
49 /* 6805 Registers */
50 typedef struct
51 {
52 	INT32 	subtype;		/* Which sub-type is being emulated */
53 	UINT32	sp_mask;		/* Stack pointer address mask */
54 	UINT32	sp_low; 		/* Stack pointer low water mark (or floor) */
55     PAIR    pc;             /* Program counter */
56 	PAIR	s;				/* Stack pointer */
57 	UINT8	a;				/* Accumulator */
58 	UINT8	x;				/* Index register */
59 	UINT8	cc; 			/* Condition codes */
60 
61 	UINT16	pending_interrupts; /* MB */
62 	INT32 	irq_state[9];		/* KW Additional lines for HD63705 */
63 	INT32   nmi_state;
64 	INT32   nTotalCycles;
65 	INT32   end_run;
66 	int 	(*irq_callback)(int irqline);
67 } m6805_Regs;
68 
69 /* 6805 registers */
70 static m6805_Regs m6805;
71 
72 #define SUBTYPE	m6805.subtype	/* CPU Type */
73 #define SP_MASK m6805.sp_mask	/* stack pointer mask */
74 #define SP_LOW	m6805.sp_low	/* stack pointer low water mark */
75 #define pPC 	m6805.pc		/* program counter PAIR */
76 #define PC		m6805.pc.w.l	/* program counter lower word */
77 #define S		m6805.s.w.l 	/* stack pointer lower word */
78 #define A		m6805.a 		/* accumulator */
79 #define X		m6805.x 		/* index register */
80 #define CC		m6805.cc		/* condition codes */
81 
82 static PAIR ea; 		/* effective address */
83 #define EAD ea.d
84 #define EA  ea.w.l
85 
86 /* public globals */
87 static int m6805_ICount=50000;
88 
89 /* DS -- THESE ARE RE-DEFINED IN m6805.h TO RAM, ROM or FUNCTIONS IN cpuintrf.c */
90 #define RM(Addr)			M6805_RDMEM(Addr)
91 #define WM(Addr,Value)		M6805_WRMEM(Addr,Value)
92 #define M_RDOP(Addr)        M6805_RDOP(Addr)
93 #define M_RDOP_ARG(Addr)	M6805_RDOP_ARG(Addr)
94 
95 /* macros to tweak the PC and SP */
96 #define SP_INC	if( ++S > SP_MASK) S = SP_LOW
97 #define SP_DEC	if( --S < SP_LOW) S = SP_MASK
98 #define SP_ADJUST(s) ( ( (s) & SP_MASK ) | SP_LOW )
99 
100 /* macros to access memory */
101 #define IMMBYTE(b) {b = M_RDOP_ARG(PC++);}
102 #define IMMWORD(w) {w.d = 0; w.b.h = M_RDOP_ARG(PC); w.b.l = M_RDOP_ARG(PC+1); PC+=2;}
103 #define SKIPBYTE() {M_RDOP_ARG(PC++);}
104 
105 #define PUSHBYTE(b) wr_s_handler_b(&b)
106 #define PUSHWORD(w) wr_s_handler_w(&w)
107 #define PULLBYTE(b) rd_s_handler_b(&b)
108 #define PULLWORD(w) rd_s_handler_w(&w)
109 
110 /* CC masks      H INZC
111               7654 3210 */
112 #define CFLAG 0x01
113 #define ZFLAG 0x02
114 #define NFLAG 0x04
115 #define IFLAG 0x08
116 #define HFLAG 0x10
117 
118 #define CLR_NZ	  CC&=~(NFLAG|ZFLAG)
119 #define CLR_HNZC  CC&=~(HFLAG|NFLAG|ZFLAG|CFLAG)
120 #define CLR_Z	  CC&=~(ZFLAG)
121 #define CLR_NZC   CC&=~(NFLAG|ZFLAG|CFLAG)
122 #define CLR_ZC	  CC&=~(ZFLAG|CFLAG)
123 
124 /* macros for CC -- CC bits affected should be reset before calling */
125 #define SET_Z(a)       if(!a)SEZ
126 #define SET_Z8(a)	   SET_Z((UINT8)a)
127 #define SET_N8(a)	   CC|=((a&0x80)>>5)
128 #define SET_H(a,b,r)   CC|=((a^b^r)&0x10)
129 #define SET_C8(a)	   CC|=((a&0x100)>>8)
130 
131 static const UINT8 flags8i[256]=	 /* increment */
132 {
133 	0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
134 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
136 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
137 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
138 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
139 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
140 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
141 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
142 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
143 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
144 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
145 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
146 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
147 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
148 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
149 };
150 static const UINT8 flags8d[256]= /* decrement */
151 {
152 	0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
153 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
154 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
155 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
156 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
157 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
158 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
159 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
160 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
161 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
162 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
163 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
164 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
165 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
166 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
167 	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
168 };
169 #define SET_FLAGS8I(a)		{CC|=flags8i[(a)&0xff];}
170 #define SET_FLAGS8D(a)		{CC|=flags8d[(a)&0xff];}
171 
172 /* combos */
173 #define SET_NZ8(a)			{SET_N8(a);SET_Z(a);}
174 #define SET_FLAGS8(a,b,r)	{SET_N8(r);SET_Z8(r);SET_C8(r);}
175 
176 /* for treating an unsigned UINT8 as a signed INT16 */
177 #define SIGNED(b) ((INT16)(b&0x80?b|0xff00:b))
178 
179 /* Macros for addressing modes */
180 #define DIRECT EAD=0;IMMBYTE(ea.b.l)
181 #define IMM8 EA=PC++
182 #define EXTENDED IMMWORD(ea)
183 #define INDEXED EA=X
184 #define INDEXED1 {EAD=0; IMMBYTE(ea.b.l); EA+=X;}
185 #define INDEXED2 {IMMWORD(ea); EA+=X;}
186 
187 /* macros to set status flags */
188 #if defined(SEC)
189 #undef SEC
190 #endif
191 #define SEC CC|=CFLAG
192 #define CLC CC&=~CFLAG
193 #define SEZ CC|=ZFLAG
194 #define CLZ CC&=~ZFLAG
195 #define SEN CC|=NFLAG
196 #define CLN CC&=~NFLAG
197 #define SEH CC|=HFLAG
198 #define CLH CC&=~HFLAG
199 #define SEI CC|=IFLAG
200 #define CLI CC&=~IFLAG
201 
202 /* macros for convenience */
203 #define DIRBYTE(b) {DIRECT;b=RM(EAD);}
204 #define EXTBYTE(b) {EXTENDED;b=RM(EAD);}
205 #define IDXBYTE(b) {INDEXED;b=RM(EAD);}
206 #define IDX1BYTE(b) {INDEXED1;b=RM(EAD);}
207 #define IDX2BYTE(b) {INDEXED2;b=RM(EAD);}
208 /* Macros for branch instructions */
209 #define BRANCH(f) { UINT8 t; IMMBYTE(t); if(f) { PC += SIGNED(t); } }
210 
211 /* what they say it is ... */
212 static const unsigned char cycles1[] =
213 {
214 		/* 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
215 	/*0*/ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
216 	/*1*/  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
217 	/*2*/  4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
218 	/*3*/  6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 0, 6, 6, 0,
219 	/*4*/  4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4,
220 	/*5*/  4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4,
221 	/*6*/  7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7,
222 	/*7*/  6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 6, 0, 6,
223 	/*8*/  9, 6, 0,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224 	/*9*/  0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2,
225 	/*A*/  2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 8, 2, 0,
226 	/*B*/  4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 7, 4, 5,
227 	/*C*/  5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 8, 5, 6,
228 	/*D*/  6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 5, 9, 6, 7,
229 	/*E*/  5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 8, 5, 6,
230 	/*F*/  4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 7, 4, 5
231 };
232 
233 
234 /* pre-clear a PAIR union; clearing h2 and h3 only might be faster? */
235 #define CLEAR_PAIR(p)   p->d = 0
236 
rd_s_handler_b(UINT8 * b)237 M6805_INLINE void rd_s_handler_b( UINT8 *b )
238 {
239 	SP_INC;
240 	*b = RM( S );
241 }
242 
rd_s_handler_w(PAIR * p)243 M6805_INLINE void rd_s_handler_w( PAIR *p )
244 {
245 	CLEAR_PAIR(p);
246 	SP_INC;
247 	p->b.h = RM( S );
248 	SP_INC;
249 	p->b.l = RM( S );
250 }
251 
wr_s_handler_b(UINT8 * b)252 M6805_INLINE void wr_s_handler_b( UINT8 *b )
253 {
254 	WM( S, *b );
255 	SP_DEC;
256 }
257 
wr_s_handler_w(PAIR * p)258 M6805_INLINE void wr_s_handler_w( PAIR *p )
259 {
260 	WM( S, p->b.l );
261     SP_DEC;
262 	WM( S, p->b.h );
263     SP_DEC;
264 }
265 
RM16(UINT32 Addr,PAIR * p)266 M6805_INLINE void RM16( UINT32 Addr, PAIR *p )
267 {
268 	CLEAR_PAIR(p);
269     p->b.h = RM(Addr);
270     ++Addr;
271 //  if( ++Addr > AMASK ) Addr = 0;
272 	p->b.l = RM(Addr);
273 }
274 
275 #ifdef UNUSED_FUNCTION
WM16(UINT32 Addr,PAIR * p)276 M6805_INLINE void WM16( UINT32 Addr, PAIR *p )
277 {
278 	WM( Addr, p->b.h );
279     ++Addr;
280 //  if( ++Addr > AMASK ) Addr = 0;
281 	WM( Addr, p->b.l );
282 }
283 #endif
284 
285 
286 /* Generate interrupt - m68705 version */
m68705_Interrupt(void)287 static void m68705_Interrupt(void)
288 {
289 	if( (m6805.pending_interrupts & ((1<<M6805_IRQ_LINE)|M68705_INT_MASK)) != 0 )
290 	{
291 		if ( (CC & IFLAG) == 0 )
292 		{
293 			PUSHWORD(m6805.pc);
294 			PUSHBYTE(m6805.x);
295 			PUSHBYTE(m6805.a);
296 			PUSHBYTE(m6805.cc);
297 			SEI;
298 			if (m6805.irq_callback)
299 				(*m6805.irq_callback)(0);
300 
301 			if ((m6805.pending_interrupts & (1<<M68705_IRQ_LINE)) != 0 )
302 			{
303 				m6805.pending_interrupts &= ~(1<<M68705_IRQ_LINE);
304 				RM16( 0xfffa, &pPC);
305 			}
306 			else if((m6805.pending_interrupts&(1<<M68705_INT_TIMER))!=0)
307 			{
308 				m6805.pending_interrupts &= ~(1<<M68705_INT_TIMER);
309 				RM16( 0xfff8, &pPC);
310 			}
311 		}
312 		m6805_ICount -= 11;
313 		m6805.nTotalCycles += 11;
314 	}
315 }
316 
317 /* Generate interrupts */
Interrupt(void)318 static void Interrupt(void)
319 {
320 	/* the 6805 latches interrupt requests internally, so we don't clear */
321 	/* pending_interrupts until the interrupt is taken, no matter what the */
322 	/* external IRQ pin does. */
323 
324 	if( (m6805.pending_interrupts & (1<<HD63705_INT_NMI)) != 0)
325 	{
326 		PUSHWORD(m6805.pc);
327 		PUSHBYTE(m6805.x);
328 		PUSHBYTE(m6805.a);
329 		PUSHBYTE(m6805.cc);
330         SEI;
331 		/* no vectors supported, just do the callback to clear irq_state if needed */
332 		if (m6805.irq_callback)
333 			(*m6805.irq_callback)(0);
334 
335 		RM16( 0x1ffc, &pPC);
336 		m6805.pending_interrupts &= ~(1<<HD63705_INT_NMI);
337 
338 		m6805_ICount -= 11;
339 		m6805.nTotalCycles += 11;
340 	}
341 	else if( (m6805.pending_interrupts & ((1<<M6805_IRQ_LINE)|HD63705_INT_MASK)) != 0 ) {
342 		if ( (CC & IFLAG) == 0 ) {
343 	{
344 		PUSHWORD(m6805.pc);
345 		PUSHBYTE(m6805.x);
346 		PUSHBYTE(m6805.a);
347 		PUSHBYTE(m6805.cc);
348         SEI;
349 		/* no vectors supported, just do the callback to clear irq_state if needed */
350 		if (m6805.irq_callback)
351 			(*m6805.irq_callback)(0);
352 
353 
354 //#if (HAS_HD63705)
355 		if(SUBTYPE==SUBTYPE_HD63705)
356 		{
357 			/* Need to add emulation of other interrupt sources here KW-2/4/99 */
358 			/* This is just a quick patch for Namco System 2 operation         */
359 
360 			if((m6805.pending_interrupts&(1<<HD63705_INT_IRQ1))!=0)
361 			{
362 				m6805.pending_interrupts &= ~(1<<HD63705_INT_IRQ1);
363 				RM16( 0x1ff8, &pPC);
364 			}
365 			else if((m6805.pending_interrupts&(1<<HD63705_INT_IRQ2))!=0)
366 			{
367 				m6805.pending_interrupts &= ~(1<<HD63705_INT_IRQ2);
368 				RM16( 0x1fec, &pPC);
369 			}
370 			else if((m6805.pending_interrupts&(1<<HD63705_INT_ADCONV))!=0)
371 			{
372 				m6805.pending_interrupts &= ~(1<<HD63705_INT_ADCONV);
373 				RM16( 0x1fea, &pPC);
374 			}
375 			else if((m6805.pending_interrupts&(1<<HD63705_INT_TIMER1))!=0)
376 			{
377 				m6805.pending_interrupts &= ~(1<<HD63705_INT_TIMER1);
378 				RM16( 0x1ff6, &pPC);
379 			}
380 			else if((m6805.pending_interrupts&(1<<HD63705_INT_TIMER2))!=0)
381 			{
382 				m6805.pending_interrupts &= ~(1<<HD63705_INT_TIMER2);
383 				RM16( 0x1ff4, &pPC);
384 			}
385 			else if((m6805.pending_interrupts&(1<<HD63705_INT_TIMER3))!=0)
386 			{
387 				m6805.pending_interrupts &= ~(1<<HD63705_INT_TIMER3);
388 				RM16( 0x1ff2, &pPC);
389 			}
390 			else if((m6805.pending_interrupts&(1<<HD63705_INT_PCI))!=0)
391 			{
392 				m6805.pending_interrupts &= ~(1<<HD63705_INT_PCI);
393 				RM16( 0x1ff0, &pPC);
394 			}
395 			else if((m6805.pending_interrupts&(1<<HD63705_INT_SCI))!=0)
396 			{
397 				m6805.pending_interrupts &= ~(1<<HD63705_INT_SCI);
398 				RM16( 0x1fee, &pPC);
399 			}
400 		}
401 		else
402 //#endif
403 		{
404 			RM16( 0xffff - 5, &pPC );
405 		}
406 
407 		}	// CC & IFLAG
408 			m6805.pending_interrupts &= ~(1<<M6805_IRQ_LINE);
409 		}
410 		m6805_ICount -= 11;
411 		m6805.nTotalCycles += 11;
412 	}
413 }
414 
m6805_reset()415 static void m6805_reset()
416 {
417 	int (*save_irqcallback)(int) = m6805.irq_callback;
418 	memset(&m6805, 0, sizeof(m6805));
419 	m6805.irq_callback = save_irqcallback;
420 	/* Force CPU sub-type and relevant masks */
421 	m6805.subtype	= SUBTYPE_M6805;
422 	SP_MASK = 0x07f;
423 	SP_LOW	= 0x060;
424 	/* Initial stack pointer */
425 	S = SP_MASK;
426 	/* IRQ disabled */
427     SEI;
428 	RM16( 0xfffe , &pPC );
429 }
430 
m6805Reset()431 void m6805Reset() {
432 #if defined FBNEO_DEBUG
433 	if (!DebugCPU_M6805Initted) bprintf(PRINT_ERROR, _T("m6805Reset called without init\n"));
434 #endif
435 
436 	m6805_reset();
437 }
438 
439 //static void m6805_init(int ) //int (*irqcallback)(int))
440 //{
441 //	m6805.irq_callback = irqcallback;
442 //}
443 
444 //static void m6805_exit(void)
445 //{
446 //	/* nothing to do */
447 //}
448 
449 
m6805SetIrqLine(int,int state)450 void m6805SetIrqLine(int , int state)
451 {
452 #if defined FBNEO_DEBUG
453 	if (!DebugCPU_M6805Initted) bprintf(PRINT_ERROR, _T("m6805SetIrqLine called without init\n"));
454 #endif
455 
456 	/* Basic 6805 only has one IRQ line */
457 	/* See HD63705 specific version     */
458 	if (m6805.irq_state[0] == state) return;
459 
460 	m6805.irq_state[0] = state;
461 	if (state != CLEAR_LINE)
462 		m6805.pending_interrupts |= 1<<M6805_IRQ_LINE;
463 }
464 
465 
466 #include "6805ops.c"
467 
468 
469 /* execute instructions on this CPU until icount expires */
m6805Run(int cycles)470 int m6805Run(int cycles)
471 {
472 #if defined FBNEO_DEBUG
473 	if (!DebugCPU_M6805Initted) bprintf(PRINT_ERROR, _T("m6805Run called without init\n"));
474 #endif
475 
476 	UINT8 ireg;
477 	m6805_ICount = cycles;
478 	S = SP_ADJUST( S );     /* Taken from CPU_SET_CONTEXT when pointer'afying */
479 
480 	m6805.end_run = 0;
481 
482 	do
483 	{
484 		if (m6805.pending_interrupts != 0)
485 		{
486 			if (SUBTYPE==SUBTYPE_M68705)
487 			{
488 				m68705_Interrupt();
489 			}
490 			else
491 			{
492 				Interrupt();
493 			}
494 		}
495 
496 		ireg=M_RDOP(PC++);
497 
498 		switch( ireg )
499 		{
500 			case 0x00: brset(0x01); break;
501 			case 0x01: brclr(0x01); break;
502 			case 0x02: brset(0x02); break;
503 			case 0x03: brclr(0x02); break;
504 			case 0x04: brset(0x04); break;
505 			case 0x05: brclr(0x04); break;
506 			case 0x06: brset(0x08); break;
507 			case 0x07: brclr(0x08); break;
508 			case 0x08: brset(0x10); break;
509 			case 0x09: brclr(0x10); break;
510 			case 0x0A: brset(0x20); break;
511 			case 0x0B: brclr(0x20); break;
512 			case 0x0C: brset(0x40); break;
513 			case 0x0D: brclr(0x40); break;
514 			case 0x0E: brset(0x80); break;
515 			case 0x0F: brclr(0x80); break;
516 			case 0x10: bset(0x01); break;
517 			case 0x11: bclr(0x01); break;
518 			case 0x12: bset(0x02); break;
519 			case 0x13: bclr(0x02); break;
520 			case 0x14: bset(0x04); break;
521 			case 0x15: bclr(0x04); break;
522 			case 0x16: bset(0x08); break;
523 			case 0x17: bclr(0x08); break;
524 			case 0x18: bset(0x10); break;
525 			case 0x19: bclr(0x10); break;
526 			case 0x1a: bset(0x20); break;
527 			case 0x1b: bclr(0x20); break;
528 			case 0x1c: bset(0x40); break;
529 			case 0x1d: bclr(0x40); break;
530 			case 0x1e: bset(0x80); break;
531 			case 0x1f: bclr(0x80); break;
532 			case 0x20: bra(); break;
533 			case 0x21: brn(); break;
534 			case 0x22: bhi(); break;
535 			case 0x23: bls(); break;
536 			case 0x24: bcc(); break;
537 			case 0x25: bcs(); break;
538 			case 0x26: bne(); break;
539 			case 0x27: beq(); break;
540 			case 0x28: bhcc(); break;
541 			case 0x29: bhcs(); break;
542 			case 0x2a: bpl(); break;
543 			case 0x2b: bmi(); break;
544 			case 0x2c: bmc(); break;
545 			case 0x2d: bms(); break;
546 			case 0x2e: bil(); break;
547 			case 0x2f: bih(); break;
548 			case 0x30: neg_di(); break;
549 			case 0x31: illegal(); break;
550 			case 0x32: illegal(); break;
551 			case 0x33: com_di(); break;
552 			case 0x34: lsr_di(); break;
553 			case 0x35: illegal(); break;
554 			case 0x36: ror_di(); break;
555 			case 0x37: asr_di(); break;
556 			case 0x38: lsl_di(); break;
557 			case 0x39: rol_di(); break;
558 			case 0x3a: dec_di(); break;
559 			case 0x3b: illegal(); break;
560 			case 0x3c: inc_di(); break;
561 			case 0x3d: tst_di(); break;
562 			case 0x3e: illegal(); break;
563 			case 0x3f: clr_di(); break;
564 			case 0x40: nega(); break;
565 			case 0x41: illegal(); break;
566 			case 0x42: illegal(); break;
567 			case 0x43: coma(); break;
568 			case 0x44: lsra(); break;
569 			case 0x45: illegal(); break;
570 			case 0x46: rora(); break;
571 			case 0x47: asra(); break;
572 			case 0x48: lsla(); break;
573 			case 0x49: rola(); break;
574 			case 0x4a: deca(); break;
575 			case 0x4b: illegal(); break;
576 			case 0x4c: inca(); break;
577 			case 0x4d: tsta(); break;
578 			case 0x4e: illegal(); break;
579 			case 0x4f: clra(); break;
580 			case 0x50: negx(); break;
581 			case 0x51: illegal(); break;
582 			case 0x52: illegal(); break;
583 			case 0x53: comx(); break;
584 			case 0x54: lsrx(); break;
585 			case 0x55: illegal(); break;
586 			case 0x56: rorx(); break;
587 			case 0x57: asrx(); break;
588 			case 0x58: aslx(); break;
589 			case 0x59: rolx(); break;
590 			case 0x5a: decx(); break;
591 			case 0x5b: illegal(); break;
592 			case 0x5c: incx(); break;
593 			case 0x5d: tstx(); break;
594 			case 0x5e: illegal(); break;
595 			case 0x5f: clrx(); break;
596 			case 0x60: neg_ix1(); break;
597 			case 0x61: illegal(); break;
598 			case 0x62: illegal(); break;
599 			case 0x63: com_ix1(); break;
600 			case 0x64: lsr_ix1(); break;
601 			case 0x65: illegal(); break;
602 			case 0x66: ror_ix1(); break;
603 			case 0x67: asr_ix1(); break;
604 			case 0x68: lsl_ix1(); break;
605 			case 0x69: rol_ix1(); break;
606 			case 0x6a: dec_ix1(); break;
607 			case 0x6b: illegal(); break;
608 			case 0x6c: inc_ix1(); break;
609 			case 0x6d: tst_ix1(); break;
610 			case 0x6e: illegal(); break;
611 			case 0x6f: clr_ix1(); break;
612 			case 0x70: neg_ix(); break;
613 			case 0x71: illegal(); break;
614 			case 0x72: illegal(); break;
615 			case 0x73: com_ix(); break;
616 			case 0x74: lsr_ix(); break;
617 			case 0x75: illegal(); break;
618 			case 0x76: ror_ix(); break;
619 			case 0x77: asr_ix(); break;
620 			case 0x78: lsl_ix(); break;
621 			case 0x79: rol_ix(); break;
622 			case 0x7a: dec_ix(); break;
623 			case 0x7b: illegal(); break;
624 			case 0x7c: inc_ix(); break;
625 			case 0x7d: tst_ix(); break;
626 			case 0x7e: illegal(); break;
627 			case 0x7f: clr_ix(); break;
628 			case 0x80: rti(); break;
629 			case 0x81: rts(); break;
630 			case 0x82: illegal(); break;
631 			case 0x83: swi(); break;
632 			case 0x84: illegal(); break;
633 			case 0x85: illegal(); break;
634 			case 0x86: illegal(); break;
635 			case 0x87: illegal(); break;
636 			case 0x88: illegal(); break;
637 			case 0x89: illegal(); break;
638 			case 0x8a: illegal(); break;
639 			case 0x8b: illegal(); break;
640 			case 0x8c: illegal(); break;
641 			case 0x8d: illegal(); break;
642 			case 0x8e: illegal(); break;
643 			case 0x8f: illegal(); break;
644 			case 0x90: illegal(); break;
645 			case 0x91: illegal(); break;
646 			case 0x92: illegal(); break;
647 			case 0x93: illegal(); break;
648 			case 0x94: illegal(); break;
649 			case 0x95: illegal(); break;
650 			case 0x96: illegal(); break;
651 			case 0x97: tax(); break;
652 			case 0x98: CLC; break;
653 			case 0x99: SEC; break;
654 #if IRQ_LEVEL_DETECT
655 			case 0x9a: CLI; if (m6805.irq_state != CLEAR_LINE) m6805.pending_interrupts |= 1<<M6805_IRQ_LINE; break;
656 #else
657 			case 0x9a: CLI; break;
658 #endif
659 			case 0x9b: SEI; break;
660 			case 0x9c: rsp(); break;
661 			case 0x9d: nop(); break;
662 			case 0x9e: illegal(); break;
663 			case 0x9f: txa(); break;
664 			case 0xa0: suba_im(); break;
665 			case 0xa1: cmpa_im(); break;
666 			case 0xa2: sbca_im(); break;
667 			case 0xa3: cpx_im(); break;
668 			case 0xa4: anda_im(); break;
669 			case 0xa5: bita_im(); break;
670 			case 0xa6: lda_im(); break;
671 			case 0xa7: illegal(); break;
672 			case 0xa8: eora_im(); break;
673 			case 0xa9: adca_im(); break;
674 			case 0xaa: ora_im(); break;
675 			case 0xab: adda_im(); break;
676 			case 0xac: illegal(); break;
677 			case 0xad: bsr(); break;
678 			case 0xae: ldx_im(); break;
679 			case 0xaf: illegal(); break;
680 			case 0xb0: suba_di(); break;
681 			case 0xb1: cmpa_di(); break;
682 			case 0xb2: sbca_di(); break;
683 			case 0xb3: cpx_di(); break;
684 			case 0xb4: anda_di(); break;
685 			case 0xb5: bita_di(); break;
686 			case 0xb6: lda_di(); break;
687 			case 0xb7: sta_di(); break;
688 			case 0xb8: eora_di(); break;
689 			case 0xb9: adca_di(); break;
690 			case 0xba: ora_di(); break;
691 			case 0xbb: adda_di(); break;
692 			case 0xbc: jmp_di(); break;
693 			case 0xbd: jsr_di(); break;
694 			case 0xbe: ldx_di(); break;
695 			case 0xbf: stx_di(); break;
696 			case 0xc0: suba_ex(); break;
697 			case 0xc1: cmpa_ex(); break;
698 			case 0xc2: sbca_ex(); break;
699 			case 0xc3: cpx_ex(); break;
700 			case 0xc4: anda_ex(); break;
701 			case 0xc5: bita_ex(); break;
702 			case 0xc6: lda_ex(); break;
703 			case 0xc7: sta_ex(); break;
704 			case 0xc8: eora_ex(); break;
705 			case 0xc9: adca_ex(); break;
706 			case 0xca: ora_ex(); break;
707 			case 0xcb: adda_ex(); break;
708 			case 0xcc: jmp_ex(); break;
709 			case 0xcd: jsr_ex(); break;
710 			case 0xce: ldx_ex(); break;
711 			case 0xcf: stx_ex(); break;
712 			case 0xd0: suba_ix2(); break;
713 			case 0xd1: cmpa_ix2(); break;
714 			case 0xd2: sbca_ix2(); break;
715 			case 0xd3: cpx_ix2(); break;
716 			case 0xd4: anda_ix2(); break;
717 			case 0xd5: bita_ix2(); break;
718 			case 0xd6: lda_ix2(); break;
719 			case 0xd7: sta_ix2(); break;
720 			case 0xd8: eora_ix2(); break;
721 			case 0xd9: adca_ix2(); break;
722 			case 0xda: ora_ix2(); break;
723 			case 0xdb: adda_ix2(); break;
724 			case 0xdc: jmp_ix2(); break;
725 			case 0xdd: jsr_ix2(); break;
726 			case 0xde: ldx_ix2(); break;
727 			case 0xdf: stx_ix2(); break;
728 			case 0xe0: suba_ix1(); break;
729 			case 0xe1: cmpa_ix1(); break;
730 			case 0xe2: sbca_ix1(); break;
731 			case 0xe3: cpx_ix1(); break;
732 			case 0xe4: anda_ix1(); break;
733 			case 0xe5: bita_ix1(); break;
734 			case 0xe6: lda_ix1(); break;
735 			case 0xe7: sta_ix1(); break;
736 			case 0xe8: eora_ix1(); break;
737 			case 0xe9: adca_ix1(); break;
738 			case 0xea: ora_ix1(); break;
739 			case 0xeb: adda_ix1(); break;
740 			case 0xec: jmp_ix1(); break;
741 			case 0xed: jsr_ix1(); break;
742 			case 0xee: ldx_ix1(); break;
743 			case 0xef: stx_ix1(); break;
744 			case 0xf0: suba_ix(); break;
745 			case 0xf1: cmpa_ix(); break;
746 			case 0xf2: sbca_ix(); break;
747 			case 0xf3: cpx_ix(); break;
748 			case 0xf4: anda_ix(); break;
749 			case 0xf5: bita_ix(); break;
750 			case 0xf6: lda_ix(); break;
751 			case 0xf7: sta_ix(); break;
752 			case 0xf8: eora_ix(); break;
753 			case 0xf9: adca_ix(); break;
754 			case 0xfa: ora_ix(); break;
755 			case 0xfb: adda_ix(); break;
756 			case 0xfc: jmp_ix(); break;
757 			case 0xfd: jsr_ix(); break;
758 			case 0xfe: ldx_ix(); break;
759 			case 0xff: stx_ix(); break;
760 		}
761 		m6805_ICount -= cycles1[ireg];
762 		m6805.nTotalCycles += cycles1[ireg];
763 	} while( m6805_ICount > 0 && !m6805.end_run);
764 
765 	return cycles - m6805_ICount;
766 }
767 
m6805Idle(int cycles)768 int m6805Idle(int cycles)
769 {
770 	m6805.nTotalCycles += cycles;
771 
772 	return cycles;
773 }
774 
m6805RunEnd()775 void m6805RunEnd()
776 {
777 #if defined FBNEO_DEBUG
778 	if (!DebugCPU_M6805Initted) bprintf(PRINT_ERROR, _T("m6805RunEnd called without init\n"));
779 #endif
780 
781 	m6805.end_run = 1;
782 }
783 
m6805NewFrame()784 void m6805NewFrame()
785 {
786 #if defined FBNEO_DEBUG
787 	if (!DebugCPU_M6805Initted) bprintf(PRINT_ERROR, _T("m6805NewFrame called without init\n"));
788 #endif
789 
790 	m6805.nTotalCycles = 0;
791 }
792 
m6805TotalCycles()793 int m6805TotalCycles()
794 {
795 #if defined FBNEO_DEBUG
796 	if (!DebugCPU_M6805Initted) bprintf(PRINT_ERROR, _T("m6805TotalCycles called without init\n"));
797 #endif
798 
799 	return m6805.nTotalCycles; // segment cycles taken care of! (search nTotalCycles)
800 }
801 
m6805Scan(int nAction)802 int m6805Scan(int nAction)
803 {
804 #if defined FBNEO_DEBUG
805 	if (!DebugCPU_M6805Initted) bprintf(PRINT_ERROR, _T("m6805Scan called without init\n"));
806 #endif
807 
808 	struct BurnArea ba;
809 
810 	if (nAction & ACB_DRIVER_DATA) {
811 		memset(&ba, 0, sizeof(ba));
812 
813 		ba.Data	  = &m6805;
814 		ba.nLen	  = STRUCT_SIZE_HELPER(m6805_Regs, nTotalCycles);
815 		ba.szName = "m6805 Registers";
816 		BurnAcb(&ba);
817 	}
818 
819 	return 0;
820 }
821 
822 
823 /****************************************************************************
824  * M68705 section
825  ****************************************************************************/
826 
m68705Reset()827 void m68705Reset()
828 {
829 #if defined FBNEO_DEBUG
830 	if (!DebugCPU_M6805Initted) bprintf(PRINT_ERROR, _T("m68705Reset called without init\n"));
831 #endif
832 
833 	m6805_reset();
834 	/* Overide default 6805 type */
835 	m6805.subtype = SUBTYPE_M68705;
836 	RM16( 0xfffe, &m6805.pc );
837 }
838 
m68705SetIrqLine(int irqline,int state)839 void m68705SetIrqLine(int irqline, int state)
840 {
841 #if defined FBNEO_DEBUG
842 	if (!DebugCPU_M6805Initted) bprintf(PRINT_ERROR, _T("m68705SetIrqLine called without init\n"));
843 #endif
844 	if (m6805.irq_state[irqline] == state ) return;
845 	m6805.irq_state[irqline] = state;
846 	if (state != CLEAR_LINE) m6805.pending_interrupts |= 1<<irqline;
847 }
848 
849 
850 /****************************************************************************
851  * HD63705 section
852  ****************************************************************************/
853 
854 //	m6805.irq_callback = irqcallback;
855 
hd63705Reset(void)856 void hd63705Reset(void)
857 {
858 #if defined FBNEO_DEBUG
859 	if (!DebugCPU_M6805Initted) bprintf(PRINT_ERROR, _T("hd63705Reset called without init\n"));
860 #endif
861 
862 	m6805_reset();
863 
864 	/* Overide default 6805 types */
865 	m6805.subtype	= SUBTYPE_HD63705;
866 	SP_MASK = 0x17f;
867 	SP_LOW	= 0x100;
868 	RM16( 0x1ffe, &m6805.pc );
869 	S = 0x17f;
870 }
871 
hd63705SetIrqLine(int irqline,int state)872 void hd63705SetIrqLine(int irqline, int state)
873 {
874 #if defined FBNEO_DEBUG
875 	if (!DebugCPU_M6805Initted) bprintf(PRINT_ERROR, _T("hd63705SetIrqLine called without init\n"));
876 #endif
877 
878 	if (irqline == 0x20) //INPUT_LINE_NMI)
879 	{
880 		if (m6805.nmi_state == state) return;
881 
882 		m6805.nmi_state = state;
883 		if (state != CLEAR_LINE)
884 			m6805.pending_interrupts |= 1<<HD63705_INT_NMI;
885 	}
886 	else if (irqline <= HD63705_INT_ADCONV)
887 	{
888 		if (m6805.irq_state[irqline] == state) return;
889 		m6805.irq_state[irqline] = state;
890 		if (state != CLEAR_LINE) m6805.pending_interrupts |= 1<<irqline;
891 	}
892 }
893 
m6805_core_set_irq(INT32,INT32 line,INT32 state)894 void m6805_core_set_irq(INT32 /*cpu*/, INT32 line, INT32 state)
895 {
896 	if (m6805.subtype == SUBTYPE_HD63705)
897 	{
898 		hd63705SetIrqLine(line, state);
899 	}
900 	else
901 	{
902 		m6805SetIrqLine(line, state);
903 	}
904 }
905