~ubuntu-branches/debian/squeeze/stella/squeeze

« back to all changes in this revision

Viewing changes to src/debugger/DiStella.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Stephen Kitt
  • Date: 2010-07-12 23:49:36 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20100712234936-juawrr3etzhr2qpv
Tags: 3.1.2-1
* New maintainer (closes: #532039).
* New upstream version (closes: #461121):
  - includes launcher (closes: #396058).
* Fix the reference to the X Window System in the description (closes:
  #411815).
* Move to main, DFSG-free ROMs are available (see README.Debian).
* Enhance the package description.
* Drop the libslang2-dev dependency (closes: #560274).
* Remove the Encoding entry from stella.desktop.
* Avoid ignoring errors when cleaning.
* Add ${misc:Depends} to the package dependencies.
* Provide a doc-base file to install the documentation using doc-base.
* Switch to debhelper 7 with a simplified rules file.
* Use autotools-dev to provide updated configuration files.
* Update to Standards-Version 3.9.0:
  - Move to menu section Applications/Emulators.
  - Move the homepage declaration.
* Re-write the manpage.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//============================================================================
 
2
//
 
3
//   SSSS    tt          lll  lll       
 
4
//  SS  SS   tt           ll   ll        
 
5
//  SS     tttttt  eeee   ll   ll   aaaa 
 
6
//   SSSS    tt   ee  ee  ll   ll      aa
 
7
//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
 
8
//  SS  SS   tt   ee      ll   ll  aa  aa
 
9
//   SSSS     ttt  eeeee llll llll  aaaaa
 
10
//
 
11
// Copyright (c) 1995-2010 by Bradford W. Mott, Stephen Anthony
 
12
// and the Stella Team
 
13
//
 
14
// See the file "License.txt" for information on usage and redistribution of
 
15
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
 
16
//
 
17
// $Id: DiStella.cxx 2002 2010-04-10 21:57:49Z stephena $
 
18
//============================================================================
 
19
 
 
20
#include "bspf.hxx"
 
21
#include "Debugger.hxx"
 
22
#include "DiStella.hxx"
 
23
 
 
24
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
25
DiStella::DiStella(CartDebug::DisassemblyList& list, uInt16 start,
 
26
                   bool resolvedata)
 
27
  : myList(list)
 
28
{
 
29
  while(!myAddressQueue.empty())
 
30
    myAddressQueue.pop();
 
31
 
 
32
  myAppData.start  = 0x0000;
 
33
  myAppData.end    = 0x0FFF;
 
34
  myAppData.length = 4096;
 
35
 
 
36
  memset(labels, 0, 0x1000);
 
37
 
 
38
  /*============================================
 
39
    The offset is the address where the code segment
 
40
    starts.  For a 4K game, it is usually 0xf000,
 
41
    which would then have the code data end at 0xffff,
 
42
    but that is not necessarily the case.  Because the
 
43
    Atari 2600 only has 13 address lines, it's possible
 
44
    that the "code" can be considered to start in a lot
 
45
    of different places.  So, we use the start
 
46
    address as a reference to determine where the
 
47
    offset is, logically-anded to produce an offset
 
48
    that is a multiple of 4K.
 
49
 
 
50
    Example:
 
51
      Start address = $D973, so therefore
 
52
      Offset to code = $D000
 
53
      Code range = $D000-$DFFF
 
54
  =============================================*/
 
55
  myOffset = (start - (start % 0x1000));
 
56
 
 
57
  myAddressQueue.push(start);
 
58
 
 
59
  if(resolvedata)
 
60
  {
 
61
    while(!myAddressQueue.empty())
 
62
    {
 
63
      myPC = myAddressQueue.front();
 
64
      myPCBeg = myPC;
 
65
      myAddressQueue.pop();
 
66
      disasm(myPC, 1);
 
67
      for (uInt32 k = myPCBeg; k <= myPCEnd; k++)
 
68
        mark(k, REACHABLE);
 
69
    }
 
70
    
 
71
    for (int k = 0; k <= myAppData.end; k++)
 
72
    {
 
73
      if (!check_bit(labels[k], REACHABLE))
 
74
        mark(k+myOffset, DATA);
 
75
    }
 
76
  }
 
77
 
 
78
  // Second pass
 
79
  disasm(myOffset, 2);
 
80
 
 
81
  // Third pass
 
82
  disasm(myOffset, 3);
 
83
}
 
84
 
 
85
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
86
DiStella::~DiStella()
 
87
{
 
88
}
 
89
 
 
90
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
91
void DiStella::disasm(uInt32 distart, int pass)
 
92
{
 
93
#define HEX4 uppercase << hex << setw(4) << setfill('0')
 
94
#define HEX2 uppercase << hex << setw(2) << setfill('0')
 
95
 
 
96
  uInt8 op, d1, opsrc;
 
97
  uInt16 ad;
 
98
  short amode;
 
99
  int bytes=0, labfound=0, addbranch=0;
 
100
  stringstream nextline, nextlinebytes;
 
101
  myDisasmBuf.str("");
 
102
 
 
103
  /* pc=myAppData.start; */
 
104
  myPC = distart - myOffset;
 
105
  while(myPC <= myAppData.end)
 
106
  {
 
107
    if(check_bit(labels[myPC], GFX))
 
108
      /* && !check_bit(labels[myPC], REACHABLE))*/
 
109
    {
 
110
      if (pass == 2)
 
111
        mark(myPC+myOffset,VALID_ENTRY);
 
112
      else if (pass == 3)
 
113
      {
 
114
        if (check_bit(labels[myPC],REFERENCED))
 
115
          myDisasmBuf << HEX4 << myPC+myOffset << "'L'" << HEX4 << myPC+myOffset << "'";
 
116
        else
 
117
          myDisasmBuf << HEX4 << myPC+myOffset << "'     '";
 
118
 
 
119
        myDisasmBuf << ".byte $" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset) << " ; ";
 
120
        showgfx(Debugger::debugger().peek(myPC+myOffset));
 
121
        myDisasmBuf << " $" << HEX4 << myPC+myOffset;
 
122
        addEntry();
 
123
      }
 
124
      myPC++;
 
125
    }
 
126
    else if (check_bit(labels[myPC], DATA) && !check_bit(labels[myPC], GFX))
 
127
        /* && !check_bit(labels[myPC],REACHABLE)) {  */
 
128
    {
 
129
      mark(myPC+myOffset, VALID_ENTRY);
 
130
      if (pass == 3)
 
131
      {
 
132
        bytes = 1;
 
133
        myDisasmBuf << HEX4 << myPC+myOffset << "'L" << HEX4 << myPC+myOffset << "'.byte "
 
134
              << "$" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset);
 
135
      }
 
136
      myPC++;
 
137
 
 
138
      while (check_bit(labels[myPC], DATA) && !check_bit(labels[myPC], REFERENCED)
 
139
             && !check_bit(labels[myPC], GFX) && pass == 3 && myPC <= myAppData.end)
 
140
      {
 
141
        if (pass == 3)
 
142
        {
 
143
          bytes++;
 
144
          if (bytes == 17)
 
145
          {
 
146
            addEntry();
 
147
            myDisasmBuf << "    '     '.byte $" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset);
 
148
            bytes = 1;
 
149
          }
 
150
          else
 
151
            myDisasmBuf << ",$" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset);
 
152
        }
 
153
        myPC++;
 
154
      }
 
155
 
 
156
      if (pass == 3)
 
157
      {
 
158
        addEntry();
 
159
        myDisasmBuf << "    '     ' ";
 
160
        addEntry();
 
161
      }
 
162
    }
 
163
    else
 
164
    {
 
165
      op = Debugger::debugger().peek(myPC+myOffset);
 
166
      /* version 2.1 bug fix */
 
167
      if (pass == 2)
 
168
        mark(myPC+myOffset, VALID_ENTRY);
 
169
      else if (pass == 3)
 
170
      {
 
171
        if (check_bit(labels[myPC], REFERENCED))
 
172
          myDisasmBuf << HEX4 << myPC+myOffset << "'L" << HEX4 << myPC+myOffset << "'";
 
173
        else
 
174
          myDisasmBuf << HEX4 << myPC+myOffset << "'     '";
 
175
      }
 
176
 
 
177
      amode = ourLookup[op].addr_mode;
 
178
      myPC++;
 
179
 
 
180
      if (ourLookup[op].mnemonic[0] == '.')
 
181
      {
 
182
        amode = IMPLIED;
 
183
        if (pass == 3)
 
184
          nextline << ".byte $" << HEX2 << (int)op << " ;";
 
185
      }
 
186
 
 
187
      if (pass == 1)
 
188
      {
 
189
        opsrc = ourLookup[op].source;
 
190
        /* M_REL covers BPL, BMI, BVC, BVS, BCC, BCS, BNE, BEQ
 
191
           M_ADDR = JMP $NNNN, JSR $NNNN
 
192
           M_AIND = JMP Abs, Indirect */
 
193
        if ((opsrc == M_REL) || (opsrc == M_ADDR) || (opsrc == M_AIND))
 
194
          addbranch = 1;
 
195
        else
 
196
          addbranch = 0;
 
197
      }
 
198
      else if (pass == 3)
 
199
      {
 
200
        nextline << ourLookup[op].mnemonic;
 
201
        nextlinebytes << HEX2 << (int)op << " ";
 
202
      }
 
203
 
 
204
      if (myPC >= myAppData.end)
 
205
      {
 
206
        switch(amode)
 
207
        {
 
208
          case ABSOLUTE:
 
209
          case ABSOLUTE_X:
 
210
          case ABSOLUTE_Y:
 
211
          case INDIRECT_X:
 
212
          case INDIRECT_Y:
 
213
          case ABS_INDIRECT:
 
214
          {
 
215
            if (pass == 3)
 
216
            {
 
217
              /* Line information is already printed; append .byte since last instruction will
 
218
                 put recompilable object larger that original binary file */
 
219
              myDisasmBuf << ".byte $" << HEX2 << (int)op;
 
220
              addEntry();
 
221
 
 
222
              if (myPC == myAppData.end)
 
223
              {
 
224
                if (check_bit(labels[myPC],REFERENCED))
 
225
                  myDisasmBuf << HEX4 << myPC+myOffset << "'L" << HEX4 << myPC+myOffset << "'";
 
226
                else
 
227
                  myDisasmBuf << HEX4 << myPC+myOffset << "'     '";
 
228
 
 
229
                op = Debugger::debugger().peek(myPC+myOffset);  myPC++;
 
230
                myDisasmBuf << ".byte $" << HEX2 << (int)op;
 
231
                addEntry();
 
232
              }
 
233
            }
 
234
            myPCEnd = myAppData.end + myOffset;
 
235
            return;
 
236
          }
 
237
 
 
238
          case ZERO_PAGE:
 
239
          case IMMEDIATE:
 
240
          case ZERO_PAGE_X:
 
241
          case ZERO_PAGE_Y:
 
242
          case RELATIVE:
 
243
          {
 
244
            if (myPC > myAppData.end)
 
245
            {
 
246
              if (pass == 3)
 
247
              {
 
248
                /* Line information is already printed, but we can remove the
 
249
                   Instruction (i.e. BMI) by simply clearing the buffer to print */
 
250
                myDisasmBuf << ".byte $" << HEX2 << (int)op;
 
251
                addEntry();
 
252
                nextline.str("");
 
253
                nextlinebytes.str("");
 
254
              }
 
255
              myPC++;
 
256
              myPCEnd = myAppData.end + myOffset;
 
257
              return;
 
258
            }
 
259
          }
 
260
 
 
261
          default:
 
262
            break;
 
263
        }
 
264
      }
 
265
 
 
266
      /* Version 2.1 added the extensions to mnemonics */
 
267
      switch(amode)
 
268
      {
 
269
    #if 0
 
270
        case IMPLIED:
 
271
        {
 
272
          if (op == 0x40 || op == 0x60)
 
273
            if (pass == 3)
 
274
              nextline << "\n";
 
275
          break;
 
276
        }
 
277
    #endif
 
278
        case ACCUMULATOR:
 
279
        {
 
280
          if (pass == 3)
 
281
            nextline << "    A";
 
282
          break;
 
283
        }
 
284
 
 
285
        case ABSOLUTE:
 
286
        {
 
287
          ad = Debugger::debugger().dpeek(myPC+myOffset);  myPC+=2;
 
288
          labfound = mark(ad, REFERENCED);
 
289
          if (pass == 1)
 
290
          {
 
291
            if ((addbranch) && !check_bit(labels[ad & myAppData.end], REACHABLE))
 
292
            {
 
293
              if (ad > 0xfff)
 
294
                myAddressQueue.push((ad & myAppData.end) + myOffset);
 
295
 
 
296
              mark(ad, REACHABLE);
 
297
            }
 
298
          }
 
299
          else if (pass == 3)
 
300
          {
 
301
            if (ad < 0x100)
 
302
              nextline << ".w  ";
 
303
            else
 
304
              nextline << "    ";
 
305
 
 
306
            if (labfound == 1)
 
307
            {
 
308
              nextline << "L" << HEX4 << ad;
 
309
              nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
 
310
            }
 
311
            else if (labfound == 3)
 
312
            {
 
313
              nextline << CartDebug::ourIOMnemonic[ad-0x280];
 
314
              nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
 
315
            }
 
316
            else if (labfound == 4)
 
317
            {
 
318
              int tmp = (ad & myAppData.end)+myOffset;
 
319
              nextline << "L" << HEX4 << tmp;
 
320
              nextlinebytes << HEX2 << (int)(tmp&0xff) << " " << HEX2 << (int)(tmp>>8);
 
321
            }
 
322
            else
 
323
            {
 
324
              nextline << "$" << HEX4 << ad;
 
325
              nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
 
326
            }
 
327
          }
 
328
          break;
 
329
        }
 
330
 
 
331
        case ZERO_PAGE:
 
332
        {
 
333
          d1 = Debugger::debugger().peek(myPC+myOffset);  myPC++;
 
334
          labfound = mark(d1, REFERENCED);
 
335
          if (pass == 3)
 
336
          {
 
337
            if (labfound == 2)
 
338
              nextline << "    " << (ourLookup[op].rw_mode == READ ?
 
339
                CartDebug::ourTIAMnemonicR[d1&0x0f] : CartDebug::ourTIAMnemonicW[d1&0x3f]);
 
340
            else
 
341
              nextline << "    $" << HEX2 << (int)d1;
 
342
 
 
343
            nextlinebytes << HEX2 << (int)d1;
 
344
          }
 
345
          break;
 
346
        }
 
347
 
 
348
        case IMMEDIATE:
 
349
        {
 
350
          d1 = Debugger::debugger().peek(myPC+myOffset);  myPC++;
 
351
          if (pass == 3)
 
352
          {
 
353
            nextline << "    #$" << HEX2 << (int)d1 << " ";
 
354
            nextlinebytes << HEX2 << (int)d1;
 
355
          }
 
356
          break;
 
357
        }
 
358
 
 
359
        case ABSOLUTE_X:
 
360
        {
 
361
          ad = Debugger::debugger().dpeek(myPC+myOffset);  myPC+=2;
 
362
          labfound = mark(ad, REFERENCED);
 
363
          if (pass == 3)
 
364
          {
 
365
            if (ad < 0x100)
 
366
              nextline << ".wx ";
 
367
            else
 
368
              nextline << "    ";
 
369
 
 
370
            if (labfound == 1)
 
371
            {
 
372
              nextline << "L" << HEX4 << ad << ",X";
 
373
              nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
 
374
            }
 
375
            else if (labfound == 3)
 
376
            {
 
377
              nextline << CartDebug::ourIOMnemonic[ad-0x280] << ",X";
 
378
              nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
 
379
            }
 
380
            else if (labfound == 4)
 
381
            {
 
382
              int tmp = (ad & myAppData.end)+myOffset;
 
383
              nextline << "L" << HEX4 << tmp << ",X";
 
384
              nextlinebytes << HEX2 << (int)(tmp&0xff) << " " << HEX2 << (int)(tmp>>8);
 
385
            }
 
386
            else
 
387
            {
 
388
              nextline << "$" << HEX4 << ad << ",X";
 
389
              nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
 
390
            }
 
391
          }
 
392
          break;
 
393
        }
 
394
 
 
395
        case ABSOLUTE_Y:
 
396
        {
 
397
          ad = Debugger::debugger().dpeek(myPC+myOffset);  myPC+=2;
 
398
          labfound = mark(ad, REFERENCED);
 
399
          if (pass == 3)
 
400
          {
 
401
            if (ad < 0x100)
 
402
              nextline << ".wy ";
 
403
            else
 
404
              nextline << "    ";
 
405
 
 
406
            if (labfound == 1)
 
407
            {
 
408
              nextline << "L" << HEX4 << ad << ",Y";
 
409
              nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
 
410
            }
 
411
            else if (labfound == 3)
 
412
            {
 
413
              nextline << CartDebug::ourIOMnemonic[ad-0x280] << ",Y";
 
414
              nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
 
415
            }
 
416
            else if (labfound == 4)
 
417
            {
 
418
              int tmp = (ad & myAppData.end)+myOffset;
 
419
              nextline << "L" << HEX4 << tmp << ",Y";
 
420
              nextlinebytes << HEX2 << (int)(tmp&0xff) << " " << HEX2 << (int)(tmp>>8);
 
421
            }
 
422
            else
 
423
            {
 
424
              nextline << "$" << HEX4 << ad << ",Y";
 
425
              nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
 
426
            }
 
427
          }
 
428
          break;
 
429
        }
 
430
 
 
431
        case INDIRECT_X:
 
432
        {
 
433
          d1 = Debugger::debugger().peek(myPC+myOffset);  myPC++;
 
434
          if (pass == 3)
 
435
          {
 
436
            nextline << "    ($" << HEX2 << (int)d1 << ",X)";
 
437
            nextlinebytes << HEX2 << (int)d1;
 
438
          }
 
439
          break;
 
440
        }
 
441
 
 
442
        case INDIRECT_Y:
 
443
        {
 
444
          d1 = Debugger::debugger().peek(myPC+myOffset);  myPC++;
 
445
          if (pass == 3)
 
446
          {
 
447
            nextline << "    ($" << HEX2 << (int)d1 << "),Y";
 
448
            nextlinebytes << HEX2 << (int)d1;
 
449
          }
 
450
          break;
 
451
        }
 
452
 
 
453
        case ZERO_PAGE_X:
 
454
        {
 
455
          d1 = Debugger::debugger().peek(myPC+myOffset);  myPC++;
 
456
          labfound = mark(d1, REFERENCED);
 
457
          if (pass == 3)
 
458
          {
 
459
            if (labfound == 2)
 
460
              nextline << "    " << (ourLookup[op].rw_mode == READ ?
 
461
                CartDebug::ourTIAMnemonicR[d1&0x0f] :
 
462
                CartDebug::ourTIAMnemonicW[d1&0x3f])  << ",X";
 
463
            else
 
464
              nextline << "    $" << HEX2 << (int)d1 << ",X";
 
465
          }
 
466
          nextlinebytes << HEX2 << (int)d1;
 
467
          break;
 
468
        }
 
469
 
 
470
        case ZERO_PAGE_Y:
 
471
        {
 
472
          d1 = Debugger::debugger().peek(myPC+myOffset);  myPC++;
 
473
          labfound = mark(d1,REFERENCED);
 
474
          if (pass == 3)
 
475
          {
 
476
            if (labfound == 2)
 
477
              nextline << "    " << (ourLookup[op].rw_mode == READ ?
 
478
                CartDebug::ourTIAMnemonicR[d1&0x0f] :
 
479
                CartDebug::ourTIAMnemonicW[d1&0x3f])  << ",Y";
 
480
            else
 
481
              nextline << "    $" << HEX2 << (int)d1 << ",Y";
 
482
          }
 
483
          nextlinebytes << HEX2 << (int)d1;
 
484
          break;
 
485
        }
 
486
 
 
487
        case RELATIVE:
 
488
        {
 
489
          // SA - 04-06-2010: there seemed to be a bug in distella,
 
490
          // where wraparound occurred on a 32-bit int, and subsequent
 
491
          // indexing into the labels array caused a crash
 
492
          d1 = Debugger::debugger().peek(myPC+myOffset);  myPC++;
 
493
          ad = ((myPC + (Int8)d1) & 0xfff) + myOffset;
 
494
 
 
495
          labfound = mark(ad+myOffset, REFERENCED);
 
496
          if (pass == 1)
 
497
          {
 
498
            if ((addbranch) && !check_bit(labels[ad-myOffset], REACHABLE))
 
499
            {
 
500
              myAddressQueue.push(ad);
 
501
              mark(ad, REACHABLE);
 
502
            }
 
503
          }
 
504
          else if (pass == 3)
 
505
          {
 
506
            if (labfound == 1)
 
507
              nextline << "    L" << HEX4 << ad;
 
508
            else
 
509
              nextline << "    $" << HEX4 << ad;
 
510
 
 
511
            nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
 
512
          }
 
513
          break;
 
514
        }
 
515
 
 
516
        case ABS_INDIRECT:
 
517
        {
 
518
          ad = Debugger::debugger().dpeek(myPC+myOffset);  myPC+=2;
 
519
          labfound = mark(ad, REFERENCED);
 
520
          if (pass == 3)
 
521
          {
 
522
            if (ad < 0x100)
 
523
              nextline << ".ind ";
 
524
            else
 
525
              nextline << "     ";
 
526
          }
 
527
          if (labfound == 1)
 
528
            nextline << "(L" << HEX4 << ad << ")";
 
529
          else if (labfound == 3)
 
530
            nextline << "(" << CartDebug::ourIOMnemonic[ad-0x280] << ")";
 
531
          else
 
532
            nextline << "($" << HEX4 << ad << ")";
 
533
 
 
534
          nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
 
535
          break;
 
536
        }
 
537
      } // end switch
 
538
 
 
539
      if (pass == 1)
 
540
      {
 
541
        if (!strcmp(ourLookup[op].mnemonic,"RTS") ||
 
542
            !strcmp(ourLookup[op].mnemonic,"JMP") ||
 
543
            /* !strcmp(ourLookup[op].mnemonic,"BRK") || */
 
544
            !strcmp(ourLookup[op].mnemonic,"RTI"))
 
545
        {
 
546
          myPCEnd = (myPC-1) + myOffset;
 
547
          return;
 
548
        }
 
549
      }
 
550
      else if (pass == 3)
 
551
      {
 
552
        myDisasmBuf << nextline.str();;
 
553
        uInt32 nextlinelen = nextline.str().length();
 
554
        if (nextlinelen <= 15)
 
555
        {
 
556
          /* Print spaces to align cycle count data */
 
557
          for (uInt32 charcnt=0;charcnt<15-nextlinelen;charcnt++)
 
558
            myDisasmBuf << " ";
 
559
        }
 
560
        myDisasmBuf << ";" << dec << (int)ourLookup[op].cycles << "'" << nextlinebytes.str();
 
561
        addEntry();
 
562
        if (op == 0x40 || op == 0x60)
 
563
        {
 
564
          myDisasmBuf << "    '     ' ";
 
565
          addEntry();
 
566
        }
 
567
 
 
568
        nextline.str("");
 
569
        nextlinebytes.str("");
 
570
      }
 
571
    }
 
572
  }  /* while loop */
 
573
 
 
574
  /* Just in case we are disassembling outside of the address range, force the myPCEnd to EOF */
 
575
  myPCEnd = myAppData.end + myOffset;
 
576
}
 
577
 
 
578
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
579
int DiStella::mark(uInt32 address, MarkType bit)
 
580
{
 
581
  /*-----------------------------------------------------------------------
 
582
    For any given offset and code range...
 
583
 
 
584
    If we're between the offset and the end of the code range, we mark
 
585
    the bit in the labels array for that data.  The labels array is an
 
586
    array of label info for each code address.  If this is the case,
 
587
    return "1", else...
 
588
 
 
589
    We sweep for hardware/system equates, which are valid addresses,
 
590
    outside the scope of the code/data range.  For these, we mark its
 
591
    corresponding hardware/system array element, and return "2" or "3"
 
592
    (depending on which system/hardware element was accessed), or "5"
 
593
    for zero-page RAM.  If this was not the case...
 
594
 
 
595
    Next we check if it is a code "mirror".  For the 2600, address ranges
 
596
    are limited with 13 bits, so other addresses can exist outside of the
 
597
    standard code/data range.  For these, we mark the element in the "labels"
 
598
    array that corresponds to the mirrored address, and return "4"
 
599
 
 
600
    If all else fails, it's not a valid address, so return 0.
 
601
 
 
602
    A quick example breakdown for a 2600 4K cart:
 
603
    ===========================================================
 
604
      $00-$3d =     system equates (WSYNC, etc...); mark the array's element
 
605
                    with the appropriate bit; return 2.
 
606
      $0080-$00FF = zero-page RAM; mark the array's element
 
607
                    with the appropriate bit; return 5.
 
608
      $0280-$0297 = system equates (INPT0, etc...); mark the array's element
 
609
                    with the appropriate bit; return 3.
 
610
      $1000-$1FFF = CODE/DATA, mark the code/data array for the mirrored address
 
611
                    with the appropriate bit; return 4.
 
612
      $3000-$3FFF = CODE/DATA, mark the code/data array for the mirrored address
 
613
                    with the appropriate bit; return 4.
 
614
      $5000-$5FFF = CODE/DATA, mark the code/data array for the mirrored address
 
615
                    with the appropriate bit; return 4.
 
616
      $7000-$7FFF = CODE/DATA, mark the code/data array for the mirrored address
 
617
                    with the appropriate bit; return 4.
 
618
      $9000-$9FFF = CODE/DATA, mark the code/data array for the mirrored address
 
619
                    with the appropriate bit; return 4.
 
620
      $B000-$BFFF = CODE/DATA, mark the code/data array for the mirrored address
 
621
                    with the appropriate bit; return 4.
 
622
      $D000-$DFFF = CODE/DATA, mark the code/data array for the mirrored address
 
623
                    with the appropriate bit; return 4.
 
624
      $F000-$FFFF = CODE/DATA, mark the code/data array for the address
 
625
                    with the appropriate bit; return 1.
 
626
      Anything else = invalid, return 0.
 
627
    ===========================================================
 
628
  -----------------------------------------------------------------------*/
 
629
 
 
630
  if (address >= myOffset && address <= myAppData.end + myOffset)
 
631
  {
 
632
    labels[address-myOffset] = labels[address-myOffset] | bit;
 
633
    return 1;
 
634
  }
 
635
  else if (address >= 0 && address <= 0x3f)
 
636
  {
 
637
    return 2;
 
638
  }
 
639
/* This isn't supported by the core code yet, so why waste time checking
 
640
  else if (address >= 0x80 && address <= 0xff)
 
641
  {
 
642
    return 5;
 
643
  }
 
644
*/
 
645
  else if (address >= 0x280 && address <= 0x297)
 
646
  {
 
647
    return 3;
 
648
  }
 
649
  else if (address > 0x1000)
 
650
  {
 
651
    /* 2K & 4K case */
 
652
    labels[address & myAppData.end] = labels[address & myAppData.end] | bit;
 
653
    return 4;
 
654
  }
 
655
  else
 
656
    return 0;
 
657
}
 
658
 
 
659
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
660
void DiStella::showgfx(uInt8 c)
 
661
{
 
662
  int i;
 
663
 
 
664
  myDisasmBuf << "|";
 
665
  for(i = 0;i < 8; i++)
 
666
  {
 
667
    if (c > 127)
 
668
      myDisasmBuf << "X";
 
669
    else
 
670
      myDisasmBuf << " ";
 
671
 
 
672
    c = c << 1;
 
673
  }
 
674
  myDisasmBuf << "|";
 
675
}
 
676
 
 
677
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
678
void DiStella::addEntry()
 
679
{
 
680
  const string& line = myDisasmBuf.str();
 
681
  CartDebug::DisassemblyTag tag;
 
682
 
 
683
  if(line[0] == ' ')
 
684
    tag.address = 0;
 
685
  else
 
686
    myDisasmBuf >> setw(4) >> hex >> tag.address;
 
687
 
 
688
  if(line[5] != ' ')
 
689
    tag.label = line.substr(5, 5);
 
690
 
 
691
  switch(line[11])
 
692
  {
 
693
    case ' ':
 
694
      tag.disasm = " ";
 
695
      break;
 
696
    case '.':
 
697
      tag.disasm = line.substr(11);
 
698
      break;
 
699
    default:
 
700
      tag.disasm = line.substr(11, 17);
 
701
      tag.bytes  = line.substr(29);
 
702
      break;
 
703
  }
 
704
  myList.push_back(tag);
 
705
 
 
706
  myDisasmBuf.str("");
 
707
}
 
708
 
 
709
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
710
const DiStella::Instruction_tag DiStella::ourLookup[256] = {
 
711
/****  Positive  ****/
 
712
 
 
713
  /* 00 */ { "BRK", IMPLIED,     M_NONE, NONE,  7 }, /* Pseudo Absolute */
 
714
  /* 01 */ { "ORA", INDIRECT_X,  M_INDX, READ,  6 }, /* (Indirect,X) */
 
715
  /* 02 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT */
 
716
  /* 03 */ { "slo", INDIRECT_X,  M_INDX, WRITE, 8 },
 
717
 
 
718
  /* 04 */ { "nop", ZERO_PAGE,   M_NONE, NONE,  3 },
 
719
  /* 05 */ { "ORA", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
720
  /* 06 */ { "ASL", ZERO_PAGE,   M_ZERO, WRITE, 5 }, /* Zeropage */
 
721
  /* 07 */ { "slo", ZERO_PAGE,   M_ZERO, WRITE, 5 },
 
722
 
 
723
  /* 08 */ { "PHP", IMPLIED,     M_SR,   NONE,  3 },
 
724
  /* 09 */ { "ORA", IMMEDIATE,   M_IMM,  READ,  2 }, /* Immediate */
 
725
  /* 0a */ { "ASL", ACCUMULATOR, M_AC,   WRITE, 2 }, /* Accumulator */
 
726
  /* 0b */ { "anc", IMMEDIATE,   M_ACIM, READ,  2 },
 
727
 
 
728
  /* 0c */ { "nop", ABSOLUTE,    M_NONE, NONE,  4 },
 
729
  /* 0d */ { "ORA", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
730
  /* 0e */ { "ASL", ABSOLUTE,    M_ABS,  WRITE, 6 }, /* Absolute */
 
731
  /* 0f */ { "slo", ABSOLUTE,    M_ABS,  WRITE, 6 },
 
732
 
 
733
  /* 10 */ { "BPL", RELATIVE,    M_REL,  READ,  2 },
 
734
  /* 11 */ { "ORA", INDIRECT_Y,  M_INDY, READ,  5 }, /* (Indirect),Y */
 
735
  /* 12 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT */
 
736
  /* 13 */ { "slo", INDIRECT_Y,  M_INDY, WRITE, 8 },
 
737
 
 
738
  /* 14 */ { "nop", ZERO_PAGE_X, M_NONE, NONE,  4 },
 
739
  /* 15 */ { "ORA", ZERO_PAGE_X, M_ZERX, READ,  4 }, /* Zeropage,X */
 
740
  /* 16 */ { "ASL", ZERO_PAGE_X, M_ZERX, WRITE, 6 }, /* Zeropage,X */
 
741
  /* 17 */ { "slo", ZERO_PAGE_X, M_ZERX, WRITE, 6 },
 
742
 
 
743
  /* 18 */ { "CLC", IMPLIED,     M_NONE, NONE,  2 },
 
744
  /* 19 */ { "ORA", ABSOLUTE_Y,  M_ABSY, READ,  4 }, /* Absolute,Y */
 
745
  /* 1a */ { "nop", IMPLIED,     M_NONE, NONE,  2 },
 
746
  /* 1b */ { "slo", ABSOLUTE_Y,  M_ABSY, WRITE, 7 },
 
747
 
 
748
  /* 1c */ { "nop", ABSOLUTE_X,  M_NONE, NONE,  4 },
 
749
  /* 1d */ { "ORA", ABSOLUTE_X,  M_ABSX, READ,  4 }, /* Absolute,X */
 
750
  /* 1e */ { "ASL", ABSOLUTE_X,  M_ABSX, WRITE, 7 }, /* Absolute,X */
 
751
  /* 1f */ { "slo", ABSOLUTE_X,  M_ABSX, WRITE, 7 },
 
752
 
 
753
  /* 20 */ { "JSR", ABSOLUTE,    M_ADDR, READ,  6 },
 
754
  /* 21 */ { "AND", INDIRECT_X,  M_INDX, READ,  6 }, /* (Indirect ,X) */
 
755
  /* 22 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT */
 
756
  /* 23 */ { "rla", INDIRECT_X,  M_INDX, WRITE, 8 },
 
757
 
 
758
  /* 24 */ { "BIT", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
759
  /* 25 */ { "AND", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
760
  /* 26 */ { "ROL", ZERO_PAGE,   M_ZERO, WRITE, 5 }, /* Zeropage */
 
761
  /* 27 */ { "rla", ZERO_PAGE,   M_ZERO, WRITE, 5 },
 
762
 
 
763
  /* 28 */ { "PLP", IMPLIED,     M_NONE, NONE,  4 },
 
764
  /* 29 */ { "AND", IMMEDIATE,   M_IMM,  READ,  2 }, /* Immediate */
 
765
  /* 2a */ { "ROL", ACCUMULATOR, M_AC,   WRITE, 2 }, /* Accumulator */
 
766
  /* 2b */ { "anc", IMMEDIATE,   M_ACIM, READ,  2 },
 
767
 
 
768
  /* 2c */ { "BIT", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
769
  /* 2d */ { "AND", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
770
  /* 2e */ { "ROL", ABSOLUTE,    M_ABS,  WRITE, 6 }, /* Absolute */
 
771
  /* 2f */ { "rla", ABSOLUTE,    M_ABS,  WRITE, 6 },
 
772
 
 
773
  /* 30 */ { "BMI", RELATIVE,    M_REL,  READ,  2 },
 
774
  /* 31 */ { "AND", INDIRECT_Y,  M_INDY, READ,  5 }, /* (Indirect),Y */
 
775
  /* 32 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT */
 
776
  /* 33 */ { "rla", INDIRECT_Y,  M_INDY, WRITE, 8 },
 
777
 
 
778
  /* 34 */ { "nop", ZERO_PAGE_X, M_NONE, NONE,  4 },
 
779
  /* 35 */ { "AND", ZERO_PAGE_X, M_ZERX, READ,  4 }, /* Zeropage,X */
 
780
  /* 36 */ { "ROL", ZERO_PAGE_X, M_ZERX, WRITE, 6 }, /* Zeropage,X */
 
781
  /* 37 */ { "rla", ZERO_PAGE_X, M_ZERX, WRITE, 6 },
 
782
 
 
783
  /* 38 */ { "SEC", IMPLIED,     M_NONE, NONE,  2 },
 
784
  /* 39 */ { "AND", ABSOLUTE_Y,  M_ABSY, READ,  4 }, /* Absolute,Y */
 
785
  /* 3a */ { "nop", IMPLIED,     M_NONE, NONE,  2 },
 
786
  /* 3b */ { "rla", ABSOLUTE_Y,  M_ABSY, WRITE, 7 },
 
787
 
 
788
  /* 3c */ { "nop", ABSOLUTE_X,  M_NONE, NONE,  4 },
 
789
  /* 3d */ { "AND", ABSOLUTE_X,  M_ABSX, READ,  4 }, /* Absolute,X */
 
790
  /* 3e */ { "ROL", ABSOLUTE_X,  M_ABSX, WRITE, 7 }, /* Absolute,X */
 
791
  /* 3f */ { "rla", ABSOLUTE_X,  M_ABSX, WRITE, 7 },
 
792
 
 
793
  /* 40 */ { "RTI", IMPLIED,     M_NONE, NONE,  6 },
 
794
  /* 41 */ { "EOR", INDIRECT_X,  M_INDX, READ,  6 }, /* (Indirect,X) */
 
795
  /* 42 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT */
 
796
  /* 43 */ { "sre", INDIRECT_X,  M_INDX, WRITE, 8 },
 
797
 
 
798
  /* 44 */ { "nop", ZERO_PAGE,   M_NONE, NONE,  3 },
 
799
  /* 45 */ { "EOR", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
800
  /* 46 */ { "LSR", ZERO_PAGE,   M_ZERO, WRITE, 5 }, /* Zeropage */
 
801
  /* 47 */ { "sre", ZERO_PAGE,   M_ZERO, WRITE, 5 },
 
802
 
 
803
  /* 48 */ { "PHA", IMPLIED,     M_AC,   NONE,  3 },
 
804
  /* 49 */ { "EOR", IMMEDIATE,   M_IMM,  READ,  2 }, /* Immediate */
 
805
  /* 4a */ { "LSR", ACCUMULATOR, M_AC,   WRITE, 2 }, /* Accumulator */
 
806
  /* 4b */ { "asr", IMMEDIATE,   M_ACIM, READ,  2 }, /* (AC & IMM) >>1 */
 
807
 
 
808
  /* 4c */ { "JMP", ABSOLUTE,    M_ADDR, READ,  3 }, /* Absolute */
 
809
  /* 4d */ { "EOR", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
810
  /* 4e */ { "LSR", ABSOLUTE,    M_ABS,  WRITE, 6 }, /* Absolute */
 
811
  /* 4f */ { "sre", ABSOLUTE,    M_ABS,  WRITE, 6 },
 
812
 
 
813
  /* 50 */ { "BVC", RELATIVE,    M_REL,  READ,  2 },
 
814
  /* 51 */ { "EOR", INDIRECT_Y,  M_INDY, READ,  5 }, /* (Indirect),Y */
 
815
  /* 52 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT */
 
816
  /* 53 */ { "sre", INDIRECT_Y,  M_INDY, WRITE, 8 },
 
817
 
 
818
  /* 54 */ { "nop", ZERO_PAGE_X, M_NONE, NONE,  4 },
 
819
  /* 55 */ { "EOR", ZERO_PAGE_X, M_ZERX, READ,  4 }, /* Zeropage,X */
 
820
  /* 56 */ { "LSR", ZERO_PAGE_X, M_ZERX, WRITE, 6 }, /* Zeropage,X */
 
821
  /* 57 */ { "sre", ZERO_PAGE_X, M_ZERX, WRITE, 6 },
 
822
 
 
823
  /* 58 */ { "CLI", IMPLIED,     M_NONE, NONE,  2 },
 
824
  /* 59 */ { "EOR", ABSOLUTE_Y,  M_ABSY, READ,  4 }, /* Absolute,Y */
 
825
  /* 5a */ { "nop", IMPLIED,     M_NONE, NONE,  2 },
 
826
  /* 5b */ { "sre", ABSOLUTE_Y,  M_ABSY, WRITE, 7 },
 
827
 
 
828
  /* 5c */ { "nop", ABSOLUTE_X,  M_NONE, NONE,  4 },
 
829
  /* 5d */ { "EOR", ABSOLUTE_X,  M_ABSX, READ,  4 }, /* Absolute,X */
 
830
  /* 5e */ { "LSR", ABSOLUTE_X,  M_ABSX, WRITE, 7 }, /* Absolute,X */
 
831
  /* 5f */ { "sre", ABSOLUTE_X,  M_ABSX, WRITE, 7 },
 
832
 
 
833
  /* 60 */ { "RTS", IMPLIED,     M_NONE, NONE,  6 },
 
834
  /* 61 */ { "ADC", INDIRECT_X,  M_INDX, READ,  6 }, /* (Indirect,X) */
 
835
  /* 62 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT */
 
836
  /* 63 */ { "rra", INDIRECT_X,  M_INDX, WRITE, 8 },
 
837
 
 
838
  /* 64 */ { "nop", ZERO_PAGE,   M_NONE, NONE,  3 },
 
839
  /* 65 */ { "ADC", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
840
  /* 66 */ { "ROR", ZERO_PAGE,   M_ZERO, WRITE, 5 }, /* Zeropage */
 
841
  /* 67 */ { "rra", ZERO_PAGE,   M_ZERO, WRITE, 5 },
 
842
 
 
843
  /* 68 */ { "PLA", IMPLIED,     M_NONE, NONE,  4 },
 
844
  /* 69 */ { "ADC", IMMEDIATE,   M_IMM,  READ,  2 }, /* Immediate */
 
845
  /* 6a */ { "ROR", ACCUMULATOR, M_AC,   WRITE, 2 }, /* Accumulator */
 
846
  /* 6b */ { "arr", IMMEDIATE,   M_ACIM, READ,  2 }, /* ARR isn't typo */
 
847
 
 
848
  /* 6c */ { "JMP", ABS_INDIRECT,M_AIND, READ,  5 }, /* Indirect */
 
849
  /* 6d */ { "ADC", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
850
  /* 6e */ { "ROR", ABSOLUTE,    M_ABS,  WRITE, 6 }, /* Absolute */
 
851
  /* 6f */ { "rra", ABSOLUTE,    M_ABS,  WRITE, 6 },
 
852
 
 
853
  /* 70 */ { "BVS", RELATIVE,    M_REL,  READ,  2 },
 
854
  /* 71 */ { "ADC", INDIRECT_Y,  M_INDY, READ,  5 }, /* (Indirect),Y */
 
855
  /* 72 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT relative? */
 
856
  /* 73 */ { "rra", INDIRECT_Y,  M_INDY, WRITE, 8 },
 
857
 
 
858
  /* 74 */ { "nop", ZERO_PAGE_X, M_NONE, NONE,  4 },
 
859
  /* 75 */ { "ADC", ZERO_PAGE_X, M_ZERX, READ,  4 }, /* Zeropage,X */
 
860
  /* 76 */ { "ROR", ZERO_PAGE_X, M_ZERX, WRITE, 6 }, /* Zeropage,X */
 
861
  /* 77 */ { "rra", ZERO_PAGE_X, M_ZERX, WRITE, 6 },
 
862
 
 
863
  /* 78 */ { "SEI", IMPLIED,     M_NONE, NONE,  2 },
 
864
  /* 79 */ { "ADC", ABSOLUTE_Y,  M_ABSY, READ,  4 }, /* Absolute,Y */
 
865
  /* 7a */ { "nop", IMPLIED,     M_NONE, NONE,  2 },
 
866
  /* 7b */ { "rra", ABSOLUTE_Y,  M_ABSY, WRITE, 7 },
 
867
 
 
868
  /* 7c */ { "nop", ABSOLUTE_X,  M_NONE, NONE,  4 },
 
869
  /* 7d */ { "ADC", ABSOLUTE_X,  M_ABSX, READ,  4 },  /* Absolute,X */
 
870
  /* 7e */ { "ROR", ABSOLUTE_X,  M_ABSX, WRITE, 7 },  /* Absolute,X */
 
871
  /* 7f */ { "rra", ABSOLUTE_X,  M_ABSX, WRITE, 7 },
 
872
 
 
873
  /****  Negative  ****/
 
874
 
 
875
  /* 80 */ { "nop", IMMEDIATE,   M_NONE, NONE,  2 },
 
876
  /* 81 */ { "STA", INDIRECT_X,  M_AC,   WRITE, 6 }, /* (Indirect,X) */
 
877
  /* 82 */ { "nop", IMMEDIATE,   M_NONE, NONE,  2 },
 
878
  /* 83 */ { "sax", INDIRECT_X,  M_ANXR, WRITE, 6 },
 
879
 
 
880
  /* 84 */ { "STY", ZERO_PAGE,   M_YR,   WRITE, 3 }, /* Zeropage */
 
881
  /* 85 */ { "STA", ZERO_PAGE,   M_AC,   WRITE, 3 }, /* Zeropage */
 
882
  /* 86 */ { "STX", ZERO_PAGE,   M_XR,   WRITE, 3 }, /* Zeropage */
 
883
  /* 87 */ { "sax", ZERO_PAGE,   M_ANXR, WRITE, 3 },
 
884
 
 
885
  /* 88 */ { "DEY", IMPLIED,     M_YR,   NONE,  2 },
 
886
  /* 89 */ { "nop", IMMEDIATE,   M_NONE, NONE,  2 },
 
887
  /* 8a */ { "TXA", IMPLIED,     M_XR,   NONE,  2 },
 
888
  /****  very abnormal: usually AC = AC | #$EE & XR & #$oper  ****/
 
889
  /* 8b */ { "ane", IMMEDIATE,   M_AXIM, READ,  2 },
 
890
 
 
891
  /* 8c */ { "STY", ABSOLUTE,    M_YR,   WRITE, 4 }, /* Absolute */
 
892
  /* 8d */ { "STA", ABSOLUTE,    M_AC,   WRITE, 4 }, /* Absolute */
 
893
  /* 8e */ { "STX", ABSOLUTE,    M_XR,   WRITE, 4 }, /* Absolute */
 
894
  /* 8f */ { "sax", ABSOLUTE,    M_ANXR, WRITE, 4 },
 
895
 
 
896
  /* 90 */ { "BCC", RELATIVE,    M_REL,  READ,  2 },
 
897
  /* 91 */ { "STA", INDIRECT_Y,  M_AC,   WRITE, 6 }, /* (Indirect),Y */
 
898
  /* 92 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT relative? */
 
899
  /* 93 */ { "sha", INDIRECT_Y,  M_ANXR, WRITE, 6 },
 
900
 
 
901
  /* 94 */ { "STY", ZERO_PAGE_X, M_YR,   WRITE, 4 }, /* Zeropage,X */
 
902
  /* 95 */ { "STA", ZERO_PAGE_X, M_AC,   WRITE, 4 }, /* Zeropage,X */
 
903
  /* 96 */ { "STX", ZERO_PAGE_Y, M_XR,   WRITE, 4 }, /* Zeropage,Y */
 
904
  /* 97 */ { "sax", ZERO_PAGE_Y, M_ANXR, WRITE, 4 },
 
905
 
 
906
  /* 98 */ { "TYA", IMPLIED,     M_YR,   NONE,  2 },
 
907
  /* 99 */ { "STA", ABSOLUTE_Y,  M_AC,   WRITE, 5 }, /* Absolute,Y */
 
908
  /* 9a */ { "TXS", IMPLIED,     M_XR,   NONE,  2 },
 
909
  /*** This is very mysterious comm AND ... */
 
910
  /* 9b */ { "shs", ABSOLUTE_Y,  M_ANXR, WRITE, 5 },
 
911
 
 
912
  /* 9c */ { "shy", ABSOLUTE_X,  M_YR,   WRITE, 5 },
 
913
  /* 9d */ { "STA", ABSOLUTE_X,  M_AC,   WRITE, 5 }, /* Absolute,X */
 
914
  /* 9e */ { "shx", ABSOLUTE_Y,  M_XR  , WRITE, 5 },
 
915
  /* 9f */ { "sha", ABSOLUTE_Y,  M_ANXR, WRITE, 5 },
 
916
 
 
917
  /* a0 */ { "LDY", IMMEDIATE,   M_IMM,  READ,  2 }, /* Immediate */
 
918
  /* a1 */ { "LDA", INDIRECT_X,  M_INDX, READ,  6 }, /* (indirect,X) */
 
919
  /* a2 */ { "LDX", IMMEDIATE,   M_IMM,  READ,  2 }, /* Immediate */
 
920
  /* a3 */ { "lax", INDIRECT_X,  M_INDX, READ,  6 }, /* (indirect,X) */
 
921
 
 
922
  /* a4 */ { "LDY", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
923
  /* a5 */ { "LDA", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
924
  /* a6 */ { "LDX", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
925
  /* a7 */ { "lax", ZERO_PAGE,   M_ZERO, READ,  3 },
 
926
 
 
927
  /* a8 */ { "TAY", IMPLIED,     M_AC,   NONE,  2 },
 
928
  /* a9 */ { "LDA", IMMEDIATE,   M_IMM,  READ,  2 }, /* Immediate */
 
929
  /* aa */ { "TAX", IMPLIED,     M_AC,   NONE,  2 },
 
930
  /* ab */ { "lxa", IMMEDIATE,   M_ACIM, READ,  2 }, /* LXA isn't a typo */
 
931
 
 
932
  /* ac */ { "LDY", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
933
  /* ad */ { "LDA", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
934
  /* ae */ { "LDX", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
935
  /* af */ { "lax", ABSOLUTE,    M_ABS,  READ,  4 },
 
936
 
 
937
  /* b0 */ { "BCS", RELATIVE,    M_REL,  READ,  2 },
 
938
  /* b1 */ { "LDA", INDIRECT_Y,  M_INDY, READ,  5 }, /* (indirect),Y */
 
939
  /* b2 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT */
 
940
  /* b3 */ { "lax", INDIRECT_Y,  M_INDY, READ,  5 },
 
941
 
 
942
  /* b4 */ { "LDY", ZERO_PAGE_X, M_ZERX, READ,  4 }, /* Zeropage,X */
 
943
  /* b5 */ { "LDA", ZERO_PAGE_X, M_ZERX, READ,  4 }, /* Zeropage,X */
 
944
  /* b6 */ { "LDX", ZERO_PAGE_Y, M_ZERY, READ,  4 }, /* Zeropage,Y */
 
945
  /* b7 */ { "lax", ZERO_PAGE_Y, M_ZERY, READ,  4 },
 
946
 
 
947
  /* b8 */ { "CLV", IMPLIED,     M_NONE, NONE,  2 },
 
948
  /* b9 */ { "LDA", ABSOLUTE_Y,  M_ABSY, READ,  4 }, /* Absolute,Y */
 
949
  /* ba */ { "TSX", IMPLIED,     M_SP,   NONE,  2 },
 
950
  /* bb */ { "las", ABSOLUTE_Y,  M_SABY, READ,  4 },
 
951
 
 
952
  /* bc */ { "LDY", ABSOLUTE_X,  M_ABSX, READ,  4 }, /* Absolute,X */
 
953
  /* bd */ { "LDA", ABSOLUTE_X,  M_ABSX, READ,  4 }, /* Absolute,X */
 
954
  /* be */ { "LDX", ABSOLUTE_Y,  M_ABSY, READ,  4 }, /* Absolute,Y */
 
955
  /* bf */ { "lax", ABSOLUTE_Y,  M_ABSY, READ,  4 },
 
956
 
 
957
  /* c0 */ { "CPY", IMMEDIATE,   M_IMM,  READ,  2 }, /* Immediate */
 
958
  /* c1 */ { "CMP", INDIRECT_X,  M_INDX, READ,  6 }, /* (Indirect,X) */
 
959
  /* c2 */ { "nop", IMMEDIATE,   M_NONE, NONE,  2 }, /* occasional TILT */
 
960
  /* c3 */ { "dcp", INDIRECT_X,  M_INDX, WRITE, 8 },
 
961
 
 
962
  /* c4 */ { "CPY", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
963
  /* c5 */ { "CMP", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
964
  /* c6 */ { "DEC", ZERO_PAGE,   M_ZERO, WRITE, 5 }, /* Zeropage */
 
965
  /* c7 */ { "dcp", ZERO_PAGE,   M_ZERO, WRITE, 5 },
 
966
 
 
967
  /* c8 */ { "INY", IMPLIED,     M_YR,   NONE,  2 },
 
968
  /* c9 */ { "CMP", IMMEDIATE,   M_IMM,  READ,  2 }, /* Immediate */
 
969
  /* ca */ { "DEX", IMPLIED,     M_XR,   NONE,  2 },
 
970
  /* cb */ { "sbx", IMMEDIATE,   M_IMM,  READ,  2 },
 
971
 
 
972
  /* cc */ { "CPY", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
973
  /* cd */ { "CMP", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
974
  /* ce */ { "DEC", ABSOLUTE,    M_ABS,  WRITE, 6 }, /* Absolute */
 
975
  /* cf */ { "dcp", ABSOLUTE,    M_ABS,  WRITE, 6 },
 
976
 
 
977
  /* d0 */ { "BNE", RELATIVE,    M_REL,  READ,  2 },
 
978
  /* d1 */ { "CMP", INDIRECT_Y,  M_INDY, READ,  5 }, /* (Indirect),Y */
 
979
  /* d2 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT */
 
980
  /* d3 */ { "dcp", INDIRECT_Y,  M_INDY, WRITE, 8 },
 
981
 
 
982
  /* d4 */ { "nop", ZERO_PAGE_X, M_NONE, NONE,  4 },
 
983
  /* d5 */ { "CMP", ZERO_PAGE_X, M_ZERX, READ,  4 }, /* Zeropage,X */
 
984
  /* d6 */ { "DEC", ZERO_PAGE_X, M_ZERX, WRITE, 6 }, /* Zeropage,X */
 
985
  /* d7 */ { "dcp", ZERO_PAGE_X, M_ZERX, WRITE, 6 },
 
986
 
 
987
  /* d8 */ { "CLD", IMPLIED,     M_NONE, NONE,  2 },
 
988
  /* d9 */ { "CMP", ABSOLUTE_Y,  M_ABSY, READ,  4 }, /* Absolute,Y */
 
989
  /* da */ { "nop", IMPLIED,     M_NONE, NONE,  2 },
 
990
  /* db */ { "dcp", ABSOLUTE_Y,  M_ABSY, WRITE, 7 },
 
991
 
 
992
  /* dc */ { "nop", ABSOLUTE_X,  M_NONE, NONE,  4 },
 
993
  /* dd */ { "CMP", ABSOLUTE_X,  M_ABSX, READ,  4 }, /* Absolute,X */
 
994
  /* de */ { "DEC", ABSOLUTE_X,  M_ABSX, WRITE, 7 }, /* Absolute,X */
 
995
  /* df */ { "dcp", ABSOLUTE_X,  M_ABSX, WRITE, 7 },
 
996
 
 
997
  /* e0 */ { "CPX", IMMEDIATE,   M_IMM,  READ,  2 }, /* Immediate */
 
998
  /* e1 */ { "SBC", INDIRECT_X,  M_INDX, READ,  6 }, /* (Indirect,X) */
 
999
  /* e2 */ { "nop", IMMEDIATE,   M_NONE, NONE,  2 },
 
1000
  /* e3 */ { "isb", INDIRECT_X,  M_INDX, WRITE, 8 },
 
1001
 
 
1002
  /* e4 */ { "CPX", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
1003
  /* e5 */ { "SBC", ZERO_PAGE,   M_ZERO, READ,  3 }, /* Zeropage */
 
1004
  /* e6 */ { "INC", ZERO_PAGE,   M_ZERO, WRITE, 5 }, /* Zeropage */
 
1005
  /* e7 */ { "isb", ZERO_PAGE,   M_ZERO, WRITE, 5 },
 
1006
 
 
1007
  /* e8 */ { "INX", IMPLIED,     M_XR,   NONE,  2 },
 
1008
  /* e9 */ { "SBC", IMMEDIATE,   M_IMM,  READ,  2 }, /* Immediate */
 
1009
  /* ea */ { "NOP", IMPLIED,     M_NONE, NONE,  2 },
 
1010
  /* eb */ { "sbc", IMMEDIATE,   M_IMM,  READ,  2 }, /* same as e9 */
 
1011
 
 
1012
  /* ec */ { "CPX", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
1013
  /* ed */ { "SBC", ABSOLUTE,    M_ABS,  READ,  4 }, /* Absolute */
 
1014
  /* ee */ { "INC", ABSOLUTE,    M_ABS,  WRITE, 6 }, /* Absolute */
 
1015
  /* ef */ { "isb", ABSOLUTE,    M_ABS,  WRITE, 6 },
 
1016
 
 
1017
  /* f0 */ { "BEQ", RELATIVE,    M_REL,  READ,  2 },
 
1018
  /* f1 */ { "SBC", INDIRECT_Y,  M_INDY, READ,  5 }, /* (Indirect),Y */
 
1019
  /* f2 */ { "jam", IMPLIED,     M_NONE, NONE,  0 }, /* TILT */
 
1020
  /* f3 */ { "isb", INDIRECT_Y,  M_INDY, WRITE, 8 },
 
1021
 
 
1022
  /* f4 */ { "nop", ZERO_PAGE_X, M_NONE, NONE,  4 },
 
1023
  /* f5 */ { "SBC", ZERO_PAGE_X, M_ZERX, READ,  4 }, /* Zeropage,X */
 
1024
  /* f6 */ { "INC", ZERO_PAGE_X, M_ZERX, WRITE, 6 }, /* Zeropage,X */
 
1025
  /* f7 */ { "isb", ZERO_PAGE_X, M_ZERX, WRITE, 6 },
 
1026
 
 
1027
  /* f8 */ { "SED", IMPLIED,     M_NONE, NONE,  2 },
 
1028
  /* f9 */ { "SBC", ABSOLUTE_Y,  M_ABSY, READ,  4 }, /* Absolute,Y */
 
1029
  /* fa */ { "nop", IMPLIED,     M_NONE, NONE,  2 },
 
1030
  /* fb */ { "isb", ABSOLUTE_Y,  M_ABSY, WRITE, 7 },
 
1031
 
 
1032
  /* fc */ { "nop", ABSOLUTE_X,  M_NONE, NONE,  4 },
 
1033
  /* fd */ { "SBC", ABSOLUTE_X,  M_ABSX, READ,  4 }, /* Absolute,X */
 
1034
  /* fe */ { "INC", ABSOLUTE_X,  M_ABSX, WRITE, 7 }, /* Absolute,X */
 
1035
  /* ff */ { "isb", ABSOLUTE_X,  M_ABSX, WRITE, 7 }
 
1036
};