File: debugger.html

package info (click to toggle)
stella 6.5.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 36,560 kB
  • sloc: ansic: 179,838; cpp: 69,659; asm: 6,563; sh: 3,721; makefile: 758; perl: 499; objc: 188; yacc: 86
file content (1763 lines) | stat: -rw-r--r-- 84,475 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
<html>
<head>
  <title>Stella Debugger</title>
  <style>
    table, th, td {
    border: 1px solid;
    padding: 4px;
    padding-left: 8px;
    padding-right: 8px;
    border-collapse: collapse;
  }
  </style>
</head>

<body>

  <center><b><font size="7">Stella</font></b></center>
  <center><h4><b>Release 6.5.2</b></h4></center>
  <center><h1><b>Integrated Debugger</b></h1></center>
  <center><h4><b>(a work in progress)</b></h4></center>
  <br>

  <h2>Contents</h2>
  <ul>
    <li><a href="#Features">Features</a></li>
    <li><a href="#HowToDebugger">How to use the Debugger</a>
      <ul>
        <li><a href="#Startup">Startup</a></li>
        <li><a href="#GlobalButtons">Global Buttons</a></li>
        <li><a href="#ChangeTracking">Change Tracking</a></li>
        <li><a href="#PromptTab">Prompt Tab</a>
          <ul>
            <li><a href="#TabCompletion">Tab Key Auto-Complete</a></li>
            <li><a href="#Expressions">Expressions</a></li>
              <ul>
                <li><a href="#Prefixes">Prefixes</a></li>
              </ul>
            </li>
            <li><a href="#BreakpointsEtc">Breakpoints, watches and traps, oh my!</a>
              <ul>
                <li><a href="#Breakpoints">Breakpoints</a></li>
                <li><a href="#ConditionalBreaks">Conditional Breaks</a></li>
                <li><a href="#Functions">Functions</a></li>
                <li><a href="#BuiltInFunctions">Built-in Functions</a></li>
                <li><a href="#PseudoRegisters">Pseudo-Registers</a></li>
                <li><a href="#Watches">Watches</a></li>
                <li><a href="#Traps">Traps</a></li>
              </ul>
            </li>
            <li><a href="#SaveWork">Save your work!</a></li>
            <li><a href="#PromptCommands">Prompt Commands</a></li>
          </ul>
        </li>
        <li><a href="#IOTab">I/O Tab</a></li>
        <li><a href="#AudioTab">Audio Tab</a></li>
        <li><a href="#TIADisplay">TIA Display</a></li>
        <li><a href="#TIAInfo">TIA Information</a></li>
        <li><a href="#TIAZoom">TIA Zoom</a></li>
        <li><a href="#BreakpointStatus">Breakpoint/Trap Status</a></li>
        <li><a href="#CPURegisters">CPU Registers</a></li>
        <li><a href="#DataOpButtons">Data Operations Buttons</a></li>
        <li><a href="#M6532">M6532/RIOT RAM</a></li>
          <ul>
            <li><a href="#M6532Search">M6532/RIOT RAM (search/compare mode)</a></li>
          </ul>
        </li>
        <li><a href="#Disassembly">ROM Disassembly</a>
          <ul>
            <li><a href="#DisassemblySettings">ROM Disassembly Settings</a></li>
            <li><a href="#Limitations">Limitations</a></li>
          </ul>
        </li>
        <li><a href="#BankswitchInformation">Detailed Bankswitch Information</a></li>
        <li><a href="#CartridgeRAMInformation">Detailed Cartridge Extended RAM Information</a></li>
      </ul>
    </li>
    <li><a href="#DistellaConfiguration">DiStella Configuration Files</a></li>
    <li><a href="#Howtohack">Tutorial: How to hack a ROM</a></li>
    </li>
  </ul>
  <br>

<h1><a name="Features">Features</a></h1>
<p>The debugger in Stella may never be complete, as we're constantly
adding new features requested by homebrew developers. However, even in its
current form it's still quite powerful, and is able to boast at least one
feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.</p>

<p>Here's a (non-comprehensive) list of what the debugger can do so far:</p>
<ul>
  <li>Display registers and memory.</li>

  <li>Dump state of TIA and RIOT, with things like joystick directions and
    NUSIZx decoded into English (more-or-less).</li>

  <li>Change registers/memory, including toggles for flags in P register.</li>

  <li>Single step/trace.</li>

  <li>Breakpoints - break running program and enter debugger when the
    Program Counter hits a predefined address; you can set as many
    breakpoints as you want.</li>

  <li>Conditional breakpoints - Break running program when some arbitrary
    condition is true (e.g. "breakif {a == $7f &amp;&amp; c}" will break when the Accumulator value is $7f and the Carry flag is true, no matter where
    in the program this happens). Unlike the cond breaks in PCAE, Stella's
    are *fast*: the emulation will run at full speed unless you use lots
    of breakif's at the same time, or have a slow CPU.</li>

  <li>Watches - View contents of a location/register before every
    debugger prompt.</li>

  <li>Traps - Like breakpoints, but break on read/write/any access to
    *any* memory location. Traps can also be combined with conditions to
    become conditional traps.</li>

  <li>Frame advance (automatic breakpoint at beginning of next frame)
    You can advance multiple frames with one command.</li>

  <li>Rewind previous advance operations and undo rewinds.</li>

  <li>Supports DiStella 'configuration directives', which may be used to
    override automatic code/data determination in the disassembly. For now,
    the following directives are supported: CODE, GFX, PGFX, COL, PCOL, BCOL, AUD, DATA, ROW.
    These directives can be entered at the debugger prompt, or be (automatically)
    loaded and saved in configuration files.</li>

  <li>Extensive disassembly support, both from the emulation core and with help
    from DiStella. Where possible, the disassembly differentiates between code,
    player and playfield graphics, colors and audio (ie, addresses stored in
    GRPx, PFx, COLUxx, AUDxx)
    and data (addresses used as an operand of a command). Code sections are also
    differentiated between actual code, and 'tentative' code (ie, areas that may
    represent code sections, but haven't actually been executed yet). Such
    tentative code is marked with a '*' symbol.</li>

  <li>Supports visual representation of the bitmap data of graphics areas,
    as well as the ability to directly edit these areas in either hex or binary.</li>

  <li>Support for DASM symbol files (created with DASM's -s option),
    including automatically loading symbol files if they're named
    romname.sym</li>

  <li>Support for DASM list files (created with DASM's -l option),
    including automatically loading list files if they're named
    romname.lst</li>

  <li>Built-in VCS.H symbols, if no symbol file is loaded.</li>

  <li>Symbolic names in disassembly.</li>

  <li>Symbolic names accepted as input.</li>

  <li>Ability to generate DASM-compatible disassembly files (currently single-bank
    only) with all the features mentioned above.</li>

  <li>Tab completion for commands, symbol names and functions.</li>
  <li>Graphical editor for RIOT and extended RAM. Acts a lot like a spreadsheet.
    Input in hex, with displays for label/decimal/binary for
    currently-selected location.</li>
  <li>GUI CPU state window.</li>
  <!--Cheat system (similar to MAME) (still needs a way to save/load cheats)-->
  <li>Reset the 6502.</li>
  <li>Start emulator in debugger (via command-line option "-debug").</li>
  <li>Save CLI session to a text file.</li>
  <li>Supports hex, decimal, and binary input and output almost everywhere.
    (disassembly is still hex).</li>
  <li>Support for bank switching. You can see how many banks a cart has and the
    currently selected bank, and manually change banks.</li>
  <li>Registers/memory that get changed by the CPU during debugging are
    highlighted when they're displayed.</li>
  <li>Data sources for the CPU SP/A/X/Y registers, showing the resolved/source
    address of of load operands.</li>
  <li>Scanline advance (like frame advance, break at beginning
    of next scanline).</li>
  <li>TIA display is updated during step/trace, so we can see our
    scanlines being drawn as it happens. This isn't 100% perfect: unlike
    a real TIA, the one in Stella only updates when it's written to.</li>
  <li>Graphical TIA tab, with register names and GUI buttons for
    various bits (e.g. click ENAM0 to turn it on).</li>
  <li>GUI Disassembly window, scrollable, with checkboxes for breakpoints.</li>
  <li>Script (batch) file support, including auto-running a script file
    named after the ROM image.</li>
  <li>Saving the current debugger state to a script file (including
    breakpoints, traps, etc).</li>
  <li>Built-in functions for use with "breakif", to support common conditions
    (such as breaking when the user presses Game Select...)</li>
  <li>Patching ROM in-place.</li>
  <li>Save patched ROM</li>
</ul>

<h3>Future planned features:</h3>

<ul>
  <li>GUI for cheat codes (Cheetah and normal codes).</li>
  <li>Perhaps 2 panes in the disassembly window (so you can see 2 parts of the
    code at once).</li>
  <li>Add bookmark support to disassembly window.</li>
  <li>More "special variables" for the expression parser.</li>
  <li>Possibly a mini-assembler</li>
  <li>Possibly support for recording and playing back input files, like
    MAME. This isn't a debugger feature per se, but it'll make it easier
    to reliably trigger a bug so you can debug it.</li>
<!--
  <li>Graphics ROM view, so you can see your sprite data (it might still
    be upside-down though :)</li> -->
  <li>Various new GUI enhancements</li>
</ul>

</br>
<h1><a name="HowToDebugger">How to use the Debugger</a></h1>

<p>Pressing ` (aka backtick, backquote, grave accent) toggles the debugger on
&amp; off. When you exit the debugger, the emulation resumes at the current
program counter, and continues until either a breakpoint/trap is hit,
or the ` key is pressed again.</p>

<p>The main debugger window will look similar to the following (note that the
letters here are for reference in the document below; they aren't actually
present in the debugger):</p>
<p><img src="graphics/debugger_main.png"></p>

<p>For space reasons, the Prompt, TIA, I/O and Audio displays are split into
4 tabs, only one of which is visible at a time. You can use the mouse or
keyboard to select which tab you want to view. Control/Cmd + Tab cycles between
tabs from left-to-right, Shift-Control/Cmd + Tab cycles right-to-left.
Pressing Tab (or Shift + Tab) cycles between widgets in the current tab (except
for in the Prompt Tab, where 'tab' is used for something else).</p>

<p>Note for the GUI display:
<ul>
<li>Hexadecimal values are either not prefixed or with '$'.</li>
<li>Decimal values are prefixed with '#'.</li>
<li>Binary values are prefixed with '%'.</li>
</ul>
</p>

<p>You can also enter the debugger at emulator startup by use the 'debug'
command on the command line, or alternatively within the ROM launcher in
'Power-on options':
<pre>
  ; will enter the debugger before any instructions run
  stella -debug mygame.bin

  ; alternatively, you can use 'break' to accomplish the same thing
  ; $fffc is the 6502/6507 init vector. This command will break and enter the
  ; debugger before the first 6507 instruction runs, so you can debug the
  ; startup code:
  stella -break "*($fffc)" mygame.bin
</pre>
</p>

<p>Using the ` key will always enter the debugger at the end of
the frame (for NTSC games usually scanline 262). This is because Stella only checks
for keystrokes once per frame. Once in the debugger, you can control
execution by stepping one instruction, scanline, or frame at a time
(or more than one at a time, using commands in the prompt). You can
also set breakpoints or traps, which will cause the emulator to enter
the debugger when they are triggered, even if it happens in mid-frame.</p>
</br>

<h2><a name="Startup">Startup</a></h2>
At startup, the debugger automatically tries load a number of files which
will provide additional information for the debugger and can make debugging
more convenient.

<ul>
  <li>
    "autoexec.script"</br>
    Use this plain text file to define e.g. your own functions or settings.
    They will be loaded at startup for each ROM.

    <p>The location of this file will depend on the OS as follows:</p>
    <p>
    <table cellpadding=4 border="1">
      <tr>
        <td><b>Linux/Unix</b></td>
        <td><i>$HOME/.config/stella/autoexec.script</i></td>
      </tr>
      <tr>
        <td><b>Macintosh</b></td>
        <td><i>$HOME/Library/Application Support/Stella/autoexec.script</i></td>
      </tr>
      <tr>
        <td><b>Windows</b></td>
        <td><i>%APPDATA%\Stella\autoexec.script</i></td>
      </tr>
      <tr>
        <td><b>If using 'basedir'<br>or 'baseinappdir'</b></td>
        <td><i>_BASEDIR_/autoexec.script</i></td>
      </tr>
    </table>
    </p>
  </li>
  <li>
    "&lt;rom_filename&gt;.script" (located in the same directory as the ROM)</br>
    In this ROM specific, plain text file you can store breaks, traps, watches
    etc. for future re-use. Use the "save" command to create this file using
    the current settings. You can also manually edit the file and add more commands.
    </br></br>
  </li>
  <li>
    "&lt;rom_filename&gt;.cfg"</br>
    This file is described in <a href="#DistellaConfiguration">
    <b>DiStella Configuration Files</b></a>.
    </br></br>
  </li>
  <li>
    "&lt;rom_filename&gt;.lst" (located in the same directory as the ROM)</br>
  </li>
  <li>
    "&lt;rom_filename&gt;.sym" (located in the same directory as the ROM)</br>
    If you provied the -l and -s parameters DASM will create these two files during
    assembly. Stella uses the file content to display the correct labels.
  </li>
</ul>
<p>Note that all files are only accessed if you enter
the debugger at least once during a program run. This means you can create
these files, and not worry about slowing down emulation unless you're
actively using the debugger.</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="GlobalButtons">Global Buttons</a></h2>

<p>There are some buttons on the right top that always show up no matter which
tab you are looking at. This is because these are the ones that are most frequently
used.</p>

<ul>
  <p><img src="graphics/debugger_globalbuttons.png"></p>
</ul>

<p>The larger button at the left top (labeled '&lt;') performs the rewind operation,
which will undo the previous Step/Trace/Scan/Frame... advance, the smaller button at
the left bottom (labeled '&gt;') performs the unwind operation, which will undo the
previous rewind operation. The rewind buffer is 100 levels deep by default, the
size can be configured e.g. in the
<b><a href="index.html#Debugger">Developer Settings</a> - Time Machine</b> dialog.<p>

<p>The other operations are Step, Trace, Scan +1, Frame +1 and Run.</p>

<p>You can also use the buttons from anywhere in the GUI via hotkeys.</p>
<p>
<table BORDER=1 cellpadding=4>
  <tr>
    <th>Key</th>
    <th>Function</th>
  </tr>
  <tr>
    <td>Control + S</td>
    <td>Step</td>
  </tr>
  <tr>
    <td>Control + T</td>
    <td>Trace</td>
  </tr>
  <tr>
    <td>Control + L</td>
    <td>Scan +1</td>
  </tr>
  <tr>
    <td>Control + F</td>
    <td>Frame +1</td>
  </tr>
  <tr>
    <td>Alt + Left arrow</td>
    <td>Rewind 1</td>
  </tr>
  <tr>
    <td>Shift-Alt + Left arrow</td>
    <td>Rewind 10</td>
  </tr>
  <tr>
    <td>Alt + Down arrow</td>
    <td>Rewind all</td>
  </tr>
  <tr>
    <td>Alt + Right arrow</td>
    <td>Unwind 1</td>
  </tr>
  <tr>
    <td>Shift-Alt + Right arrow</td>
    <td>Unwind 10</td>
  </tr>
  <tr>
    <td>Alt + Up arrow</td>
    <td>Unwind all</td>
  </tr>
  <tr>
    <td>Backquote (`)</td>
    <td>Run, exits debugger</td>
  </tr>
</table>
</p>
For MacOS use 'Cmd' instead of &nbsp;'Alt' key.
<p>To the left of the global buttons, you find the 'Options...' button.</p>
<ul>
  <p><img src="graphics/debugger_options.png"></p>
</ul>
<p>This opens the <a href="index.html#Options">Options Menu</a> which is described
in detail in the <a href="index.html">User's Guide</a>.</p>

<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="ChangeTracking"></a>Change Tracking</h2>

<p>The debugger tracks changes to the CPU, TIA and RIOT registers and RAM by
displaying changed locations or registers with a red background after each step,
trace, scanline, or frame advance. This sounds simple, and it is, but
it's also amazingly useful.</p>

<p>One clarification about the change tracking: it only tracks when values
have <b>changed</b>. If the ROM writes a value into a RAM location that
already contained the same value, that's not considered a change (old
value was $whatever, new value is the same, so nothing got tracked). This
may change in a future version of Stella.</p>

<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="PromptTab"><u>(A)</u> Prompt Tab</a></h2>

<p>This is a command-line interface, similar to the DOS DEBUG command
or Supermon for the C=64.</p>

<p>Editing keys work about like you'd expect them to in Windows, but many
Bash-style commands are also supported:</p>

<table border="1" cellpadding=4>
  <tr><th>Key</th><th>Function</th></tr>
  <tr><td>Home</td><td>Move cursor to beginning of line</td></tr>
  <tr><td>End</td><td>Move cursor to end of line</td></tr>
  <tr><td>Delete</td><td>Remove character to right of cursor</td></tr>
  <tr><td>Backspace</td><td>Remove character to left of cursor</td></tr>
  <tr><td>Control + A</td><td>Same function as 'Home'</td></tr>
  <tr><td>Control + E</td><td>Same function as 'End'</td></tr>
  <tr><td>Control + D</td><td>Same function as 'Delete'</td></tr>
  <tr><td>Control + K</td><td>Remove all characters from cursor to end of line</td></tr>
  <tr><td>Control + U</td><td>Remove all characters from cursor to beginning of line</td></tr>
  <tr><td>Control + W</td><td>Remove entire word to left of cursor</td></tr>
  <tr><td>Shift + PgUp</td><td>Scroll up through previous commands one screen/page</td></tr>
  <tr><td>Shift + PgDown</td><td>Scroll down through previous commands one screen/page</td></tr>
  <tr><td>Shift + Up</td><td>Scroll up through previous commands one line</td></tr>
  <tr><td>Shift + Down</td><td>Scroll down through previous commands one line</td></tr>
  <tr><td>Shift + Home</td><td>Scroll to beginning of commands</td></tr>
  <tr><td>Shift + End</td><td>Scroll to end of commands</td></tr>
</table>
<p>You can also scroll with the mouse. Copy and paste is not yet supported.</p>

<p>To see the available commands, enter "help". For extended help, type "help cmd",
where 'cmd' is the command you wish to know about. The available commands are listed
in <a href="#PromptCommands"><b>Prompt Commands</b></a> at the end of this section. Bash-style tab completion is supported for commands,
labels and functions (see below).</p>

<p>For now, there are some functions that only exist in the prompt. We
intend to add GUI equivalents for all (or almost all?) of the prompt
commands in future releases. People who like command prompts will be able to
use the prompt, but people who hate them will have a fully functional
debugger without typing (or without typing much, anyway).</p>

<p>Note: unlike the rest of the UI, whatever is shown in the prompt will not
be updated during debugging and thus eventually become "stale". You can update it
just by re-running the relevant commands in the prompt.</p>
</br>

<h3><a name="TabCompletion">Tab Key Auto-Complete</a></h3>

<p>While entering a command, label or function, you can type a partial name and
press the Tab key to attempt to auto-complete it. If you've ever used
"bash", this will be immediately familiar. If not, try it: load up
a ROM, go to the debugger, type "g" (but don't press Enter),
then hit Tab. The "g" will change to "gfx" (since this is the only
built-in command starting with a "g"). If there are multiple possible
completions (try with "tr" instead of "g"), you'll see a list of them,
and your partial name will be completed as far as possible.
After the first character, the autocompletion considers all
characters in the right order as a match (e.g. "twf" will be completed to
"trapwriteif").</p>

<p>Tab completion works on all labels: built-in, loaded from a symbol file,
or set during debugging with the "define" command. It also works with
built-in functions and those defined with the "function" command,
but it doesn't (yet) work on filenames.</p>
</br>

<h3><a name="Expressions">Expressions</a></h3>

<p>Almost every command takes a value: the "a" command takes a
byte to stuff into the accumulator, the "break" command
takes an address to set/clear a breakpoint at. These values
can be as a hex constant ($ff, $1234), or as complex as
"the low byte of the 16-bit value located at the address
pointed to by the binary number 1010010110100101" (which
would be "@&lt;\1010010110100101"). You can also use registers
and labels in expressions.</p>

<p>You can use arithmetic and boolean operators in expressions. The
syntax is very C-like. The operators supported are:</p>

<pre>
      + - * /  (add, subtract, multiply, divide: 2+2 is 4)
      %        (modulus/remainder: 3%2 is 1)
      &amp; | ^ ~  (bitwise AND, OR, XOR, NOT: 2&amp;3 is 2)
      &amp;&amp; || !  (logical AND, OR, NOT: 2&amp;&amp;3 is 1, 2||0 is 0)
      ( )      (parentheses for grouping: (2+2)*3 is 12)
      * @      (byte and word pointer dereference: *$80 is the byte stored
                at location $80)
      [ ]      (array-style byte pointer dereference: $80[1] is the byte
                stored at location ($80+1) or $81)
      &lt; &gt;      (prefix versions: low and high byte. &lt;$abcd is $cd)
      == &lt; &gt; &lt;= &gt;= !=
               (comparison: equality, less-than, greater-than, less-or-equals,
                greater-or-equals, not-equals)
      &lt;&lt; &gt;&gt;    (bit shifts, left and right: 1&lt;&lt;1 is 2, 2&gt;&gt;1 is 1)
</pre>

<p>Division by zero is not an error: it results in zero instead.</p>

<p>None of the operators change the values of their operands. There
are no variable-assignment or increment/decrement operators. This
may change in the future, which is why we used "==" for equality
instead of just "=".</p>

<p>The bitwise and logical boolean operators are different in that the
bitwise operators operate on all the bits of the operand (just like
AND, ORA, EOR in 6502 asm), while the logical operators treat their
operands as 0 for false, non-zero for true, and return either 0 or 1.
So $1234&amp;$5678 results in $1230, whereas $1234&amp;&amp;$5678 results in 1.
This is just like C or C++...</p>

<h4><a name="Prefixes">Prefixes</a></h4>

<p>Like some programming languages, the debugger uses prefixed characters
to change the meaning of an expression. The prefixes are:</p>

<ul>
  <li>Dereference prefixes:<br>

    <p><pre>'*'</pre>
        Dereference a byte pointer. "*a" means "the byte at the address that
        the A register points to". If A is 255 (hex $ff), the result will be
        the value currently stored in memory location 255. This operator
        will be very familiar to you if you're a C or C++ developer. It's
        equivalent to the PEEK() function in most 8-bit BASICs. Also, the
        debugger supports array-like byte dereferences: *address can be
        written as address[0]. *(address+1) can be written as address[1],
        etc.</p>

    <p><pre>'@'</pre>
        Dereference a pointer to a word. This is just like the "*" byte deref,
        except it refers to a 16-bit value, occupying 2 locations, in
        low-byte-first format (standard for the 6507).</p>

    <p>The following are equivalent:</p>
    <pre>
         @address
         *address+$100**(address+1)
         address[0]+#256*address[1]
    </pre>

    <p>(TODO: add (indirect),y and (indirect,x) syntax)</p>
  </li>

  <li>Hi/Lo Byte Prefixes:<br>
    <p><pre>'&lt;'</pre>
    Take the low byte of a 16-bit value. This has no effect on an 8-bit
    value: "a" is equal to "&lt;a". However, "&lt;$1234" equals "$34".</p>

    <p><pre>'&gt;'</pre>
    Take the high byte of a 16-bit value. For 8-bit values such as
    the Accumulator, this will always result in zero. For 16-bit values,
    "&lt;$1234" = "$12".</p>
  </li>

  <li>Number Base Prefixes:<br>
    <p><pre>'#'</pre>
    Treat the input as a decimal number.</p>

    <p><pre>'$'</pre>
    Treat the input as a hex number.</p>

    <p><pre>'\'</pre>
    Treat the input as a binary number.</p>

    <p>These only have meaning when they come before a number, not a
    label or a register. "\1010" means 10 decimal. So do "$0a" and
    "#10". "a" by itself is always the Accumulator, no matter what
    the default base is set to.</p>

    <p>If you don't specify any number base prefix, the number is
    assumed to be in the default base. When you first start Stella,
    the default base is 16 (hexadecimal). You can change it with the
    "base" command. If you want to change the default base to decimal permanently,
    you can put a
    <pre>
      base #10
    </pre>
    command in your "autoexec.script" file (for details
    see <a href="#Startup"><b>Startup</b></a>).</p>
  </li>
</ul>
<p>Remember, you can use arbitrarily complex expressions with any
command that takes arguments.</p>

</br>
<h3><a name="BreakpointsEtc">Breakpoints, watches and traps, oh my!</a></h3>

<h4><a name="Breakpoints">Breakpoints</a></h4>

<p>A breakpoint is a "hotspot" in your program that causes the emulator
to stop emulating and jump into the debugger. You can set as many
breakpoints as you like. The command is "break xx yy" where xx is any
expression and yy a bank number.  Both arguments are optional. If you have
created a symbol file, you can use labels for the expression.</p>

<p>Example: You have got a label called "kernel". To break there,
the command is "break kernel". After you've set the breakpoint,
exit the debugger (enter "run" or click the 'Run' button). The emulator
will run until it gets to the breakpoint, then it will enter the
debugger with the Program Counter pointing to the instruction
at the breakpoint.</p>

<p>Breakpoints happen *before* an instruction is executed: the
instruction at the breakpoint location will be the "next"
instruction.</p>

<p>To remove a breakpoint, you just run the same command you used to
set it. In the example, "break kernel" will remove the breakpoint.
The "break" command can be thought of as a *toggle*: it turns the
breakpoint on &amp; off, like a light switch.</p>

<p>You could also use "clearbreaks" to remove all the breakpoints. Also,
there is a "listbreaks" command that will list them all.</p>

<h4><a name="ConditionalBreaks">Conditional Breaks</a></h4>

<p>A conditional breakpoint causes the emulator to enter the debugger when
some arbitrary condition becomes true. "True" means "not zero" here:
"2+2" is considered true because it's not zero. "2-2" is false, because
it evaluates to zero. This is exactly how things work in C and lots
of other languages, but it might take some getting used to if you've
never used such a language.</p>

<p>Suppose you want to enter the debugger when the Game Reset switch is
pressed. Looking at the Stella Programmers' Guide, we see that this
switch is read at bit 0 of SWCHB. This bit will be 0 if the switch is
pressed, or 1 otherwise.</p>

<p>To have an expression read the contents of an address, we use the
dereference operator "*". Since we're looking at SWCHB, we need
"*SWCHB".</p>

<p>We're only wanting to look at bit 0, so let's mask off all the other
bits: "*SWCHB&amp;1". The expression now evaluates to bit 0 of SWCHB. We're
almost there: this will be 1 (true) if the switch is NOT pressed. We
want to break if it IS pressed...</p>

<p>So we invert the sense of the test with a logical NOT operator (which
is the "!" operator): !(*SWCHB&amp;1). The parentheses are necessary as
we want to apply the ! to the result of the &amp;, not just the first term
(the "*SWCHB").</p>

<p>"breakif !(*SWCHB&amp;1)" will do the job for us. However, it's an ugly mess
of letters, numbers, and punctuation. We can do a little better:</p>

<p>"breakif { !(*SWCHB &amp; 1 ) }" is a lot more readable, isn't it? If
you're going to use readable expressions with spaces in them,
enclose the entire expression in curly braces.</p>

<p>Remember that Stella only checks for input once per frame, so a break
condition that depends on input (like SWCHB) will always happen at the
end of a frame. This is different from how a real 2600 works, but most
ROMs only check for input once per frame anyway.</p>

<p>Conditional breaks appear in "listbreaks", numbered starting from
zero. You can remove a cond-break with "delbreakif number", where
the number comes from "listbreaks" or by entering the same conditional break again.</p>

<p>Any time the debugger is entered due to a trap, breakpoint, or
conditional break, the reason will be displayed in the
<a href="#BreakpointStatus"><b>Breakpoint/Trap Status</b></a> area.

<h4><a name="Functions">Functions</a></h4>

<p>There is one annoyance about complex expressions: once we
remove the conditional break with "delbreakif" or "clearbreaks",
we'd have to retype it (or search backwards with the up-arrow key)
if we wanted to use it again.</p>

<p>We can avoid this by defining the expression as a function, then using
"breakif function_name":</p>

<pre>
  function gameReset { !(*SWCHB &amp; 1 ) }
  breakif gameReset
</pre>

<p>Now we have a meaningful name for the condition, so we can use it again.
Not only that: we can use the function as part of a bigger expression.
Suppose we've also defined a gameSelect function that evaluates to true
if the Game Select switch is pressed. We want to break when the user
presses both Select and Reset:</p>

<pre>
  breakif { gameReset &amp;&amp; gameSelect }
</pre>

<p>User-defined functions appear in "listfunctions", which shows the label
and expression for each function. Functions can be removed with
"delfunction label", where the labels come from "listfunctions".</p>

<h4><a name="BuiltInFunctions">Built-in Functions</a></h4>

<p>Stella has some pre-defined functions for use with the "breakif"
command. These allow you to break and enter the debugger on various
conditions without having to define the conditions yourself.</p>

<p>Built-in functions and pseudo-registers always start with an _
(underscore) character. It is suggested that you don't start labels in
your game's source with underscores, if you plan to use them with the
Stella debugger.</p>

<table border="1" cellpadding=4>
<tr><th>Function</th><th>Definition</th><th>Description</th></tr>
<tr><td> _joy0left</td><td> !(*SWCHA &amp; $40)</td><td> Left joystick moved left</td></tr>
<tr><td> _joy0right</td><td> !(*SWCHA &amp; $80)</td><td> Left joystick moved right</td></tr>
<tr><td> _joy0up</td><td> !(*SWCHA &amp; $10)</td><td> Left joystick moved up</td></tr>
<tr><td> _joy0down</td><td> !(*SWCHA &amp; $20)</td><td> Left joystick moved down</td></tr>
<tr><td> _joy0button</td><td> !(*INPT4 &amp; $80)</td><td> Left joystick button pressed</td></tr>
<tr><td> _joy1left</td><td> !(*SWCHA &amp; $04)</td><td> Right joystick moved left</td></tr>
<tr><td> _joy1right</td><td> !(*SWCHA &amp; $08)</td><td> Right joystick moved right</td></tr>
<tr><td> _joy1up</td><td> !(*SWCHA &amp; $01)</td><td> Right joystick moved up</td></tr>
<tr><td> _joy1down</td><td> !(*SWCHA &amp; $02)</td><td> Right joystick moved down</td></tr>
<tr><td> _joy1button</td><td> !(*INPT5 &amp; $80)</td><td> Right joystick button pressed</td></tr>
<tr><td> _select</td><td> !(*SWCHB &amp; $02)</td><td> Game Select pressed</td></tr>
<tr><td> _reset</td><td> !(*SWCHB &amp; $01)</td><td> Game Reset pressed</td></tr>
<tr><td> _color</td><td> *SWCHB &amp; $08</td><td> Color/BW set to Color</td></tr>
<tr><td> _bw</td><td> !(*SWCHB &amp; $08)</td><td> Color/BW set to BW</td></tr>
<tr><td> _diff0b</td><td> !(*SWCHB &amp; $40)</td><td> Left difficulty set to B (easy)</td></tr>
<tr><td> _diff0a</td><td> *SWCHB &amp; $40</td><td> Left difficulty set to A (hard)</td></tr>
<tr><td> _diff1b</td><td> !(*SWCHB &amp; $80)</td><td> Right difficulty set to B (easy)</td></tr>
<tr><td> _diff1a</td><td> *SWCHB &amp; $80</td><td> Right difficulty set to A (hard)</td></tr>
</table>

<p>Don't worry about memorizing them all: the Prompt "help" command
will show you a list of them.</p>

<h4><a name="PseudoRegisters">Pseudo-Registers</a></h4>

<p>These "registers" are provided for you to use in your conditional breaks.
They're not registers in the conventional sense, since they don't exist in
a real system. For example, while the debugger keeps track of the number
of scanlines in a frame, a real system would not (there is no register
that holds 'number of scanlines' on an actual console).</p>
<table border="1" cellpadding=4>
<tr><th>Function</th><th>Description</th></tr>
<tr><td> _bank</td><td> Currently selected bank</td></tr>
<tr><td> _cclocks</td><td> Color clocks on a scanline</td></tr>
<tr><td> _cycleshi</td><td> Higher 32 bits of number of cycles since emulation started</td></tr>
<tr><td> _cycleslo</td><td> Lower 32 bits of number of cycles since emulation started</td></tr>
<tr><td> _fcount</td><td> Number of frames since emulation started</td></tr>
<tr><td> _fcycles</td><td> Number of cycles since frame started</td></tr>
<tr><td> _ftimreadcycles</td><td>Number of cycles used by timer reads since frame started</td></tr>
<tr><td> _fwsynccycles</td><td>Number of cycles skipped by WSYNC since frame started</td></tr>
<tr><td> _icycles</td><td> Number of cycles of last instruction</td></tr>
<tr><td> _scan</td><td> Current scanline count</td></tr>
<tr><td> _scanend</td><td> Scanline count at end of last frame</td></tr>
<tr><td> _scycles</td><td> Number of cycles in current scanline</td></tr>
<tr><td> _timwrapread</td><td> Timer read wrapped on this cycle</td></tr>
<tr><td> _timwrapwrite</td><td> Timer write wrapped on this cycle</td></tr>
<tr><td> _vblank</td><td> Whether vertical blank is enabled (1 or 0)</td></tr>
<tr><td> _vsync</td><td> Whether vertical sync is enabled (1 or 0)</td></tr>
</table>

<p><b>_scan</b> always contains the current scanline count. You can use
this to break your program in the middle of your kernel. Example:</p>
<pre>
    breakif _scan==#64
</pre>
<p>This will cause Stella to enter the debugger when the TIA reaches the
beginning of the 64th scanline.</p>

<p><b>_bank</b> always contains the currently selected bank. For 2K or 4K
(non-bankswitched) ROMs, it will always contain 0. One useful use is:</p>

<pre>
    breakif { pc==myLabel &amp;&amp; _bank==1 }
</pre>

<p>This is similar to setting a regular breakpoint, but it will only trigger
when bank 1 is selected.</p>

<h4><a name="Watches">Watches</a></h4>

<p>A watch is an expression that gets evaluated and printed before
every prompt. This is useful for e.g. tracking the contents of a
memory location while stepping through code that modifies it.</p>

<p>You can set up to 10 watches (in future the number will be unlimited).
Since the expression isn't evaluated until it's used, you can include
registers: "watch *y" will show you the contents of the location
pointed to by the Y register, even if the Y register changes.</p>

<p>The watches are numbered. The numbers are printed along with the
watches, so you can tell which is which. To delete a watch use the
"delwatch" command with the watch number (1 to whatever). You can
also delete them all with the "clearwatches" command.</p>

<p>Note that there's no real point in watching a label or CPU register
without dereferencing it: Labels are constants, and CPU registers
are already visible in the <a href="#CPURegisters"><b>CPU Registers</b></a> widget</p>

<h4><a name="Traps">Traps</a></h4>

<p>A trap is similar to a breakpoint, except that it catches
accesses to a memory address, rather than specific location in the
program. They're useful for finding code that modifies TIA registers
or memory.</p>

<p>Traps can also combined with a condition ("trapif"). If an access
to a memory address is caught, the condition is evaluated additionally.
Only if the condition is true too, the emulations stops. For details
about conditions see <a href="#ConditionalBreaks"><b>Conditional Breaks</b></a> described above.</p>

<p>An example: you are debugging a game, and you want to stop the
emulation and enter the debugger whenever RESP0 is strobed. You'd use
the command "trap RESP0" to set the trap, then exit the debugger. The
emulator will run until the next time RESP0 is accessed (either read
or write). Once the trap is hit, you can examine the TIA state to
see what the actual player 0 position is, in color clocks (or you
can in the future when we implement that feature in the TIA dump!)</p>

<p>Unlike breakpoints, traps stop the emulation *after* the instruction
that triggered the trap. The reason for this is simple: until the
instruction is executed, the emulator can't know it's going to hit a
trap. After the trap is hit, the instruction is done executing, and
whatever effects it may have had on e.g. the TIA state have already
happened... but we don't have a way to run the emulated VCS in reverse,
so the best we can do is stop before the next instruction runs.</p>

<p>Traps come in two varieties: read access traps and write access traps.
It is possible to set both types of trap on the same address (that's
what the plain "trap" command does). To set a read or write only trap,
use "trapread(if)" or "trapwrite(if)".

<p>All traps appear in "listtraps", numbered starting from zero. You
can remove a trap with "deltrap number", where the number comes from
"listtraps" or by entering the identical trap again. You can get rid of
all traps at once with the "cleartraps" command.</p></p>

</br>
<h3><a name="SaveWork">Save your work!</a></h3>
<p>Stella offers several commands to save your work inside the debugger for
later re-use.</p>

<ul>
  <li>
    <b><a name="savecmd">save</a></b>: If you've defined a lot of complex functions, you probably will
    want to re-use them in future runs of the debugger. You can save all
    your functions, breakpoints, conditional breaks, traps and watches with the
    "save" command. If you name your saved file the same as the ROM filename
    and place it in the ROM directory, it will be auto-loaded next time you
    load the same ROM in Stella. The saved file is just a plain text file
    called "&lt;rom_filename&gt;.script", so you can edit it and add new functions, etc.
    <p>Note: While "save" is ROM specific, you can also create a file called
    "autoexec.script" which will be loaded when the debugger starts, no matter
    what ROM you have loaded.<p>
    See <a href="#Startup"><b>Startup</b></a> for details.
  </li>
  <li>
    <b>saveconfig</b>: The "saveconfig" command creates a
    <a href="#DistellaConfiguration"><b>DiStella Configuration File</b></a> which is
    based on Stella's dynamic and static analysis of the current ROM.
    <p>This will be automatically loaded the next time your start the debugger.
    From there on, you can continue analyzing the ROM and then use "saveconfig"
    again to update the configuration. You can also use "loadconfig" to load it
    manually.
    <p>Note that this is not tested for multi-banked ROMs.</p>
  </li>
  <li>
    <b>savedis</b>:
    While your are playing or debugging a game, Stella will gather dynamic
    information about the ROM. It can then use that information together with
    a static analysis of the ROM and therefore create a better disassembly
    than DiStella alone. "savedis" allows you to save that disassembly as the
    result of this combined analysis.
    <p>Note that this currently only works for single banked ROMs. For larger
    ROMs, the created disassembly is incomplete.</p>
  </li>
  <li>
    <p><b>saverom</b>:
    If you have manipulated a ROM, you can save it with "saverom". The file is
    named "&lt;rom_filename&gt;.a26".</p>
  </li>
  <li>
    <p><b>saveses</b>:
    The "saveses" command dumps the whole prompt session into a file named
    "&lt;YYYY-MM-DD_HH-mm-ss&gt;.txt". So you can later lookup what you did exactly
    when you were debugging at that time.</p>
  </li>
  <li>
  <p><b>saveallstates</b>:
    This command works identical to the save all states hotkey (Alt + F9) during emulation.
    The saved states can be loaded with "loadallstates".</p>
  </li>
  <li>
  <p><b>savestate</b>:
    This command works identical to the save state hotkey (F9) during emulation.
    Any previously saved state can be loaded with "loadstate" plus the slot
    number (0-9).</p>
  </li>
</ul>
</br>

<h3><a name="PromptCommands">Prompt Commands</a></h3>

<p>Type "help" to see this list in the debugger.<br/>
Type "help 'cmd'" to see extended information about the given command.</p>

<pre>
                a - Set Accumulator to &lt;value&gt;
              aud - Mark 'AUD' range in disassembly
             base - Set default number base to &lt;base&gt; (bin, dec, hex)
             bcol - Mark 'BCOL' range in disassembly
            break - Set/clear breakpoint at &lt;address&gt; and &lt;bank&gt;
          breakif - Set/clear breakpoint on &lt;condition&gt;
       breaklabel - Set/clear breakpoint on &lt;address&gt; (no mirrors, all banks)
                c - Carry Flag: set (0 or 1), or toggle (no arg)
            cheat - Use a cheat code (see manual for cheat types)
      clearbreaks - Clear all breakpoints
      clearconfig - Clear DiStella config directives [bank xx]
clearsavestateifs - Clear all savestate points
       cleartraps - Clear all traps
     clearwatches - Clear all watches
              cls - Clear prompt area of text
             code - Mark 'CODE' range in disassembly
              col - Mark 'COL' range in disassembly
        colortest - Show value xx as TIA color
                d - Decimal Mode Flag: set (0 or 1), or toggle (no arg)
             data - Mark 'DATA' range in disassembly
      debugcolors - Show Fixed Debug Colors information
           define - Define label xx for address yy
       delbreakif - Delete conditional breakif &lt;xx&gt;
      delfunction - Delete function with label xx
   delsavestateif - Delete conditional savestate point &lt;xx&gt;
          deltrap - Delete trap &lt;xx&gt;
         delwatch - Delete watch &lt;xx&gt;
           disasm - Disassemble address xx [yy lines] (default=PC)
             dump - Dump data at address &lt;xx&gt; [to yy] [1: memory; 2: CPU state; 4: input regs] [?]
             exec - Execute script file &lt;xx&gt; [prefix]
          exitrom - Exit emulator, return to ROM launcher
            frame - Advance emulation by &lt;xx&gt; frames (default=1)
         function - Define function name xx for expression yy
              gfx - Mark 'GFX' range in disassembly
             help - help &lt;command&gt;
           joy0up - Set joystick 0 up direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
         joy0down - Set joystick 0 down direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
         joy0left - Set joystick 0 left direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
        joy0right - Set joystick 0 right direction to value <x> (0 or 1), or toggle (no arg)
         joy0fire - Set joystick 0 fire button to value &lt;x&gt; (0 or 1), or toggle (no arg)
           joy1up - Set joystick 1 up direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
         joy1down - Set joystick 1 down direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
         joy1left - Set joystick 1 left direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
        joy1right - Set joystick 1 right direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
         joy1fire - Set joystick 1 fire button to value &lt;x&gt; (0 or 1), or toggle (no arg)
             jump - Scroll disassembly to address xx
       listbreaks - List breakpoints
       listconfig - List DiStella config directives [bank xx]
    listfunctions - List user-defined functions
 listsavestateifs - List savestate points
        listtraps - List traps
       loadconfig - Load DiStella config file
    loadallstates - Load all emulator states
        loadstate - Load emulator state xx (0-9)
                n - Negative Flag: set (0 or 1), or toggle (no arg)
          palette - Show current TIA palette
               pc - Set Program Counter to address xx
             pcol - Mark 'PCOL' range in disassembly
             pgfx - Mark 'PGFX' range in disassembly
            print - Evaluate/print expression xx in hex/dec/binary
              ram - Show ZP RAM, or set address xx to yy1 [yy2 ...]
            reset - Reset system to power-on state
           rewind - Rewind state by one or [xx] steps/traces/scanlines/frames...
             riot - Show RIOT timer/input status
              rom - Set ROM address xx to yy1 [yy2 ...]
              row - Mark 'ROW' range in disassembly
              run - Exit debugger, return to emulator
            runto - Run until string xx in disassembly
          runtopc - Run until PC is set to value xx
                s - Set Stack Pointer to value xx
             save - Save breaks, watches, traps and functions to file <xx or ?>
       saveaccess - Save access counters to CSV file [?]
       saveconfig - Save DiStella config file (with default name)
          savedis - Save DiStella disassembly to file [?]
          saverom - Save (possibly patched) ROM to file [?]
          saveses - Save console session to file [?]
         savesnap - Save current TIA image to PNG file
    saveallstates - Save all emulator states
        savestate - Save emulator state xx (valid args 0-9)
      savestateif - Create savestate on &lt;condition&gt;
         scanline - Advance emulation by &lt;xx&gt; scanlines (default=1)
             step - Single step CPU [with count xx]
        stepwhile - Single step CPU while &lt;condition&gt; is true
              tia - Show TIA state
            trace - Single step CPU over subroutines [with count xx]
             trap - Trap read/write access to address(es) xx [yy]
           trapif - On &lt;condition&gt; trap R/W access to address(es) xx [yy]
         trapread - Trap read access to address(es) xx [yy]
       trapreadif - On &lt;condition&gt; trap read access to address(es) xx [yy]
        trapwrite - Trap write access to address(es) xx [yy]
      trapwriteif - On &lt;condition&gt; trap write access to address(es) xx [yy]
             type - Show disassembly type for address xx [yy]
             uhex - Toggle upper/lowercase HEX display
            undef - Undefine label xx (if defined)
           unwind - Unwind state state by one or [xx] steps/traces/scanlines/frames...
                v - Overflow Flag: set (0 or 1), or toggle (no arg)
            watch - Print contents of address xx before every prompt
                x - Set X Register to value xx
                y - Set Y Register to value xx
                z - Zero Flag: set (0 or 1), or toggle (no arg)
</pre>

<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="TIATab"></a><u>(B)</u> TIA Tab</a></h2>

<p>When selected, this tab shows detailed status of all the TIA registers
(except for audio; use the Audio tab for those).</p>
<p><img src="graphics/debugger_tiatab.png"></p>

<p>Most of the values on the TIA tab will be self-explanatory to a 2600
developer.<p>

<p>Many of the variables inside the TIA can only be written to by the
6502. The debugger lets you get inside the TIA and see the contents
of these variables. These include the color registers, player/missile
graphics and positions, and the playfield.</p>

<p>You can control almost every aspect of the TIA from here, too: most
of the displays are editable. You can even toggle individual bits in
the GRP0/1 and playfield registers (remember to double-click).</p>

<p>The buttons allow you to write to any of the strobe registers at
any time.</p>

<p>The collision registers are displayed in decoded format, in a table.
You can see exactly which objects have hit what. These are read-only
displays; you can't toggle the bits in the current release of Stella. Of
course, you can clear all the collisions with the CXCLR Strobe button.</p>

<p>To the right of each color register, you'll see a small rectangle
drawn in the current color. Changing a color register will change the
color of this rectangle.</p>

<p>Both player graphics registers (GRP0 and GRP1) come in two versions:
a "new" and an "old" register. Writing GRP0 updates the value in the "new"
version of GRP0 and, at the same time, copies the value in the "new" GRP1
register into its "old" counterpart. Writing to GRP1 behaves the same way,
with the roles of GRP0 and GRP1 switched. The debugger shows both registers,
the "old" register being located below the "new" one. If VDEL is off, the
TIA displays the content of the "new" register, and the debugger tab reflects
this by crossing out the old register. If VDEL is enabled, the TIA displays
the "old" register, and the lines are removed in the tab.</p>

<p>The "enable ball" register (ENABL) also comes in a "new" and an "old"
version. The content of "new" is copied into "old" on writes to GRP1, and
VDELBL selects the register that is used to control the ball. This is
visualized in the debugger in the same way as the two copies of GRP0 and
GRP1</p>

<p>For many registers, writes don't take effect immediatelly as the
TIA takes some color clocks to change state. In Stella's TIA core, this
is implemented by queueing the writes, and the contents of this queue
are visualized in the debugger in the "Queued Writes" area of the TIA tab.</p>

<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="IOTab"><u>(C)</u> I/O Tab</a></h2>

<p>When selected, this tab shows detailed status of the Input, Output,
and Timer portion of the RIOT/M6532 chip (the RAM portion is accessed
in another part of the debugger).</p>
<p><img src="graphics/debugger_iotab.png"></p>

<p>As with the TIA tab, most of the values here will be self-explanatory to a 2600
developer, and almost all can be modified. However, the SWCHx registers need
further explanation:<p>
<p>SWCHx(W) can be modified; here, the (W) stands for write. Similarly,
SWACNT/SWBCNT can be directly modified. However, the results of reading back from
the SWCHx register are influenced by SWACNT/SWBCNT, and SWCHx(R) is a read-only display
reflecting this result.</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="AudioTab"><u>(D)</u> Audio Tab</a></h2>

<p>This tab lets you view the contents of the TIA audio registers and the effective
volume resulting from the two channel volumes.</p>

<p><img src="graphics/debugger_audiotab.png"></p>

<p>This tab will grow some features in a future release.</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="TIADisplay"><u>(E)</u> TIA Display</a></h2>

<p>In the upper left of the debugger, you'll see the current frame of
video as generated by the TIA. If a complete frame hasn't been drawn,
the partial contents of the current frame will be displayed up to the
current scanline, with the contents of the old frame (in black &amp;
white) filling the rest of the display. Note that if 'phosphor mode'
or TV effects are enabled, you won't see the effects here; this shows the
<b>raw</b> TIA image only.</p>

<p>To e.g. watch the TIA draw the frame one scanline at a time, you can
use the 'Scan+1' button, the prompt "scan" command or the Control-L key.</p>

<p>You can also right-click anywhere in this window to show a context menu,
as illustrated:</p>
<p><img src="graphics/debugger_tiaoutcmenu.png"></p>
<p>The options are as follows:</p>
<ul>
  <li><b>Fill to scanline</b>: This option will draw all scanlines up to the
  vertical position where the mouse was clicked (see also <a href="#TIAZoom"><b>TIA Zoom</b></a>).</li>
  <li><b>Toggle breakpoint</b>: Will toggle a conditional breakpoint at the
  scanline where the mouse was clicked. You can also use a left-click or
  the Prompt Tab commands to list and turn off the breakpoint
  (see also <a href="#TIAZoom"><b>TIA Zoom</b></a>).</li>
  <li><b>Set zoom position</b>: Influences what is shown in the TIA
  zoom area (further described in <a href="#TIAZoom"><b>TIA Zoom</b></a>).
  The zoom area will contain the area centered at the position where the
  mouse was clicked.</li>
  <li><b>Save snapshot</b>: Saves the TIA image currently shown,
  including any current 'effects' (fixed debug colors, partial fill, etc).
  </li>
</ul>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="TIAInfo"><u>(F)</u> TIA Information</a></h2>
<p>To the right of the <a href="#TIADisplay"><b>TIA Display</b></a> area, TIA information is displayed (all values are decimal):</p>
<p><img src="graphics/debugger_tiainfo.png"></p>
<p>The indicators are as follows (note that all these are read-only):</p>
<ul>
<li><b>Frame Cycls</b>: The number of CPU cycles that have been executed this frame since
VSYNC was cleared at scanline 0.</li>
<li><b>WSync Cycls</b>: The number of CPU cycles that have been skipped by WSYNC this frame since
VSYNC was cleared at scanline 0.</li>
<li><b>Timer Cycls</b>: The number of CPU cycles (approximately) that have been used by timer read loops since
VSYNC was cleared at scanline 0.</li>
<li><b>Total</b>: The total number of CPU cycles since this ROM was loaded or reset.</li>
<li><b>Delta</b>: The number of CPU cycles that have been executed since the last debugger
interrupt.</li>
<li><b>Frame Cnt.</b>: The number of frames since this ROM was loaded or reset.</li>
<li><b>Scanline</b>: The scanline that's currently being drawn, and the count from the
previous frame. Scanline 0 is the one on which VSYNC is cleared (after being set for
3 scanlines, as per the Stella Programmer's Guide).</li>
<li><b>Scan Cycle</b>: The number of CPU cycles that have been executed since the beginning
of the current scanline.</li>
<li><b>Pixel Pos</b>: The current number of visible color clocks that have been displayed on
the current scanline, starting from the beginning of the Horizontal Blank period.
During HBLANK, this value will be negative (representing the number of clocks
until the first visible one). Since there are 68 color clocks per HBLANK and
160 visible clocks per scanline, the Pixel Position will range from -68 to 159.</li>
<li><b>Color Clock</b>: The current number of total color clocks since the beginning of this
scanline's HBLANK. This counter starts at zero, but otherwise displays the same
information as the Pixel Position (so Color Clock will always be 68 more than Pixel
Position, and will range from 0 to 228).</li>
</ul>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="TIAZoom"><u>(G)</u> TIA Zoom</a></h2>
<p>Below the <a href="#TIAInfo"><b>TIA Information</b></a> is the TIA Zoom area. This allows you to enlarge
part of the TIA display, so you can see fine details. Like the
<a href="#TIADisplay"><b>TIA Display</b></a> area,
this one does generate frames as the real system would.</p>
<p>You can also right-click anywhere in this window to show a context menu,
as illustrated:</p>
<p><img src="graphics/debugger_tiazoomcmenu.png"></p>
<p>These options allow you to:</p>
<ul>
  <li><b>Fill to scanline</b>: This option will draw all scanlines up to the
  vertical position where the mouse was clicked.</li>
  <li><b>Toggle breakpoint</b>: Will toggle a conditional breakpoint at the
  scanline where the mouse was clicked. You can also
  the Prompt Tab commands to list and turn off the breakpoint.</li>
  <li><b>2x|4x|8x zoom</b>: Zoom in on the image for even greater detail.</li>
</ul>
If you click on the output window, you can zoom with the mouse wheel too. And you can
either drag and drop the zoom position with the mouse or you can scroll around using
the cursor,
PageUp/Dn and Home/End keys. You can also select the zoom position from
a context menu in the <a href="#TIADisplay"><b>TIA Display</b></a>.</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="BreakpointStatus"></a><u>(H)</u> Breakpoint/Trap Status</a></h2>
<p>Below the <a href="#TIAZoom"><b>TIA Zoom</b></a> there is a status line that
shows the reason and the address the debugger was entered (if a breakpoint or
trap was hit), as shown:</p>
<p><img src="graphics/debugger_bpstatus.png"></p>
<p>The output here will generally be self-explanatory. Due to space concerns,
the reason will be shown as follows:
<ul>
  <li>"CBP:" for conditional breakpoints</li>
  <li>"BP:" for normal breakpoints</li>
  <li>"RTrap:" for read traps</li>
  <li>"WTrap:" for write traps</li>
  <li>"RTrapIf:" for conditional read traps</li>
  <li>"WTrapIf:" for conditional write traps</li>
  <li>"RWP:" for reads from write ports</li>
  <li>"WRP:" for writes to read ports</li>
</ul>
</p>
See the <a href="#BreakpointsEtc"><b>Breakpoints, watches and traps...</b></a>
section for details.</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="CPURegisters"><u>(I)</u> CPU Registers</a></h2>
<p>This displays the current CPU state, as shown:</p>
<p><img src="graphics/debugger_cpuregs.png"></p>
<p>All the registers and flags are displayed, and can be changed by
double-clicking on them (to the left). Flags are toggled on double-click.
Selected registers here can also be changed by using the 'Data Operations' buttons,
further described in (J). All items are shown in hex. Any label defined for the
current PC value is shown to the right. Decimal and binary equivalents
are shown for SP/A/X/Y to the right (first decimal, then binary).</p>
<p>The column to the far right shows the 'source' of contents of the respective
registers. For example, consider the command 'LDA ($80),Y'. The operand of
the command resolves to some address, which isn't always easy to determine at
first glance. The 'Src Addr' area shows the actual resulting operand/address
being used with the given opcode.</p>
<p>The destination address of the last write is shown besides 'Dest'.</p>

<p>There's not much else to say about the CPU Registers widget: if you know 6502
assembly, it's pretty self-explanatory. If you don't, well, you should
learn :)</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="DataOpButtons"><u>(J)</u> Data Operations Buttons</a></h2>
<p>These buttons can be used to change values in either
<a href="#CPURegisters"><b>CPU Registers</b></a>,
the <a href="#M6532"><b>M6532/RIOT RAM</b></a> or
<a href="#CartridgeRAMInformation"><b>Detailed Cartridge Extended RAM Information</b></a>,
depending on which of these widgets is currently in focus.
<p><img src="graphics/debugger_dataops.png"></p>
<p>Each of these buttons also have a keyboard shortcut (indicated in square
brackets). In fact, many of the inputboxes in various parts of the debugger
respond to these same keyboard shortcuts. If in doubt, give them a try.</p>
<table border="1" cellpadding=4>
  <tr>
    <th>Button</th><th>Shortut</th><th>Description</th>
  </tr>
  <tr>
    <td>0</td><td><pre>'z'</pre></td><td>Set the current location/register to zero.</td>
  </tr><tr>
    <td>Inv</td><td><pre>'i' or '!'</pre></td><td>Invert the current location/register (toggle all its bits)</td>
  </tr><tr>
    <td>Neg</td><td><pre>'n'</pre></td><td>Negate the current location/register (twos' complement negative)</td>
  </tr><tr>
    <td>++</td><td><pre>'+' or '='</pre></td><td>Increment the current location/register.</td>
  </tr><tr>
    <td>--</td><td><pre>'-'</pre></td><td>Decrement the current location/register.</td>
  </tr><tr>
    <td>&lt;&lt;</td><td><pre>'&lt;' or ','</pre></td><td>Shift the current location/register left.</td>
  </tr><tr>
    <td>&gt;&gt;</td><td><pre>'&gt;' or '.'</pre></td><td>Shift the current location/register right.</td>
  </tr>
</table>
<p>Any bits shifted out of the location/register with &lt;&lt; or &gt;&gt;
are lost (they will NOT end up in the Carry flag).</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="M6532"><u>(K)</u> M6532/RIOT RAM</a></h2>
<p>This is a spreadsheet-like GUI for inspecting and changing the contents
of the 2600's zero-page RAM.</p>
<p>You can navigate with either the mouse or the keyboard arrow keys.
To change a RAM location, either double-click on it or press 'Enter' while
it's highlighted. Enter the new value (hex, other formats using the bottom textboxes), then
press 'Enter' to make the change. The currently selected RAM cell
can also be changed by using the
<a href="#DataOpButtons"><b>Data Operations Buttons</b></a> or the associated
shortcut keys.</p>
<p><img src="graphics/debugger_ram.png"></p>
<p>The 'Undo' button in the upper right should be self-explanatory; it will
undo the most previous operation to one cell only. The 'Revert' button is
more comprehensive. It will undo <b>all</b> operations on <b>all</b> cells
since you first made a change.</p>
<p>The UI objects at the bottom refer to the currently selected RAM cell.
The 'Label' textbox shows the label attached to this RAM location (if any),
and the other three textboxes show the hex, decimal and binary equivalent value.
The values can be edited here too.</p>

<p>The remaining buttons to the right are further explained in the next section.</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<h3><a name="M6532Search"><u>(L)</u> M6532/RIOT RAM (search/compare mode)</a></h3>
<p>The RAM widget also lets you search memory for values such as lives or remaining
energy, but it's also very useful when debugging to determine which
memory location holds which quantity.</p>
<p><img src="graphics/debugger_ramsearch.png"></p>
<p>To search the RAM, click 'Search...' and enter a byte value into the search editbox (0-255).
All matching values will be highlighted in the RAM widget. If no value was entered,
all RAM locations will be highlighted.</p>

<p>The 'Compare...' button is used to compare the given value using all
addresses currently highlighted. This may be an absolute number (such as 2),
or a comparative number (such as -1). Using a '+' or '-' operator
means 'search addresses for values that have changed by that amount'.</p>
<p>The 'Reset' button resets the entire operation; it clears the highlighted
addresses and allows another search.</p>
<p>The following is an example of inspecting all addresses that have
decreased by 1:</p>
<ul>
  <li>Click 'Search...' and then 'OK' (no value entered). All address/values are highlighted</li>
  <li>Exit debugger mode and lose a life, let your energy decrease, or
    do whatever it is you're trying to debug</li>
  <li>Enter debugger mode again, click 'Compare...' and and enter a '-1' for input.
    This finds all values that have decreased by 1 (as compared to their current
    values)</li>
  <li>Repeatedly following these steps may help to narrow number of
    addresses under consideration, and eventually you'll find the
    memory address you're looking for</li>
  <li>Click 'Reset' when you're finished</li>
</ul>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="Disassembly"></a><u>(M)</u> ROM Disassembly</a></h2>
<p>This area contains a disassembly of the current bank of ROM. If a symbol
file is loaded, the disassembly will have labels. Even without a symbol file, the standard TIA/RIOT labels will still be present.</p>
<p>The disassembly is often quite extensive, and whenever possible tries to automatically
differentiate between code, graphics, data and unused bytes. There are actually two
levels of disassembly in Stella. First, the emulation core tracks accesses as a game
is running, making for very accurate results. This is known as a <b>dynamic</b> analysis.
Second, the built-in DiStella code does a <b>static</b> analysis, which tentatively fills
in sections that the dynamic disassembler missed (usually because the addresses haven't
been accessed at runtime yet).</p>
<p>As such, code can be marked in two ways (absolute, when done by the emulation core),
and tentative (when done by DiStella, and the emulation core hasn't accessed it yet).
Such 'tentative' code is marked with the '*' symbol, indicating that it has the potential
to be accessed as code sometime during the program run. This gives very useful information,
since it can indicate areas toggled by an option in the game (ie, when a player dies,
when difficulty level changes, etc). It can also indicate whether blocks of code after
a relative jump are in fact code, or simply data.</p>


<p><img src="graphics/debugger_rom.png"></p>

<p>The <B>"Bank state"</B> is self-explanatory, and shows a summary of the current
bank information. For normal bankswitched ROMs, this will be the current bank number,
however more advanced schemes will show other types of information here. More detailed
information is available in <a href="#BankswitchInformation"><b>Detailed Bankswitch Information</b></a>.</p>

<p>Each line of disassembly has four fields:</p>
<ul>
<li><b>Breakpoint</b>: This is the area at the far left, to the left of the
labels. Normally there will be nothing there: this indicates that there's
no breakpoint set at that address. You can set and clear breakpoints by
clicking in this area. When a breakpoint is set, there will be a
red circle in this area. These are the same breakpoints as used
by the <a href="#Breakpoints">break</a> command, <b>not</b> the conditional "breakif" breakpoints
(which makes sense: conditional breaks can break on any condition, the Program
Counter isn't necessarily involved).</li>
<li><b>Labels</b>: Any labels assigned to the given address, either generated
automatically by DiStella, read from a DASM symbol file or custom
labels created by the user. If 'Show PC addresses'
(see <a href="#DisassemblySettings"><b>ROM Disassembly Settings</b></a>) is enabled,
the address will be shown in grey.</li>
<li><b>Disassembled bytes</b>: This is either a standard 6502 mnemonic (possibly with operand),
or information about graphics and/or data. For instructions, the cycle count will be
included, separated by a semicolon. For graphics, a bitmap of the data, and the address
of the data is included. For actual data, only the address is included.</li>
<li><b>Hex bytes</b>: These are the raw machine bytes for the code/graphics/data.
Note that only code, graphics or data will show bytes and can be edited.</li>
</ul>

<p>At this point, we should explain the various 'types' that the disassembler
can use. These are known as 'directives', and partly correspond to configuration
options from the standalone DiStella program. They are listed in order of
decreasing hierarchy:</p>
<table border="1" cellpadding=4>
  <tr>
    <td>
      <b>CODE</b>
    </td><td>
      Addresses which have appeared in the program counter, or
      which tentatively can appear in the program counter. These can be edited in hex.
    </td>
    </tr><tr>
    <td>
      <b>GFX</b>
    </td><td>
      Addresses which contain data stored in the player graphics registers
      (GRP0/GRP1). These addresses are shown with a bitmap of the graphics, which
      can be edited in either hex or binary. The bitmap is shown as large blocks.
    </td>
  </tr><tr>
    <td>
      <b>PGFX</b>
    </td><td>
      Addresses which contain data stored in the playfield graphics registers
      (PF0/PF1/PF2). These addresses are shown with a bitmap of the graphics, which
      can be edited in either hex or binary. The bitmap is shown as small dashes.
    </td>
  </tr><tr>
    <td>
      <b>COL</b>
    </td><td>
      Addresses which contain data stored in the player color registers
      (COLUP0/COLUP1). These addresses are shown as color constants, which
      can be edited in hex. The color constant names are depending on the ROM's TV type.
    </td>
  </tr><tr>
    <td>
      <b>PCOL</b>
    </td><td>
      Addresses which contain data stored in the playfield color register
      (COLUPF). These addresses are shown as color constants, which
      can be edited in hex. The color constant names are depending on the ROM's TV type.
    </td>
  </tr><tr>
    <td>
      <b>BCOL</b>
    </td><td>
      Addresses which contain data stored in the background color register
      (COLUBK). These addresses are shown as color constants, which
      can be edited in hex. The color constant names are depending on the ROM's TV type.
    </td>
  </tr><tr>
    <td>
      <b>AUD</b>
    </td><td>
      Addresses which contain data stored in the audio registers
      (AUDC0/AUDC1/AUDF0/AUDF1/AUDV0/AUDV1). These can be edited
      in hex.
    </td>
  </tr><tr>
    <td>
      <b>DATA</b>
    </td><td>
      Addresses used as an operand for some opcode. These can be edited
      in hex.
    </td>
  </tr><tr>
    <td>
      <b>ROW</b>
    </td><td>
      Addresses not used as any of the above. These are shown up
      to 8 per line and cannot be edited.
    </td>
  </tr>
</table>

<p>For code sections, the 6502 mnemonic will be UPPERCASE for all standard instructions,
or lowercase for "illegal" 6502 instructions (like "dcp"). If automatic resolving
of code sections has been disabled for any reason, you'll likely see a lot
of illegal opcodes if you scroll to a data table in ROM. This can also
occur if the disassembler hasn't yet encountered addresses in the PC.
If you step/trace/scanline/frame advance into such an area, the disassembler
will make note of it, and disassemble it correctly from that point on.</p>

<!-- TODO - is this true any longer?
<p>Beware: the cycle counts don't take into account any penalty cycles
for crossing page boundaries. All branches are shown as 2 cycles, which
is how long they take if the branch isn't taken. Branches that are
taken will actually take 3 cycles (plus a penalty cycle if they cross
page boundaries).</p> -->

<p>You can scroll through the disassembly with the mouse or keyboard. To
center the display on the current PC, press the Space bar.</p>

<p>Any time the Program Counter changes (due to a Step, Trace, Frame
or Scanline advance, or manually setting the PC), the disassembly will
scroll to the current PC location.</p>

<p>Even though ROM is supposed to be Read Only Memory, this is an
emulator: you can change ROM all you want within the debugger. The hex
bytes in the ROM Widget are editable. Double-click on them to edit
them. When you're done, press Enter to accept the changes (in which case
the cart will be re-disasembled) or Escape to cancel them.
Note that only instructions that have been fully disassembled
can be edited. In particular, blank lines or 'ROW' directives
cannot be edited. Also note that certain ROMs can have
sections of address space swapped in and out dynamically. As such, changing
the contents of a certain address will change the area pointed to <b>at
that time</b>. In particular, modifying an address that points to internal
RAM will change the RAM, not the underlying ROM. A future release may
graphically differentiate between RAM and ROM areas.</p>

<h3><a name="DisassemblySettings"></a>ROM Disassembly Settings</a></h3>

<p>The ROM Disassembly also contains a Settings dialog, accessible by right-clicking
anywhere in the listing:</p>
<p><img src="graphics/debugger_romcmenu.png"></p>
<p>The following options are available:</p>
<ul>
<li><b>Set PC @ current line</b>: Set the Program Counter to the address of the
disassembly line where the mouse was clicked.</li>

<li><b>RunTo PC @ current line</b>: Single-step through code until the Program Counter
matches the address of the disassembly line where the mouse was clicked.</li>

<li><b>Disassemble @ current line</b>: Disassemble from the disassembly line where the mouse was clicked.
This allows to fill gaps in the disassembly and is most useful for bankswitched ROMs.</li>

<li><b>Show tentative code</b>: Allow DiStella to do a static analysis/disassembly.</li>

<li><b>Show PC addresses</b>: Show Program Counter addresses as labels (where there
isn't already a defined label).</li>

<li><b>Show GFX as binary</b>: Switch between displaying/editing GFX and PGFX sections
in either binary or hexidecimal.</li>

<li><b>Use address relocation</b>: Corresponds to the DiStella '-r' option
(Relocate calls out of address range).</br>
Note: The code will continue to run fine, but the ROM image will be altered.</li>

</ul>

<h3><a name="Limitations">Limitations</a></h3>

<ul>

<li>The ROM Widget only works on ROM or zero-page RAM separately. If your game runs
code from zero-page RAM, the disassembly will show addresses $80 to $FF (zero-page
RAM address space) only. Once your RAM routine returns, the ROM Widget will switch
back to ROM space ($1000 - $1FFF and mirrors). The same is true of the "disasm"
command; it will show either ROM or RAM space, not both at the same time.</li>

<li>The standard VCS memory map has the cartridge port at locations
$F000-$FFFF. However, not all the address lines exist on a 6507, so
the cartridge port is "mirrored" at every other 4K chunk of address
space ($1000, $3000, up to $D000). Some developers find it easier
to think of the different banks of ROM as being at different addresses
(such as: Bank 0 at $D000 and bank 1 at $F000). When such a ROM runs,
the Program Counter can point to one of the mirrors instead of the main
area at $F000. This is perfectly OK, and everything works just fine.
However, breakpoints are set on actual addresses. If there were a breakpoint
set at $F010, and the bank later switched to mirror $D000, the breakpoint
will not be shown, and will not break on $D010, even though it's technically
the same address.</li>

</ul>

<p>These limitations will be addressed in a future release of Stella.</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="BankswitchInformation"><u>(N)</u> Detailed Bankswitch Information</a></h2>

<p>This area shows a detailed breakdown of the bankswitching scheme. Since
the bankswitch schemes can greatly vary in operation, this tab will be
different for each scheme, but its specific functionality should be self-explanatory.
An example of both 4K (non-bankswitched) and DPC (Pitfall II) is as follows:</p>

<p><img src="graphics/debugger_banksimple.png"></p>
<p><img src="graphics/debugger_bankcomplex.png"></p>

<p>In many cases, quite a bit of the scheme functionality can be modified.
Go ahead and try to change something!</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="CartridgeRAMInformation"><u>(O)</u> Detailed Cartridge Extended RAM Information</a></h2>

<p>If applicable, this area shows a detailed breakdown of any extra RAM supported by
the bankswitching scheme. Since the bankswitch schemes can greatly vary in operation,
this tab will be different for each scheme, but its specific functionality should be
self-explanatory. An example of both F6SC (16K Atari + ram) and DPC (Pitfall II) is
as follows:</p>

<p><img src="graphics/debugger_ram-f8sc.png"></p>
<p><img src="graphics/debugger_ram-dpc.png"></p>

<p>The RAM is shown in a grid similar to how zero-page RAM is shown in M6532/RIOT RAM
(K) and (L). See those sections for a description of usage.

<p>In the cases where RAM is always mapped into the same place in the cartridge
address space (such as Sara-chip), the RAM addresses are labeled as such. In other
cases, such as when the RAM is either quiescent (and mapped in at different places),
or not viewable by the 6507 at all, the RAM addresses are labeled as the cart sees them.
In the examples above, F8SC RAM is labeled starting at its read port, or $F080. However,
the RAM in the DPC scheme is not viewable by the 6507, so its addresses start from $0.

<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h1><a name="DistellaConfiguration">DiStella Configuration Files</a></h1>
<p>As mentioned in <a href="#Disassembly"><b>ROM Disassembly</b></a>, Stella supports the following directives:
CODE, GFX, PGFX, COL, PCOL, BCOL, AUD, DATA, ROW. While the debugger will try to automatically mark address
space with the appropriate directive, there are times when it will fail. There are
several options in this case:</p>
<ol>
<li><b>Manually set the directives</b>: Directives can be set in the debugger
prompt with the aud/code/col/bcol/gfx/pcol/pgfx/data/row commands. These accept an address range
for the given directive type. Setting a range with the same type a second time
will remove that directive from the range.</li>
<li><b>Use configuration files</b>: Configuration files can be used to automatically
load a list of directives when a ROM is loaded. These files can be generated with the
'saveconfig' command, and loaded with the 'loadconfig' command. There are also
'listconfig' and 'clearconfig' commands to show and erase (respectively) the current
directive listing. Upon opening the debugger for the first time, Stella attempts
to load a configuration file from the folder containing the ROM.  Assuming a ROM named "rr.a26" exists, the config file must be named <i>rr.cfg</i>.
</ul>
</table>
</li>
</ol>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h1><a name="HowToHack">Tutorial: How to hack a ROM</a></h1>

<p>Here is a step-by-step guide that shows you how to use the debugger to
actually do something useful. No experience with debuggers is necessary,
but it helps to know at least a little about 6502 programming.</p>

<ol>
  <li>Get the Atari Battlezone ROM image. Make sure you've got the
    regular NTSC version. Load it up in Stella and press TAB to get to
    the main menu. From there, click on "Game Information". For "Name", it
    should say "Battlezone (1983) (Atari)" and for MD5Sum it should say
    "41f252a66c6301f1e8ab3612c19bc5d4". The rest of this tutorial assumes
    you're using this version of the ROM; it may or may not work with the
    PAL version, or with any of the various "hacked" versions floating around
    on the 'net.</li>

  <li>Start the game. You begin the game with 5 lives (count the tank
    symbols at the bottom of the screen).</li>

  <li>Enter the debugger by pressing the ` (backquote) key. Don't get
    killed before you do this, though. You should still have all 5 lives.</li>

  <li>In the RAM display, click the 'Search' button and enter "5" for input.
    This searches RAM for your value and highlights all addresses that match
    the input. You should see two addresses highlighted: "00a5" and "00ba".
    These are the only two addresses that currently have the value 5, so they're
    the most likely candidates for "number of lives" counter. (However, some
    games might actually store one less than the real number of lives, or
    one more, so you might have to experiment a bit. Since this is a "rigged
    demo", I already know Battlezone stores the actual number of lives.
    Most games do, actually).</li>

  <li>Exit the debugger by pressing ` (backquote) again. The game will
    pick up where you left off.</li>

  <li>Get killed! Ram an enemy tank, or let him shoot you. Wait for
    the explosion to finish. You will now have 4 lives.</li>

  <li>Enter the debugger again. Click the 'Compare...' button in RAM widget and enter
    a value of 4. Now the RAM widget should only show one highlighted address:
    "00ba". What we did was search within our previous results (the ones that
    were 5 before) for the new value 4. Address $00ba used to have the value 5,
    but now it has 4. This means that Battlezone (almost certainly) stores the
    current number of lives at address $00ba.</li>

  <li>Test your theory. Go to the RAM display and change address $ba to
    some high number like $ff (you could use the Prompt instead: enter "ram
    $ba $ff"). Exit the debugger again (or advance the frame). You should now see lots of lives
    at the bottom of the screen (of course, there isn't room to display $ff
    (255) of them!)... play the game, get killed a few times, notice that
    you have lots of lives.</li>

  <li>Now it's time to decide what sort of "ROM hack" we want to
    accomplish. We've found the "lives" counter for the game, so we can
    either have the game start with lots of lives, or change the game
    code so we can't get killed (AKA immortality), or change the code
    so we always have the same number of lives (so we never run out, AKA
    infinite lives). Let's go for infinite lives: it's a little harder than
    just starting with lots of lives, but not as difficult as immortality
    (for that, we have to disable the collision checking code, which means
    we have to find and understand it first!)</li>

  <li>Set a Write Trap on the lives counter address: "trapwrite $ba"
    in the Prompt. Exit the debugger and play until you get killed. When
    you die, the trap will cause the emulator to enter the debugger with the
    Program Counter pointing to the instruction *after* the one that wrote
    to location $ba.</li>

  <li>Once in the debugger, look at the ROM display. The PC should be at address
    $f238, instruction "LDA $e1". You want to examine a few instructions before
    the PC, so scroll up using the mouse or arrow keys. Do you see
    the one that affects the lives counter? That's right, it's the "DEC $ba"
    at location $f236.</li>

  <li>Let's stop the DEC $ba from happening. We can't just delete the
    instruction (it would mess up the addressing of everything afterwards,
    if it were even possible), but we can replace it with some other
    instruction(s).

    <p>Since we just want to get rid of the instruction, we can replace it with
    NOP (no operation). From looking at the disassembly, you can see that
    "DEC $ba" is a 2-byte long instruction, so we will need two one-byte
    NOP instructions to replace it. From reading the prompt help (the "help"
    command), you can see that the "rom" command is what we use to patch ROM.

    <p>Unfortunately, Stella doesn't contain an assembler, so we can't just
    type NOP to put a NOP instruction in the code. We'll have to use the
    hex opcode instead.

    <p>Now crack open your 6502 reference manual and look up the NOP
    instruction's opcode... OK, OK, I'll just tell you what it is: it's $EA
    (234 decimal). We need two of them, so the bytes to insert will look like:

    <pre>    $ea $ea</pre>

    <p>Select the line at address $f236 and enter 'ROM patch' mode. This is done
    by either double-clicking the line, or pressing enter. Then delete the bytes
    with backspace key and enter "ea ea". Another way to do this would have been
    to enter "rom $f236 $ea $ea" in the Prompt widget.
  </li>

  <li>Test your patch. First, set location $ba to some number of
    lives that can be displayed on the screen ("poke $ba 3" or enter directly into
    the RAM display). Now exit the debugger and play the game. You should see 3
    lives on the screen.</li>

  <li>The crucial test: get killed again! After the explosion, you
    will *still* see 3 lives: Success! We've hacked Battlezone to give us
    infinite lives.</li>

  <li>Save your work. In the prompt: "saverom". You now
    have your very own infinite-lives version of Battlezone. The file will
    be saved in your HOME directory (NOT your ROM directory), so you might
    want to move it to your ROM directory if it isn't the current directory.
  </li>

  <li>Test the new ROM: exit Stella, and re-run it. Open your ROM
    (or give its name on the command line) and play the game. You can play
    forever! It worked.</li>
</ol>

<p>Now, try the same techniques on some other ROM image (try Pac-Man). Some
games store (lives+1) or (lives-1) instead of the actual number,
so try searching for those if you can't seem to make it work.</p>

<p>If you successfully patch a ROM in the debugger, but the saved version
won't work, or looks funny, you might need to add an entry to the
stella.pro file, to tell Stella what bankswitch and/or TV type to use.
That's outside the scope of this tutorial :)</p>

<p>Of course, the debugger is useful for a lot more than cheating and
hacking ROMs. Remember, with great power comes great responsibility,
so you have no excuse to avoid writing that game you've been thinking
about for so long now :)</p>