2 Skelton for retropc emulator
5 Author : Takeda.Toshiya
11 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
12 #pragma warning( disable : 4996 )
16 #if defined(HAS_MC6801) || defined(HAS_HD6301)
27 #define HD6301_SLP 0x10
48 /****************************************************************************/
50 /****************************************************************************/
52 uint32 MC6800::RM(uint32 Addr)
54 #if defined(HAS_MC6801) || defined(HAS_HD6301)
56 return mc6801_io_r(Addr);
57 } else if(Addr >= 0x80 && Addr < 0x100 && (ram_ctrl & 0x40)) {
58 return ram[Addr & 0x7f];
61 return d_mem->read_data8(Addr);
64 void MC6800::WM(uint32 Addr, uint32 Value)
66 #if defined(HAS_MC6801) || defined(HAS_HD6301)
68 mc6801_io_w(Addr, Value);
69 } else if(Addr >= 0x80 && Addr < 0x100 && (ram_ctrl & 0x40)) {
70 ram[Addr & 0x7f] = Value;
73 d_mem->write_data8(Addr, Value);
76 uint32 MC6800::RM16(uint32 Addr)
78 uint32 result = RM(Addr) << 8;
79 return result | RM((Addr + 1) & 0xffff);
82 void MC6800::WM16(uint32 Addr, pair *p)
85 WM((Addr + 1) & 0xffff, p->b.l);
88 #define M_RDOP(Addr) d_mem->read_data8(Addr)
89 #define M_RDOP_ARG(Addr) d_mem->read_data8(Addr)
91 /* macros to access memory */
92 #define IMMBYTE(b) b = M_RDOP_ARG(PCD); PC++
93 #define IMMWORD(w) w.b.h = M_RDOP_ARG(PCD); w.b.l = M_RDOP_ARG((PCD + 1) & 0xffff); PC += 2
95 #define PUSHBYTE(b) WM(SD, b); --S
96 #define PUSHWORD(w) WM(SD, w.b.l); --S; WM(SD, w.b.h); --S
97 #define PULLBYTE(b) S++; b = RM(SD)
98 #define PULLWORD(w) S++; w.b.h = RM(SD); S++; w.b.l = RM(SD)
100 /****************************************************************************/
101 /* MC6801/HD6301 internal i/o port */
102 /****************************************************************************/
104 #if defined(HAS_MC6801) || defined(HAS_HD6301)
106 #define CT counter.w.l
107 #define CTH counter.w.h
108 #define CTD counter.d
109 #define OC output_compare.w.l
110 #define OCH output_compare.w.h
111 #define OCD output_compare.d
112 #define TOH timer_over.w.l
113 #define TOD timer_over.d
115 #define SET_TIMER_EVENT { \
116 timer_next = (OCD - CTD < TOD - CTD) ? OCD : TOD; \
119 #define CLEANUP_COUNTERS() { \
126 #define MODIFIED_counters { \
127 OCH = (OC >= CT) ? CTH : CTH + 1; \
131 #define TCSR_OLVL 0x01
132 #define TCSR_IEDG 0x02
133 #define TCSR_ETOI 0x04
134 #define TCSR_EOCI 0x08
135 #define TCSR_EICI 0x10
136 #define TCSR_TOF 0x20
137 #define TCSR_OCF 0x40
138 #define TCSR_ICF 0x80
140 #define TRCSR_WU 0x01
141 #define TRCSR_TE 0x02
142 #define TRCSR_TIE 0x04
143 #define TRCSR_RE 0x08
144 #define TRCSR_RIE 0x10
145 #define TRCSR_TDRE 0x20
146 #define TRCSR_ORFE 0x40
147 #define TRCSR_RDRF 0x80
149 #define P3CSR_LE 0x08
150 #define P3CSR_IS3_ENABLE 0x40
151 #define P3CSR_IS3_FLAG 0x80
153 static const int RMCR_SS[] = { 16, 128, 1024, 4096 };
156 #define TAKE_ICI enter_interrupt(0xfff6)
157 #define TAKE_OCI enter_interrupt(0xfff4)
158 #define TAKE_TOI enter_interrupt(0xfff2)
159 #define TAKE_SCI enter_interrupt(0xfff0)
160 #define TAKE_TRAP enter_interrupt(0xffee)
162 uint32 MC6800::mc6801_io_r(uint32 offset)
166 // port1 data direction register
169 // port2 data direction register
172 // port1 data register
173 return (port[0].rreg & ~port[0].ddr) | (port[0].wreg & port[0].ddr);
175 // port2 data register
176 return (port[1].rreg & ~port[1].ddr) | (port[1].wreg & port[1].ddr);
178 // port3 data direction register (write only???)
181 // port4 data direction register
184 // port3 data register
185 if(p3csr_is3_flag_read) {
186 p3csr_is3_flag_read = false;
187 p3csr &= ~P3CSR_IS3_FLAG;
189 if(port[2].latched) {
190 port[2].latched = false;
191 return (port[2].latched_data & ~port[2].ddr) | (port[2].wreg & port[2].ddr);
193 return (port[2].rreg & ~port[2].ddr) | (port[2].wreg & port[2].ddr);
195 // port4 data register
196 return (port[3].rreg & ~port[3].ddr) | (port[3].wreg & port[3].ddr);
198 // timer control register
202 // free running counter (msb)
203 if(!(pending_tcsr & TCSR_TOF)) {
208 // free running counter (lsb)
211 // output compare register (msb)
212 if(!(pending_tcsr & TCSR_OCF)) {
215 return output_compare.b.h;
217 // output compare register (lsb)
218 if(!(pending_tcsr & TCSR_OCF)) {
221 return output_compare.b.l;
223 // input capture register (msb)
224 if(!(pending_tcsr & TCSR_ICF)) {
227 return (input_capture >> 0) & 0xff;
229 // input capture register (lsb)
230 return (input_capture >> 8) & 0xff;
232 // port3 control/status register
233 p3csr_is3_flag_read = true;
236 // rate and mode control register
239 if(trcsr & TRCSR_TDRE) {
240 trcsr_read_tdre = true;
242 if(trcsr & TRCSR_ORFE) {
243 trcsr_read_orfe = true;
245 if(trcsr & TRCSR_RDRF) {
246 trcsr_read_rdrf = true;
250 // receive data register
251 if(trcsr_read_orfe) {
252 trcsr_read_orfe = false;
253 trcsr &= ~TRCSR_ORFE;
255 if(trcsr_read_rdrf) {
256 trcsr_read_rdrf = false;
257 trcsr &= ~TRCSR_RDRF;
261 // transmit data register
264 // ram control register
265 return (ram_ctrl & 0x40) | 0x3f;
270 void MC6800::mc6801_io_w(uint32 offset, uint32 data)
274 // port1 data direction register
278 // port2 data direction register
282 // port1 data register
283 if(port[0].wreg != data || port[0].first_write) {
284 write_signals(&port[0].outputs, data);
286 port[0].first_write = false;
290 // port2 data register
291 if(port[1].wreg != data || port[1].first_write) {
292 write_signals(&port[1].outputs, data);
294 port[1].first_write = false;
298 // port3 data direction register
302 // port4 data direction register
306 // port3 data register
307 if(p3csr_is3_flag_read) {
308 p3csr_is3_flag_read = false;
309 p3csr &= ~P3CSR_IS3_FLAG;
311 if(port[2].wreg != data || port[2].first_write) {
312 write_signals(&port[2].outputs, data);
314 port[2].first_write = false;
318 // port4 data register
319 if(port[3].wreg != data || port[3].first_write) {
320 write_signals(&port[3].outputs, data);
322 port[3].first_write = false;
326 // timer control/status register
328 pending_tcsr &= tcsr;
331 // free running counter (msb)
333 latch09 = data & 0xff;
341 // free running counter (lsb)
342 CT = (latch09 << 8) | (data & 0xff);
348 // output compare register (msb)
349 if(output_compare.b.h != data) {
350 output_compare.b.h = data;
355 // output compare register (lsb)
356 if(output_compare.b.l != data) {
357 output_compare.b.l = data;
362 // port3 control/status register
363 p3csr = (p3csr & P3CSR_IS3_FLAG) | (data & ~P3CSR_IS3_FLAG);
366 // rate and mode control register
370 // transmit/receive control/status register
371 trcsr = (trcsr & 0xe0) | (data & 0x1f);
374 // transmit data register
375 if(trcsr_read_tdre) {
376 trcsr_read_tdre = false;
377 trcsr &= ~TRCSR_TDRE;
382 // ram control register
388 void MC6800::increment_counter(int amount)
393 if((CTD += amount) >= timer_next) {
396 OCH++; // next IRQ point
398 pending_tcsr |= TCSR_OCF;
402 TOH++; // next IRQ point
404 pending_tcsr |= TCSR_TOF;
411 if((sio_counter -= amount) <= 0) {
412 if((trcsr & TRCSR_TE) && !(trcsr & TRCSR_TDRE)) {
413 write_signals(&outputs_sio, tdr);
416 if((trcsr & TRCSR_RE) && !recv_buffer->empty()) {
417 if(trcsr & TRCSR_WU) {
421 } else if(!(trcsr & TRCSR_RDRF)) {
422 // note: wait reveived data is read by cpu, so overrun framing error never occurs
423 rdr = recv_buffer->read();
427 sio_counter += RMCR_SS[rmcr & 3];
433 #define increment_counter(amount) icount -= amount
437 #define CLR_HNZVC CC &= 0xd0
438 #define CLR_NZV CC &= 0xf1
439 #define CLR_HNZC CC &= 0xd2
440 #define CLR_NZVC CC &= 0xf0
441 #define CLR_NZ CC &= 0xf3
442 #define CLR_Z CC &= 0xfb
443 #define CLR_NZC CC &= 0xf2
444 #define CLR_ZC CC &= 0xfa
445 #define CLR_C CC &= 0xfe
447 #define SET_Z(a) if(!(a)) SEZ
448 #define SET_Z8(a) SET_Z((uint8)(a))
449 #define SET_Z16(a) SET_Z((uint16)(a))
450 #define SET_N8(a) CC |= (((a) & 0x80) >> 4)
451 #define SET_N16(a) CC |= (((a) & 0x8000) >> 12)
452 #define SET_H(a,b,r) CC |= ((((a) ^ (b) ^ (r)) & 0x10) << 1)
453 #define SET_C8(a) CC |= (((a) & 0x100) >> 8)
454 #define SET_C16(a) CC |= (((a) & 0x10000) >> 16)
455 #define SET_V8(a,b,r) CC |= ((((a) ^ (b) ^ (r) ^ ((r) >> 1)) & 0x80) >> 6)
456 #define SET_V16(a,b,r) CC |= ((((a) ^ (b) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 14)
458 static const uint8 flags8i[256] = {
460 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
461 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
462 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
463 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
464 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
465 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
466 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
467 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
468 0x0a,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
469 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
470 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
471 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
472 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
473 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
474 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
475 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08
478 static const uint8 flags8d[256] = {
480 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
481 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
482 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
483 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
484 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
485 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
486 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
487 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,
488 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
489 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
490 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
491 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
492 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
493 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
494 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
495 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08
498 #define SET_FLAGS8I(a) {CC |= flags8i[(a) & 0xff];}
499 #define SET_FLAGS8D(a) {CC |= flags8d[(a) & 0xff];}
502 #define SET_NZ8(a) {SET_N8(a); SET_Z8(a);}
503 #define SET_NZ16(a) {SET_N16(a); SET_Z16(a);}
504 #define SET_FLAGS8(a,b,r) {SET_N8(r); SET_Z8(r); SET_V8(a,b,r); SET_C8(r); }
505 #define SET_FLAGS16(a,b,r) {SET_N16(r); SET_Z16(r); SET_V16(a,b,r); SET_C16(r);}
507 /* for treating an uint8 as a signed int16 */
508 #define SIGNED(b) ((int16)(b & 0x80 ? b | 0xff00 : b))
510 /* Macros for addressing modes */
511 #define DIRECT IMMBYTE(EAD)
512 #define IMM8 EA = PC++
513 #define IMM16 {EA = PC; PC += 2;}
514 #define EXTENDED IMMWORD(pEA)
515 #define INDEXED {EA = X + (uint8)M_RDOP_ARG(PCD); PC++;}
517 /* macros to set status flags */
518 #define SEC CC |= 0x01
519 #define CLC CC &= 0xfe
520 #define SEZ CC |= 0x04
521 #define CLZ CC &= 0xfb
522 #define SEN CC |= 0x08
523 #define CLN CC &= 0xf7
524 #define SEV CC |= 0x02
525 #define CLV CC &= 0xfd
526 #define SEH CC |= 0x20
527 #define CLH CC &= 0xdf
528 #define SEI CC |= 0x10
529 #define CLI CC &= ~0x10
531 /* macros for convenience */
532 #define DIRBYTE(b) {DIRECT; b = RM(EAD); }
533 #define DIRWORD(w) {DIRECT; w.d = RM16(EAD);}
534 #define EXTBYTE(b) {EXTENDED; b = RM(EAD); }
535 #define EXTWORD(w) {EXTENDED; w.d = RM16(EAD);}
537 #define IDXBYTE(b) {INDEXED; b = RM(EAD); }
538 #define IDXWORD(w) {INDEXED; w.d = RM16(EAD);}
540 /* Macros for branch instructions */
541 #define BRANCH(f) {IMMBYTE(t); if(f) {PC += SIGNED(t);}}
542 #define NXORV ((CC & 0x08) ^ ((CC & 0x02) << 2))
544 /* Note: don't use 0 cycles here for invalid opcodes so that we don't */
545 /* hang in an infinite loop if we hit one */
546 #define XX 5 // invalid opcode unknown cc
547 static const uint8 cycles[] = {
548 #if defined(HAS_MC6800)
549 XX, 2,XX,XX,XX,XX, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2,
550 2, 2,XX,XX,XX,XX, 2, 2,XX, 2,XX, 2,XX,XX,XX,XX,
551 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
552 4, 4, 4, 4, 4, 4, 4, 4,XX, 5,XX,10,XX,XX, 9,12,
553 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2,
554 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2,
555 7,XX,XX, 7, 7,XX, 7, 7, 7, 7, 7,XX, 7, 7, 4, 7,
556 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 6, 3, 6,
557 2, 2, 2,XX, 2, 2, 2, 3, 2, 2, 2, 2, 3, 8, 3, 4,
558 3, 3, 3,XX, 3, 3, 3, 4, 3, 3, 3, 3, 4, 6, 4, 5,
559 5, 5, 5,XX, 5, 5, 5, 6, 5, 5, 5, 5, 6, 8, 6, 7,
560 4, 4, 4,XX, 4, 4, 4, 5, 4, 4, 4, 4, 5, 9, 5, 6,
561 2, 2, 2,XX, 2, 2, 2, 3, 2, 2, 2, 2,XX,XX, 3, 4,
562 3, 3, 3,XX, 3, 3, 3, 4, 3, 3, 3, 3,XX,XX, 4, 5,
563 5, 5, 5,XX, 5, 5, 5, 6, 5, 5, 5, 5,XX,XX, 6, 7,
564 4, 4, 4,XX, 4, 4, 4, 5, 4, 4, 4, 4,XX,XX, 5, 6
565 #elif defined(HAS_MC6801)
566 XX, 2,XX,XX, 3, 3, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2,
567 2, 2,XX,XX,XX,XX, 2, 2,XX, 2,XX, 2,XX,XX,XX,XX,
568 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
569 3, 3, 4, 4, 3, 3, 3, 3, 5, 5, 3,10, 4,10, 9,12,
570 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2,
571 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2,
572 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 6, 3, 6,
573 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 6, 3, 6,
574 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 4, 6, 3, 3,
575 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 4, 4,
576 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 5, 5,
577 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 5, 5,
578 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 3,XX, 3, 3,
579 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
580 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
581 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5
582 #elif defined(HAS_HD6301)
583 XX, 1,XX,XX, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
584 1, 1,XX,XX,XX,XX, 1, 1, 2, 2, 4, 1,XX,XX,XX,XX,
585 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
586 1, 1, 3, 3, 1, 1, 4, 4, 4, 5, 1,10, 5, 7, 9,12,
587 1,XX,XX, 1, 1,XX, 1, 1, 1, 1, 1,XX, 1, 1,XX, 1,
588 1,XX,XX, 1, 1,XX, 1, 1, 1, 1, 1,XX, 1, 1,XX, 1,
589 6, 7, 7, 6, 6, 7, 6, 6, 6, 6, 6, 5, 6, 4, 3, 5,
590 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 6, 4, 3, 5,
591 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 5, 3, 3,
592 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 4, 4,
593 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
594 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
595 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3,XX, 3, 3,
596 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
597 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
598 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5
599 #elif defined(HAS_MB8861)
600 XX, 2,XX,XX,XX,XX, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2,
601 2, 2,XX,XX,XX,XX, 2, 2,XX, 2,XX, 2,XX,XX,XX,XX,
602 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
603 4, 4, 4, 4, 4, 4, 4, 4,XX, 5,XX,10,XX,XX, 9,12,
604 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2,
605 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2,
606 7,XX,XX, 7, 7,XX, 7, 7, 7, 7, 7,XX, 7, 7, 4, 7,
607 6, 8, 8, 6, 6, 8, 6, 6, 6, 6, 6, 7, 6, 6, 3, 6,
608 2, 2, 2,XX, 2, 2, 2, 3, 2, 2, 2, 2, 3, 8, 3, 4,
609 3, 3, 3,XX, 3, 3, 3, 4, 3, 3, 3, 3, 4, 6, 4, 5,
610 5, 5, 5,XX, 5, 5, 5, 6, 5, 5, 5, 5, 6, 8, 6, 7,
611 4, 4, 4,XX, 4, 4, 4, 5, 4, 4, 4, 4, 5, 9, 5, 6,
612 2, 2, 2,XX, 2, 2, 2, 3, 2, 2, 2, 2,XX,XX, 3, 4,
613 3, 3, 3,XX, 3, 3, 3, 4, 3, 3, 3, 3,XX,XX, 4, 5,
614 5, 5, 5,XX, 5, 5, 5, 6, 5, 5, 5, 5, 4,XX, 6, 7,
615 4, 4, 4,XX, 4, 4, 4, 5, 4, 4, 4, 4, 7,XX, 5, 6
618 #undef XX // invalid opcode unknown cc
621 void MC6800::initialize()
623 #if defined(HAS_MC6801) || defined(HAS_HD6301)
624 recv_buffer = new FIFO(0x10000);
628 d_mem_stored = d_mem;
629 d_debugger->set_context_mem(d_mem);
633 #if defined(HAS_MC6801) || defined(HAS_HD6301)
634 void MC6800::release()
636 recv_buffer->release();
644 SEI; /* IRQ disabled */
653 #if defined(HAS_MC6801) || defined(HAS_HD6301)
654 for(int i = 0; i < 4; i++) {
656 port[i].first_write = true;
657 port[i].latched = false;
660 p3csr_is3_flag_read = false;
661 sc1_state = sc2_state = false;
663 tcsr = pending_tcsr = 0x00;
668 recv_buffer->clear();
670 trcsr_read_tdre = trcsr_read_orfe = trcsr_read_rdrf = false;
672 sio_counter = RMCR_SS[rmcr & 3];
678 void MC6800::write_signal(int id, uint32 data, uint32 mask)
683 int_state |= INT_REQ_BIT;
685 int_state &= ~INT_REQ_BIT;
690 int_state |= NMI_REQ_BIT;
692 int_state &= ~NMI_REQ_BIT;
695 #if defined(HAS_MC6801) || defined(HAS_HD6301)
696 case SIG_MC6801_PORT_1:
697 port[0].rreg = (port[0].rreg & ~mask) | (data & mask);
699 case SIG_MC6801_PORT_2:
700 if((mask & 1) && (port[1].rreg & 1) != (data & 1) && (tcsr & 2) == ((data << 1) & 2)) {
701 // active TIN edge in
703 pending_tcsr |= TCSR_ICF;
706 port[1].rreg = (port[1].rreg & ~mask) | (data & mask);
708 case SIG_MC6801_PORT_3:
709 port[2].rreg = (port[2].rreg & ~mask) | (data & mask);
711 case SIG_MC6801_PORT_4:
712 port[3].rreg = (port[3].rreg & ~mask) | (data & mask);
714 case SIG_MC6801_PORT_3_SC1:
715 if(sc1_state && !(data & mask)) {
717 if(!port[2].latched && (p3csr & P3CSR_LE)) {
718 port[2].latched_data = port[2].rreg;
719 port[2].latched = true;
720 p3csr |= P3CSR_IS3_FLAG;
723 sc1_state = ((data & mask) != 0);
725 case SIG_MC6801_PORT_3_SC2:
726 sc2_state = ((data & mask) != 0);
728 case SIG_MC6801_SIO_RECV:
729 recv_buffer->write(data & mask);
735 int MC6800::run(int clock)
739 // run only one opcode
740 #if defined(HAS_MC6801) || defined(HAS_HD6301)
745 bool now_debugging = d_debugger->now_debugging;
747 d_debugger->check_break_points(PC);
748 if(d_debugger->now_suspended) {
750 while(d_debugger->now_debugging && d_debugger->now_suspended) {
754 if(d_debugger->now_debugging) {
757 now_debugging = false;
763 if(!d_debugger->now_going) {
764 d_debugger->now_suspended = true;
766 d_mem = d_mem_stored;
776 /* run cpu while given clocks */
777 #if defined(HAS_MC6801) || defined(HAS_HD6301)
781 int first_icount = icount;
785 bool now_debugging = d_debugger->now_debugging;
787 d_debugger->check_break_points(PC);
788 if(d_debugger->now_suspended) {
790 while(d_debugger->now_debugging && d_debugger->now_suspended) {
794 if(d_debugger->now_debugging) {
797 now_debugging = false;
803 if(!d_debugger->now_going) {
804 d_debugger->now_suspended = true;
806 d_mem = d_mem_stored;
815 return first_icount - icount;
819 void MC6800::run_one_opecode()
821 if(wai_state & (MC6800_WAI | HD6301_SLP)) {
822 increment_counter(1);
824 uint8 ireg = M_RDOP(PCD);
828 increment_counter(cycles[ireg]);
832 if(int_state & NMI_REQ_BIT) {
833 wai_state &= ~HD6301_SLP;
834 int_state &= ~NMI_REQ_BIT;
835 enter_interrupt(0xfffc);
836 } else if(int_state & INT_REQ_BIT) {
837 wai_state &= ~HD6301_SLP;
839 int_state &= ~INT_REQ_BIT;
840 enter_interrupt(0xfff8);
842 #if defined(HAS_MC6801) || defined(HAS_HD6301)
843 } else if((tcsr & (TCSR_EICI | TCSR_ICF)) == (TCSR_EICI | TCSR_ICF)) {
844 wai_state &= ~HD6301_SLP;
848 } else if((tcsr & (TCSR_EOCI | TCSR_OCF)) == (TCSR_EOCI | TCSR_OCF)) {
849 wai_state &= ~HD6301_SLP;
853 } else if((tcsr & (TCSR_ETOI | TCSR_TOF)) == (TCSR_ETOI | TCSR_TOF)) {
854 wai_state &= ~HD6301_SLP;
858 } else if(((trcsr & (TRCSR_RIE | TRCSR_RDRF)) == (TRCSR_RIE | TRCSR_RDRF)) ||
859 ((trcsr & (TRCSR_RIE | TRCSR_ORFE)) == (TRCSR_RIE | TRCSR_ORFE)) ||
860 ((trcsr & (TRCSR_TIE | TRCSR_TDRE)) == (TRCSR_TIE | TRCSR_TDRE))) {
861 wai_state &= ~HD6301_SLP;
870 void MC6800::debug_write_data8(uint32 addr, uint32 data)
873 d_mem_stored->write_data8w(addr, data, &wait);
876 uint32 MC6800::debug_read_data8(uint32 addr)
879 return d_mem_stored->read_data8w(addr, &wait);
882 void MC6800::debug_write_data16(uint32 addr, uint32 data)
884 debug_write_data8(addr, (data >> 8) & 0xff);
885 debug_write_data8(addr + 1, data & 0xff);
888 uint32 MC6800::debug_read_data16(uint32 addr)
890 uint32 val = debug_read_data8(addr) << 8;
891 val |= debug_read_data8(addr + 1);
895 void MC6800::debug_write_data32(uint32 addr, uint32 data)
897 debug_write_data16(addr, (data >> 16) & 0xffff);
898 debug_write_data16(addr + 2, data & 0xffff);
901 uint32 MC6800::debug_read_data32(uint32 addr)
903 uint32 val = debug_read_data16(addr) << 16;
904 val |= debug_read_data16(addr + 2);
908 bool MC6800::debug_write_reg(const _TCHAR *reg, uint32 data)
910 if(_tcsicmp(reg, _T("A")) == 0) {
912 } else if(_tcsicmp(reg, _T("B")) == 0) {
914 } else if(_tcsicmp(reg, _T("X")) == 0 || _tcsicmp(reg, _T("IX")) == 0) {
916 } else if(_tcsicmp(reg, _T("PC")) == 0) {
918 } else if(_tcsicmp(reg, _T("SP")) == 0) {
926 void MC6800::debug_regs_info(_TCHAR *buffer, size_t buffer_len)
928 my_stprintf_s(buffer, buffer_len,
929 _T("CCR = [%c%c%c%c%c%c] A = %02X B = %02X IX = %04X PC = %04X SP = %04X"),
930 (CC & 0x01) ? _T('C') : _T('-'), (CC & 0x02) ? _T('V') : _T('-'), (CC & 0x04) ? _T('Z') : _T('-'), (CC & 0x08) ? _T('N') : _T('-'),
931 (CC & 0x10) ? _T('I') : _T('-'), (CC & 0x20) ? _T('X') : _T('-'), A, B, X, PC, S);
935 * A quick-hack 6803/6808 disassembler
937 * Note: this is not the good and proper way to disassemble anything, but it works
939 * I'm afraid to put my name on it, but I feel obligated:
940 * This code written by Aaron Giles (agiles@sirius.com) for the MAME project
944 * The disassembler knows about valid opcodes for M6800/1/2/3/8 and HD63701.
946 * Changed the string array into a table of opcode names (or tokens) and
947 * argument types. This second try should give somewhat better results.
948 * Named the undocumented HD63701YO opcodes $12 and $13 'asx1' and 'asx2',
949 * since 'add contents of stack to x register' is what they do.
956 imb, /* immediate (byte) */
957 imw, /* immediate (word) */
958 dir, /* direct address */
959 imd, /* HD63701YO: immediate, direct address */
960 ext, /* extended address */
961 idx, /* x + byte offset */
962 imx, /* HD63701YO: immediate, x + byte offset */
963 sx1 /* HD63701YO: undocumented opcodes: byte from (s+1) */
967 aba=0, abx, adca, adcb, adda, addb, addd, aim,
968 anda, andb, asl, asla, aslb, asld, asr, asra,
969 asrb, bcc, bcs, beq, bge, bgt, bhi, bita,
970 bitb, ble, bls, blt, bmi, bne, bpl, bra,
971 brn, bsr, bvc, bvs, cba, clc, cli, clr,
972 clra, clrb, clv, cmpa, cmpb, cmpx, com, coma,
973 comb, daa, dec, deca, decb, des, dex, eim,
974 eora, eorb, ill, inc, inca, incb, ins, inx,
975 jmp, jsr, lda, ldb, ldd, lds, ldx, lsr,
976 lsra, lsrb, lsrd, mul, neg, nega, negb, nop,
977 oim, ora, orb, psha, pshb, pshx, pula, pulb,
978 pulx, rol, rola, rolb, ror, rora, rorb, rti,
979 rts, sba, sbca, sbcb, sec, sev, sta, stb,
980 _std, sei, sts, stx, suba, subb, subd, swi,
981 wai, tab, tap, tba, tim, tpa, tst, tsta,
982 tstb, tsx, txs, asx1, asx2, xgdx, addx, adcx
985 static const char *const op_name_str[] = {
986 "aba", "abx", "adca", "adcb", "adda", "addb", "addd", "aim",
987 "anda", "andb", "asl", "asla", "aslb", "asld", "asr", "asra",
988 "asrb", "bcc", "bcs", "beq", "bge", "bgt", "bhi", "bita",
989 "bitb", "ble", "bls", "blt", "bmi", "bne", "bpl", "bra",
990 "brn", "bsr", "bvc", "bvs", "cba", "clc", "cli", "clr",
991 "clra", "clrb", "clv", "cmpa", "cmpb", "cmpx", "com", "coma",
992 "comb", "daa", "dec", "deca", "decb", "des", "dex", "eim",
993 "eora", "eorb", "illegal","inc", "inca", "incb", "ins", "inx",
994 "jmp", "jsr", "lda", "ldb", "ldd", "lds", "ldx", "lsr",
995 "lsra", "lsrb", "lsrd", "mul", "neg", "nega", "negb", "nop",
996 "oim", "ora", "orb", "psha", "pshb", "pshx", "pula", "pulb",
997 "pulx", "rol", "rola", "rolb", "ror", "rora", "rorb", "rti",
998 "rts", "sba", "sbca", "sbcb", "sec", "sev", "sta", "stb",
999 "std", "sei", "sts", "stx", "suba", "subb", "subd", "swi",
1000 "wai", "tab", "tap", "tba", "tim", "tpa", "tst", "tsta",
1001 "tstb", "tsx", "txs", "asx1", "asx2", "xgdx", "addx", "adcx"
1005 * This table defines the opcodes:
1007 * 0 token (menmonic)
1009 * 2 invalid opcode for 1:6800/6802/6808, 2:6801/6803, 4:HD63701
1012 static const UINT8 table[0x102][3] = {
1013 {ill, inh,7},{nop, inh,0},{ill, inh,7},{ill, inh,7},/* 00 */
1014 {lsrd,inh,1},{asld,inh,1},{tap, inh,0},{tpa, inh,0},
1015 {inx, inh,0},{dex, inh,0},{clv, inh,0},{sev, inh,0},
1016 {clc, inh,0},{sec, inh,0},{cli, inh,0},{sei, inh,0},
1017 {sba, inh,0},{cba, inh,0},{asx1,sx1,0},{asx2,sx1,0},/* 10 */
1018 {ill, inh,7},{ill, inh,7},{tab, inh,0},{tba, inh,0},
1019 {xgdx,inh,3},{daa, inh,0},{ill, inh,7},{aba, inh,0},
1020 {ill, inh,7},{ill, inh,7},{ill, inh,7},{ill, inh,7},
1021 {bra, rel,0},{brn, rel,0},{bhi, rel,0},{bls, rel,0},/* 20 */
1022 {bcc, rel,0},{bcs, rel,0},{bne, rel,0},{beq, rel,0},
1023 {bvc, rel,0},{bvs, rel,0},{bpl, rel,0},{bmi, rel,0},
1024 {bge, rel,0},{blt, rel,0},{bgt, rel,0},{ble, rel,0},
1025 {tsx, inh,0},{ins, inh,0},{pula,inh,0},{pulb,inh,0},/* 30 */
1026 {des, inh,0},{txs, inh,0},{psha,inh,0},{pshb,inh,0},
1027 {pulx,inh,1},{rts, inh,0},{abx, inh,1},{rti, inh,0},
1028 {pshx,inh,1},{mul, inh,1},{wai, inh,0},{swi, inh,0},
1029 {nega,inh,0},{ill, inh,7},{ill, inh,7},{coma,inh,0},/* 40 */
1030 {lsra,inh,0},{ill, inh,7},{rora,inh,0},{asra,inh,0},
1031 {asla,inh,0},{rola,inh,0},{deca,inh,0},{ill, inh,7},
1032 {inca,inh,0},{tsta,inh,0},{ill, inh,7},{clra,inh,0},
1033 {negb,inh,0},{ill, inh,7},{ill, inh,7},{comb,inh,0},/* 50 */
1034 {lsrb,inh,0},{ill, inh,7},{rorb,inh,0},{asrb,inh,0},
1035 {aslb,inh,0},{rolb,inh,0},{decb,inh,0},{ill, inh,7},
1036 {incb,inh,0},{tstb,inh,0},{ill, inh,7},{clrb,inh,0},
1037 {neg, idx,0},{aim, imx,3},{oim, imx,3},{com, idx,0},/* 60 */
1038 {lsr, idx,0},{eim, imx,3},{ror, idx,0},{asr, idx,0},
1039 {asl, idx,0},{rol, idx,0},{dec, idx,0},{tim, imx,3},
1040 {inc, idx,0},{tst, idx,0},{jmp, idx,0},{clr, idx,0},
1041 {neg, ext,0},{aim, imd,3},{oim, imd,3},{com, ext,0},/* 70 */
1042 {lsr, ext,0},{eim, imd,3},{ror, ext,0},{asr, ext,0},
1043 {asl, ext,0},{rol, ext,0},{dec, ext,0},{tim, imd,3},
1044 {inc, ext,0},{tst, ext,0},{jmp, ext,0},{clr, ext,0},
1045 {suba,imb,0},{cmpa,imb,0},{sbca,imb,0},{subd,imw,1},/* 80 */
1046 {anda,imb,0},{bita,imb,0},{lda, imb,0},{sta, imb,0},
1047 {eora,imb,0},{adca,imb,0},{ora, imb,0},{adda,imb,0},
1048 {cmpx,imw,0},{bsr, rel,0},{lds, imw,0},{sts, imw,0},
1049 {suba,dir,0},{cmpa,dir,0},{sbca,dir,0},{subd,dir,1},/* 90 */
1050 {anda,dir,0},{bita,dir,0},{lda, dir,0},{sta, dir,0},
1051 {eora,dir,0},{adca,dir,0},{ora, dir,0},{adda,dir,0},
1052 {cmpx,dir,0},{jsr, dir,0},{lds, dir,0},{sts, dir,0},
1053 {suba,idx,0},{cmpa,idx,0},{sbca,idx,0},{subd,idx,1},/* a0 */
1054 {anda,idx,0},{bita,idx,0},{lda, idx,0},{sta, idx,0},
1055 {eora,idx,0},{adca,idx,0},{ora, idx,0},{adda,idx,0},
1056 {cmpx,idx,0},{jsr, idx,0},{lds, idx,0},{sts, idx,0},
1057 {suba,ext,0},{cmpa,ext,0},{sbca,ext,0},{subd,ext,1},/* b0 */
1058 {anda,ext,0},{bita,ext,0},{lda, ext,0},{sta, ext,0},
1059 {eora,ext,0},{adca,ext,0},{ora, ext,0},{adda,ext,0},
1060 {cmpx,ext,0},{jsr, ext,0},{lds, ext,0},{sts, ext,0},
1061 {subb,imb,0},{cmpb,imb,0},{sbcb,imb,0},{addd,imw,1},/* c0 */
1062 {andb,imb,0},{bitb,imb,0},{ldb, imb,0},{stb, imb,0},
1063 {eorb,imb,0},{adcb,imb,0},{orb, imb,0},{addb,imb,0},
1064 {ldd, imw,1},{_std,imw,1},{ldx, imw,0},{stx, imw,0},
1065 {subb,dir,0},{cmpb,dir,0},{sbcb,dir,0},{addd,dir,1},/* d0 */
1066 {andb,dir,0},{bitb,dir,0},{ldb, dir,0},{stb, dir,0},
1067 {eorb,dir,0},{adcb,dir,0},{orb, dir,0},{addb,dir,0},
1068 {ldd, dir,1},{_std,dir,1},{ldx, dir,0},{stx, dir,0},
1069 {subb,idx,0},{cmpb,idx,0},{sbcb,idx,0},{addd,idx,1},/* e0 */
1070 {andb,idx,0},{bitb,idx,0},{ldb, idx,0},{stb, idx,0},
1071 {eorb,idx,0},{adcb,idx,0},{orb, idx,0},{addb,idx,0},
1072 {ldd, idx,1},{_std,idx,1},{ldx, idx,0},{stx, idx,0},
1073 {subb,ext,0},{cmpb,ext,0},{sbcb,ext,0},{addd,ext,1},/* f0 */
1074 {andb,ext,0},{bitb,ext,0},{ldb, ext,0},{stb, ext,0},
1075 {eorb,ext,0},{adcb,ext,0},{orb, ext,0},{addb,ext,0},
1076 {ldd, ext,1},{_std,ext,1},{ldx, ext,0},{stx, ext,0},
1078 /* extra instruction $fc for NSC-8105 */
1080 /* extra instruction $ec for NSC-8105 */
1084 /* some macros to keep things short */
1086 #define ARG1 opram[1]
1087 #define ARG2 opram[2]
1088 #define ARGW (opram[1]<<8) + opram[2]
1090 static unsigned Dasm680x (int subtype, char *buf, unsigned pc, const UINT8 *oprom, const UINT8 *opram)
1092 // UINT32 flags = 0;
1095 UINT8 opcode, args, invalid;
1099 case 6800: case 6802: case 6808: case 8105:
1102 case 6801: case 6803:
1109 /* NSC-8105 is a special case */
1110 if (subtype == 8105)
1113 code = (code & 0x3c) | ((code & 0x41) << 1) | ((code & 0x82) >> 1);
1115 /* and check for extra instruction */
1116 if (code == 0xfc) code = 0x0100;
1117 if (code == 0xec) code = 0x0101;
1120 opcode = table[code][0];
1121 args = table[code][1];
1122 invalid = table[code][2];
1124 // if (opcode == bsr || opcode == jsr) {
1125 // flags = DASMFLAG_STEP_OVER;
1126 // } else if (opcode == rti || opcode == rts) {
1127 // flags = DASMFLAG_STEP_OUT;
1130 if ( invalid & invalid_mask ) /* invalid for this cpu type ? */
1132 strcpy(buf, "illegal");
1133 return 1;// | flags | DASMFLAG_SUPPORTED;
1136 buf += sprintf(buf, "%-5s", op_name_str[opcode]);
1140 case rel: /* relative */
1141 sprintf (buf, "$%04X", pc + (INT8)ARG1 + 2);
1142 return 2;// | flags | DASMFLAG_SUPPORTED;
1143 case imb: /* immediate (byte) */
1144 sprintf (buf, "#$%02X", ARG1);
1145 return 2;// | flags | DASMFLAG_SUPPORTED;
1146 case imw: /* immediate (word) */
1147 sprintf (buf, "#$%04X", ARGW);
1148 return 3;// | flags | DASMFLAG_SUPPORTED;
1149 case idx: /* indexed + byte offset */
1150 sprintf (buf, "(x+$%02X)", ARG1 );
1151 return 2;// | flags | DASMFLAG_SUPPORTED;
1152 case imx: /* immediate, indexed + byte offset */
1153 sprintf (buf, "#$%02X,(x+$%02x)", ARG1, ARG2 );
1154 return 3;// | flags | DASMFLAG_SUPPORTED;
1155 case dir: /* direct address */
1156 sprintf (buf, "$%02X", ARG1 );
1157 return 2;// | flags | DASMFLAG_SUPPORTED;
1158 case imd: /* immediate, direct address */
1159 sprintf (buf, "#$%02X,$%02X", ARG1, ARG2);
1160 return 3;// | flags | DASMFLAG_SUPPORTED;
1161 case ext: /* extended address */
1162 sprintf (buf, "$%04X", ARGW);
1163 return 3;// | flags | DASMFLAG_SUPPORTED;
1164 case sx1: /* byte from address (s + 1) */
1165 sprintf (buf, "(s+1)");
1166 return 1;// | flags | DASMFLAG_SUPPORTED;
1168 return 1;// | flags | DASMFLAG_SUPPORTED;
1172 int MC6800::debug_dasm(uint32 pc, _TCHAR *buffer, size_t buffer_len)
1175 for(int i = 0; i < 4; i++) {
1177 ops[i] = d_mem_stored->read_data8w(pc + i, &wait);
1179 #if defined(HAS_MC6800)
1180 return Dasm680x(6800, buffer, pc, ops, ops);
1181 #elif defined(HAS_MC6801)
1182 return Dasm680x(6801, buffer, pc, ops, ops);
1183 #elif defined(HAS_HD6301)
1184 return Dasm680x(6301, buffer, pc, ops, ops);
1185 #elif defined(HAS_MB8861)
1186 return Dasm680x(6800, buffer, pc, ops, ops); // FIXME
1192 void MC6800::enter_interrupt(uint16 irq_vector)
1194 if(wai_state & MC6800_WAI) {
1196 wai_state &= ~MC6800_WAI;
1206 PCD = RM16(irq_vector);
1211 void MC6800::insn(uint8 code)
1214 case 0x00: illegal(); break;
1215 case 0x01: nop(); break;
1216 case 0x02: illegal(); break;
1217 case 0x03: illegal(); break;
1218 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1219 case 0x04: lsrd(); break;
1220 case 0x05: asld(); break;
1222 case 0x04: illegal(); break;
1223 case 0x05: illegal(); break;
1225 case 0x06: tap(); break;
1226 case 0x07: tpa(); break;
1227 case 0x08: inx(); break;
1228 case 0x09: dex(); break;
1229 case 0x0a: clv(); break;
1230 case 0x0b: sev(); break;
1231 case 0x0c: clc(); break;
1232 case 0x0d: sec(); break;
1233 case 0x0e: cli(); break;
1234 case 0x0f: sei(); break;
1235 case 0x10: sba(); break;
1236 case 0x11: cba(); break;
1237 #if defined(HAS_HD6301)
1238 case 0x12: undoc1(); break;
1239 case 0x13: undoc2(); break;
1241 case 0x12: illegal(); break;
1242 case 0x13: illegal(); break;
1244 case 0x14: illegal(); break;
1245 case 0x15: illegal(); break;
1246 case 0x16: tab(); break;
1247 case 0x17: tba(); break;
1248 #if defined(HAS_HD6301)
1249 case 0x18: xgdx(); break;
1251 case 0x18: illegal(); break;
1253 case 0x19: daa(); break;
1254 #if defined(HAS_HD6301)
1255 case 0x1a: slp(); break;
1257 case 0x1a: illegal(); break;
1259 case 0x1b: aba(); break;
1260 case 0x1c: illegal(); break;
1261 case 0x1d: illegal(); break;
1262 case 0x1e: illegal(); break;
1263 case 0x1f: illegal(); break;
1264 case 0x20: bra(); break;
1265 case 0x21: brn(); break;
1266 case 0x22: bhi(); break;
1267 case 0x23: bls(); break;
1268 case 0x24: bcc(); break;
1269 case 0x25: bcs(); break;
1270 case 0x26: bne(); break;
1271 case 0x27: beq(); break;
1272 case 0x28: bvc(); break;
1273 case 0x29: bvs(); break;
1274 case 0x2a: bpl(); break;
1275 case 0x2b: bmi(); break;
1276 case 0x2c: bge(); break;
1277 case 0x2d: blt(); break;
1278 case 0x2e: bgt(); break;
1279 case 0x2f: ble(); break;
1280 case 0x30: tsx(); break;
1281 case 0x31: ins(); break;
1282 case 0x32: pula(); break;
1283 case 0x33: pulb(); break;
1284 case 0x34: des(); break;
1285 case 0x35: txs(); break;
1286 case 0x36: psha(); break;
1287 case 0x37: pshb(); break;
1288 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1289 case 0x38: pulx(); break;
1291 case 0x38: illegal(); break;
1293 case 0x39: rts(); break;
1294 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1295 case 0x3a: abx(); break;
1297 case 0x3a: illegal(); break;
1299 case 0x3b: rti(); break;
1300 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1301 case 0x3c: pshx(); break;
1302 case 0x3d: mul(); break;
1304 case 0x3c: illegal(); break;
1305 case 0x3d: illegal(); break;
1307 case 0x3e: wai(); break;
1308 case 0x3f: swi(); break;
1309 case 0x40: nega(); break;
1310 case 0x41: illegal(); break;
1311 case 0x42: illegal(); break;
1312 case 0x43: coma(); break;
1313 case 0x44: lsra(); break;
1314 case 0x45: illegal(); break;
1315 case 0x46: rora(); break;
1316 case 0x47: asra(); break;
1317 case 0x48: asla(); break;
1318 case 0x49: rola(); break;
1319 case 0x4a: deca(); break;
1320 case 0x4b: illegal(); break;
1321 case 0x4c: inca(); break;
1322 case 0x4d: tsta(); break;
1323 case 0x4e: illegal(); break;
1324 case 0x4f: clra(); break;
1325 case 0x50: negb(); break;
1326 case 0x51: illegal(); break;
1327 case 0x52: illegal(); break;
1328 case 0x53: comb(); break;
1329 case 0x54: lsrb(); break;
1330 case 0x55: illegal(); break;
1331 case 0x56: rorb(); break;
1332 case 0x57: asrb(); break;
1333 case 0x58: aslb(); break;
1334 case 0x59: rolb(); break;
1335 case 0x5a: decb(); break;
1336 case 0x5b: illegal(); break;
1337 case 0x5c: incb(); break;
1338 case 0x5d: tstb(); break;
1339 case 0x5e: illegal(); break;
1340 case 0x5f: clrb(); break;
1341 case 0x60: neg_ix(); break;
1342 #if defined(HAS_HD6301)
1343 case 0x61: aim_ix(); break;
1344 case 0x62: oim_ix(); break;
1346 case 0x61: illegal(); break;
1347 case 0x62: illegal(); break;
1349 case 0x63: com_ix(); break;
1350 case 0x64: lsr_ix(); break;
1351 #if defined(HAS_HD6301)
1352 case 0x65: eim_ix(); break;
1354 case 0x65: illegal(); break;
1356 case 0x66: ror_ix(); break;
1357 case 0x67: asr_ix(); break;
1358 case 0x68: asl_ix(); break;
1359 case 0x69: rol_ix(); break;
1360 case 0x6a: dec_ix(); break;
1361 #if defined(HAS_HD6301)
1362 case 0x6b: tim_ix(); break;
1364 case 0x6b: illegal(); break;
1366 case 0x6c: inc_ix(); break;
1367 case 0x6d: tst_ix(); break;
1368 case 0x6e: jmp_ix(); break;
1369 case 0x6f: clr_ix(); break;
1370 case 0x70: neg_ex(); break;
1371 #if defined(HAS_HD6301)
1372 case 0x71: aim_di(); break;
1373 case 0x72: oim_di(); break;
1374 #elif defined(HAS_MB8861)
1375 case 0x71: nim_ix(); break;
1376 case 0x72: oim_ix_mb8861(); break;
1378 case 0x71: illegal(); break;
1379 case 0x72: illegal(); break;
1381 case 0x73: com_ex(); break;
1382 case 0x74: lsr_ex(); break;
1383 #if defined(HAS_HD6301)
1384 case 0x75: eim_di(); break;
1385 #elif defined(HAS_MB8861)
1386 case 0x75: xim_ix(); break;
1388 case 0x75: illegal(); break;
1390 case 0x76: ror_ex(); break;
1391 case 0x77: asr_ex(); break;
1392 case 0x78: asl_ex(); break;
1393 case 0x79: rol_ex(); break;
1394 case 0x7a: dec_ex(); break;
1395 #if defined(HAS_HD6301)
1396 case 0x7b: tim_di(); break;
1397 #elif defined(HAS_MB8861)
1398 case 0x7b: tmm_ix(); break;
1400 case 0x7b: illegal(); break;
1402 case 0x7c: inc_ex(); break;
1403 case 0x7d: tst_ex(); break;
1404 case 0x7e: jmp_ex(); break;
1405 case 0x7f: clr_ex(); break;
1406 case 0x80: suba_im(); break;
1407 case 0x81: cmpa_im(); break;
1408 case 0x82: sbca_im(); break;
1409 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1410 case 0x83: subd_im(); break;
1412 case 0x83: illegal(); break;
1414 case 0x84: anda_im(); break;
1415 case 0x85: bita_im(); break;
1416 case 0x86: lda_im(); break;
1417 case 0x87: sta_im(); break;
1418 case 0x88: eora_im(); break;
1419 case 0x89: adca_im(); break;
1420 case 0x8a: ora_im(); break;
1421 case 0x8b: adda_im(); break;
1422 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1423 case 0x8c: cpx_im (); break;
1425 case 0x8c: cmpx_im(); break;
1427 case 0x8d: bsr(); break;
1428 case 0x8e: lds_im(); break;
1429 case 0x8f: sts_im(); break;
1430 case 0x90: suba_di(); break;
1431 case 0x91: cmpa_di(); break;
1432 case 0x92: sbca_di(); break;
1433 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1434 case 0x93: subd_di(); break;
1436 case 0x93: illegal(); break;
1438 case 0x94: anda_di(); break;
1439 case 0x95: bita_di(); break;
1440 case 0x96: lda_di(); break;
1441 case 0x97: sta_di(); break;
1442 case 0x98: eora_di(); break;
1443 case 0x99: adca_di(); break;
1444 case 0x9a: ora_di(); break;
1445 case 0x9b: adda_di(); break;
1446 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1447 case 0x9c: cpx_di (); break;
1449 case 0x9c: cmpx_di(); break;
1451 case 0x9d: jsr_di(); break;
1452 case 0x9e: lds_di(); break;
1453 case 0x9f: sts_di(); break;
1454 case 0xa0: suba_ix(); break;
1455 case 0xa1: cmpa_ix(); break;
1456 case 0xa2: sbca_ix(); break;
1457 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1458 case 0xa3: subd_ix(); break;
1460 case 0xa3: illegal(); break;
1462 case 0xa4: anda_ix(); break;
1463 case 0xa5: bita_ix(); break;
1464 case 0xa6: lda_ix(); break;
1465 case 0xa7: sta_ix(); break;
1466 case 0xa8: eora_ix(); break;
1467 case 0xa9: adca_ix(); break;
1468 case 0xaa: ora_ix(); break;
1469 case 0xab: adda_ix(); break;
1470 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1471 case 0xac: cpx_ix (); break;
1473 case 0xac: cmpx_ix(); break;
1475 case 0xad: jsr_ix(); break;
1476 case 0xae: lds_ix(); break;
1477 case 0xaf: sts_ix(); break;
1478 case 0xb0: suba_ex(); break;
1479 case 0xb1: cmpa_ex(); break;
1480 case 0xb2: sbca_ex(); break;
1481 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1482 case 0xb3: subd_ex(); break;
1484 case 0xb3: illegal(); break;
1486 case 0xb4: anda_ex(); break;
1487 case 0xb5: bita_ex(); break;
1488 case 0xb6: lda_ex(); break;
1489 case 0xb7: sta_ex(); break;
1490 case 0xb8: eora_ex(); break;
1491 case 0xb9: adca_ex(); break;
1492 case 0xba: ora_ex(); break;
1493 case 0xbb: adda_ex(); break;
1494 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1495 case 0xbc: cpx_ex (); break;
1497 case 0xbc: cmpx_ex(); break;
1499 case 0xbd: jsr_ex(); break;
1500 case 0xbe: lds_ex(); break;
1501 case 0xbf: sts_ex(); break;
1502 case 0xc0: subb_im(); break;
1503 case 0xc1: cmpb_im(); break;
1504 case 0xc2: sbcb_im(); break;
1505 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1506 case 0xc3: addd_im(); break;
1508 case 0xc3: illegal(); break;
1510 case 0xc4: andb_im(); break;
1511 case 0xc5: bitb_im(); break;
1512 case 0xc6: ldb_im(); break;
1513 case 0xc7: stb_im(); break;
1514 case 0xc8: eorb_im(); break;
1515 case 0xc9: adcb_im(); break;
1516 case 0xca: orb_im(); break;
1517 case 0xcb: addb_im(); break;
1518 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1519 case 0xcc: ldd_im(); break;
1520 case 0xcd: std_im(); break;
1522 case 0xcc: illegal(); break;
1523 case 0xcd: illegal(); break;
1525 case 0xce: ldx_im(); break;
1526 case 0xcf: stx_im(); break;
1527 case 0xd0: subb_di(); break;
1528 case 0xd1: cmpb_di(); break;
1529 case 0xd2: sbcb_di(); break;
1530 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1531 case 0xd3: addd_di(); break;
1533 case 0xd3: illegal(); break;
1535 case 0xd4: andb_di(); break;
1536 case 0xd5: bitb_di(); break;
1537 case 0xd6: ldb_di(); break;
1538 case 0xd7: stb_di(); break;
1539 case 0xd8: eorb_di(); break;
1540 case 0xd9: adcb_di(); break;
1541 case 0xda: orb_di(); break;
1542 case 0xdb: addb_di(); break;
1543 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1544 case 0xdc: ldd_di(); break;
1545 case 0xdd: std_di(); break;
1547 case 0xdc: illegal(); break;
1548 case 0xdd: illegal(); break;
1550 case 0xde: ldx_di(); break;
1551 case 0xdf: stx_di(); break;
1552 case 0xe0: subb_ix(); break;
1553 case 0xe1: cmpb_ix(); break;
1554 case 0xe2: sbcb_ix(); break;
1555 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1556 case 0xe3: addd_ix(); break;
1558 case 0xe3: illegal(); break;
1560 case 0xe4: andb_ix(); break;
1561 case 0xe5: bitb_ix(); break;
1562 case 0xe6: ldb_ix(); break;
1563 case 0xe7: stb_ix(); break;
1564 case 0xe8: eorb_ix(); break;
1565 case 0xe9: adcb_ix(); break;
1566 case 0xea: orb_ix(); break;
1567 case 0xeb: addb_ix(); break;
1568 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1569 case 0xec: ldd_ix(); break;
1570 case 0xed: std_ix(); break;
1571 #elif defined(HAS_MB8861)
1572 case 0xec: adx_im(); break;
1573 case 0xed: illegal(); break;
1575 case 0xec: illegal(); break;
1576 case 0xed: illegal(); break;
1578 case 0xee: ldx_ix(); break;
1579 case 0xef: stx_ix(); break;
1580 case 0xf0: subb_ex(); break;
1581 case 0xf1: cmpb_ex(); break;
1582 case 0xf2: sbcb_ex(); break;
1583 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1584 case 0xf3: addd_ex(); break;
1586 case 0xf3: illegal(); break;
1588 case 0xf4: andb_ex(); break;
1589 case 0xf5: bitb_ex(); break;
1590 case 0xf6: ldb_ex(); break;
1591 case 0xf7: stb_ex(); break;
1592 case 0xf8: eorb_ex(); break;
1593 case 0xf9: adcb_ex(); break;
1594 case 0xfa: orb_ex(); break;
1595 case 0xfb: addb_ex(); break;
1596 #if defined(HAS_MC6801) || defined(HAS_HD6301)
1597 case 0xfc: ldd_ex(); break;
1598 case 0xfd: std_ex(); break;
1599 #elif defined(HAS_MB8861)
1600 case 0xfc: adx_ex(); break;
1601 case 0xfd: illegal(); break;
1603 case 0xfc: illegal(); break;
1604 case 0xfd: illegal(); break;
1606 case 0xfe: ldx_ex(); break;
1607 case 0xff: stx_ex(); break;
1608 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
1609 default: __assume(0);
1614 /* operate one instruction for */
1615 #define ONE_MORE_INSN() { \
1616 uint8 ireg = M_RDOP(PCD); \
1620 increment_counter(cycles[ireg]); \
1624 void MC6800::illegal()
1641 /* $04 LSRD inherent -0*-* */
1653 /* $05 ASLD inherent ?**** */
1661 SET_FLAGS16(t, t, r);
1665 /* $06 TAP inherent ##### */
1672 /* $07 TPA inherent ----- */
1678 /* $08 INX inherent --*-- */
1686 /* $09 DEX inherent --*-- */
1732 /* $10 SBA inherent -**** */
1738 SET_FLAGS8(A, B, t);
1742 /* $11 CBA inherent -**** */
1748 SET_FLAGS8(A, B, t);
1752 void MC6800::undoc1()
1758 void MC6800::undoc2()
1767 /* $16 TAB inherent -**0- */
1775 /* $17 TBA inherent -**0- */
1783 /* $18 XGDX inherent ----- */ /* HD6301 only */
1791 /* $19 DAA inherent (A) -**0* */
1798 if(lsn > 0x09 || CC & 0x20) {
1801 if(msn > 0x80 && lsn > 0x09) {
1804 if(msn > 0x90 || (CC & 0x01)) {
1808 CLR_NZV; /* keep carry from previous operation */
1816 /* $1a SLP */ /* HD6301 only */
1819 /* wait for next IRQ (same as waiting of wai) */
1820 wai_state |= HD6301_SLP;
1823 /* $1b ABA inherent ***** */
1829 SET_FLAGS8(A, B, t);
1842 /* $20 BRA relative ----- */
1850 /* $21 BRN relative ----- */
1857 /* $22 BHI relative ----- */
1861 BRANCH(!(CC & 0x05));
1864 /* $23 BLS relative ----- */
1871 /* $24 BCC relative ----- */
1875 BRANCH(!(CC & 0x01));
1878 /* $25 BCS relative ----- */
1885 /* $26 BNE relative ----- */
1889 BRANCH(!(CC & 0x04));
1892 /* $27 BEQ relative ----- */
1899 /* $28 BVC relative ----- */
1903 BRANCH(!(CC & 0x02));
1906 /* $29 BVS relative ----- */
1913 /* $2a BPL relative ----- */
1917 BRANCH(!(CC & 0x08));
1920 /* $2b BMI relative ----- */
1927 /* $2c BGE relative ----- */
1934 /* $2d BLT relative ----- */
1941 /* $2e BGT relative ----- */
1945 BRANCH(!(NXORV||CC & 0x04));
1948 /* $2f BLE relative ----- */
1952 BRANCH(NXORV||CC & 0x04);
1955 /* $30 TSX inherent ----- */
1961 /* $31 INS inherent ----- */
1967 /* $32 PULA inherent ----- */
1973 /* $33 PULB inherent ----- */
1979 /* $34 DES inherent ----- */
1985 /* $35 TXS inherent ----- */
1991 /* $36 PSHA inherent ----- */
1997 /* $37 PSHB inherent ----- */
2003 /* $38 PULX inherent ----- */
2009 /* $39 RTS inherent ----- */
2015 /* $3a ABX inherent ----- */
2021 /* $3b RTI inherent ##### */
2031 /* $3c PSHX inherent ----- */
2037 /* $3d MUL inherent --*-@ */
2047 /* $3e WAI inherent ----- */
2051 * WAI stacks the entire machine state on the
2052 * hardware stack, then waits for an interrupt.
2054 wai_state |= MC6800_WAI;
2062 /* $3f SWI absolute indirect ----- */
2074 /* $40 NEGA inherent ?**** */
2080 SET_FLAGS8(0, A, r);
2088 /* $43 COMA inherent -**01 */
2097 /* $44 LSRA inherent -0*-* */
2108 /* $46 RORA inherent -**-* */
2112 r = (CC & 0x01) << 7;
2120 /* $47 ASRA inherent ?**-* */
2126 A |= ((A & 0x40) << 1);
2130 /* $48 ASLA inherent ?**** */
2136 SET_FLAGS8(A, A, r);
2140 /* $49 ROLA inherent -**** */
2148 SET_FLAGS8(t, t, r);
2152 /* $4a DECA inherent -***- */
2162 /* $4c INCA inherent -***- */
2170 /* $4d TSTA inherent -**0- */
2179 /* $4f CLRA inherent -0100 */
2187 /* $50 NEGB inherent ?**** */
2193 SET_FLAGS8(0, B, r);
2201 /* $53 COMB inherent -**01 */
2210 /* $54 LSRB inherent -0*-* */
2221 /* $56 RORB inherent -**-* */
2225 r = (CC & 0x01) << 7;
2233 /* $57 ASRB inherent ?**-* */
2239 B |= ((B & 0x40) << 1);
2243 /* $58 ASLB inherent ?**** */
2249 SET_FLAGS8(B, B, r);
2253 /* $59 ROLB inherent -**** */
2261 SET_FLAGS8(t, t, r);
2265 /* $5a DECB inherent -***- */
2275 /* $5c INCB inherent -***- */
2283 /* $5d TSTB inherent -**0- */
2292 /* $5f CLRB inherent -0100 */
2300 /* $60 NEG indexed ?**** */
2301 void MC6800::neg_ix()
2307 SET_FLAGS8(0, t, r);
2311 /* $61 AIM --**0- */ /* HD6301 only */
2312 void MC6800::aim_ix()
2323 /* $62 OIM --**0- */ /* HD6301 only */
2324 void MC6800::oim_ix()
2335 /* $63 COM indexed -**01 */
2336 void MC6800::com_ix()
2347 /* $64 LSR indexed -0*-* */
2348 void MC6800::lsr_ix()
2359 /* $65 EIM --**0- */ /* HD6301 only */
2360 void MC6800::eim_ix()
2371 /* $66 ROR indexed -**-* */
2372 void MC6800::ror_ix()
2376 r = (CC & 0x01) << 7;
2384 /* $67 ASR indexed ?**-* */
2385 void MC6800::asr_ix()
2392 t |= ((t & 0x40) << 1);
2397 /* $68 ASL indexed ?**** */
2398 void MC6800::asl_ix()
2404 SET_FLAGS8(t, t, r);
2408 /* $69 ROL indexed -**** */
2409 void MC6800::rol_ix()
2416 SET_FLAGS8(t, t, r);
2420 /* $6a DEC indexed -***- */
2421 void MC6800::dec_ix()
2431 /* $6b TIM --**0- */ /* HD6301 only */
2432 void MC6800::tim_ix()
2442 /* $6c INC indexed -***- */
2443 void MC6800::inc_ix()
2453 /* $6d TST indexed -**0- */
2454 void MC6800::tst_ix()
2462 /* $6e JMP indexed ----- */
2463 void MC6800::jmp_ix()
2469 /* $6f CLR indexed -0100 */
2470 void MC6800::clr_ix()
2478 /* $70 NEG extended ?**** */
2479 void MC6800::neg_ex()
2485 SET_FLAGS8(0, t, r);
2489 /* $71 AIM --**0- */ /* HD6301 only */
2490 void MC6800::aim_di()
2501 /* $71 NIM --**0- */ /* MB8861 only */
2502 void MC6800::nim_ix()
2517 /* $72 OIM --**0- */ /* HD6301 only */
2518 void MC6800::oim_di()
2529 /* $72 OIM --**0- */ /* MB8861 only */
2530 void MC6800::oim_ix_mb8861()
2545 /* $73 COM extended -**01 */
2546 void MC6800::com_ex()
2557 /* $74 LSR extended -0*-* */
2558 void MC6800::lsr_ex()
2569 /* $75 EIM --**0- */ /* HD6301 only */
2570 void MC6800::eim_di()
2581 /* $75 XIM --**-- */ /* MB8861 only */
2582 void MC6800::xim_ix()
2597 /* $76 ROR extended -**-* */
2598 void MC6800::ror_ex()
2602 r = (CC & 0x01) << 7;
2610 /* $77 ASR extended ?**-* */
2611 void MC6800::asr_ex()
2618 t |= ((t & 0x40) << 1);
2623 /* $78 ASL extended ?**** */
2624 void MC6800::asl_ex()
2630 SET_FLAGS8(t, t, r);
2634 /* $79 ROL extended -**** */
2635 void MC6800::rol_ex()
2642 SET_FLAGS8(t, t, r);
2646 /* $7a DEC extended -***- */
2647 void MC6800::dec_ex()
2657 /* $7b TIM --**0- */ /* HD6301 only */
2658 void MC6800::tim_di()
2668 /* $7b TMM --***- */ /* MB8861 only */
2669 void MC6800::tmm_ix()
2685 /* $7c INC extended -***- */
2686 void MC6800::inc_ex()
2696 /* $7d TST extended -**0- */
2697 void MC6800::tst_ex()
2705 /* $7e JMP extended ----- */
2706 void MC6800::jmp_ex()
2712 /* $7f CLR extended -0100 */
2713 void MC6800::clr_ex()
2721 /* $80 SUBA immediate ?**** */
2722 void MC6800::suba_im()
2728 SET_FLAGS8(A, t, r);
2732 /* $81 CMPA immediate ?**** */
2733 void MC6800::cmpa_im()
2739 SET_FLAGS8(A, t, r);
2742 /* $82 SBCA immediate ?**** */
2743 void MC6800::sbca_im()
2747 r = A - t - (CC & 0x01);
2749 SET_FLAGS8(A, t, r);
2753 /* $83 SUBD immediate -**** */
2754 void MC6800::subd_im()
2762 SET_FLAGS16(d, b.d, r);
2766 /* $84 ANDA immediate -**0- */
2767 void MC6800::anda_im()
2776 /* $85 BITA immediate -**0- */
2777 void MC6800::bita_im()
2786 /* $86 LDA immediate -**0- */
2787 void MC6800::lda_im()
2794 /* is this a legal instruction? */
2795 /* $87 STA immediate -**0- */
2796 void MC6800::sta_im()
2804 /* $88 EORA immediate -**0- */
2805 void MC6800::eora_im()
2814 /* $89 ADCA immediate ***** */
2815 void MC6800::adca_im()
2819 r = A + t + (CC & 0x01);
2821 SET_FLAGS8(A, t, r);
2826 /* $8a ORA immediate -**0- */
2827 void MC6800::ora_im()
2836 /* $8b ADDA immediate ***** */
2837 void MC6800::adda_im()
2843 SET_FLAGS8(A, t, r);
2848 /* $8c CMPX immediate -***- */
2849 void MC6800::cmpx_im()
2861 /* $8c CPX immediate -**** (6801) */
2862 void MC6800::cpx_im()
2870 SET_FLAGS16(d, b.d, r);
2883 /* $8e LDS immediate -**0- */
2884 void MC6800::lds_im()
2891 /* $8f STS immediate -**0- */
2892 void MC6800::sts_im()
2900 /* $90 SUBA direct ?**** */
2901 void MC6800::suba_di()
2907 SET_FLAGS8(A, t, r);
2911 /* $91 CMPA direct ?**** */
2912 void MC6800::cmpa_di()
2918 SET_FLAGS8(A, t, r);
2921 /* $92 SBCA direct ?**** */
2922 void MC6800::sbca_di()
2926 r = A - t - (CC & 0x01);
2928 SET_FLAGS8(A, t, r);
2932 /* $93 SUBD direct -**** */
2933 void MC6800::subd_di()
2941 SET_FLAGS16(d, b.d, r);
2945 /* $94 ANDA direct -**0- */
2946 void MC6800::anda_di()
2955 /* $95 BITA direct -**0- */
2956 void MC6800::bita_di()
2965 /* $96 LDA direct -**0- */
2966 void MC6800::lda_di()
2973 /* $97 STA direct -**0- */
2974 void MC6800::sta_di()
2982 /* $98 EORA direct -**0- */
2983 void MC6800::eora_di()
2992 /* $99 ADCA direct ***** */
2993 void MC6800::adca_di()
2997 r = A + t + (CC & 0x01);
2999 SET_FLAGS8(A, t, r);
3004 /* $9a ORA direct -**0- */
3005 void MC6800::ora_di()
3014 /* $9b ADDA direct ***** */
3015 void MC6800::adda_di()
3021 SET_FLAGS8(A, t, r);
3026 /* $9c CMPX direct -***- */
3027 void MC6800::cmpx_di()
3039 /* $9c CPX direct -**** (6801) */
3040 void MC6800::cpx_di()
3048 SET_FLAGS16(d, b.d, r);
3051 /* $9d JSR direct ----- */
3052 void MC6800::jsr_di()
3059 /* $9e LDS direct -**0- */
3060 void MC6800::lds_di()
3067 /* $9f STS direct -**0- */
3068 void MC6800::sts_di()
3076 /* $a0 SUBA indexed ?**** */
3077 void MC6800::suba_ix()
3083 SET_FLAGS8(A, t, r);
3087 /* $a1 CMPA indexed ?**** */
3088 void MC6800::cmpa_ix()
3094 SET_FLAGS8(A, t, r);
3097 /* $a2 SBCA indexed ?**** */
3098 void MC6800::sbca_ix()
3102 r = A - t - (CC & 0x01);
3104 SET_FLAGS8(A, t, r);
3108 /* $a3 SUBD indexed -**** */
3109 void MC6800::subd_ix()
3117 SET_FLAGS16(d, b.d, r);
3121 /* $a4 ANDA indexed -**0- */
3122 void MC6800::anda_ix()
3131 /* $a5 BITA indexed -**0- */
3132 void MC6800::bita_ix()
3141 /* $a6 LDA indexed -**0- */
3142 void MC6800::lda_ix()
3149 /* $a7 STA indexed -**0- */
3150 void MC6800::sta_ix()
3158 /* $a8 EORA indexed -**0- */
3159 void MC6800::eora_ix()
3168 /* $a9 ADCA indexed ***** */
3169 void MC6800::adca_ix()
3173 r = A + t + (CC & 0x01);
3175 SET_FLAGS8(A, t, r);
3180 /* $aa ORA indexed -**0- */
3181 void MC6800::ora_ix()
3190 /* $ab ADDA indexed ***** */
3191 void MC6800::adda_ix()
3197 SET_FLAGS8(A, t, r);
3202 /* $ac CMPX indexed -***- */
3203 void MC6800::cmpx_ix()
3215 /* $ac CPX indexed -**** (6801)*/
3216 void MC6800::cpx_ix()
3224 SET_FLAGS16(d, b.d, r);
3227 /* $ad JSR indexed ----- */
3228 void MC6800::jsr_ix()
3235 /* $ae LDS indexed -**0- */
3236 void MC6800::lds_ix()
3243 /* $af STS indexed -**0- */
3244 void MC6800::sts_ix()
3252 /* $b0 SUBA extended ?**** */
3253 void MC6800::suba_ex()
3259 SET_FLAGS8(A, t, r);
3263 /* $b1 CMPA extended ?**** */
3264 void MC6800::cmpa_ex()
3270 SET_FLAGS8(A, t, r);
3273 /* $b2 SBCA extended ?**** */
3274 void MC6800::sbca_ex()
3278 r = A - t - (CC & 0x01);
3280 SET_FLAGS8(A, t, r);
3284 /* $b3 SUBD extended -**** */
3285 void MC6800::subd_ex()
3293 SET_FLAGS16(d, b.d, r);
3297 /* $b4 ANDA extended -**0- */
3298 void MC6800::anda_ex()
3307 /* $b5 BITA extended -**0- */
3308 void MC6800::bita_ex()
3317 /* $b6 LDA extended -**0- */
3318 void MC6800::lda_ex()
3325 /* $b7 STA extended -**0- */
3326 void MC6800::sta_ex()
3334 /* $b8 EORA extended -**0- */
3335 void MC6800::eora_ex()
3344 /* $b9 ADCA extended ***** */
3345 void MC6800::adca_ex()
3349 r = A + t + (CC & 0x01);
3351 SET_FLAGS8(A, t, r);
3356 /* $ba ORA extended -**0- */
3357 void MC6800::ora_ex()
3366 /* $bb ADDA extended ***** */
3367 void MC6800::adda_ex()
3373 SET_FLAGS8(A, t, r);
3378 /* $bc CMPX extended -***- */
3379 void MC6800::cmpx_ex()
3391 /* $bc CPX extended -**** (6801) */
3392 void MC6800::cpx_ex()
3400 SET_FLAGS16(d, b.d, r);
3403 /* $bd JSR extended ----- */
3404 void MC6800::jsr_ex()
3411 /* $be LDS extended -**0- */
3412 void MC6800::lds_ex()
3419 /* $bf STS extended -**0- */
3420 void MC6800::sts_ex()
3428 /* $c0 SUBB immediate ?**** */
3429 void MC6800::subb_im()
3435 SET_FLAGS8(B, t, r);
3439 /* $c1 CMPB immediate ?**** */
3440 void MC6800::cmpb_im()
3446 SET_FLAGS8(B, t, r);
3449 /* $c2 SBCB immediate ?**** */
3450 void MC6800::sbcb_im()
3454 r = B - t - (CC & 0x01);
3456 SET_FLAGS8(B, t, r);
3460 /* $c3 ADDD immediate -**** */
3461 void MC6800::addd_im()
3469 SET_FLAGS16(d, b.d, r);
3473 /* $c4 ANDB immediate -**0- */
3474 void MC6800::andb_im()
3483 /* $c5 BITB immediate -**0- */
3484 void MC6800::bitb_im()
3493 /* $c6 LDB immediate -**0- */
3494 void MC6800::ldb_im()
3501 /* is this a legal instruction? */
3502 /* $c7 STB immediate -**0- */
3503 void MC6800::stb_im()
3511 /* $c8 EORB immediate -**0- */
3512 void MC6800::eorb_im()
3521 /* $c9 ADCB immediate ***** */
3522 void MC6800::adcb_im()
3526 r = B + t + (CC & 0x01);
3528 SET_FLAGS8(B, t, r);
3533 /* $ca ORB immediate -**0- */
3534 void MC6800::orb_im()
3543 /* $cb ADDB immediate ***** */
3544 void MC6800::addb_im()
3550 SET_FLAGS8(B, t, r);
3555 /* $CC LDD immediate -**0- */
3556 void MC6800::ldd_im()
3563 /* is this a legal instruction? */
3564 /* $cd STD immediate -**0- */
3565 void MC6800::std_im()
3573 /* $ce LDX immediate -**0- */
3574 void MC6800::ldx_im()
3581 /* $cf STX immediate -**0- */
3582 void MC6800::stx_im()
3590 /* $d0 SUBB direct ?**** */
3591 void MC6800::subb_di()
3597 SET_FLAGS8(B, t, r);
3601 /* $d1 CMPB direct ?**** */
3602 void MC6800::cmpb_di()
3608 SET_FLAGS8(B, t, r);
3611 /* $d2 SBCB direct ?**** */
3612 void MC6800::sbcb_di()
3616 r = B - t - (CC & 0x01);
3618 SET_FLAGS8(B, t, r);
3622 /* $d3 ADDD direct -**** */
3623 void MC6800::addd_di()
3631 SET_FLAGS16(d, b.d, r);
3635 /* $d4 ANDB direct -**0- */
3636 void MC6800::andb_di()
3645 /* $d5 BITB direct -**0- */
3646 void MC6800::bitb_di()
3655 /* $d6 LDB direct -**0- */
3656 void MC6800::ldb_di()
3663 /* $d7 STB direct -**0- */
3664 void MC6800::stb_di()
3672 /* $d8 EORB direct -**0- */
3673 void MC6800::eorb_di()
3682 /* $d9 ADCB direct ***** */
3683 void MC6800::adcb_di()
3687 r = B + t + (CC & 0x01);
3689 SET_FLAGS8(B, t, r);
3694 /* $da ORB direct -**0- */
3695 void MC6800::orb_di()
3704 /* $db ADDB direct ***** */
3705 void MC6800::addb_di()
3711 SET_FLAGS8(B, t, r);
3716 /* $dc LDD direct -**0- */
3717 void MC6800::ldd_di()
3724 /* $dd STD direct -**0- */
3725 void MC6800::std_di()
3733 /* $de LDX direct -**0- */
3734 void MC6800::ldx_di()
3741 /* $dF STX direct -**0- */
3742 void MC6800::stx_di()
3750 /* $e0 SUBB indexed ?**** */
3751 void MC6800::subb_ix()
3757 SET_FLAGS8(B, t, r);
3761 /* $e1 CMPB indexed ?**** */
3762 void MC6800::cmpb_ix()
3768 SET_FLAGS8(B, t, r);
3771 /* $e2 SBCB indexed ?**** */
3772 void MC6800::sbcb_ix()
3776 r = B - t - (CC & 0x01);
3778 SET_FLAGS8(B, t, r);
3782 /* $e3 ADDD indexed -**** */
3783 void MC6800::addd_ix()
3791 SET_FLAGS16(d, b.d, r);
3795 /* $e4 ANDB indexed -**0- */
3796 void MC6800::andb_ix()
3805 /* $e5 BITB indexed -**0- */
3806 void MC6800::bitb_ix()
3815 /* $e6 LDB indexed -**0- */
3816 void MC6800::ldb_ix()
3823 /* $e7 STB indexed -**0- */
3824 void MC6800::stb_ix()
3832 /* $e8 EORB indexed -**0- */
3833 void MC6800::eorb_ix()
3842 /* $e9 ADCB indexed ***** */
3843 void MC6800::adcb_ix()
3847 r = B + t + (CC & 0x01);
3849 SET_FLAGS8(B, t, r);
3854 /* $ea ORB indexed -**0- */
3855 void MC6800::orb_ix()
3864 /* $eb ADDB indexed ***** */
3865 void MC6800::addb_ix()
3871 SET_FLAGS8(B, t, r);
3876 /* $ec LDD indexed -**0- */
3877 void MC6800::ldd_ix()
3884 /* $ec ADX immediate -**** */ /* MB8861 only */
3885 void MC6800::adx_im()
3892 SET_FLAGS16(d, t, r);
3896 /* $ed STD indexed -**0- */
3897 void MC6800::std_ix()
3905 /* $ee LDX indexed -**0- */
3906 void MC6800::ldx_ix()
3913 /* $ef STX indexed -**0- */
3914 void MC6800::stx_ix()
3922 /* $f0 SUBB extended ?**** */
3923 void MC6800::subb_ex()
3929 SET_FLAGS8(B, t, r);
3933 /* $f1 CMPB extended ?**** */
3934 void MC6800::cmpb_ex()
3940 SET_FLAGS8(B, t, r);
3943 /* $f2 SBCB extended ?**** */
3944 void MC6800::sbcb_ex()
3948 r = B - t - (CC & 0x01);
3950 SET_FLAGS8(B, t, r);
3954 /* $f3 ADDD extended -**** */
3955 void MC6800::addd_ex()
3963 SET_FLAGS16(d, b.d, r);
3967 /* $f4 ANDB extended -**0- */
3968 void MC6800::andb_ex()
3977 /* $f5 BITB extended -**0- */
3978 void MC6800::bitb_ex()
3987 /* $f6 LDB extended -**0- */
3988 void MC6800::ldb_ex()
3995 /* $f7 STB extended -**0- */
3996 void MC6800::stb_ex()
4004 /* $f8 EORB extended -**0- */
4005 void MC6800::eorb_ex()
4014 /* $f9 ADCB extended ***** */
4015 void MC6800::adcb_ex()
4019 r = B + t + (CC & 0x01);
4021 SET_FLAGS8(B, t, r);
4026 /* $fa ORB extended -**0- */
4027 void MC6800::orb_ex()
4036 /* $fb ADDB extended ***** */
4037 void MC6800::addb_ex()
4043 SET_FLAGS8(B, t, r);
4048 /* $fc LDD extended -**0- */
4049 void MC6800::ldd_ex()
4056 /* $fc ADX immediate -**** */ /* MB8861 only */
4057 void MC6800::adx_ex()
4065 SET_FLAGS16(d, b.d, r);
4069 /* $fd STD extended -**0- */
4070 void MC6800::std_ex()
4078 /* $fe LDX extended -**0- */
4079 void MC6800::ldx_ex()
4086 /* $ff STX extended -**0- */
4087 void MC6800::stx_ex()
4095 #define STATE_VERSION 1
4097 void MC6800::save_state(FILEIO* state_fio)
4099 state_fio->FputUint32(STATE_VERSION);
4100 state_fio->FputInt32(this_device_id);
4102 state_fio->FputUint32(pc.d);
4103 state_fio->FputUint16(prevpc);
4104 state_fio->FputUint32(sp.d);
4105 state_fio->FputUint32(ix.d);
4106 state_fio->FputUint32(acc_d.d);
4107 state_fio->FputUint32(ea.d);
4108 state_fio->FputUint8(cc);
4109 state_fio->FputInt32(wai_state);
4110 state_fio->FputInt32(int_state);
4111 state_fio->FputInt32(icount);
4112 #if defined(HAS_MC6801) || defined(HAS_HD6301)
4113 for(int i = 0; i < 4; i++) {
4114 state_fio->FputUint8(port[i].wreg);
4115 state_fio->FputUint8(port[i].rreg);
4116 state_fio->FputUint8(port[i].ddr);
4117 state_fio->FputUint8(port[i].latched_data);
4118 state_fio->FputBool(port[i].latched);
4119 state_fio->FputBool(port[i].first_write);
4121 state_fio->FputUint8(p3csr);
4122 state_fio->FputBool(p3csr_is3_flag_read);
4123 state_fio->FputBool(sc1_state);
4124 state_fio->FputBool(sc2_state);
4125 state_fio->FputUint32(counter.d);
4126 state_fio->FputUint32(output_compare.d);
4127 state_fio->FputUint32(timer_over.d);
4128 state_fio->FputUint8(tcsr);
4129 state_fio->FputUint8(pending_tcsr);
4130 state_fio->FputUint16(input_capture);
4132 state_fio->FputUint16(latch09);
4134 state_fio->FputUint32(timer_next);
4135 recv_buffer->save_state((void *)state_fio);
4136 state_fio->FputUint8(trcsr);
4137 state_fio->FputUint8(rdr);
4138 state_fio->FputUint8(tdr);
4139 state_fio->FputBool(trcsr_read_tdre);
4140 state_fio->FputBool(trcsr_read_orfe);
4141 state_fio->FputBool(trcsr_read_rdrf);
4142 state_fio->FputUint8(rmcr);
4143 state_fio->FputInt32(sio_counter);
4144 state_fio->FputUint8(ram_ctrl);
4145 state_fio->Fwrite(ram, sizeof(ram), 1);
4149 bool MC6800::load_state(FILEIO* state_fio)
4151 if(state_fio->FgetUint32() != STATE_VERSION) {
4154 if(state_fio->FgetInt32() != this_device_id) {
4157 pc.d = state_fio->FgetUint32();
4158 prevpc = state_fio->FgetUint16();
4159 sp.d = state_fio->FgetUint32();
4160 ix.d = state_fio->FgetUint32();
4161 acc_d.d = state_fio->FgetUint32();
4162 ea.d = state_fio->FgetUint32();
4163 cc = state_fio->FgetUint8();
4164 wai_state = state_fio->FgetInt32();
4165 int_state = state_fio->FgetInt32();
4166 icount = state_fio->FgetInt32();
4167 #if defined(HAS_MC6801) || defined(HAS_HD6301)
4168 for(int i = 0; i < 4; i++) {
4169 port[i].wreg = state_fio->FgetUint8();
4170 port[i].rreg = state_fio->FgetUint8();
4171 port[i].ddr = state_fio->FgetUint8();
4172 port[i].latched_data = state_fio->FgetUint8();
4173 port[i].latched = state_fio->FgetBool();
4174 port[i].first_write = state_fio->FgetBool();
4176 p3csr = state_fio->FgetUint8();
4177 p3csr_is3_flag_read = state_fio->FgetBool();
4178 sc1_state = state_fio->FgetBool();
4179 sc2_state = state_fio->FgetBool();
4180 counter.d = state_fio->FgetUint32();
4181 output_compare.d = state_fio->FgetUint32();
4182 timer_over.d = state_fio->FgetUint32();
4183 tcsr = state_fio->FgetUint8();
4184 pending_tcsr = state_fio->FgetUint8();
4185 input_capture = state_fio->FgetUint16();
4187 latch09 = state_fio->FgetUint16();
4189 timer_next = state_fio->FgetUint32();
4190 if(!recv_buffer->load_state((void *)state_fio)) {
4193 trcsr = state_fio->FgetUint8();
4194 rdr = state_fio->FgetUint8();
4195 tdr = state_fio->FgetUint8();
4196 trcsr_read_tdre = state_fio->FgetBool();
4197 trcsr_read_orfe = state_fio->FgetBool();
4198 trcsr_read_rdrf = state_fio->FgetBool();
4199 rmcr = state_fio->FgetUint8();
4200 sio_counter = state_fio->FgetInt32();
4201 ram_ctrl = state_fio->FgetUint8();
4202 state_fio->Fread(ram, sizeof(ram), 1);