home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_100
/
190_01
/
bc.c
< prev
next >
Wrap
Text File
|
1985-11-14
|
17KB
|
861 lines
/******************************************************************
bc.c, code building function of as68 assembler
*/
/* (C) Copyright 1982 Steve Passe */
/* All Rights Reserved */
/* version 1.00 */
/* created 10/21/82 */
/* version 1.01
8/30/83 ver. 1.01 modified for Aztec ver. 1.05g smp
*/
/* begincode */
/* includes */
#define AZTECZII 1
#ifndef AZTECZII
#include <stdio.h>
#else
#include "stdio.h" /* with aztecII compiler */
#endif
#include "b:as68.h"
/* externals */
extern char pass; /* present pass number, 1 or 2 */
extern unsigned line_count; /* line number of source file */
extern long loc_counter; /* address to assemble obj code */
extern int loc_plus; /* increment to loc counter */
extern FLAG abs_long; /* default to absolute long add.*/
extern FLAG rorg; /* in pc relative mode */
extern char label[32]; /* buffer for label from preparse */
extern char instr[33]; /* buffer for mnem, psdo or macro */
extern struct _mtable mtable[]; /* mnemonic lookup table */
extern struct _mvalue mvalue[]; /* mnemonic code table */
extern struct _oprnd op1, op2; /* structs to hold operand val */
extern char code[]; /* code array */
p1_mnem(mt)
struct _mtable *mt;
{
int result, index;
if ((index = match(mt)) == ERROR) {
/** flush error stack someday? */
return ERROR;
}
switch (result = mvalue[index]._opc_len) { /* determine code length... */
case 1:
case 2:
case 3:
break;
case 12: /* _imd not contained in opcode */
case 13:
result -= 10; /* strip '10' flag */
result += p1_codelen(&op2); /* add second operand length */
break;
case 0: /* gotta figure it out */
if (/**rorg**/ op1._rel_lbl && mvalue[index]._optyp1 == _sadr
&& (op1._typ == _address || op1._typ == _d16_ani)) {
result = 2 + p1_codelen(&op2); /* 1 for opcode, 1 for raddr */
}
else result = p1_codelen(&op1) + p1_codelen(&op2) + 1; /* 1 for code */
break;
}
loc_plus = result * 2;
return result;
}
p1_codelen(op)
struct _oprnd *op;
{
int result;
switch (op->_typ) {
case _address:
result = (op->_long_val) ? 2 : 1;
break;
case _d16_ani:
case _d8_anx:
case _labeli:
case _reglst:
case _label: /* needed? */
result = 1;
break;
default:
result = 0;
}
return result;
}
p2_mnem(mt)
struct _mtable *mt;
{
register int x; /* scratch */
int index ; /* index to mvalue */
int result;
for (x = 0; x < 10; ++x) { /* init code array to 0 */
code[x] = 0;
}
if ((index = match(mt)) == ERROR) {
dump_code(CODE, code, 0);
return ERROR;
}
code[0] = mvalue[index]._opcb1; /* get opcode */
code[1] = mvalue[index]._opcb2; /* get opcode */
if ((result = (*mvalue[index]._p2_action)()) < 0) { /* call funct */
err_out(result);
loc_plus = 0;
}
else loc_plus = ++result * 2; /* bytes created */
dump_code(CODE, code, loc_plus); /* send them */
return result; /* words created */
}
match(mt)
struct _mtable *mt;
{
int index; /* index to mvalue */
int type1, type2; /* operand types */
if ((type1 = op_eval(&op1)) < 0) { /* legal type found? */
err_out(BAD_OP1); /* first op bad */
}
if ((type2 = op_eval(&op2)) < 0) { /* second op? */
err_out(BAD_OP2); /* no good */
}
if (type1 < 0 || type2 < 0) {
return ERROR; /* use NULL opcode */
}
if ((index = type_search(mt, type1, type2)) <=0) {
switch (index) {
case ILGL_OP1:
err_out(ILGL_OP1); /* no good */
return ERROR;
case ILGL_OP2:
err_out(ILGL_OP2); /* no good */
return ERROR;
default:
return ERROR;
}
}
return index;
}
type_search(mt, type1, type2)
struct _mtable *mt;
int type1;
int type2;
{
register int x, y; /* count and index */
char t1, t2; /* temp for array value */
for (x = mt->_mvc, y = mt->_mvi; x; --x, ++y) { /* search */
/* find op1 match... */
if (((t1 = mvalue[y]._optyp1) == type1) /* if exact match */
|| ((!(t1 & ~0xf0)) && (t1 & type1))) { /* or classtyp and match */
/* search for second match */
for ( ; (mvalue[y]._optyp1 == t1) && x; --x, ++y) {
if (((t2 = mvalue[y]._optyp2) == type2) /* 2nd matches */
|| ((!(t2 & ~0xf0)) && (t2 & type2))) { /* or typ & match */
return y; /* found a match */
}
}
return ILGL_OP2;
}
}
return ILGL_OP1;
}
/* mask 3 bit immediate data from op1 over bits 3-1 of code [0] */
bbb(op)
struct _oprnd *op;
{
if (op->_data & ~7) return ERR_BBB;
code[0] |= (op->_data << 1);
return NULL;
}
/* first ext word holds bit number (7/31) from first operand */
bbbx(size, op)
int size;
struct _oprnd *op;
{
switch (size) {
case 3:
if (op->_data & ~7L) return ERR_BX3; /* range? */
case 5:
if (op->_data & ~31L) return ERR_BX5;
code[3] = op->_data;
return 1; /* 1 ext word */
default:
return ERR_BX;
}
}
/** mask bits 3-1 of first byte with op1, 8 = 00 */
ccc(op)
struct _oprnd *op;
{
if (op->_data < 1L || op->_data > 8L) return ERR_CCC;
code[0] |= (op->_data << 1) & 0x0f;
/** if (op->_data != 8L) code[0] |= op->_data << 1; **/
return NULL; /* no words added */
}
/* mask bits 3-1 of first byte, or bits 2-0 of second, with op reg */
rsd(byt, op)
int byt;
struct _oprnd *op;
{
code[byt] |= (byt) ? op->_reg : op->_reg << 1;
return NULL;
}
/* register mask list from op into ext */
mmkk(order, op)
char order;
struct _oprnd *op;
{
register int x;
unsigned u1 = 0;
unsigned m1 = 0x0001;
unsigned m2 = 0x8000;
switch (order) {
case '>':
code[2] = op->_reg_list >> 8; /* high byte */
code[3] = op->_reg_list; /* low byte */
return 1;
case '<':
for (x = 15; x >= 0; --x) {
u1 |= (op->_reg_list & (m1 << x)) ? (m2 >> x) : 0;
}
code[2] = u1 >> 8; /* high byte */
code[3] = u1; /* low byte */
return 1;
default:
return ERR_MK;
}
}
/* combined e, f, g, h, and j routines, 12/4/82 */
efghj(arg, i, op)
char arg;
int i;
struct _oprnd *op;
{
int len, displ;
switch (op->_typ) {
case _ani: /* (an) */
if (arg == 'g') {
code[0] |= (op->_reg << 1);
code[1] |= 0x80;
}
else {
code[1] |= (0x10 | op->_reg);
}
return NULL;
case _pd_ani: /* -(an) */
switch (arg) {
case 'g':
code[0] |= (0x01 | op->_reg << 1);
return NULL;
case 'j': return ERR_J;
case 'h': return ERR_H;
default:
code[1] |= (0x20 | op->_reg);
return NULL;
}
case _ani_pi: /* (an)+ */
switch (arg) {
case 'g':
code[0] |= (op->_reg << 1);
code[1] |= 0xc0;
return NULL;
case 'j': return ERR_J;
case 'h': return ERR_H;
default:
code[1] |= (0x18 | op->_reg);
return NULL;
}
case _d16_ani: /* d16(an) */
switch (arg) {
case 'e':
case 'j':
if (/**rorg**/ op->_rel_lbl) {
op->_ireg = op->_reg; /* reg is an index */
op->_iregtyp = op->_regtyp; /* move type */
op->_displ -= (loc_counter + 2); /* make pc relative */
code[1] |= 0x3b;
return _d8_i(i, op); /* indexed label */
}
break;
case 'g':
code[0] |= (0x01 | op->_reg << 1);
code[1] |= 0x40;
return _d16(i, op);
}
code[1] |= (0x28 | op->_reg);
return _d16(i, op);
case _d8_anx: /* d8(an,i) */
if (arg == 'g') {
code[0] |= (0x01 | op->_reg << 1);
code[1] |= 0x80;
}
else {
code[1] |= (0x30 | op->_reg);
}
return _d8_i(i, op);
case _address: /* abs. add., short or long, or label if _rel_lbl */
switch (arg) {
case 'e':
case 'j':
if (/**rorg**/ op->_rel_lbl) {
code[1] |= 0x3a;
op->_displ = op->_addr - (loc_counter + 2); /* rel. to pc */
return _d16(i, op); /* finish as 'label' */
}
break;
case 'g':
code[1] |= 0xc0;
if (op->_long_val) {
code[0] |= 0x03;
code[i++] = op->_addr >> 24;
code[i++] = op->_addr >> 16;
len = 2;
}
else {
code[0] |= (0x01);
len = 1;
}
code[i++] = op->_addr >> 8;
code[i] = op->_addr;
return len;
}
if (op->_long_val) {
code[1] |= (0x39);
code[i++] = op->_addr >> 24;
code[i++] = op->_addr >> 16;
len = 2;
}
else {
code[1] |= (0x38);
len = 1;
}
code[i++] = op->_addr >> 8;
code[i] = op->_addr;
return len;
case _label: /* relative label */
switch (arg) {
case 'g': return ERR_G;
case 'f': return ERR_F;
case 'h': return ERR_H;
default:
code[1] |= 0x3a;
op->_displ -= (loc_counter + 2); /* rel. to pc */
return _d16(i, op);
}
case _labeli: /* label(i) */
switch (arg) {
case 'g': return ERR_G;
case 'f': return ERR_F;
case 'h': return ERR_H;
default:
code[1] |= 0x3b;
op->_displ -= (loc_counter + 2); /* rel. to pc */
return _d8_i(i, op);
}
default:
return ERR_EFGHJ;
}
}
_d16(i, op)
int i;
struct _oprnd *op;
{
if ((op->_displ > 32767) || (op->_displ < -32768)) return ERR_D16;
code[i] = op->_displ >> 8; /* displacement... */
code[i+1] = op->_displ; /* ...into ext */
return 1; /* 1 ext word returned */
}
_d8_i(i, op)
int i;
struct _oprnd *op;
{
if ((op->_displ > 127) || (op->_displ < -128)) return ERR_D8I;
if (op->_iregtyp == 'a') code[i] |= 0x80; /* index is addr reg */
code[i] |= (op->_ireg << 4); /* add index reg # */
if (op->_inxl) code[i] |= 0x08; /* mark long index size */
code[i+1] = op->_displ; /* 8 bit displacement */
return 1;
}
/* 8/16 bit address displacement */
xxxx(size, op)
int size;
struct _oprnd *op;
{
int displ;
switch (op->_typ) {
case _address: /* absolute address */
displ = op->_addr - (loc_counter + 2); /* make relative to pc */
break;
case _label: /* relative address */
displ = op->_displ;
break;
default: /* somethings wrong... */
return ERR_XXX;
}
switch (size) {
case 8:
if (displ > 127 || displ < -128) return ERR_XX; /* check range */
code[1] |= displ; /* put into array */
return NULL; /* no ext word */
case 16:
if (displ > 32766 || displ < -32768) return ERR_XXXX; /* range */
code[2] = displ >> 8;
code[3] = displ;
return 1; /* 1 ext word returned */
default:
return ERR_XXX;
}
}
/** */
yy(op)
struct _oprnd *op;
{
if (op->_data > 255L || op->_data < -128L) return ERR_Y;
code[1] = op->_data;
return NULL; /* no ext word */
}
oyz(size, op)
int size;
struct _oprnd *op;
{
switch (size) {
case 8:
if (op->_data > 255L || op->_data < -128L) return ERR_OY;
code[3] = op->_data;
return 1; /* one ext word added */
case 16:
if (op->_data > 65535L || op->_data < -32768L) return ERR_YY;
code[2] = op->_data >> 8;
code[3] = op->_data;
return 1; /* one ext word added */
case 32:
code[2] = op->_data >> 24;
code[3] = op->_data >> 16;
code[4] = op->_data >> 8;
code[5] = op->_data;
return 2;
default:
return ERR_OYZ;
}
}
/*
byte 1 byte 2 byte 3 byte 4 byte 5 byte 6 byte 7 byte 8 byte 9 byte 10
*/
/* none none */
nn()
{
return NULL; /* no action required */
}
/* none none zero yy */
nnoy()
{
return oyz(8, &op1); /* 8 bits imd data */
}
/* none none yyyy */
nnyy()
{
return oyz(16, &op1); /* 16 bits imd data */
}
/* none xx */
nx()
{
return xxxx(8, &op1); /* 16 bit displ from op1 */
}
/* none none xxxx */
nnxx()
{
return xxxx(16, &op1); /* 16 bit displ from op1 */
}
/* none ddd */
nd()
{
return rsd(1, &op1); /* dest reg from op1 into byte 1 */
}
nd2()
{
return rsd(1, &op2); /* dest reg from op2 into byte 1 */
}
/* none ddd zero bbbbb */
ndob()
{
rsd(1, &op2); /* dest reg from op2 into byte 1 */
return bbbx(5, &op1); /* bit field spec into first ext */
}
/* none ddd kkkk */
ndkk()
{
rsd(1, &op2); /* dest reg from op2 into byte 1 */
return mmkk('<', &op1); /* reglist from op1 into ext */
}
/* none ddd zero yy */
ndoy()
{
rsd(1, &op2); /* dest reg from op2 into byte 1 */
return oyz(8, &op1); /* 8 bits imd data */
}
/* none ddd yyyy */
ndyy()
{
rsd(1, &op2); /* dest reg from op2 into byte 1 */
return oyz(16, &op1); /* 16 bits of immediate data */
}
/* none ddd yyyy zzzz */
ndyz()
{
rsd(1, &op2); /* dest reg from op2 into byte 1 */
return oyz(32, &op1); /* 32 bits of immediate data */
}
/* none eeeeee [ext] [ext] */
ne()
{
return efghj('e', 2, &op1);
}
/* none ffffff [ext] [ext] */
nf()
{
return efghj('f', 2, &op1);
}
nf2()
{
return efghj('f', 2, &op2);
}
/* none ffffff zero bbb [ext] [ext] */
nfob()
{
bbbx(3, &op1);
return (efghj('f', 4, &op2) + 1);
}
/* none ffffff zero yy [ext] [ext] */
nfoy()
{
oyz(8, &op1); /* 8 bits imd data */
return (efghj('f', 4, &op2) + 1); /* op2 destination address */
}
/* none ffffff yyyy [ext] [ext] */
nfyy()
{
oyz(16, &op1); /* 16 bits imd data */
return (efghj('f', 4, &op2) + 1); /* op2 destination address */
}
/* none ffffff yyyy zzzz [ext] [ext] */
nfyz()
{
oyz(32, &op1); /* 32 bits imd data */
return (efghj('f', 6, &op2) + 2); /* op2 destination address */
}
/* none hhhhhh mmmm [ext] [ext] */
nhmm()
{
mmkk('>', &op1); /* reglist from op1 into ext */
return (efghj('h', 4, &op2) + 1); /* op2 destination address */
}
/* none jjjjjj [ext] [ext] */
nj()
{
return efghj('j', 2, &op1);
}
/* none jjjjjj mmmm [ext] [ext] */
njmm()
{
mmkk('>', &op2); /* reglist from op2 into ext */
return (efghj('j', 4, &op1) + 1);
}
/* none rrr */
nr()
{
return rsd(1, &op1); /* source reg from op1 into byte 1 */
}
nr2()
{
return rsd(1, &op2); /* source reg from op2 into byte 1 */
}
/* none rrr xxxx */
nrxx()
{
rsd(1, &op1); /* source reg from op1 into byte 1 */
return xxxx(16, &op2); /* 16 bit displ from op1 */
}
/* none sss [same as 'none rrr':nr()] */
/* none sss mmmm */
nsmm()
{
rsd(1, &op1); /* source reg from op1 into byte 1 */
return mmkk('>', &op2); /* reglist from op1 into ext */
}
/* none vvvv */
nv()
{
if (op1._data & ~15l) return ERR_V;
code[1] |= op1._data;
return NULL;
}
/* bbb ddd */
/* same as ccc ddd (sort of) */
/* bbb ffffff [ext] [ext] */
/* bbb is a misnomer for these two... */
cf()
{
ccc(&op1);
return efghj('f', 2, &op2);
}
/* ccc ddd */
cd()
{
ccc(&op1);
return rsd(1, &op2);
}
/* ddd none zero yy */
dnoy()
{
rsd(0, &op2);
return oyz(8, &op1); /* 8 bits of immediate data */
}
/* ddd none yyyy */
dnyy()
{
rsd(0, &op2);
return oyz(16, &op1); /* 16 bits of immediate data */
}
/* ddd none yyyy zzzz */
dnyz()
{
rsd(0, &op2);
return oyz(32, &op1); /* 32 bits of immediate data */
}
/* ddd eeeeee [ext] [ext] */
de()
{
rsd(0, &op2); /* dest reg from op2 into byte 1 */
return efghj('e', 2, &op1);
}
/* ddd jjjjjj [ext] [ext] */
dj()
{
rsd(0, &op2);
return efghj('j', 2, &op1);
}
/* ddd rrr */
dr()
{
rsd(0, &op2);
return rsd(1, &op1); /* source reg from op1 into byte 1 */
}
/* ddd sss [same as 'ddd rrr': dr()] */
/* ddd sss xxxx */
dsxx()
{
rsd(0, &op2);
rsd(1, &op1); /* source reg from op1 into byte 1 */
return xxxx(16, &op1); /* 16 bit displ from op1 */
}
/* ddd yy */
dy()
{
rsd(0, &op2);
return yy(&op1);
}
/* gggggg none zero yy [ext] [ext] */
gnoy()
{
oyz(8, &op1); /* 8 bits of immediate data */
return (efghj('g', 4, &op2) + 1);
}
/* gggggg none yyyy [ext] [ext] */
gnyy()
{
oyz(16, &op1); /* 16 bits of immediate data */
return (efghj('g', 4, &op2) + 1);
}
/* gggggg none yyyy zzzz [ext] [ext] */
gnyz()
{
oyz(32, &op1); /* 32 bits of immediate data */
return (efghj('g', 6, &op2) + 2);
}
/* gggggg eeeeee [exts] [exts] [extd] [extd] */
ge()
{
int temp;
temp = efghj('e', 2, &op1);
return (efghj('g', 2 + (temp * 2), &op2) + temp);
}
/* gggggg sss [ext] [ext] */
gs()
{
rsd(1, &op1);
return efghj('g', 2, &op2);
}
/* rrr ddd */
rd()
{
rsd(0, &op1);
return rsd(1, &op2);
}
/* rrr ffffff [ext] [ext] */
rf()
{
rsd(0, &op1);
return efghj('f', 2, &op2);
}
/* sss ddd [same as 'rrr ddd': rd()] */
/* sss ddd xxxx */
sdxx()
{
rsd(0, &op1); /* source reg from op1 into byte 1 */
rsd(1, &op2);
return xxxx(16, &op2); /* 16 bit displ from op2 */
}
/* sss ffffff [ext] [ext] */
sf()
{
rsd(0, &op1); /* source reg from op1 into byte 0 */
return efghj('f', 2, &op2);
}
/* endcode */
16 bits of immediate data */
return (efghj('g',