1File: PASS2.C                                                             Page       1
     1   /*
     2   	Copyright 1981
     3   	Alcyon Corporation
     4   	8716 Production Ave.
     5   	San Diego, Ca.  92121
     6   */
     7    
     8   /*
     9    * pass two for the 68000 assembler
    10    *		Bill Allen
    11    *		March 1980
    12    */
    13    
    14   #include "as68.h"
    15   #include "cout.h"	/*c.out header definition & MAGIC*/
    16    
    17   #define MOVEA 0100
    18    
    19   int p2gi();
    20    
    21   extern char tfilname[];	/*name of it file*/
    22   extern char initfnam[];	/*name of the initilization file*/
    23   int (*p2direct[])();
    24    
    25   int opf1(), opf2(), opf3(), opf4(), opf5(), relbr(), opf7(), opf8();
    26   int opf9(), opf11(), opf12(), opf13(), opf15(), opf17(), opf20();
    27   int opf21(), opf22(), opf23();
    28    
    29   int (*opfary[])() {
    30   	0,		/*0*/
    31   	opf1,	/*1*/
    32   	opf2,	/*2*/
    33   	opf3,	/*3*/
    34   	opf4,	/*4*/
    35   	opf5,	/*5*/
    36   	relbr,	/*6*/
    37   	opf7,	/*7*/
    38   	opf8,	/*8*/
    39   	opf9,	/*9*/
    40   	opf4,	/*10*/
    41   	opf11,	/*11*/
    42   	opf12,	/*12*/
    43   	opf13,	/*13*/
    44   	opf9,	/*14*/
    45   	opf15,	/*15*/
    46   	opf17,	/*16*/
    47   	opf17,	/*17*/
    48   	opf13,	/*18*/
    49   	opf11,	/*19*/
    50   	opf20,	/*20*/
    51   	opf21,	/*21*/
    52   	opf22,	/*22*/
    53   	opf23,	/*23*/
    54   	opf9,	/*24*/
    55   	opf9,	/*25*/
    56   	opf5,	/*26*/		/* [vlh] cmp, chk, extention verification */
    57   	opf4,	/*27*/		/* [vlh] addx, subx, extension verification */
    58   	opf13,	/*28*/		/* [vlh] swap, extension verification */
    59   	opf9,	/*29*/		/* [vlh] pea, extention verification */
1File: PASS2.C                                                             Page       2
    60   	opf15	/*30*/		/* [vlh] lea, extension verification */
    61   };
    62    
    63   #define LSTFRMT 30
    64    
    65   int f1mode[] {0,0,0100,0,0200};
    66   int f2mode[] {0,0,0100,0,0200};
    67   int f3mode[] {0,010000,030000,0,020000};
    68   int f15mode[] {0,0,0300,0,0700};
    69   int f5mode[] {0,0,0100,0,0200};
    70   int f5amode[] {0,0,0300,0,0700};
    71   int f13mode[] {0,0,0200,0,0300};
    72   int f23mode[] {0,0400,0500,0,0600};
    73   int rlbits[5];			/*holds relocation bits for instr*/
    74   int pline;				/*number of last printed line*/
    75   int brkln2 077777;		/*pass 2 break line number for debugging*/
    76   int prsp;				/*special print alignment flag*/
    77   int amode;				/*addressing mode*/
    78   int nitleft;
    79   /*pass two driver*/
    80   pass2()
    81   {
    82   	register short *p;
    83   	register i;
    84   	register (*dirop)();
    85    
    86   	pitix = itbuf;		/* This is init for doitrd*/
    87   	xline = LPP;
    88   	nitleft = 0;
    89   	lbuf.nunused = tbuf.nunused = dabuf.nunused = drbuf.nunused = 512;
    90   	lbuf.fildes = lfn;		/*set buffered io for binary file*/
    91   	lbuf.xfree = &lbuf.buff[0];
    92   	tbuf.fildes = trbfn;	/*set buffered io for text reloc bits file*/
    93   	tbuf.xfree = &tbuf.buff[0];
    94   	dabuf.fildes = dafn;	/*set buffered io for data bytes*/
    95   	dabuf.xfree = &dabuf.buff[0];
    96   	drbuf.fildes = drbfn;	/*set buffered io for data reloc bits*/
    97   	drbuf.xfree = &drbuf.buff[0];
    98   	couthd.ch_magic = MAGIC;/*c.out magic number*/
    99   	if(savelc[TEXT]&1)
   100   		savelc[TEXT]++;		/*make it even*/
   101   	couthd.ch_tsize = savelc[TEXT];	/*text size*/
   102   	if(savelc[DATA]&1)
   103   		savelc[DATA]++;		/*make it even*/
   104   	couthd.ch_dsize = savelc[DATA];	/*data size*/
   105   	couthd.ch_bsize = savelc[BSS];	/*bss size*/
   106   /*symbol table size is not known now -- it is set at end of pass 2*/
   107   /*  entry point and stack size are zero for now*/
   108   	p = &couthd;
   109   	for(i=0; i<HDSIZE/2; i++) {
   110   		putw(*p++,&lbuf);		/*write the file header words*/
   111   	}
   112   	savelc[0] = 0; savelc[1] = 0; savelc[2] = 0; savelc[3] = 0;
   113   	loctr = 0;		/*location counter*/
   114   	rlflg = TEXT;	/*TEXT relocatable*/
   115   	p2flg = 1;		/*pass two*/
   116   #ifdef	UNIX
   117   	if (lseek(ifn,0L,0) == -1)	{	/*beginning of source*/
   118   		rpterr("seek error on source file\n");
1File: PASS2.C                                                             Page       3
   119   		abort();
   120   	}
   121   #else
   122   	close(ifn);		/* This way for goddamn Whitesmith's	*/
   123   	ifn=open(sfname,0,0);	/* Re-open the fucking source file	*/
   124   	if(ifn < 0)		/* Couldn't				*/
   125   	{
   126   		printf("Unable to open file %s\n",sfname);
   127   		abort();
   128   	}
   129   #endif
   130   	close(itfn);
   131   	LASTCHTFN = itfnc;
   132   	itfn = openfi(tfilname,0);	/*open it for reading*/
   133   	pline = 1;		/*no lines printed*/
   134   	fchr=gchr();	/*get first char*/
   135   	while(ristb())	 {		/*pass 2 main loop*/
   136   		p2absln = stbuf[0].itop;	/*line number*/
   137   		if(p2absln>=brkln2)		/*for debugging the assembler*/
   138   		i=0;
   139   		opcpt = stbuf[2].itop.ptrw2;	/*ptr to opcode entry in main tab*/
   140   		nite = stbuf[0].itrl & 0377;	/*number of it entries*/
   141   		pnite = &stbuf[nite];		/*ptr to end of stmt*/
   142   		modelen = stbuf[2].itrl;	/*instr mode length*/
   143   		p1inlen = stbuf[1].itrl;	/*pass 1 instr length guess*/
   144   		opdix = ITOP1;			/*first operand*/
   145   		pitw = &stbuf[ITOP1];		/*ptr to first operand*/
   146   		prsp = 0;			/*special print flag off*/
   147   		instrlen = 2;			/*default for print*/
   148   		if(opcpt->flags&OPDR) {	/*opcode is a directive*/
   149   			i = opcpt->vl1;	/*directive number*/
   150   			dirop = p2direct[i];
   151   			(*dirop)();			/*handle directive*/
   152   		}
   153   		else {
   154   			gcist();			/*generate code for one statement*/
   155   		}
   156   	}
   157   }
   158    
   159   /* generate code for an instruction*/
   160   /*  call with*/
   161   /*		intermediate text for instruction in stbuf*/
   162   gcist()
   163   {
   164   	register i,j;
   165    
   166   	if(stbuf[0].itty != ITBS)	/*beginning of statement*/
   167   		abort();
   168   	format = (opcpt->flags)&OPFF;
   169   	in_err = 0;				/*[vlh] no error this instruction, yet*/
   170   	ival = 0;				/*initial value for possible operand*/
   171   	reloc = ABS;
   172   	instrlen = 2;			/*at least 2 bytes*/
   173   	ins[0] = opcpt->vl1;	/*opcode value*/
   174   	rlbits[0] = INSABS;		/*instruction absolute*/
   175   	pins = &ins[1];
   176   	prlb = &rlbits[1];
   177   	if(nite>ITOP1) {		/*operands*/
1File: PASS2.C                                                             Page       4
   178   		if(!format) {
   179   			uerr(9);
   180   		}
   181   		else if(format>LSTFRMT)	/* [vlh] was a magic number... */
   182   			abort();
   183   		else {
   184   			(*opfary[format])();
   185   		}
   186   	}
   187   	if (!ckein() && !in_err) 		/* at end of statement ?? */
   188   		uerr(6);
   189   	print(1);			/*print source*/
   190    
   191   	loctr =+ p1inlen;
   192   	if (!in_err && p1inlen != instrlen)	/* [vlh] 2nd pass error recovery */
   193   		uerr(38);
   194   	outinstr();		/*write out instr binary*/
   195   }
   196    
   197   /* relative branches*/
   198   relbr()
   199   {
   200   	expr(&p2gi);
   201   	if(extflg) {	/*external reference*/
   202   		instrlen =+ 2;		/*long relative*/
   203   		*pins++ = ival;		/*pass constant part*/
   204   		*prlb++ = (extref<<3)|EXTREL;	/*ext ref*/
   205   		return;
   206   	}
   207   	ival =- (loctr+2);		/*calc relative offset*/
   208   	if(itype!=ITCN || reloc != rlflg) {
   209   		uerr(22);		/*invalid relative branch*/
   210   		ival = 0;
   211   	}
   212   	reloc = ABS;
   213   	if(p1inlen==4) {		/*long displacement*/
   214   		if(ival< (-32768L) || ival > (32767L))
   215   			uerr(22);
   216   		instrlen =+ 2;
   217   		*pins++ = ival;
   218   		*prlb++ = DABS;		/*data absolute*/
   219   	}
   220   	else {					/*short displacement*/
   221   		if (ival>127 || ival<-128)
   222   			uerr(22);
   223   		ins[0] =| (ival.wd2&0377);
   224   	}
   225   	if (!ival)	{	/* make it a nop */
   226   		opcpt = nopptr;
   227   		ins[0] = opcpt->vl1.wd2;
   228   		pins = &ins[1];
   229   		if (modelen==4) {
   230   			*pins++ = opcpt->vl1.wd2;
   231   			rlbits[1] = INSABS;
   232   		}
   233   	}
   234   	in_err++;	/* ignore extra eg. bra *+$d04(pc) vs. bra *+d04 */
   235   }
   236    
1File: PASS2.C                                                             Page       5
   237   /* format one -- add, sub, and, or, cmp, etc.*/
   238   /*  one operand must be a D reg (or A reg dest for add, sub, or cmp)*/
   239   opf1()
   240   {
   241   	register int *p;
   242    
   243   	if(get2ops())
   244   		return;
   245   	if (ins[0]==AND || ins[0]==OR)
   246   		if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
   247   			if (ins[0]==AND) opcpt = andiptr;
   248   			else opcpt = oriptr;
   249   			ins[0] = opcpt->vl1.wd2;
   250   			format = (opcpt->flags)&OPFF;
   251   			ccr_or_sr();
   252   			return;
   253   		}
   254   	p = f1mode;
   255   	if(ckdreg(&opnd[1])) {	/*destn is D reg*/
   256   		if((opcpt==andptr||opcpt==orptr)&&ckareg(&opnd[0]))	/*A source*/
   257   			uerr(20);
   258   		makef1(opnd[1].ea,p[modelen],&opnd[0]);	/*make instr*/
   259   		return;
   260   	}
   261   	else if(ckdreg(&opnd[0]) && memalt(&opnd[1])) {	/*source is D reg*/
   262   		if (pcea(&opnd[1])) uerr(10);
   263   		makef1(opnd[0].ea,p[modelen]+0400,&opnd[1]);
   264   		return;
   265   	}
   266   	else if(ckareg(&opnd[1])) {	/*A reg is dstn*/
   267   		if(opcpt==addptr)
   268   			opcpt = addaptr;
   269   		else if(opcpt==cmpptr)
   270   			opcpt = cmpaptr;
   271   		else if(opcpt==subptr)
   272   			opcpt = subaptr;
   273   		else {
   274   			uerr(20);
   275   			return;
   276   		}
   277   		format = (opcpt->flags)&OPFF;
   278   		opnd[1].ea =& 07;
   279   		p = f15mode;
   280   		makef1(opnd[1].ea,p[modelen],&opnd[0]);	/*make instr*/
   281   		return;
   282   	}
   283   	else if(!makeimm())		/*make an immediate instr*/
   284   		uerr(20);
   285   }
   286    
   287   /* format 2 -- addi, andi, subi, etc*/
   288   opf2()
   289   {
   290   	if(get2ops())
   291   		return;
   292   	if(ins[0]==ANDI || ins[0]==ORI || ins[0]==EORI) {
   293   		if(cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
   294   			ccr_or_sr();
   295   			return;
1File: PASS2.C                                                             Page       6
   296   		}
   297   	}
   298   	if(opnd[0].ea != IMM) {
   299   		uerr(9);
   300   		return;
   301   	}
   302   	if(!dataalt(&opnd[1]) || pcea(&opnd[1])) {
   303   		uerr(20);
   304   		return;
   305   	}
   306   	genimm();
   307   }
   308    
   309   /*format #3 -- move and movea*/
   310   opf3()
   311   {
   312   	register i,j,k;
   313    
   314   	if(get2ops())
   315   		return;
   316   	if(cksprg(&opnd[1],CCR)) {
   317   		ins[0] = MOVECCR;
   318   opf3l1:
   319   		if (modelen==1 || modelen==4) uerr(34);
   320   		if(anysprg(&opnd[0]))
   321   			uerr(20);
   322   		ins[0] =| opnd[0].ea;
   323   		if(!dataea(&opnd[0]))
   324   			uerr(9);
   325   		doea(&opnd[0]);
   326   		return;
   327   	}
   328   	if(cksprg(&opnd[1],SR)) {
   329   		ins[0] = MOVESR;
   330   		goto opf3l1;
   331   	}
   332   	if(cksprg(&opnd[0],SR)) {
   333   		if (modelen==1 || modelen==4)
   334   			uerr(34);
   335   		if(anysprg(&opnd[1]))
   336   			uerr(20);
   337   		ins[0] = SRMOVE | opnd[1].ea;
   338   		if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
   339   			uerr(10);
   340   		doea(&opnd[1]);
   341   		return;
   342   	}
   343   	if(cksprg(&opnd[0],USP)) {
   344   		if (modelen == 1)
   345   			uerr(34);	/* default is word, can't test */
   346   		if (!ckareg(&opnd[1]))
   347   			uerr(33);
   348   		ins[0] = MOVEUSP|8|(opnd[1].ea&7);
   349   		return;
   350   	}
   351   	if(cksprg(&opnd[1],USP)) {
   352   		if (modelen == 1)
   353   			uerr(34);	/* default is word, can't test */
   354   		if (!ckareg(&opnd[0]))
1File: PASS2.C                                                             Page       7
   355   			uerr(33);
   356   		ins[0] = MOVEUSP|(opnd[0].ea&7);
   357   		return;
   358   	}
   359   	k = ins[0];
   360   	ins[0] =| f3mode[modelen];
   361   	ckbytea();
   362   	ins[0] =| opnd[0].ea;		/*source ea*/
   363   	doea(&opnd[0]);
   364   	ins[0] =| (opnd[1].ea&7)<<9;	/*dest register*/
   365   	ins[0] =| (opnd[1].ea&070)<<3;	/*dest mode*/
   366   	doea(&opnd[1]);
   367   	if(k==MOVEA) {
   368   		if(dataea(&opnd[1]))
   369   			uerr(20);
   370   	}
   371   	else if((pcea(&opnd[1]) && dataea(&opnd[1])) || opnd[1].ea==IMM)
   372   		uerr(20);
   373   }
   374    
   375   /* format 4 -- abcd, sbcd */
   376   /* format 10 -- cmpm*/
   377   /* format 27 -- addx, subx */
   378   opf4()
   379   {
   380   	if(get2ops())
   381   		return;
   382   	if (format==27) { /*addx,subx add in size bits*/
   383   		ins[0] =| f1mode[modelen];
   384   	}
   385   	else if(format==10) {	/*cmpm*/
   386   		if((opnd[0].ea&070)!=INDINC || (opnd[1].ea&070)!=INDINC)
   387   			uerr(20);
   388   		ins[0] =| f1mode[modelen] | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
   389   		return;
   390   	}
   391   	if(ckdreg(&opnd[0]) && ckdreg(&opnd[1])) {
   392   		ins[0] =| ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
   393   		return;
   394   	}
   395   	if((opnd[0].ea&070)==DECIND && (opnd[1].ea&070)==DECIND) {
   396   		ins[0] =| 010 | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
   397   		return;
   398   	}
   399   	uerr(20);
   400   }
   401    
   402   /*format 5 -- div, mul*/
   403   /*format 26 -- cmp, chk */
   404   opf5()
   405   {
   406   	if(get2ops())
   407   		return;
   408   	if(!ckdreg(&opnd[1])) {
   409   		if(opcpt==cmpptr) {
   410   			if(!dataea(&opnd[1]))	/* [vlh] made define */
   411   				ins[0] =| f5amode[modelen];	/* was pumode */
   412   			else if(makeimm())
   413   				return;
1File: PASS2.C                                                             Page       8
   414   			else
   415   				uerr(20);
   416   		}
   417   		else
   418   			uerr(20);
   419   	}
   420   	if(opcpt==cmpptr) {
   421   		ins[0] =| f5mode[modelen];	/* was pumode */
   422   		ckbytea();
   423   	}
   424   	else if(!dataea(&opnd[0]))
   425   		uerr(20);
   426   	ins[0] =| (opnd[1].ea&7)<<9 | opnd[0].ea;
   427   	doea(&opnd[0]);
   428   }
   429    
   430   #define BTST	0000
   431   /* format 7 -- bit instrs -- btst, bclr, bset, etc*/
   432   opf7()
   433   {
   434   	if(get2ops())
   435   		return;
   436   	if(opnd[1].ea==IMM||(ins[0]!=BTST&&pcea(&opnd[1]))||ckareg(&opnd[1]))
   437   		uerr(20);
   438   	if(ckdreg(&opnd[0])) {
   439   		ins[0] =| (opnd[0].ea<<9)|0400;
   440   	}
   441   	else {		/*static bit #*/
   442   		if(opnd[0].con<0L || opnd[0].con>31 ||
   443   			(opnd[1].ea&INDIRECT&&opnd[0].con>7)) /* [vlh] */
   444   			uerr(23);
   445   		if(opnd[0].ea != IMM)
   446   			uerr(17);
   447   		ins[0] =| 04000;
   448   		dodisp(&opnd[0]);
   449   	}
   450   	if (modelen==1 && !(memea(&opnd[1])))	/*[vlh]*/
   451   			uerr(20);
   452   	else if (!(ckdreg(&opnd[1])) && modelen==4)
   453   		uerr(20);
   454   	ins[0] =| opnd[1].ea;
   455   	doea(&opnd[1]);
   456   }
   457    
   458   /* format 8 -- shifts and rotates*/
   459   opf8()
   460   {
   461   	register i;
   462    
   463   	getea(0);	/*get first operand*/
   464   	if(pitw >= pnite) {		/*end of all ops*/
   465   		if(ckdreg(&opnd[0])) {	/*shift dreg one bit*/
   466   			cpop01();		/*copy opnd 0 to 1*/
   467   			opnd[0].ea = IMM;
   468   			opnd[0].con = 1L;
   469   			if (!ckdreg(&opnd[1])) uerr(20);
   470   opf8l1:
   471   			if(opnd[0].con<1 || opnd[0].con>8)	/*[vlh legal range 1..8*/
   472   				uerr(37);
1File: PASS2.C                                                             Page       9
   473   			ins[0] =| ((opnd[0].con.wd2&7)<<9)|f1mode[modelen]|opnd[1].ea;
   474   			return;
   475   		}
   476   		i = (ins[0]&077)<<6;
   477   		ins[0] =& 0177700;
   478   		ins[0] =| 0300|i|opnd[0].ea;
   479   		if(!memalt(&opnd[0]) || pcea(&opnd[0]) || modelen != 2)
   480   			uerr(20);
   481   		doea(&opnd[0]);
   482   		return;
   483   	}
   484   	if(!ckcomma()) {
   485   		uerr(10);
   486   		return;
   487   	}
   488   	getea(1);		/*get second operand*/
   489   	if(!ckdreg(&opnd[1]))	/* [vlh] second operand must be dreg */
   490   		uerr(20);
   491   	if(ckdreg(&opnd[0])) {	/*first op is D reg*/
   492   		ins[0] =| (opnd[0].ea<<9)|040;	/*reg # and reg bit*/
   493   	}
   494   	else {
   495   		if(opnd[0].ea != IMM)
   496   			uerr(20);
   497   		goto opf8l1;
   498   	}
   499   	ins[0] =| f1mode[modelen] | opnd[1].ea;	/*put in size and reg #*/
   500   }
   501    
   502   /* format 9 -- jmp, jsr */
   503   /* format 14 -- stop */
   504   /* format 24 -- clr, neg, negx, not */
   505   /* format 25 -- s?? */
   506   /* format 29 -- pea */
   507   /* one operand instructions -- jmp, clr, neg, not, sge, etc.*/
   508   opf9()
   509   {
   510   	getea(0);
   511   	if(format==24) {	/*clr, not, etc*/
   512   		ins[0] =| f1mode[modelen];	/*add size bits*/
   513   		if(!dataalt(&opnd[0]) || pcea(&opnd[0]))
   514   			uerr(20);
   515   	}
   516   	else if(format==25) {	/*tas,scc, etc*/
   517   		if(ckareg(&opnd[0]) || pcea(&opnd[0]) || opnd[0].ea==IMM)
   518   			uerr(20);
   519   	}
   520   	else if(format==14) {		/*stop*/
   521   		if(modelen!=2 || opnd[0].ea!=IMM)
   522   			uerr(20);
   523   		doea(&opnd[0]);
   524   		return;
   525   	}
   526   	else if(!controlea(&opnd[0]))	/*jmp, jsr, etc*/
   527   		uerr(20);
   528   	ins[0] =| opnd[0].ea;
   529   	doea(&opnd[0]);
   530   }
   531    
1File: PASS2.C                                                             Page      10
   532   /* format 11 -- dbcc*/
   533   /* format 19 -- link*/
   534   opf11()
   535   {
   536   	if(get2ops())
   537   		return;
   538   	if(format==19) {		/*link*/
   539   		if(!ckareg(&opnd[0]))
   540   			uerr(33);
   541   		if(opnd[1].ea != IMM)
   542   			uerr(17);
   543   	}
   544   	else {
   545   		if(!ckdreg(&opnd[0]))
   546   			uerr(33);
   547   		if(opnd[1].drlc!=rlflg)	/*[vlh]don't chk opnd[1].ea!=LADDR||SADDR*/
   548   			uerr(22);
   549   		opnd[1].con =- (loctr+2L);
   550   		cksize(&opnd[1]);
   551   		opnd[1].drlc = ABS;		/*not relocatable*/
   552   	}
   553   	ins[0] =| opnd[0].ea&7;	/*put in reg #*/
   554   	dodisp(&opnd[1]);
   555   }
   556    
   557   /* format 12 -- exg*/
   558   opf12()
   559   {
   560   	register i;
   561    
   562   	if(get2ops())
   563   		return;
   564   	if(ckdreg(&opnd[0])) {
   565   		if(ckdreg(&opnd[1])) {	/*exchange D regs*/
   566   			ins[0] =| 0100 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
   567   			return;
   568   		}
   569   		if(ckareg(&opnd[1])) {	/*ins[0] <- A and D flag*/
   570   			ins[0] =| 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
   571   			return;
   572   		}
   573   	}
   574   	if(ckareg(&opnd[0])) {
   575   		if(ckareg(&opnd[1])) {	/*both a regs*/
   576   			ins[0] =| 0110 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
   577   			return;
   578   		}
   579   		if(ckdreg(&opnd[1])) {	/*A and D regs*/
   580   			i = opnd[0].ea;		/*exchg ea's*/
   581   			opnd[0].ea = opnd[1].ea;
   582   			opnd[1].ea = i;
   583   			ins[0] =| 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
   584   			return;
   585   		}
   586   	}
   587   	uerr(20);
   588   }
   589    
   590   /* format 13 -- ext, unlk*/
1File: PASS2.C                                                             Page      11
   591   /* format 18 -- trap*/
   592   /* format 28 -- swap */
   593   #define UNLK	047130
   594    
   595   opf13()
   596   {
   597   	getea(0);
   598   	if(format==18) {	/*trap*/
   599   		if(opnd[0].con<0 || opnd[0].con>15)
   600   			uerr(15);
   601   		ins[0] =| opnd[0].con.wd2;
   602   		return;
   603   	}
   604   	if(ins[0]==UNLK) {	/*unlk instr*/
   605   		if(!ckareg(&opnd[0]))
   606   			uerr(20);
   607   	}
   608   	else {
   609   		if(!ckdreg(&opnd[0]))
   610   			uerr(20);
   611   		if (format==13)		/* ext */
   612   			ins[0] =| f13mode[modelen];
   613   	}
   614   	ins[0] =| opnd[0].ea&7;
   615   }
   616    
   617   /* format 15 -- adda, cmpa, suba*/
   618   /* format 30 -- lea */
   619   opf15()
   620   {
   621   	register i;
   622    
   623   	if(get2ops())
   624   		return;
   625   	if(!ckareg(&opnd[1]))
   626   		uerr(33);
   627   	if(format==30) {
   628   		i = 0700;
   629   		if(!controlea(&opnd[0]))
   630   			uerr(20);
   631   	}
   632   	else
   633   		i = f15mode[modelen];
   634   	makef1(opnd[1].ea&7,i,&opnd[0]);
   635   	if (format==15 && opnd[0].ea != 071) cksize(&opnd[0]);
   636   }
   637    
   638   /*formats 16 and 17 -- addq, inc, subq, dec*/
   639   opf17()
   640   {
   641   	if(format==16) {	/*inc or dec*/
   642   		clrea(&opnd[0]);
   643   		opnd[0].ea = IMM;
   644   		opnd[0].con = 1L;
   645   		opnd[0].drlc = ABS;
   646   		getea(1);
   647   	}
   648   	else {
   649   		if(get2ops())
1File: PASS2.C                                                             Page      12
   650   			return;
   651   	}
   652   	if(opnd[0].ea != IMM || !altea(&opnd[1]) || pcea(&opnd[1]))
   653   		uerr(20);
   654   	if(opnd[0].con<=0 || opnd[0].con>8)
   655   		uerr(15);
   656   	if(modelen==1 && !dataea(&opnd[1]))
   657   		uerr(34);
   658   	ins[0] =| f1mode[modelen]|((opnd[0].con.wd2&7)<<9)|opnd[1].ea;
   659   	doea(&opnd[1]);
   660   }
   661    
   662   /* format 20 -- movem */
   663   int regmsk0[] {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
   664   				0100,040,020,010,4,2,1};
   665   int regmsk1[] {1,2,4,010,020,040,0100,0200,0400,01000,02000,04000,010000,
   666   				020000,040000,0100000};
   667   opf20()
   668   {
   669   	register dr;
   670   	register i,j;
   671    
   672   	dr = 0;
   673   	if(getreg() != -1 || pitw->itty == ITRM) {	/*regs to memory*/
   674   		if (pitw->itty != ITRM) {	/* [vlh] */
   675   			pitw--;
   676   			j = getrlist(regmsk0);
   677   		}
   678   		else {
   679   			j = pitw->itop;
   680   			pitw++;
   681   		}
   682   		if(!ckcomma())
   683   			uerr(10);
   684   	}
   685   	else
   686   		dr = 02000;
   687   	getea(0);
   688   	if(dr) {
   689   		if(!ckcomma())
   690   			uerr(10);
   691   		if (pitw->itty != ITRM)		/* [vlh] */
   692   			j = getrlist(regmsk1);	/*mem to regs*/
   693   		else {
   694   			j = pitw->itop;
   695   			j = fixmask(j);
   696   			pitw++;
   697   		}
   698   	}
   699   	else {
   700   		if(controlea(&opnd[0]))
   701   			j = fixmask(j);
   702   	}
   703   	i = opnd[0].ea&070;
   704   	if(!controlea(&opnd[0]) && i!=INDINC && i!=DECIND)
   705   		uerr(20);
   706   	if(modelen==4)	/*long*/
   707   		ins[0] =| 0100;
   708   	ins[0] =| opnd[0].ea|dr;
1File: PASS2.C                                                             Page      13
   709   	*pins++ = j;			/*reg mask*/
   710   	*prlb++ = DABS;
   711   	instrlen =+ 2;
   712   	doea(&opnd[0]);
   713   	if (!dr) {	/* 1st argument (2nd is reg list) */
   714   		if (pcea(&opnd[0]) || (opnd[0].ea&070)==INDINC)
   715   			uerr(20);	/* xx(pc), xx(pc,dx), -(ax) */
   716   	}
   717   	else	/* 2nd argument (1st is reg list) */
   718   		if ((opnd[0].ea&070)==DECIND)
   719   			uerr(20);	/* (ax)+ */
   720   }
   721    
   722   /*
   723    * get a list of registers for the movem instr
   724    * call with:
   725    *	ptr to reg-to-mem or mem-to-reg array of bits
   726    */
   727   getrlist(ap)
   728   int *ap;
   729   {
   730   	register int *p,i,j;
   731   	register int mask;
   732    
   733   	p = ap;
   734   	mask = 0;
   735   	while((i=getreg()) != -1) {
   736   		if(ckitc(pitw,'-')) {
   737   			pitw++;
   738   			if((j=getreg()) == -1) {
   739   				uerr(40);
   740   				break;
   741   			}
   742   			while(i<=j)
   743   				mask =| p[i++];
   744   		}
   745   		else
   746   			mask =| p[i];
   747   		if(ckitc(pitw,'/'))
   748   			pitw++;
   749   		else
   750   			break;
   751   	}
   752   	if(!mask)
   753   		uerr(40);
   754   	return(mask);
   755   }
   756    
   757   /*reverse a movem register mask for control ea to memory*/
   758   fixmask(msk)
   759   {
   760   	register i,j,k;
   761    
   762   	k = (msk&1) ? 0100000 : 0;
   763   	i = 2;
   764   	j = 040000;
   765   	while(i) {
   766   		if(msk&i)
   767   			k =| j;
1File: PASS2.C                                                             Page      14
   768   		i =<< 1;
   769   		j =>> 1;
   770   	}
   771   	return(k);
   772   }
   773    
   774   /* format 21 -- movep*/
   775   opf21()
   776   {
   777   	register m,d;
   778   	register char *p;
   779    
   780   	if(get2ops())
   781   		return;
   782   	if(ckdreg(&opnd[0])) {	/*d reg source*/
   783   		m = 0600;
   784   		d = opnd[0].ea;
   785   		p = &opnd[1];
   786   	}
   787   	else if(ckdreg(&opnd[1])) {		/*d reg dest*/
   788   		m = 0400;
   789   		d = opnd[1].ea;
   790   		p = &opnd[0];
   791   	}
   792   	else {
   793   		uerr(20);
   794   	}
   795   	if((p->ea&070) != INDDISP)
   796   		uerr(20);
   797   	if(modelen == 4)
   798   		m =| 0100;
   799   	ins[0] =| (d<<9)|m|(p->ea&7);
   800   	*pins++ = p->con.wd2;
   801   	*prlb++ = p->drlc;
   802   	instrlen =+ 2;
   803   }
   804    
   805   /* format 22 -- moveq*/
   806   opf22()
   807   {
   808   	if(get2ops())
   809   		return;
   810   	if(opnd[0].ea != IMM)
   811   		uerr(17);
   812   	if(opnd[0].con>255L || opnd[0].con<-256L)
   813   		uerr(15);
   814   	if(!ckdreg(&opnd[1]))
   815   		uerr(33);
   816   	ins[0] =| (opnd[1].ea<<9) | (opnd[0].con.wd2&0377);
   817   }
   818    
   819   /* format 23 -- eor*/
   820   opf23()
   821   {
   822   	if(get2ops())
   823   		return;
   824   	if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
   825   		opcpt = eoriptr;
   826   		ins[0] = opcpt->vl1.wd2;
1File: PASS2.C                                                             Page      15
   827   		format = (opcpt->flags)&OPFF;
   828   		ccr_or_sr();
   829   		return;
   830   	}
   831   	if(!ckdreg(&opnd[0])) {
   832   		if(makeimm())	/*must be immediate*/
   833   			return;
   834   		uerr(20);		/*or error*/
   835   	}
   836   	if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
   837   		uerr(20);
   838   	ins[0] =| (opnd[0].ea<<9)|f23mode[modelen]|opnd[1].ea;
   839   	doea(&opnd[1]);
   840   }
   841    
