2 Skelton for retropc emulator
5 Author : Takeda.Toshiya
14 //#if defined(USE_SHARED_DLL)
16 //#include "libcpu_newdev/libcpu_mc6809/mc6809.h"
21 #include "mc6809_consts.h"
25 MC6809_PHASE_PUSH_STACK,
26 MC6809_PHASE_FETCH_VECTOR,
27 MC6809_PHASE_DEAD_CYCLE,
29 MC6809_PHASE_REQ_HALT,
34 #define SIG_CPU_HALTREQ 0x8000 + SIG_CPU_BUSREQ
35 // Note: Below is ugly hack cause of CPU#0 cannot modify clock.
36 #define SIG_CPU_WAIT_FACTOR 0x8001 + SIG_CPU_BUSREQ
40 class MC6809_BASE : public DEVICE
50 outputs_t outputs_bus_ba; // Bus available.
51 outputs_t outputs_bus_bs; // Bus status.
54 pair32_t pc; /* Program counter */
55 pair32_t ppc; /* Previous program counter */
56 pair32_t acc; /* Accumulator a and b */
57 pair32_t dp; /* Direct Page register (page in MSB) */
58 pair32_t u, s; /* Stack pointers */
59 pair32_t x, y; /* Index registers */
61 pair32_t ea; /* effective address */
64 /* In Motorola's datasheet, status has some valiants. 20171207 K.O */
72 uint64_t total_icount;
73 uint64_t prev_total_icount;
77 void WM16(uint32_t Addr, pair32_t *p);
78 void cpu_irq_push(void);
79 void cpu_firq_push(void);
80 void cpu_nmi_push(void);
81 void cpu_irq_fetch_vector_address(void);
82 void cpu_firq_fetch_vector_address(void);
83 void cpu_nmi_fetch_vector_address(void);
84 void cpu_wait(int clocks = 1);
87 const uint8_t flags8i[256] = {
88 CC_Z,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
89 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
90 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
91 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
92 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
93 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
94 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
95 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
96 CC_N|CC_V,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
97 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
98 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
99 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
100 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
101 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
102 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
103 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N
107 const uint8_t flags8d[256] = {
108 CC_Z,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
109 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
110 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
111 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
112 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
113 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
114 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
115 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,CC_V,
116 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
117 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
118 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
119 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
120 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
121 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
122 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
123 CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N
126 /* FIXME: Cycles differ slighly from hd6309 emulation */
127 const int index_cycle_em[256] = { /* Index Loopup cycle counts */
128 /* 0xX0, 0xX1, 0xX2, 0xX3, 0xX4, 0xX5, 0xX6, 0xX7, 0xX8, 0xX9, 0xXA, 0xXB, 0xXC, 0xXD, 0xXE, 0xXF */
130 /* 0x0X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
131 /* 0x1X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
132 /* 0x2X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
133 /* 0x3X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
134 /* 0x4X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
135 /* 0x5X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
136 /* 0x6X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
137 /* 0x7X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
138 /* 0x8X */ 2, 3, 2, 3, 0, 1, 1, 1, 1, 4, 0, 4, 1, 5, 0, 2,
139 /* 0x9X */ 5, 6, 5, 6, 3, 4, 4, 4, 4, 7, 3, 7, 4, 8, 3, 3,
140 /* 0xAX */ 2, 3, 2, 3, 0, 1, 1, 1, 1, 4, 0, 4, 1, 5, 0, 2,
141 /* 0xBX */ 5, 6, 5, 6, 3, 4, 4, 4, 4, 7, 3, 7, 4, 8, 3, 5,
142 /* 0xCX */ 2, 3, 2, 3, 0, 1, 1, 1, 1, 4, 0, 4, 1, 5, 0, 2,
143 /* 0xDX */ 5, 6, 5, 6, 3, 4, 4, 4, 4, 7, 3, 7, 4, 8, 3, 5,
144 /* 0xEX */ 2, 3, 2, 3, 0, 1, 1, 1, 1, 4, 0, 4, 1, 5, 0, 2,
145 /* 0xFX */ 4, 6, 5, 6, 3, 4, 4, 4, 4, 7, 3, 7, 4, 8, 3, 5
148 /* timings for 1-byte opcodes */
149 /* 20100731 Fix to XM7 */
150 const int cycles1[256] = {
151 /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
152 /*0 */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 6,
153 /*1 */ 0, 0, 2, 2, 0, 0, 5, 9, 3, 2, 3, 2, 3, 2, 8, 6,
154 /*2 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
155 /*3 */ 4, 4, 4, 4, 5, 5, 5, 5, 4, 5, 3, 6, 20, 11, 1, 19,
156 /*4 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
157 /*5 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
158 /*6 */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 6,
159 /*7 */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 7,
160 /*8 */ 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 4, 7, 3, 3,
161 /*9 */ 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5,
162 /*A*/ 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5,
163 /*B*/ 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 7, 8, 6, 6,
164 /*C*/ 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 3, 0, 3, 3,
165 /*D*/ 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
166 /*E*/ 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
167 /*F*/ 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6
170 virtual void run_one_opecode();
171 void op(uint8_t ireg);
172 void fetch_effective_address();
173 void fetch_effective_address_IDX(uint8_t upper, uint8_t lower);
175 inline void BRANCH(bool cond);
176 inline void LBRANCH(bool cond);
178 inline pair32_t RM16_PAIR(uint32_t addr);
179 inline uint8_t GET_INDEXED_DATA(void);
180 inline pair32_t GET_INDEXED_DATA16(void);
182 inline void NEG_MEM(uint8_t a_neg);
183 inline uint8_t NEG_REG(uint8_t r_neg);
184 inline void COM_MEM(uint8_t a_neg);
185 inline uint8_t COM_REG(uint8_t r_neg);
186 inline void LSR_MEM(uint8_t a_neg);
187 inline uint8_t LSR_REG(uint8_t r_neg);
188 inline void ROR_MEM(uint8_t a_neg);
189 inline uint8_t ROR_REG(uint8_t r_neg);
190 inline void ASR_MEM(uint8_t a_neg);
191 inline uint8_t ASR_REG(uint8_t r_neg);
192 inline void ASL_MEM(uint8_t a_neg);
193 inline uint8_t ASL_REG(uint8_t r_neg);
194 inline void ROL_MEM(uint8_t a_neg);
195 inline uint8_t ROL_REG(uint8_t r_neg);
196 inline void DEC_MEM(uint8_t a_neg);
197 inline uint8_t DEC_REG(uint8_t r_neg);
198 inline void DCC_MEM(uint8_t a_neg);
199 inline uint8_t DCC_REG(uint8_t r_neg);
200 inline void INC_MEM(uint8_t a_neg);
201 inline uint8_t INC_REG(uint8_t r_neg);
202 inline void TST_MEM(uint8_t a_neg);
203 inline uint8_t TST_REG(uint8_t r_neg);
204 inline uint8_t CLC_REG(uint8_t r_neg);
205 inline void CLR_MEM(uint8_t a_neg);
206 inline uint8_t CLR_REG(uint8_t r_neg);
208 inline uint8_t SUB8_REG(uint8_t reg, uint8_t data);
209 inline uint8_t CMP8_REG(uint8_t reg, uint8_t data);
210 inline uint8_t SBC8_REG(uint8_t reg, uint8_t data);
211 inline uint8_t AND8_REG(uint8_t reg, uint8_t data);
212 inline uint8_t BIT8_REG(uint8_t reg, uint8_t data);
213 inline uint8_t OR8_REG(uint8_t reg, uint8_t data);
214 inline uint8_t EOR8_REG(uint8_t reg, uint8_t data);
215 inline uint8_t ADD8_REG(uint8_t reg, uint8_t data);
216 inline uint8_t ADC8_REG(uint8_t reg, uint8_t data);
217 inline void STORE8_REG(uint8_t reg);
218 inline uint8_t LOAD8_REG(uint8_t reg);
220 inline uint16_t SUB16_REG(uint16_t reg, uint16_t data);
221 inline uint16_t ADD16_REG(uint16_t reg, uint16_t data);
222 inline uint16_t CMP16_REG(uint16_t reg, uint16_t data);
223 inline uint16_t LOAD16_REG(uint16_t reg);
224 inline void STORE16_REG(pair32_t *p);
229 inline void adca_im();
523 uint64_t cycles_tmp_count;
524 uint32_t insns_count;
525 uint32_t extra_tmp_count;
532 MC6809_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
535 total_icount = prev_total_icount = 0;
536 cycles_tmp_count = 0;
538 __USE_DEBUGGER = false;
539 initialize_output_signals(&outputs_bus_ba);
540 initialize_output_signals(&outputs_bus_bs);
541 set_device_name(_T("MC6809 MPU"));
549 uint32_t get_debug_prog_addr_mask()
553 uint32_t get_debug_data_addr_mask()
557 void write_debug_data8(uint32_t addr, uint32_t data);
558 uint32_t read_debug_data8(uint32_t addr);
559 void write_debug_data16(uint32_t addr, uint32_t data)
561 write_debug_data8(addr, (data >> 8) & 0xff);
562 write_debug_data8(addr + 1, data & 0xff);
564 uint32_t read_debug_data16(uint32_t addr)
566 uint32_t val = read_debug_data8(addr) << 8;
567 val |= read_debug_data8(addr + 1);
570 void write_debug_data32(uint32_t addr, uint32_t data)
572 write_debug_data16(addr, (data >> 16) & 0xffff);
573 write_debug_data16(addr + 2, data & 0xffff);
575 uint32_t read_debug_data32(uint32_t addr)
577 uint32_t val = read_debug_data16(addr) << 16;
578 val |= read_debug_data16(addr + 2);
581 void write_debug_io8(uint32_t addr, uint32_t data);
582 uint32_t read_debug_io8(uint32_t addr);
583 void write_debug_io16(uint32_t addr, uint32_t data)
585 write_debug_io8(addr, (data >> 8) & 0xff);
586 write_debug_io8(addr + 1, data & 0xff);
588 uint32_t read_debug_io16(uint32_t addr)
590 uint32_t val = read_debug_io8(addr) << 8;
591 val |= read_debug_io8(addr + 1);
594 void write_debug_io32(uint32_t addr, uint32_t data)
596 write_debug_io16(addr, (data >> 16) & 0xffff);
597 write_debug_io16(addr + 2, data & 0xffff);
599 uint32_t read_debug_io32(uint32_t addr)
601 uint32_t val = read_debug_io16(addr) << 16;
602 val |= read_debug_io16(addr + 2);
605 bool write_debug_reg(const _TCHAR *reg, uint32_t data);
606 void get_debug_regs_info(_TCHAR *buffer, size_t buffer_len);
607 virtual int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len);
608 virtual uint32_t cpu_disassemble_m6809(_TCHAR *buffer, uint32_t pc, const uint8_t *oprom, const uint8_t *opram);
609 virtual void debugger_hook(void);
612 virtual void initialize();
614 void write_signal(int id, uint32_t data, uint32_t mask);
615 bool process_state(FILEIO* state_fio, bool loading);
617 void set_extra_clock(int clock)
619 extra_icount += clock;
621 int get_extra_clock()
629 uint32_t get_next_pc()
642 uint32_t get_ustack()
646 uint32_t get_sstack()
668 void set_context_mem(DEVICE* device)
672 void set_context_bus_ba(DEVICE* device, int id, uint32_t mask)
674 register_output_signal(&outputs_bus_ba, device, id, mask);
676 void set_context_bus_bs(DEVICE* device, int id, uint32_t mask)
678 register_output_signal(&outputs_bus_bs, device, id, mask);
681 void set_context_debugger(DEBUGGER* device)
688 class MC6809 : public MC6809_BASE
692 MC6809(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MC6809_BASE(parent_vm, parent_emu)
697 void run_one_opecode();
698 uint32_t cpu_disassemble_m6809(_TCHAR *buffer, uint32_t pc, const uint8_t *oprom, const uint8_t *opram);
699 int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len);
700 void debugger_hook(void);