OSDN Git Service

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