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