📄 outco68.c
字号:
== 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 + -