Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* deco6800.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /*                                                                           */
  6. /* Dissector 6800/02                                                         */
  7. /*                                                                           */
  8. /*****************************************************************************/
  9.  
  10. #include "stdinc.h"
  11. #include <ctype.h>
  12.  
  13. #include "dasmdef.h"
  14. #include "cpulist.h"
  15. #include "codechunks.h"
  16. #include "invaddress.h"
  17. #include "strutil.h"
  18.  
  19. #include "deco68.h"
  20.  
  21. static unsigned nData;
  22.  
  23. static CPUVar CPU6800, CPU6802;
  24.  
  25. typedef enum
  26. {
  27.   eUnknown,
  28.   eImplicit,
  29.   eDirect,
  30.   eIndexed,
  31.   eExtended,
  32.   eImmediate,
  33.   eRelative
  34. } tAddrType;
  35.  
  36. typedef struct
  37. {
  38.   tAddrType Type;
  39.   Byte OpSize, NextAddresses;
  40.   const char *Memo;
  41. } tOpcodeList;
  42.  
  43. static const tOpcodeList OpcodeList[256] =
  44. {
  45.   /* 0x00 */ { eUnknown   , 0, 0, NULL   },
  46.   /* 0x01 */ { eImplicit  , 0, 1, "nop"  },
  47.   /* 0x02 */ { eUnknown   , 0, 0, NULL   },
  48.   /* 0x03 */ { eUnknown   , 0, 0, NULL   },
  49.   /* 0x04 */ { eUnknown   , 0, 0, NULL   },
  50.   /* 0x05 */ { eUnknown   , 0, 0, NULL   },
  51.   /* 0x06 */ { eImplicit  , 0, 1, "tap"  },
  52.   /* 0x07 */ { eImplicit  , 0, 1, "tpa"  },
  53.   /* 0x08 */ { eImplicit  , 1, 1, "inx"  },
  54.   /* 0x09 */ { eImplicit  , 1, 1, "dex"  },
  55.   /* 0x0a */ { eImplicit  , 0, 0, "clv"  },
  56.   /* 0x0b */ { eImplicit  , 0, 0, "sev"  },
  57.   /* 0x0c */ { eImplicit  , 0, 1, "clc"  },
  58.   /* 0x0d */ { eImplicit  , 0, 1, "sec"  },
  59.   /* 0x0e */ { eImplicit  , 0, 1, "cli"  },
  60.   /* 0x0f */ { eImplicit  , 0, 1, "sei"  },
  61.   /* 0x10 */ { eImplicit  , 0, 1, "sba"  },
  62.   /* 0x11 */ { eImplicit  , 0, 1, "cba"  },
  63.   /* 0x12 */ { eUnknown   , 0, 0, NULL   },
  64.   /* 0x13 */ { eUnknown   , 0, 0, NULL   },
  65.   /* 0x14 */ { eImplicit  , 0, 1, "nba"  },
  66.   /* 0x15 */ { eUnknown   , 0, 0, NULL   },
  67.   /* 0x16 */ { eImplicit  , 0, 1, "tab"  },
  68.   /* 0x17 */ { eImplicit  , 0, 1, "tba"  },
  69.   /* 0x18 */ { eUnknown   , 0, 0, NULL   },
  70.   /* 0x19 */ { eImplicit  , 0, 1, "daa"  },
  71.   /* 0x1a */ { eUnknown   , 0, 0, NULL   },
  72.   /* 0x1b */ { eImplicit  , 0, 1, "aba"  },
  73.   /* 0x1c */ { eUnknown   , 0, 0, NULL   },
  74.   /* 0x1d */ { eUnknown   , 0, 0, NULL   },
  75.   /* 0x1e */ { eUnknown   , 0, 0, NULL   },
  76.   /* 0x1f */ { eUnknown   , 0, 0, NULL   },
  77.   /* 0x20 */ { eRelative  , 0, 2, "bra"  },
  78.   /* 0x21 */ { eUnknown   , 0, 0, NULL   },
  79.   /* 0x22 */ { eRelative  , 0, 3, "bhi"  },
  80.   /* 0x23 */ { eRelative  , 0, 3, "bls"  },
  81.   /* 0x24 */ { eRelative  , 0, 3, "bcc"  },
  82.   /* 0x25 */ { eRelative  , 0, 3, "bcs"  },
  83.   /* 0x26 */ { eRelative  , 0, 3, "bne"  },
  84.   /* 0x27 */ { eRelative  , 0, 3, "beq"  },
  85.   /* 0x28 */ { eRelative  , 0, 3, "bvc"  },
  86.   /* 0x29 */ { eRelative  , 0, 3, "bvs"  },
  87.   /* 0x2a */ { eRelative  , 0, 3, "bpl"  },
  88.   /* 0x2b */ { eRelative  , 0, 3, "bmi"  },
  89.   /* 0x2c */ { eRelative  , 0, 3, "bge"  },
  90.   /* 0x2d */ { eRelative  , 0, 3, "blt"  },
  91.   /* 0x2e */ { eRelative  , 0, 3, "bgt"  },
  92.   /* 0x2f */ { eRelative  , 0, 3, "ble"  },
  93.   /* 0x30 */ { eImplicit  , 1, 1, "tsx"  },
  94.   /* 0x31 */ { eImplicit  , 1, 1, "ins"  },
  95.   /* 0x32 */ { eImplicit  , 0, 1, "pula" },
  96.   /* 0x33 */ { eImplicit  , 0, 1, "pulb" },
  97.   /* 0x34 */ { eImplicit  , 0, 0, "dess" },
  98.   /* 0x35 */ { eImplicit  , 0, 0, "txs"  },
  99.   /* 0x36 */ { eImplicit  , 0, 1, "psha" },
  100.   /* 0x37 */ { eImplicit  , 0, 1, "pshb" },
  101.   /* 0x38 */ { eUnknown   , 0, 0, NULL   },
  102.   /* 0x39 */ { eImplicit  , 0, 0, "rts"  },
  103.   /* 0x3a */ { eUnknown   , 0, 0, NULL   },
  104.   /* 0x3b */ { eImplicit  , 0, 0, "rti"  },
  105.   /* 0x3c */ { eUnknown   , 0, 0, NULL   },
  106.   /* 0x3d */ { eUnknown   , 0, 0, NULL   },
  107.   /* 0x3e */ { eImplicit  , 0, 1, "wai"  },
  108.   /* 0x3f */ { eImplicit  , 0, 1, "swi"  },
  109.   /* 0x40 */ { eImplicit  , 0, 1, "nega" },
  110.   /* 0x41 */ { eUnknown   , 0, 0, NULL   },
  111.   /* 0x42 */ { eUnknown   , 0, 0, NULL   },
  112.   /* 0x43 */ { eImplicit  , 0, 1, "coma" },
  113.   /* 0x44 */ { eImplicit  , 0, 1, "lsra" },
  114.   /* 0x45 */ { eUnknown   , 0, 0, NULL   },
  115.   /* 0x46 */ { eImplicit  , 0, 1, "rora" },
  116.   /* 0x47 */ { eImplicit  , 0, 1, "asra" },
  117.   /* 0x48 */ { eImplicit  , 0, 1, "asla" },
  118.   /* 0x49 */ { eImplicit  , 0, 1, "rola" },
  119.   /* 0x4a */ { eImplicit  , 0, 1, "deca" },
  120.   /* 0x4b */ { eUnknown   , 0, 0, NULL   },
  121.   /* 0x4c */ { eImplicit  , 0, 1, "inca" },
  122.   /* 0x4d */ { eImplicit  , 0, 1, "tsta" },
  123.   /* 0x4e */ { eUnknown   , 0, 0, NULL   },
  124.   /* 0x4f */ { eImplicit  , 0, 1, "clra" },
  125.   /* 0x50 */ { eImplicit  , 0, 1, "negb" },
  126.   /* 0x51 */ { eUnknown   , 0, 0, NULL   },
  127.   /* 0x52 */ { eUnknown   , 0, 0, NULL   },
  128.   /* 0x53 */ { eImplicit  , 0, 1, "comb" },
  129.   /* 0x54 */ { eImplicit  , 0, 1, "lsrb" },
  130.   /* 0x55 */ { eUnknown   , 0, 0, NULL   },
  131.   /* 0x56 */ { eImplicit  , 0, 1, "rorb" },
  132.   /* 0x57 */ { eImplicit  , 0, 1, "asrb" },
  133.   /* 0x58 */ { eImplicit  , 0, 1, "aslb" },
  134.   /* 0x59 */ { eImplicit  , 0, 1, "rolb" },
  135.   /* 0x5a */ { eImplicit  , 0, 1, "decb" },
  136.   /* 0x5b */ { eUnknown   , 0, 0, NULL   },
  137.   /* 0x5c */ { eImplicit  , 0, 1, "incb" },
  138.   /* 0x5d */ { eImplicit  , 0, 1, "tstb" },
  139.   /* 0x5e */ { eUnknown   , 0, 0, NULL   },
  140.   /* 0x5f */ { eImplicit  , 0, 1, "clrb" },
  141.   /* 0x60 */ { eIndexed   , 0, 1, "neg"  },
  142.   /* 0x61 */ { eUnknown   , 0, 0, NULL   },
  143.   /* 0x62 */ { eUnknown   , 0, 0, NULL   },
  144.   /* 0x63 */ { eIndexed   , 0, 1, "com"  },
  145.   /* 0x64 */ { eIndexed   , 0, 1, "lsr"  },
  146.   /* 0x65 */ { eUnknown   , 0, 0, NULL   },
  147.   /* 0x66 */ { eIndexed   , 0, 1, "ror"  },
  148.   /* 0x67 */ { eIndexed   , 0, 1, "asr"  },
  149.   /* 0x68 */ { eIndexed   , 0, 1, "asl"  },
  150.   /* 0x69 */ { eIndexed   , 0, 1, "rol"  },
  151.   /* 0x6a */ { eIndexed   , 0, 1, "dec"  },
  152.   /* 0x6b */ { eUnknown   , 0, 0, NULL   },
  153.   /* 0x6c */ { eIndexed   , 0, 1, "inc"  },
  154.   /* 0x6d */ { eIndexed   , 0, 1, "tst"  },
  155.   /* 0x6e */ { eIndexed   , 0, 0, "jmp"  },
  156.   /* 0x6f */ { eIndexed   , 0, 1, "clr"  },
  157.   /* 0x70 */ { eExtended  , 0, 1, "neg"  },
  158.   /* 0x71 */ { eUnknown   , 0, 0, NULL   },
  159.   /* 0x72 */ { eUnknown   , 0, 0, NULL   },
  160.   /* 0x73 */ { eExtended  , 0, 1, "com"  },
  161.   /* 0x74 */ { eExtended  , 0, 1, "lsr"  },
  162.   /* 0x75 */ { eUnknown   , 0, 0, NULL   },
  163.   /* 0x76 */ { eExtended  , 0, 1, "ror"  },
  164.   /* 0x77 */ { eExtended  , 0, 1, "asr"  },
  165.   /* 0x78 */ { eExtended  , 0, 1, "asl"  },
  166.   /* 0x79 */ { eExtended  , 0, 1, "rol"  },
  167.   /* 0x7a */ { eExtended  , 0, 1, "dec"  },
  168.   /* 0x7b */ { eUnknown   , 0, 0, NULL   },
  169.   /* 0x7c */ { eExtended  , 0, 1, "inc"  },
  170.   /* 0x7d */ { eExtended  , 0, 1, "tst"  },
  171.   /* 0x7e */ { eExtended  , 0, 2, "jmp"  },
  172.   /* 0x7f */ { eExtended  , 0, 1, "clr"  },
  173.   /* 0x80 */ { eImmediate , 0, 1, "suba" },
  174.   /* 0x81 */ { eImmediate , 0, 1, "cmpa" },
  175.   /* 0x82 */ { eImmediate , 0, 1, "sbca" },
  176.   /* 0x83 */ { eUnknown   , 0, 0, NULL   },
  177.   /* 0x84 */ { eImmediate , 0, 1, "anda" },
  178.   /* 0x85 */ { eImmediate , 0, 1, "bita" },
  179.   /* 0x86 */ { eImmediate , 0, 1, "ldaa" },
  180.   /* 0x87 */ { eUnknown   , 0, 0, NULL   },
  181.   /* 0x88 */ { eImmediate , 0, 1, "eora" },
  182.   /* 0x89 */ { eImmediate , 0, 1, "adca" },
  183.   /* 0x8a */ { eImmediate , 0, 1, "oraa" },
  184.   /* 0x8b */ { eImmediate , 0, 1, "adda" },
  185.   /* 0x8c */ { eImmediate , 1, 1, "cpx"  },
  186.   /* 0x8d */ { eRelative  , 0, 3, "bsr"  },
  187.   /* 0x8e */ { eImmediate , 1, 1, "lds"  },
  188.   /* 0x8f */ { eUnknown   , 0, 0, NULL   },
  189.   /* 0x90 */ { eDirect    , 0, 1, "suba" },
  190.   /* 0x91 */ { eDirect    , 0, 1, "cmpa" },
  191.   /* 0x92 */ { eDirect    , 0, 1, "sbca" },
  192.   /* 0x93 */ { eUnknown   , 0, 0, NULL   },
  193.   /* 0x94 */ { eDirect    , 0, 1, "anda" },
  194.   /* 0x95 */ { eDirect    , 0, 1, "bita" },
  195.   /* 0x96 */ { eDirect    , 0, 1, "ldaa" },
  196.   /* 0x97 */ { eDirect    , 0, 1, "staa" },
  197.   /* 0x98 */ { eDirect    , 0, 1, "eora" },
  198.   /* 0x99 */ { eDirect    , 0, 1, "adca" },
  199.   /* 0x9a */ { eDirect    , 0, 1, "oraa" },
  200.   /* 0x9b */ { eDirect    , 0, 1, "adda" },
  201.   /* 0x9c */ { eDirect    , 1, 1, "cpx"  },
  202.   /* 0x9d */ { eUnknown   , 0, 0, NULL   },
  203.   /* 0x9e */ { eDirect    , 1, 1, "lds"  },
  204.   /* 0x9f */ { eDirect    , 1, 1, "sts"  },
  205.   /* 0xa0 */ { eIndexed   , 0, 1, "suba" },
  206.   /* 0xa1 */ { eIndexed   , 0, 1, "cmpa" },
  207.   /* 0xa2 */ { eIndexed   , 0, 1, "sbca" },
  208.   /* 0xa3 */ { eUnknown   , 0, 0, NULL   },
  209.   /* 0xa4 */ { eIndexed   , 0, 1, "anda" },
  210.   /* 0xa5 */ { eIndexed   , 0, 1, "bita" },
  211.   /* 0xa6 */ { eIndexed   , 0, 1, "ldaa" },
  212.   /* 0xa7 */ { eIndexed   , 0, 1, "staa" },
  213.   /* 0xa8 */ { eIndexed   , 0, 1, "eora" },
  214.   /* 0xa9 */ { eIndexed   , 0, 1, "adca" },
  215.   /* 0xaa */ { eIndexed   , 0, 1, "oraa" },
  216.   /* 0xab */ { eIndexed   , 0, 1, "adda" },
  217.   /* 0xac */ { eIndexed   , 1, 1, "cpx"  },
  218.   /* 0xad */ { eIndexed   , 0, 1, "jsr"  },
  219.   /* 0xae */ { eIndexed   , 1, 1, "lds"  },
  220.   /* 0xaf */ { eIndexed   , 1, 1, "sts"  },
  221.   /* 0xb0 */ { eExtended  , 0, 1, "suba" },
  222.   /* 0xb1 */ { eExtended  , 0, 1, "cmpa" },
  223.   /* 0xb2 */ { eExtended  , 0, 1, "sbca" },
  224.   /* 0xb3 */ { eUnknown   , 0, 0, NULL   },
  225.   /* 0xb4 */ { eExtended  , 0, 1, "anda" },
  226.   /* 0xb5 */ { eExtended  , 0, 1, "bita" },
  227.   /* 0xb6 */ { eExtended  , 0, 1, "ldaa" },
  228.   /* 0xb7 */ { eExtended  , 0, 1, "staa" },
  229.   /* 0xb8 */ { eExtended  , 0, 1, "eora" },
  230.   /* 0xb9 */ { eExtended  , 0, 1, "adca" },
  231.   /* 0xba */ { eExtended  , 0, 1, "oraa" },
  232.   /* 0xbb */ { eExtended  , 0, 1, "adda" },
  233.   /* 0xbc */ { eExtended  , 1, 1, "cpx"  },
  234.   /* 0xbd */ { eExtended  , 0, 3, "jsr"  },
  235.   /* 0xbe */ { eExtended  , 1, 0, "lds"  },
  236.   /* 0xbf */ { eExtended  , 1, 0, "sts"  },
  237.   /* 0xc0 */ { eImmediate , 0, 1, "subb" },
  238.   /* 0xc1 */ { eImmediate , 0, 1, "cmpb" },
  239.   /* 0xc2 */ { eImmediate , 0, 1, "sbcb" },
  240.   /* 0xc3 */ { eUnknown   , 0, 0, NULL   },
  241.   /* 0xc4 */ { eImmediate , 0, 1, "andb" },
  242.   /* 0xc5 */ { eImmediate , 0, 1, "bitb" },
  243.   /* 0xc6 */ { eImmediate , 0, 1, "ldab" },
  244.   /* 0xc7 */ { eImmediate , 0, 1, "stab" },
  245.   /* 0xc8 */ { eImmediate , 0, 1, "eorb" },
  246.   /* 0xc9 */ { eImmediate , 0, 1, "adcb" },
  247.   /* 0xca */ { eImmediate , 0, 1, "orab" },
  248.   /* 0xcb */ { eImmediate , 0, 1, "addb" },
  249.   /* 0xcc */ { eUnknown   , 0, 0, NULL   },
  250.   /* 0xcd */ { eUnknown   , 0, 0, NULL   },
  251.   /* 0xce */ { eImmediate , 1, 1, "ldx"  },
  252.   /* 0xcf */ { eUnknown   , 0, 0, NULL   },
  253.   /* 0xd0 */ { eDirect    , 0, 1, "subb" },
  254.   /* 0xd1 */ { eDirect    , 0, 1, "cmpb" },
  255.   /* 0xd2 */ { eDirect    , 0, 1, "sbcb" },
  256.   /* 0xd3 */ { eUnknown   , 0, 0, NULL   },
  257.   /* 0xd4 */ { eDirect    , 0, 1, "andb" },
  258.   /* 0xd5 */ { eDirect    , 0, 1, "bitb" },
  259.   /* 0xd6 */ { eDirect    , 0, 1, "ldab" },
  260.   /* 0xd7 */ { eDirect    , 0, 1, "stab" },
  261.   /* 0xd8 */ { eDirect    , 0, 1, "eorb" },
  262.   /* 0xd9 */ { eDirect    , 0, 1, "adcb" },
  263.   /* 0xda */ { eDirect    , 0, 1, "orab" },
  264.   /* 0xdb */ { eDirect    , 0, 1, "addb" },
  265.   /* 0xdc */ { eUnknown   , 0, 0, NULL   },
  266.   /* 0xdd */ { eUnknown   , 0, 0, NULL   },
  267.   /* 0xde */ { eDirect    , 0, 1, "ldx"  },
  268.   /* 0xdf */ { eDirect    , 0, 1, "stx"  },
  269.   /* 0xe0 */ { eIndexed   , 0, 1, "subb" },
  270.   /* 0xe1 */ { eIndexed   , 0, 1, "cmpb" },
  271.   /* 0xe2 */ { eIndexed   , 0, 1, "sbcb" },
  272.   /* 0xe3 */ { eUnknown   , 0, 0, NULL   },
  273.   /* 0xe4 */ { eIndexed   , 0, 1, "andb" },
  274.   /* 0xe5 */ { eIndexed   , 0, 1, "bitb" },
  275.   /* 0xe6 */ { eIndexed   , 0, 1, "ldab" },
  276.   /* 0xe7 */ { eIndexed   , 0, 1, "stab" },
  277.   /* 0xe8 */ { eIndexed   , 0, 1, "eorb" },
  278.   /* 0xe9 */ { eIndexed   , 0, 1, "adcb" },
  279.   /* 0xea */ { eIndexed   , 0, 1, "orab" },
  280.   /* 0xeb */ { eIndexed   , 0, 1, "addb" },
  281.   /* 0xec */ { eUnknown   , 0, 0, NULL   },
  282.   /* 0xed */ { eUnknown   , 0, 0, NULL   },
  283.   /* 0xee */ { eIndexed   , 1, 1, "ldx"  },
  284.   /* 0xef */ { eIndexed   , 1, 1, "stx"  },
  285.   /* 0xf0 */ { eExtended  , 0, 1, "subb" },
  286.   /* 0xf1 */ { eExtended  , 0, 1, "cmpb" },
  287.   /* 0xf2 */ { eExtended  , 0, 1, "sbcb" },
  288.   /* 0xf3 */ { eUnknown   , 0, 0, NULL   },
  289.   /* 0xf4 */ { eExtended  , 0, 1, "andb" },
  290.   /* 0xf5 */ { eExtended  , 0, 1, "bitb" },
  291.   /* 0xf6 */ { eExtended  , 0, 1, "ldab" },
  292.   /* 0xf7 */ { eExtended  , 0, 1, "stab" },
  293.   /* 0xf8 */ { eExtended  , 0, 1, "eorb" },
  294.   /* 0xf9 */ { eExtended  , 0, 1, "adcb" },
  295.   /* 0xfa */ { eExtended  , 0, 1, "orab" },
  296.   /* 0xfb */ { eExtended  , 0, 1, "addb" },
  297.   /* 0xfc */ { eUnknown   , 0, 0, NULL   },
  298.   /* 0xfd */ { eUnknown   , 0, 0, NULL   },
  299.   /* 0xfe */ { eExtended  , 1, 1, "ldx"  },
  300.   /* 0xff */ { eExtended  , 1, 1, "stx"  },
  301. };
  302.  
  303. static const tOpcodeList DummyOpcode = { eUnknown   , 0, 0, NULL   };
  304.  
  305. static Boolean RetrieveData(LargeWord Address, Byte *pBuffer, unsigned Count)
  306. {
  307.   LargeWord Trans;
  308.  
  309.   while (Count > 0)
  310.   {
  311.     Trans = 0x10000 - Address;
  312.     if (Count < Trans)
  313.       Trans = Count;
  314.     if (!RetrieveCodeFromChunkList(&CodeChunks, Address, pBuffer, Trans))
  315.     {
  316.       char NumString[50];
  317.  
  318.       HexString(NumString, sizeof(NumString), Address, 0);
  319.       fprintf(stderr, "cannot retrieve instruction arg @ 0x%s\n", NumString);
  320.       return FALSE;
  321.     }
  322.     pBuffer += Trans;
  323.     Count -= Trans;
  324.     Address = (Address + Trans) & 0xffff;
  325.     nData += Trans;
  326.   }
  327.   return TRUE;
  328. }
  329.  
  330. static const char *MakeSymbolic(Word Address, int AddrLen, const char *pSymbolPrefix, char *pBuffer, int BufferSize)
  331. {
  332.   const char *pResult;
  333.  
  334.   if ((pResult = LookupInvSymbol(Address)))
  335.     return pResult;
  336.  
  337.   HexString(pBuffer, BufferSize, Address, AddrLen << 1);
  338.   if (!pSymbolPrefix)
  339.   {
  340.     strmaxprep(pBuffer, "$", BufferSize);
  341.     return pBuffer;
  342.   }
  343.  
  344.   strmaxprep(pBuffer, pSymbolPrefix, BufferSize);
  345.   AddInvSymbol(pBuffer, Address);
  346.   return pBuffer;
  347. }
  348.  
  349. static void Disassemble_68(LargeWord Address, tDisassInfo *pInfo, Boolean AsData, int DataSize)
  350. {
  351.   Byte Opcode, Data[10];
  352.   LargeInt Dist;
  353.   char NumBuf[60], NumBuf2[60];
  354.   const char *pOp, *pSymbolPrefix;
  355.   Word OpAddr = 0;
  356.   const tOpcodeList *pOpcode;
  357.  
  358.   pInfo->CodeLen = 0;
  359.   pInfo->NextAddressCount = 0;
  360.   pInfo->SrcLine[0] = '\0';
  361.   pInfo->pRemark = NULL;
  362.  
  363.   if (!RetrieveData(Address, &Opcode, 1))
  364.     return;
  365.   nData = 1;
  366.  
  367.   pOpcode = AsData ? &DummyOpcode : OpcodeList + Opcode;
  368.   switch (pOpcode->Type)
  369.   {
  370.     case eImplicit:
  371.       pInfo->CodeLen = 1;
  372.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s", pOpcode->Memo);
  373.       break;
  374.     case eDirect:
  375.       if (!RetrieveData(Address + 1, Data, 1))
  376.         return;
  377.       pInfo->CodeLen = 2;
  378.       OpAddr = Data[0];
  379.       pOp = MakeSymbolic(OpAddr, 1, NULL, NumBuf, sizeof(NumBuf));
  380.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\t%s", pOpcode->Memo, pOp);
  381.       break;
  382.     case eIndexed:
  383.       if (!RetrieveData(Address + 1, Data, 1))
  384.         return;
  385.       pInfo->CodeLen = 2;
  386.       OpAddr = Data[0];
  387.       pOp = MakeSymbolic(OpAddr, 1, NULL, NumBuf, sizeof(NumBuf));
  388.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\t%s,x", pOpcode->Memo, pOp);
  389.       if (!pOpcode->NextAddresses)
  390.         pInfo->pRemark = "indirect jump, investigate here";
  391.       if ((pOpcode->NextAddresses == 1) && (!strcmp(pOpcode->Memo, "jsr")))
  392.         pInfo->pRemark = "indirect subroutine call, investigate here";
  393.       break;
  394.     case eExtended:
  395.       if (!RetrieveData(Address + 1, Data, 2))
  396.         return;
  397.       pInfo->CodeLen = 3;
  398.       OpAddr = (((Word)Data[0]) << 8) | Data[1];
  399.       if (pOpcode->NextAddresses & 2)
  400.         pSymbolPrefix = strcmp(pOpcode->Memo, "jsr") ? "lab_" : "sub_";
  401.       else
  402.         pSymbolPrefix = NULL;
  403.       pOp = MakeSymbolic(OpAddr, 2, pSymbolPrefix, NumBuf, sizeof(NumBuf));
  404.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\t%s", pOpcode->Memo, pOp);
  405.       break;
  406.     case eImmediate:
  407.       if (!RetrieveData(Address + 1, Data, pOpcode->OpSize + 1))
  408.         return;
  409.       pInfo->CodeLen = 2 + pOpcode->OpSize;
  410.       OpAddr = pOpcode->OpSize ? (((Word)Data[0]) << 8) | Data[1] : Data[0];
  411.       pOp = MakeSymbolic(OpAddr, pOpcode->OpSize + 1, NULL, NumBuf, sizeof(NumBuf));
  412.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\t#%s", pOpcode->Memo, pOp);
  413.       break;
  414.     case eRelative:
  415.       if (!RetrieveData(Address + 1, Data, 1))
  416.         return;
  417.       pInfo->CodeLen = 2;
  418.       Dist = Data[0];
  419.       if (Dist & 0x80)
  420.         Dist -= 256;
  421.       OpAddr = (Address + 2 + Dist) & 0xffff;
  422.       pOp = MakeSymbolic(OpAddr, 2, strcmp(pOpcode->Memo, "bsr") ? "lab_" : "sub_", NumBuf, sizeof(NumBuf));
  423.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\t%s", pOpcode->Memo, pOp);
  424.       break;
  425.     default:
  426.       if (DataSize < 0)
  427.         DataSize = 1;
  428.       if (!RetrieveData(Address + 1, Data, DataSize - 1))
  429.         return;
  430.       HexString(NumBuf, sizeof(NumBuf), Opcode, 2);
  431.       HexString(NumBuf2, sizeof(NumBuf2), Address, 0);
  432.       if (!AsData)
  433.         fprintf(stderr, "unknown opcode 0x%s @ %s\n", NumBuf, NumBuf2);
  434.       switch (DataSize)
  435.       {
  436.         case 2:
  437.           OpAddr = (((Word)Opcode) << 8) | Data[0];
  438.           pOp = MakeSymbolic(OpAddr, 2, NULL, NumBuf, sizeof(NumBuf));
  439.           as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "adr\t%s", pOp);
  440.           pInfo->CodeLen = 2;
  441.           break;
  442.         default:
  443.           pInfo->CodeLen = 1;
  444.           HexString(NumBuf, sizeof(NumBuf), Opcode, 2);
  445.           as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "byt\t$%s", NumBuf);
  446.       }
  447.   }
  448.  
  449.   pInfo->NextAddressCount = 0;
  450.   if (pOpcode->NextAddresses & 2)
  451.     pInfo->NextAddresses[pInfo->NextAddressCount++] = OpAddr;
  452.   if (pOpcode->NextAddresses & 1)
  453.     pInfo->NextAddresses[pInfo->NextAddressCount++] = (Address + pInfo->CodeLen) % 0xffff;
  454.  
  455.   if (nData != pInfo->CodeLen)
  456.     as_snprcatf(pInfo->SrcLine, sizeof(pInfo->SrcLine), " ; ouch %u != %u", nData, pInfo->CodeLen);
  457. }
  458.  
  459. static void SwitchTo_68(void)
  460. {
  461.   Disassemble = Disassemble_68;
  462. }
  463.  
  464. void deco68_init(void)
  465. {
  466.   CPU6800 = AddCPU("6800", SwitchTo_68);
  467.   CPU6802 = AddCPU("6802", SwitchTo_68);
  468. }
  469.