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