mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
Upload
Digital Research
This commit is contained in:
850
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/pass2.c
Normal file
850
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/as68/pass2.c
Normal file
@@ -0,0 +1,850 @@
|
||||
/*
|
||||
Copyright 1983
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
|
||||
@(#)pass2.c 1.5 12/16/83
|
||||
*/
|
||||
|
||||
/*
|
||||
* pass two for the 68000 assembler
|
||||
* Bill Allen
|
||||
* March 1980
|
||||
*/
|
||||
|
||||
#include "as68.h"
|
||||
#include "p2def.h"
|
||||
|
||||
/*pass two driver*/
|
||||
pass2()
|
||||
{
|
||||
register short i;
|
||||
register int (*dirop)();
|
||||
|
||||
pitix = &itbuf[ITBSZ]; /*it buffer is empty*/
|
||||
lbuf.cc = tbuf.cc = dabuf.cc = drbuf.cc = BSIZE;
|
||||
lbuf.fd = lfn; /*set buffered io for binary file*/
|
||||
lbuf.cp = &lbuf.cbuf[0];
|
||||
tbuf.fd = trbfn; /*set buffered io for text reloc bits file*/
|
||||
tbuf.cp = &tbuf.cbuf[0];
|
||||
dabuf.fd = dafn; /*set buffered io for data bytes*/
|
||||
dabuf.cp = &dabuf.cbuf[0];
|
||||
drbuf.fd = drbfn; /*set buffered io for data reloc bits*/
|
||||
drbuf.cp = &drbuf.cbuf[0];
|
||||
couthd.ch_magic = MAGIC;/*c.out magic number*/
|
||||
if(savelc[TEXT]&1)
|
||||
savelc[TEXT]++; /*make it even*/
|
||||
couthd.ch_tsize = savelc[TEXT]; /*text size*/
|
||||
if(savelc[DATA]&1)
|
||||
savelc[DATA]++; /*make it even*/
|
||||
couthd.ch_dsize = savelc[DATA]; /*data size*/
|
||||
couthd.ch_bsize = savelc[BSS]; /*bss size*/
|
||||
/**
|
||||
* symbol table size is not known now -- it is set at end of pass 2
|
||||
* entry point and stack size are zero for now
|
||||
**/
|
||||
putchd(&lbuf,&couthd); /* [vlh] 4.1, replaces write_header */
|
||||
savelc[0] = 0; savelc[1] = 0; savelc[2] = 0; savelc[3] = 0;
|
||||
loctr = 0; /*location counter*/
|
||||
rlflg = TEXT; /*TEXT relocatable*/
|
||||
p2flg = 1; /*pass two*/
|
||||
if (lseek(ifn,0L,0) == -1L) { /*beginning of source*/
|
||||
rpterr("seek error on source file\n");
|
||||
abort();
|
||||
}
|
||||
close(itfn);
|
||||
LASTCHTFN = itfnc;
|
||||
itfn = openfi(tfilname,0,1); /*open it for reading*/
|
||||
pline = 1; /*no lines printed*/
|
||||
fchr=gchr(); /*get first char*/
|
||||
while(1) { /*pass 2 main loop*/
|
||||
ristb(); /*read it for one statement*/
|
||||
p2absln = stbuf[0].itop; /*line number*/
|
||||
if(p2absln>=brkln2) /*for debugging the assembler*/
|
||||
i=0;
|
||||
opcpt = stbuf[2].itop.ptrw2; /*ptr to opcode entry in main tab*/
|
||||
nite = stbuf[0].itrl & 0377; /*number of it entries*/
|
||||
pnite = &stbuf[nite].itty; /*ptr to end of stmt*/
|
||||
modelen = stbuf[2].itrl; /*instr mode length*/
|
||||
p1inlen = stbuf[1].itrl; /*pass 1 instr length guess*/
|
||||
opdix = ITOP1; /*first operand*/
|
||||
pitw = &stbuf[ITOP1].itty; /*ptr to first operand*/
|
||||
prsp = 0; /*special print flag off*/
|
||||
instrlen = 2; /*default for print*/
|
||||
if(opcpt->flags&OPDR) { /*opcode is a directive*/
|
||||
i = opcpt->vl1; /*directive number*/
|
||||
if (i<=DIRECT) {
|
||||
dirop = p2direct[i];
|
||||
(*dirop)(); /*handle directive*/
|
||||
}
|
||||
else
|
||||
uerr(21);
|
||||
}
|
||||
else
|
||||
gcist(); /*generate code for one statement*/
|
||||
}
|
||||
}
|
||||
|
||||
/* generate code for an instruction*/
|
||||
/* call with*/
|
||||
/* intermediate text for instruction in stbuf*/
|
||||
gcist()
|
||||
{
|
||||
if(stbuf[0].itty != ITBS) /*beginning of statement*/
|
||||
abort();
|
||||
format = (opcpt->flags)&OPFF;
|
||||
in_err = 0; /*[vlh] no error this instruction, yet*/
|
||||
ival = 0; /*initial value for possible operand*/
|
||||
reloc = ABS;
|
||||
instrlen = 2; /*at least 2 bytes*/
|
||||
ins[0] = opcpt->vl1.loword; /*opcode value, 4.2 ==> loword*/
|
||||
rlbits[0] = INSABS; /*instruction absolute*/
|
||||
pins = &ins[1];
|
||||
prlb = &rlbits[1];
|
||||
if(nite>ITOP1) { /*operands*/
|
||||
if(!format)
|
||||
uerr(9);
|
||||
else if(format>LSTFRMT) /* [vlh] was a magic number... */
|
||||
abort();
|
||||
else {
|
||||
(*opfary[format])();
|
||||
}
|
||||
}
|
||||
if (!ckein() && !in_err) /* at end of statement ?? */
|
||||
uerr(6);
|
||||
print(1); /*print source*/
|
||||
|
||||
loctr += p1inlen;
|
||||
if (!in_err && p1inlen != instrlen) /* [vlh] 2nd pass error recovery */
|
||||
uerr(38);
|
||||
outinstr(); /*write out instr binary*/
|
||||
}
|
||||
|
||||
/* relative branches*/
|
||||
relbr()
|
||||
{
|
||||
expr(&p2gi);
|
||||
if(extflg) { /*external reference*/
|
||||
instrlen += 2; /*long relative*/
|
||||
*pins++ = ival; /*pass constant part*/
|
||||
*prlb++ = (extref<<3)|EXTREL; /*ext ref*/
|
||||
return;
|
||||
}
|
||||
ival -= (loctr+2); /*calc relative offset*/
|
||||
if(itype!=ITCN || reloc != rlflg) {
|
||||
uerr(22); /*invalid relative branch*/
|
||||
ival = 0;
|
||||
}
|
||||
reloc = ABS;
|
||||
if(p1inlen==4) { /*long displacement*/
|
||||
if(ival>32767 || ival<-32768)
|
||||
uerr(22);
|
||||
instrlen += 2;
|
||||
*pins++ = ival;
|
||||
*prlb++ = DABS; /*data absolute*/
|
||||
}
|
||||
else { /*short displacement*/
|
||||
if(ival>127 || ival<-128)
|
||||
uerr(22);
|
||||
ins[0] |= (ival.loword&0377);
|
||||
}
|
||||
/* [vlh] 4.2 0==>2 make it a nop if -N specified */
|
||||
if ((ival==0) || (ival==2 && didorg)) {
|
||||
opcpt = nopptr;
|
||||
ins[0] = opcpt->vl1.loword;
|
||||
if(instrlen==4) { /* long branch */
|
||||
pins = &ins[1];
|
||||
*pins++ = opcpt->vl1.loword;
|
||||
rlbits[1] = INSABS;
|
||||
}
|
||||
}
|
||||
in_err++; /* ignore extra eg. bra *+$d04(pc) vs. bra *+d04 */
|
||||
}
|
||||
|
||||
#define US (unsigned short)
|
||||
/* format one -- add, sub, and, or, cmp, etc.*/
|
||||
/* one operand must be a D reg (or A reg dest for add, sub, or cmp)*/
|
||||
opf1()
|
||||
{
|
||||
register short *p;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if (ins[0]==(US AND) || ins[0]==(US OR))
|
||||
if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
if (ins[0]==(US AND))
|
||||
opcpt = andiptr;
|
||||
else
|
||||
opcpt = oriptr;
|
||||
ins[0] = opcpt->vl1.loword;
|
||||
format = (opcpt->flags)&OPFF;
|
||||
ccr_or_sr();
|
||||
return;
|
||||
}
|
||||
p = f1mode;
|
||||
if(ckdreg(&opnd[1])) { /*destn is D reg*/
|
||||
if((opcpt==andptr||opcpt==orptr)&&ckareg(&opnd[0])) /*A source*/
|
||||
uerr(20);
|
||||
makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
|
||||
return;
|
||||
}
|
||||
else if(ckdreg(&opnd[0]) && memalt(&opnd[1])) { /*source is D reg*/
|
||||
if (pcea(&opnd[1])) uerr(10);
|
||||
makef1(opnd[0].ea,p[modelen]+0400,&opnd[1]);
|
||||
return;
|
||||
}
|
||||
else if(ckareg(&opnd[1])) { /*A reg is dstn*/
|
||||
if(opcpt==addptr)
|
||||
opcpt = addaptr;
|
||||
else if(opcpt==cmpptr)
|
||||
opcpt = cmpaptr;
|
||||
else if(opcpt==subptr)
|
||||
opcpt = subaptr;
|
||||
else {
|
||||
uerr(20);
|
||||
return;
|
||||
}
|
||||
format = (opcpt->flags)&OPFF;
|
||||
opnd[1].ea &= 07;
|
||||
p = f15mode;
|
||||
makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
|
||||
return;
|
||||
}
|
||||
else if(!makeimm()) /*make an immediate instr*/
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/* format 2 -- addi, andi, subi, etc*/
|
||||
opf2()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(ins[0]==ANDI || ins[0]==ORI || ins[0]==EORI) {
|
||||
if(cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
ccr_or_sr();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(opnd[0].ea != IMM) {
|
||||
uerr(9);
|
||||
return;
|
||||
}
|
||||
if(!dataalt(&opnd[1]) || pcea(&opnd[1])) {
|
||||
uerr(20);
|
||||
return;
|
||||
}
|
||||
genimm();
|
||||
}
|
||||
|
||||
/*format #3 -- move and movea*/
|
||||
opf3()
|
||||
{
|
||||
register short k;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(cksprg(&opnd[0],CCR)) { /* [vlh] 03-aug-83 */
|
||||
ins[0] = MOVEFCC;
|
||||
if(anysprg(&opnd[1]))
|
||||
uerr(20);
|
||||
if (modelen == BYTESIZ || modelen == LONGSIZ)
|
||||
uerr(34);
|
||||
if (!m68010)
|
||||
uerr(8);
|
||||
ins[0] |= opnd[1].ea;
|
||||
if(!dataea(&opnd[1]))
|
||||
uerr(9);
|
||||
doea(&opnd[1]);
|
||||
return;
|
||||
}
|
||||
if(cksprg(&opnd[1],CCR)) {
|
||||
ins[0] = MOVETCC;
|
||||
opf3l1:
|
||||
if(anysprg(&opnd[0]))
|
||||
uerr(20);
|
||||
if (modelen == BYTESIZ || modelen == LONGSIZ)
|
||||
uerr(34);
|
||||
ins[0] |= opnd[0].ea;
|
||||
if(!dataea(&opnd[0]))
|
||||
uerr(9);
|
||||
doea(&opnd[0]);
|
||||
return;
|
||||
}
|
||||
if(cksprg(&opnd[1],SR)) {
|
||||
ins[0] = MOVESR;
|
||||
goto opf3l1;
|
||||
}
|
||||
if(cksprg(&opnd[0],SR)) {
|
||||
if (modelen == BYTESIZ || modelen == LONGSIZ)
|
||||
uerr(34);
|
||||
if(anysprg(&opnd[1]))
|
||||
uerr(20);
|
||||
ins[0] = SRMOVE | opnd[1].ea;
|
||||
if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
|
||||
uerr(10);
|
||||
doea(&opnd[1]);
|
||||
return;
|
||||
}
|
||||
if(cksprg(&opnd[0],USP)) {
|
||||
if (modelen == BYTESIZ)
|
||||
uerr(34); /* default is word, can't test */
|
||||
if (!ckareg(&opnd[1]))
|
||||
uerr(33);
|
||||
ins[0] = MOVEUSP|8|(opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
if(cksprg(&opnd[1],USP)) {
|
||||
if (modelen == BYTESIZ)
|
||||
uerr(34); /* default is word, can't test */
|
||||
if (!ckareg(&opnd[0]))
|
||||
uerr(33);
|
||||
ins[0] = MOVEUSP|(opnd[0].ea&7);
|
||||
return;
|
||||
}
|
||||
k = ins[0];
|
||||
ins[0] |= f3mode[modelen];
|
||||
ckbytea();
|
||||
ins[0] |= opnd[0].ea; /*source ea*/
|
||||
doea(&opnd[0]);
|
||||
ins[0] |= (opnd[1].ea&7)<<9; /*dest register*/
|
||||
ins[0] |= (opnd[1].ea&070)<<3; /*dest mode*/
|
||||
doea(&opnd[1]);
|
||||
if(k==MOVEA) {
|
||||
if(dataea(&opnd[1]))
|
||||
uerr(20);
|
||||
}
|
||||
else if((pcea(&opnd[1]) && dataea(&opnd[1])) || opnd[1].ea==IMM)
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/* format 4 -- abcd, sbcd */
|
||||
/* format 10 -- cmpm*/
|
||||
/* format 27 -- addx, subx */
|
||||
opf4()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if (format==27) { /*addx,subx add in size bits*/
|
||||
ins[0] |= f1mode[modelen];
|
||||
}
|
||||
else if(format==10) { /*cmpm*/
|
||||
if((opnd[0].ea&070)!=INDINC || (opnd[1].ea&070)!=INDINC)
|
||||
uerr(20);
|
||||
ins[0] |= f1mode[modelen] | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
if (m68010) { /* [vlh] 4.2 */
|
||||
uerr(31);
|
||||
nerror--; /* just a warning */
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(ckdreg(&opnd[0]) && ckdreg(&opnd[1])) {
|
||||
ins[0] |= ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
return;
|
||||
}
|
||||
if((opnd[0].ea&070)==DECIND && (opnd[1].ea&070)==DECIND) {
|
||||
ins[0] |= 010 | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
return;
|
||||
}
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/*format 5 -- div, mul*/
|
||||
/*format 26 -- cmp, chk */
|
||||
opf5()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(!ckdreg(&opnd[1])) {
|
||||
if(opcpt==cmpptr) {
|
||||
if(!dataea(&opnd[1])) /* [vlh] made define */
|
||||
ins[0] |= f5amode[modelen]; /* was pumode */
|
||||
else if(makeimm())
|
||||
return;
|
||||
else
|
||||
uerr(20);
|
||||
}
|
||||
else
|
||||
uerr(20);
|
||||
}
|
||||
if(opcpt==cmpptr) {
|
||||
ins[0] |= f5mode[modelen]; /* was pumode */
|
||||
ckbytea();
|
||||
}
|
||||
else if(!dataea(&opnd[0]))
|
||||
uerr(20);
|
||||
ins[0] |= (opnd[1].ea&7)<<9 | opnd[0].ea;
|
||||
doea(&opnd[0]);
|
||||
}
|
||||
|
||||
#define BTST 0000
|
||||
/* format 7 -- bit instrs -- btst, bclr, bset, etc*/
|
||||
opf7()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(opnd[1].ea==IMM||(ins[0]!=BTST&&pcea(&opnd[1]))||ckareg(&opnd[1]))
|
||||
uerr(20);
|
||||
if(ckdreg(&opnd[0])) {
|
||||
ins[0] |= (opnd[0].ea<<9)|0400;
|
||||
}
|
||||
else { /*static bit #*/
|
||||
if(opnd[0].con<0L || opnd[0].con>31 ||
|
||||
(opnd[1].ea&INDIRECT&&opnd[0].con>7)) /* [vlh] */
|
||||
uerr(23);
|
||||
if(opnd[0].ea != IMM)
|
||||
uerr(17);
|
||||
ins[0] |= 04000;
|
||||
dodisp(&opnd[0]);
|
||||
}
|
||||
if (modelen==1 && !(memea(&opnd[1]))) /*[vlh]*/
|
||||
uerr(20);
|
||||
else if (!(ckdreg(&opnd[1])) && modelen==4)
|
||||
uerr(20);
|
||||
ins[0] |= opnd[1].ea;
|
||||
doea(&opnd[1]);
|
||||
}
|
||||
|
||||
/* format 8 -- shifts and rotates*/
|
||||
opf8()
|
||||
{
|
||||
register short i;
|
||||
|
||||
getea(0); /*get first operand*/
|
||||
if(pitw >= pnite) { /*end of all ops*/
|
||||
if(ckdreg(&opnd[0])) { /*shift dreg one bit*/
|
||||
cpop01(); /*copy opnd 0 to 1*/
|
||||
opnd[0].ea = IMM;
|
||||
opnd[0].con = 1L;
|
||||
if (!ckdreg(&opnd[1])) uerr(20);
|
||||
opf8l1:
|
||||
if(opnd[0].con<1 || opnd[0].con>8) /*[vlh legal range 1..8*/
|
||||
uerr(37);
|
||||
ins[0] |= ((opnd[0].con.loword&7)<<9)|f1mode[modelen]|opnd[1].ea;
|
||||
return;
|
||||
}
|
||||
i = (ins[0]&077)<<6;
|
||||
ins[0] &= 0177700;
|
||||
ins[0] |= 0300|i|opnd[0].ea;
|
||||
if(!memalt(&opnd[0]) || pcea(&opnd[0]) || modelen != 2)
|
||||
uerr(20);
|
||||
doea(&opnd[0]);
|
||||
return;
|
||||
}
|
||||
if(!ckcomma()) {
|
||||
uerr(10);
|
||||
return;
|
||||
}
|
||||
getea(1); /*get second operand*/
|
||||
if(!ckdreg(&opnd[1])) /* [vlh] second operand must be dreg */
|
||||
uerr(20);
|
||||
if(ckdreg(&opnd[0])) { /*first op is D reg*/
|
||||
ins[0] |= (opnd[0].ea<<9)|040; /*reg # and reg bit*/
|
||||
}
|
||||
else {
|
||||
if(opnd[0].ea != IMM)
|
||||
uerr(20);
|
||||
goto opf8l1;
|
||||
}
|
||||
ins[0] |= f1mode[modelen] | opnd[1].ea; /*put in size and reg #*/
|
||||
}
|
||||
|
||||
/* format 9 -- jmp, jsr */
|
||||
/* format 14 -- stop */
|
||||
/* format 14 -- rtd (68010) */
|
||||
/* format 24 -- clr, neg, negx, not */
|
||||
/* format 25 -- s?? */
|
||||
/* format 29 -- pea */
|
||||
/* one operand instructions -- jmp, clr, neg, not, sge, etc.*/
|
||||
opf9()
|
||||
{
|
||||
getea(0);
|
||||
if(format==24) { /*clr, not, etc*/
|
||||
ins[0] |= f1mode[modelen]; /*add size bits*/
|
||||
if(!dataalt(&opnd[0]) || pcea(&opnd[0]))
|
||||
uerr(20);
|
||||
}
|
||||
else if(format==25) { /*tas,scc, etc*/
|
||||
if(ckareg(&opnd[0]) || pcea(&opnd[0]) || opnd[0].ea==IMM)
|
||||
uerr(20);
|
||||
}
|
||||
else if(format==14) { /*stop*/
|
||||
if (ins[0] == RTD && !m68010) /* [vlh] 4.2 */
|
||||
uerr(8);
|
||||
if(modelen!=2 || opnd[0].ea!=IMM)
|
||||
uerr(20);
|
||||
doea(&opnd[0]);
|
||||
return;
|
||||
}
|
||||
else if(!controlea(&opnd[0])) /*jmp, jsr, etc*/
|
||||
uerr(20);
|
||||
ins[0] |= opnd[0].ea;
|
||||
doea(&opnd[0]);
|
||||
}
|
||||
|
||||
/* format 11 -- dbcc*/
|
||||
/* format 19 -- link*/
|
||||
opf11()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(format==19) { /*link*/
|
||||
if(!ckareg(&opnd[0]))
|
||||
uerr(33);
|
||||
if(opnd[1].ea != IMM)
|
||||
uerr(17);
|
||||
}
|
||||
else {
|
||||
if(!ckdreg(&opnd[0]))
|
||||
uerr(33);
|
||||
if(opnd[1].drlc!=rlflg) /*[vlh]don't chk opnd[1].ea!=LADDR||SADDR*/
|
||||
uerr(22);
|
||||
opnd[1].con -= (loctr+2L);
|
||||
cksize(&opnd[1]);
|
||||
opnd[1].drlc = ABS; /*not relocatable*/
|
||||
}
|
||||
ins[0] |= opnd[0].ea&7; /*put in reg #*/
|
||||
dodisp(&opnd[1]);
|
||||
}
|
||||
|
||||
/* format 12 -- exg*/
|
||||
opf12()
|
||||
{
|
||||
register short i;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(ckdreg(&opnd[0])) {
|
||||
if(ckdreg(&opnd[1])) { /*exchange D regs*/
|
||||
ins[0] |= 0100 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
if(ckareg(&opnd[1])) { /*ins[0] <- A and D flag*/
|
||||
ins[0] |= 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(ckareg(&opnd[0])) {
|
||||
if(ckareg(&opnd[1])) { /*both a regs*/
|
||||
ins[0] |= 0110 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
if(ckdreg(&opnd[1])) { /*A and D regs*/
|
||||
i = opnd[0].ea; /*exchg ea's*/
|
||||
opnd[0].ea = opnd[1].ea;
|
||||
opnd[1].ea = i;
|
||||
ins[0] |= 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
}
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/* format 13 -- ext, unlk*/
|
||||
/* format 18 -- trap*/
|
||||
/* format 28 -- swap */
|
||||
#define UNLK 047130
|
||||
|
||||
opf13()
|
||||
{
|
||||
getea(0);
|
||||
if(format==18) { /*trap*/
|
||||
if(opnd[0].con<0 || opnd[0].con>15)
|
||||
uerr(15);
|
||||
ins[0] |= opnd[0].con.loword;
|
||||
return;
|
||||
}
|
||||
if(ins[0]==UNLK) { /*unlk instr*/
|
||||
if(!ckareg(&opnd[0]))
|
||||
uerr(20);
|
||||
}
|
||||
else {
|
||||
if(!ckdreg(&opnd[0]))
|
||||
uerr(20);
|
||||
if (format==13) /* ext */
|
||||
ins[0] |= f13mode[modelen];
|
||||
}
|
||||
ins[0] |= opnd[0].ea&7;
|
||||
}
|
||||
|
||||
/* format 15 -- adda, cmpa, suba*/
|
||||
/* format 30 -- lea */
|
||||
opf15()
|
||||
{
|
||||
register short i;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(!ckareg(&opnd[1]))
|
||||
uerr(33);
|
||||
if(format==30) {
|
||||
i = 0700;
|
||||
if(!controlea(&opnd[0]))
|
||||
uerr(20);
|
||||
}
|
||||
else
|
||||
i = f15mode[modelen];
|
||||
makef1(opnd[1].ea&7,i,&opnd[0]);
|
||||
if (format==15 && opnd[0].ea != 071) cksize(&opnd[0]);
|
||||
}
|
||||
|
||||
/*formats 16 and 17 -- addq, inc, subq, dec*/
|
||||
opf17()
|
||||
{
|
||||
if(format==16) { /*inc or dec*/
|
||||
clrea(&opnd[0]);
|
||||
opnd[0].ea = IMM;
|
||||
opnd[0].con = 1L;
|
||||
opnd[0].drlc = ABS;
|
||||
getea(1);
|
||||
}
|
||||
else {
|
||||
if(get2ops())
|
||||
return;
|
||||
}
|
||||
if(opnd[0].ea != IMM || !altea(&opnd[1]) || pcea(&opnd[1]))
|
||||
uerr(20);
|
||||
if(opnd[0].con<=0 || opnd[0].con>8)
|
||||
uerr(15);
|
||||
if(modelen==1 && !dataea(&opnd[1]))
|
||||
uerr(34);
|
||||
ins[0] |= f1mode[modelen]|((opnd[0].con.loword&7)<<9)|opnd[1].ea;
|
||||
doea(&opnd[1]);
|
||||
}
|
||||
|
||||
/* format 20 -- movem */
|
||||
short regmsk0[] = {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
|
||||
0100,040,020,010,4,2,1};
|
||||
short regmsk1[] = {1,2,4,010,020,040,0100,0200,0400,01000,02000,04000,010000,
|
||||
020000,040000,0100000};
|
||||
opf20()
|
||||
{
|
||||
register short dr, i, j;
|
||||
|
||||
dr = 0;
|
||||
if(getreg() != -1 || pitw->itty == ITRM) { /*regs to memory*/
|
||||
if (pitw->itty != ITRM) { /* [vlh] */
|
||||
pitw--;
|
||||
j = getrlist(regmsk0);
|
||||
}
|
||||
else {
|
||||
j = pitw->itop;
|
||||
pitw++;
|
||||
}
|
||||
if(!ckcomma())
|
||||
uerr(10);
|
||||
}
|
||||
else
|
||||
dr = 02000;
|
||||
getea(0);
|
||||
if(dr) {
|
||||
if(!ckcomma())
|
||||
uerr(10);
|
||||
if (pitw->itty != ITRM) /* [vlh] */
|
||||
j = getrlist(regmsk1); /*mem to regs*/
|
||||
else {
|
||||
j = pitw->itop;
|
||||
j = fixmask(j);
|
||||
pitw++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(controlea(&opnd[0]))
|
||||
j = fixmask(j);
|
||||
}
|
||||
i = opnd[0].ea&070;
|
||||
if(!controlea(&opnd[0]) && i!=INDINC && i!=DECIND)
|
||||
uerr(20);
|
||||
if(modelen==4) /*long*/
|
||||
ins[0] |= 0100;
|
||||
ins[0] |= opnd[0].ea|dr;
|
||||
*pins++ = j; /*reg mask*/
|
||||
*prlb++ = DABS;
|
||||
instrlen += 2;
|
||||
doea(&opnd[0]);
|
||||
if (!dr) { /* 1st argument (2nd is reg list) */
|
||||
if (pcea(&opnd[0]) || (opnd[0].ea&070)==INDINC)
|
||||
uerr(20); /* xx(pc), xx(pc,dx), -(ax) */
|
||||
}
|
||||
else /* 2nd argument (1st is reg list) */
|
||||
if ((opnd[0].ea&070)==DECIND)
|
||||
uerr(20); /* (ax)+ */
|
||||
}
|
||||
|
||||
/*
|
||||
* get a list of registers for the movem instr
|
||||
* call with:
|
||||
* ptr to reg-to-mem or mem-to-reg array of bits
|
||||
*/
|
||||
getrlist(ap)
|
||||
short *ap;
|
||||
{
|
||||
register short *p, i, j, mask;
|
||||
|
||||
p = ap;
|
||||
mask = 0;
|
||||
while((i=getreg()) != -1) {
|
||||
if(ckitc(pitw,'-')) {
|
||||
pitw++;
|
||||
if((j=getreg()) == -1) {
|
||||
uerr(40);
|
||||
break;
|
||||
}
|
||||
while(i<=j)
|
||||
mask |= p[i++];
|
||||
}
|
||||
else
|
||||
mask |= p[i];
|
||||
if(ckitc(pitw,'/'))
|
||||
pitw++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if(!mask)
|
||||
uerr(40);
|
||||
return(mask);
|
||||
}
|
||||
|
||||
/*reverse a movem register mask for control ea to memory*/
|
||||
fixmask(msk)
|
||||
int msk;
|
||||
{
|
||||
register short i, j, k;
|
||||
|
||||
k = (msk&1) ? 0100000 : 0;
|
||||
i = 2;
|
||||
j = 040000;
|
||||
while(i) {
|
||||
if(msk&i)
|
||||
k |= j;
|
||||
i <<= 1;
|
||||
j >>= 1;
|
||||
}
|
||||
return(k);
|
||||
}
|
||||
|
||||
/* format 21 -- movep*/
|
||||
opf21()
|
||||
{
|
||||
register short m,d;
|
||||
register char *p;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(ckdreg(&opnd[0])) { /*d reg source*/
|
||||
m = 0600;
|
||||
d = opnd[0].ea;
|
||||
p = &opnd[1];
|
||||
}
|
||||
else if(ckdreg(&opnd[1])) { /*d reg dest*/
|
||||
m = 0400;
|
||||
d = opnd[1].ea;
|
||||
p = &opnd[0];
|
||||
}
|
||||
else {
|
||||
uerr(20);
|
||||
}
|
||||
if((p->ea&070) != INDDISP)
|
||||
uerr(20);
|
||||
if(modelen == 4)
|
||||
m |= 0100;
|
||||
ins[0] |= (d<<9)|m|(p->ea&7);
|
||||
*pins++ = p->con.loword;
|
||||
*prlb++ = p->drlc;
|
||||
instrlen += 2;
|
||||
}
|
||||
|
||||
/* format 22 -- moveq*/
|
||||
opf22()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(opnd[0].ea != IMM)
|
||||
uerr(17);
|
||||
if(opnd[0].con>255L || opnd[0].con<-256L)
|
||||
uerr(15);
|
||||
if(!ckdreg(&opnd[1]))
|
||||
uerr(33);
|
||||
ins[0] |= (opnd[1].ea<<9) | (opnd[0].con.loword&0377);
|
||||
}
|
||||
|
||||
/* format 23 -- eor*/
|
||||
opf23()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
opcpt = eoriptr;
|
||||
ins[0] = opcpt->vl1.loword;
|
||||
format = (opcpt->flags)&OPFF;
|
||||
ccr_or_sr();
|
||||
return;
|
||||
}
|
||||
if(!ckdreg(&opnd[0])) {
|
||||
if(makeimm()) /*must be immediate*/
|
||||
return;
|
||||
uerr(20); /*or error*/
|
||||
}
|
||||
if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
|
||||
uerr(20);
|
||||
ins[0] |= (opnd[0].ea<<9)|f23mode[modelen]|opnd[1].ea;
|
||||
doea(&opnd[1]);
|
||||
}
|
||||
|
||||
/* format 31 -- movec and moves (68010 only) [vlh] 4.2 */
|
||||
opf31()
|
||||
{
|
||||
register struct op *cntrl, *genrl, *eaop;
|
||||
|
||||
instrlen += 2;
|
||||
if (!m68010)
|
||||
uerr(8);
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if (ins[0] == MOVEC) {
|
||||
if (modelen == BYTESIZ)
|
||||
uerr(34);
|
||||
if ( cksprg(&opnd[0],USP) || cksprg(&opnd[0],SFC) ||
|
||||
cksprg(&opnd[0],DFC) || cksprg(&opnd[0],VSR)) {
|
||||
cntrl = &opnd[0];
|
||||
genrl = &opnd[1];
|
||||
}
|
||||
else {
|
||||
if ( !cksprg(&opnd[1],USP) && !cksprg(&opnd[1],SFC) &&
|
||||
!cksprg(&opnd[1],DFC) && !cksprg(&opnd[1],VSR))
|
||||
uerr(18);
|
||||
ins[0] |= 1; /* direction Rn --> Rc */
|
||||
cntrl = &opnd[1];
|
||||
genrl = &opnd[0];
|
||||
}
|
||||
if (!ckreg(genrl))
|
||||
uerr(18);
|
||||
*pins = ((genrl->ea)<<12) & 0xF000; /* [vlh] 4.3 11==12,8==F */
|
||||
if (cksprg(cntrl,DFC))
|
||||
*pins |= DFC_CR;
|
||||
else if (cksprg(cntrl,USP))
|
||||
*pins |= USP_CR;
|
||||
else if (cksprg(cntrl,VSR))
|
||||
*pins |= VSR_CR;
|
||||
/* else... *pins |= SFC_CR; (SFC_CR == 0)*/
|
||||
}
|
||||
else { /* MOVES */
|
||||
ins[0] |= f1mode[modelen];
|
||||
if (ckreg(&opnd[0])) {
|
||||
genrl = &opnd[0];
|
||||
eaop = &opnd[1];
|
||||
*pins = 0x800; /* from general register to <ea> */
|
||||
}
|
||||
else {
|
||||
genrl = &opnd[1];
|
||||
eaop = &opnd[0];
|
||||
*pins = 0;
|
||||
}
|
||||
*pins |= ((genrl->ea)<<12) & 0xF000; /* [vlh] 4.3 11==>12 */
|
||||
if (!memalt(eaop) || pcea(eaop) || ckreg(eaop))
|
||||
uerr(20);
|
||||
ins[0] |= eaop->ea;
|
||||
doea(eaop);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user