Subversion Repositories pentevo

Rev

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

  1. /* deco87c800.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /*                                                                           */
  6. /* DissectorTLCS-870                                                         */
  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 "deco87c800.h"
  20.  
  21. static CPUVar CPU87C00;
  22.  
  23. static const char Reg8Names[] = "awcbedlh";
  24. static const char *Reg16Names[] = { "wa", "bc", "de", "hl" };
  25. static const char *RelNames[8] =
  26. {
  27.   "z", "nz", "cs", "cc", "le", "gt", "t", "f"
  28. };
  29. static const char *ALUInstr[8] =
  30. {
  31.   "addc", "add", "subb", "sub", "and" , "xor", "or", "cmp"
  32. };
  33.  
  34. static unsigned nData;
  35.  
  36. static char *ZeroHexString(char *pBuffer, size_t BufferSize, LargeWord Num, int ByteLen)
  37. {
  38.   HexString(pBuffer + 1, BufferSize - 1, Num, ByteLen * 2);
  39.   if (isdigit(pBuffer[1]))
  40.     return pBuffer + 1;
  41.   else
  42.   {
  43.     pBuffer[0] = '0';
  44.     return pBuffer;
  45.   }
  46. }
  47.  
  48. static const char *MakeSymbolic(LargeWord Address, int AddrLen, const char *pSymbolPrefix, char *pBuffer, int BufferSize)
  49. {
  50.   const char *pResult;
  51.  
  52.   if ((pResult = LookupInvSymbol(Address)))
  53.     return pResult;
  54.  
  55.   HexString(pBuffer, BufferSize, Address, AddrLen << 1);
  56.   if (!pSymbolPrefix)
  57.   {
  58.     if (isdigit(*pBuffer))
  59.       strmaxprep(pBuffer, "0", BufferSize);
  60.     as_snprcatf(pBuffer, BufferSize, "%c", HexStartCharacter + ('h' - 'a'));
  61.     return pBuffer;
  62.   }
  63.  
  64.   strmaxprep(pBuffer, pSymbolPrefix, BufferSize);
  65.   AddInvSymbol(pBuffer, Address);
  66.   return pBuffer;
  67. }
  68.  
  69. static Boolean RetrieveData(LargeWord Address, Byte *pBuffer, unsigned Count)
  70. {
  71.   LargeWord Trans;
  72.  
  73.   while (Count > 0)
  74.   {
  75.     Trans = 0x10000 - Address;
  76.     if (Count < Trans)
  77.       Trans = Count;
  78.     if (!RetrieveCodeFromChunkList(&CodeChunks, Address, pBuffer, Trans))
  79.     {
  80.       char NumString[50];
  81.  
  82.       HexString(NumString, sizeof(NumString), Address, 0);
  83.       fprintf(stderr, "cannot retrieve code @ 0x%s\n", NumString);
  84.       return False;
  85.     }
  86.     pBuffer += Trans;
  87.     Count -= Trans;
  88.     Address = (Address + Trans) & 0xffff;
  89.     nData += Trans;
  90.   }
  91.   return TRUE;
  92. }
  93.  
  94. static void SimpleNextAddress(tDisassInfo *pInfo, LargeWord ThisAddress)
  95. {
  96.   pInfo->NextAddressCount = 1;
  97.   pInfo->NextAddresses[0] = (ThisAddress + pInfo->CodeLen) % 0xffff;
  98. }
  99.  
  100. static void PrintData(char *pDest, size_t DestSize, const Byte *pData, unsigned DataLen)
  101. {
  102.   char NumBuf[40];
  103.   unsigned z;
  104.  
  105.   as_snprintf(pDest, DestSize, "db\t");
  106.   for (z = 0; z < DataLen; z++)
  107.   {
  108.     if (z)
  109.       as_snprcatf(pDest, DestSize, ",");
  110.     as_snprcatf(pDest, DestSize, "%sh", ZeroHexString(NumBuf, sizeof(NumBuf), pData[z], 1));
  111.   }
  112. }
  113.  
  114. static void RegPrefix(LargeWord Address, tDisassInfo *pInfo, unsigned PrefixLen, unsigned SrcRegIndex)
  115. {
  116.   Byte Opcode, Data[5];
  117.   char NumBuf[40], NumBuf2[40];
  118.  
  119.   if (!RetrieveData(Address + PrefixLen, &Opcode, 1))
  120.     return;
  121.  
  122.   switch (Opcode)
  123.   {
  124.     case 0x01:
  125.       pInfo->CodeLen = PrefixLen + 1;
  126.       SimpleNextAddress(pInfo, Address);
  127.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "swap\t%c",
  128.                   Reg8Names[SrcRegIndex]);
  129.       break;
  130.     case 0x02:
  131.       if (SrcRegIndex > 3)
  132.         goto inv16;
  133.       pInfo->CodeLen = PrefixLen + 1;
  134.       SimpleNextAddress(pInfo, Address);
  135.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "mul\t%c,%c",
  136.                   Reg8Names[SrcRegIndex * 2 + 1], Reg8Names[SrcRegIndex * 2]);
  137.       break;
  138.     case 0x03:
  139.       if (SrcRegIndex > 3)
  140.         goto inv16;
  141.       pInfo->CodeLen = PrefixLen + 1;
  142.       SimpleNextAddress(pInfo, Address);
  143.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "div\t%s,c",
  144.                   Reg16Names[SrcRegIndex]);
  145.       break;
  146.     case 0x04:
  147.       if (SrcRegIndex > 0)
  148.         goto inv16;
  149.       pInfo->CodeLen = PrefixLen + 1;
  150.       SimpleNextAddress(pInfo, Address);
  151.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "retn");
  152.       break;
  153.     case 0x06:
  154.       if (SrcRegIndex > 3)
  155.         goto inv16;
  156.       pInfo->CodeLen = PrefixLen + 1;
  157.       SimpleNextAddress(pInfo, Address);
  158.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "pop\t%s",
  159.                   Reg16Names[SrcRegIndex]);
  160.       break;
  161.     case 0x07:
  162.       if (SrcRegIndex > 3)
  163.         goto inv16;
  164.       pInfo->CodeLen = PrefixLen + 1;
  165.       SimpleNextAddress(pInfo, Address);
  166.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "push\t%s",
  167.                   Reg16Names[SrcRegIndex]);
  168.       break;
  169.     case 0x0a:
  170.       pInfo->CodeLen = PrefixLen + 1;
  171.       SimpleNextAddress(pInfo, Address);
  172.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "daa\t%c",
  173.                   Reg8Names[SrcRegIndex]);
  174.       break;
  175.     case 0x0b:
  176.       pInfo->CodeLen = PrefixLen + 1;
  177.       SimpleNextAddress(pInfo, Address);
  178.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "das\t%c",
  179.                   Reg8Names[SrcRegIndex]);
  180.       break;
  181.     case 0x10: case 0x11: case 0x12: case 0x13:
  182.       if (SrcRegIndex > 3)
  183.         goto inv16;
  184.       pInfo->CodeLen = PrefixLen + 1;
  185.       SimpleNextAddress(pInfo, Address);
  186.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "xch\t%s,%s",
  187.                   Reg16Names[Opcode & 3], Reg16Names[SrcRegIndex]);
  188.       break;
  189.     case 0x14: case 0x15: case 0x16: case 0x17:
  190.       if (SrcRegIndex > 3)
  191.         goto inv16;
  192.       pInfo->CodeLen = PrefixLen + 1;
  193.       SimpleNextAddress(pInfo, Address);
  194.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%s,%s",
  195.                   Reg16Names[Opcode & 3], Reg16Names[SrcRegIndex]);
  196.       break;
  197.     case 0x1c:
  198.       pInfo->CodeLen = PrefixLen + 1;
  199.       SimpleNextAddress(pInfo, Address);
  200.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "shlc\t%c",
  201.                   Reg8Names[SrcRegIndex]);
  202.       break;
  203.     case 0x1d:
  204.       pInfo->CodeLen = PrefixLen + 1;
  205.       SimpleNextAddress(pInfo, Address);
  206.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "shrc\t%c",
  207.                   Reg8Names[SrcRegIndex]);
  208.       break;
  209.     case 0x1e:
  210.       pInfo->CodeLen = PrefixLen + 1;
  211.       SimpleNextAddress(pInfo, Address);
  212.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "rolc\t%c",
  213.                   Reg8Names[SrcRegIndex]);
  214.       break;
  215.     case 0x1f:
  216.       pInfo->CodeLen = PrefixLen + 1;
  217.       SimpleNextAddress(pInfo, Address);
  218.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "rorc\t%c",
  219.                   Reg8Names[SrcRegIndex]);
  220.       break;
  221.     case 0x30: case 0x31: case 0x32: case 0x33:
  222.     case 0x34: case 0x35: case 0x36: case 0x37:
  223.       if (SrcRegIndex > 3)
  224.         goto inv16;
  225.       pInfo->CodeLen = PrefixLen + 1;
  226.       SimpleNextAddress(pInfo, Address);
  227.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\twa,%s",
  228.                   ALUInstr[Opcode & 7], Reg16Names[SrcRegIndex]);
  229.       break;
  230.     case 0x38: case 0x39: case 0x3a: case 0x3b:
  231.     case 0x3c: case 0x3d: case 0x3e: case 0x3f:
  232.       if (SrcRegIndex > 3)
  233.         goto inv16;
  234.       if (!RetrieveData(Address + PrefixLen + 1, Data, 2))
  235.         return;
  236.       pInfo->CodeLen = PrefixLen + 1 + 2;
  237.       SimpleNextAddress(pInfo, Address);
  238.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\t%s,%sh",
  239.                   ALUInstr[Opcode & 7], Reg16Names[SrcRegIndex],
  240.                   ZeroHexString(NumBuf, sizeof(NumBuf), (((Word)Data[1]) << 8) | Data[0], 2));
  241.       break;
  242.     case 0x40: case 0x41: case 0x42: case 0x43:
  243.     case 0x44: case 0x45: case 0x46: case 0x47:
  244.       pInfo->CodeLen = PrefixLen + 1;
  245.       SimpleNextAddress(pInfo, Address);
  246.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "set\t%c.%u",
  247.                   Reg8Names[SrcRegIndex], Opcode & 7);
  248.       break;
  249.     case 0x48: case 0x49: case 0x4a: case 0x4b:
  250.     case 0x4c: case 0x4d: case 0x4e: case 0x4f:
  251.       pInfo->CodeLen = PrefixLen + 1;
  252.       SimpleNextAddress(pInfo, Address);
  253.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "clr\t%c.%u",
  254.                   Reg8Names[SrcRegIndex], Opcode & 7);
  255.       break;
  256.     case 0x58: case 0x59: case 0x5a: case 0x5b:
  257.     case 0x5c: case 0x5d: case 0x5e: case 0x5f:
  258.       pInfo->CodeLen = PrefixLen + 1;
  259.       SimpleNextAddress(pInfo, Address);
  260.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%c,%c",
  261.                   Reg8Names[Opcode & 7], Reg8Names[SrcRegIndex]);
  262.       break;
  263.     case 0x60: case 0x61: case 0x62: case 0x63:
  264.     case 0x64: case 0x65: case 0x66: case 0x67:
  265.       pInfo->CodeLen = PrefixLen + 1;
  266.       SimpleNextAddress(pInfo, Address);
  267.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\ta,%c",
  268.                   ALUInstr[Opcode & 7], Reg8Names[SrcRegIndex]);
  269.       break;
  270.     case 0x68: case 0x69: case 0x6a: case 0x6b:
  271.     case 0x6c: case 0x6d: case 0x6e: case 0x6f:
  272.       pInfo->CodeLen = PrefixLen + 1;
  273.       SimpleNextAddress(pInfo, Address);
  274.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\t%c,a",
  275.                   ALUInstr[Opcode & 7], Reg8Names[SrcRegIndex]);
  276.       break;
  277.     case 0x70: case 0x71: case 0x72: case 0x73:
  278.     case 0x74: case 0x75: case 0x76: case 0x77:
  279.       if (!RetrieveData(Address + PrefixLen + 1, Data, 1))
  280.         return;
  281.       pInfo->CodeLen = PrefixLen + 1 + 1;
  282.       SimpleNextAddress(pInfo, Address);
  283.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\t%c,%s",
  284.                   ALUInstr[Opcode & 7], Reg8Names[SrcRegIndex],
  285.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  286.       break;
  287.     case 0x82: case 0x83:
  288.       pInfo->CodeLen = PrefixLen + 1;
  289.       SimpleNextAddress(pInfo, Address);
  290.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "set\t(%s).%c",
  291.                   Reg16Names[Opcode & 3], Reg8Names[SrcRegIndex]);
  292.       break;
  293.     case 0x8a: case 0x8b:
  294.       pInfo->CodeLen = PrefixLen + 1;
  295.       SimpleNextAddress(pInfo, Address);
  296.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "clr\t(%s).%c",
  297.                   Reg16Names[Opcode & 3], Reg8Names[SrcRegIndex]);
  298.       break;
  299.     case 0x92: case 0x93:
  300.       pInfo->CodeLen = PrefixLen + 1;
  301.       SimpleNextAddress(pInfo, Address);
  302.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "cpl\t(%s).%c",
  303.                   Reg16Names[Opcode & 3], Reg8Names[SrcRegIndex]);
  304.       break;
  305.     case 0x9a: case 0x9b:
  306.       pInfo->CodeLen = PrefixLen + 1;
  307.       SimpleNextAddress(pInfo, Address);
  308.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t(%s).%c,cf",
  309.                   Reg16Names[Opcode & 3], Reg8Names[SrcRegIndex]);
  310.       break;
  311.     case 0x9e: case 0x9f:
  312.       pInfo->CodeLen = PrefixLen + 1;
  313.       SimpleNextAddress(pInfo, Address);
  314.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\tcf,(%s).%c",
  315.                   Reg16Names[Opcode & 3], Reg8Names[SrcRegIndex]);
  316.       break;
  317.     case 0xa8: case 0xa9: case 0xaa: case 0xab:
  318.     case 0xac: case 0xad: case 0xae: case 0xaf:
  319.       pInfo->CodeLen = PrefixLen + 1;
  320.       SimpleNextAddress(pInfo, Address);
  321.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "xch\t%c,%c",
  322.                   Reg8Names[Opcode & 7], Reg8Names[SrcRegIndex]);
  323.       break;
  324.     case 0xc0: case 0xc1: case 0xc2: case 0xc3:
  325.     case 0xc4: case 0xc5: case 0xc6: case 0xc7:
  326.       pInfo->CodeLen = PrefixLen + 1;
  327.       SimpleNextAddress(pInfo, Address);
  328.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "cpl\t%c.%u",
  329.                   Reg8Names[SrcRegIndex], Opcode & 7);
  330.       break;
  331.     case 0xc8: case 0xc9: case 0xca: case 0xcb:
  332.     case 0xcc: case 0xcd: case 0xce: case 0xcf:
  333.       pInfo->CodeLen = PrefixLen + 1;
  334.       SimpleNextAddress(pInfo, Address);
  335.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%c.%u,cf",
  336.                   Reg8Names[SrcRegIndex], Opcode & 7);
  337.       break;
  338.     case 0xd0: case 0xd1: case 0xd2: case 0xd3:
  339.     case 0xd4: case 0xd5: case 0xd6: case 0xd7:
  340.       pInfo->CodeLen = PrefixLen + 1;
  341.       SimpleNextAddress(pInfo, Address);
  342.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "xor\tcf,%c.%u",
  343.                   Reg8Names[SrcRegIndex], Opcode & 7);
  344.       break;
  345.     case 0xd8: case 0xd9: case 0xda: case 0xdb:
  346.     case 0xdc: case 0xdd: case 0xde: case 0xdf:
  347.       pInfo->CodeLen = PrefixLen + 1;
  348.       SimpleNextAddress(pInfo, Address);
  349.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\tcf,%c.%u",
  350.                   Reg8Names[SrcRegIndex], Opcode & 7);
  351.       break;
  352.     inv16:
  353.     case 0xfa:
  354.       if (SrcRegIndex > 3)
  355.         goto inv16;
  356.       pInfo->CodeLen = PrefixLen + 1;
  357.       SimpleNextAddress(pInfo, Address);
  358.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\tsp,%s",
  359.                   Reg16Names[Opcode & 3]);
  360.       break;
  361.     case 0xfb:
  362.       if (SrcRegIndex > 3)
  363.         goto inv16;
  364.       pInfo->CodeLen = PrefixLen + 1;
  365.       SimpleNextAddress(pInfo, Address);
  366.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%s,sp",
  367.                   Reg16Names[Opcode & 3]);
  368.       break;
  369.     case 0xfc:
  370.       if (SrcRegIndex > 3)
  371.         goto inv16;
  372.       pInfo->CodeLen = PrefixLen + 1;
  373.       SimpleNextAddress(pInfo, Address);
  374.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "call\t%s",
  375.                   Reg16Names[Opcode & 3]);
  376.       pInfo->pRemark = "indirect jump, investigate here";
  377.       break;
  378.     case 0xfe:
  379.       if (SrcRegIndex > 3)
  380.         goto inv16;
  381.       pInfo->CodeLen = PrefixLen + 1;
  382.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "jp\t%s",
  383.                   Reg16Names[Opcode & 3]);
  384.       pInfo->pRemark = "indirect jump, investigate here";
  385.       break;
  386.     default:
  387.       HexString(NumBuf, sizeof(NumBuf), Opcode, 2);
  388.       HexString(NumBuf2, sizeof(NumBuf2), Address, 0);
  389.       printf("unknown reg prefix opcode 0x%s @ %s\n", NumBuf, NumBuf2);
  390.       pInfo->CodeLen = PrefixLen + 1;
  391.       pInfo->NextAddressCount = 0;
  392.       RetrieveData(Address, Data, pInfo->CodeLen);
  393.       nData -= pInfo->CodeLen;
  394.       PrintData(pInfo->SrcLine, sizeof(pInfo->SrcLine), Data, pInfo->CodeLen);
  395.       break;
  396.   }
  397. }
  398.  
  399. static void MemPrefix(LargeWord Address, tDisassInfo *pInfo, unsigned PrefixLen, const char *pPrefixString)
  400. {
  401.   Byte Opcode, Data[5];
  402.   char NumBuf[40], NumBuf2[40];
  403.  
  404.   if (!RetrieveData(Address + PrefixLen, &Opcode, 1))
  405.     return;
  406.  
  407.   switch (Opcode)
  408.   {
  409.     case 0x08:
  410.       pInfo->CodeLen = PrefixLen + 1;
  411.       SimpleNextAddress(pInfo, Address);
  412.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "rold\ta,%s",
  413.                   pPrefixString);
  414.       break;
  415.     case 0x09:
  416.       pInfo->CodeLen = PrefixLen + 1;
  417.       SimpleNextAddress(pInfo, Address);
  418.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "rord\ta,%s",
  419.                   pPrefixString);
  420.       break;
  421.     case 0x10: case 0x11: case 0x12: case 0x13:
  422.       pInfo->CodeLen = PrefixLen + 1;
  423.       SimpleNextAddress(pInfo, Address);
  424.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%s,%s",
  425.                   pPrefixString, Reg16Names[Opcode & 3]);
  426.       break;
  427.     case 0x14: case 0x15: case 0x16: case 0x17:
  428.       pInfo->CodeLen = PrefixLen + 1;
  429.       SimpleNextAddress(pInfo, Address);
  430.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%s,%s",
  431.                   Reg16Names[Opcode & 3], pPrefixString);
  432.       break;
  433.     case 0x20:
  434.       pInfo->CodeLen = PrefixLen + 1;
  435.       SimpleNextAddress(pInfo, Address);
  436.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "inc\t%s",
  437.                   pPrefixString);
  438.       break;
  439.     case 0x26:
  440.       if (!RetrieveData(Address + PrefixLen + 1, Data, 1))
  441.         return;
  442.       pInfo->CodeLen = PrefixLen + 1 + 1;
  443.       SimpleNextAddress(pInfo, Address);
  444.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t(%sh),%s",
  445.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1), pPrefixString);
  446.       break;
  447.     case 0x27:
  448.       pInfo->CodeLen = PrefixLen + 1;
  449.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t(hl),%s",
  450.                   pPrefixString);
  451.       break;
  452.     case 0x28:
  453.       pInfo->CodeLen = PrefixLen + 1;
  454.       SimpleNextAddress(pInfo, Address);
  455.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "dec\t%s",
  456.                   pPrefixString);
  457.       break;
  458.     case 0x2c:
  459.       if (!RetrieveData(Address + PrefixLen + 1, Data, 1))
  460.         return;
  461.       pInfo->CodeLen = PrefixLen + 1 + 1;
  462.       SimpleNextAddress(pInfo, Address);
  463.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%s,%sh",
  464.                   pPrefixString, ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  465.       break;
  466.     case 0x2f:
  467.       if (!RetrieveData(Address + PrefixLen + 1, Data, 1))
  468.         return;
  469.       pInfo->CodeLen = PrefixLen + 1 + 1;
  470.       SimpleNextAddress(pInfo, Address);
  471.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "mcmp\t%s,%sh",
  472.                   pPrefixString, ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  473.       break;
  474.     case 0x40: case 0x41: case 0x42: case 0x43:
  475.     case 0x44: case 0x45: case 0x46: case 0x47:
  476.       pInfo->CodeLen = PrefixLen + 1;
  477.       SimpleNextAddress(pInfo, Address);
  478.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "set\t%s.%u",
  479.                   pPrefixString, Opcode & 7);
  480.       break;
  481.     case 0x48: case 0x49: case 0x4a: case 0x4b:
  482.     case 0x4c: case 0x4d: case 0x4e: case 0x4f:
  483.       pInfo->CodeLen = PrefixLen + 1;
  484.       SimpleNextAddress(pInfo, Address);
  485.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "clr\t%s.%u",
  486.                   pPrefixString, Opcode & 7);
  487.       break;
  488.     case 0x50: case 0x51: case 0x52: case 0x53:
  489.     case 0x54: case 0x55: case 0x56: case 0x57:
  490.       pInfo->CodeLen = PrefixLen + 1;
  491.       SimpleNextAddress(pInfo, Address);
  492.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%s,%c",
  493.                   pPrefixString, Reg8Names[Opcode & 7]);
  494.       break;
  495.     case 0x58: case 0x59: case 0x5a: case 0x5b:
  496.     case 0x5c: case 0x5d: case 0x5e: case 0x5f:
  497.       pInfo->CodeLen = PrefixLen + 1;
  498.       SimpleNextAddress(pInfo, Address);
  499.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%c,%s",
  500.                   Reg8Names[Opcode & 7], pPrefixString);
  501.       break;
  502.     case 0x60: case 0x61: case 0x62: case 0x63:
  503.     case 0x64: case 0x65: case 0x66: case 0x67:
  504.       pInfo->CodeLen = PrefixLen + 1;
  505.       SimpleNextAddress(pInfo, Address);
  506.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\t%s,(hl)",
  507.                   ALUInstr[Opcode & 7], pPrefixString);
  508.       break;
  509.     case 0x70: case 0x71: case 0x72: case 0x73:
  510.     case 0x74: case 0x75: case 0x76: case 0x77:
  511.       if (!RetrieveData(Address + PrefixLen + 1, Data, 1))
  512.         return;
  513.       pInfo->CodeLen = PrefixLen + 1 + 1;
  514.       SimpleNextAddress(pInfo, Address);
  515.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\t%s,%sh",
  516.                   ALUInstr[Opcode & 7], pPrefixString,
  517.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  518.       break;
  519.     case 0x78: case 0x79: case 0x7a: case 0x7b:
  520.     case 0x7c: case 0x7d: case 0x7e: case 0x7f:
  521.       pInfo->CodeLen = PrefixLen + 1;
  522.       SimpleNextAddress(pInfo, Address);
  523.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\ta,%s",
  524.                   ALUInstr[Opcode & 7], pPrefixString);
  525.       break;
  526.     case 0xa8: case 0xa9: case 0xaa: case 0xab:
  527.     case 0xac: case 0xad: case 0xae: case 0xaf:
  528.       pInfo->CodeLen = PrefixLen + 1;
  529.       SimpleNextAddress(pInfo, Address);
  530.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "xch\t%c,%s",
  531.                   Reg8Names[Opcode & 7], pPrefixString);
  532.       break;
  533.     case 0xc0: case 0xc1: case 0xc2: case 0xc3:
  534.     case 0xc4: case 0xc5: case 0xc6: case 0xc7:
  535.       pInfo->CodeLen = PrefixLen + 1;
  536.       SimpleNextAddress(pInfo, Address);
  537.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "cpl\t%s.%u",
  538.                   pPrefixString, Opcode & 7);
  539.       break;
  540.     case 0xc8: case 0xc9: case 0xca: case 0xcb:
  541.     case 0xcc: case 0xcd: case 0xce: case 0xcf:
  542.       pInfo->CodeLen = PrefixLen + 1;
  543.       SimpleNextAddress(pInfo, Address);
  544.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%s.%u,cf",
  545.                   pPrefixString, Opcode & 7);
  546.       break;
  547.     case 0xd0: case 0xd1: case 0xd2: case 0xd3:
  548.     case 0xd4: case 0xd5: case 0xd6: case 0xd7:
  549.       pInfo->CodeLen = PrefixLen + 1;
  550.       SimpleNextAddress(pInfo, Address);
  551.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "xor\tcf,%s.%u",
  552.                   pPrefixString, Opcode & 7);
  553.       break;
  554.     case 0xd8: case 0xd9: case 0xda: case 0xdb:
  555.     case 0xdc: case 0xdd: case 0xde: case 0xdf:
  556.       pInfo->CodeLen = PrefixLen + 1;
  557.       SimpleNextAddress(pInfo, Address);
  558.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\tcf,%s.%u",
  559.                   pPrefixString, Opcode & 7);
  560.       break;
  561.     case 0xfc:
  562.       pInfo->CodeLen = PrefixLen + 1;
  563.       SimpleNextAddress(pInfo, Address);
  564.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "call\t%s",
  565.                   pPrefixString);
  566.       pInfo->pRemark = "indirect subroutine call, investigate here";
  567.       break;
  568.     case 0xfe:
  569.       pInfo->CodeLen = PrefixLen + 1;
  570.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "jp\t%s",
  571.                   pPrefixString);
  572.       pInfo->pRemark = "indirect jump, investigate here";
  573.       break;
  574.     default:
  575.       HexString(NumBuf, sizeof(NumBuf), Opcode, 2);
  576.       HexString(NumBuf2, sizeof(NumBuf2), Address, 0);
  577.       printf("unknown mem opcode 0x%s @ %s\n", NumBuf, NumBuf2);
  578.       pInfo->CodeLen = PrefixLen + 1;
  579.       pInfo->NextAddressCount = 0;
  580.       RetrieveData(Address, Data, pInfo->CodeLen);
  581.       nData -= pInfo->CodeLen;
  582.       PrintData(pInfo->SrcLine, sizeof(pInfo->SrcLine), Data, pInfo->CodeLen);
  583.       break;
  584.   }
  585. }
  586.  
  587. static void Disassemble_87C800(LargeWord Address, tDisassInfo *pInfo, Boolean AsData, int DataSize)
  588. {
  589.   Byte Opcode, Data[10];
  590.   Word Arg;
  591.   char NumBuf[40], NumBuf2[40];
  592.   LargeInt Dist;
  593.   unsigned Vector;
  594.   Boolean ActAsData = AsData;
  595.  
  596.   pInfo->CodeLen = 0;
  597.   pInfo->NextAddressCount = 0;
  598.   pInfo->SrcLine[0] = '\0';
  599.   pInfo->pRemark = NULL;
  600.  
  601.   if (!RetrieveData(Address, &Opcode, 1))
  602.     return;
  603.   nData = 1;
  604.  
  605.   if (!AsData)
  606.   switch (Opcode)
  607.   {
  608.     case 0x00:
  609.       pInfo->CodeLen = 1;
  610.       SimpleNextAddress(pInfo, Address);
  611.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "nop");
  612.       break;
  613.     case 0x01:
  614.       pInfo->CodeLen = 1;
  615.       SimpleNextAddress(pInfo, Address);
  616.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "swap\ta");
  617.       break;
  618.     case 0x02:
  619.       pInfo->CodeLen = 1;
  620.       SimpleNextAddress(pInfo, Address);
  621.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "mul\tw,a");
  622.       break;
  623.     case 0x03:
  624.       pInfo->CodeLen = 1;
  625.       SimpleNextAddress(pInfo, Address);
  626.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "div\twa,c");
  627.       break;
  628.     case 0x04:
  629.       pInfo->CodeLen = 1;
  630.       SimpleNextAddress(pInfo, Address);
  631.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "reti");
  632.       break;
  633.     case 0x05:
  634.       pInfo->CodeLen = 1;
  635.       SimpleNextAddress(pInfo, Address);
  636.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ret");
  637.       break;
  638.     case 0x06:
  639.       pInfo->CodeLen = 1;
  640.       SimpleNextAddress(pInfo, Address);
  641.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "pop\tpsw");
  642.       break;
  643.     case 0x07:
  644.       pInfo->CodeLen = 1;
  645.       SimpleNextAddress(pInfo, Address);
  646.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "push\tpsw");
  647.       break;
  648.     case 0x0a:
  649.       pInfo->CodeLen = 1;
  650.       SimpleNextAddress(pInfo, Address);
  651.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "daa\ta");
  652.       break;
  653.     case 0x0b:
  654.       pInfo->CodeLen = 1;
  655.       SimpleNextAddress(pInfo, Address);
  656.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "das\ta");
  657.       break;
  658.     case 0x0c:
  659.       pInfo->CodeLen = 1;
  660.       SimpleNextAddress(pInfo, Address);
  661.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "clr\tcf");
  662.       break;
  663.     case 0x0d:
  664.       pInfo->CodeLen = 1;
  665.       SimpleNextAddress(pInfo, Address);
  666.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "set\tcf");
  667.       break;
  668.     case 0x0e:
  669.       pInfo->CodeLen = 1;
  670.       SimpleNextAddress(pInfo, Address);
  671.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "cpl\tcf");
  672.       break;
  673.     case 0x0f:
  674.       if (!RetrieveData(Address + 1, Data, 1))
  675.         return;
  676.       pInfo->CodeLen = 2;
  677.       SimpleNextAddress(pInfo, Address);
  678.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\trbs,%sh",
  679.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  680.       break;
  681.     case 0x10: case 0x11: case 0x12: case 0x13:
  682.       pInfo->CodeLen = 1;
  683.       SimpleNextAddress(pInfo, Address);
  684.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "inc\t%s",
  685.                   Reg16Names[Opcode & 3]);
  686.       break;
  687.     case 0x14: case 0x15: case 0x16: case 0x17:
  688.       if (!RetrieveData(Address + 1, Data, 2))
  689.         return;
  690.       pInfo->CodeLen = 3;
  691.       SimpleNextAddress(pInfo, Address);
  692.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%s,%sh",
  693.                   Reg16Names[Opcode & 3],
  694.                   ZeroHexString(NumBuf, sizeof(NumBuf), (((Word)Data[1]) << 8) | Data[0], 2));
  695.       break;
  696.     case 0x18: case 0x19: case 0x1a: case 0x1b:
  697.       pInfo->CodeLen = 1;
  698.       SimpleNextAddress(pInfo, Address);
  699.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "dec\t%s",
  700.                   Reg16Names[Opcode & 3]);
  701.       break;
  702.     case 0x1c:
  703.       pInfo->CodeLen = 1;
  704.       SimpleNextAddress(pInfo, Address);
  705.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "shlc\ta");
  706.       break;
  707.     case 0x1d:
  708.       pInfo->CodeLen = 1;
  709.       SimpleNextAddress(pInfo, Address);
  710.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "shrc\ta");
  711.       break;
  712.     case 0x1e:
  713.       pInfo->CodeLen = 1;
  714.       SimpleNextAddress(pInfo, Address);
  715.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "rolc\ta");
  716.       break;
  717.     case 0x1f:
  718.       pInfo->CodeLen = 1;
  719.       SimpleNextAddress(pInfo, Address);
  720.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "rorc\ta");
  721.       break;
  722.     case 0x20:
  723.       if (!RetrieveData(Address + 1, Data, 1))
  724.         return;
  725.       pInfo->CodeLen = 2;
  726.       SimpleNextAddress(pInfo, Address);
  727.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "inc\t(%sh)",
  728.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  729.       break;
  730.     case 0x21:
  731.       pInfo->CodeLen = 1;
  732.       SimpleNextAddress(pInfo, Address);
  733.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "inc\t(hl)");
  734.       break;
  735.     case 0x22:
  736.       if (!RetrieveData(Address + 1, Data, 1))
  737.         return;
  738.       pInfo->CodeLen = 2;
  739.       SimpleNextAddress(pInfo, Address);
  740.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\ta,(%sh)",
  741.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  742.       break;
  743.     case 0x23:
  744.       pInfo->CodeLen = 1;
  745.       SimpleNextAddress(pInfo, Address);
  746.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\ta,(hl)");
  747.       break;
  748.     case 0x24:
  749.       if (!RetrieveData(Address + 1, Data, 3))
  750.         return;
  751.       pInfo->CodeLen = 4;
  752.       SimpleNextAddress(pInfo, Address);
  753.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ldw\t(%sh),%sh",
  754.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1),
  755.                   ZeroHexString(NumBuf2, sizeof(NumBuf2), (((Word)Data[2]) << 8) | Data[1], 2));
  756.       break;
  757.     case 0x25:
  758.       if (!RetrieveData(Address + 1, Data, 2))
  759.         return;
  760.       pInfo->CodeLen = 3;
  761.       SimpleNextAddress(pInfo, Address);
  762.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ldw\t(hl),%sh",
  763.                   ZeroHexString(NumBuf, sizeof(NumBuf), (((Word)Data[1]) << 8) | Data[0], 2));
  764.       break;
  765.     case 0x26:
  766.       if (!RetrieveData(Address + 1, Data, 2))
  767.         return;
  768.       pInfo->CodeLen = 3;
  769.       SimpleNextAddress(pInfo, Address);
  770.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t(%sh),(%sh)",
  771.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[1], 1),
  772.                   ZeroHexString(NumBuf2, sizeof(NumBuf2), Data[0], 1));
  773.       break;
  774.     case 0x28:
  775.       if (!RetrieveData(Address + 1, Data, 1))
  776.         return;
  777.       pInfo->CodeLen = 2;
  778.       SimpleNextAddress(pInfo, Address);
  779.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "dec\t(%sh)",
  780.                   ZeroHexString(NumBuf2, sizeof(NumBuf2), Data[0], 1));
  781.       break;
  782.     case 0x29:
  783.       pInfo->CodeLen = 1;
  784.       SimpleNextAddress(pInfo, Address);
  785.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "dec\t(hl)");
  786.       break;
  787.     case 0x2a:
  788.       if (!RetrieveData(Address + 1, Data, 1))
  789.         return;
  790.       pInfo->CodeLen = 2;
  791.       SimpleNextAddress(pInfo, Address);
  792.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t(%sh),a",
  793.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  794.       break;
  795.     case 0x2b:
  796.       pInfo->CodeLen = 1;
  797.       SimpleNextAddress(pInfo, Address);
  798.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t(hl),a");
  799.       break;
  800.     case 0x2c:
  801.       if (!RetrieveData(Address + 1, Data, 2))
  802.         return;
  803.       pInfo->CodeLen = 3;
  804.       SimpleNextAddress(pInfo, Address);
  805.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t(%sh),%sh",
  806.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1),
  807.                   ZeroHexString(NumBuf2, sizeof(NumBuf2), Data[1], 1));
  808.       break;
  809.     case 0x2d:
  810.       if (!RetrieveData(Address + 1, Data, 1))
  811.         return;
  812.       pInfo->CodeLen = 2;
  813.       SimpleNextAddress(pInfo, Address);
  814.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t(hl),%sh",
  815.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  816.       break;
  817.     case 0x2e:
  818.       if (!RetrieveData(Address + 1, Data, 1))
  819.         return;
  820.       pInfo->CodeLen = 2;
  821.       SimpleNextAddress(pInfo, Address);
  822.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "clr\t(%sh)",
  823.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  824.       break;
  825.     case 0x2f:
  826.       pInfo->CodeLen = 1;
  827.       SimpleNextAddress(pInfo, Address);
  828.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "clr\t(hl)");
  829.       break;
  830.     case 0x30: case 0x31: case 0x32: case 0x33:
  831.     case 0x34: case 0x35: case 0x36: case 0x37:
  832.       if (!RetrieveData(Address + 1, Data, 1))
  833.         return;
  834.       pInfo->CodeLen = 2;
  835.       SimpleNextAddress(pInfo, Address);
  836.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%c,%sh",
  837.                   Reg8Names[Opcode & 7], ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  838.       break;
  839.     case 0x40: case 0x41: case 0x42: case 0x43:
  840.     case 0x44: case 0x45: case 0x46: case 0x47:
  841.       if (!RetrieveData(Address + 1, Data, 1))
  842.         return;
  843.       pInfo->CodeLen = 2;
  844.       SimpleNextAddress(pInfo, Address);
  845.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "set\t(%sh).%u",
  846.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1), Opcode & 7);
  847.       break;
  848.     case 0x48: case 0x49: case 0x4a: case 0x4b:
  849.     case 0x4c: case 0x4d: case 0x4e: case 0x4f:
  850.       if (!RetrieveData(Address + 1, Data, 1))
  851.         return;
  852.       pInfo->CodeLen = 2;
  853.       SimpleNextAddress(pInfo, Address);
  854.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "clr\t(%sh).%u",
  855.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1), Opcode & 7);
  856.       break;
  857.     case 0x50: case 0x51: case 0x52: case 0x53:
  858.     case 0x54: case 0x55: case 0x56: case 0x57:
  859.       pInfo->CodeLen = 1;
  860.       SimpleNextAddress(pInfo, Address);
  861.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\ta,%c",
  862.                   Reg8Names[Opcode & 7]);
  863.       break;
  864.     case 0x58: case 0x59: case 0x5a: case 0x5b:
  865.     case 0x5c: case 0x5d: case 0x5e: case 0x5f:
  866.       pInfo->CodeLen = 1;
  867.       SimpleNextAddress(pInfo, Address);
  868.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\t%c,a",
  869.                   Reg8Names[Opcode & 7]);
  870.       break;
  871.     case 0x60: case 0x61: case 0x62: case 0x63:
  872.     case 0x64: case 0x65: case 0x66: case 0x67:
  873.       pInfo->CodeLen = 1;
  874.       SimpleNextAddress(pInfo, Address);
  875.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "inc\t%c",
  876.                   Reg8Names[Opcode & 7]);
  877.       break;
  878.     case 0x68: case 0x69: case 0x6a: case 0x6b:
  879.     case 0x6c: case 0x6d: case 0x6e: case 0x6f:
  880.       pInfo->CodeLen = 1;
  881.       SimpleNextAddress(pInfo, Address);
  882.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "dec\t%c",
  883.                   Reg8Names[Opcode & 7]);
  884.       break;
  885.     case 0x70: case 0x71: case 0x72: case 0x73:
  886.     case 0x74: case 0x75: case 0x76: case 0x77:
  887.       if (!RetrieveData(Address + 1, Data, 1))
  888.         return;
  889.       pInfo->CodeLen = 2;
  890.       SimpleNextAddress(pInfo, Address);
  891.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\ta,%sh",
  892.                   ALUInstr[Opcode & 7], ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  893.       break;
  894.     case 0x78: case 0x79: case 0x7a: case 0x7b:
  895.     case 0x7c: case 0x7d: case 0x7e: case 0x7f:
  896.       if (!RetrieveData(Address + 1, Data, 1))
  897.         return;
  898.       pInfo->CodeLen = 2;
  899.       SimpleNextAddress(pInfo, Address);
  900.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "%s\ta,(%sh)",
  901.                   ALUInstr[Opcode & 7],
  902.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  903.       break;
  904.     case 0x80: case 0x81: case 0x82: case 0x83:
  905.     case 0x84: case 0x85: case 0x86: case 0x87:
  906.     case 0x88: case 0x89: case 0x8a: case 0x8b:
  907.     case 0x8c: case 0x8d: case 0x8e: case 0x8f:
  908.     case 0x90: case 0x91: case 0x92: case 0x93:
  909.     case 0x94: case 0x95: case 0x96: case 0x97:
  910.     case 0x98: case 0x99: case 0x9a: case 0x9b:
  911.     case 0x9c: case 0x9d: case 0x9e: case 0x9f:
  912.       pInfo->CodeLen = 1;
  913.       SimpleNextAddress(pInfo, Address);
  914.       Dist = Opcode & 0x1f;
  915.       if (Dist & 0x10)
  916.         Dist = Dist - 32;
  917.       pInfo->NextAddresses[pInfo->NextAddressCount++] = (Address + 2 + Dist) & 0xffff;
  918.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "jrs\tt,%sh",
  919.                   MakeSymbolic(pInfo->NextAddresses[1], 2, "lab_", NumBuf, sizeof(NumBuf)));
  920.       break;
  921.     case 0xa0: case 0xa1: case 0xa2: case 0xa3:
  922.     case 0xa4: case 0xa5: case 0xa6: case 0xa7:
  923.     case 0xa8: case 0xa9: case 0xaa: case 0xab:
  924.     case 0xac: case 0xad: case 0xae: case 0xaf:
  925.     case 0xb0: case 0xb1: case 0xb2: case 0xb3:
  926.     case 0xb4: case 0xb5: case 0xb6: case 0xb7:
  927.     case 0xb8: case 0xb9: case 0xba: case 0xbb:
  928.     case 0xbc: case 0xbd: case 0xbe: case 0xbf:
  929.       pInfo->CodeLen = 1;
  930.       SimpleNextAddress(pInfo, Address);
  931.       Dist = Opcode & 0x1f;
  932.       if (Dist & 0x10)
  933.         Dist = Dist - 32;
  934.       pInfo->NextAddresses[pInfo->NextAddressCount++] = (Address + 2 + Dist) & 0xffff;
  935.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "jrs\tf,%sh",
  936.                   MakeSymbolic(pInfo->NextAddresses[1], 2, "lab_", NumBuf, sizeof(NumBuf)));
  937.       break;
  938.     case 0xc0: case 0xc1: case 0xc2: case 0xc3:
  939.     case 0xc4: case 0xc5: case 0xc6: case 0xc7:
  940.     case 0xc8: case 0xc9: case 0xca: case 0xcb:
  941.     case 0xcc: case 0xcd: case 0xce: case 0xcf:
  942.       Vector = Opcode & 15;
  943.       pInfo->CodeLen = 1;
  944.       SimpleNextAddress(pInfo, Address);
  945.       if (RetrieveData(0xffc0 + (Vector << 1), Data, 2))
  946.         pInfo->NextAddresses[pInfo->NextAddressCount++] = (((Word)Data[1]) << 8) | Data[0];
  947.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "callv\t%u\t ; %sh", Vector,
  948.                   MakeSymbolic(pInfo->NextAddresses[1], 2, "subv_", NumBuf, sizeof(NumBuf)));
  949.       nData -= 2;
  950.       break;
  951.     case 0xd0: case 0xd1: case 0xd2: case 0xd3:
  952.     case 0xd4: case 0xd5: case 0xd6: case 0xd7:
  953.       if (!RetrieveData(Address + 1, Data, 1))
  954.         return;
  955.       pInfo->CodeLen = 2;
  956.       SimpleNextAddress(pInfo, Address);
  957.       Dist = Data[0];
  958.       if (Dist & 0x80)
  959.         Dist -= 256;
  960.       pInfo->NextAddresses[pInfo->NextAddressCount++] = (Address + 2 + Dist) & 0xffff;
  961.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "jr\t%s,%sh",
  962.                   RelNames[Opcode & 7],
  963.                   MakeSymbolic(pInfo->NextAddresses[1], 2, "lab_", NumBuf, sizeof(NumBuf)));
  964.       break;
  965.     case 0xd8: case 0xd9: case 0xda: case 0xdb:
  966.     case 0xdc: case 0xdd: case 0xde: case 0xdf:
  967.       if (!RetrieveData(Address + 1, Data, 1))
  968.         return;
  969.       pInfo->CodeLen = 2;
  970.       SimpleNextAddress(pInfo, Address);
  971.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "test\t(%sh).%u",
  972.                   ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1), Opcode & 7);
  973.       break;
  974.     case 0xe0:
  975.     case 0xf0:
  976.       if (!RetrieveData(Address + 1, Data, 1))
  977.         return;
  978.       as_snprintf(NumBuf2, sizeof(NumBuf2), "(%sh)", ZeroHexString(NumBuf, sizeof(NumBuf), Data[0], 1));
  979.       MemPrefix(Address, pInfo, 2, NumBuf2);
  980.       break;
  981.     case 0xe1:
  982.     case 0xf1:
  983.       MemPrefix(Address, pInfo, 1, "(pc+a)");
  984.       break;
  985.     case 0xe2:
  986.     case 0xf2:
  987.       MemPrefix(Address, pInfo, 1, "(de)");
  988.       break;
  989.     case 0xe3:
  990.     case 0xf3:
  991.       MemPrefix(Address, pInfo, 1, "(hl)");
  992.       break;
  993.     case 0xe4:
  994.     case 0xf4:
  995.       if (!RetrieveData(Address + 1, Data, 1))
  996.         return;
  997.       Dist = Data[0];
  998.       if (Dist & 0x80)
  999.         Dist -= 256;
  1000.       as_snprintf(NumBuf2, sizeof(NumBuf2), "(hl%s%d)",
  1001.                   Dist < 0 ? "" : "+", (int)Dist);
  1002.       MemPrefix(Address, pInfo, 2, NumBuf2);
  1003.       break;
  1004.     case 0xe5:
  1005.     case 0xf5:
  1006.       MemPrefix(Address, pInfo, 1, "(hl+c)");
  1007.       break;
  1008.     case 0xe6:
  1009.     case 0xf6:
  1010.       MemPrefix(Address, pInfo, 1, "(hl+)");
  1011.       break;
  1012.     case 0xe7:
  1013.     case 0xf7:
  1014.       MemPrefix(Address, pInfo, 1, "(-hl)");
  1015.       break;
  1016.     case 0xe8: case 0xe9: case 0xea: case 0xeb:
  1017.     case 0xec: case 0xed: case 0xee: case 0xef:
  1018.       RegPrefix(Address, pInfo, 1, Opcode & 7);
  1019.       break;
  1020.     case 0xfa:
  1021.       if (!RetrieveData(Address + 1, Data, 2))
  1022.         return;
  1023.       pInfo->CodeLen = 3;
  1024.       SimpleNextAddress(pInfo, Address);
  1025.       Arg = (((Word)Data[1]) << 8) | Data[0];
  1026.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "ld\tsp,%sh",
  1027.                   ZeroHexString(NumBuf, sizeof(NumBuf), Arg, 2));
  1028.       break;
  1029.     case 0xfb:
  1030.       if (!RetrieveData(Address + 1, Data, 1))
  1031.         return;
  1032.       pInfo->CodeLen = 2;
  1033.       Dist = Data[0];
  1034.       if (Dist & 0x80)
  1035.         Dist -= 256;
  1036.       pInfo->NextAddresses[pInfo->NextAddressCount++] = (Address + 2 + Dist) & 0xffff;
  1037.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "jr\t%sh",
  1038.                   MakeSymbolic(pInfo->NextAddresses[0], 2, "lab_", NumBuf, sizeof(NumBuf)));
  1039.       break;
  1040.     case 0xfc:
  1041.       if (!RetrieveData(Address + 1, Data, 2))
  1042.         return;
  1043.       pInfo->CodeLen = 3;
  1044.       SimpleNextAddress(pInfo, Address);
  1045.       pInfo->NextAddresses[pInfo->NextAddressCount++] = (((Word)Data[1]) << 8) | Data[0];
  1046.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "call\t%sh",
  1047.                   MakeSymbolic(pInfo->NextAddresses[1], 2, "sub_", NumBuf, sizeof(NumBuf)));
  1048.       break;
  1049.     case 0xfd:
  1050.       if (!RetrieveData(Address + 1, Data, 1))
  1051.         return;
  1052.       pInfo->CodeLen = 2;
  1053.       SimpleNextAddress(pInfo, Address);
  1054.       pInfo->NextAddresses[pInfo->NextAddressCount++] = 0xff00 + Data[0];
  1055.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "callp\t%sh",
  1056.                   MakeSymbolic(pInfo->NextAddresses[1], 2, "sub_", NumBuf, sizeof(NumBuf)));
  1057.       break;
  1058.     case 0xfe:
  1059.       if (!RetrieveData(Address + 1, Data, 2))
  1060.         return;
  1061.       pInfo->CodeLen = 3;
  1062.       pInfo->NextAddresses[pInfo->NextAddressCount++] = (((Word)Data[1]) << 8) | Data[0];
  1063.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "jp\t%sh",
  1064.                   MakeSymbolic(pInfo->NextAddresses[0], 2, "lab_", NumBuf, sizeof(NumBuf)));
  1065.       break;
  1066.     case 0xff:
  1067.       pInfo->CodeLen = 1;
  1068.       SimpleNextAddress(pInfo, Address);
  1069.       as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "swi");
  1070.       break;
  1071.     default:
  1072.       ActAsData = True;
  1073.   }
  1074.  
  1075.   if (ActAsData)
  1076.   {
  1077.     if (DataSize < 0)
  1078.       DataSize = 1;
  1079.     if (!RetrieveData(Address + 1, Data, DataSize - 1))
  1080.       return;
  1081.     HexString(NumBuf, sizeof(NumBuf), Opcode, 2);
  1082.     HexString(NumBuf2, sizeof(NumBuf2), Address, 0);
  1083.     if (!AsData)
  1084.       printf("unknown opcode 0x%s @ %s\n", NumBuf, NumBuf2);
  1085.     pInfo->NextAddressCount = 0;
  1086.     switch (DataSize)
  1087.     {
  1088.       case 2:
  1089.       {
  1090.         Word Addr = (((Word)Data[0]) << 8) | Opcode;
  1091.         as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "dw\t%s",
  1092.                     MakeSymbolic(Addr, 2, NULL, NumBuf, sizeof(NumBuf)));
  1093.         pInfo->CodeLen = 2;
  1094.         break;
  1095.       }
  1096.       default:
  1097.         pInfo->CodeLen = 1;
  1098.         as_snprintf(pInfo->SrcLine, sizeof(pInfo->SrcLine), "db\t%sh",
  1099.                     ZeroHexString(NumBuf, sizeof(NumBuf), Opcode, 1));
  1100.     }
  1101.     if (AsData)
  1102.       SimpleNextAddress(pInfo, Address);
  1103.   }
  1104.  
  1105.   if (nData != pInfo->CodeLen)
  1106.     as_snprcatf(pInfo->SrcLine, sizeof(pInfo->SrcLine), " ; ouch %u != %u", nData, pInfo->CodeLen);
  1107. }
  1108.  
  1109. static void SwitchTo_87C800(void)
  1110. {
  1111.   Disassemble = Disassemble_87C800;
  1112. }
  1113.  
  1114. void deco87c800_init(void)
  1115. {
  1116.   CPU87C00 = AddCPU("87C00", SwitchTo_87C800);
  1117. }
  1118.