OSDN Git Service

[VM][MC6809] TRY: Fixing hangup with F-BASIC v3.0ε.Thanks to Ryu Takegami-San. (see...
[csp-qt/common_source_project-fm7.git] / source / src / vm / mc6809.cpp
1 /*
2         Skelton for retropc emulator
3
4         Origin : MAME 0.142
5         Author : Takeda.Toshiya
6         Date   : 2011.05.06-
7
8         [ MC6809 ]
9         Notes from K.Ohta <whatisthis.sowhat _at_ gmail.com> at Jan 16, 2015:
10               All of undocumented instructions (i.e. ngc, flag16) of MC6809(not HD6309) are written by me.
11               These behaviors of undocumented insns are refered from "vm/cpu_x86.asm" (ia32 assembly codefor nasm) within XM7
12               written by Ryu Takegami , and older article wrote in magazine, "I/O" at 1985.
13               But, these C implements are written from scratch by me , and I tested many years at XM7/SDL.
14               Perhaps, these insns. are not implement MAME/MESS yet.
15 */
16
17 // Fixed IRQ/FIRQ by Mr.Sasaji at 2011.06.17
18
19 #include "vm.h"
20 #include "../emu.h"
21 #include "mc6809.h"
22 #include "mc6809_consts.h"
23
24 #ifdef USE_DEBUGGER
25 #include "debugger.h"
26 #endif
27
28 void MC6809::initialize()
29 {
30         MC6809_BASE::initialize();
31         int_state = 0;
32         busreq = false;
33
34         if(__USE_DEBUGGER) {
35                 d_mem_stored = d_mem;
36                 d_debugger->set_context_mem(d_mem);
37         }
38 }
39
40 void MC6809::run_one_opecode()
41 {
42         if(__USE_DEBUGGER) {
43                 bool now_debugging = d_debugger->now_debugging;
44                 if(now_debugging) {
45                         d_debugger->check_break_points(PC);
46                         if(d_debugger->now_suspended) {
47                                 osd->mute_sound();
48                                 d_debugger->now_waiting = true;
49                                 while(d_debugger->now_debugging && d_debugger->now_suspended) {
50                                         osd->sleep(10);
51                                 }
52                                 d_debugger->now_waiting = false;
53                         }
54                         if(d_debugger->now_debugging) {
55                                 d_mem = d_debugger;
56                         } else {
57                                 now_debugging = false;
58                         }
59                 
60                         d_debugger->add_cpu_trace(PC);
61                         int first_icount = icount;
62                         pPPC = pPC;
63                         uint8_t ireg = ROP(PCD);
64                         PC++;
65                         icount -= cycles1[ireg];
66                         icount -= extra_icount;
67                         extra_icount = 0;
68                         op(ireg);
69                         total_icount += first_icount - icount;
70                 
71                         if(now_debugging) {
72                                 if(!d_debugger->now_going) {
73                                         d_debugger->now_suspended = true;
74                                 }
75                                 d_mem = d_mem_stored;
76                         }
77                 } else {
78                         d_debugger->add_cpu_trace(PC);
79                         int first_icount = icount;
80                         pPPC = pPC;
81                         uint8_t ireg = ROP(PCD);
82                         PC++;
83                         icount -= cycles1[ireg];
84                         icount -= extra_icount;
85                         extra_icount = 0;
86                         op(ireg);
87                         total_icount += first_icount - icount;
88                 }
89         } else {
90                 pPPC = pPC;
91                 uint8_t ireg = ROP(PCD);
92                 PC++;
93                 icount -= cycles1[ireg];
94                 icount -= extra_icount;
95                 extra_icount = 0;
96                 op(ireg);
97         }
98 }
99
100
101 // from MAME 0.160
102
103
104 #ifdef USE_DEBUGGER
105
106 /*****************************************************************************
107
108     6809dasm.c - a 6809 opcode disassembler
109     Version 1.4 1-MAR-95
110     Copyright Sean Riddle
111
112     Thanks to Franklin Bowen for bug fixes, ideas
113
114     Freely distributable on any medium given all copyrights are retained
115     by the author and no charge greater than $7.00 is made for obtaining
116     this software
117
118     Please send all bug reports, update ideas and data files to:
119     sriddle@ionet.net
120
121 *****************************************************************************/
122 // Opcode structure
123 struct opcodeinfo
124 {
125         uint8_t   opcode;     // 8-bit opcode value
126         uint8_t   length;     // Opcode length in bytes
127         _TCHAR  name[6];    // Opcode name
128         uint8_t   mode;       // Addressing mode
129 //      unsigned flags;     // Disassembly flags
130 };
131
132 enum m6809_addressing_modes
133 {
134         INH,                // Inherent
135         DIR,                // Direct
136         IND,                // Indexed
137         REL,                // Relative (8 bit)
138         LREL,               // Long relative (16 bit)
139         EXT,                // Extended
140         IMM,                // Immediate
141         IMM_RR,             // Register-to-register
142         PG1,                // Switch to page 1 opcodes
143         PG2                 // Switch to page 2 opcodes
144 };
145
146 // Page 0 opcodes (single byte)
147 static const opcodeinfo m6809_pg0opcodes[] =
148 {
149         { 0x00, 2, _T("NEG"),   DIR    },
150         { 0x01, 2, _T("NEG"),   DIR    },
151         { 0x02, 2, _T("NGC"),   DIR    },
152         { 0x03, 2, _T("COM"),   DIR    },
153         { 0x04, 2, _T("LSR"),   DIR    },
154         { 0x05, 2, _T("LSR"),   DIR    },
155         { 0x06, 2, _T("ROR"),   DIR    },
156         { 0x07, 2, _T("ASR"),   DIR    },
157         { 0x08, 2, _T("ASL"),   DIR    },
158         { 0x09, 2, _T("ROL"),   DIR    },
159         { 0x0A, 2, _T("DEC"),   DIR    },
160         { 0x0B, 2, _T("DCC"),   DIR    },
161         { 0x0C, 2, _T("INC"),   DIR    },
162         { 0x0D, 2, _T("TST"),   DIR    },
163         { 0x0E, 2, _T("JMP"),   DIR    },
164         { 0x0F, 2, _T("CLR"),   DIR    },
165
166         { 0x10, 1, _T("page1"), PG1    },
167         { 0x11, 1, _T("page2"), PG2    },
168         { 0x12, 1, _T("NOP"),   INH    },
169         { 0x13, 1, _T("SYNC"),  INH    },
170         { 0x14, 1, _T("HALT"),  INH    },
171         { 0x15, 1, _T("HALT"),  INH    },
172         { 0x16, 3, _T("LBRA"),  LREL   },
173         { 0x17, 3, _T("LBSR"),  LREL   },
174         { 0x18, 1, _T("ASLCC"), INH    },
175         { 0x19, 1, _T("DAA"),   INH    },
176         { 0x1A, 2, _T("ORCC"),  IMM    },
177         { 0x1B, 1, _T("NOP"),   INH    },
178         { 0x1C, 2, _T("ANDCC"), IMM    },
179         { 0x1D, 1, _T("SEX"),   INH    },
180         { 0x1E, 2, _T("EXG"),   IMM_RR },
181         { 0x1F, 2, _T("TFR"),   IMM_RR },
182
183         { 0x20, 2, _T("BRA"),   REL    },
184         { 0x21, 2, _T("BRN"),   REL    },
185         { 0x22, 2, _T("BHI"),   REL    },
186         { 0x23, 2, _T("BLS"),   REL    },
187         { 0x24, 2, _T("BCC"),   REL    },
188         { 0x25, 2, _T("BCS"),   REL    },
189         { 0x26, 2, _T("BNE"),   REL    },
190         { 0x27, 2, _T("BEQ"),   REL    },
191         { 0x28, 2, _T("BVC"),   REL    },
192         { 0x29, 2, _T("BVS"),   REL    },
193         { 0x2A, 2, _T("BPL"),   REL    },
194         { 0x2B, 2, _T("BMI"),   REL    },
195         { 0x2C, 2, _T("BGE"),   REL    },
196         { 0x2D, 2, _T("BLT"),   REL    },
197         { 0x2E, 2, _T("BGT"),   REL    },
198         { 0x2F, 2, _T("BLE"),   REL    },
199
200         { 0x30, 2, _T("LEAX"),  IND    },
201         { 0x31, 2, _T("LEAY"),  IND    },
202         { 0x32, 2, _T("LEAS"),  IND    },
203         { 0x33, 2, _T("LEAU"),  IND    },
204         { 0x34, 2, _T("PSHS"),  INH    },
205         { 0x35, 2, _T("PULS"),  INH    },
206         { 0x36, 2, _T("PSHU"),  INH    },
207         { 0x37, 2, _T("PULU"),  INH    },
208         { 0x38, 2, _T("ANDCC"), IMM    },
209         { 0x39, 1, _T("RTS"),   INH    },
210         { 0x3A, 1, _T("ABX"),   INH    },
211         { 0x3B, 1, _T("RTI"),   INH    },
212         { 0x3C, 2, _T("CWAI"),  IMM    },
213         { 0x3D, 1, _T("MUL"),   INH    },
214         { 0x3F, 1, _T("SWI"),   INH    },
215
216         { 0x40, 1, _T("NEGA"),  INH    },
217         { 0x41, 1, _T("NEGA"),  INH    },
218         { 0x42, 1, _T("NGGA"),  INH    },
219         { 0x43, 1, _T("COMA"),  INH    },
220         { 0x44, 1, _T("LSRA"),  INH    },
221         { 0x45, 1, _T("LSRA"),  INH    },
222         { 0x46, 1, _T("RORA"),  INH    },
223         { 0x47, 1, _T("ASRA"),  INH    },
224         { 0x48, 1, _T("ASLA"),  INH    },
225         { 0x49, 1, _T("ROLA"),  INH    },
226         { 0x4A, 1, _T("DECA"),  INH    },
227         { 0x4B, 1, _T("DCCA"),  INH    },
228         { 0x4C, 1, _T("INCA"),  INH    },
229         { 0x4D, 1, _T("TSTA"),  INH    },
230         { 0x4E, 1, _T("CLCA"),  INH    },
231         { 0x4F, 1, _T("CLRA"),  INH    },
232
233         { 0x50, 1, _T("NEGB"),  INH    },
234         { 0x51, 1, _T("NEGB"),  INH    },
235         { 0x52, 1, _T("NGGB"),  INH    },
236         { 0x53, 1, _T("COMB"),  INH    },
237         { 0x54, 1, _T("LSRB"),  INH    },
238         { 0x55, 1, _T("LSRB"),  INH    },
239         { 0x56, 1, _T("RORB"),  INH    },
240         { 0x57, 1, _T("ASRB"),  INH    },
241         { 0x58, 1, _T("ASLB"),  INH    },
242         { 0x59, 1, _T("ROLB"),  INH    },
243         { 0x5A, 1, _T("DECB"),  INH    },
244         { 0x5B, 1, _T("DCCB"),  INH    },
245         { 0x5C, 1, _T("INCB"),  INH    },
246         { 0x5D, 1, _T("TSTB"),  INH    },
247         { 0x5E, 1, _T("CLCB"),  INH    },
248         { 0x5F, 1, _T("CLRB"),  INH    },
249
250         { 0x60, 2, _T("NEG"),   IND    },
251         { 0x61, 2, _T("NEG"),   IND    },
252         { 0x62, 2, _T("NGC"),   IND    },
253         { 0x63, 2, _T("COM"),   IND    },
254         { 0x64, 2, _T("LSR"),   IND    },
255         { 0x65, 2, _T("LSR"),   IND    },
256         { 0x66, 2, _T("ROR"),   IND    },
257         { 0x67, 2, _T("ASR"),   IND    },
258         { 0x68, 2, _T("ASL"),   IND    },
259         { 0x69, 2, _T("ROL"),   IND    },
260         { 0x6A, 2, _T("DEC"),   IND    },
261         { 0x6B, 2, _T("DCC"),   IND    },
262         { 0x6C, 2, _T("INC"),   IND    },
263         { 0x6D, 2, _T("TST"),   IND    },
264         { 0x6E, 2, _T("JMP"),   IND    },
265         { 0x6F, 2, _T("CLR"),   IND    },
266
267         { 0x70, 3, _T("NEG"),   EXT    },
268         { 0x71, 3, _T("NEG"),   EXT    },
269         { 0x72, 3, _T("NGC"),   EXT    },
270         { 0x73, 3, _T("COM"),   EXT    },
271         { 0x74, 3, _T("LSR"),   EXT    },
272         { 0x75, 3, _T("LSR"),   EXT    },
273         { 0x76, 3, _T("ROR"),   EXT    },
274         { 0x77, 3, _T("ASR"),   EXT    },
275         { 0x78, 3, _T("ASL"),   EXT    },
276         { 0x79, 3, _T("ROL"),   EXT    },
277         { 0x7A, 3, _T("DEC"),   EXT    },
278         { 0x7B, 3, _T("DCC"),   EXT    },
279         { 0x7C, 3, _T("INC"),   EXT    },
280         { 0x7D, 3, _T("TST"),   EXT    },
281         { 0x7E, 3, _T("JMP"),   EXT    },
282         { 0x7F, 3, _T("CLR"),   EXT    },
283
284         { 0x80, 2, _T("SUBA"),  IMM    },
285         { 0x81, 2, _T("CMPA"),  IMM    },
286         { 0x82, 2, _T("SBCA"),  IMM    },
287         { 0x83, 3, _T("SUBD"),  IMM    },
288         { 0x84, 2, _T("ANDA"),  IMM    },
289         { 0x85, 2, _T("BITA"),  IMM    },
290         { 0x86, 2, _T("LDA"),   IMM    },
291         { 0x87, 2, _T("FLAG"),  IMM    },
292         { 0x88, 2, _T("EORA"),  IMM    },
293         { 0x89, 2, _T("ADCA"),  IMM    },
294         { 0x8A, 2, _T("ORA"),   IMM    },
295         { 0x8B, 2, _T("ADDA"),  IMM    },
296         { 0x8C, 3, _T("CMPX"),  IMM    },
297         { 0x8D, 2, _T("BSR"),   REL    },
298         { 0x8E, 3, _T("LDX"),   IMM    },
299         { 0x8F, 3, _T("FLAG"),  IMM    },
300
301         { 0x90, 2, _T("SUBA"),  DIR    },
302         { 0x91, 2, _T("CMPA"),  DIR    },
303         { 0x92, 2, _T("SBCA"),  DIR    },
304         { 0x93, 2, _T("SUBD"),  DIR    },
305         { 0x94, 2, _T("ANDA"),  DIR    },
306         { 0x95, 2, _T("BITA"),  DIR    },
307         { 0x96, 2, _T("LDA"),   DIR    },
308         { 0x97, 2, _T("STA"),   DIR    },
309         { 0x98, 2, _T("EORA"),  DIR    },
310         { 0x99, 2, _T("ADCA"),  DIR    },
311         { 0x9A, 2, _T("ORA"),   DIR    },
312         { 0x9B, 2, _T("ADDA"),  DIR    },
313         { 0x9C, 2, _T("CMPX"),  DIR    },
314         { 0x9D, 2, _T("JSR"),   DIR    },
315         { 0x9E, 2, _T("LDX"),   DIR    },
316         { 0x9F, 2, _T("STX"),   DIR    },
317
318         { 0xA0, 2, _T("SUBA"),  IND    },
319         { 0xA1, 2, _T("CMPA"),  IND    },
320         { 0xA2, 2, _T("SBCA"),  IND    },
321         { 0xA3, 2, _T("SUBD"),  IND    },
322         { 0xA4, 2, _T("ANDA"),  IND    },
323         { 0xA5, 2, _T("BITA"),  IND    },
324         { 0xA6, 2, _T("LDA"),   IND    },
325         { 0xA7, 2, _T("STA"),   IND    },
326         { 0xA8, 2, _T("EORA"),  IND    },
327         { 0xA9, 2, _T("ADCA"),  IND    },
328         { 0xAA, 2, _T("ORA"),   IND    },
329         { 0xAB, 2, _T("ADDA"),  IND    },
330         { 0xAC, 2, _T("CMPX"),  IND    },
331         { 0xAD, 2, _T("JSR"),   IND    },
332         { 0xAE, 2, _T("LDX"),   IND    },
333         { 0xAF, 2, _T("STX"),   IND    },
334
335         { 0xB0, 3, _T("SUBA"),  EXT    },
336         { 0xB1, 3, _T("CMPA"),  EXT    },
337         { 0xB2, 3, _T("SBCA"),  EXT    },
338         { 0xB3, 3, _T("SUBD"),  EXT    },
339         { 0xB4, 3, _T("ANDA"),  EXT    },
340         { 0xB5, 3, _T("BITA"),  EXT    },
341         { 0xB6, 3, _T("LDA"),   EXT    },
342         { 0xB7, 3, _T("STA"),   EXT    },
343         { 0xB8, 3, _T("EORA"),  EXT    },
344         { 0xB9, 3, _T("ADCA"),  EXT    },
345         { 0xBA, 3, _T("ORA"),   EXT    },
346         { 0xBB, 3, _T("ADDA"),  EXT    },
347         { 0xBC, 3, _T("CMPX"),  EXT    },
348         { 0xBD, 3, _T("JSR"),   EXT    },
349         { 0xBE, 3, _T("LDX"),   EXT    },
350         { 0xBF, 3, _T("STX"),   EXT    },
351
352         { 0xC0, 2, _T("SUBB"),  IMM    },
353         { 0xC1, 2, _T("CMPB"),  IMM    },
354         { 0xC2, 2, _T("SBCB"),  IMM    },
355         { 0xC3, 3, _T("ADDD"),  IMM    },
356         { 0xC4, 2, _T("ANDB"),  IMM    },
357         { 0xC5, 2, _T("BITB"),  IMM    },
358         { 0xC6, 2, _T("LDB"),   IMM    },
359         { 0xC7, 2, _T("FLAG"),  IMM    },
360         { 0xC8, 2, _T("EORB"),  IMM    },
361         { 0xC9, 2, _T("ADCB"),  IMM    },
362         { 0xCA, 2, _T("ORB"),   IMM    },
363         { 0xCB, 2, _T("ADDB"),  IMM    },
364         { 0xCC, 3, _T("LDD"),   IMM    },
365         { 0xCD, 1, _T("HALT"),  INH    },
366         { 0xCE, 3, _T("LDU"),   IMM    },
367         { 0xCF, 3, _T("FLAG"),  IMM    },
368
369         { 0xD0, 2, _T("SUBB"),  DIR    },
370         { 0xD1, 2, _T("CMPB"),  DIR    },
371         { 0xD2, 2, _T("SBCB"),  DIR    },
372         { 0xD3, 2, _T("ADDD"),  DIR    },
373         { 0xD4, 2, _T("ANDB"),  DIR    },
374         { 0xD5, 2, _T("BITB"),  DIR    },
375         { 0xD6, 2, _T("LDB"),   DIR    },
376         { 0xD7, 2, _T("STB"),   DIR    },
377         { 0xD8, 2, _T("EORB"),  DIR    },
378         { 0xD9, 2, _T("ADCB"),  DIR    },
379         { 0xDA, 2, _T("ORB"),   DIR    },
380         { 0xDB, 2, _T("ADDB"),  DIR    },
381         { 0xDC, 2, _T("LDD"),   DIR    },
382         { 0xDD, 2, _T("STD"),   DIR    },
383         { 0xDE, 2, _T("LDU"),   DIR    },
384         { 0xDF, 2, _T("STU"),   DIR    },
385
386         { 0xE0, 2, _T("SUBB"),  IND    },
387         { 0xE1, 2, _T("CMPB"),  IND    },
388         { 0xE2, 2, _T("SBCB"),  IND    },
389         { 0xE3, 2, _T("ADDD"),  IND    },
390         { 0xE4, 2, _T("ANDB"),  IND    },
391         { 0xE5, 2, _T("BITB"),  IND    },
392         { 0xE6, 2, _T("LDB"),   IND    },
393         { 0xE7, 2, _T("STB"),   IND    },
394         { 0xE8, 2, _T("EORB"),  IND    },
395         { 0xE9, 2, _T("ADCB"),  IND    },
396         { 0xEA, 2, _T("ORB"),   IND    },
397         { 0xEB, 2, _T("ADDB"),  IND    },
398         { 0xEC, 2, _T("LDD"),   IND    },
399         { 0xED, 2, _T("STD"),   IND    },
400         { 0xEE, 2, _T("LDU"),   IND    },
401         { 0xEF, 2, _T("STU"),   IND    },
402
403         { 0xF0, 3, _T("SUBB"),  EXT    },
404         { 0xF1, 3, _T("CMPB"),  EXT    },
405         { 0xF2, 3, _T("SBCB"),  EXT    },
406         { 0xF3, 3, _T("ADDD"),  EXT    },
407         { 0xF4, 3, _T("ANDB"),  EXT    },
408         { 0xF5, 3, _T("BITB"),  EXT    },
409         { 0xF6, 3, _T("LDB"),   EXT    },
410         { 0xF7, 3, _T("STB"),   EXT    },
411         { 0xF8, 3, _T("EORB"),  EXT    },
412         { 0xF9, 3, _T("ADCB"),  EXT    },
413         { 0xFA, 3, _T("ORB"),   EXT    },
414         { 0xFB, 3, _T("ADDB"),  EXT    },
415         { 0xFC, 3, _T("LDD"),   EXT    },
416         { 0xFD, 3, _T("STD"),   EXT    },
417         { 0xFE, 3, _T("LDU"),   EXT    },
418         { 0xFF, 3, _T("STU"),   EXT    }
419 };
420
421 // Page 1 opcodes (0x10 0x..)
422 static const opcodeinfo m6809_pg1opcodes[] =
423 {
424         { 0x20, 4, _T("LBRA"),  LREL   },
425         { 0x21, 4, _T("LBRN"),  LREL   },
426         { 0x22, 4, _T("LBHI"),  LREL   },
427         { 0x23, 4, _T("LBLS"),  LREL   },
428         { 0x24, 4, _T("LBCC"),  LREL   },
429         { 0x25, 4, _T("LBCS"),  LREL   },
430         { 0x26, 4, _T("LBNE"),  LREL   },
431         { 0x27, 4, _T("LBEQ"),  LREL   },
432         { 0x28, 4, _T("LBVC"),  LREL   },
433         { 0x29, 4, _T("LBVS"),  LREL   },
434         { 0x2A, 4, _T("LBPL"),  LREL   },
435         { 0x2B, 4, _T("LBMI"),  LREL   },
436         { 0x2C, 4, _T("LBGE"),  LREL   },
437         { 0x2D, 4, _T("LBLT"),  LREL   },
438         { 0x2E, 4, _T("LBGT"),  LREL   },
439         { 0x2F, 4, _T("LBLE"),  LREL   },
440         { 0x3F, 2, _T("SWI2"),  INH    },
441         { 0x83, 4, _T("CMPD"),  IMM    },
442         { 0x8C, 4, _T("CMPY"),  IMM    },
443         { 0x8D, 4, _T("LBSR"),  LREL   },
444         { 0x8E, 4, _T("LDY"),   IMM    },
445         { 0x93, 3, _T("CMPD"),  DIR    },
446         { 0x9C, 3, _T("CMPY"),  DIR    },
447         { 0x9E, 3, _T("LDY"),   DIR    },
448         { 0x9F, 3, _T("STY"),   DIR    },
449         { 0xA3, 3, _T("CMPD"),  IND    },
450         { 0xAC, 3, _T("CMPY"),  IND    },
451         { 0xAE, 3, _T("LDY"),   IND    },
452         { 0xAF, 3, _T("STY"),   IND    },
453         { 0xB3, 4, _T("CMPD"),  EXT    },
454         { 0xBC, 4, _T("CMPY"),  EXT    },
455         { 0xBE, 4, _T("LDY"),   EXT    },
456         { 0xBF, 4, _T("STY"),   EXT    },
457         { 0xCE, 4, _T("LDS"),   IMM    },
458         { 0xDE, 3, _T("LDS"),   DIR    },
459         { 0xDF, 3, _T("STS"),   DIR    },
460         { 0xEE, 3, _T("LDS"),   IND    },
461         { 0xEF, 3, _T("STS"),   IND    },
462         { 0xFE, 4, _T("LDS"),   EXT    },
463         { 0xFF, 4, _T("STS"),   EXT    }
464 };
465
466 // Page 2 opcodes (0x11 0x..)
467 static const opcodeinfo m6809_pg2opcodes[] =
468 {
469         { 0x3F, 2, _T("SWI3"),  INH    },
470         { 0x83, 4, _T("CMPU"),  IMM    },
471         { 0x8C, 4, _T("CMPS"),  IMM    },
472         { 0x93, 3, _T("CMPU"),  DIR    },
473         { 0x9C, 3, _T("CMPS"),  DIR    },
474         { 0xA3, 3, _T("CMPU"),  IND    },
475         { 0xAC, 3, _T("CMPS"),  IND    },
476         { 0xB3, 4, _T("CMPU"),  EXT    },
477         { 0xBC, 4, _T("CMPS"),  EXT    }
478 };
479
480 static const opcodeinfo *const m6809_pgpointers[3] =
481 {
482         m6809_pg0opcodes, m6809_pg1opcodes, m6809_pg2opcodes
483 };
484
485 static const int m6809_numops[3] =
486 {
487         array_length(m6809_pg0opcodes),
488         array_length(m6809_pg1opcodes),
489         array_length(m6809_pg2opcodes)
490 };
491 #endif /* USE_DEBUGGER */
492
493 uint32_t MC6809::cpu_disassemble_m6809(_TCHAR *buffer, uint32_t pc, const uint8_t *oprom, const uint8_t *opram)
494 {
495 #ifdef USE_DEBUGGER
496         uint8_t opcode, mode, pb, pbm, reg;
497         const uint8_t *operandarray;
498         unsigned int ea;//, flags;
499         int numoperands, offset;
500         int i, p = 0, page = 0;
501         bool opcode_found = false;
502         bool indirect;
503         const _TCHAR *name = NULL;
504
505         do {
506                 opcode = oprom[p++];
507
508                 for (i = 0; i < m6809_numops[page]; i++)
509                         if (m6809_pgpointers[page][i].opcode == opcode)
510                                 break;
511
512                 if (i < m6809_numops[page])
513                         opcode_found = true;
514                 else
515                 {
516                         _stprintf(buffer, _T("Illegal Opcode %02X"), opcode);
517                         return p;
518                 }
519
520                 if (m6809_pgpointers[page][i].mode >= PG1)
521                 {
522                         page = m6809_pgpointers[page][i].mode - PG1 + 1;
523                         opcode_found = false;
524                 }
525         } while (!opcode_found);
526
527         if (page == 0)
528                 numoperands = m6809_pgpointers[page][i].length - 1;
529         else
530                 numoperands = m6809_pgpointers[page][i].length - 2;
531
532         operandarray = &opram[p];
533         p += numoperands;
534         pc += p;
535         mode = m6809_pgpointers[page][i].mode;
536 //      flags = m6809_pgpointers[page][i].flags;
537
538         buffer += _stprintf(buffer, _T("%-6s"), m6809_pgpointers[page][i].name);
539
540         switch (mode)
541         {
542         case INH:
543                 switch (opcode)
544                 {
545                 case 0x34:  // PSHS
546                 case 0x36:  // PSHU
547                         pb = operandarray[0];
548                         if (pb & 0x80)
549                                 buffer += _stprintf(buffer, _T("PC"));
550                         if (pb & 0x40)
551                                 buffer += _stprintf(buffer, _T("%s%s"), (pb&0x80)?_T(","):_T(""), (opcode==0x34)?"U":"S");
552                         if (pb & 0x20)
553                                 buffer += _stprintf(buffer, _T("%sY"),  (pb&0xc0)?_T(","):_T(""));
554                         if (pb & 0x10)
555                                 buffer += _stprintf(buffer, _T("%sX"),  (pb&0xe0)?_T(","):_T(""));
556                         if (pb & 0x08)
557                                 buffer += _stprintf(buffer, _T("%sDP"), (pb&0xf0)?_T(","):_T(""));
558                         if (pb & 0x04)
559                                 buffer += _stprintf(buffer, _T("%sB"),  (pb&0xf8)?_T(","):_T(""));
560                         if (pb & 0x02)
561                                 buffer += _stprintf(buffer, _T("%sA"),  (pb&0xfc)?_T(","):_T(""));
562                         if (pb & 0x01)
563                                 buffer += _stprintf(buffer, _T("%sCC"), (pb&0xfe)?_T(","):_T(""));
564                         break;
565                 case 0x35:  // PULS
566                 case 0x37:  // PULU
567                         pb = operandarray[0];
568                         if (pb & 0x01)
569                                 buffer += _stprintf(buffer, _T("CC"));
570                         if (pb & 0x02)
571                                 buffer += _stprintf(buffer, _T("%sA"),  (pb&0x01)?_T(","):_T(""));
572                         if (pb & 0x04)
573                                 buffer += _stprintf(buffer, _T("%sB"),  (pb&0x03)?_T(","):_T(""));
574                         if (pb & 0x08)
575                                 buffer += _stprintf(buffer, _T("%sDP"), (pb&0x07)?_T(","):_T(""));
576                         if (pb & 0x10)
577                                 buffer += _stprintf(buffer, _T("%sX"),  (pb&0x0f)?_T(","):_T(""));
578                         if (pb & 0x20)
579                                 buffer += _stprintf(buffer, _T("%sY"),  (pb&0x1f)?_T(","):_T(""));
580                         if (pb & 0x40)
581                                 buffer += _stprintf(buffer, _T("%s%s"), (pb&0x3f)?_T(","):_T(""), (opcode==0x35)?_T("U"):_T("S"));
582                         if (pb & 0x80)
583                                 buffer += _stprintf(buffer, _T("%sPC ; (PUL? PC=RTS)"), (pb&0x7f)?_T(","):_T(""));
584                         break;
585                 default:
586                         // No operands
587                         break;
588                 }
589                 break;
590
591         case DIR:
592                 ea = operandarray[0];
593                 buffer += _stprintf(buffer, _T("$%02X"), ea);
594                 break;
595
596         case REL:
597                 offset = (int8_t)operandarray[0];
598                 buffer += _stprintf(buffer, _T("%s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04X"), (pc + offset) & 0xffff));
599                 break;
600
601         case LREL:
602                 offset = (int16_t)((operandarray[0] << 8) + operandarray[1]);
603                 buffer += _stprintf(buffer, _T("%s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04X"), (pc + offset) & 0xffff));
604                 break;
605
606         case EXT:
607                 ea = (operandarray[0] << 8) + operandarray[1];
608                 buffer += _stprintf(buffer, _T("%s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04X"), ea));
609                 break;
610
611         case IND:
612                 pb = operandarray[0];
613                 reg = (pb >> 5) & 3;
614                 pbm = pb & 0x8f;
615                 indirect = ((pb & 0x90) == 0x90 )? true : false;
616
617                 // open brackets if indirect
618                 if (indirect && pbm != 0x80 && pbm != 0x82)
619                         buffer += _stprintf(buffer, _T("["));
620
621                 switch (pbm)
622                 {
623                 case 0x80:  // ,R+
624                         if (indirect)
625                                 _tcscpy(buffer, _T("Illegal Postbyte"));
626                         else
627                                 buffer += _stprintf(buffer, _T(",%s+"), m6809_regs[reg]);
628                         break;
629
630                 case 0x81:  // ,R++
631                         buffer += _stprintf(buffer, _T(",%s++"), m6809_regs[reg]);
632                         break;
633
634                 case 0x82:  // ,-R
635                   //if (indirect)
636                   //    _tcscpy(buffer, _T("Illegal Postbyte"));
637                   //    else
638                                 buffer += _stprintf(buffer, _T(",-%s"), m6809_regs[reg]);
639                         break;
640
641                 case 0x83:  // ,--R
642                         buffer += _stprintf(buffer, _T(",--%s"), m6809_regs[reg]);
643                         break;
644
645                 case 0x84:  // ,R
646                         buffer += _stprintf(buffer, _T(",%s"), m6809_regs[reg]);
647                         break;
648
649                 case 0x85:  // (+/- B),R
650                         buffer += _stprintf(buffer, _T("B,%s"), m6809_regs[reg]);
651                         break;
652
653                 case 0x86:  // (+/- A),R
654                         buffer += _stprintf(buffer, _T("A,%s"), m6809_regs[reg]);
655                         break;
656
657                 case 0x87:  // (+/- A),R // Also 0x*6.
658                         buffer += _stprintf(buffer, _T("A,%s"), m6809_regs[reg]);
659                         break;
660                         //case 0x87:
661                         //_tcscpy(buffer, _T("Illegal Postbyte"));
662                         //break;
663
664                 case 0x88:  // (+/- 7 bit offset),R
665                         offset = (int8_t)opram[p++];
666                         buffer += _stprintf(buffer, _T("%s"), (offset < 0) ? "-" : "");
667                         buffer += _stprintf(buffer, _T("$%02X,"), (offset < 0) ? -offset : offset);
668                         buffer += _stprintf(buffer, _T("%s"), m6809_regs[reg]);
669                         break;
670
671                 case 0x89:  // (+/- 15 bit offset),R
672                         offset = (int16_t)((opram[p+0] << 8) + opram[p+1]);
673                         p += 2;
674                         buffer += _stprintf(buffer, _T("%s"), (offset < 0) ? "-" : "");
675                         buffer += _stprintf(buffer, _T("$%04X,"), (offset < 0) ? -offset : offset);
676                         buffer += _stprintf(buffer, _T("%s"), m6809_regs[reg]);
677                         break;
678
679                 case 0x8a:
680                         _tcscpy(buffer, _T("Illegal Postbyte"));
681                         break;
682
683                 case 0x8b:  // (+/- D),R
684                         buffer += _stprintf(buffer, _T("D,%s"), m6809_regs[reg]);
685                         break;
686
687                 case 0x8c:  // (+/- 7 bit offset),PC
688                         offset = (int8_t)opram[p++];
689                         if((name = get_symbol(d_debugger->first_symbol, (p - 1 + offset) & 0xffff)) != NULL) {
690                                 buffer += _stprintf(buffer, _T("%s,PCR"), name);
691                         } else {
692                                 buffer += _stprintf(buffer, _T("%s"), (offset < 0) ? "-" : "");
693                                 buffer += _stprintf(buffer, _T("$%02X,PC"), (offset < 0) ? -offset : offset);
694                         }
695                         break;
696
697                 case 0x8d:  // (+/- 15 bit offset),PC
698                         offset = (int16_t)((opram[p+0] << 8) + opram[p+1]);
699                         p += 2;
700                         if((name = get_symbol(d_debugger->first_symbol, (p - 2 + offset) & 0xffff)) != NULL) {
701                                 buffer += _stprintf(buffer, _T("%s,PCR"), name);
702                         } else {
703                                 buffer += _stprintf(buffer, _T("%s"), (offset < 0) ? "-" : "");
704                                 buffer += _stprintf(buffer, _T("$%04X,PC"), (offset < 0) ? -offset : offset);
705                         }
706                         break;
707
708                 case 0x8e: // $FFFFF
709                   //_tcscpy(buffer, _T("Illegal Postbyte"));
710                         offset = (int16_t)0xffff;
711                         //p += 2;
712                         buffer += _stprintf(buffer, _T("$%04X"), offset);
713                         break;
714
715                 case 0x8f:  // address
716                         ea = (uint16_t)((opram[p+0] << 8) + opram[p+1]);
717                         p += 2;
718                         buffer += _stprintf(buffer, _T("%s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04X"), ea));
719                         break;
720
721                 default:    // (+/- 4 bit offset),R
722                         offset = pb & 0x1f;
723                         if (offset > 15)
724                                 offset = offset - 32;
725                         buffer += _stprintf(buffer, _T("%s"), (offset < 0) ? "-" : "");
726                         buffer += _stprintf(buffer, _T("$%X,"), (offset < 0) ? -offset : offset);
727                         buffer += _stprintf(buffer, _T("%s"), m6809_regs[reg]);
728                         break;
729                 }
730
731                 // close brackets if indirect
732                 if (indirect && pbm != 0x80 && pbm != 0x82)
733                         buffer += _stprintf(buffer, _T("]"));
734                 break;
735
736         case IMM:
737                 if (numoperands == 2)
738                 {
739                         ea = (operandarray[0] << 8) + operandarray[1];
740                         buffer += _stprintf(buffer, _T("#%s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04X"), ea));
741                 }
742                 else
743                 if (numoperands == 1)
744                 {
745                         ea = operandarray[0];
746                         buffer += _stprintf(buffer, _T("#$%02X"), ea);
747                 }
748                 break;
749
750         case IMM_RR:
751                 pb = operandarray[0];
752                 buffer += _stprintf(buffer, _T("%s,%s"), m6809_regs_te[(pb >> 4) & 0xf], m6809_regs_te[pb & 0xf]);
753                 break;
754         }
755
756         return p;
757 #else
758         return 0;
759 #endif
760 }
761
762 int MC6809::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
763 {
764         if(__USE_DEBUGGER) {
765                 _TCHAR buffer_tmp[1024]; // enough ???
766                 uint8_t ops[4];
767                 for(int i = 0; i < 4; i++) {
768                         ops[i] = d_mem_stored->read_data8(pc + i);
769                 }
770                 int length = cpu_disassemble_m6809(buffer_tmp, pc, ops, ops);
771                 my_tcscpy_s(buffer, buffer_len, buffer_tmp);
772                 return length;
773         }
774         return 0;
775 }
776
777