git @ Cat's Eye Technologies linapple / master inc / Debugger_Types.h
master

Tree @master (Download .tar.gz)

Debugger_Types.h @masterraw · history · blame

   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
#pragma once


// Addressing _____________________________________________________________________________________

  enum
  {
//    MAX_ADDRESSING_MODE_LEN = 12

    MAX_OPMODE_FORMAT = 12,
    MAX_OPMODE_NAME   = 32

    , NO_6502_TARGET = -1
    , _6502_NUM_FLAGS = 8
  };

  enum RangeType_t
  {
    RANGE_MISSING_ARG_2 = 0, // error
    RANGE_HAS_LEN          , // valid case 1
    RANGE_HAS_END          , // valid case 2
  };

  struct AddressingMode_t
  {
    char  m_sFormat[ MAX_OPMODE_FORMAT ];
    int   m_nBytes;
    char  m_sName  [ MAX_OPMODE_NAME ];
  };

  /*
      +---------------------+--------------------------+
      | Opmode  e           |     assembler format     |
      +=====================+==========================+
      | Immediate           |          #aa             |
      | Absolute            |          aaaa            |
      | Zero Page           |          aa              |   Note:
      | Implied             |                          |
      | Indirect Absolute   |          (aaaa)          |     aa = 2 hex digits
      | Absolute Indexed,X  |          aaaa,X          |          as $FF
      | Absolute Indexed,Y  |          aaaa,Y          |
      | Zero Page Indexed,X |          aa,X            |     aaaa = 4 hex
      | Zero Page Indexed,Y |          aa,Y            |          digits as
      | Indexed Indirect    |          (aa,X)          |          $FFFF
      | Indirect Indexed    |          (aa),Y          |
      | Relative            |          aaaa            |     Can also be
      | Accumulator         |          A               |     assembler labels
      +---------------------+--------------------------+
      (Table 2-3. _6502 Software Design_, Scanlon, 1980)

  Opcode: opc aaa od
    opc...od = Mnemonic / Opcode
    ...aaa.. = Addressing g_nAppMode
  od = 00
    000  #Immediate
    001  Zero page
    011  Absolute
    101  Zero page,X
    111  Absolute,X
  od = 01
    000  (Zero page,X)
    001  Zero page
    010  #Immediate
    011  Absolute
    100  (Zero page),Y
    101  Zero page,X
    110  Absolute,Y
    111  Absolute,X
  od = 10
    000  #Immediate
    001  Zero page
    010  Accumulator
    011  Absolute
    101  Zero page,X
    111  Absolute,X
  */
  /*
    Legend:
      A = Absolute (fortunately Accumulator is implicit, leaving us to use 'A')
      I = Indexed  ( would of been X, but need reg X)
      M = iMmediate
      N = iNdirect
      R = Relative
      X = Offset X Register
      Y = Offset Y Register
      Z = Zeropage
  */
  enum AddressingMode_e // ADDRESSING_MODES_e
  {
      AM_IMPLIED // Note: SetDebugBreakOnInvalid() assumes this order of first 4 entries
    , AM_1    //    Invalid 1 Byte
    , AM_2    //    Invalid 2 Bytes
    , AM_3    //    Invalid 3 Bytes
    , AM_M    //  4 #Immediate
    , AM_A    //  5 $Absolute
    , AM_Z    //  6 Zeropage
    , AM_AX   //  7 Absolute, X
    , AM_AY   //  8 Absolute, Y
    , AM_ZX   //  9 Zeropage, X
    , AM_ZY   // 10 Zeropage, Y
    , AM_R    // 11 Relative
    , AM_IZX  // 12 Indexed (Zeropage Indirect, X)
    , AM_IAX  // 13 Indexed (Absolute Indirect, X)
    , AM_NZY  // 14 Indirect (Zeropage) Indexed, Y
    , AM_NZ   // 15 Indirect (Zeropage)
    , AM_NA   // 16 Indirect (Absolute) i.e. JMP

    , NUM_ADDRESSING_MODES
    , NUM_OPMODES = NUM_ADDRESSING_MODES
    , AM_I = NUM_ADDRESSING_MODES, // for assemler

  // Deprecated
  /*
    ADDR_INVALID1  =  1,
    ADDR_INVALID2  =  2,
    ADDR_INVALID3  =  3,
    ADDR_IMM       =  4, // Immediate
    ADDR_ABS       =  5, // Absolute
    ADDR_ZP        =  6, // Zeropage
    ADDR_ABSX      =  7, // Absolute + X
    ADDR_ABSY      =  8, // Absolute + Y
    ADDR_ZP_X      =  9, // Zeropage + X
    ADDR_ZP_Y      = 10, // Zeropage + Y
    ADDR_REL       = 11, // Relative
    ADDR_INDX      = 12, // Indexed (Zeropage) Indirect
    ADDR_ABSIINDX  = 13, // Indexed (Absolute) Indirect
    ADDR_INDY      = 14, // Indirect (Zeropage) Indexed
    ADDR_IZPG      = 15, // Indirect (Zeropage)
    ADDR_IABS      = 16, // Indirect Absolute (i.e. JMP)
  */
  };


// Assembler ______________________________________________________________________________________

  enum Prompt_e
  {
    PROMPT_COMMAND,
    PROMPT_ASSEMBLER,
    NUM_PROMPTS
  };


// Bookmarks ______________________________________________________________________________________

  enum
  {
    MAX_BOOKMARKS = 10
  };

// Breakpoints ____________________________________________________________________________________

  enum
  {
    MAX_BREAKPOINTS = 16
  };

  /*
    Breakpoints are now in a tri-state.
    This allows one to set a bunch of breakpoints, and re-enable the ones you want
    without having to remember which addresses you previously added. :-)

    The difference between Set and Enabled breakpoints:

      Set  Enabled  Break?
      x    x        yes, listed as full brightness
      x    -        no, listed as dimmed
      -    ?        no, not listed
  */
  // NOTE: Order must match _PARAM_REGS_*
  // NOTE: Order must match Breakpoint_Source_t
  // NOTE: Order must match g_aBreakpointSource
  enum BreakpointSource_t
  {
    BP_SRC_REG_A ,
    BP_SRC_REG_X ,
    BP_SRC_REG_Y ,

    BP_SRC_REG_PC, // Program Counter
    BP_SRC_REG_S , // Stack Counter

    BP_SRC_REG_P , // Processor Status
    BP_SRC_FLAG_C, // Carry
    BP_SRC_FLAG_Z, // Zero
    BP_SRC_FLAG_I, // Interrupt
    BP_SRC_FLAG_D, // Decimal
    BP_SRC_FLAG_B, // Break
    BP_SRC_FLAG_R, // Reserved
    BP_SRC_FLAG_V, // Overflow
    BP_SRC_FLAG_N, // Sign

    BP_SRC_OPCODE,
    BP_SRC_MEM_1 ,

    NUM_BREAKPOINT_SOURCES
  };

  // Note: Order must match Breakpoint_Operator_t
  // Note: Order must much _PARAM_BREAKPOINT_*
  // Note: Order must match g_aBreakpointSymbols
  enum BreakpointOperator_t
  {
    BP_OP_LESS_EQUAL   , // <= REG
    BP_OP_LESS_THAN    , // <  REG
    BP_OP_EQUAL        , // =  REG
    BP_OP_NOT_EQUAL    , // != REG
//    BP_OP_NOT_EQUAL_1  , // !  REG
    BP_OP_GREATER_THAN , // >  REG
    BP_OP_GREATER_EQUAL, // >= REG
    BP_OP_READ         , // @  MEM @ ? *
    BP_OP_WRITE        , // *  MEM @ ? *
    BP_OP_READ_WRITE   , // ?  MEM @ ? *
    NUM_BREAKPOINT_OPERATORS
  };

  struct Breakpoint_t
  {
    WORD                 nAddress; // for registers, functions as nValue
    WORD                 nLength ;
    BreakpointSource_t   eSource;
    BreakpointOperator_t eOperator;
    bool                 bSet    ; // used to be called enabled pre 2.0
    bool                 bEnabled;
  };

  typedef Breakpoint_t Bookmark_t;
  typedef Breakpoint_t Watches_t;
  typedef Breakpoint_t ZeroPagePointers_t;


// Colors ___________________________________________________________________

  enum Color_Schemes_e
  {
    SCHEME_COLOR, // NOTE: MUST match order in CMD_WINDOW_COLOR
    SCHEME_MONO , // NOTE: MUST match order in CMD_WINDOW_MONOCHROME
    SCHEME_BW   , // NOTE: MUST match order in CMD_WINDOW_BW
//    SCHEME_CUSTOM
    NUM_COLOR_SCHEMES
  };

  // Named, since they are easier to remember.
  // Ok, maybe RGB + CYMK is a little "too" cute. But what the hell, it works out nicely.
   enum DebugPalette_e
  {
    // mipmap level:   8   7   6   5   4   3   2   1   0
    // color depth:  256 224 192 160 128  96  64  32   0
    //               +32 +32 +32 +32 +32 +32 +32 +32
    // NOTE: Levels of black are redundant.
    //                              // BGR
    K0,                             // ---  K
    R8, R7, R6, R5, R4, R3, R2, R1, // --1  R  Red
    G8, G7, G6, G5, G4, G3, G2, G1, // -1-  G  Green
    Y8, Y7, Y6, Y5, Y4, Y3, Y2, Y1, // -11  Y  Yellow
    B8, B7, B6, B5, B4, B3, B2, B1, // 1--  B  Blue
    M8, M7, M6, M5, M4, M3, M2, M1, // 1-1  M  Magenta
    C8, C7, C6, C5, C4, C3, C2, C1, // 11-  C  Cyan
    W8, W7, W6, W5, W4, W3, W2, W1, // 111  W  White / Gray / Black

    COLOR_CUSTOM_01, COLOR_CUSTOM_02, COLOR_CUSTOM_03, COLOR_CUSTOM_04,
    COLOR_CUSTOM_05, COLOR_CUSTOM_06, COLOR_CUSTOM_07, COLOR_CUSTOM_08,
    COLOR_CUSTOM_09, COLOR_CUSTOM_11, CUSTOM_COLOR_11, COLOR_CUSTOM_12,
    COLOR_CUSTOM_13, COLOR_CUSTOM_14, COLOR_CUSTOM_15, COLOR_CUSTOM_16,

    NUM_PALETTE,

    // Gray Aliases
    G000 = K0,
    G032 = W1,
    G064 = W2,
    G096 = W3,
    G128 = W4,
    G160 = W5,
    G192 = W6,
    G224 = W7,
    G256 = W8
  };

  // Yeah, this was a PITA to organize.
  enum DebugColors_e
  {
      BG_CONSOLE_OUTPUT  // Black   Window
    , FG_CONSOLE_OUTPUT  // White
    , BG_CONSOLE_INPUT   // Black   Window
    , FG_CONSOLE_INPUT   // Light Blue

    , BG_DISASM_1        // Blue*   Odd address
    , BG_DISASM_2        // Blue*   Even address

    , BG_DISASM_BP_S_C   // Red     Breakpoint Set     (cursor)
    , FG_DISASM_BP_S_C   // White   Breakpoint Set&Ena (cursor)

    // Note: redundant BG_DISASM_BP_0_C = BG_DISASM_BP_S_C
    , BG_DISASM_BP_0_C   // DimRed  Breakpoint Disabled (cursor)
    , FG_DISASM_BP_0_C   // Gray192 Breakpoint Disabled (cursor)

    , FG_DISASM_BP_S_X   // Red     Set      (not cursor)
    , FG_DISASM_BP_0_X   // White   Disabled (not cursor)

    , BG_DISASM_C        // White (Cursor)
    , FG_DISASM_C        // Blue  (Cursor)

    , BG_DISASM_PC_C     // Yellow (not cursor)
    , FG_DISASM_PC_C     // White  (not cursor)

    , BG_DISASM_PC_X     // Dim Yellow (not cursor)
    , FG_DISASM_PC_X     // White      (not cursor)

    , BG_DISASM_BOOKMARK // Lite Blue    (always)
    , FG_DISASM_BOOKMARK // White   addr (always)

    , FG_DISASM_ADDRESS  // White   addr
    , FG_DISASM_OPERATOR // Gray192     :               $ (also around instruction addressing g_nAppMode)
    , FG_DISASM_OPCODE   // Yellow       xx xx xx
    , FG_DISASM_MNEMONIC // White                   LDA
    , FG_DISASM_TARGET   // Orange                       FAC8
    , FG_DISASM_SYMBOL   // Purple                       HOME
    , FG_DISASM_CHAR     // Cyan                               'c'
    , FG_DISASM_BRANCH   // Green                                   ^ = v

    , BG_INFO            // Cyan    Regs/Stack/BP/Watch/ZP
    , FG_INFO_TITLE      // White   Regs/Stack/BP/Watch/ZP
    , FG_INFO_BULLET     //         1
    , FG_INFO_OPERATOR   // Gray192  :    -
    , FG_INFO_ADDRESS    // Orange    FA62 FA63 (Yellow -> Orange)
    , FG_INFO_OPCODE     // Yellow              xx
    , FG_INFO_REG        // Orange (Breakpoints)
    , BG_INFO_INVERSE    // White
    , FG_INFO_INVERSE    // Cyan
    , BG_INFO_CHAR       // mid Cyan
    , FG_INFO_CHAR_HI    // White
    , FG_INFO_CHAR_LO    // Yellow

    , BG_INFO_IO_BYTE    // Orange (high bit)
    , FG_INFO_IO_BYTE    // Orange (non-high bit)

    , BG_DATA_1          // Cyan*   Window
    , BG_DATA_2          // Cyan*
    , FG_DATA_BYTE       // default same as FG_DISASM_OPCODE
    , FG_DATA_TEXT       // default same as FG_DISASM_NMEMONIC

    , BG_SYMBOLS_1       // window
    , BG_SYMBOLS_2
    , FG_SYMBOLS_ADDRESS // default same as FG_DISASM_ADDRESS
    , FG_SYMBOLS_NAME    // default same as FG_DISASM_SYMBOL

    , BG_SOURCE_TITLE
    , FG_SOURCE_TITLE
    , BG_SOURCE_1        // odd
    , BG_SOURCE_2        // even
    , FG_SOURCE

    , NUM_COLORS
  };

// Config _________________________________________________________________________________________

  enum ConfigSave_t
  {
    CONFIG_SAVE_FILE_CREATE,
    CONFIG_SAVE_FILE_APPEND
  };

// Commands _______________________________________________________________________________________

  enum Update_e
  {
    UPDATE_NOTHING,
    UPDATE_BACKGROUND      = (1 <<  0),
    UPDATE_BREAKPOINTS     = (1 <<  1),
    UPDATE_CONSOLE_DISPLAY = (1 <<  2),
    UPDATE_CONSOLE_INPUT   = (1 <<  3),
    UPDATE_DISASM          = (1 <<  4),
    UPDATE_FLAGS           = (1 <<  5),
    UPDATE_MEM_DUMP        = (1 <<  6),
    UPDATE_REGS            = (1 <<  7),
    UPDATE_STACK           = (1 <<  8),
    UPDATE_SYMBOLS         = (1 <<  9),
    UPDATE_TARGETS         = (1 << 10),
    UPDATE_WATCH           = (1 << 11),
    UPDATE_ZERO_PAGE       = (1 << 12),

    UPDATE_ALL = -1
  };

  typedef int Update_t;

  enum
  {
    MAX_COMMAND_LEN = 12,

    MAX_ARGS        = 32, // was 40
    ARG_SYNTAX_ERROR= -1,
    MAX_ARG_LEN     = 56, // was 12, extended to allow font names
  };

  // NOTE: All Commands return flags of what needs to be redrawn
  typedef Update_t (*CmdFuncPtr_t)(int);

  struct Command_t
  {
    char         m_sName[ MAX_COMMAND_LEN ];
    CmdFuncPtr_t pFunction;
    int          iCommand;     // offset (enum) for direct command name lookup
    char        *pHelpSummary; // 1 line help summary
//    Hash_t       m_nHash; // TODO
  };

  // Commands sorted by Category
  // NOTE: Commands_e and g_aCommands[] order _MUST_ match !!! Aliases are listed at the end
  enum Commands_e
  {
// CPU
      CMD_CURSOR_JUMP_PC // Shift
    , CMD_CURSOR_SET_PC  // Ctrl
    , CMD_ASSEMBLE
    , CMD_BREAK_INVALID
    , CMD_BREAK_OPCODE
    , CMD_GO
    , CMD_IN
    , CMD_INPUT_KEY
    , CMD_JSR
    , CMD_NOP
    , CMD_OUT
// CPU - Meta Info
    , CMD_PROFILE
    , CMD_REGISTER_SET
// CPU - Stack
//    , CMD_STACK_LIST
    , CMD_STACK_POP
    , CMD_STACK_POP_PSEUDO
    , CMD_STACK_PUSH
//    , CMD_STACK_RETURN
    , CMD_STEP_OVER
    , CMD_STEP_OUT
// CPU - Meta Info
    , CMD_TRACE
    , CMD_TRACE_FILE
    , CMD_TRACE_LINE
    , CMD_UNASSEMBLE
// Bookmarks
    , CMD_BOOKMARK
    , CMD_BOOKMARK_ADD
    , CMD_BOOKMARK_CLEAR
    , CMD_BOOKMARK_LIST
//    , CMD_BOOKMARK_LOAD
    , CMD_BOOKMARK_GOTO
    , CMD_BOOKMARK_SAVE
// Breakpoints
    , CMD_BREAKPOINT
    , CMD_BREAKPOINT_ADD_SMART // smart breakpoint
    , CMD_BREAKPOINT_ADD_REG   // break on: PC == Address (fetch/execute)
    , CMD_BREAKPOINT_ADD_PC    // alias BPX = BA
//    ,  CMD_BREAKPOINT_SET  = CMD_BREAKPOINT_ADD_ADDR // alias
//    ,  CMD_BREAKPOINT_EXEC = CMD_BREAKPOINT_ADD_ADDR // alias
    , CMD_BREAKPOINT_ADD_IO  // break on: [$C000-$C7FF] Load/Store
    , CMD_BREAKPOINT_ADD_MEM // break on: [$0000-$FFFF], excluding IO

    , CMD_BREAKPOINT_CLEAR
//    ,  CMD_BREAKPOINT_REMOVE = CMD_BREAKPOINT_CLEAR // alias
    , CMD_BREAKPOINT_DISABLE
    , CMD_BREAKPOINT_EDIT
    , CMD_BREAKPOINT_ENABLE
    , CMD_BREAKPOINT_LIST
//    , CMD_BREAKPOINT_LOAD
    , CMD_BREAKPOINT_SAVE
// Benchmark / Timing
//    , CMD_BENCHMARK_START
//    , CMD_BENCHMARK_STOP
//    , CMD_PROFILE_START
//    , CMD_PROFILE_STOP
// Config (debugger settings)
    , CMD_BENCHMARK
    , CMD_CONFIG_BW         // BW    # rr gg bb
    , CMD_CONFIG_COLOR      // COLOR # rr gg bb

    , CMD_CONFIG_DISASM
//    , CMD_CONFIG_DISASM_BRANCH
//    , CMD_CONFIG_DISASM_COLON
//    , CMD_CONFIG_DISASM_OPCODE
//    , CMD_CONFIG_DISASM_SPACES

    , CMD_CONFIG_FONT
//    , CMD_CONFIG_FONT2 // PARAM_FONT_DISASM PARAM_FONT_INFO PARAM_FONT_SOURCE
    , CMD_CONFIG_HCOLOR     // TODO Video :: SETFRAMECOLOR(#,R,G,B)
    , CMD_CONFIG_LOAD
    , CMD_CONFIG_MONOCHROME // MONO  # rr gg bb
    , CMD_CONFIG_SAVE
// Cursor
    , CMD_CURSOR_JUMP_RET_ADDR
    , CMD_CURSOR_LINE_UP   // Smart Line Up
    , CMD_CURSOR_LINE_UP_1 // Shift
    , CMD_CURSOR_LINE_DOWN // Smart Line Down
    , CMD_CURSOR_LINE_DOWN_1 // Shift
//    , CMD_CURSOR_PAGE_UP
//    , CMD_CURSOR_PAGE_DOWN
    , CMD_CURSOR_PAGE_UP
    , CMD_CURSOR_PAGE_UP_256 // up to nearest page boundary
    , CMD_CURSOR_PAGE_UP_4K // Up to nearest 4K boundary

    , CMD_CURSOR_PAGE_DOWN
    , CMD_CURSOR_PAGE_DOWN_256 // Down to nearest page boundary
    , CMD_CURSOR_PAGE_DOWN_4K // Down to nearest 4K boundary
// Disk
    , CMD_DISK
// Flags - CPU
    , CMD_FLAG_CLEAR // Flag order must match g_aFlagNames CZIDBRVN
    , CMD_FLAG_CLR_C // 8
    , CMD_FLAG_CLR_Z // 7
    , CMD_FLAG_CLR_I // 6
    , CMD_FLAG_CLR_D // 5
    , CMD_FLAG_CLR_B // 4
    , CMD_FLAG_CLR_R // 3
    , CMD_FLAG_CLR_V // 2
    , CMD_FLAG_CLR_N // 1

    , CMD_FLAG_SET   // Flag order must match g_aFlagNames CZIDBRVN
    , CMD_FLAG_SET_C // 8
    , CMD_FLAG_SET_Z // 7
    , CMD_FLAG_SET_I // 6
    , CMD_FLAG_SET_D // 5
    , CMD_FLAG_SET_B // 4
    , CMD_FLAG_SET_R // 3
    , CMD_FLAG_SET_V // 2
    , CMD_FLAG_SET_N // 1
// Help
    , CMD_HELP_LIST
    , CMD_HELP_SPECIFIC
    , CMD_VERSION
    , CMD_MOTD // Message of the Day
// Memory
    , CMD_MEMORY_COMPARE

    , _CMD_MEM_MINI_DUMP_HEX_1_1 // alias MD
    , _CMD_MEM_MINI_DUMP_HEX_1_2 // alias MD = D
    , CMD_MEM_MINI_DUMP_HEX_1
    , CMD_MEM_MINI_DUMP_HEX_2
    , _CMD_MEM_MINI_DUMP_HEX_1_3 // alias M1
    , _CMD_MEM_MINI_DUMP_HEX_2_1 // alias M2

    , CMD_MEM_MINI_DUMP_ASCII_1    // ASCII
    , CMD_MEM_MINI_DUMP_ASCII_2
    , CMD_MEM_MINI_DUMP_APPLE_1 // Low-Bit inverse, High-Bit normal
    , CMD_MEM_MINI_DUMP_APPLE_2
//    , CMD_MEM_MINI_DUMP_TXT_LO_1 // ASCII (Controls Chars)
//    , CMD_MEM_MINI_DUMP_TXT_LO_2
//    , CMD_MEM_MINI_DUMP_TXT_HI_1 // ASCII (High Bit)
//    , CMD_MEM_MINI_DUMP_TXT_HI_2

//    , CMD_MEMORY_DUMP = CMD_MEM_MINI_DUMP_HEX_1
    , CMD_MEMORY_EDIT
    , CMD_MEMORY_ENTER_BYTE
    , CMD_MEMORY_ENTER_WORD
    , CMD_MEMORY_LOAD
    , CMD_MEMORY_MOVE
    , CMD_MEMORY_SAVE
    , CMD_MEMORY_SEARCH
//    , CMD_MEMORY_SEARCH_ASCII   // Ascii Text
//    , CMD_MEMORY_SEARCH_APPLE   // Flashing Chars, Hi-Bit Set
    , CMD_MEMORY_SEARCH_HEX
    , CMD_MEMORY_FILL
// Output
    , CMD_OUTPUT_CALC
    , CMD_OUTPUT_ECHO
    , CMD_OUTPUT_PRINT
    , CMD_OUTPUT_PRINTF
    , CMD_OUTPUT_RUN
// Source Level Debugging
    , CMD_SOURCE
    , CMD_SYNC
// Symbols
    , CMD_SYMBOLS_LOOKUP
//    , CMD_SYMBOLS
    , CMD_SYMBOLS_MAIN
    , CMD_SYMBOLS_USER
    , CMD_SYMBOLS_SRC
//    , CMD_SYMBOLS_FIND
//    , CMD_SYMBOLS_CLEAR
    , CMD_SYMBOLS_INFO
    , CMD_SYMBOLS_LIST
//    , CMD_SYMBOLS_LOAD_1
//    , CMD_SYMBOLS_LOAD_2
//    , CMD_SYMBOLS_SAVE
// Watch
    , CMD_WATCH
    , CMD_WATCH_ADD
    , CMD_WATCH_CLEAR
    , CMD_WATCH_DISABLE
    , CMD_WATCH_ENABLE
    , CMD_WATCH_LIST
//    , CMD_WATCH_LOAD
    , CMD_WATCH_SAVE
// Window
//    , CMD_WINDOW_COLOR_CUSTOM
    , CMD_WINDOW

    , CMD_WINDOW_CODE
    , CMD_WINDOW_CODE_1
    , CMD_WINDOW_CODE_2

    , CMD_WINDOW_CONSOLE

    , CMD_WINDOW_DATA
    , CMD_WINDOW_DATA_1
    , CMD_WINDOW_DATA_2

    // SOURCE is reserved for source level debugging
    , CMD_WINDOW_SOURCE_1
    , CMD_WINDOW_SOURCE_2

//    , CMD_WINDOW_STACK_1
//    , CMD_WINDOW_STACK_2

    // SYMBOLS is reserved for symbols lookup/commands
//    , CMD_WINDOW_SYMBOLS_1
//    , CMD_WINDOW_SYMBOLS_2

//    , CMD_WINDOW_ZEROPAGE_1
//    , CMD_WINDOW_ZEROPAGE_2

    , CMD_WINDOW_OUTPUT
//    , CMD_WINDOW_SOURCE
// ZeroPage
    , CMD_ZEROPAGE_POINTER
    , CMD_ZEROPAGE_POINTER_0
    , CMD_ZEROPAGE_POINTER_1
    , CMD_ZEROPAGE_POINTER_2
    , CMD_ZEROPAGE_POINTER_3
    , CMD_ZEROPAGE_POINTER_4
    , CMD_ZEROPAGE_POINTER_5
    , CMD_ZEROPAGE_POINTER_6
    , CMD_ZEROPAGE_POINTER_7
    , CMD_ZEROPAGE_POINTER_ADD
    , CMD_ZEROPAGE_POINTER_CLEAR
    , CMD_ZEROPAGE_POINTER_DISABLE
    , CMD_ZEROPAGE_POINTER_ENABLE
    , CMD_ZEROPAGE_POINTER_LIST
//    , CMD_ZEROPAGE_POINTER_LOAD
    , CMD_ZEROPAGE_POINTER_SAVE

    , NUM_COMMANDS
  };


// CPU
  Update_t CmdCursorJumpPC(int nArgs);
  Update_t CmdCursorSetPC (int nArgs);
  Update_t CmdAssemble    (int nArgs);
  Update_t CmdBreakInvalid(int nArgs); // Breakpoint IFF Full-speed!
  Update_t CmdBreakOpcode (int nArgs); // Breakpoint IFF Full-speed!
  Update_t CmdGo          (int nArgs);
  Update_t CmdIn          (int nArgs);
  Update_t CmdKey         (int nArgs);
  Update_t CmdJSR         (int nArgs);
  Update_t CmdNOP         (int nArgs);
  Update_t CmdOut         (int nArgs);
  Update_t CmdStepOver    (int nArgs);
  Update_t CmdStepOut     (int nArgs);
  Update_t CmdTrace       (int nArgs);  // alias for CmdStepIn
  Update_t CmdTraceFile   (int nArgs);
  Update_t CmdTraceLine   (int nArgs);
  Update_t CmdUnassemble  (int nArgs); // code dump, aka, Unassemble
// Bookmarks
  Update_t CmdBookmark       (int nArgs);
  Update_t CmdBookmarkAdd    (int nArgs);
  Update_t CmdBookmarkClear  (int nArgs);
  Update_t CmdBookmarkList   (int nArgs);
  Update_t CmdBookmarkGoto   (int nArgs);
//  Update_t CmdBookmarkLoad   (int nArgs);
  Update_t CmdBookmarkSave   (int nArgs);
// Breakpoints
  Update_t CmdBreakpoint        (int nArgs);
  Update_t CmdBreakpointAddSmart(int nArgs);
  Update_t CmdBreakpointAddReg  (int nArgs);
  Update_t CmdBreakpointAddPC   (int nArgs);
  Update_t CmdBreakpointAddIO   (int nArgs);
  Update_t CmdBreakpointAddMem  (int nArgs);
  Update_t CmdBreakpointClear   (int nArgs);
  Update_t CmdBreakpointDisable (int nArgs);
  Update_t CmdBreakpointEdit    (int nArgs);
  Update_t CmdBreakpointEnable  (int nArgs);
  Update_t CmdBreakpointList    (int nArgs);
//  Update_t CmdBreakpointLoad    (int nArgs);
  Update_t CmdBreakpointSave    (int nArgs);
// Benchmark
  Update_t CmdBenchmark      (int nArgs);
  Update_t CmdBenchmarkStart (int nArgs); //Update_t CmdSetupBenchmark (int nArgs);
  Update_t CmdBenchmarkStop  (int nArgs); //Update_t CmdExtBenchmark (int nArgs);
  Update_t CmdProfile        (int nArgs);
  Update_t CmdProfileStart   (int nArgs);
  Update_t CmdProfileStop    (int nArgs);
// Config
//  Update_t CmdConfigMenu        (int nArgs);
//  Update_t CmdConfigBase        (int nArgs);
//  Update_t CmdConfigBaseHex     (int nArgs);
//  Update_t CmdConfigBaseDec     (int nArgs);
  Update_t CmdConfigColorMono   (int nArgs);
  Update_t CmdConfigDisasm      (int nArgs);
  Update_t CmdConfigFont        (int nArgs);
  Update_t CmdConfigHColor      (int nArgs);
  Update_t CmdConfigLoad        (int nArgs);
  Update_t CmdConfigSave        (int nArgs);
  Update_t CmdConfigSetFont     (int nArgs);
  Update_t CmdConfigGetFont     (int nArgs);
// Cursor
  Update_t CmdCursorFollowTarget(int nArgs);
  Update_t CmdCursorLineDown    (int nArgs);
  Update_t CmdCursorLineUp      (int nArgs);
  Update_t CmdCursorJumpRetAddr (int nArgs);
  Update_t CmdCursorRunUntil    (int nArgs);
  Update_t CmdCursorPageDown    (int nArgs);
  Update_t CmdCursorPageDown256 (int nArgs);
  Update_t CmdCursorPageDown4K  (int nArgs);
  Update_t CmdCursorPageUp      (int nArgs);
  Update_t CmdCursorPageUp256   (int nArgs);
  Update_t CmdCursorPageUp4K    (int nArgs);
// Disk
  Update_t CmdDisk              (int nArgs);
// Help
  Update_t CmdHelpList          (int nArgs);
  Update_t CmdHelpSpecific      (int Argss);
  Update_t CmdVersion           (int nArgs);
  Update_t CmdMOTD              (int nArgs);
// Flags
  Update_t CmdFlag      (int nArgs);
  Update_t CmdFlagClear (int nArgs);
  Update_t CmdFlagSet   (int nArgs);
// Memory (Data)
  Update_t CmdMemoryCompare      (int nArgs);
  Update_t CmdMemoryMiniDumpHex  (int nArgs);
  Update_t CmdMemoryMiniDumpAscii(int nArgs);
  Update_t CmdMemoryMiniDumpApple(int nArgs);
//  Update_t CmdMemoryMiniDumpLow  (int nArgs);
//  Update_t CmdMemoryMiniDumpHigh (int nArgs);

  Update_t CmdMemoryEdit         (int nArgs);
  Update_t CmdMemoryEnterByte    (int nArgs);
  Update_t CmdMemoryEnterWord    (int nArgs);
  Update_t CmdMemoryFill         (int nArgs);
  Update_t CmdMemoryLoad         (int nArgs);
  Update_t CmdMemoryMove         (int nArgs);
  Update_t CmdMemorySave         (int nArgs);
  Update_t CmdMemorySearch       (int nArgs);
//  Update_t CmdMemorySearchLowBit (int nArgs);
//  Update_t CmdMemorySearchHiBit  (int nArgs);
  Update_t CmdMemorySearchAscii  (int nArgs);
  Update_t CmdMemorySearchApple  (int nArgs);
  Update_t CmdMemorySearchHex    (int nArgs);
// Output/Scripts
  Update_t CmdOutputCalc         (int nArgs);
  Update_t CmdOutputEcho         (int nArgs);
  Update_t CmdOutputPrint        (int nArgs);
  Update_t CmdOutputPrintf       (int nArgs);
  Update_t CmdOutputRun          (int nArgs);
// Registers
  Update_t CmdRegisterSet     (int nArgs);
// Source Level Debugging
  Update_t CmdSource          (int nArgs);
  Update_t CmdSync            (int nArgs);
// Stack
  Update_t CmdStackPush       (int nArgs);
  Update_t CmdStackPop        (int nArgs);
  Update_t CmdStackPopPseudo  (int nArgs);
  Update_t CmdStackReturn     (int nArgs);
// Symbols
  Update_t CmdSymbols         (int nArgs);
  Update_t CmdSymbolsClear    (int nArgs);
  Update_t CmdSymbolsList     (int nArgs);
  Update_t CmdSymbolsLoad     (int nArgs);
  Update_t CmdSymbolsInfo     (int nArgs);
  Update_t CmdSymbolsMain     (int nArgs);
  Update_t CmdSymbolsUser     (int nArgs);
  Update_t CmdSymbolsSave     (int nArgs);
  Update_t CmdSymbolsSource   (int nArgs);
// Watch
  Update_t CmdWatch        (int nArgs);
  Update_t CmdWatchAdd     (int nArgs);
  Update_t CmdWatchClear   (int nArgs);
  Update_t CmdWatchDisable (int nArgs);
  Update_t CmdWatchEnable  (int nArgs);
  Update_t CmdWatchList    (int nArgs);
//  Update_t CmdWatchLoad    (int nArgs);
  Update_t CmdWatchSave    (int nArgs);
// Window
  Update_t CmdWindow            (int nArgs);
  Update_t CmdWindowCycleNext   (int nArgs);
  Update_t CmdWindowCyclePrev   (int nArgs);
  Update_t CmdWindowLast        (int nArgs);

  Update_t CmdWindowShowCode    (int nArgs);
  Update_t CmdWindowShowCode1   (int nArgs);
  Update_t CmdWindowShowCode2   (int nArgs);
  Update_t CmdWindowShowData    (int nArgs);
  Update_t CmdWindowShowData1   (int nArgs);
  Update_t CmdWindowShowData2   (int nArgs);
  Update_t CmdWindowShowSymbols1(int nArgs);
  Update_t CmdWindowShowSymbols2(int nArgs);
  Update_t CmdWindowShowSource  (int nArgs);
  Update_t CmdWindowShowSource1 (int nArgs);
  Update_t CmdWindowShowSource2 (int nArgs);

  Update_t CmdWindowViewCode    (int nArgs);
  Update_t CmdWindowViewConsole (int nArgs);
  Update_t CmdWindowViewData    (int nArgs);
  Update_t CmdWindowViewOutput  (int nArgs);
  Update_t CmdWindowViewSource  (int nArgs);
  Update_t CmdWindowViewSymbols (int nArgs);

  Update_t CmdWindowWidthToggle (int nArgs);

//  Update_t CmdZeroPageShow      (int nArgs);
//  Update_t CmdZeroPageHide      (int nArgs);
//  Update_t CmdZeroPageToggle    (int nArgs);

// ZeroPage
  Update_t CmdZeroPage        (int nArgs);
  Update_t CmdZeroPageAdd     (int nArgs);
  Update_t CmdZeroPageClear   (int nArgs);
  Update_t CmdZeroPageDisable (int nArgs);
  Update_t CmdZeroPageEnable  (int nArgs);
  Update_t CmdZeroPageList    (int nArgs);
//  Update_t CmdZeroPageLoad    (int nArgs);
  Update_t CmdZeroPageSave    (int nArgs);
  Update_t CmdZeroPagePointer (int nArgs);


// Cursor _________________________________________________________________________________________
  enum Cursor_Align_e
  {
    CURSOR_ALIGN_TOP,
    CURSOR_ALIGN_CENTER
  };

  enum CursorHiLightState_e
  {
    CURSOR_NORMAL    , // White
    CURSOR_CPU_PC    , // Yellow
    CURSOR_BREAKPOINT, // Red
  };


// Disassembly ____________________________________________________________________________________

  enum DisasmBranch_e
  {
      DISASM_BRANCH_OFF = 0
    , DISASM_BRANCH_PLAIN
    , DISASM_BRANCH_FANCY
    , NUM_DISASM_BRANCH_TYPES
  };

  enum DisasmFormat_e
  {
    DISASM_FORMAT_CHAR           = (1 << 0),
    DISASM_FORMAT_SYMBOL         = (1 << 1),
    DISASM_FORMAT_OFFSET         = (1 << 2),
    DISASM_FORMAT_BRANCH         = (1 << 3),
    DISASM_FORMAT_TARGET_POINTER = (1 << 4),
    DISASM_FORMAT_TARGET_VALUE   = (1 << 5),
  };

  enum DisasmImmediate_e
  {
      DISASM_IMMED_OFF = 0
    , DISASM_IMMED_TARGET
    , DISASM_IMMED_MODE
    , DISASM_IMMED_BOTH
    , NUM_DISASM_IMMED_TYPES
  };

  enum DisasmTargets_e
  {
      DISASM_TARGET_OFF  = 0
    , DISASM_TARGET_VAL  // Note: Also treated as bit flag !!
    , DISASM_TARGET_ADDR // Note: Also treated as bit flag !!
    , DISASM_TARGET_BOTH // Note: Also treated as bit flag !!
    , NUM_DISASM_TARGET_TYPES
  };

  enum DisasmText_e
  {
    nMaxAddressLen    = 40,
    nMaxOpcodes       =  3,
    CHARS_FOR_ADDRESS =  8, // 4 digits plus null
  };

  struct DisasmLine_t
  {
    int iOpcode;
    int iOpmode;
    int nOpbyte;

    char sAddress  [ CHARS_FOR_ADDRESS ];
    char sOpCodes  [(nMaxOpcodes*3)+1];

    int  nTarget;
    char sTarget   [nMaxAddressLen];

    char sTargetOffset[ CHARS_FOR_ADDRESS ]; // +/- 255, realistically +/-1
    int  nTargetOffset;

    char sTargetPointer[ CHARS_FOR_ADDRESS ];
    char sTargetValue  [ CHARS_FOR_ADDRESS ];
//    char sTargetAddress[ CHARS_FOR_ADDRESS ];

    char sImmediate[ 4 ]; // 'c'
    char nImmediate;
    char sBranch   [ 4 ]; // ^

    bool bTargetImmediate;
    bool bTargetIndirect;
    bool bTargetIndexed ;
    bool bTargetRelative;
    bool bTargetX       ;
    bool bTargetY       ;
    bool bTargetValue   ;

    void Clear()
    {
      sAddress  [ 0 ] = 0;
      sOpCodes  [ 0 ] = 0;

      nTarget = 0;
      sTarget   [ 0 ] = 0;

      sTargetOffset[ 0 ] = 0;
      nTargetOffset = 0;

      sTargetPointer[ 0 ] = 0;
      sTargetValue  [ 0 ] = 0;

      sImmediate[ 0 ] = 0;
      nImmediate = 0;

      sBranch   [ 0 ] = 0;

      bTargetImmediate = false;
      bTargetIndexed   = false;
      bTargetIndirect  = false;
//      bTargetInside    = false;
//      bTargetOutside   = false;
      bTargetRelative  = false;
      bTargetX         = false;
      bTargetY         = false; // need to dislay ",Y"
      bTargetValue     = false;
    }
  };

// Font ___________________________________________________________________________________________
  enum FontType_e
  {
//      FONT_DEFAULT
      FONT_INFO
    , FONT_CONSOLE
    , FONT_DISASM_DEFAULT
    , FONT_DISASM_BRANCH
  //  , FONT_SOURCE
    , NUM_FONTS
  };

  enum
  {
    MAX_FONT_NAME = MAX_ARG_LEN // was 64
  };

  enum FontSpacing_e
  {
    FONT_SPACING_CLASSIC   , // least lines (most spacing)
    FONT_SPACING_CLEAN     , // more lines (minimal spacing)
    FONT_SPACING_COMPRESSED, // max lines (least spacing)
    NUM_FONT_SPACING
  };

  struct FontConfig_t
  {
    char  _sFontName[ MAX_FONT_NAME ];
//    HFONT _hFont;
//    int   _iFontType;
    int   _nFontWidthAvg;
    int   _nFontWidthMax;
    int   _nFontHeight;
    int   _nLineHeight; // may or may not include spacer
  };


// Instructions / Opcodes _________________________________________________________________________

  //#define SUPPORT_Z80_EMU
  #ifdef SUPPORT_Z80_EMU
    #define OUTPUT_Z80_REGS
    #define REG_AF 0xF0
    #define REG_BC 0xF2
    #define REG_DE 0xF4
    #define REG_HL 0xF6
    #define REG_IX 0xF8
  #endif

  enum MemoryAccess_e
  {
    MEM_R  = (1 << 0), // Read
    MEM_W  = (1 << 1), // Write
    MEM_RI = (1 << 2), // Read Implicit (Implied)
    MEM_WI = (1 << 3), // Write Implicit (Implied)
    MEM_S  = (1 << 4), // Stack (Read/Write)
    MEM_IM = (1 << 5), // Immediate - Technically reads target byte

    NUM_MEM_ACCESS,

  // Alias
    MEM_READ  = (1 << 0),
    MEM_WRITE = (1 << 1),
  };

  enum
  {
    NUM_OPCODES      = 256,
    MAX_MNEMONIC_LEN =   3,
  };

  struct Opcodes_t
  {
    char  sMnemonic[ MAX_MNEMONIC_LEN+1 ];
    // int16 for structure 8-byte alignment
    short nAddressMode; // TODO/FIX: nOpmode
    short nMemoryAccess;
  };

  struct Instruction2_t
  {
    char   sMnemonic[MAX_MNEMONIC_LEN+1];
    int    nAddressMode;
    int    iMemoryAccess;
  };

  enum Opcode_e
  {
    OPCODE_BRA     = 0x80,

    OPCODE_JSR     = 0x20,
    OPCODE_JMP_A   = 0x4C, // Absolute
    OPCODE_JMP_NA  = 0x6C, // Indirect Absolute
    OPCODE_JMP_IAX = 0x7C, // Indexed (Absolute Indirect, X)
  };

  // Note: "int" causes overflow when profiling for any amount of time.
  // typedef unsigned int Profile_t;
  // i.e.
  //  double nPercent = static_cast<double>(100 * tProfileOpcode.uProfile) / nOpcodeTotal; // overflow
  typedef double Profile_t;

  struct ProfileOpcode_t
  {
    int       m_iOpcode;
    Profile_t m_nCount; // Histogram

    // functor
    bool operator () (const ProfileOpcode_t & rLHS, const ProfileOpcode_t & rRHS) const
    {
      bool bGreater = (rLHS.m_nCount > rRHS.m_nCount);
      return bGreater;
    }
  };

  struct ProfileOpmode_t
  {
    int       m_iOpmode;
    Profile_t m_nCount; // Histogram

    // functor
    bool operator () (const ProfileOpmode_t & rLHS, const ProfileOpmode_t & rRHS) const
    {
      bool bGreater = (rLHS.m_nCount > rRHS.m_nCount);
      return bGreater;
    }
  };

  enum ProfileFormat_e
  {
    PROFILE_FORMAT_SPACE,
    PROFILE_FORMAT_TAB,
    PROFILE_FORMAT_COMMA,
  };

// Memory _________________________________________________________________________________________

  extern const          int _6502_BRANCH_POS      ;//= +127
  extern const          int _6502_BRANCH_NEG      ;//= -128
  extern const unsigned int _6502_ZEROPAGE_END    ;//= 0x00FF;
  extern const unsigned int _6502_STACK_END       ;//= 0x01FF;
  extern const unsigned int _6502_IO_BEGIN        ;//= 0xC000;
  extern const unsigned int _6502_IO_END          ;//= 0xC0FF;
  extern const unsigned int _6502_MEM_BEGIN       ;//= 0x0000;
  extern const unsigned int _6502_MEM_END         ;//= 0xFFFF;


  enum DEVICE_e
  {
    DEV_MEMORY,
    DEV_DISK2 ,
    DEV_SY6522,
    DEV_AY8910,
    NUM_DEVICES
  };

  enum MemoryView_e
  {
    MEM_VIEW_HEX   ,

    // 0x00 .. 0x1F Ctrl              (Inverse)
    // 0x20 .. 0x7F Flash / MouseText (Cyan)
    // 0x80 .. 0x9F Hi-Bit Ctrl       (Yellow)
    // 0xA0 .. 0xFF Hi-Bit Normal     (White)
    MEM_VIEW_ASCII ,
    MEM_VIEW_APPLE , // Low-Bit ASCII (Colorized Background)
//    MEM_VIEW_TXT_LO, // Ctrl Chars mapped to visible range, and inverse
//    MEM_VIEW_TXT_HI, // High Bit Ascii
    NUM_MEM_VIEWS
  };

  struct MemoryDump_t
  {
    bool         bActive;
    WORD         nAddress; // nAddressMemDump; // was USHORT
    DEVICE_e     eDevice;
    MemoryView_e eView;
  };

  enum MemoryDump_e
  {
    MEM_DUMP_1,
    MEM_DUMP_2,
    NUM_MEM_DUMPS
  };

  enum MemoryMiniDump_e
  {
    NUM_MEM_MINI_DUMPS = 2
  };

  enum MemorySearch_e
  {
    MEM_SEARCH_BYTE_EXACT    , // xx
    MEM_SEARCH_NIB_LOW_EXACT , // ?x
    MEM_SEARCH_NIB_HIGH_EXACT, // x?
    MEM_SEARCH_BYTE_1_WILD   , // ?
    MEM_SEARCH_BYTE_N_WILD   , // ??

    MEM_SEARCH_TYPE_MASK = (1 << 16) - 1,
    MEM_SEARCH_FOUND     = (1 << 16)
  };

  struct MemorySearch_t
  {
    BYTE           m_nValue  ; // search value
    MemorySearch_e m_iType   ; //
    bool           m_bFound  ; //
  };

  typedef vector<MemorySearch_t> MemorySearchValues_t;
  typedef vector<int>            MemorySearchResults_t;

// Parameters _____________________________________________________________________________________

  /* i.e.
      SYM LOAD = $C600   (1) type: string, nVal1 = symlookup; (2) type: operator, token: EQUAL; (3) type: address, token:DOLLAR
      BP LOAD            type:
      BP $LOAD           type: (1) = symbol, val=1adress
  */
  enum ArgToken_e // Arg Token Type
  {
    // Single Char Tokens must come first
      TOKEN_ALPHANUMERIC //
    , TOKEN_AMPERSAND    // &
    , TOKEN_AT           // @  results dereference. i.e. S 0,FFFF C030; L @1
    , TOKEN_BRACE_L      // {
    , TOKEN_BRACE_R      // }
    , TOKEN_BRACKET_L    // [
    , TOKEN_BRACKET_R    // ]
    , TOKEN_BSLASH       // \xx Hex Literal
    , TOKEN_CARET        // ^
//    , TOKEN_CHAR
    , TOKEN_COLON        // : Range
    , TOKEN_COMMA        // , Length
//    , TOKEN_DIGIT
    , TOKEN_DOLLAR       // $ Address (symbol lookup forced)
    , TOKEN_EQUAL        // = Assign Argment.n2 = Argument2
    , TOKEN_EXCLAMATION  // !
    , TOKEN_FSLASH       // /
    , TOKEN_GREATER_THAN // >
    , TOKEN_HASH         // # Value  no symbol lookup
    , TOKEN_LESS_THAN    // <
    , TOKEN_MINUS        // - Delta  Argument1 -= Argument2
    , TOKEN_PAREN_L      // (
    , TOKEN_PAREN_R      // )
    , TOKEN_PERCENT      // %
    , TOKEN_PIPE         // |
    , TOKEN_PLUS         // + Delta  Argument1 += Argument2
    , TOKEN_QUOTE_SINGLE // '
    , TOKEN_QUOTE_DOUBLE // "
    , TOKEN_SEMI         // ; Command Seperator
    , TOKEN_SPACE        //   Token Delimiter
    , TOKEN_STAR         // *
//    , TOKEN_TAB          // '\t'
    , TOKEN_TILDE        // ~

    // Multi char tokens come last
    , TOKEN_COMMENT_EOL  // //
    ,_TOKEN_FLAG_MULTI = TOKEN_COMMENT_EOL
    , TOKEN_GREATER_EQUAL// >=
    , TOKEN_LESS_EQUAL   // <=
    , TOKEN_NOT_EQUAL    // !=
//    , TOKEN_COMMENT_1    // /*
//    , TOKEN_COMMENT_2    // */

    , NUM_TOKENS // signal none, or bad
    , NO_TOKEN = NUM_TOKENS
  };

  enum ArgType_e
  {
      TYPE_ADDRESS  = (1 << 0) // $#### or $symbolname
    , TYPE_OPERATOR = (1 << 1)
    , TYPE_QUOTED_1 = (1 << 2)
    , TYPE_QUOTED_2 = (1 << 3) // "..."
    , TYPE_STRING   = (1 << 4) // LOAD
    , TYPE_RANGE    = (1 << 5)
    , TYPE_LENGTH   = (1 << 6)
    , TYPE_VALUE    = (1 << 7)
    , TYPE_NO_REG   = (1 << 8) // Don't do register value -> Argument.nValue
    , TYPE_NO_SYM   = (1 << 9) // Don't do symbol lookup  -> Argument.nValue
  };

  struct TokenTable_t
  {
    ArgToken_e eToken;
    ArgType_e  eType ;
    char       sToken[4];
  };

  struct Arg_t
  {
    char       sArg[ MAX_ARG_LEN ]; // Array chars comes first, for alignment
    int        nArgLen; // Needed for TextSearch "ABC\x00"
    WORD       nValue ; // 2
//    WORD       nVal1  ; // 2
//    WORD       nVal2  ; // 2 If we have a Len (,)
    // Enums and Bools should come last for alignment
    ArgToken_e eToken ; // 1/2/4
    int        bType  ; // 1/2/4 // Flags of ArgType_e
    DEVICE_e   eDevice; // 1/2/4
    bool       bSymbol; // 1
  };

  // NOTE: Order MUST match g_aParameters[] !!!
  enum Parameters_e
  {
    // Note: Order must match Breakpoint_Operator_t
    // Note: Order must much _PARAM_BREAKPOINT_*
    // Note: Order must match g_aBreakpointSymbols
    _PARAM_BREAKPOINT_BEGIN
    , PARAM_BP_LESS_EQUAL = _PARAM_BREAKPOINT_BEGIN   // <=
    , PARAM_BP_LESS_THAN     // <
    , PARAM_BP_EQUAL         // =
    , PARAM_BP_NOT_EQUAL     // !=
    , PARAM_BP_NOT_EQUAL_1   // !
    , PARAM_BP_GREATER_THAN  // >
    , PARAM_BP_GREATER_EQUAL // >=
    , PARAM_BP_READ          // R
    ,_PARAM_BP_READ          // ? alias READ
    , PARAM_BP_WRITE         // W
    ,_PARAM_BP_WRITE         // @ alias write
    , PARAM_BP_READ_WRITE    // * alias READ WRITE
  , _PARAM_BREAKPOINT_END
  ,  PARAM_BREAKPOINT_NUM = _PARAM_BREAKPOINT_END - _PARAM_BREAKPOINT_BEGIN

//    , PARAM_SIZE  // TODO: used by FONT SIZE

  // Note: Order must match Breakpoint_Source_t
  , _PARAM_REGS_BEGIN = _PARAM_BREAKPOINT_END // Daisy Chain
// Regs
    , PARAM_REG_A = _PARAM_REGS_BEGIN
    , PARAM_REG_X
    , PARAM_REG_Y
    , PARAM_REG_PC // Program Counter
    , PARAM_REG_SP // Stack Pointer
// Flags
    , PARAM_FLAGS  // Processor Status
    , PARAM_FLAG_C // Carry
    , PARAM_FLAG_Z // Zero
    , PARAM_FLAG_I // Interrupt
    , PARAM_FLAG_D // Decimal
    , PARAM_FLAG_B // Break
    , PARAM_FLAG_R // Reserved
    , PARAM_FLAG_V // Overflow
    , PARAM_FLAG_N // Sign
  , _PARAM_REGS_END
  ,  PARAM_REGS_NUM = _PARAM_REGS_END - _PARAM_REGS_BEGIN

// Disasm
  , _PARAM_CONFIG_BEGIN = _PARAM_REGS_END // Daisy Chain
    , PARAM_CONFIG_BRANCH = _PARAM_CONFIG_BEGIN // g_iConfigDisasmBranchType   [0|1|2]
    , PARAM_CONFIG_COLON   // g_bConfigDisasmAddressColon [0|1]
    , PARAM_CONFIG_OPCODE  // g_bConfigDisasmOpcodesView  [0|1]
    , PARAM_CONFIG_POINTER // g_bConfigInfoTargetPointer  [0|1]
    , PARAM_CONFIG_SPACES  // g_bConfigDisasmOpcodeSpaces [0|1]
    , PARAM_CONFIG_TARGET  // g_iConfigDisasmTargets      [0|1|2]
  , _PARAM_CONFIG_END
  , PARAM_CONFIG_NUM = _PARAM_CONFIG_END - _PARAM_CONFIG_BEGIN

// Disk
  , _PARAM_DISK_BEGIN = _PARAM_CONFIG_END // Daisy Chain
    , PARAM_DISK_EJECT = _PARAM_DISK_BEGIN // DISK 1 EJECT
    , PARAM_DISK_PROTECT                   // DISK 1 PROTECT
    , PARAM_DISK_READ                      // DISK 1 READ Track Sector NumSectors MemAddress
  , _PARAM_DISK_END
  ,  PARAM_DISK_NUM = _PARAM_DISK_END - _PARAM_DISK_BEGIN

  , _PARAM_FONT_BEGIN = _PARAM_DISK_END // Daisy Chain
    , PARAM_FONT_MODE = _PARAM_FONT_BEGIN
  , _PARAM_FONT_END
  ,  PARAM_FONT_NUM = _PARAM_FONT_END - _PARAM_FONT_BEGIN

  , _PARAM_GENERAL_BEGIN = _PARAM_FONT_END // Daisy Chain
    , PARAM_FIND = _PARAM_GENERAL_BEGIN
    , PARAM_BRANCH
    , PARAM_CATEGORY
    , PARAM_CLEAR
    , PARAM_LOAD
    , PARAM_LIST
    , PARAM_OFF
    , PARAM_ON
    , PARAM_RESET
    , PARAM_SAVE
    , PARAM_START
    , PARAM_STOP
  , _PARAM_GENERAL_END
  ,  PARAM_GENERAL_NUM = _PARAM_GENERAL_END - _PARAM_GENERAL_BEGIN

  , _PARAM_HELPCATEGORIES_BEGIN = _PARAM_GENERAL_END // Daisy Chain
    , PARAM_WILDSTAR = _PARAM_HELPCATEGORIES_BEGIN
    , PARAM_CAT_BOOKMARKS
    , PARAM_CAT_BREAKPOINTS
    , PARAM_CAT_CONFIG
    , PARAM_CAT_CPU
//    , PARAM_CAT_EXPRESSION
    , PARAM_CAT_FLAGS
    , PARAM_CAT_HELP
    , PARAM_CAT_KEYBOARD
    , PARAM_CAT_MEMORY
    , PARAM_CAT_OUTPUT
    , PARAM_CAT_OPERATORS
    , PARAM_CAT_RANGE
//    , PARAM_CAT_REGISTERS
    , PARAM_CAT_SYMBOLS
    , PARAM_CAT_WATCHES
    , PARAM_CAT_WINDOW
    , PARAM_CAT_ZEROPAGE
  , _PARAM_HELPCATEGORIES_END
  ,  PARAM_HELPCATEGORIES_NUM = _PARAM_HELPCATEGORIES_END - _PARAM_HELPCATEGORIES_BEGIN

  , _PARAM_MEM_SEARCH_BEGIN = _PARAM_HELPCATEGORIES_END  // Daisy Chain
    , PARAM_MEM_SEARCH_WILD = _PARAM_MEM_SEARCH_BEGIN
//    , PARAM_MEM_SEARCH_BYTE
  , _PARAM_MEM_SEARCH_END
  ,  PARAM_MEM_SEARCH_NUM = _PARAM_MEM_SEARCH_END - _PARAM_MEM_SEARCH_BEGIN

  , _PARAM_SOURCE_BEGIN = _PARAM_MEM_SEARCH_END  // Daisy Chain
    , PARAM_SRC_MEMORY = _PARAM_SOURCE_BEGIN
    ,_PARAM_SRC_MEMORY  // alias MEM = MEMORY
    , PARAM_SRC_SYMBOLS
    ,_PARAM_SRC_SYMBOLS // alias SYM = SYMBOLS
    , PARAM_SRC_MERLIN
    , PARAM_SRC_ORCA
  , _PARAM_SOURCE_END
  ,  PARAM_SOURCE_NUM = _PARAM_SOURCE_END - _PARAM_SOURCE_BEGIN

  , _PARAM_WINDOW_BEGIN = _PARAM_SOURCE_END  // Daisy Chain
    // These are the "full screen" "windows" / Panels / Tab sheets
    , PARAM_CODE = _PARAM_WINDOW_BEGIN // disasm
//    , PARAM_CODE_1  // disasm top // removed, since can't set top window for code/data
    , PARAM_CODE_2  // disasm bot
    , PARAM_CONSOLE
    , PARAM_DATA    // data all
//    , PARAM_DATA_1  // data top // removed, since can't set top window for code/data
    , PARAM_DATA_2  // data bot
    , PARAM_DISASM
    , PARAM_INFO    // Togle INFO on/off
    , PARAM_SOURCE
    , _PARAM_SRC     // alias SRC = SOURCE
//    , PARAM_SOURCE_1 // source top // removed, since can't set top window for code/data
    , PARAM_SOURCE_2 // source bot
    , PARAM_SYMBOLS
    , _PARAM_SYM     // alias SYM = SYMBOLS
//    , PARAM_SYMBOL_1 // symbols top // removed, since can't set top window for code/data
    , PARAM_SYMBOL_2 // symbols bot
  , _PARAM_WINDOW_END
  ,  PARAM_WINDOW_NUM = _PARAM_WINDOW_END - _PARAM_WINDOW_BEGIN

    , NUM_PARAMS = _PARAM_WINDOW_END // Daisy Chain

// Aliases (actuall names)
//    ,PARAM_DISASM = PARAM_CODE_1
//    , PARAM_BREAKPOINT_READ  = PARAM_READ
//    , PARAM_BREAKPOINT_WRITE = PARAM_WRITE
  };


// Source Level Debugging _________________________________________________________________________

  enum
  {
    NO_SOURCE_LINE = -1
  };

  typedef map<WORD, int> SourceAssembly_t; // Address -> Line #  &  FileName


// Symbols ________________________________________________________________________________________

  enum
  {
    MAX_SYMBOLS_LEN = 13
  };

  // ****************************************
  // WARNING: This is the simple enumeration.
  // See: g_aSymbols[]
  // ****************************************
  enum Symbols_e
  {
    SYMBOLS_MAIN,
    SYMBOLS_USER,
    SYMBOLS_SRC ,
    NUM_SYMBOL_TABLES = 3
  };

  // ****************************************
  // WARNING: This is the bit-flags to select which table.
  // See: CmdSymbolsListTable()
  // ****************************************
  enum SymbolTable_e
  {
    SYMBOL_TABLE_MAIN = (1 << 0),
    SYMBOL_TABLE_USER = (1 << 1),
    SYMBOL_TABLE_SRC  = (1 << 2),
  };

  typedef map<WORD, string> SymbolTable_t;


// Watches ________________________________________________________________________________________

  enum
  {
    MAX_WATCHES = 16
  };


// Window _________________________________________________________________________________________

  enum Window_e
  {
    WINDOW_CODE    ,
    WINDOW_DATA    ,
    WINDOW_CONSOLE ,
    NUM_WINDOWS    ,
// Not implemented yet
    WINDOW_IO      , // soft switches   $addr  name   state
    WINDOW_SYMBOLS ,
    WINDOW_ZEROPAGE,
    WINDOW_SOURCE  ,
  };

  struct WindowSplit_t
  {
    bool     bSplit;
    Window_e eTop;
    Window_e eBot;
    // TODO: nTopHeight
    // TODO: nBotHeight
  };


// Zero Page ______________________________________________________________________________________

  enum
  {
    MAX_ZEROPAGE_POINTERS = 8
  };