Subversion Repositories pentevo

Rev

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

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