TV BOYエミュレータを更新しました。
case 0x02: // port1 data register #ifdef _TVBOY if (prevpc==0xff3c) return (port[0].rreg & ~port[0].ddr) | (port[0].wreg & port[0].ddr | 0x80); else #endif return (port[0].rreg & ~port[0].ddr) | (port[0].wreg & port[0].ddr);
case 0x14: // ram control register return (ram_ctrl & 0x40) | 0x3f; #ifdef _TVBOY case 0x19: return 0x10; #endif } return 0; }
- 市街戦200X年(ふつうに遊べる!)
- ミスターボム(ふつうに遊べる!)
- エキサイトインベーダー(ふつうに遊べる!)NEW
- ロボタンウォーズ(ふつうに遊べる!)NEW
- 地対空大作戦(サウンドが鳴らない)
- フロッガー(タイトルでフリーズ)
ソースコード差分は以下になります。
/* Skelton for retropc emulator Origin : MAME 0.142 Author : Takeda.Toshiya Date : 2011.04.23- [ MC6800 ] */ #if defined(_MSC_VER) && (_MSC_VER >= 1400) #pragma warning( disable : 4996 ) #endif #include "mc6800.h" #if defined(HAS_MC6801) || defined(HAS_HD6301) #include "../fifo.h" #endif #ifdef USE_DEBUGGER #include "debugger.h" #endif #define INT_REQ_BIT 1 #define NMI_REQ_BIT 2 #define MC6800_WAI 8 #define HD6301_SLP 0x10 #define pPC pc #define pS sp #define pX ix #define pD acc_d #define pEA ea #define PC pc.w.l #define PCD pc.d #define S sp.w.l #define SD sp.d #define X ix.w.l #define D acc_d.w.l #define A acc_d.b.h #define B acc_d.b.l #define CC cc #define EAD ea.d #define EA ea.w.l /****************************************************************************/ /* memory */ /****************************************************************************/ uint32_t MC6800::RM(uint32_t Addr) { #if defined(HAS_MC6801) || defined(HAS_HD6301) if(Addr < 0x20) { return mc6801_io_r(Addr); } else if(Addr >= 0x80 && Addr < 0x100 && (ram_ctrl & 0x40)) { return ram[Addr & 0x7f]; } #endif return d_mem->read_data8(Addr); } void MC6800::WM(uint32_t Addr, uint32_t Value) { #if defined(HAS_MC6801) || defined(HAS_HD6301) if(Addr < 0x20) { mc6801_io_w(Addr, Value); } else if(Addr >= 0x80 && Addr < 0x100 && (ram_ctrl & 0x40)) { ram[Addr & 0x7f] = Value; } else #endif d_mem->write_data8(Addr, Value); } uint32_t MC6800::RM16(uint32_t Addr) { uint32_t result = RM(Addr) << 8; return result | RM((Addr + 1) & 0xffff); } void MC6800::WM16(uint32_t Addr, pair32_t *p) { WM(Addr, p->b.h); WM((Addr + 1) & 0xffff, p->b.l); } //#define M_RDOP(Addr) d_mem->read_data8(Addr) //#define M_RDOP_ARG(Addr) d_mem->read_data8(Addr) #define M_RDOP(Addr) RM(Addr) #define M_RDOP_ARG(Addr) RM(Addr) /* macros to access memory */ #define IMMBYTE(b) b = M_RDOP_ARG(PCD); PC++ #define IMMWORD(w) w.b.h = M_RDOP_ARG(PCD); w.b.l = M_RDOP_ARG((PCD + 1) & 0xffff); PC += 2 #define PUSHBYTE(b) WM(SD, b); --S #define PUSHWORD(w) WM(SD, w.b.l); --S; WM(SD, w.b.h); --S #define PULLBYTE(b) S++; b = RM(SD) #define PULLWORD(w) S++; w.b.h = RM(SD); S++; w.b.l = RM(SD) /****************************************************************************/ /* MC6801/HD6301 internal i/o port */ /****************************************************************************/ #if defined(HAS_MC6801) || defined(HAS_HD6301) #define CT counter.w.l #define CTH counter.w.h #define CTD counter.d #define OC output_compare.w.l #define OCH output_compare.w.h #define OCD output_compare.d #define TOH timer_over.w.l #define TOD timer_over.d #define SET_TIMER_EVENT { \ timer_next = (OCD - CTD < TOD - CTD) ? OCD : TOD; \ } #define CLEANUP_COUNTERS() { \ OCH -= CTH; \ TOH -= CTH; \ CTH = 0; \ SET_TIMER_EVENT; \ } #define MODIFIED_counters { \ OCH = (OC >= CT) ? CTH : CTH + 1; \ SET_TIMER_EVENT; \ } #define TCSR_OLVL 0x01 #define TCSR_IEDG 0x02 #define TCSR_ETOI 0x04 #define TCSR_EOCI 0x08 #define TCSR_EICI 0x10 #define TCSR_TOF 0x20 #define TCSR_OCF 0x40 #define TCSR_ICF 0x80 #define TRCSR_WU 0x01 #define TRCSR_TE 0x02 #define TRCSR_TIE 0x04 #define TRCSR_RE 0x08 #define TRCSR_RIE 0x10 #define TRCSR_TDRE 0x20 #define TRCSR_ORFE 0x40 #define TRCSR_RDRF 0x80 #define P3CSR_LE 0x08 #define P3CSR_IS3_ENABLE 0x40 #define P3CSR_IS3_FLAG 0x80 static const int RMCR_SS[] = { 16, 128, 1024, 4096 }; /* take interrupt */ #define TAKE_ICI enter_interrupt(0xfff6) #define TAKE_OCI enter_interrupt(0xfff4) #define TAKE_TOI enter_interrupt(0xfff2) #define TAKE_SCI enter_interrupt(0xfff0) #define TAKE_TRAP enter_interrupt(0xffee) uint32_t MC6800::mc6801_io_r(uint32_t offset) { switch (offset) { case 0x00: // port1 data direction register return port[0].ddr; case 0x01: // port2 data direction register return port[1].ddr; case 0x02: // port1 data register #ifdef _TVBOY if (prevpc==0xff3c) return (port[0].rreg & ~port[0].ddr) | (port[0].wreg & port[0].ddr | 0x80); else #endif return (port[0].rreg & ~port[0].ddr) | (port[0].wreg & port[0].ddr); case 0x03: // port2 data register return (port[1].rreg & ~port[1].ddr) | (port[1].wreg & port[1].ddr); case 0x04: // port3 data direction register (write only???) return port[2].ddr; case 0x05: // port4 data direction register return port[3].ddr; case 0x06: // port3 data register if(p3csr_is3_flag_read) { p3csr_is3_flag_read = false; p3csr &= ~P3CSR_IS3_FLAG; } if(port[2].latched) { port[2].latched = false; return (port[2].latched_data & ~port[2].ddr) | (port[2].wreg & port[2].ddr); } return (port[2].rreg & ~port[2].ddr) | (port[2].wreg & port[2].ddr); case 0x07: // port4 data register return (port[3].rreg & ~port[3].ddr) | (port[3].wreg & port[3].ddr); case 0x08: // timer control register pending_tcsr = 0; return tcsr; case 0x09: // free running counter (msb) if(!(pending_tcsr & TCSR_TOF)) { tcsr &= ~TCSR_TOF; } return counter.b.h; case 0x0a: // free running counter (lsb) return counter.b.l; case 0x0b: // output compare register (msb) if(!(pending_tcsr & TCSR_OCF)) { tcsr &= ~TCSR_OCF; } return output_compare.b.h; case 0x0c: // output compare register (lsb) if(!(pending_tcsr & TCSR_OCF)) { tcsr &= ~TCSR_OCF; } return output_compare.b.l; case 0x0d: // input capture register (msb) if(!(pending_tcsr & TCSR_ICF)) { tcsr &= ~TCSR_ICF; } return (input_capture >> 0) & 0xff; case 0x0e: // input capture register (lsb) return (input_capture >> 8) & 0xff; case 0x0f: // port3 control/status register p3csr_is3_flag_read = true; return p3csr; case 0x10: // rate and mode control register return rmcr; case 0x11: if(trcsr & TRCSR_TDRE) { trcsr_read_tdre = true; } if(trcsr & TRCSR_ORFE) { trcsr_read_orfe = true; } if(trcsr & TRCSR_RDRF) { trcsr_read_rdrf = true; } return trcsr; case 0x12: // receive data register if(trcsr_read_orfe) { trcsr_read_orfe = false; trcsr &= ~TRCSR_ORFE; } if(trcsr_read_rdrf) { trcsr_read_rdrf = false; trcsr &= ~TRCSR_RDRF; } return rdr; case 0x13: // transmit data register return tdr; case 0x14: // ram control register return (ram_ctrl & 0x40) | 0x3f; #ifdef _TVBOY case 0x19: return 0x10; #endif } return 0; } void MC6800::mc6801_io_w(uint32_t offset, uint32_t data) { switch(offset) { case 0x00: // port1 data direction register port[0].ddr = data; break; case 0x01: // port2 data direction register port[1].ddr = data; break; case 0x02: // port1 data register if(port[0].wreg != data || port[0].first_write) { write_signals(&port[0].outputs, data); port[0].wreg = data; port[0].first_write = false; } break; case 0x03: // port2 data register if(port[1].wreg != data || port[1].first_write) { write_signals(&port[1].outputs, data); port[1].wreg = data; port[1].first_write = false; } break; case 0x04: // port3 data direction register port[2].ddr = data; break; case 0x05: // port4 data direction register port[3].ddr = data; break; case 0x06: // port3 data register if(p3csr_is3_flag_read) { p3csr_is3_flag_read = false; p3csr &= ~P3CSR_IS3_FLAG; } if(port[2].wreg != data || port[2].first_write) { write_signals(&port[2].outputs, data); port[2].wreg = data; port[2].first_write = false; } break; case 0x07: // port4 data register if(port[3].wreg != data || port[3].first_write) { write_signals(&port[3].outputs, data); port[3].wreg = data; port[3].first_write = false; } break; case 0x08: // timer control/status register tcsr = data; pending_tcsr &= tcsr; break; case 0x09: // free running counter (msb) #ifdef HAS_HD6301 latch09 = data & 0xff; #endif CT = 0xfff8; TOH = CTH; MODIFIED_counters; break; #ifdef HAS_HD6301 case 0x0a: // free running counter (lsb) CT = (latch09 << 8) | (data & 0xff); TOH = CTH; MODIFIED_counters; break; #endif case 0x0b: // output compare register (msb) if(output_compare.b.h != data) { output_compare.b.h = data; MODIFIED_counters; } tcsr &=~TCSR_OCF; break; case 0x0c: // output compare register (lsb) if(output_compare.b.l != data) { output_compare.b.l = data; MODIFIED_counters; } tcsr &=~TCSR_OCF; break; case 0x0f: // port3 control/status register p3csr = (p3csr & P3CSR_IS3_FLAG) | (data & ~P3CSR_IS3_FLAG); break; case 0x10: // rate and mode control register rmcr = data; break; case 0x11: // transmit/receive control/status register trcsr = (trcsr & 0xe0) | (data & 0x1f); break; case 0x13: // transmit data register if(trcsr_read_tdre) { trcsr_read_tdre = false; trcsr &= ~TRCSR_TDRE; } tdr = data; break; case 0x14: // ram control register ram_ctrl = data; break; } } #endif void MC6800::increment_counter(int amount) { #ifdef USE_DEBUGGER total_icount += amount; #endif icount -= amount; #if defined(HAS_MC6801) || defined(HAS_HD6301) // timer if((CTD += amount) >= timer_next) { /* OCI */ if( CTD >= OCD) { OCH++; // next IRQ point tcsr |= TCSR_OCF; pending_tcsr |= TCSR_OCF; } /* TOI */ if( CTD >= TOD) { TOH++; // next IRQ point tcsr |= TCSR_TOF; pending_tcsr |= TCSR_TOF; } /* set next event */ SET_TIMER_EVENT; } // serial i/o if((sio_counter -= amount) <= 0) { if((trcsr & TRCSR_TE) && !(trcsr & TRCSR_TDRE)) { write_signals(&outputs_sio, tdr); trcsr |= TRCSR_TDRE; } if((trcsr & TRCSR_RE) && !recv_buffer->empty()) { if(trcsr & TRCSR_WU) { // skip 10 bits trcsr &= ~TRCSR_WU; recv_buffer->read(); } else if(!(trcsr & TRCSR_RDRF)) { // note: wait reveived data is read by cpu, so overrun framing error never occurs rdr = recv_buffer->read(); trcsr |= TRCSR_RDRF; } } sio_counter += RMCR_SS[rmcr & 3]; } #endif } #define CLR_HNZVC CC &= 0xd0 #define CLR_NZV CC &= 0xf1 #define CLR_HNZC CC &= 0xd2 #define CLR_NZVC CC &= 0xf0 #define CLR_NZ CC &= 0xf3 #define CLR_Z CC &= 0xfb #define CLR_NZC CC &= 0xf2 #define CLR_ZC CC &= 0xfa #define CLR_C CC &= 0xfe #define SET_Z(a) if(!(a)) SEZ #define SET_Z8(a) SET_Z((uint8_t)(a)) #define SET_Z16(a) SET_Z((uint16_t)(a)) #define SET_N8(a) CC |= (((a) & 0x80) >> 4) #define SET_N16(a) CC |= (((a) & 0x8000) >> 12) #define SET_H(a,b,r) CC |= ((((a) ^ (b) ^ (r)) & 0x10) << 1) #define SET_C8(a) CC |= (((a) & 0x100) >> 8) #define SET_C16(a) CC |= (((a) & 0x10000) >> 16) #define SET_V8(a,b,r) CC |= ((((a) ^ (b) ^ (r) ^ ((r) >> 1)) & 0x80) >> 6) #define SET_V16(a,b,r) CC |= ((((a) ^ (b) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 14) static const uint8_t flags8i[256] = { /* increment */ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x0a,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08 }; static const uint8_t flags8d[256] = { /* decrement */ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08 }; #define SET_FLAGS8I(a) {CC |= flags8i[(a) & 0xff];} #define SET_FLAGS8D(a) {CC |= flags8d[(a) & 0xff];} /* combos */ #define SET_NZ8(a) {SET_N8(a); SET_Z8(a);} #define SET_NZ16(a) {SET_N16(a); SET_Z16(a);} #define SET_FLAGS8(a,b,r) {SET_N8(r); SET_Z8(r); SET_V8(a,b,r); SET_C8(r); } #define SET_FLAGS16(a,b,r) {SET_N16(r); SET_Z16(r); SET_V16(a,b,r); SET_C16(r);} /* for treating an uint8_t as a signed int16_t */ #define SIGNED(b) ((int16_t)(b & 0x80 ? b | 0xff00 : b)) /* Macros for addressing modes */ #define DIRECT IMMBYTE(EAD) #define IMM8 EA = PC++ #define IMM16 {EA = PC; PC += 2;} #define EXTENDED IMMWORD(pEA) #define INDEXED {EA = X + (uint8_t)M_RDOP_ARG(PCD); PC++;} /* macros to set status flags */ #define SEC CC |= 0x01 #define CLC CC &= 0xfe #define SEZ CC |= 0x04 #define CLZ CC &= 0xfb #define SEN CC |= 0x08 #define CLN CC &= 0xf7 #define SEV CC |= 0x02 #define CLV CC &= 0xfd #define SEH CC |= 0x20 #define CLH CC &= 0xdf #define SEI CC |= 0x10 #define CLI CC &= ~0x10 /* macros for convenience */ #define DIRBYTE(b) {DIRECT; b = RM(EAD); } #define DIRWORD(w) {DIRECT; w.d = RM16(EAD);} #define EXTBYTE(b) {EXTENDED; b = RM(EAD); } #define EXTWORD(w) {EXTENDED; w.d = RM16(EAD);} #define IDXBYTE(b) {INDEXED; b = RM(EAD); } #define IDXWORD(w) {INDEXED; w.d = RM16(EAD);} /* Macros for branch instructions */ #define BRANCH(f) {IMMBYTE(t); if(f) {PC += SIGNED(t);}} #define NXORV ((CC & 0x08) ^ ((CC & 0x02) << 2)) /* Note: don't use 0 cycles here for invalid opcodes so that we don't */ /* hang in an infinite loop if we hit one */ #define XX 5 // invalid opcode unknown cc static const uint8_t cycles[] = { #if defined(HAS_MC6800) XX, 2,XX,XX,XX,XX, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,XX,XX,XX,XX, 2, 2,XX, 2,XX, 2,XX,XX,XX,XX, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,XX, 5,XX,10,XX,XX, 9,12, 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2, 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2, 7,XX,XX, 7, 7,XX, 7, 7, 7, 7, 7,XX, 7, 7, 4, 7, 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 6, 3, 6, 2, 2, 2,XX, 2, 2, 2, 3, 2, 2, 2, 2, 3, 8, 3, 4, 3, 3, 3,XX, 3, 3, 3, 4, 3, 3, 3, 3, 4, 6, 4, 5, 5, 5, 5,XX, 5, 5, 5, 6, 5, 5, 5, 5, 6, 8, 6, 7, 4, 4, 4,XX, 4, 4, 4, 5, 4, 4, 4, 4, 5, 9, 5, 6, 2, 2, 2,XX, 2, 2, 2, 3, 2, 2, 2, 2,XX,XX, 3, 4, 3, 3, 3,XX, 3, 3, 3, 4, 3, 3, 3, 3,XX,XX, 4, 5, 5, 5, 5,XX, 5, 5, 5, 6, 5, 5, 5, 5,XX,XX, 6, 7, 4, 4, 4,XX, 4, 4, 4, 5, 4, 4, 4, 4,XX,XX, 5, 6 #elif defined(HAS_MC6801) XX, 2,XX,XX, 3, 3, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,XX,XX,XX,XX, 2, 2,XX, 2,XX, 2,XX,XX,XX,XX, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, 5, 5, 3,10, 4,10, 9,12, 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2, 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2, 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 6, 3, 6, 6,XX,XX, 6, 6,XX, 6, 6, 6, 6, 6,XX, 6, 6, 3, 6, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 4, 6, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 5, 5, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 5, 5, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 3,XX, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5 #elif defined(HAS_HD6301) XX, 1,XX,XX, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,XX,XX,XX,XX, 1, 1, 2, 2, 4, 1,XX,XX,XX,XX, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 1, 1, 4, 4, 4, 5, 1,10, 5, 7, 9,12, 1,XX,XX, 1, 1,XX, 1, 1, 1, 1, 1,XX, 1, 1,XX, 1, 1,XX,XX, 1, 1,XX, 1, 1, 1, 1, 1,XX, 1, 1,XX, 1, 6, 7, 7, 6, 6, 7, 6, 6, 6, 6, 6, 5, 6, 4, 3, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 6, 4, 3, 5, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 5, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3,XX, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5 #elif defined(HAS_MB8861) XX, 2,XX,XX,XX,XX, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,XX,XX,XX,XX, 2, 2,XX, 2,XX, 2,XX,XX,XX,XX, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,XX, 5,XX,10,XX,XX, 9,12, 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2, 2,XX,XX, 2, 2,XX, 2, 2, 2, 2, 2,XX, 2, 2,XX, 2, 7,XX,XX, 7, 7,XX, 7, 7, 7, 7, 7,XX, 7, 7, 4, 7, 6, 8, 8, 6, 6, 8, 6, 6, 6, 6, 6, 7, 6, 6, 3, 6, 2, 2, 2,XX, 2, 2, 2, 3, 2, 2, 2, 2, 3, 8, 3, 4, 3, 3, 3,XX, 3, 3, 3, 4, 3, 3, 3, 3, 4, 6, 4, 5, 5, 5, 5,XX, 5, 5, 5, 6, 5, 5, 5, 5, 6, 8, 6, 7, 4, 4, 4,XX, 4, 4, 4, 5, 4, 4, 4, 4, 5, 9, 5, 6, 2, 2, 2,XX, 2, 2, 2, 3, 2, 2, 2, 2,XX,XX, 3, 4, 3, 3, 3,XX, 3, 3, 3, 4, 3, 3, 3, 3,XX,XX, 4, 5, 5, 5, 5,XX, 5, 5, 5, 6, 5, 5, 5, 5, 4,XX, 6, 7, 4, 4, 4,XX, 4, 4, 4, 5, 4, 4, 4, 4, 7,XX, 5, 6 #endif }; #undef XX // invalid opcode unknown cc void MC6800::initialize() { #if defined(HAS_MC6801) || defined(HAS_HD6301) recv_buffer = new FIFO(0x10000); ram_ctrl = 0xc0; #endif #ifdef USE_DEBUGGER d_mem_stored = d_mem; d_debugger->set_context_mem(d_mem); #endif } #if defined(HAS_MC6801) || defined(HAS_HD6301) void MC6800::release() { recv_buffer->release(); delete recv_buffer; } #endif void MC6800::reset() { CC = 0xc0; SEI; /* IRQ disabled */ PCD = RM16(0xfffe); // S = X = D = EA = 0; SD = X = D = EAD = 0; wai_state = 0; int_state = 0; icount = 0; #if defined(HAS_MC6801) || defined(HAS_HD6301) for(int i = 0; i < 4; i++) { port[i].ddr = 0x00; port[i].first_write = true; port[i].latched = false; } p3csr = 0x00; p3csr_is3_flag_read = false; sc1_state = sc2_state = false; tcsr = pending_tcsr = 0x00; CTD = 0x0000; OCD = 0xffff; TOD = 0xffff; recv_buffer->clear(); trcsr = TRCSR_TDRE; trcsr_read_tdre = trcsr_read_orfe = trcsr_read_rdrf = false; rmcr = 0x00; sio_counter = RMCR_SS[rmcr & 3]; ram_ctrl |= 0x40; #endif } void MC6800::write_signal(int id, uint32_t data, uint32_t mask) { switch(id) { case SIG_CPU_IRQ: if(data & mask) { int_state |= INT_REQ_BIT; } else { int_state &= ~INT_REQ_BIT; } break; case SIG_CPU_NMI: if(data & mask) { int_state |= NMI_REQ_BIT; } else { int_state &= ~NMI_REQ_BIT; } break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case SIG_MC6801_PORT_1: port[0].rreg = (port[0].rreg & ~mask) | (data & mask); break; case SIG_MC6801_PORT_2: if((mask & 1) && (port[1].rreg & 1) != (data & 1) && (tcsr & 2) == ((data << 1) & 2)) { // active TIN edge in tcsr |= TCSR_ICF; pending_tcsr |= TCSR_ICF; input_capture = CT; } port[1].rreg = (port[1].rreg & ~mask) | (data & mask); break; case SIG_MC6801_PORT_3: port[2].rreg = (port[2].rreg & ~mask) | (data & mask); break; case SIG_MC6801_PORT_4: port[3].rreg = (port[3].rreg & ~mask) | (data & mask); break; case SIG_MC6801_PORT_3_SC1: if(sc1_state && !(data & mask)) { // SC1: H -> L if(!port[2].latched && (p3csr & P3CSR_LE)) { port[2].latched_data = port[2].rreg; port[2].latched = true; p3csr |= P3CSR_IS3_FLAG; } } sc1_state = ((data & mask) != 0); break; case SIG_MC6801_PORT_3_SC2: sc2_state = ((data & mask) != 0); break; case SIG_MC6801_SIO_RECV: recv_buffer->write(data & mask); break; #endif } } int MC6800::run(int clock) { // run cpu if(clock == -1) { // run only one opcode #if defined(HAS_MC6801) || defined(HAS_HD6301) CLEANUP_COUNTERS(); #endif icount = 0; run_one_opecode(); return -icount; } else { /* run cpu while given clocks */ #if defined(HAS_MC6801) || defined(HAS_HD6301) CLEANUP_COUNTERS(); #endif icount += clock; int first_icount = icount; while(icount > 0) { run_one_opecode(); } return first_icount - icount; } } void MC6800::run_one_opecode() { if(wai_state & (MC6800_WAI | HD6301_SLP)) { increment_counter(1); } else { do { one_more_insn = false; #ifdef USE_DEBUGGER bool now_debugging = d_debugger->now_debugging; if(now_debugging) { d_debugger->check_break_points(PC); if(d_debugger->now_suspended) { d_debugger->now_waiting = true; emu->start_waiting_in_debugger(); while(d_debugger->now_debugging && d_debugger->now_suspended) { emu->process_waiting_in_debugger(); } emu->finish_waiting_in_debugger(); d_debugger->now_waiting = false; } if(d_debugger->now_debugging) { d_mem = d_debugger; } else { now_debugging = false; } d_debugger->add_cpu_trace(PC); uint8_t ireg = M_RDOP(PCD); prevpc = PC; PC++; insn(ireg); increment_counter(cycles[ireg]); if(now_debugging) { if(!d_debugger->now_going) { d_debugger->now_suspended = true; } d_mem = d_mem_stored; } } else { d_debugger->add_cpu_trace(PC); #endif uint8_t ireg = M_RDOP(PCD); prevpc = PC; PC++; insn(ireg); increment_counter(cycles[ireg]); #ifdef USE_DEBUGGER } #endif } while(one_more_insn); } // check interrupt if(int_state & NMI_REQ_BIT) { wai_state &= ~HD6301_SLP; int_state &= ~NMI_REQ_BIT; enter_interrupt(0xfffc); } else if(int_state & INT_REQ_BIT) { wai_state &= ~HD6301_SLP; if(!(CC & 0x10)) { int_state &= ~INT_REQ_BIT; enter_interrupt(0xfff8); } #if defined(HAS_MC6801) || defined(HAS_HD6301) } else if((tcsr & (TCSR_EICI | TCSR_ICF)) == (TCSR_EICI | TCSR_ICF)) { wai_state &= ~HD6301_SLP; if(!(CC & 0x10)) { TAKE_ICI; } } else if((tcsr & (TCSR_EOCI | TCSR_OCF)) == (TCSR_EOCI | TCSR_OCF)) { wai_state &= ~HD6301_SLP; if(!(CC & 0x10)) { TAKE_OCI; } } else if((tcsr & (TCSR_ETOI | TCSR_TOF)) == (TCSR_ETOI | TCSR_TOF)) { wai_state &= ~HD6301_SLP; if(!(CC & 0x10)) { TAKE_TOI; } } else if(((trcsr & (TRCSR_RIE | TRCSR_RDRF)) == (TRCSR_RIE | TRCSR_RDRF)) || ((trcsr & (TRCSR_RIE | TRCSR_ORFE)) == (TRCSR_RIE | TRCSR_ORFE)) || ((trcsr & (TRCSR_TIE | TRCSR_TDRE)) == (TRCSR_TIE | TRCSR_TDRE))) { wai_state &= ~HD6301_SLP; if(!(CC & 0x10)) { TAKE_SCI; } #endif } } #ifdef USE_DEBUGGER void MC6800::write_debug_data8(uint32_t addr, uint32_t data) { int wait; d_mem_stored->write_data8w(addr, data, &wait); } uint32_t MC6800::read_debug_data8(uint32_t addr) { int wait; return d_mem_stored->read_data8w(addr, &wait); } void MC6800::write_debug_data16(uint32_t addr, uint32_t data) { write_debug_data8(addr, (data >> 8) & 0xff); write_debug_data8(addr + 1, data & 0xff); } uint32_t MC6800::read_debug_data16(uint32_t addr) { uint32_t val = read_debug_data8(addr) << 8; val |= read_debug_data8(addr + 1); return val; } void MC6800::write_debug_data32(uint32_t addr, uint32_t data) { write_debug_data16(addr, (data >> 16) & 0xffff); write_debug_data16(addr + 2, data & 0xffff); } uint32_t MC6800::read_debug_data32(uint32_t addr) { uint32_t val = read_debug_data16(addr) << 16; val |= read_debug_data16(addr + 2); return val; } bool MC6800::write_debug_reg(const _TCHAR *reg, uint32_t data) { if(_tcsicmp(reg, _T("A")) == 0) { A = data; } else if(_tcsicmp(reg, _T("B")) == 0) { B = data; } else if(_tcsicmp(reg, _T("X")) == 0 || _tcsicmp(reg, _T("IX")) == 0) { X = data; } else if(_tcsicmp(reg, _T("PC")) == 0) { PC = data; } else if(_tcsicmp(reg, _T("SP")) == 0) { S = data; } else { return false; } return true; } bool MC6800::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) { my_stprintf_s(buffer, buffer_len, _T("CCR = [%c%c%c%c%c%c] A = %02X B = %02X IX = %04X PC = %04X SP = %04X\n") _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), (CC & 0x01) ? _T('C') : _T('-'), (CC & 0x02) ? _T('V') : _T('-'), (CC & 0x04) ? _T('Z') : _T('-'), (CC & 0x08) ? _T('N') : _T('-'), (CC & 0x10) ? _T('I') : _T('-'), (CC & 0x20) ? _T('X') : _T('-'), A, B, X, PC, S, total_icount, total_icount - prev_total_icount, get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); prev_total_icount = total_icount; return true; } /* * A quick-hack 6803/6808 disassembler * * Note: this is not the good and proper way to disassemble anything, but it works * * I'm afraid to put my name on it, but I feel obligated: * This code written by Aaron Giles (agiles@sirius.com) for the MAME project * * History: * 990314 HJB * The disassembler knows about valid opcodes for M6800/1/2/3/8 and HD63701. * 990302 HJB * Changed the string array into a table of opcode names (or tokens) and * argument types. This second try should give somewhat better results. * Named the undocumented HD63701YO opcodes $12 and $13 'asx1' and 'asx2', * since 'add contents of stack to x register' is what they do. * */ enum addr_mode { inh, /* inherent */ rel, /* relative */ imb, /* immediate (byte) */ imw, /* immediate (word) */ dir, /* direct address */ imd, /* HD63701YO: immediate, direct address */ ext, /* extended address */ idx, /* x + byte offset */ imx, /* HD63701YO: immediate, x + byte offset */ sx1 /* HD63701YO: undocumented opcodes: byte from (s+1) */ }; enum op_names { aba=0, abx, adca, adcb, adda, addb, addd, aim, anda, andb, asl, asla, aslb, asld, asr, asra, asrb, bcc, bcs, beq, bge, bgt, bhi, bita, bitb, ble, bls, blt, bmi, bne, bpl, bra, brn, bsr, bvc, bvs, cba, clc, cli, clr, clra, clrb, clv, cmpa, cmpb, cmpx, com, coma, comb, daa, dec, deca, decb, des, dex, eim, eora, eorb, ill, inc, inca, incb, ins, inx, jmp, jsr, lda, ldb, ldd, lds, ldx, lsr, lsra, lsrb, lsrd, mul, neg, nega, negb, nop, oim, ora, orb, psha, pshb, pshx, pula, pulb, pulx, rol, rola, rolb, ror, rora, rorb, rti, rts, sba, sbca, sbcb, sec, sev, sta, stb, _std, sei, sts, stx, suba, subb, subd, swi, wai, tab, tap, tba, tim, tpa, tst, tsta, tstb, tsx, txs, asx1, asx2, xgdx, addx, adcx }; static const char *const op_name_str[] = { "aba", "abx", "adca", "adcb", "adda", "addb", "addd", "aim", "anda", "andb", "asl", "asla", "aslb", "asld", "asr", "asra", "asrb", "bcc", "bcs", "beq", "bge", "bgt", "bhi", "bita", "bitb", "ble", "bls", "blt", "bmi", "bne", "bpl", "bra", "brn", "bsr", "bvc", "bvs", "cba", "clc", "cli", "clr", "clra", "clrb", "clv", "cmpa", "cmpb", "cmpx", "com", "coma", "comb", "daa", "dec", "deca", "decb", "des", "dex", "eim", "eora", "eorb", "illegal","inc", "inca", "incb", "ins", "inx", "jmp", "jsr", "lda", "ldb", "ldd", "lds", "ldx", "lsr", "lsra", "lsrb", "lsrd", "mul", "neg", "nega", "negb", "nop", "oim", "ora", "orb", "psha", "pshb", "pshx", "pula", "pulb", "pulx", "rol", "rola", "rolb", "ror", "rora", "rorb", "rti", "rts", "sba", "sbca", "sbcb", "sec", "sev", "sta", "stb", "std", "sei", "sts", "stx", "suba", "subb", "subd", "swi", "wai", "tab", "tap", "tba", "tim", "tpa", "tst", "tsta", "tstb", "tsx", "txs", "asx1", "asx2", "xgdx", "addx", "adcx" }; /* * This table defines the opcodes: * byte meaning * 0 token (menmonic) * 1 addressing mode * 2 invalid opcode for 1:6800/6802/6808, 2:6801/6803, 4:HD63701 */ static const UINT8 table[0x102][3] = { {ill, inh,7},{nop, inh,0},{ill, inh,7},{ill, inh,7},/* 00 */ {lsrd,inh,1},{asld,inh,1},{tap, inh,0},{tpa, inh,0}, {inx, inh,0},{dex, inh,0},{clv, inh,0},{sev, inh,0}, {clc, inh,0},{sec, inh,0},{cli, inh,0},{sei, inh,0}, {sba, inh,0},{cba, inh,0},{asx1,sx1,0},{asx2,sx1,0},/* 10 */ {ill, inh,7},{ill, inh,7},{tab, inh,0},{tba, inh,0}, {xgdx,inh,3},{daa, inh,0},{ill, inh,7},{aba, inh,0}, {ill, inh,7},{ill, inh,7},{ill, inh,7},{ill, inh,7}, {bra, rel,0},{brn, rel,0},{bhi, rel,0},{bls, rel,0},/* 20 */ {bcc, rel,0},{bcs, rel,0},{bne, rel,0},{beq, rel,0}, {bvc, rel,0},{bvs, rel,0},{bpl, rel,0},{bmi, rel,0}, {bge, rel,0},{blt, rel,0},{bgt, rel,0},{ble, rel,0}, {tsx, inh,0},{ins, inh,0},{pula,inh,0},{pulb,inh,0},/* 30 */ {des, inh,0},{txs, inh,0},{psha,inh,0},{pshb,inh,0}, {pulx,inh,1},{rts, inh,0},{abx, inh,1},{rti, inh,0}, {pshx,inh,1},{mul, inh,1},{wai, inh,0},{swi, inh,0}, {nega,inh,0},{ill, inh,7},{ill, inh,7},{coma,inh,0},/* 40 */ {lsra,inh,0},{ill, inh,7},{rora,inh,0},{asra,inh,0}, {asla,inh,0},{rola,inh,0},{deca,inh,0},{ill, inh,7}, {inca,inh,0},{tsta,inh,0},{ill, inh,7},{clra,inh,0}, {negb,inh,0},{ill, inh,7},{ill, inh,7},{comb,inh,0},/* 50 */ {lsrb,inh,0},{ill, inh,7},{rorb,inh,0},{asrb,inh,0}, {aslb,inh,0},{rolb,inh,0},{decb,inh,0},{ill, inh,7}, {incb,inh,0},{tstb,inh,0},{ill, inh,7},{clrb,inh,0}, {neg, idx,0},{aim, imx,3},{oim, imx,3},{com, idx,0},/* 60 */ {lsr, idx,0},{eim, imx,3},{ror, idx,0},{asr, idx,0}, {asl, idx,0},{rol, idx,0},{dec, idx,0},{tim, imx,3}, {inc, idx,0},{tst, idx,0},{jmp, idx,0},{clr, idx,0}, {neg, ext,0},{aim, imd,3},{oim, imd,3},{com, ext,0},/* 70 */ {lsr, ext,0},{eim, imd,3},{ror, ext,0},{asr, ext,0}, {asl, ext,0},{rol, ext,0},{dec, ext,0},{tim, imd,3}, {inc, ext,0},{tst, ext,0},{jmp, ext,0},{clr, ext,0}, {suba,imb,0},{cmpa,imb,0},{sbca,imb,0},{subd,imw,1},/* 80 */ {anda,imb,0},{bita,imb,0},{lda, imb,0},{sta, imb,0}, {eora,imb,0},{adca,imb,0},{ora, imb,0},{adda,imb,0}, {cmpx,imw,0},{bsr, rel,0},{lds, imw,0},{sts, imw,0}, {suba,dir,0},{cmpa,dir,0},{sbca,dir,0},{subd,dir,1},/* 90 */ {anda,dir,0},{bita,dir,0},{lda, dir,0},{sta, dir,0}, {eora,dir,0},{adca,dir,0},{ora, dir,0},{adda,dir,0}, {cmpx,dir,0},{jsr, dir,0},{lds, dir,0},{sts, dir,0}, {suba,idx,0},{cmpa,idx,0},{sbca,idx,0},{subd,idx,1},/* a0 */ {anda,idx,0},{bita,idx,0},{lda, idx,0},{sta, idx,0}, {eora,idx,0},{adca,idx,0},{ora, idx,0},{adda,idx,0}, {cmpx,idx,0},{jsr, idx,0},{lds, idx,0},{sts, idx,0}, {suba,ext,0},{cmpa,ext,0},{sbca,ext,0},{subd,ext,1},/* b0 */ {anda,ext,0},{bita,ext,0},{lda, ext,0},{sta, ext,0}, {eora,ext,0},{adca,ext,0},{ora, ext,0},{adda,ext,0}, {cmpx,ext,0},{jsr, ext,0},{lds, ext,0},{sts, ext,0}, {subb,imb,0},{cmpb,imb,0},{sbcb,imb,0},{addd,imw,1},/* c0 */ {andb,imb,0},{bitb,imb,0},{ldb, imb,0},{stb, imb,0}, {eorb,imb,0},{adcb,imb,0},{orb, imb,0},{addb,imb,0}, {ldd, imw,1},{_std,imw,1},{ldx, imw,0},{stx, imw,0}, {subb,dir,0},{cmpb,dir,0},{sbcb,dir,0},{addd,dir,1},/* d0 */ {andb,dir,0},{bitb,dir,0},{ldb, dir,0},{stb, dir,0}, {eorb,dir,0},{adcb,dir,0},{orb, dir,0},{addb,dir,0}, {ldd, dir,1},{_std,dir,1},{ldx, dir,0},{stx, dir,0}, {subb,idx,0},{cmpb,idx,0},{sbcb,idx,0},{addd,idx,1},/* e0 */ {andb,idx,0},{bitb,idx,0},{ldb, idx,0},{stb, idx,0}, {eorb,idx,0},{adcb,idx,0},{orb, idx,0},{addb,idx,0}, {ldd, idx,1},{_std,idx,1},{ldx, idx,0},{stx, idx,0}, {subb,ext,0},{cmpb,ext,0},{sbcb,ext,0},{addd,ext,1},/* f0 */ {andb,ext,0},{bitb,ext,0},{ldb, ext,0},{stb, ext,0}, {eorb,ext,0},{adcb,ext,0},{orb, ext,0},{addb,ext,0}, {ldd, ext,1},{_std,ext,1},{ldx, ext,0},{stx, ext,0}, /* extra instruction $fc for NSC-8105 */ {addx,ext,0}, /* extra instruction $ec for NSC-8105 */ {adcx,imb,0} }; /* some macros to keep things short */ #define OP oprom[0] #define ARG1 opram[1] #define ARG2 opram[2] #define ARGW (opram[1]<<8) + opram[2] static unsigned Dasm680x (int subtype, _TCHAR *buf, unsigned pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol) { // UINT32 flags = 0; int invalid_mask; int code = OP; UINT8 opcode, args, invalid; switch( subtype ) { case 6800: case 6802: case 6808: case 8105: invalid_mask = 1; break; case 6801: case 6803: invalid_mask = 2; break; default: invalid_mask = 4; } /* NSC-8105 is a special case */ if (subtype == 8105) { /* swap bits */ code = (code & 0x3c) | ((code & 0x41) << 1) | ((code & 0x82) >> 1); /* and check for extra instruction */ if (code == 0xfc) code = 0x0100; if (code == 0xec) code = 0x0101; } opcode = table[code][0]; args = table[code][1]; invalid = table[code][2]; // if (opcode == bsr || opcode == jsr) { // flags = DASMFLAG_STEP_OVER; // } else if (opcode == rti || opcode == rts) { // flags = DASMFLAG_STEP_OUT; // } if ( invalid & invalid_mask ) /* invalid for this cpu type ? */ { _tcscpy(buf, _T("illegal")); return 1;// | flags | DASMFLAG_SUPPORTED; } buf += _stprintf(buf, _T("%-5s"), op_name_str[opcode]); switch( args ) { case rel: /* relative */ _stprintf (buf, _T("%s"), get_value_or_symbol(first_symbol, _T("$%04X"), pc + (INT8)ARG1 + 2)); return 2;// | flags | DASMFLAG_SUPPORTED; case imb: /* immediate (byte) */ _stprintf (buf, _T("#$%02X"), ARG1); return 2;// | flags | DASMFLAG_SUPPORTED; case imw: /* immediate (word) */ _stprintf (buf, _T("#%s"), get_value_or_symbol(first_symbol, _T("$%04X"), ARGW)); return 3;// | flags | DASMFLAG_SUPPORTED; case idx: /* indexed + byte offset */ _stprintf (buf, _T("(x+$%02X)"), ARG1 ); return 2;// | flags | DASMFLAG_SUPPORTED; case imx: /* immediate, indexed + byte offset */ _stprintf (buf, _T("#$%02X,(x+$%02x)"), ARG1, ARG2 ); return 3;// | flags | DASMFLAG_SUPPORTED; case dir: /* direct address */ _stprintf (buf, _T("$%02X"), ARG1 ); return 2;// | flags | DASMFLAG_SUPPORTED; case imd: /* immediate, direct address */ _stprintf (buf, _T("#$%02X,$%02X"), ARG1, ARG2); return 3;// | flags | DASMFLAG_SUPPORTED; case ext: /* extended address */ _stprintf (buf, _T("%s"), get_value_or_symbol(first_symbol, _T("$%04X"), ARGW)); return 3;// | flags | DASMFLAG_SUPPORTED; case sx1: /* byte from address (s + 1) */ _stprintf (buf, _T("(s+1)")); return 1;// | flags | DASMFLAG_SUPPORTED; default: return 1;// | flags | DASMFLAG_SUPPORTED; } } int MC6800::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len) { uint8_t ops[4]; for(int i = 0; i < 4; i++) { int wait; ops[i] = d_mem_stored->read_data8w(pc + i, &wait); } #if defined(HAS_MC6800) return Dasm680x(6800, buffer, pc, ops, ops, d_debugger->first_symbol); #elif defined(HAS_MC6801) return Dasm680x(6801, buffer, pc, ops, ops, d_debugger->first_symbol); #elif defined(HAS_HD6301) return Dasm680x(6301, buffer, pc, ops, ops, d_debugger->first_symbol); #elif defined(HAS_MB8861) return Dasm680x(6800, buffer, pc, ops, ops, d_debugger->first_symbol); // FIXME #endif return 0; } #endif void MC6800::enter_interrupt(uint16_t irq_vector) { if(wai_state & MC6800_WAI) { #ifdef USE_DEBUGGER total_icount += 4; #endif icount -= 4; wai_state &= ~MC6800_WAI; } else { PUSHWORD(pPC); PUSHWORD(pX); PUSHBYTE(A); PUSHBYTE(B); PUSHBYTE(CC); #ifdef USE_DEBUGGER total_icount += 12; #endif icount -= 12; } SEI; PCD = RM16(irq_vector); } // opcodes void MC6800::insn(uint8_t code) { switch(code) { case 0x00: illegal(); break; case 0x01: nop(); break; case 0x02: illegal(); break; case 0x03: illegal(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0x04: lsrd(); break; case 0x05: asld(); break; #else case 0x04: illegal(); break; case 0x05: illegal(); break; #endif case 0x06: tap(); break; case 0x07: tpa(); break; case 0x08: inx(); break; case 0x09: dex(); break; case 0x0a: clv(); break; case 0x0b: sev(); break; case 0x0c: clc(); break; case 0x0d: sec(); break; case 0x0e: cli(); break; case 0x0f: sei(); break; case 0x10: sba(); break; case 0x11: cba(); break; #if defined(HAS_HD6301) case 0x12: undoc1(); break; case 0x13: undoc2(); break; #else case 0x12: illegal(); break; case 0x13: illegal(); break; #endif case 0x14: illegal(); break; case 0x15: illegal(); break; case 0x16: tab(); break; case 0x17: tba(); break; #if defined(HAS_HD6301) case 0x18: xgdx(); break; #else case 0x18: illegal(); break; #endif case 0x19: daa(); break; #if defined(HAS_HD6301) case 0x1a: slp(); break; #else case 0x1a: illegal(); break; #endif case 0x1b: aba(); break; case 0x1c: illegal(); break; case 0x1d: illegal(); break; case 0x1e: illegal(); break; case 0x1f: illegal(); break; case 0x20: bra(); break; case 0x21: brn(); break; case 0x22: bhi(); break; case 0x23: bls(); break; case 0x24: bcc(); break; case 0x25: bcs(); break; case 0x26: bne(); break; case 0x27: beq(); break; case 0x28: bvc(); break; case 0x29: bvs(); break; case 0x2a: bpl(); break; case 0x2b: bmi(); break; case 0x2c: bge(); break; case 0x2d: blt(); break; case 0x2e: bgt(); break; case 0x2f: ble(); break; case 0x30: tsx(); break; case 0x31: ins(); break; case 0x32: pula(); break; case 0x33: pulb(); break; case 0x34: des(); break; case 0x35: txs(); break; case 0x36: psha(); break; case 0x37: pshb(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0x38: pulx(); break; #else case 0x38: illegal(); break; #endif case 0x39: rts(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0x3a: abx(); break; #else case 0x3a: illegal(); break; #endif case 0x3b: rti(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0x3c: pshx(); break; case 0x3d: mul(); break; #else case 0x3c: illegal(); break; case 0x3d: illegal(); break; #endif case 0x3e: wai(); break; case 0x3f: swi(); break; case 0x40: nega(); break; case 0x41: illegal(); break; case 0x42: illegal(); break; case 0x43: coma(); break; case 0x44: lsra(); break; case 0x45: illegal(); break; case 0x46: rora(); break; case 0x47: asra(); break; case 0x48: asla(); break; case 0x49: rola(); break; case 0x4a: deca(); break; case 0x4b: illegal(); break; case 0x4c: inca(); break; case 0x4d: tsta(); break; case 0x4e: illegal(); break; case 0x4f: clra(); break; case 0x50: negb(); break; case 0x51: illegal(); break; case 0x52: illegal(); break; case 0x53: comb(); break; case 0x54: lsrb(); break; case 0x55: illegal(); break; case 0x56: rorb(); break; case 0x57: asrb(); break; case 0x58: aslb(); break; case 0x59: rolb(); break; case 0x5a: decb(); break; case 0x5b: illegal(); break; case 0x5c: incb(); break; case 0x5d: tstb(); break; case 0x5e: illegal(); break; case 0x5f: clrb(); break; case 0x60: neg_ix(); break; #if defined(HAS_HD6301) case 0x61: aim_ix(); break; case 0x62: oim_ix(); break; #else case 0x61: illegal(); break; case 0x62: illegal(); break; #endif case 0x63: com_ix(); break; case 0x64: lsr_ix(); break; #if defined(HAS_HD6301) case 0x65: eim_ix(); break; #else case 0x65: illegal(); break; #endif case 0x66: ror_ix(); break; case 0x67: asr_ix(); break; case 0x68: asl_ix(); break; case 0x69: rol_ix(); break; case 0x6a: dec_ix(); break; #if defined(HAS_HD6301) case 0x6b: tim_ix(); break; #else case 0x6b: illegal(); break; #endif case 0x6c: inc_ix(); break; case 0x6d: tst_ix(); break; case 0x6e: jmp_ix(); break; case 0x6f: clr_ix(); break; case 0x70: neg_ex(); break; #if defined(HAS_HD6301) case 0x71: aim_di(); break; case 0x72: oim_di(); break; #elif defined(HAS_MB8861) case 0x71: nim_ix(); break; case 0x72: oim_ix_mb8861(); break; #else case 0x71: illegal(); break; case 0x72: illegal(); break; #endif case 0x73: com_ex(); break; case 0x74: lsr_ex(); break; #if defined(HAS_HD6301) case 0x75: eim_di(); break; #elif defined(HAS_MB8861) case 0x75: xim_ix(); break; #else case 0x75: illegal(); break; #endif case 0x76: ror_ex(); break; case 0x77: asr_ex(); break; case 0x78: asl_ex(); break; case 0x79: rol_ex(); break; case 0x7a: dec_ex(); break; #if defined(HAS_HD6301) case 0x7b: tim_di(); break; #elif defined(HAS_MB8861) case 0x7b: tmm_ix(); break; #else case 0x7b: illegal(); break; #endif case 0x7c: inc_ex(); break; case 0x7d: tst_ex(); break; case 0x7e: jmp_ex(); break; case 0x7f: clr_ex(); break; case 0x80: suba_im(); break; case 0x81: cmpa_im(); break; case 0x82: sbca_im(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0x83: subd_im(); break; #else case 0x83: illegal(); break; #endif case 0x84: anda_im(); break; case 0x85: bita_im(); break; case 0x86: lda_im(); break; case 0x87: sta_im(); break; case 0x88: eora_im(); break; case 0x89: adca_im(); break; case 0x8a: ora_im(); break; case 0x8b: adda_im(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0x8c: cpx_im (); break; #else case 0x8c: cmpx_im(); break; #endif case 0x8d: bsr(); break; case 0x8e: lds_im(); break; case 0x8f: sts_im(); break; case 0x90: suba_di(); break; case 0x91: cmpa_di(); break; case 0x92: sbca_di(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0x93: subd_di(); break; #else case 0x93: illegal(); break; #endif case 0x94: anda_di(); break; case 0x95: bita_di(); break; case 0x96: lda_di(); break; case 0x97: sta_di(); break; case 0x98: eora_di(); break; case 0x99: adca_di(); break; case 0x9a: ora_di(); break; case 0x9b: adda_di(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0x9c: cpx_di (); break; #else case 0x9c: cmpx_di(); break; #endif case 0x9d: jsr_di(); break; case 0x9e: lds_di(); break; case 0x9f: sts_di(); break; case 0xa0: suba_ix(); break; case 0xa1: cmpa_ix(); break; case 0xa2: sbca_ix(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xa3: subd_ix(); break; #else case 0xa3: illegal(); break; #endif case 0xa4: anda_ix(); break; case 0xa5: bita_ix(); break; case 0xa6: lda_ix(); break; case 0xa7: sta_ix(); break; case 0xa8: eora_ix(); break; case 0xa9: adca_ix(); break; case 0xaa: ora_ix(); break; case 0xab: adda_ix(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xac: cpx_ix (); break; #else case 0xac: cmpx_ix(); break; #endif case 0xad: jsr_ix(); break; case 0xae: lds_ix(); break; case 0xaf: sts_ix(); break; case 0xb0: suba_ex(); break; case 0xb1: cmpa_ex(); break; case 0xb2: sbca_ex(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xb3: subd_ex(); break; #else case 0xb3: illegal(); break; #endif case 0xb4: anda_ex(); break; case 0xb5: bita_ex(); break; case 0xb6: lda_ex(); break; case 0xb7: sta_ex(); break; case 0xb8: eora_ex(); break; case 0xb9: adca_ex(); break; case 0xba: ora_ex(); break; case 0xbb: adda_ex(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xbc: cpx_ex (); break; #else case 0xbc: cmpx_ex(); break; #endif case 0xbd: jsr_ex(); break; case 0xbe: lds_ex(); break; case 0xbf: sts_ex(); break; case 0xc0: subb_im(); break; case 0xc1: cmpb_im(); break; case 0xc2: sbcb_im(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xc3: addd_im(); break; #else case 0xc3: illegal(); break; #endif case 0xc4: andb_im(); break; case 0xc5: bitb_im(); break; case 0xc6: ldb_im(); break; case 0xc7: stb_im(); break; case 0xc8: eorb_im(); break; case 0xc9: adcb_im(); break; case 0xca: orb_im(); break; case 0xcb: addb_im(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xcc: ldd_im(); break; case 0xcd: std_im(); break; #else case 0xcc: illegal(); break; case 0xcd: illegal(); break; #endif case 0xce: ldx_im(); break; case 0xcf: stx_im(); break; case 0xd0: subb_di(); break; case 0xd1: cmpb_di(); break; case 0xd2: sbcb_di(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xd3: addd_di(); break; #else case 0xd3: illegal(); break; #endif case 0xd4: andb_di(); break; case 0xd5: bitb_di(); break; case 0xd6: ldb_di(); break; case 0xd7: stb_di(); break; case 0xd8: eorb_di(); break; case 0xd9: adcb_di(); break; case 0xda: orb_di(); break; case 0xdb: addb_di(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xdc: ldd_di(); break; case 0xdd: std_di(); break; #else case 0xdc: illegal(); break; case 0xdd: illegal(); break; #endif case 0xde: ldx_di(); break; case 0xdf: stx_di(); break; case 0xe0: subb_ix(); break; case 0xe1: cmpb_ix(); break; case 0xe2: sbcb_ix(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xe3: addd_ix(); break; #else case 0xe3: illegal(); break; #endif case 0xe4: andb_ix(); break; case 0xe5: bitb_ix(); break; case 0xe6: ldb_ix(); break; case 0xe7: stb_ix(); break; case 0xe8: eorb_ix(); break; case 0xe9: adcb_ix(); break; case 0xea: orb_ix(); break; case 0xeb: addb_ix(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xec: ldd_ix(); break; case 0xed: std_ix(); break; #elif defined(HAS_MB8861) case 0xec: adx_im(); break; case 0xed: illegal(); break; #else case 0xec: illegal(); break; case 0xed: illegal(); break; #endif case 0xee: ldx_ix(); break; case 0xef: stx_ix(); break; case 0xf0: subb_ex(); break; case 0xf1: cmpb_ex(); break; case 0xf2: sbcb_ex(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xf3: addd_ex(); break; #else case 0xf3: illegal(); break; #endif case 0xf4: andb_ex(); break; case 0xf5: bitb_ex(); break; case 0xf6: ldb_ex(); break; case 0xf7: stb_ex(); break; case 0xf8: eorb_ex(); break; case 0xf9: adcb_ex(); break; case 0xfa: orb_ex(); break; case 0xfb: addb_ex(); break; #if defined(HAS_MC6801) || defined(HAS_HD6301) case 0xfc: ldd_ex(); break; case 0xfd: std_ex(); break; #elif defined(HAS_MB8861) case 0xfc: adx_ex(); break; case 0xfd: illegal(); break; #else case 0xfc: illegal(); break; case 0xfd: illegal(); break; #endif case 0xfe: ldx_ex(); break; case 0xff: stx_ex(); break; #if defined(_MSC_VER) && (_MSC_VER >= 1200) default: __assume(0); #endif } } /* operate one instruction for */ #define ONE_MORE_INSN() { \ uint8_t ireg = M_RDOP(PCD); \ prevpc = PC; \ PC++; \ insn(ireg); \ increment_counter(cycles[ireg]); \ } /* $00 ILLEGAL */ void MC6800::illegal() { #ifdef HAS_HD6301 TAKE_TRAP; #endif } /* $01 NOP */ void MC6800::nop() { } /* $02 ILLEGAL */ /* $03 ILLEGAL */ /* $04 LSRD inherent -0*-* */ void MC6800::lsrd() { uint16_t t; CLR_NZC; t = D; CC |= (t & 0x0001); t >>= 1; SET_Z16(t); D = t; } /* $05 ASLD inherent ?**** */ void MC6800::asld() { int r; uint16_t t; t = D; r = t << 1; CLR_NZVC; SET_FLAGS16(t, t, r); D = r; } /* $06 TAP inherent ##### */ void MC6800::tap() { CC = A; // ONE_MORE_INSN(); one_more_insn = true; } /* $07 TPA inherent ----- */ void MC6800::tpa() { A = CC; } /* $08 INX inherent --*-- */ void MC6800::inx() { ++X; CLR_Z; SET_Z16(X); } /* $09 DEX inherent --*-- */ void MC6800::dex() { --X; CLR_Z; SET_Z16(X); } /* $0a CLV */ void MC6800::clv() { CLV; } /* $0b SEV */ void MC6800::sev() { SEV; } /* $0c CLC */ void MC6800::clc() { CLC; } /* $0d SEC */ void MC6800::sec() { SEC; } /* $0e CLI */ void MC6800::cli() { CLI; // ONE_MORE_INSN(); one_more_insn = true; } /* $0f SEI */ void MC6800::sei() { SEI; // ONE_MORE_INSN(); one_more_insn = true; } /* $10 SBA inherent -**** */ void MC6800::sba() { uint16_t t; t = A - B; CLR_NZVC; SET_FLAGS8(A, B, t); A = (uint8_t)t; } /* $11 CBA inherent -**** */ void MC6800::cba() { uint16_t t; t = A - B; CLR_NZVC; SET_FLAGS8(A, B, t); } /* $12 ILLEGAL */ void MC6800::undoc1() { X += RM(S + 1); } /* $13 ILLEGAL */ void MC6800::undoc2() { X += RM(S + 1); } /* $14 ILLEGAL */ /* $15 ILLEGAL */ /* $16 TAB inherent -**0- */ void MC6800::tab() { B=A; CLR_NZV; SET_NZ8(B); } /* $17 TBA inherent -**0- */ void MC6800::tba() { A = B; CLR_NZV; SET_NZ8(A); } /* $18 XGDX inherent ----- */ /* HD6301 only */ void MC6800::xgdx() { uint16_t t = X; X = D; D = t; } /* $19 DAA inherent (A) -**0* */ void MC6800::daa() { uint8_t msn, lsn; uint16_t t, cf = 0; msn = A & 0xf0; lsn = A & 0x0f; if(lsn > 0x09 || CC & 0x20) { cf |= 0x06; } if(msn > 0x80 && lsn > 0x09) { cf |= 0x60; } if(msn > 0x90 || (CC & 0x01)) { cf |= 0x60; } t = cf + A; CLR_NZV; /* keep carry from previous operation */ SET_NZ8((uint8_t)t); SET_C8(t); A = (uint8_t)t; } /* $1a ILLEGAL */ /* $1a SLP */ /* HD6301 only */ void MC6800::slp() { /* wait for next IRQ (same as waiting of wai) */ wai_state |= HD6301_SLP; } /* $1b ABA inherent ***** */ void MC6800::aba() { uint16_t t; t = A + B; CLR_HNZVC; SET_FLAGS8(A, B, t); SET_H(A, B, t); A = (uint8_t)t; } /* $1c ILLEGAL */ /* $1d ILLEGAL */ /* $1e ILLEGAL */ /* $1f ILLEGAL */ /* $20 BRA relative ----- */ void MC6800::bra() { uint8_t t; IMMBYTE(t); PC += SIGNED(t); } /* $21 BRN relative ----- */ void MC6800::brn() { uint8_t t; IMMBYTE(t); } /* $22 BHI relative ----- */ void MC6800::bhi() { uint8_t t; BRANCH(!(CC & 0x05)); } /* $23 BLS relative ----- */ void MC6800::bls() { uint8_t t; BRANCH(CC & 0x05); } /* $24 BCC relative ----- */ void MC6800::bcc() { uint8_t t; BRANCH(!(CC & 0x01)); } /* $25 BCS relative ----- */ void MC6800::bcs() { uint8_t t; BRANCH(CC & 0x01); } /* $26 BNE relative ----- */ void MC6800::bne() { uint8_t t; BRANCH(!(CC & 0x04)); } /* $27 BEQ relative ----- */ void MC6800::beq() { uint8_t t; BRANCH(CC & 0x04); } /* $28 BVC relative ----- */ void MC6800::bvc() { uint8_t t; BRANCH(!(CC & 0x02)); } /* $29 BVS relative ----- */ void MC6800::bvs() { uint8_t t; BRANCH(CC & 0x02); } /* $2a BPL relative ----- */ void MC6800::bpl() { uint8_t t; BRANCH(!(CC & 0x08)); } /* $2b BMI relative ----- */ void MC6800::bmi() { uint8_t t; BRANCH(CC & 0x08); } /* $2c BGE relative ----- */ void MC6800::bge() { uint8_t t; BRANCH(!NXORV); } /* $2d BLT relative ----- */ void MC6800::blt() { uint8_t t; BRANCH(NXORV); } /* $2e BGT relative ----- */ void MC6800::bgt() { uint8_t t; BRANCH(!(NXORV||CC & 0x04)); } /* $2f BLE relative ----- */ void MC6800::ble() { uint8_t t; BRANCH(NXORV||CC & 0x04); } /* $30 TSX inherent ----- */ void MC6800::tsx() { X = (S + 1); } /* $31 INS inherent ----- */ void MC6800::ins() { ++S; } /* $32 PULA inherent ----- */ void MC6800::pula() { PULLBYTE(A); } /* $33 PULB inherent ----- */ void MC6800::pulb() { PULLBYTE(B); } /* $34 DES inherent ----- */ void MC6800::des() { --S; } /* $35 TXS inherent ----- */ void MC6800::txs() { S = (X - 1); } /* $36 PSHA inherent ----- */ void MC6800::psha() { PUSHBYTE(A); } /* $37 PSHB inherent ----- */ void MC6800::pshb() { PUSHBYTE(B); } /* $38 PULX inherent ----- */ void MC6800::pulx() { PULLWORD(pX); } /* $39 RTS inherent ----- */ void MC6800::rts() { PULLWORD(pPC); } /* $3a ABX inherent ----- */ void MC6800::abx() { X += B; } /* $3b RTI inherent ##### */ void MC6800::rti() { PULLBYTE(CC); PULLBYTE(B); PULLBYTE(A); PULLWORD(pX); PULLWORD(pPC); } /* $3c PSHX inherent ----- */ void MC6800::pshx() { PUSHWORD(pX); } /* $3d MUL inherent --*-@ */ void MC6800::mul() { uint16_t t; t = A*B; CLR_C; if(t & 0x80) SEC; D = t; } /* $3e WAI inherent ----- */ void MC6800::wai() { /* * WAI stacks the entire machine state on the * hardware stack, then waits for an interrupt. */ wai_state |= MC6800_WAI; PUSHWORD(pPC); PUSHWORD(pX); PUSHBYTE(A); PUSHBYTE(B); PUSHBYTE(CC); } /* $3f SWI absolute indirect ----- */ void MC6800::swi() { PUSHWORD(pPC); PUSHWORD(pX); PUSHBYTE(A); PUSHBYTE(B); PUSHBYTE(CC); SEI; PCD = RM16(0xfffa); } /* $40 NEGA inherent ?**** */ void MC6800::nega() { uint16_t r; r = -A; CLR_NZVC; SET_FLAGS8(0, A, r); A = (uint8_t)r; } /* $41 ILLEGAL */ /* $42 ILLEGAL */ /* $43 COMA inherent -**01 */ void MC6800::coma() { A = ~A; CLR_NZV; SET_NZ8(A); SEC; } /* $44 LSRA inherent -0*-* */ void MC6800::lsra() { CLR_NZC; CC |= (A & 0x01); A >>= 1; SET_Z8(A); } /* $45 ILLEGAL */ /* $46 RORA inherent -**-* */ void MC6800::rora() { uint8_t r; r = (CC & 0x01) << 7; CLR_NZC; CC |= (A & 0x01); r |= A >> 1; SET_NZ8(r); A = r; } /* $47 ASRA inherent ?**-* */ void MC6800::asra() { CLR_NZC; CC |= (A & 0x01); A >>= 1; A |= ((A & 0x40) << 1); SET_NZ8(A); } /* $48 ASLA inherent ?**** */ void MC6800::asla() { uint16_t r; r = A << 1; CLR_NZVC; SET_FLAGS8(A, A, r); A = (uint8_t)r; } /* $49 ROLA inherent -**** */ void MC6800::rola() { uint16_t t, r; t = A; r = CC & 0x01; r |= t << 1; CLR_NZVC; SET_FLAGS8(t, t, r); A = (uint8_t)r; } /* $4a DECA inherent -***- */ void MC6800::deca() { --A; CLR_NZV; SET_FLAGS8D(A); } /* $4b ILLEGAL */ /* $4c INCA inherent -***- */ void MC6800::inca() { ++A; CLR_NZV; SET_FLAGS8I(A); } /* $4d TSTA inherent -**0- */ void MC6800::tsta() { CLR_NZVC; SET_NZ8(A); } /* $4e ILLEGAL */ /* $4f CLRA inherent -0100 */ void MC6800::clra() { A = 0; CLR_NZVC; SEZ; } /* $50 NEGB inherent ?**** */ void MC6800::negb() { uint16_t r; r = -B; CLR_NZVC; SET_FLAGS8(0, B, r); B = (uint8_t)r; } /* $51 ILLEGAL */ /* $52 ILLEGAL */ /* $53 COMB inherent -**01 */ void MC6800::comb() { B = ~B; CLR_NZV; SET_NZ8(B); SEC; } /* $54 LSRB inherent -0*-* */ void MC6800::lsrb() { CLR_NZC; CC |= (B & 0x01); B >>= 1; SET_Z8(B); } /* $55 ILLEGAL */ /* $56 RORB inherent -**-* */ void MC6800::rorb() { uint8_t r; r = (CC & 0x01) << 7; CLR_NZC; CC |= (B & 0x01); r |= B >> 1; SET_NZ8(r); B = r; } /* $57 ASRB inherent ?**-* */ void MC6800::asrb() { CLR_NZC; CC |= (B & 0x01); B >>= 1; B |= ((B & 0x40) << 1); SET_NZ8(B); } /* $58 ASLB inherent ?**** */ void MC6800::aslb() { uint16_t r; r = B << 1; CLR_NZVC; SET_FLAGS8(B, B, r); B = (uint8_t)r; } /* $59 ROLB inherent -**** */ void MC6800::rolb() { uint16_t t, r; t = B; r = CC & 0x01; r |= t << 1; CLR_NZVC; SET_FLAGS8(t, t, r); B = (uint8_t)r; } /* $5a DECB inherent -***- */ void MC6800::decb() { --B; CLR_NZV; SET_FLAGS8D(B); } /* $5b ILLEGAL */ /* $5c INCB inherent -***- */ void MC6800::incb() { ++B; CLR_NZV; SET_FLAGS8I(B); } /* $5d TSTB inherent -**0- */ void MC6800::tstb() { CLR_NZVC; SET_NZ8(B); } /* $5e ILLEGAL */ /* $5f CLRB inherent -0100 */ void MC6800::clrb() { B=0; CLR_NZVC; SEZ; } /* $60 NEG indexed ?**** */ void MC6800::neg_ix() { uint16_t r, t; IDXBYTE(t); r = -t; CLR_NZVC; SET_FLAGS8(0, t, r); WM(EAD, r); } /* $61 AIM --**0- */ /* HD6301 only */ void MC6800::aim_ix() { uint8_t t, r; IMMBYTE(t); IDXBYTE(r); r &= t; CLR_NZV; SET_NZ8(r); WM(EAD, r); } /* $62 OIM --**0- */ /* HD6301 only */ void MC6800::oim_ix() { uint8_t t, r; IMMBYTE(t); IDXBYTE(r); r |= t; CLR_NZV; SET_NZ8(r); WM(EAD, r); } /* $63 COM indexed -**01 */ void MC6800::com_ix() { uint8_t t; IDXBYTE(t); t = ~t; CLR_NZV; SET_NZ8(t); SEC; WM(EAD, t); } /* $64 LSR indexed -0*-* */ void MC6800::lsr_ix() { uint8_t t; IDXBYTE(t); CLR_NZC; CC |= (t & 0x01); t >>= 1; SET_Z8(t); WM(EAD, t); } /* $65 EIM --**0- */ /* HD6301 only */ void MC6800::eim_ix() { uint8_t t, r; IMMBYTE(t); IDXBYTE(r); r ^= t; CLR_NZV; SET_NZ8(r); WM(EAD, r); } /* $66 ROR indexed -**-* */ void MC6800::ror_ix() { uint8_t t, r; IDXBYTE(t); r = (CC & 0x01) << 7; CLR_NZC; CC |= (t & 0x01); r |= t >> 1; SET_NZ8(r); WM(EAD, r); } /* $67 ASR indexed ?**-* */ void MC6800::asr_ix() { uint8_t t; IDXBYTE(t); CLR_NZC; CC |= (t & 0x01); t >>= 1; t |= ((t & 0x40) << 1); SET_NZ8(t); WM(EAD, t); } /* $68 ASL indexed ?**** */ void MC6800::asl_ix() { uint16_t t, r; IDXBYTE(t); r = t << 1; CLR_NZVC; SET_FLAGS8(t, t, r); WM(EAD, r); } /* $69 ROL indexed -**** */ void MC6800::rol_ix() { uint16_t t, r; IDXBYTE(t); r = CC & 0x01; r |= t << 1; CLR_NZVC; SET_FLAGS8(t, t, r); WM(EAD, r); } /* $6a DEC indexed -***- */ void MC6800::dec_ix() { uint8_t t; IDXBYTE(t); --t; CLR_NZV; SET_FLAGS8D(t); WM(EAD, t); } /* $6b TIM --**0- */ /* HD6301 only */ void MC6800::tim_ix() { uint8_t t, r; IMMBYTE(t); IDXBYTE(r); r &= t; CLR_NZV; SET_NZ8(r); } /* $6c INC indexed -***- */ void MC6800::inc_ix() { uint8_t t; IDXBYTE(t); ++t; CLR_NZV; SET_FLAGS8I(t); WM(EAD, t); } /* $6d TST indexed -**0- */ void MC6800::tst_ix() { uint8_t t; IDXBYTE(t); CLR_NZVC; SET_NZ8(t); } /* $6e JMP indexed ----- */ void MC6800::jmp_ix() { INDEXED; PC = EA; } /* $6f CLR indexed -0100 */ void MC6800::clr_ix() { INDEXED; WM(EAD, 0); CLR_NZVC; SEZ; } /* $70 NEG extended ?**** */ void MC6800::neg_ex() { uint16_t r, t; EXTBYTE(t); r = -t; CLR_NZVC; SET_FLAGS8(0, t, r); WM(EAD, r); } /* $71 AIM --**0- */ /* HD6301 only */ void MC6800::aim_di() { uint8_t t, r; IMMBYTE(t); DIRBYTE(r); r &= t; CLR_NZV; SET_NZ8(r); WM(EAD, r); } /* $71 NIM --**0- */ /* MB8861 only */ void MC6800::nim_ix() { uint8_t t, r; IMMBYTE(t); IDXBYTE(r); r &= t; CLR_NZV; if(!r) { SEZ; } else { SEN; } WM(EAD, r); } /* $72 OIM --**0- */ /* HD6301 only */ void MC6800::oim_di() { uint8_t t, r; IMMBYTE(t); DIRBYTE(r); r |= t; CLR_NZV; SET_NZ8(r); WM(EAD, r); } /* $72 OIM --**0- */ /* MB8861 only */ void MC6800::oim_ix_mb8861() { uint8_t t, r; IMMBYTE(t); IDXBYTE(r); r |= t; CLR_NZV; if(!r) { SEZ; } else { SEN; } WM(EAD, r); } /* $73 COM extended -**01 */ void MC6800::com_ex() { uint8_t t; EXTBYTE(t); t = ~t; CLR_NZV; SET_NZ8(t); SEC; WM(EAD, t); } /* $74 LSR extended -0*-* */ void MC6800::lsr_ex() { uint8_t t; EXTBYTE(t); CLR_NZC; CC |= (t & 0x01); t >>= 1; SET_Z8(t); WM(EAD, t); } /* $75 EIM --**0- */ /* HD6301 only */ void MC6800::eim_di() { uint8_t t, r; IMMBYTE(t); DIRBYTE(r); r ^= t; CLR_NZV; SET_NZ8(r); WM(EAD, r); } /* $75 XIM --**-- */ /* MB8861 only */ void MC6800::xim_ix() { uint8_t t, r; IMMBYTE(t); IDXBYTE(r); r ^= t; CLR_NZ; if(!r) { SEZ; } else { SEN; } WM(EAD, r); } /* $76 ROR extended -**-* */ void MC6800::ror_ex() { uint8_t t, r; EXTBYTE(t); r = (CC & 0x01) << 7; CLR_NZC; CC |= (t & 0x01); r |= t >> 1; SET_NZ8(r); WM(EAD, r); } /* $77 ASR extended ?**-* */ void MC6800::asr_ex() { uint8_t t; EXTBYTE(t); CLR_NZC; CC |= (t & 0x01); t >>= 1; t |= ((t & 0x40) << 1); SET_NZ8(t); WM(EAD, t); } /* $78 ASL extended ?**** */ void MC6800::asl_ex() { uint16_t t, r; EXTBYTE(t); r = t << 1; CLR_NZVC; SET_FLAGS8(t, t, r); WM(EAD, r); } /* $79 ROL extended -**** */ void MC6800::rol_ex() { uint16_t t, r; EXTBYTE(t); r = CC & 0x01; r |= t << 1; CLR_NZVC; SET_FLAGS8(t, t, r); WM(EAD, r); } /* $7a DEC extended -***- */ void MC6800::dec_ex() { uint8_t t; EXTBYTE(t); --t; CLR_NZV; SET_FLAGS8D(t); WM(EAD, t); } /* $7b TIM --**0- */ /* HD6301 only */ void MC6800::tim_di() { uint8_t t, r; IMMBYTE(t); DIRBYTE(r); r &= t; CLR_NZV; SET_NZ8(r); } /* $7b TMM --***- */ /* MB8861 only */ void MC6800::tmm_ix() { uint8_t t, r; IMMBYTE(t); IDXBYTE(r); r &= t; CLR_NZV; if(!t || !r) { SEZ; } else if(r == t) { SEV; } else { SEN; } } /* $7c INC extended -***- */ void MC6800::inc_ex() { uint8_t t; EXTBYTE(t); ++t; CLR_NZV; SET_FLAGS8I(t); WM(EAD, t); } /* $7d TST extended -**0- */ void MC6800::tst_ex() { uint8_t t; EXTBYTE(t); CLR_NZVC; SET_NZ8(t); } /* $7e JMP extended ----- */ void MC6800::jmp_ex() { EXTENDED; PC = EA; } /* $7f CLR extended -0100 */ void MC6800::clr_ex() { EXTENDED; WM(EAD, 0); CLR_NZVC; SEZ; } /* $80 SUBA immediate ?**** */ void MC6800::suba_im() { uint16_t t, r; IMMBYTE(t); r = A - t; CLR_NZVC; SET_FLAGS8(A, t, r); A = (uint8_t)r; } /* $81 CMPA immediate ?**** */ void MC6800::cmpa_im() { uint16_t t, r; IMMBYTE(t); r = A - t; CLR_NZVC; SET_FLAGS8(A, t, r); } /* $82 SBCA immediate ?**** */ void MC6800::sbca_im() { uint16_t t, r; IMMBYTE(t); r = A - t - (CC & 0x01); CLR_NZVC; SET_FLAGS8(A, t, r); A = (uint8_t)r; } /* $83 SUBD immediate -**** */ void MC6800::subd_im() { uint32_t r, d; pair32_t b; IMMWORD(b); d = D; r = d - b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); D = r; } /* $84 ANDA immediate -**0- */ void MC6800::anda_im() { uint8_t t; IMMBYTE(t); A &= t; CLR_NZV; SET_NZ8(A); } /* $85 BITA immediate -**0- */ void MC6800::bita_im() { uint8_t t, r; IMMBYTE(t); r = A & t; CLR_NZV; SET_NZ8(r); } /* $86 LDA immediate -**0- */ void MC6800::lda_im() { IMMBYTE(A); CLR_NZV; SET_NZ8(A); } /* is this a legal instruction? */ /* $87 STA immediate -**0- */ void MC6800::sta_im() { CLR_NZV; SET_NZ8(A); IMM8; WM(EAD, A); } /* $88 EORA immediate -**0- */ void MC6800::eora_im() { uint8_t t; IMMBYTE(t); A ^= t; CLR_NZV; SET_NZ8(A); } /* $89 ADCA immediate ***** */ void MC6800::adca_im() { uint16_t t, r; IMMBYTE(t); r = A + t + (CC & 0x01); CLR_HNZVC; SET_FLAGS8(A, t, r); SET_H(A, t, r); A = (uint8_t)r; } /* $8a ORA immediate -**0- */ void MC6800::ora_im() { uint8_t t; IMMBYTE(t); A |= t; CLR_NZV; SET_NZ8(A); } /* $8b ADDA immediate ***** */ void MC6800::adda_im() { uint16_t t, r; IMMBYTE(t); r = A + t; CLR_HNZVC; SET_FLAGS8(A, t, r); SET_H(A, t, r); A = (uint8_t)r; } /* $8c CMPX immediate -***- */ void MC6800::cmpx_im() { uint32_t r, d; pair32_t b; IMMWORD(b); d = X; r = d - b.d; CLR_NZV; SET_NZ16(r); SET_V16(d, b.d, r); } /* $8c CPX immediate -**** (6801) */ void MC6800::cpx_im() { uint32_t r, d; pair32_t b; IMMWORD(b); d = X; r = d - b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); } /* $8d BSR ----- */ void MC6800::bsr() { uint8_t t; IMMBYTE(t); PUSHWORD(pPC); PC += SIGNED(t); } /* $8e LDS immediate -**0- */ void MC6800::lds_im() { IMMWORD(pS); CLR_NZV; SET_NZ16(S); } /* $8f STS immediate -**0- */ void MC6800::sts_im() { CLR_NZV; SET_NZ16(S); IMM16; WM16(EAD, &pS); } /* $90 SUBA direct ?**** */ void MC6800::suba_di() { uint16_t t, r; DIRBYTE(t); r = A - t; CLR_NZVC; SET_FLAGS8(A, t, r); A = (uint8_t)r; } /* $91 CMPA direct ?**** */ void MC6800::cmpa_di() { uint16_t t, r; DIRBYTE(t); r = A - t; CLR_NZVC; SET_FLAGS8(A, t, r); } /* $92 SBCA direct ?**** */ void MC6800::sbca_di() { uint16_t t, r; DIRBYTE(t); r = A - t - (CC & 0x01); CLR_NZVC; SET_FLAGS8(A, t, r); A = (uint8_t)r; } /* $93 SUBD direct -**** */ void MC6800::subd_di() { uint32_t r, d; pair32_t b; DIRWORD(b); d = D; r = d - b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); D = r; } /* $94 ANDA direct -**0- */ void MC6800::anda_di() { uint8_t t; DIRBYTE(t); A &= t; CLR_NZV; SET_NZ8(A); } /* $95 BITA direct -**0- */ void MC6800::bita_di() { uint8_t t, r; DIRBYTE(t); r = A & t; CLR_NZV; SET_NZ8(r); } /* $96 LDA direct -**0- */ void MC6800::lda_di() { DIRBYTE(A); CLR_NZV; SET_NZ8(A); } /* $97 STA direct -**0- */ void MC6800::sta_di() { CLR_NZV; SET_NZ8(A); DIRECT; WM(EAD, A); } /* $98 EORA direct -**0- */ void MC6800::eora_di() { uint8_t t; DIRBYTE(t); A ^= t; CLR_NZV; SET_NZ8(A); } /* $99 ADCA direct ***** */ void MC6800::adca_di() { uint16_t t, r; DIRBYTE(t); r = A + t + (CC & 0x01); CLR_HNZVC; SET_FLAGS8(A, t, r); SET_H(A, t, r); A = (uint8_t)r; } /* $9a ORA direct -**0- */ void MC6800::ora_di() { uint8_t t; DIRBYTE(t); A |= t; CLR_NZV; SET_NZ8(A); } /* $9b ADDA direct ***** */ void MC6800::adda_di() { uint16_t t, r; DIRBYTE(t); r = A + t; CLR_HNZVC; SET_FLAGS8(A, t, r); SET_H(A, t, r); A = (uint8_t)r; } /* $9c CMPX direct -***- */ void MC6800::cmpx_di() { uint32_t r, d; pair32_t b; DIRWORD(b); d = X; r = d - b.d; CLR_NZV; SET_NZ16(r); SET_V16(d, b.d, r); } /* $9c CPX direct -**** (6801) */ void MC6800::cpx_di() { uint32_t r, d; pair32_t b; DIRWORD(b); d = X; r = d - b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); } /* $9d JSR direct ----- */ void MC6800::jsr_di() { DIRECT; PUSHWORD(pPC); PC = EA; } /* $9e LDS direct -**0- */ void MC6800::lds_di() { DIRWORD(pS); CLR_NZV; SET_NZ16(S); } /* $9f STS direct -**0- */ void MC6800::sts_di() { CLR_NZV; SET_NZ16(S); DIRECT; WM16(EAD, &pS); } /* $a0 SUBA indexed ?**** */ void MC6800::suba_ix() { uint16_t t, r; IDXBYTE(t); r = A - t; CLR_NZVC; SET_FLAGS8(A, t, r); A = (uint8_t)r; } /* $a1 CMPA indexed ?**** */ void MC6800::cmpa_ix() { uint16_t t, r; IDXBYTE(t); r = A - t; CLR_NZVC; SET_FLAGS8(A, t, r); } /* $a2 SBCA indexed ?**** */ void MC6800::sbca_ix() { uint16_t t, r; IDXBYTE(t); r = A - t - (CC & 0x01); CLR_NZVC; SET_FLAGS8(A, t, r); A = (uint8_t)r; } /* $a3 SUBD indexed -**** */ void MC6800::subd_ix() { uint32_t r, d; pair32_t b; IDXWORD(b); d = D; r = d - b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); D = r; } /* $a4 ANDA indexed -**0- */ void MC6800::anda_ix() { uint8_t t; IDXBYTE(t); A &= t; CLR_NZV; SET_NZ8(A); } /* $a5 BITA indexed -**0- */ void MC6800::bita_ix() { uint8_t t, r; IDXBYTE(t); r = A & t; CLR_NZV; SET_NZ8(r); } /* $a6 LDA indexed -**0- */ void MC6800::lda_ix() { IDXBYTE(A); CLR_NZV; SET_NZ8(A); } /* $a7 STA indexed -**0- */ void MC6800::sta_ix() { CLR_NZV; SET_NZ8(A); INDEXED; WM(EAD, A); } /* $a8 EORA indexed -**0- */ void MC6800::eora_ix() { uint8_t t; IDXBYTE(t); A ^= t; CLR_NZV; SET_NZ8(A); } /* $a9 ADCA indexed ***** */ void MC6800::adca_ix() { uint16_t t, r; IDXBYTE(t); r = A + t + (CC & 0x01); CLR_HNZVC; SET_FLAGS8(A, t, r); SET_H(A, t, r); A = (uint8_t)r; } /* $aa ORA indexed -**0- */ void MC6800::ora_ix() { uint8_t t; IDXBYTE(t); A |= t; CLR_NZV; SET_NZ8(A); } /* $ab ADDA indexed ***** */ void MC6800::adda_ix() { uint16_t t, r; IDXBYTE(t); r = A + t; CLR_HNZVC; SET_FLAGS8(A, t, r); SET_H(A, t, r); A = (uint8_t)r; } /* $ac CMPX indexed -***- */ void MC6800::cmpx_ix() { uint32_t r, d; pair32_t b; IDXWORD(b); d = X; r = d - b.d; CLR_NZV; SET_NZ16(r); SET_V16(d, b.d, r); } /* $ac CPX indexed -**** (6801)*/ void MC6800::cpx_ix() { uint32_t r, d; pair32_t b; IDXWORD(b); d = X; r = d - b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); } /* $ad JSR indexed ----- */ void MC6800::jsr_ix() { INDEXED; PUSHWORD(pPC); PC = EA; } /* $ae LDS indexed -**0- */ void MC6800::lds_ix() { IDXWORD(pS); CLR_NZV; SET_NZ16(S); } /* $af STS indexed -**0- */ void MC6800::sts_ix() { CLR_NZV; SET_NZ16(S); INDEXED; WM16(EAD, &pS); } /* $b0 SUBA extended ?**** */ void MC6800::suba_ex() { uint16_t t, r; EXTBYTE(t); r = A - t; CLR_NZVC; SET_FLAGS8(A, t, r); A = (uint8_t)r; } /* $b1 CMPA extended ?**** */ void MC6800::cmpa_ex() { uint16_t t, r; EXTBYTE(t); r = A - t; CLR_NZVC; SET_FLAGS8(A, t, r); } /* $b2 SBCA extended ?**** */ void MC6800::sbca_ex() { uint16_t t, r; EXTBYTE(t); r = A - t - (CC & 0x01); CLR_NZVC; SET_FLAGS8(A, t, r); A = (uint8_t)r; } /* $b3 SUBD extended -**** */ void MC6800::subd_ex() { uint32_t r, d; pair32_t b; EXTWORD(b); d = D; r = d - b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); D = r; } /* $b4 ANDA extended -**0- */ void MC6800::anda_ex() { uint8_t t; EXTBYTE(t); A &= t; CLR_NZV; SET_NZ8(A); } /* $b5 BITA extended -**0- */ void MC6800::bita_ex() { uint8_t t, r; EXTBYTE(t); r = A & t; CLR_NZV; SET_NZ8(r); } /* $b6 LDA extended -**0- */ void MC6800::lda_ex() { EXTBYTE(A); CLR_NZV; SET_NZ8(A); } /* $b7 STA extended -**0- */ void MC6800::sta_ex() { CLR_NZV; SET_NZ8(A); EXTENDED; WM(EAD, A); } /* $b8 EORA extended -**0- */ void MC6800::eora_ex() { uint8_t t; EXTBYTE(t); A ^= t; CLR_NZV; SET_NZ8(A); } /* $b9 ADCA extended ***** */ void MC6800::adca_ex() { uint16_t t, r; EXTBYTE(t); r = A + t + (CC & 0x01); CLR_HNZVC; SET_FLAGS8(A, t, r); SET_H(A, t, r); A = (uint8_t)r; } /* $ba ORA extended -**0- */ void MC6800::ora_ex() { uint8_t t; EXTBYTE(t); A |= t; CLR_NZV; SET_NZ8(A); } /* $bb ADDA extended ***** */ void MC6800::adda_ex() { uint16_t t, r; EXTBYTE(t); r = A + t; CLR_HNZVC; SET_FLAGS8(A, t, r); SET_H(A, t, r); A = (uint8_t)r; } /* $bc CMPX extended -***- */ void MC6800::cmpx_ex() { uint32_t r, d; pair32_t b; EXTWORD(b); d = X; r = d - b.d; CLR_NZV; SET_NZ16(r); SET_V16(d, b.d, r); } /* $bc CPX extended -**** (6801) */ void MC6800::cpx_ex() { uint32_t r, d; pair32_t b; EXTWORD(b); d = X; r = d - b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); } /* $bd JSR extended ----- */ void MC6800::jsr_ex() { EXTENDED; PUSHWORD(pPC); PC = EA; } /* $be LDS extended -**0- */ void MC6800::lds_ex() { EXTWORD(pS); CLR_NZV; SET_NZ16(S); } /* $bf STS extended -**0- */ void MC6800::sts_ex() { CLR_NZV; SET_NZ16(S); EXTENDED; WM16(EAD, &pS); } /* $c0 SUBB immediate ?**** */ void MC6800::subb_im() { uint16_t t, r; IMMBYTE(t); r = B - t; CLR_NZVC; SET_FLAGS8(B, t, r); B = (uint8_t)r; } /* $c1 CMPB immediate ?**** */ void MC6800::cmpb_im() { uint16_t t, r; IMMBYTE(t); r = B - t; CLR_NZVC; SET_FLAGS8(B, t, r); } /* $c2 SBCB immediate ?**** */ void MC6800::sbcb_im() { uint16_t t, r; IMMBYTE(t); r = B - t - (CC & 0x01); CLR_NZVC; SET_FLAGS8(B, t, r); B = (uint8_t)r; } /* $c3 ADDD immediate -**** */ void MC6800::addd_im() { uint32_t r, d; pair32_t b; IMMWORD(b); d = D; r = d + b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); D = r; } /* $c4 ANDB immediate -**0- */ void MC6800::andb_im() { uint8_t t; IMMBYTE(t); B &= t; CLR_NZV; SET_NZ8(B); } /* $c5 BITB immediate -**0- */ void MC6800::bitb_im() { uint8_t t, r; IMMBYTE(t); r = B & t; CLR_NZV; SET_NZ8(r); } /* $c6 LDB immediate -**0- */ void MC6800::ldb_im() { IMMBYTE(B); CLR_NZV; SET_NZ8(B); } /* is this a legal instruction? */ /* $c7 STB immediate -**0- */ void MC6800::stb_im() { CLR_NZV; SET_NZ8(B); IMM8; WM(EAD, B); } /* $c8 EORB immediate -**0- */ void MC6800::eorb_im() { uint8_t t; IMMBYTE(t); B ^= t; CLR_NZV; SET_NZ8(B); } /* $c9 ADCB immediate ***** */ void MC6800::adcb_im() { uint16_t t, r; IMMBYTE(t); r = B + t + (CC & 0x01); CLR_HNZVC; SET_FLAGS8(B, t, r); SET_H(B, t, r); B = (uint8_t)r; } /* $ca ORB immediate -**0- */ void MC6800::orb_im() { uint8_t t; IMMBYTE(t); B |= t; CLR_NZV; SET_NZ8(B); } /* $cb ADDB immediate ***** */ void MC6800::addb_im() { uint16_t t, r; IMMBYTE(t); r = B + t; CLR_HNZVC; SET_FLAGS8(B, t, r); SET_H(B, t, r); B = (uint8_t)r; } /* $CC LDD immediate -**0- */ void MC6800::ldd_im() { IMMWORD(pD); CLR_NZV; SET_NZ16(D); } /* is this a legal instruction? */ /* $cd STD immediate -**0- */ void MC6800::std_im() { IMM16; CLR_NZV; SET_NZ16(D); WM16(EAD, &pD); } /* $ce LDX immediate -**0- */ void MC6800::ldx_im() { IMMWORD(pX); CLR_NZV; SET_NZ16(X); } /* $cf STX immediate -**0- */ void MC6800::stx_im() { CLR_NZV; SET_NZ16(X); IMM16; WM16(EAD, &pX); } /* $d0 SUBB direct ?**** */ void MC6800::subb_di() { uint16_t t, r; DIRBYTE(t); r = B - t; CLR_NZVC; SET_FLAGS8(B, t, r); B = (uint8_t)r; } /* $d1 CMPB direct ?**** */ void MC6800::cmpb_di() { uint16_t t, r; DIRBYTE(t); r = B - t; CLR_NZVC; SET_FLAGS8(B, t, r); } /* $d2 SBCB direct ?**** */ void MC6800::sbcb_di() { uint16_t t, r; DIRBYTE(t); r = B - t - (CC & 0x01); CLR_NZVC; SET_FLAGS8(B, t, r); B = (uint8_t)r; } /* $d3 ADDD direct -**** */ void MC6800::addd_di() { uint32_t r, d; pair32_t b; DIRWORD(b); d = D; r = d + b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); D = r; } /* $d4 ANDB direct -**0- */ void MC6800::andb_di() { uint8_t t; DIRBYTE(t); B &= t; CLR_NZV; SET_NZ8(B); } /* $d5 BITB direct -**0- */ void MC6800::bitb_di() { uint8_t t, r; DIRBYTE(t); r = B & t; CLR_NZV; SET_NZ8(r); } /* $d6 LDB direct -**0- */ void MC6800::ldb_di() { DIRBYTE(B); CLR_NZV; SET_NZ8(B); } /* $d7 STB direct -**0- */ void MC6800::stb_di() { CLR_NZV; SET_NZ8(B); DIRECT; WM(EAD, B); } /* $d8 EORB direct -**0- */ void MC6800::eorb_di() { uint8_t t; DIRBYTE(t); B ^= t; CLR_NZV; SET_NZ8(B); } /* $d9 ADCB direct ***** */ void MC6800::adcb_di() { uint16_t t, r; DIRBYTE(t); r = B + t + (CC & 0x01); CLR_HNZVC; SET_FLAGS8(B, t, r); SET_H(B, t, r); B = (uint8_t)r; } /* $da ORB direct -**0- */ void MC6800::orb_di() { uint8_t t; DIRBYTE(t); B |= t; CLR_NZV; SET_NZ8(B); } /* $db ADDB direct ***** */ void MC6800::addb_di() { uint16_t t, r; DIRBYTE(t); r = B + t; CLR_HNZVC; SET_FLAGS8(B, t, r); SET_H(B, t, r); B = (uint8_t)r; } /* $dc LDD direct -**0- */ void MC6800::ldd_di() { DIRWORD(pD); CLR_NZV; SET_NZ16(D); } /* $dd STD direct -**0- */ void MC6800::std_di() { DIRECT; CLR_NZV; SET_NZ16(D); WM16(EAD, &pD); } /* $de LDX direct -**0- */ void MC6800::ldx_di() { DIRWORD(pX); CLR_NZV; SET_NZ16(X); } /* $dF STX direct -**0- */ void MC6800::stx_di() { CLR_NZV; SET_NZ16(X); DIRECT; WM16(EAD, &pX); } /* $e0 SUBB indexed ?**** */ void MC6800::subb_ix() { uint16_t t, r; IDXBYTE(t); r = B - t; CLR_NZVC; SET_FLAGS8(B, t, r); B = (uint8_t)r; } /* $e1 CMPB indexed ?**** */ void MC6800::cmpb_ix() { uint16_t t, r; IDXBYTE(t); r = B - t; CLR_NZVC; SET_FLAGS8(B, t, r); } /* $e2 SBCB indexed ?**** */ void MC6800::sbcb_ix() { uint16_t t, r; IDXBYTE(t); r = B - t - (CC & 0x01); CLR_NZVC; SET_FLAGS8(B, t, r); B = (uint8_t)r; } /* $e3 ADDD indexed -**** */ void MC6800::addd_ix() { uint32_t r, d; pair32_t b; IDXWORD(b); d = D; r = d + b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); D = r; } /* $e4 ANDB indexed -**0- */ void MC6800::andb_ix() { uint8_t t; IDXBYTE(t); B &= t; CLR_NZV; SET_NZ8(B); } /* $e5 BITB indexed -**0- */ void MC6800::bitb_ix() { uint8_t t, r; IDXBYTE(t); r = B & t; CLR_NZV; SET_NZ8(r); } /* $e6 LDB indexed -**0- */ void MC6800::ldb_ix() { IDXBYTE(B); CLR_NZV; SET_NZ8(B); } /* $e7 STB indexed -**0- */ void MC6800::stb_ix() { CLR_NZV; SET_NZ8(B); INDEXED; WM(EAD, B); } /* $e8 EORB indexed -**0- */ void MC6800::eorb_ix() { uint8_t t; IDXBYTE(t); B ^= t; CLR_NZV; SET_NZ8(B); } /* $e9 ADCB indexed ***** */ void MC6800::adcb_ix() { uint16_t t, r; IDXBYTE(t); r = B + t + (CC & 0x01); CLR_HNZVC; SET_FLAGS8(B, t, r); SET_H(B, t, r); B = (uint8_t)r; } /* $ea ORB indexed -**0- */ void MC6800::orb_ix() { uint8_t t; IDXBYTE(t); B |= t; CLR_NZV; SET_NZ8(B); } /* $eb ADDB indexed ***** */ void MC6800::addb_ix() { uint16_t t, r; IDXBYTE(t); r = B + t; CLR_HNZVC; SET_FLAGS8(B, t, r); SET_H(B, t, r); B = (uint8_t)r; } /* $ec LDD indexed -**0- */ void MC6800::ldd_ix() { IDXWORD(pD); CLR_NZV; SET_NZ16(D); } /* $ec ADX immediate -**** */ /* MB8861 only */ void MC6800::adx_im() { uint32_t r, d, t; IMMBYTE(t); d = X; r = d + t; CLR_NZVC; SET_FLAGS16(d, t, r); X = r; } /* $ed STD indexed -**0- */ void MC6800::std_ix() { INDEXED; CLR_NZV; SET_NZ16(D); WM16(EAD, &pD); } /* $ee LDX indexed -**0- */ void MC6800::ldx_ix() { IDXWORD(pX); CLR_NZV; SET_NZ16(X); } /* $ef STX indexed -**0- */ void MC6800::stx_ix() { CLR_NZV; SET_NZ16(X); INDEXED; WM16(EAD, &pX); } /* $f0 SUBB extended ?**** */ void MC6800::subb_ex() { uint16_t t, r; EXTBYTE(t); r = B - t; CLR_NZVC; SET_FLAGS8(B, t, r); B = (uint8_t)r; } /* $f1 CMPB extended ?**** */ void MC6800::cmpb_ex() { uint16_t t, r; EXTBYTE(t); r = B - t; CLR_NZVC; SET_FLAGS8(B, t, r); } /* $f2 SBCB extended ?**** */ void MC6800::sbcb_ex() { uint16_t t, r; EXTBYTE(t); r = B - t - (CC & 0x01); CLR_NZVC; SET_FLAGS8(B, t, r); B = (uint8_t)r; } /* $f3 ADDD extended -**** */ void MC6800::addd_ex() { uint32_t r, d; pair32_t b; EXTWORD(b); d = D; r = d + b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); D = r; } /* $f4 ANDB extended -**0- */ void MC6800::andb_ex() { uint8_t t; EXTBYTE(t); B &= t; CLR_NZV; SET_NZ8(B); } /* $f5 BITB extended -**0- */ void MC6800::bitb_ex() { uint8_t t, r; EXTBYTE(t); r = B & t; CLR_NZV; SET_NZ8(r); } /* $f6 LDB extended -**0- */ void MC6800::ldb_ex() { EXTBYTE(B); CLR_NZV; SET_NZ8(B); } /* $f7 STB extended -**0- */ void MC6800::stb_ex() { CLR_NZV; SET_NZ8(B); EXTENDED; WM(EAD, B); } /* $f8 EORB extended -**0- */ void MC6800::eorb_ex() { uint8_t t; EXTBYTE(t); B ^= t; CLR_NZV; SET_NZ8(B); } /* $f9 ADCB extended ***** */ void MC6800::adcb_ex() { uint16_t t, r; EXTBYTE(t); r = B + t + (CC & 0x01); CLR_HNZVC; SET_FLAGS8(B, t, r); SET_H(B, t, r); B = (uint8_t)r; } /* $fa ORB extended -**0- */ void MC6800::orb_ex() { uint8_t t; EXTBYTE(t); B |= t; CLR_NZV; SET_NZ8(B); } /* $fb ADDB extended ***** */ void MC6800::addb_ex() { uint16_t t, r; EXTBYTE(t); r = B + t; CLR_HNZVC; SET_FLAGS8(B, t, r); SET_H(B, t, r); B = (uint8_t)r; } /* $fc LDD extended -**0- */ void MC6800::ldd_ex() { EXTWORD(pD); CLR_NZV; SET_NZ16(D); } /* $fc ADX immediate -**** */ /* MB8861 only */ void MC6800::adx_ex() { uint32_t r, d; pair32_t b; EXTWORD(b); d = X; r = d + b.d; CLR_NZVC; SET_FLAGS16(d, b.d, r); X = r; } /* $fd STD extended -**0- */ void MC6800::std_ex() { EXTENDED; CLR_NZV; SET_NZ16(D); WM16(EAD, &pD); } /* $fe LDX extended -**0- */ void MC6800::ldx_ex() { EXTWORD(pX); CLR_NZV; SET_NZ16(X); } /* $ff STX extended -**0- */ void MC6800::stx_ex() { CLR_NZV; SET_NZ16(X); EXTENDED; WM16(EAD, &pX); } #define STATE_VERSION 2 bool MC6800::process_state(FILEIO* state_fio, bool loading) { if(!state_fio->StateCheckUint32(STATE_VERSION)) { return false; } if(!state_fio->StateCheckInt32(this_device_id)) { return false; } state_fio->StateValue(pc.d); state_fio->StateValue(prevpc); state_fio->StateValue(sp.d); state_fio->StateValue(ix.d); state_fio->StateValue(acc_d.d); state_fio->StateValue(ea.d); state_fio->StateValue(cc); state_fio->StateValue(wai_state); state_fio->StateValue(int_state); #ifdef USE_DEBUGGER state_fio->StateValue(total_icount); #endif state_fio->StateValue(icount); #if defined(HAS_MC6801) || defined(HAS_HD6301) for(int i = 0; i < 4; i++) { state_fio->StateValue(port[i].wreg); state_fio->StateValue(port[i].rreg); state_fio->StateValue(port[i].ddr); state_fio->StateValue(port[i].latched_data); state_fio->StateValue(port[i].latched); state_fio->StateValue(port[i].first_write); } state_fio->StateValue(p3csr); state_fio->StateValue(p3csr_is3_flag_read); state_fio->StateValue(sc1_state); state_fio->StateValue(sc2_state); state_fio->StateValue(counter.d); state_fio->StateValue(output_compare.d); state_fio->StateValue(timer_over.d); state_fio->StateValue(tcsr); state_fio->StateValue(pending_tcsr); state_fio->StateValue(input_capture); #ifdef HAS_HD6301 state_fio->StateValue(latch09); #endif state_fio->StateValue(timer_next); if(!recv_buffer->process_state((void *)state_fio, loading)) { return false; } state_fio->StateValue(trcsr); state_fio->StateValue(rdr); state_fio->StateValue(tdr); state_fio->StateValue(trcsr_read_tdre); state_fio->StateValue(trcsr_read_orfe); state_fio->StateValue(trcsr_read_rdrf); state_fio->StateValue(rmcr); state_fio->StateValue(sio_counter); state_fio->StateValue(ram_ctrl); state_fio->StateArray(ram, sizeof(ram), 1); #endif #ifdef USE_DEBUGGER // post process if(loading) { prev_total_icount = total_icount; } #endif return true; }