Top secrets sources NedoPC pentevo

Rev

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

/* code6100.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
/*                                                                           */
/* AS-Portierung                                                             */
/*                                                                           */
/* Codegenerator Intersil IM6100                                             */
/*                                                                           */
/*****************************************************************************/

#include "stdinc.h"
#include <ctype.h>
#include <string.h>
#include <assert.h>

#include "nls.h"
#include "strutil.h"
#include "chunks.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmallg.h"
#include "asmitree.h"
#include "literals.h"
#include "codevars.h"
#include "codepseudo.h"
#include "headids.h"
#include "errmsg.h"
#include "onoff_common.h"

#include "code6100.h"

/*---------------------------------------------------------------------------*/

#define INSTINFO_COUNT 76

static CPUVar CPU6100;
static CPUVar CPU6120;


static Boolean BaseInst;

/* TODO: Not used anywhere? */

#if 0
static PInstTable InstTableOP[3]; /* Operate Instruction */
static const Word Inst6120 =  0x8000;
static const Word PanelOnly = 0x4000;
static const Word NormOnly =  0x2000;
#endif

#define F_6120  0x0001

#define F_Norm  0x0040  /* Normal mode only */
#define F_Panel 0x0080  /* Panel mode only */
#define F_Combi 0x1000
#define F_GP1   0x0800
#define F_GP2   0x0400
#define F_GP3   0x0200
#define F_GP(n) (0x0800>>(n))

static LongInt IBVal;

static Boolean PanelMode;
static unsigned int mregistered = 0;

static ASSUMERec ASSUME6100[] =
{
        {"IB", &IBVal, 0, 7, 0xff, NULL},
};

static void DecodeMR(Word Index);
static void DecodeOP(Word Index);
static void DecodeIOT(Word Index);
static void DecodeFix(Word Index);
static void DecodeMEI(Word Index);
static void DecodeRadix(Word Index);
static void DecodeDC(Word Index);
static void DecodeDS(Word Index);
static void DecodeLTORG(Word Index);

typedef struct
{
        char NName[8];
        InstProc Proc;
        Word NCode[3];
        Word Flags;
} tInstInfo;

static tInstInfo *InstInfo;

/*---------------------------------------------------------------------------*/

static Boolean ChkValidInst(Word Index)
{
        Word Flags = InstInfo[Index].Flags;

        if (!(Flags & F_Combi) && !BaseInst)
        {
                WrError(ErrNum_InvCombination);
                return False;
        }

        if (Flags & F_6120)
        {
                if (MomCPU < CPU6120)
                {
                        WrError(ErrNum_InstructionNotSupported);
                        return False;
                }
        }

        if (Flags & F_Panel)
        {
                if (!PanelMode)
                {
                        WrStrErrorPos(ErrNum_NotInNormalMode, &OpPart);
                }
        }
        if (Flags & F_Norm)
        {
                if (PanelMode)
                {
                        WrStrErrorPos(ErrNum_NotInPanelMode, &OpPart);
                }
        }

        return True;
}

/*---------------------------------------------------------------------------*/

static void DecodeMR(Word Index)
{
        Boolean Indirect = False;
        Boolean CurrPage = True;
        Boolean Literal = False;
        Word adrPos = 1;
        Integer Adr;
        Boolean OK;
        tSymbolFlags Flags;
        Word NCode = InstInfo[Index].NCode[0];

        if (!ChkValidInst(Index)) return;

        if (!ChkArgCnt(1, 2)) return;

        if (ArgCnt == 2)
        {
                size_t i;

                for (i = 0; i < strlen(ArgStr[1].str.p_str); i++)
                {
                        switch (as_toupper(ArgStr[1].str.p_str[i]))
                        {
                                case 'I':
                                        Indirect = True;
                                        break;
                                case 'Z':
                                        CurrPage = False;
                                        break;
                                case 'L':
                                        Literal = True;
                                        break;
                                default:
                                        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
                                        return;
                        }
                }
                if (!CurrPage && Literal)
                {
                        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
                        return;
                }
                if (Literal && !Indirect && (NCode == 02000 || NCode == 03000))
                {
                        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
                        return;
                }
                adrPos = 2;
        }

        Adr = EvalStrIntExpressionWithFlags(&ArgStr[adrPos], Int16, &OK, &Flags);
        if (!OK) return;

        if (Literal)
        {
                Boolean Critical = mFirstPassUnknown(Flags) || mUsesForwards(Flags);
                tStrComp LComp;
                String LStr;

                if (!mFirstPassUnknownOrQuestionable(Flags) && !ChkRange(Adr, -2048, 4095)) return;

                StrCompMkTemp(&LComp, LStr, sizeof(LStr));

    literal_make(&LComp, NULL, Adr, eSymbolSize12Bit, Critical);
                Adr = EvalStrIntExpressionWithFlags(&LComp, UInt12, &OK, &Flags);
                if (!OK) return;

                Adr |= EProgCounter() & 070000; /* Add current field to pass checks */
        }

        if (!mFirstPassUnknownOrQuestionable(Flags))
        {
                if (!ChkRange(Adr, 0, 32767)) return;

                if ((NCode == 04000 || NCode == 05000) && !Indirect)
                {
                        if (IBVal == ASSUME6100[0].NothingVal)
                        {
                                if ((Adr & 070000) != (EProgCounter() & 070000))
                                {
                                        /* Address not in current field */
                                        WrError(ErrNum_TargInDiffField);
                                        return;
                                }
                        }
                        else
                        {
                                if ((Adr & 070000) != (IBVal << 12))
                                {
                                        /* Address not in IB field */
                                        WrError(ErrNum_InAccFieldErr);
                                        return;
                                }
                        }
                }
                else
                {
                        if ((Adr & 070000) != (EProgCounter() & 070000))
                        {
                                /* Address not in current field */
                                WrError(ErrNum_TargInDiffField);
                                return;
                        }
                }

                if (!CurrPage && (Adr & 07600))
                {
                        /* Not in ZERO page */
                        WrError(ErrNum_InAccPageErr);
                        return;
                }
                if (!(Adr & 07600))
                {
                        /* Zero page */
                        CurrPage = False;
                }
                else if ((Adr & 07600) != (EProgCounter() & 07600))
                {
                        /* Not in current page */
                        WrError(ErrNum_TargOnDiffPage);
                        return;
                }
        }

        WAsmCode[0] = NCode | (Indirect ? 00400 : 0) | (CurrPage ? 00200 : 0) | (Adr & 00177);
        CodeLen = 1;
}

static Word CCode[3];

static void DecodeOP(Word Index)
{
        Word i;
        Word Flags = InstInfo[Index].Flags;

        if (!ChkValidInst(Index)) return;

        if (BaseInst)
        {
                for (i = 0; i < 3; i++) CCode[i] = 0;
                if (Flags & F_GP1) CCode[0] = InstInfo[Index].NCode[0];
                if (Flags & F_GP2) CCode[1] = InstInfo[Index].NCode[1];
                if (Flags & F_GP3) CCode[2] = InstInfo[Index].NCode[2];

                BaseInst = False;
                for (i = 1; i <= ArgCnt; i++)
                {
                        NLS_UpString(ArgStr[i].str.p_str);
                        if (!LookupInstTable(InstTable, ArgStr[i].str.p_str))
                        {
                                WrError(ErrNum_UnknownInstruction);
                                return;
                        }
                }
                for (i = 0; i < 3; i++)
                {
                        if (CCode[i])
                        {
                                WAsmCode[0] = CCode[i];
                                CodeLen = 1;
                                return;
                        }
                }
                WrError(ErrNum_InvCombination);
                return;
        }
        else
        {
                Word NCode;
                Word tmp;

                for (i = 0; i < 3; i++)
                {
                        if (!CCode[i]) continue;

                        if (!(Flags & F_GP(i)))
                        {
                                CCode[i] = 0;
                                continue;
                        }

                        NCode = InstInfo[Index].NCode[i];

                        tmp = CCode[i] | NCode;
      /* non-base instruction does not contribute any new bits (duplicate instruction?) */
                        if (tmp == CCode[i] || tmp == NCode)
                        {
                                CCode[i] = 0;
                                return;
                        }

                        switch (i)
                        {
                        case 0:
        /* Group 1: RAR, RAL, RTR, RTL, and BSW cannot be used in same instruction */
                                if ((CCode[i] & 00016) && (NCode & 00016))
                                {
                                        CCode[0] = 0;
                                        return;
                                }
                                break;
                        case 1:
        /* Group 2: SMA|SZA|SNL and SPA|SNA|SZL cannot be used in same instruction */
                                if ((CCode[i] & 00160) && (NCode & 00160) && ((CCode[i] & 00010) != (NCode & 00010)))
                                {
                                        CCode[i] = 0;
                                        return;
                                }
                                break;
                        }

                        CCode[i] = tmp;
                }
        }
}

static void DecodeIOT(Word Index)
{
        Word dev;
        Word opr;
        Boolean OK;
        Word NCode = InstInfo[Index].NCode[0];

        if (!ChkValidInst(Index)) return;

        if (!ChkArgCnt(2, 2)) return;

        dev = EvalStrIntExpression(&ArgStr[1], UInt6, &OK);
        if (!OK) return;

        opr = EvalStrIntExpression(&ArgStr[2], UInt3, &OK);
        if (!OK) return;

        WAsmCode[0] = NCode | (dev << 3) | opr;
        CodeLen = 1;
}

static void DecodeFix(Word Index)
{
        Word NCode = InstInfo[Index].NCode[0];

        if (!ChkValidInst(Index)) return;

        if (!ChkArgCnt(0, 0)) return;

        WAsmCode[0] = NCode;
        CodeLen = 1;
}

static void DecodeMEI(Word Index)
{
        int fieldPos = 1;
        Word field;
        Boolean OK;
        Word NCode = InstInfo[Index].NCode[0];

        if (!ChkValidInst(Index)) return;

        if (!ChkArgCnt(1, 2)) return;

        if (ArgCnt == 2)
        {
                if ((!as_strcasecmp(OpPart.str.p_str, "CDF") && !as_strcasecmp(ArgStr[1].str.p_str, "CIF")) ||
                        (!as_strcasecmp(OpPart.str.p_str, "CIF") && !as_strcasecmp(ArgStr[1].str.p_str, "CDF")))
                {
                        NCode = 06203;
                        fieldPos = 2;
                }
                else
                {
                        WrError(ErrNum_UnknownInstruction);
                        return;
                }
        }

        field = EvalStrIntExpression(&ArgStr[fieldPos], UInt3, &OK);
        if (!OK) return;

        WAsmCode[0] = NCode | (field << 3);
        CodeLen = 1;
}

static void DecodeRadix(Word Base)
{
        if (!ChkArgCnt(0, 0)) return;

        RadixBase = Base;
}

static Boolean DecodeConst(tStrComp *pStr)
{
        TempResult t;
        tSymbolFlags Flags;
        int c;
        Boolean ret = True;

        as_tempres_ini(&t);
        EvalStrExpression(pStr, &t);
        Flags = t.Flags;
        switch (t.Typ)
        {
                case TempInt:
                        if (!mFirstPassUnknownOrQuestionable(Flags))
                                if (!ChkRange(t.Contents.Int, -2048, 4095)) break;

                        WAsmCode[CodeLen++] = t.Contents.Int & 07777;
                        break;
                case TempString:
                        as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pStr);
                        for (c = 0; c < (int)t.Contents.str.len; c++)
                        {
                                WAsmCode[CodeLen++] = t.Contents.str.p_str[c] & 07777;
                        }
                        break;
                default:
                        ret = False;
        }
        as_tempres_free(&t);

        return ret;
}

static void DecodeDC(Word Index)
{
        Boolean result = True;
        int i;

        UNUSED(Index);

        for (i = 1; i <= ArgCnt; i++)
        {
                if (result)
                {
                        result = DecodeConst(&ArgStr[i]);
                }
        }

        if (!result) CodeLen = 0;
}

static void DecodeDS(Word Index)
{
        Boolean OK;
        tSymbolFlags Flags;
        Word Val;

        UNUSED(Index);

        if (!ChkArgCnt(1, 1)) return;

        Val = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt12, &OK, &Flags);
        if (!OK) return;
        if (mFirstPassUnknown(Flags))
        {
                WrStrErrorPos(ErrNum_FirstPassCalc, &ArgStr[1]);
                return;
        }

        DontPrint = True;
        CodeLen = Val;
        BookKeeping();
}

static LargeInt ltorg_12(const as_literal_t *p_lit, struct sStrComp *p_name)
{
  LargeInt ret;

  SetMaxCodeLen((CodeLen + 1) * 2);
        WAsmCode[CodeLen] = p_lit->value & 07777;
  ret = EProgCounter() + CodeLen;
        EnterIntSymbol(p_name, ret, ActPC, False);
        CodeLen++;
  return ret;
}

static void DecodeLTORG(Word Index)
{

        UNUSED(Index);

        if (!ChkArgCnt(0, 0)) return;

  literals_dump(ltorg_12, eSymbolSize12Bit, MomSectionHandle, False);
}

/* TODO: Not used anywhere? */

#if 0
static Boolean DecodeDefault(tStrComp *OpStr)
{
        Boolean result;
        int i;

        result = DecodeConst(OpStr);

        for (i = 1; i <= ArgCnt; i++)
        {
                if (result)
                {
                        result = DecodeConst(&ArgStr[i]);
                }
        }

        if (!result) CodeLen = 0;

        return result;
}
#endif

/*---------------------------------------------------------------------------*/

static void AddInstInfo(const char *pName, InstProc Proc,
                        Word Code0, Word Code1, Word Code2, Word Flags)
{
  assert(InstrZ < INSTINFO_COUNT);
  InstInfo[InstrZ].NCode[0] = Code0;
  InstInfo[InstrZ].NCode[1] = Code1;
  InstInfo[InstrZ].NCode[2] = Code2;
  InstInfo[InstrZ].Flags = Flags;
  AddInstTable(InstTable, pName, InstrZ++, Proc);
}

static void InitFields(void)
{
        InstTable = CreateInstTable(96);

  InstrZ = 0;
  InstInfo = (tInstInfo*)malloc(INSTINFO_COUNT * sizeof(*InstInfo));

        /* Memory Reference Instruction */
        AddInstInfo("AND", DecodeMR, 00000,     0,     0, 0);
        AddInstInfo("TAD", DecodeMR, 01000,     0,     0, 0);
        AddInstInfo("ISZ", DecodeMR, 02000,     0,     0, 0);
        AddInstInfo("DCA", DecodeMR, 03000,     0,     0, 0);
        AddInstInfo("JMS", DecodeMR, 04000,     0,     0, 0);
        AddInstInfo("JMP", DecodeMR, 05000,     0,     0, 0);

        /* Operate Instruction (Group 1) */
        AddInstInfo("NOP", DecodeOP, 07000, 07400, 07401, F_Combi | F_GP1 | F_GP2 | F_GP3);
        AddInstInfo("IAC", DecodeOP, 07001,     0,     0, F_Combi | F_GP1);
        AddInstInfo("RAL", DecodeOP, 07004,     0,     0, F_Combi | F_GP1);
        AddInstInfo("RTL", DecodeOP, 07006,     0,     0, F_Combi | F_GP1);
        AddInstInfo("R3L", DecodeOP, 07014,     0,     0, F_6120 | F_Combi | F_GP1);
        AddInstInfo("RAR", DecodeOP, 07010,     0,     0, F_Combi | F_GP1);
        AddInstInfo("RTR", DecodeOP, 07012,     0,     0, F_Combi | F_GP1);
        AddInstInfo("BSW", DecodeOP, 07002,     0,     0, F_Combi | F_GP1);
        AddInstInfo("CML", DecodeOP, 07020,     0,     0, F_Combi | F_GP1);
        AddInstInfo("CMA", DecodeOP, 07040,     0,     0, F_Combi | F_GP1);
        AddInstInfo("CIA", DecodeOP, 07041,     0,     0, F_Combi | F_GP1);
        AddInstInfo("CLL", DecodeOP, 07100,     0,     0, F_Combi | F_GP1);
        AddInstInfo("STL", DecodeOP, 07120,     0,     0, F_Combi | F_GP1);
        AddInstInfo("CLA", DecodeOP, 07200, 07600, 07601, F_Combi | F_GP1 | F_GP2 | F_GP3);
        AddInstInfo("GLK", DecodeOP, 07204,     0,     0, F_Combi | F_GP1);
        AddInstInfo("GLT", DecodeOP, 07204,     0,     0, F_Combi | F_GP1);     /* Some documents say "GLT" */
        AddInstInfo("STA", DecodeOP, 07240,     0,     0, F_Combi | F_GP1);

        /* Operate Instruction (Group 2) */
        AddInstInfo("HLT", DecodeOP,     0, 07402,     0, F_Combi | F_GP2);
        AddInstInfo("OSR", DecodeOP,     0, 07404,     0, F_Combi | F_GP2);
        AddInstInfo("SKP", DecodeOP,     0, 07410,     0, F_Combi | F_GP2);
        AddInstInfo("SNL", DecodeOP,     0, 07420,     0, F_Combi | F_GP2);
        AddInstInfo("SZL", DecodeOP,     0, 07430,     0, F_Combi | F_GP2);
        AddInstInfo("SZA", DecodeOP,     0, 07440,     0, F_Combi | F_GP2);
        AddInstInfo("SNA", DecodeOP,     0, 07450,     0, F_Combi | F_GP2);
        AddInstInfo("SMA", DecodeOP,     0, 07500,     0, F_Combi | F_GP2);
        AddInstInfo("SPA", DecodeOP,     0, 07510,     0, F_Combi | F_GP2);
        AddInstInfo("LAS", DecodeOP,     0, 07604,     0, F_Combi | F_GP2);

        /* Operate Instruction (Group 3) */
        AddInstInfo("MQL", DecodeOP,     0,     0, 07421, F_Combi | F_GP3);
        AddInstInfo("MQA", DecodeOP,     0,     0, 07501, F_Combi | F_GP3);
        AddInstInfo("SWP", DecodeOP,     0,     0, 07521, F_Combi | F_GP3);
        AddInstInfo("CAM", DecodeOP,     0,     0, 07621, F_Combi | F_GP3);
        AddInstInfo("ACL", DecodeOP,     0,     0, 07701, F_Combi | F_GP3);

        /* I/O Transfer Instruction */
        AddInstInfo("IOT" , DecodeIOT, 06000,     0,     0, 0);
        AddInstInfo("SKON", DecodeFix, 06000,     0,     0, F_Norm);
        AddInstInfo("ION" , DecodeFix, 06001,     0,     0, 0);
        AddInstInfo("IOF" , DecodeFix, 06002,     0,     0, 0);
        AddInstInfo("SRQ" , DecodeFix, 06003,     0,     0, F_Norm);
        AddInstInfo("GTF" , DecodeFix, 06004,     0,     0, F_Norm);
        AddInstInfo("RTF" , DecodeFix, 06005,     0,     0, 0);
        AddInstInfo("SGT" , DecodeFix, 06006,     0,     0, 0);
        AddInstInfo("CAF" , DecodeFix, 06007,     0,     0, 0);

        /* Stack Operation Instruction (6120 only) */
        AddInstInfo("PPC1", DecodeFix, 06205,    0,     0, F_6120);
        AddInstInfo("PPC2", DecodeFix, 06245,    0,     0, F_6120);
        AddInstInfo("PAC1", DecodeFix, 06215,    0,     0, F_6120);
        AddInstInfo("PAC2", DecodeFix, 06255,    0,     0, F_6120);
        AddInstInfo("RTN1", DecodeFix, 06225,    0,     0, F_6120);
        AddInstInfo("RTN2", DecodeFix, 06265,    0,     0, F_6120);
        AddInstInfo("POP1", DecodeFix, 06235,    0,     0, F_6120);
        AddInstInfo("POP2", DecodeFix, 06275,    0,     0, F_6120);
        AddInstInfo("RSP1", DecodeFix, 06207,    0,     0, F_6120);
        AddInstInfo("RSP2", DecodeFix, 06227,    0,     0, F_6120);
        AddInstInfo("LSP1", DecodeFix, 06217,    0,     0, F_6120);
        AddInstInfo("LSP2", DecodeFix, 06237,    0,     0, F_6120);

        /* Internal Control Instruction */
        AddInstInfo("WSR", DecodeFix, 06246,    0,     0, F_6120);
        AddInstInfo("GCF", DecodeFix, 06256,    0,     0, F_6120);

        /* Main Memory Control Instruction (6120 only) */
        AddInstInfo("PR0", DecodeFix, 06206,    0,     0, F_6120 | F_Norm);
        AddInstInfo("PR1", DecodeFix, 06216,    0,     0, F_6120 | F_Norm);
        AddInstInfo("PR2", DecodeFix, 06226,    0,     0, F_6120 | F_Norm);
        AddInstInfo("PR3", DecodeFix, 06236,    0,     0, F_6120 | F_Norm);

        /* Panel Mode Instruction */
        AddInstInfo("PRS", DecodeFix, 06000,    0,     0, F_Panel);
        AddInstInfo("PG0", DecodeFix, 06003,    0,     0, F_Panel);
        AddInstInfo("PEX", DecodeFix, 06004,    0,     0, F_Panel);
        AddInstInfo("CPD", DecodeFix, 06266,    0,     0, F_Panel);
        AddInstInfo("SPD", DecodeFix, 06276,    0,     0, F_Panel);

        /* Memory Extension Instruction */
        AddInstInfo("CDF", DecodeMEI, 06201,    0,     0, F_6120);
        AddInstInfo("CIF", DecodeMEI, 06202,    0,     0, F_6120);
        AddInstInfo("RDF", DecodeFix, 06214,    0,     0, F_6120);
        AddInstInfo("RIF", DecodeFix, 06224,    0,     0, F_6120);
        AddInstInfo("RIB", DecodeFix, 06234,    0,     0, F_6120);
        AddInstInfo("RMF", DecodeFix, 06244,    0,     0, F_6120);

        /* Pseudo Instruction */
        AddInstTable(InstTable, "DECIMAL", 10, DecodeRadix);
        AddInstTable(InstTable, "OCTAL",    8, DecodeRadix);
        AddInstTable(InstTable, "DC",       0, DecodeDC);
        AddInstTable(InstTable, "DS",       0, DecodeDS);
        AddInstTable(InstTable, "LTORG",    0, DecodeLTORG);
}

static void DeinitFields(void)
{
  free(InstInfo);
        DestroyInstTable(InstTable);
}

/*---------------------------------------------------------------------------*/

static void MakeCode_6100(void)
{
        CodeLen = 0;
        DontPrint = False;

        if (Memo("")) return;

        BaseInst = True;
        if (!LookupInstTable(InstTable, OpPart.str.p_str))
                WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
}

static void InitCode_6100(void)
{
        mregistered = 0;

        IBVal = 0;
}

static Boolean IsDef_6100(void)
{
        return False;
}

static void SwitchFrom_6100(void)
{
        DeinitFields();
}

static void SwitchTo_6100(void)
{
        const TFamilyDescr *pDescr;

        TurnWords = True;
        SetIntConstMode(eIntConstModeC);

        pDescr = FindFamilyByName("IM6100");
        PCSymbol = ".";
        HeaderID = pDescr->Id;
        NOPCode = 0x7000;
        DivideChars = " \t";
        HasAttrs = False;

        ValidSegs = (1 << SegCode);
        Grans[SegCode] = 2;
        ListGrans[SegCode] = 2;
        SegInits[SegCode] = 0x0000;
        if (MomCPU >= CPU6120)
                SegLimits[SegCode] = 0x7fff;
        else
                SegLimits[SegCode] = 0x0fff;

        if (!(mregistered & (1 << 0)))
        {
                mregistered |= (1 << 0);
                SetFlag(&PanelMode, "INPANEL", False);
        }
        AddONOFF("PANEL", &PanelMode, "INPANEL", False);

        pASSUMERecs = ASSUME6100;
        ASSUMERecCnt = as_array_size(ASSUME6100);

        MakeCode = MakeCode_6100;
        IsDef = IsDef_6100;
        SwitchFrom = SwitchFrom_6100;
        InitFields();
}

void code6100_init(void)
{
        CPU6100 = AddCPU("6100", SwitchTo_6100);
        CPU6120 = AddCPU("6120", SwitchTo_6100);

        AddInitPassProc(InitCode_6100);

        AddCopyright("Intersil IM6100 Generator (C) 2022 Haruo Asano");
}