⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 outco68.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 5 页
字号:
                == 4 ? 0x800 : 0));
            ins->ofs[ins->rescount] = val;
            ins->resobyte[ins->rescount] = data == ins->oper1 ? 4 : 20;
            ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
            PUTWORD(p, val >> 16);
            PUTWORD(p, val &0xffff);
        }
        else
        {
            DIAG("putbased - Offset too large for 68000");
        }
    }
    else
    {
        if (val <  - 0x80 || val > 0x7f)
        {
            if (prm_68020)
            {
                if (val <  - 0x8000 || val > 0x7fff)
                {
                    PUTWORD(p, 0x130 + (data->sreg << 12) + (data->mode ==
                        am_baseindxdata ? 0 : 0x8000) + (data->scale << 9) + 
                        (data->sz == 4 ? 0x800 : 0));
                    PUTWORD(p, val >> 16);
                    PUTWORD(p, val &0xffff);
                }
                else
                {
                    PUTWORD(p, 0x120 + (data->sreg << 12) + (data->mode ==
                        am_baseindxdata ? 0 : 0x8000) + (data->scale << 9) + 
                        (data->sz == 4 ? 0x800 : 0));
                    PUTWORD(p, val &0xffff);
                }
            }
            else
                DIAG("Offset too large for 68000");
        }
        else
        {
            PUTWORD(p, (data->sreg << 12) + (data->mode == am_baseindxdata ? 0 
                : 0x8000) + (val &0xff) + (data->scale << 9) + (data->sz == 4 ?
                0x800 : 0));
        }
    }
    return data->preg + 0x30;
}

//-------------------------------------------------------------------------

static int putpcbased(OCODE *ins, AMODE *data, unsigned char **p)
{
    long val;
    int resolved = 1;
    val = ResolveOffset(ins, data->offset, &resolved);
    if (!resolved)
    {
        if (prm_68020)
        {
            val += 2;
            PUTWORD(p, 0x130 + (data->sreg << 12) + (data->mode ==
                am_pcindxdata ? 0 : 0x8000) + (data->scale << 9) + (data->sz ==
                4 ? 0x800 : 0));
            ins->ofs[ins->rescount] = val;
            ins->pcrelofs = (*p) - ins->outbuf;
            ins->pcrelres = ins->rescount;
            ins->resobyte[ins->rescount] = data == ins->oper1 ? 4 : 20;
            ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
            ins->reloffset = data;
            ins->branched = BR_PCREL;
            PUTWORD(p, val >> 16);
            PUTWORD(p, val &0xffff);

        }
        else
        {
            DIAG("putpcbased - Offset too large for 68000");
        }
    }
    else
    {
        if (val)
            DIAG("putpcbased PC rel address to non-label");
        PUTWORD(p, (data->sreg << 12) + (data->mode == am_pcindxdata ? 0 :
            0x8000) + (data->scale << 9) + (data->sz == 4 ? 0x800 : 0));
    }
    return 0x3b;
}

//-------------------------------------------------------------------------

static int putaddr(int size, OCODE *ins, AMODE *data, unsigned char **p)
{
    int rv;
    long val;
    int resolved = 1;
    val = ResolveOffset(ins, data->offset, &resolved);
    if (!resolved)
    {
        if (prm_68020)
        {
            int ew = 0x170;
            PUTWORD(p, 0x170);
            ins->ofs[ins->rescount] = val;
            ins->resobyte[ins->rescount] = data == ins->oper1 ? 4 : 20;
            ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
            PUTWORD(p, val >> 16);
            PUTWORD(p, val &0xffff);
            rv = data->preg + 0x30;
        }
        else
        {
            ins->ofs[ins->rescount] = val;
            ins->resobyte[ins->rescount] = data == ins->oper1 ? 2 : 18;
            ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
            PUTWORD(p, val &0xffff);
            rv = data->preg + 0x28;
        }
    }
    else
    {
        if (val <  - 0x8000 || val > 0x7fff)
        {
            if (prm_68020)
            {
                PUTWORD(p, 0x170);
                PUTWORD(p, val >> 16)PUTWORD(p, val &0xffff);
                rv = data->preg + 0x30;
            }
            else
                DIAG("putaddr - Offset too large for 68000");
        }
        else
        {
            PUTWORD(p, val &0xffff);
            rv = data->preg + 0x28;
        }
    }
    return rv;
}

//-------------------------------------------------------------------------

static int putpcaddr(int size, OCODE *ins, AMODE *data, unsigned char **p)
{
    int rv;
    long val;
    int resolved = 1;
    val = ResolveOffset(ins, data->offset, &resolved);
    if (!resolved)
    {
        if (prm_68020)
        {
            int ew = 0x170;
            val += 2;
            PUTWORD(p, ew);
            ins->ofs[ins->rescount] = val;
            ins->pcrelofs = (*p) - ins->outbuf;
            ins->pcrelres = ins->rescount;
            ins->resobyte[ins->rescount] = data == ins->oper1 ? 4 : 20;
            ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
            ins->reloffset = data;
            ins->branched = BR_PCREL;
            PUTWORD(p, val >> 16);
            PUTWORD(p, val &0xffff);
            rv = data->preg + 0x3b;

        }
        else
        {
            ins->ofs[ins->rescount] = val;
            ins->pcrelofs = (*p) - ins->outbuf;
            ins->pcrelres = ins->rescount;
            ins->resobyte[ins->rescount] = data == ins->oper1 ? 2 : 18;
            ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
            ins->reloffset = data;
            ins->branched = BR_PCREL;
            PUTWORD(p, val &0xffff);
            rv = data->preg + 0x3A;
        }
    }
    else
    {
        DIAG("PC rel address to non-label");
        PUTWORD(p, 0);
    }
    return rv;
}

//-------------------------------------------------------------------------

static int putdirect(int size, OCODE *ins, AMODE *data, unsigned char **p)
{
    int resolved = 1;
    int adr = 0;
    adr = ResolveOffset(ins, ins->oper1->offset, &resolved);
    if (size == 2)
    {
        if (resolved)
        {
            PUTWORD(p, data->offset->v.i);
        }
        else
        {
            ins->ofs[ins->rescount] = adr;
            ins->resobyte[ins->rescount] = data == ins->oper1 ? 2 : 18;
            ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
            PUTWORD(p, adr);
        }
        return 0x38;
    }
    else
    {
        if (resolved)
        {
            PUTWORD(p, data->offset->v.i >> 16);
            PUTWORD(p, data->offset->v.i &0xffff);
        }
        else
        {
            ins->ofs[ins->rescount] = adr;
            ins->resobyte[ins->rescount] = data == ins->oper1 ? 4 : 20;
            ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
            PUTWORD(p, adr >> 16);
            PUTWORD(p, adr);
        }
        return 0x39;
    }
}

//-------------------------------------------------------------------------

static void putam(int size, OCODE *ins, AMODE *data, unsigned char **p)
{
    int resolved = 1;
    int adr = 0;
    switch (data->mode)
    {
        case am_dreg:
            ins->outbuf[1] |= data->preg;
            break;
        case am_areg:
            ins->outbuf[1] |= 8+data->preg;
            break;
        case am_immed:
            ins->outbuf[1] |= 0x3c;
            switch (size)
            {
            case 1:
                adr = ResolveOffset(ins, ins->oper1->offset, &resolved);
                if (resolved)
                {
                    PUTWORD(p, ins->oper1->offset->v.i &0xff);
                }
                else
                {
                    ins->ofs[ins->rescount] = adr;
                    ins->resobyte[ins->rescount] = data == ins->oper1 ? 2 : 18;
                    ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
                    PUTWORD(p, adr);
                }
                break;
            case 2:
                adr = ResolveOffset(ins, ins->oper1->offset, &resolved);
                if (resolved)
                {
                    PUTWORD(p, ins->oper1->offset->v.i &0xffff);
                }
                else
                {
                    ins->ofs[ins->rescount] = adr;
                    ins->resobyte[ins->rescount] = data == ins->oper1 ? 2 : 18;
                    ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
                    PUTWORD(p, adr);
                }
                break;
            case 4:
                adr = ResolveOffset(ins, ins->oper1->offset, &resolved);
                if (resolved)
                {
                    PUTWORD(p, ins->oper1->offset->v.i >> 16);
                    PUTWORD(p, ins->oper1->offset->v.i &65535);
                }
                else
                {
                    ins->ofs[ins->rescount] = adr;
                    ins->resobyte[ins->rescount] = data == ins->oper1 ? 4 : 20;
                    ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
                    PUTWORD(p, adr >> 16);
                    PUTWORD(p, adr &0xffff);
                }
                break;
            case 7:
                {
                    float val = data->offset->v.f;
                    reverseemit(curseg, &val, 4);
                }
                break;
            case 8:
                {
                    double val = data->offset->v.f;
                    reverseemit(curseg, &val, 8);
                }
                break;
            case 10:
                {
                    long double val = data->offset->v.f;
                    reverseemit(curseg, &val, 10);
                }
                break;
            }
            break;
        case am_direct:
        case am_adirect:
            ins->outbuf[1] |= putdirect(data->preg, ins, data, p);
            break;
        case am_pcindxdata:
        case am_pcindxaddr:
            ins->outbuf[1] |= putpcbased(ins, data, p);
            break;
        case am_pcindx:
            ins->outbuf[1] |= putpcaddr(size, ins, data, p);
            break;
        case am_ind:
            ins->outbuf[1] |= 0x10 + data->preg;
            break;
        case am_ainc:
            ins->outbuf[1] |= 0x18 + data->preg;
            break;
        case am_adec:
            ins->outbuf[1] |= 0x20 + data->preg;
            break;
        case am_indx:
            ins->outbuf[1] |= putaddr(size, ins, data, p);
            break;
        case am_baseindxdata:
            ins->outbuf[1] |= putbased(ins, data, 0, p);
            break;
        case am_baseindxaddr:
            ins->outbuf[1] |= putbased(ins, data, 1, p);
            break;
        default:
            DIAG("putam - Unknown address mode");
    }
}

//-------------------------------------------------------------------------

static void putam2(int size, OCODE *ins, AMODE *data, unsigned char **p)
{
    short val, val1;
    int vv = ins->outbuf[1] &0x3f;
    ins->outbuf[1] &= 0xc0;
    putam(size, ins, data, p);
    val1 = ins->outbuf[1];
    val = val1 + (ins->outbuf[0] << 8);
    val |= (val1 &0x38) << 3;
    val |= (val1 &0x7) << 9;
    val &= 0xffc0;
    ins->outbuf[0] = val >> 8;
    ins->outbuf[1] = val | vv;
}

//-------------------------------------------------------------------------

static void putbranch(int val, OCODE *ins, unsigned char **p)
{
    int size;
    int resolved = 1;
    long addr;
    switch (size = ins->length)
    {
        case 1:
            ins->branched = BR_BYTE;
            break;
        case 2:
            ins->branched = BR_SHORT;
            break;
        case 4:
            if (prm_68020)
            {
                ins->branched = BR_LONG;
                val |= 0xff;
            }
            else
                DIAG("putbranch - Long branch for 68000");
            break;
        default:
            size = 2;
            if (prm_68020)
            {
                val |= 0xff;
                size = 4;
                ins->branched = BR_LONG;
            }
            else
                ins->branched = BR_SHORT;
            break;
    }
    addr = ResolveOffset(ins, ins->oper1->offset, &resolved);
    if (size == 1)
    {
        PUTWORD(p, val + (addr &0xff));
    }
    else
        PUTWORD(p, val);
    ins->ofs[ins->rescount] = addr;
    ins->reloffset = ins->oper1;
    ins->resobyte[ins->rescount] = size;
    ins->pcrelofs = (*p) - ins->outbuf;
    ins->pcrelres = ins->rescount;
    ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
    if (size != 1)
    {
        if (size == 4)
            PUTWORD(p, addr >> 16);
        PUTWORD(p, addr);
    }
}

//-------------------------------------------------------------------------

static void putdbranch(int val, OCODE *ins, unsigned char **p)
{
    long addr;
    int resolved = 1;
    ins->branched = BR_SHORT | BR_DBRA;
    PUTWORD(p, val + 0xc8 + ins->oper1->preg);
    addr = ResolveOffset(ins, ins->oper2->offset, &resolved);
    ins->ofs[ins->rescount] = addr;
    ins->pcrelofs = 2;
    ins->reloffset = ins->oper2;
    ins->resobyte[ins->rescount] = 18;
    ins->addroffset[ins->rescount++] =  *p - ins->outbuf;
    PUTWORD(p, addr);
}

//-------------------------------------------------------------------------

static void putfbranch(int val, OCODE *ins, unsigned char **p)
{
    int size = 2;
    int resolved = 1;
    long addr;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -