Top secrets sources NedoPC pentevo

Rev

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

/* codenano.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
/*                                                                           */
/* AS-Portierung                                                             */
/*                                                                           */
/* Codegenerator HP Nanoprocessor                                            */
/*                                                                           */
/*****************************************************************************/

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

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

#include "codenano.h"

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

static CPUVar CPUNANO;

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

static void DecodeBit(Word Index)
{
        if (ChkArgCnt(1,1))
        {
                Word val;
                Boolean OK;

                val = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
                if (!OK) return;

                BAsmCode[0] = Index | val;
                CodeLen = 1;
        }
}

static void DecodeFixed(Word Index)
{
        if (ChkArgCnt(0,0))
        {
                BAsmCode[0] = Index;
                CodeLen = 1;
        }
}

static void DecodeImm(Word Index)
{
        if (ChkArgCnt(1,1))
        {
                Word val;
                Boolean OK;

                val = EvalStrIntExpression(&ArgStr[1], UInt8, &OK);
                if (!OK) return;

                BAsmCode[0] = Index;
                BAsmCode[1] = val;
                CodeLen = 2;
        }
}

static void DecodeReg(Word Index)
{
        if (ChkArgCnt(1,1))
        {
                Word reg;
                Boolean OK;

                reg = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
                if (!OK) return;

                BAsmCode[0] = Index | reg;
                CodeLen = 1;
        }
}

static void DecodeRegImm(Word Index)
{
        if (ChkArgCnt(2,2))
        {
                Word reg;
                Word val;
                Boolean OK;

                reg = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
                if (!OK) return;

                val = EvalStrIntExpression(&ArgStr[2], UInt8, &OK);
                if (!OK) return;

                BAsmCode[0] = Index | reg;
                BAsmCode[1] = val;
                CodeLen = 2;
        }
}

static void DecodeDev(Word Index)
{
        if (ChkArgCnt(1,1))
        {
                Word dev;
                Boolean OK;

                dev = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
                if (!OK) return;
                if (Index == 0x50 && dev == 15) /* OTA 15 not allowed */
                {
                        WrError(ErrNum_OverRange);
                        return;
                }

                BAsmCode[0] = Index | dev;
                CodeLen = 1;
        }
}

static void DecodeDevImm(Word Index)
{
        if (ChkArgCnt(2,2))
        {
                Word dev;
                Word val;
                Boolean OK;

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

                val = EvalStrIntExpression(&ArgStr[2], UInt8, &OK);
                if (!OK) return;

                if (dev == 15)  /* OTR 15,xx not allowed */
                {
                        WrError(ErrNum_OverRange);
                        return;
                }

                BAsmCode[0] = Index | dev;
                BAsmCode[1] = val;
                CodeLen = 2;
        }
}

static void DecodeDirect(Word Index)
{
        if (ChkArgCnt(1,1))
        {
                Word val;
                Boolean OK;

                val = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
                if (!OK) return;
                if (val == 7)
                {
                        WrError(ErrNum_OverRange);
                        return;
                }

                BAsmCode[0] = Index | val;
                CodeLen = 1;
        }
}

static void DecodeAddress(Word Index)
{
        if (ChkArgCnt(1,1))
        {
                Word val;
                Boolean OK;

                val = EvalStrIntExpression(&ArgStr[1], UInt11, &OK);
                if (!OK) return;

                BAsmCode[0] = Index | (val >> 8);
                BAsmCode[1] = val & 0xff;
                CodeLen = 2;
        }
}


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

static void AddBit(const char *NName, Word NCode)
{
        AddInstTable(InstTable, NName, NCode, DecodeBit);
}

static void AddFixed(const char *NName, Word NCode)
{
        AddInstTable(InstTable, NName, NCode, DecodeFixed);
}

static void AddImm(const char *NName, Word NCode)
{
        AddInstTable(InstTable, NName, NCode, DecodeImm);
}

static void AddReg(const char *NName, Word NCode)
{
        AddInstTable(InstTable, NName, NCode, DecodeReg);
}

static void AddRegImm(const char *NName, Word NCode)
{
        AddInstTable(InstTable, NName, NCode, DecodeRegImm);
}

static void AddDev(const char *NName, Word NCode)
{
        AddInstTable(InstTable, NName, NCode, DecodeDev);
}

static void AddDevImm(const char *NName, Word NCode)
{
        AddInstTable(InstTable, NName, NCode, DecodeDevImm);
}

static void AddDirect(const char *NName, Word NCode)
{
        AddInstTable(InstTable, NName, NCode, DecodeDirect);
}

static void AddAddress(const char *NName, Word NCode)
{
        AddInstTable(InstTable, NName, NCode, DecodeAddress);
}

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

        /* A. Accumulator Group */
        AddBit("SBS", 0x10);
        AddBit("SBZ", 0x30);
        AddBit("SBN", 0x20);
        AddBit("CBN", 0xA0);
        AddFixed("INB", 0x00);
        AddFixed("IND", 0x02);
        AddFixed("DEB", 0x01);
        AddFixed("DED", 0x03);
        AddFixed("CLA", 0x04);
        AddFixed("CMA", 0x05);
        AddFixed("LSA", 0x07);
        AddFixed("RSA", 0x06);
        AddFixed("SES", 0x1f);
        AddFixed("SEZ", 0x3f);
        AddImm("LDR", 0xcf);

        /* B. Register Transfer Group */
        AddReg("LDA", 0x60);
        AddReg("STA", 0x70);
        AddReg("LDI", 0xe0);
        AddReg("STI", 0xf0);
        AddRegImm("STR", 0xd0);

        /* C. Extend Register Group */
        AddFixed("STE", 0xb4);
        AddFixed("CLE", 0xb5);

        /* D. Interrupt Group */
        AddFixed("DSI", 0xaf);
        AddFixed("ENI", 0x2f);

        /* E. Comparator Group */
        AddFixed("SLT", 0x09);
        AddFixed("SEQ", 0x0a);
        AddFixed("SAZ", 0x0b);
        AddFixed("SLE", 0x0c);
        AddFixed("SGE", 0x0d);
        AddFixed("SNE", 0x0e);
        AddFixed("SAN", 0x0f);
        AddFixed("SGT", 0x08);

        /* F. Input/Output Group */
        AddDev("INA", 0x40);
        AddDev("OTA", 0x50);
        AddDevImm("OTR", 0xc0);
        AddDirect("STC", 0x28);
        AddDirect("CLC", 0xa8);
        AddDirect("SFS", 0x18);
        AddDirect("SFZ", 0x38);
        AddFixed("RTI", 0x90);
        AddFixed("RTE", 0xb1);
        AddFixed("NOP", 0x5f);
        AddReg("JAI", 0x90);
        AddReg("JAS", 0x98);

        /* G. Program Control Group */
        AddAddress("JMP", 0x80);
        AddAddress("JSB", 0x88);
        AddFixed("RTS", 0xb8);
        AddFixed("RSE", 0xb9);
}

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

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

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

        if (Memo("")) return;

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

static Boolean IsDef_NANO(void)
{
        return False;
}

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

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

        TurnWords = False;
        SetIntConstMode(eIntConstModeC);

        pDescr = FindFamilyByName("NANO");
        PCSymbol = "*";
        HeaderID = pDescr->Id;
        NOPCode = 0x5f;
        DivideChars = ",";
        HasAttrs = False;

        ValidSegs = (1 << SegCode);
        Grans[SegCode] = 1;
        ListGrans[SegCode] = 1;
        SegInits[SegCode] = 0x0000;
        SegLimits[SegCode] = 0x07ff;

        MakeCode = MakeCode_NANO;
        IsDef = IsDef_NANO;
        SwitchFrom = SwitchFrom_NANO;
        InitFields();
}

void codenano_init(void)
{
        CPUNANO = AddCPU("NANO", SwitchTo_NANO);

        AddCopyright("HP Nanoprocessor Generator (C) 2022 Haruo Asano");
}