Subversion Repositories pentevo

Rev

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

  1. /* code6100.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator Intersil IM6100                                             */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <ctype.h>
  13. #include <string.h>
  14. #include <assert.h>
  15.  
  16. #include "nls.h"
  17. #include "strutil.h"
  18. #include "chunks.h"
  19. #include "asmdef.h"
  20. #include "asmsub.h"
  21. #include "asmpars.h"
  22. #include "asmallg.h"
  23. #include "asmitree.h"
  24. #include "literals.h"
  25. #include "codevars.h"
  26. #include "codepseudo.h"
  27. #include "headids.h"
  28. #include "errmsg.h"
  29. #include "onoff_common.h"
  30.  
  31. #include "code6100.h"
  32.  
  33. /*---------------------------------------------------------------------------*/
  34.  
  35. #define INSTINFO_COUNT 76
  36.  
  37. static CPUVar CPU6100;
  38. static CPUVar CPU6120;
  39.  
  40.  
  41. static Boolean BaseInst;
  42.  
  43. /* TODO: Not used anywhere? */
  44.  
  45. #if 0
  46. static PInstTable InstTableOP[3]; /* Operate Instruction */
  47. static const Word Inst6120 =  0x8000;
  48. static const Word PanelOnly = 0x4000;
  49. static const Word NormOnly =  0x2000;
  50. #endif
  51.  
  52. #define F_6120  0x0001
  53.  
  54. #define F_Norm  0x0040  /* Normal mode only */
  55. #define F_Panel 0x0080  /* Panel mode only */
  56. #define F_Combi 0x1000
  57. #define F_GP1   0x0800
  58. #define F_GP2   0x0400
  59. #define F_GP3   0x0200
  60. #define F_GP(n) (0x0800>>(n))
  61.  
  62. static LongInt IBVal;
  63.  
  64. static Boolean PanelMode;
  65. static unsigned int mregistered = 0;
  66.  
  67. static ASSUMERec ASSUME6100[] =
  68. {
  69.         {"IB", &IBVal, 0, 7, 0xff, NULL},
  70. };
  71.  
  72. static void DecodeMR(Word Index);
  73. static void DecodeOP(Word Index);
  74. static void DecodeIOT(Word Index);
  75. static void DecodeFix(Word Index);
  76. static void DecodeMEI(Word Index);
  77. static void DecodeRadix(Word Index);
  78. static void DecodeDC(Word Index);
  79. static void DecodeDS(Word Index);
  80. static void DecodeLTORG(Word Index);
  81.  
  82. typedef struct
  83. {
  84.         char NName[8];
  85.         InstProc Proc;
  86.         Word NCode[3];
  87.         Word Flags;
  88. } tInstInfo;
  89.  
  90. static tInstInfo *InstInfo;
  91.  
  92. /*---------------------------------------------------------------------------*/
  93.  
  94. static Boolean ChkValidInst(Word Index)
  95. {
  96.         Word Flags = InstInfo[Index].Flags;
  97.  
  98.         if (!(Flags & F_Combi) && !BaseInst)
  99.         {
  100.                 WrError(ErrNum_InvCombination);
  101.                 return False;
  102.         }
  103.  
  104.         if (Flags & F_6120)
  105.         {
  106.                 if (MomCPU < CPU6120)
  107.                 {
  108.                         WrError(ErrNum_InstructionNotSupported);
  109.                         return False;
  110.                 }
  111.         }
  112.  
  113.         if (Flags & F_Panel)
  114.         {
  115.                 if (!PanelMode)
  116.                 {
  117.                         WrStrErrorPos(ErrNum_NotInNormalMode, &OpPart);
  118.                 }
  119.         }
  120.         if (Flags & F_Norm)
  121.         {
  122.                 if (PanelMode)
  123.                 {
  124.                         WrStrErrorPos(ErrNum_NotInPanelMode, &OpPart);
  125.                 }
  126.         }
  127.  
  128.         return True;
  129. }
  130.  
  131. /*---------------------------------------------------------------------------*/
  132.  
  133. static void DecodeMR(Word Index)
  134. {
  135.         Boolean Indirect = False;
  136.         Boolean CurrPage = True;
  137.         Boolean Literal = False;
  138.         Word adrPos = 1;
  139.         Integer Adr;
  140.         Boolean OK;
  141.         tSymbolFlags Flags;
  142.         Word NCode = InstInfo[Index].NCode[0];
  143.  
  144.         if (!ChkValidInst(Index)) return;
  145.  
  146.         if (!ChkArgCnt(1, 2)) return;
  147.  
  148.         if (ArgCnt == 2)
  149.         {
  150.                 size_t i;
  151.  
  152.                 for (i = 0; i < strlen(ArgStr[1].str.p_str); i++)
  153.                 {
  154.                         switch (as_toupper(ArgStr[1].str.p_str[i]))
  155.                         {
  156.                                 case 'I':
  157.                                         Indirect = True;
  158.                                         break;
  159.                                 case 'Z':
  160.                                         CurrPage = False;
  161.                                         break;
  162.                                 case 'L':
  163.                                         Literal = True;
  164.                                         break;
  165.                                 default:
  166.                                         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  167.                                         return;
  168.                         }
  169.                 }
  170.                 if (!CurrPage && Literal)
  171.                 {
  172.                         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  173.                         return;
  174.                 }
  175.                 if (Literal && !Indirect && (NCode == 02000 || NCode == 03000))
  176.                 {
  177.                         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  178.                         return;
  179.                 }
  180.                 adrPos = 2;
  181.         }
  182.  
  183.         Adr = EvalStrIntExpressionWithFlags(&ArgStr[adrPos], Int16, &OK, &Flags);
  184.         if (!OK) return;
  185.  
  186.         if (Literal)
  187.         {
  188.                 Boolean Critical = mFirstPassUnknown(Flags) || mUsesForwards(Flags);
  189.                 tStrComp LComp;
  190.                 String LStr;
  191.  
  192.                 if (!mFirstPassUnknownOrQuestionable(Flags) && !ChkRange(Adr, -2048, 4095)) return;
  193.  
  194.                 StrCompMkTemp(&LComp, LStr, sizeof(LStr));
  195.  
  196.     literal_make(&LComp, NULL, Adr, eSymbolSize12Bit, Critical);
  197.                 Adr = EvalStrIntExpressionWithFlags(&LComp, UInt12, &OK, &Flags);
  198.                 if (!OK) return;
  199.  
  200.                 Adr |= EProgCounter() & 070000; /* Add current field to pass checks */
  201.         }
  202.  
  203.         if (!mFirstPassUnknownOrQuestionable(Flags))
  204.         {
  205.                 if (!ChkRange(Adr, 0, 32767)) return;
  206.  
  207.                 if ((NCode == 04000 || NCode == 05000) && !Indirect)
  208.                 {
  209.                         if (IBVal == ASSUME6100[0].NothingVal)
  210.                         {
  211.                                 if ((Adr & 070000) != (EProgCounter() & 070000))
  212.                                 {
  213.                                         /* Address not in current field */
  214.                                         WrError(ErrNum_TargInDiffField);
  215.                                         return;
  216.                                 }
  217.                         }
  218.                         else
  219.                         {
  220.                                 if ((Adr & 070000) != (IBVal << 12))
  221.                                 {
  222.                                         /* Address not in IB field */
  223.                                         WrError(ErrNum_InAccFieldErr);
  224.                                         return;
  225.                                 }
  226.                         }
  227.                 }
  228.                 else
  229.                 {
  230.                         if ((Adr & 070000) != (EProgCounter() & 070000))
  231.                         {
  232.                                 /* Address not in current field */
  233.                                 WrError(ErrNum_TargInDiffField);
  234.                                 return;
  235.                         }
  236.                 }
  237.  
  238.                 if (!CurrPage && (Adr & 07600))
  239.                 {
  240.                         /* Not in ZERO page */
  241.                         WrError(ErrNum_InAccPageErr);
  242.                         return;
  243.                 }
  244.                 if (!(Adr & 07600))
  245.                 {
  246.                         /* Zero page */
  247.                         CurrPage = False;
  248.                 }
  249.                 else if ((Adr & 07600) != (EProgCounter() & 07600))
  250.                 {
  251.                         /* Not in current page */
  252.                         WrError(ErrNum_TargOnDiffPage);
  253.                         return;
  254.                 }
  255.         }
  256.  
  257.         WAsmCode[0] = NCode | (Indirect ? 00400 : 0) | (CurrPage ? 00200 : 0) | (Adr & 00177);
  258.         CodeLen = 1;
  259. }
  260.  
  261. static Word CCode[3];
  262.  
  263. static void DecodeOP(Word Index)
  264. {
  265.         Word i;
  266.         Word Flags = InstInfo[Index].Flags;
  267.  
  268.         if (!ChkValidInst(Index)) return;
  269.  
  270.         if (BaseInst)
  271.         {
  272.                 for (i = 0; i < 3; i++) CCode[i] = 0;
  273.                 if (Flags & F_GP1) CCode[0] = InstInfo[Index].NCode[0];
  274.                 if (Flags & F_GP2) CCode[1] = InstInfo[Index].NCode[1];
  275.                 if (Flags & F_GP3) CCode[2] = InstInfo[Index].NCode[2];
  276.  
  277.                 BaseInst = False;
  278.                 for (i = 1; i <= ArgCnt; i++)
  279.                 {
  280.                         NLS_UpString(ArgStr[i].str.p_str);
  281.                         if (!LookupInstTable(InstTable, ArgStr[i].str.p_str))
  282.                         {
  283.                                 WrError(ErrNum_UnknownInstruction);
  284.                                 return;
  285.                         }
  286.                 }
  287.                 for (i = 0; i < 3; i++)
  288.                 {
  289.                         if (CCode[i])
  290.                         {
  291.                                 WAsmCode[0] = CCode[i];
  292.                                 CodeLen = 1;
  293.                                 return;
  294.                         }
  295.                 }
  296.                 WrError(ErrNum_InvCombination);
  297.                 return;
  298.         }
  299.         else
  300.         {
  301.                 Word NCode;
  302.                 Word tmp;
  303.  
  304.                 for (i = 0; i < 3; i++)
  305.                 {
  306.                         if (!CCode[i]) continue;
  307.  
  308.                         if (!(Flags & F_GP(i)))
  309.                         {
  310.                                 CCode[i] = 0;
  311.                                 continue;
  312.                         }
  313.  
  314.                         NCode = InstInfo[Index].NCode[i];
  315.  
  316.                         tmp = CCode[i] | NCode;
  317.       /* non-base instruction does not contribute any new bits (duplicate instruction?) */
  318.                         if (tmp == CCode[i] || tmp == NCode)
  319.                         {
  320.                                 CCode[i] = 0;
  321.                                 return;
  322.                         }
  323.  
  324.                         switch (i)
  325.                         {
  326.                         case 0:
  327.         /* Group 1: RAR, RAL, RTR, RTL, and BSW cannot be used in same instruction */
  328.                                 if ((CCode[i] & 00016) && (NCode & 00016))
  329.                                 {
  330.                                         CCode[0] = 0;
  331.                                         return;
  332.                                 }
  333.                                 break;
  334.                         case 1:
  335.         /* Group 2: SMA|SZA|SNL and SPA|SNA|SZL cannot be used in same instruction */
  336.                                 if ((CCode[i] & 00160) && (NCode & 00160) && ((CCode[i] & 00010) != (NCode & 00010)))
  337.                                 {
  338.                                         CCode[i] = 0;
  339.                                         return;
  340.                                 }
  341.                                 break;
  342.                         }
  343.  
  344.                         CCode[i] = tmp;
  345.                 }
  346.         }
  347. }
  348.  
  349. static void DecodeIOT(Word Index)
  350. {
  351.         Word dev;
  352.         Word opr;
  353.         Boolean OK;
  354.         Word NCode = InstInfo[Index].NCode[0];
  355.  
  356.         if (!ChkValidInst(Index)) return;
  357.  
  358.         if (!ChkArgCnt(2, 2)) return;
  359.  
  360.         dev = EvalStrIntExpression(&ArgStr[1], UInt6, &OK);
  361.         if (!OK) return;
  362.  
  363.         opr = EvalStrIntExpression(&ArgStr[2], UInt3, &OK);
  364.         if (!OK) return;
  365.  
  366.         WAsmCode[0] = NCode | (dev << 3) | opr;
  367.         CodeLen = 1;
  368. }
  369.  
  370. static void DecodeFix(Word Index)
  371. {
  372.         Word NCode = InstInfo[Index].NCode[0];
  373.  
  374.         if (!ChkValidInst(Index)) return;
  375.  
  376.         if (!ChkArgCnt(0, 0)) return;
  377.  
  378.         WAsmCode[0] = NCode;
  379.         CodeLen = 1;
  380. }
  381.  
  382. static void DecodeMEI(Word Index)
  383. {
  384.         int fieldPos = 1;
  385.         Word field;
  386.         Boolean OK;
  387.         Word NCode = InstInfo[Index].NCode[0];
  388.  
  389.         if (!ChkValidInst(Index)) return;
  390.  
  391.         if (!ChkArgCnt(1, 2)) return;
  392.  
  393.         if (ArgCnt == 2)
  394.         {
  395.                 if ((!as_strcasecmp(OpPart.str.p_str, "CDF") && !as_strcasecmp(ArgStr[1].str.p_str, "CIF")) ||
  396.                         (!as_strcasecmp(OpPart.str.p_str, "CIF") && !as_strcasecmp(ArgStr[1].str.p_str, "CDF")))
  397.                 {
  398.                         NCode = 06203;
  399.                         fieldPos = 2;
  400.                 }
  401.                 else
  402.                 {
  403.                         WrError(ErrNum_UnknownInstruction);
  404.                         return;
  405.                 }
  406.         }
  407.  
  408.         field = EvalStrIntExpression(&ArgStr[fieldPos], UInt3, &OK);
  409.         if (!OK) return;
  410.  
  411.         WAsmCode[0] = NCode | (field << 3);
  412.         CodeLen = 1;
  413. }
  414.  
  415. static void DecodeRadix(Word Base)
  416. {
  417.         if (!ChkArgCnt(0, 0)) return;
  418.  
  419.         RadixBase = Base;
  420. }
  421.  
  422. static Boolean DecodeConst(tStrComp *pStr)
  423. {
  424.         TempResult t;
  425.         tSymbolFlags Flags;
  426.         int c;
  427.         Boolean ret = True;
  428.  
  429.         as_tempres_ini(&t);
  430.         EvalStrExpression(pStr, &t);
  431.         Flags = t.Flags;
  432.         switch (t.Typ)
  433.         {
  434.                 case TempInt:
  435.                         if (!mFirstPassUnknownOrQuestionable(Flags))
  436.                                 if (!ChkRange(t.Contents.Int, -2048, 4095)) break;
  437.  
  438.                         WAsmCode[CodeLen++] = t.Contents.Int & 07777;
  439.                         break;
  440.                 case TempString:
  441.                         as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pStr);
  442.                         for (c = 0; c < (int)t.Contents.str.len; c++)
  443.                         {
  444.                                 WAsmCode[CodeLen++] = t.Contents.str.p_str[c] & 07777;
  445.                         }
  446.                         break;
  447.                 default:
  448.                         ret = False;
  449.         }
  450.         as_tempres_free(&t);
  451.  
  452.         return ret;
  453. }
  454.  
  455. static void DecodeDC(Word Index)
  456. {
  457.         Boolean result = True;
  458.         int i;
  459.  
  460.         UNUSED(Index);
  461.  
  462.         for (i = 1; i <= ArgCnt; i++)
  463.         {
  464.                 if (result)
  465.                 {
  466.                         result = DecodeConst(&ArgStr[i]);
  467.                 }
  468.         }
  469.  
  470.         if (!result) CodeLen = 0;
  471. }
  472.  
  473. static void DecodeDS(Word Index)
  474. {
  475.         Boolean OK;
  476.         tSymbolFlags Flags;
  477.         Word Val;
  478.  
  479.         UNUSED(Index);
  480.  
  481.         if (!ChkArgCnt(1, 1)) return;
  482.  
  483.         Val = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt12, &OK, &Flags);
  484.         if (!OK) return;
  485.         if (mFirstPassUnknown(Flags))
  486.         {
  487.                 WrStrErrorPos(ErrNum_FirstPassCalc, &ArgStr[1]);
  488.                 return;
  489.         }
  490.  
  491.         DontPrint = True;
  492.         CodeLen = Val;
  493.         BookKeeping();
  494. }
  495.  
  496. static LargeInt ltorg_12(const as_literal_t *p_lit, struct sStrComp *p_name)
  497. {
  498.   LargeInt ret;
  499.  
  500.   SetMaxCodeLen((CodeLen + 1) * 2);
  501.         WAsmCode[CodeLen] = p_lit->value & 07777;
  502.   ret = EProgCounter() + CodeLen;
  503.         EnterIntSymbol(p_name, ret, ActPC, False);
  504.         CodeLen++;
  505.   return ret;
  506. }
  507.  
  508. static void DecodeLTORG(Word Index)
  509. {
  510.  
  511.         UNUSED(Index);
  512.  
  513.         if (!ChkArgCnt(0, 0)) return;
  514.  
  515.   literals_dump(ltorg_12, eSymbolSize12Bit, MomSectionHandle, False);
  516. }
  517.  
  518. /* TODO: Not used anywhere? */
  519.  
  520. #if 0
  521. static Boolean DecodeDefault(tStrComp *OpStr)
  522. {
  523.         Boolean result;
  524.         int i;
  525.  
  526.         result = DecodeConst(OpStr);
  527.  
  528.         for (i = 1; i <= ArgCnt; i++)
  529.         {
  530.                 if (result)
  531.                 {
  532.                         result = DecodeConst(&ArgStr[i]);
  533.                 }
  534.         }
  535.  
  536.         if (!result) CodeLen = 0;
  537.  
  538.         return result;
  539. }
  540. #endif
  541.  
  542. /*---------------------------------------------------------------------------*/
  543.  
  544. static void AddInstInfo(const char *pName, InstProc Proc,
  545.                         Word Code0, Word Code1, Word Code2, Word Flags)
  546. {
  547.   assert(InstrZ < INSTINFO_COUNT);
  548.   InstInfo[InstrZ].NCode[0] = Code0;
  549.   InstInfo[InstrZ].NCode[1] = Code1;
  550.   InstInfo[InstrZ].NCode[2] = Code2;
  551.   InstInfo[InstrZ].Flags = Flags;
  552.   AddInstTable(InstTable, pName, InstrZ++, Proc);
  553. }
  554.  
  555. static void InitFields(void)
  556. {
  557.         InstTable = CreateInstTable(96);
  558.  
  559.   InstrZ = 0;
  560.   InstInfo = (tInstInfo*)malloc(INSTINFO_COUNT * sizeof(*InstInfo));
  561.  
  562.         /* Memory Reference Instruction */
  563.         AddInstInfo("AND", DecodeMR, 00000,     0,     0, 0);
  564.         AddInstInfo("TAD", DecodeMR, 01000,     0,     0, 0);
  565.         AddInstInfo("ISZ", DecodeMR, 02000,     0,     0, 0);
  566.         AddInstInfo("DCA", DecodeMR, 03000,     0,     0, 0);
  567.         AddInstInfo("JMS", DecodeMR, 04000,     0,     0, 0);
  568.         AddInstInfo("JMP", DecodeMR, 05000,     0,     0, 0);
  569.  
  570.         /* Operate Instruction (Group 1) */
  571.         AddInstInfo("NOP", DecodeOP, 07000, 07400, 07401, F_Combi | F_GP1 | F_GP2 | F_GP3);
  572.         AddInstInfo("IAC", DecodeOP, 07001,     0,     0, F_Combi | F_GP1);
  573.         AddInstInfo("RAL", DecodeOP, 07004,     0,     0, F_Combi | F_GP1);
  574.         AddInstInfo("RTL", DecodeOP, 07006,     0,     0, F_Combi | F_GP1);
  575.         AddInstInfo("R3L", DecodeOP, 07014,     0,     0, F_6120 | F_Combi | F_GP1);
  576.         AddInstInfo("RAR", DecodeOP, 07010,     0,     0, F_Combi | F_GP1);
  577.         AddInstInfo("RTR", DecodeOP, 07012,     0,     0, F_Combi | F_GP1);
  578.         AddInstInfo("BSW", DecodeOP, 07002,     0,     0, F_Combi | F_GP1);
  579.         AddInstInfo("CML", DecodeOP, 07020,     0,     0, F_Combi | F_GP1);
  580.         AddInstInfo("CMA", DecodeOP, 07040,     0,     0, F_Combi | F_GP1);
  581.         AddInstInfo("CIA", DecodeOP, 07041,     0,     0, F_Combi | F_GP1);
  582.         AddInstInfo("CLL", DecodeOP, 07100,     0,     0, F_Combi | F_GP1);
  583.         AddInstInfo("STL", DecodeOP, 07120,     0,     0, F_Combi | F_GP1);
  584.         AddInstInfo("CLA", DecodeOP, 07200, 07600, 07601, F_Combi | F_GP1 | F_GP2 | F_GP3);
  585.         AddInstInfo("GLK", DecodeOP, 07204,     0,     0, F_Combi | F_GP1);
  586.         AddInstInfo("GLT", DecodeOP, 07204,     0,     0, F_Combi | F_GP1);     /* Some documents say "GLT" */
  587.         AddInstInfo("STA", DecodeOP, 07240,     0,     0, F_Combi | F_GP1);
  588.  
  589.         /* Operate Instruction (Group 2) */
  590.         AddInstInfo("HLT", DecodeOP,     0, 07402,     0, F_Combi | F_GP2);
  591.         AddInstInfo("OSR", DecodeOP,     0, 07404,     0, F_Combi | F_GP2);
  592.         AddInstInfo("SKP", DecodeOP,     0, 07410,     0, F_Combi | F_GP2);
  593.         AddInstInfo("SNL", DecodeOP,     0, 07420,     0, F_Combi | F_GP2);
  594.         AddInstInfo("SZL", DecodeOP,     0, 07430,     0, F_Combi | F_GP2);
  595.         AddInstInfo("SZA", DecodeOP,     0, 07440,     0, F_Combi | F_GP2);
  596.         AddInstInfo("SNA", DecodeOP,     0, 07450,     0, F_Combi | F_GP2);
  597.         AddInstInfo("SMA", DecodeOP,     0, 07500,     0, F_Combi | F_GP2);
  598.         AddInstInfo("SPA", DecodeOP,     0, 07510,     0, F_Combi | F_GP2);
  599.         AddInstInfo("LAS", DecodeOP,     0, 07604,     0, F_Combi | F_GP2);
  600.  
  601.         /* Operate Instruction (Group 3) */
  602.         AddInstInfo("MQL", DecodeOP,     0,     0, 07421, F_Combi | F_GP3);
  603.         AddInstInfo("MQA", DecodeOP,     0,     0, 07501, F_Combi | F_GP3);
  604.         AddInstInfo("SWP", DecodeOP,     0,     0, 07521, F_Combi | F_GP3);
  605.         AddInstInfo("CAM", DecodeOP,     0,     0, 07621, F_Combi | F_GP3);
  606.         AddInstInfo("ACL", DecodeOP,     0,     0, 07701, F_Combi | F_GP3);
  607.  
  608.         /* I/O Transfer Instruction */
  609.         AddInstInfo("IOT" , DecodeIOT, 06000,     0,     0, 0);
  610.         AddInstInfo("SKON", DecodeFix, 06000,     0,     0, F_Norm);
  611.         AddInstInfo("ION" , DecodeFix, 06001,     0,     0, 0);
  612.         AddInstInfo("IOF" , DecodeFix, 06002,     0,     0, 0);
  613.         AddInstInfo("SRQ" , DecodeFix, 06003,     0,     0, F_Norm);
  614.         AddInstInfo("GTF" , DecodeFix, 06004,     0,     0, F_Norm);
  615.         AddInstInfo("RTF" , DecodeFix, 06005,     0,     0, 0);
  616.         AddInstInfo("SGT" , DecodeFix, 06006,     0,     0, 0);
  617.         AddInstInfo("CAF" , DecodeFix, 06007,     0,     0, 0);
  618.  
  619.         /* Stack Operation Instruction (6120 only) */
  620.         AddInstInfo("PPC1", DecodeFix, 06205,    0,     0, F_6120);
  621.         AddInstInfo("PPC2", DecodeFix, 06245,    0,     0, F_6120);
  622.         AddInstInfo("PAC1", DecodeFix, 06215,    0,     0, F_6120);
  623.         AddInstInfo("PAC2", DecodeFix, 06255,    0,     0, F_6120);
  624.         AddInstInfo("RTN1", DecodeFix, 06225,    0,     0, F_6120);
  625.         AddInstInfo("RTN2", DecodeFix, 06265,    0,     0, F_6120);
  626.         AddInstInfo("POP1", DecodeFix, 06235,    0,     0, F_6120);
  627.         AddInstInfo("POP2", DecodeFix, 06275,    0,     0, F_6120);
  628.         AddInstInfo("RSP1", DecodeFix, 06207,    0,     0, F_6120);
  629.         AddInstInfo("RSP2", DecodeFix, 06227,    0,     0, F_6120);
  630.         AddInstInfo("LSP1", DecodeFix, 06217,    0,     0, F_6120);
  631.         AddInstInfo("LSP2", DecodeFix, 06237,    0,     0, F_6120);
  632.  
  633.         /* Internal Control Instruction */
  634.         AddInstInfo("WSR", DecodeFix, 06246,    0,     0, F_6120);
  635.         AddInstInfo("GCF", DecodeFix, 06256,    0,     0, F_6120);
  636.  
  637.         /* Main Memory Control Instruction (6120 only) */
  638.         AddInstInfo("PR0", DecodeFix, 06206,    0,     0, F_6120 | F_Norm);
  639.         AddInstInfo("PR1", DecodeFix, 06216,    0,     0, F_6120 | F_Norm);
  640.         AddInstInfo("PR2", DecodeFix, 06226,    0,     0, F_6120 | F_Norm);
  641.         AddInstInfo("PR3", DecodeFix, 06236,    0,     0, F_6120 | F_Norm);
  642.  
  643.         /* Panel Mode Instruction */
  644.         AddInstInfo("PRS", DecodeFix, 06000,    0,     0, F_Panel);
  645.         AddInstInfo("PG0", DecodeFix, 06003,    0,     0, F_Panel);
  646.         AddInstInfo("PEX", DecodeFix, 06004,    0,     0, F_Panel);
  647.         AddInstInfo("CPD", DecodeFix, 06266,    0,     0, F_Panel);
  648.         AddInstInfo("SPD", DecodeFix, 06276,    0,     0, F_Panel);
  649.  
  650.         /* Memory Extension Instruction */
  651.         AddInstInfo("CDF", DecodeMEI, 06201,    0,     0, F_6120);
  652.         AddInstInfo("CIF", DecodeMEI, 06202,    0,     0, F_6120);
  653.         AddInstInfo("RDF", DecodeFix, 06214,    0,     0, F_6120);
  654.         AddInstInfo("RIF", DecodeFix, 06224,    0,     0, F_6120);
  655.         AddInstInfo("RIB", DecodeFix, 06234,    0,     0, F_6120);
  656.         AddInstInfo("RMF", DecodeFix, 06244,    0,     0, F_6120);
  657.  
  658.         /* Pseudo Instruction */
  659.         AddInstTable(InstTable, "DECIMAL", 10, DecodeRadix);
  660.         AddInstTable(InstTable, "OCTAL",    8, DecodeRadix);
  661.         AddInstTable(InstTable, "DC",       0, DecodeDC);
  662.         AddInstTable(InstTable, "DS",       0, DecodeDS);
  663.         AddInstTable(InstTable, "LTORG",    0, DecodeLTORG);
  664. }
  665.  
  666. static void DeinitFields(void)
  667. {
  668.   free(InstInfo);
  669.         DestroyInstTable(InstTable);
  670. }
  671.  
  672. /*---------------------------------------------------------------------------*/
  673.  
  674. static void MakeCode_6100(void)
  675. {
  676.         CodeLen = 0;
  677.         DontPrint = False;
  678.  
  679.         if (Memo("")) return;
  680.  
  681.         BaseInst = True;
  682.         if (!LookupInstTable(InstTable, OpPart.str.p_str))
  683.                 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  684. }
  685.  
  686. static void InitCode_6100(void)
  687. {
  688.         mregistered = 0;
  689.  
  690.         IBVal = 0;
  691. }
  692.  
  693. static Boolean IsDef_6100(void)
  694. {
  695.         return False;
  696. }
  697.  
  698. static void SwitchFrom_6100(void)
  699. {
  700.         DeinitFields();
  701. }
  702.  
  703. static void SwitchTo_6100(void)
  704. {
  705.         const TFamilyDescr *pDescr;
  706.  
  707.         TurnWords = True;
  708.         SetIntConstMode(eIntConstModeC);
  709.  
  710.         pDescr = FindFamilyByName("IM6100");
  711.         PCSymbol = ".";
  712.         HeaderID = pDescr->Id;
  713.         NOPCode = 0x7000;
  714.         DivideChars = " \t";
  715.         HasAttrs = False;
  716.  
  717.         ValidSegs = (1 << SegCode);
  718.         Grans[SegCode] = 2;
  719.         ListGrans[SegCode] = 2;
  720.         SegInits[SegCode] = 0x0000;
  721.         if (MomCPU >= CPU6120)
  722.                 SegLimits[SegCode] = 0x7fff;
  723.         else
  724.                 SegLimits[SegCode] = 0x0fff;
  725.  
  726.         if (!(mregistered & (1 << 0)))
  727.         {
  728.                 mregistered |= (1 << 0);
  729.                 SetFlag(&PanelMode, "INPANEL", False);
  730.         }
  731.         AddONOFF("PANEL", &PanelMode, "INPANEL", False);
  732.  
  733.         pASSUMERecs = ASSUME6100;
  734.         ASSUMERecCnt = as_array_size(ASSUME6100);
  735.  
  736.         MakeCode = MakeCode_6100;
  737.         IsDef = IsDef_6100;
  738.         SwitchFrom = SwitchFrom_6100;
  739.         InitFields();
  740. }
  741.  
  742. void code6100_init(void)
  743. {
  744.         CPU6100 = AddCPU("6100", SwitchTo_6100);
  745.         CPU6120 = AddCPU("6120", SwitchTo_6100);
  746.  
  747.         AddInitPassProc(InitCode_6100);
  748.  
  749.         AddCopyright("Intersil IM6100 Generator (C) 2022 Haruo Asano");
  750. }
  751.