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