// CLASS - the 1LT8 Assembler
// written by Lutz Vieweg 1991-1994
//
// This source is based on the original GFA-BASIC version
// of CLASS I wrote 3 years ago. The consequences are:
//
// - the programming style looks partly awful. The most part of the
// conversion from GFA-BASIC was done by search & replace,
// so the program has still some typical structures of a BASIC
// program.
//
// - the code is not very efficient. Luckily, assembling is not
// such a time critical task...
//
// - if macro-support is enabled ("-macros"), the exit is currently
// "dirty", memory resources are not freed by the program.
// That means: DON'T USE "-macros" ON A SYSTEM WITHOUT
// RESOURCE-TRACKING. I'll fix this later.
//
// For more information, look into class.doc
// The class "Str" is used to emulate GFA-BASIC strings,
// they can be of arbitrary size (not limited to 32767 byte
// as the "String" class from libg++.a), and they may contain
// zeroes.
#include <Str.h>
// NibStr hold strings of nibbles
#include "NibStr.h"
#include "SourceLine.h"
// Symbol and ObjectFile classes are defined here
#include "object.h"
// floating-point parsing routines written by Alex Ramos
#include "fp_support.h"
// We do our I/O via streams
#include <iostream.h>
#include <fstream.h>
// Bstreams are the (re-)storable variant of streams
#include <Bstream.h>
// a siple error-handler, should be used more often when
// the code is finally cleaned up
#include <set_error.h>
extern "C" {
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h> // need sscanf() from there
#ifndef hpux // HP-UX includes are prepared for inclusion from C++
#include <math.h>
#endif
}
#ifdef hpux
#include <math.h>
#endif
extern const char * version_tag;
// global variable en masse - awful, isn't it? :(
ObjectFile obj;
AVLTree<Symbol> l_arr;
List<SourceLine> src;
ListItem<SourceLine> * akt_line;
int line;
bool verbose = 0;
Str last_ext_ref = "*";
bool last_exp_had_lbl = false; // true if last evaluated expr. contained a label
unsigned long adr = 0;
unsigned long nib_len = 0;
Str * m_name;
Str * m_txt;
Str * m_para;
Str last_label;
Str p1;
Str p2;
Str src_name;
Str incdir_name;
int base_add = 0;
bool ul_list = false;
bool exe_flag = false;
bool tmp_lbl = false;
int max_macros = 100;
int macros;
int mac_count = 0;
bool no_mac = true;
static const char rev_nibs[16] = {
// 0 1 2 3 4 5 6 7 8 9 a b c d e f
0x00,0x08,0x04,0x0c,0x02,0x0a,0x06,0x0e,0x01,0x09,0x05,0x0d,0x03,0x0b,0x07,0x0f
};
Str no_ext(const Str & a) {
unsigned long i = a.rindex('.');
unsigned long j = a.rindex('/');
if ( i != (unsigned long)~0 && (j == (unsigned long)~0 || j < i) ) {
return a.before(i);
} else {
return a;
}
}
Str nparas(Str & x) {
bool f;
unsigned long i;
static Str a;
if ( ! x.length() ) {
return x;
} else {
char * c = (char *)x;
char z = 0;
for ( i=0; i < x.length() ; i++) {
z = *c++;
if ( (z != 32 && z!=9) || z==59 ) break;
}
if ( i==x.length() || z==59 ) {
x = "";
return x;
} else {
x = x.after(i-1);
}
if ( x == "" ) {
return x;
} else {
f = true;
char * c = (char *)x;
char z = 0;
for ( i=0; i < x.length(); i++) {
z = *c++;
if ( z==34 ) {
f = !f;
}
if ( f ) {
if ( z==44 || z==9 || z==59 || z==32 ) break;
}
}
if ( i==x.length() ) {
a = x;
x = "";
return a;
} else {
a = x.left(i);
if ( z==59 ) {
x = "";
} else {
x = x.after(i);
i++;
}
return a;
}
}
}
}
Str & npara(Str & x) {
int i;
static Str a;
if ( ! x.length() ) {
a.clear();
return a; // Str((unsigned long)0);
} else {
i = x.index((char)1);
a = x.before(i);
x = x.after(i);
return a;
}
}
int nrof_paras(const Str & x) {
unsigned long i;
int c = 0;
if ( x.length() ) {
for ( i=0; i < x.length(); i++ ) {
if (x.chr(i) == 1) c++;
}
return c;
} else {
return 0;
}
}
/*
inline Str nword(Str & x) {
return x.next_word();
}
*/
int error_count = 0;
void norm_err(const Str & err) {
int i;
int o;
Str f;
Str a;
++error_count;
cerr << "ERROR: " << err << '\n';
if (!akt_line) return;
o = -1;
ListItem<SourceLine> * err_line = akt_line;
for (i = line; i >= 0; i--) {
if ( err_line->obc == "AKTFILE" ) break;
o++;
err_line = err_line->get_prev();
}
a = err_line->para;
f = npara(a);
i = o + npara(a).val();
cerr << "FILE: '" << f << "' LINE: " << i << '\n';
akt_line->obc = "";
akt_line->para = "";
akt_line->encoded = true;
}
void ill_siz_err(void) {
norm_err("illegal size extension to " + akt_line->obc);
}
void op_rng_err(void) {
norm_err("operand out of range for " + akt_line->obc);
}
void ill_add_err(void) {
norm_err("illegal adressing mode for " + akt_line->obc );
}
void fatal_err(const Str & err) {
set_error("FATAL ERROR: ", err);
}
void insert_imm_val (unsigned long a, const NibStr & ns, bool reloc_demand = false);
void insert_imm_val (unsigned long a, const NibStr & ns, bool reloc_demand) {
if (last_ext_ref.length()) {
obj.imports.add_tail(Import(a, ns.length(), last_ext_ref, reloc_demand));
} else {
if (reloc_demand) {
obj.relocs.add_tail(a);
}
}
obj.body.insert(a, ns);
last_ext_ref = "*";
}
void insert_imm_adr (unsigned long a, const NibStr & ns, bool reloc_demand) {
if (last_ext_ref.length()) {
obj.imports.add_tail(Import(a, ns.length(), last_ext_ref, reloc_demand));
} else {
if (last_exp_had_lbl) {
obj.relocs.add_tail(a);
}
}
obj.body.insert(a, ns);
last_ext_ref = "*";
}
double eval_d(Str & e, int & s);
unsigned long long eval_i(Str & e, int & s);
Symbol * find_label_p(const Str & lname, int & s, Str & err) {
Str l(lname);
if ( tmp_lbl ) {
if ( l.chr(0) == '.' ) {
l=last_label+l+".";
}
}
AVLItem<Symbol> * p = l_arr.find(Symbol(l));
if (p == 0) {
err = "undefined label '"+l+"'";
s = -1;
return 0;
} else {
if ( p->resolved ) {
if (p->external) {
if (last_ext_ref.length()) {
s = -1;
err = "no (further) external reference allowed here";
return 0;
} else {
last_ext_ref = l;
p->accessed = true;
return 0;
}
} else {
p->accessed = true;
return p;
}
} else {
s = 0;
return 0;
}
}
}
double find_label_d(const Str & lname, int & s, Str & err) {
Symbol * p = find_label_p(lname, s, err);
if (!p) return 0;
if (! p->isfloat) {
err = "cannot use integer value in floating point expression";
s = -1;
return 0;
}
return p->fvalue;
}
unsigned long long find_label_i(const Str & lname, int & s, Str & err) {
Symbol * p = find_label_p(lname, s, err);
if (!p) return 0;
if (p->isfloat) {
err = "cannot use floating point value in integer expression";
s = -1;
return 0;
}
if (! p->numerical) {
last_exp_had_lbl = true;
}
return p->ivalue;
}
double use_val_d(Str & e, int & s, Str & err) {
double x;
Str a;
unsigned long i;
for (i = 0; i < e.length(); i++) {
bool flag = false;
switch (e.chr(i)) {
case '+':
case '-':
case '*':
case '/':
case '\\':
case '&':
case '|':
case '(':
case ')':
case ' ':
case ',':
flag = true;
break;
}
if (flag) break;
}
a = e.left(i);
e = e.after(i-1);
x = atof((char *)a);
return x;
}
unsigned long long use_val_i(Str & e, int & s, Str & err) {
unsigned long long x;
Str a;
unsigned int i;
for (i = 0; i < e.length(); i++) {
bool flag = false;
switch (e.chr(i)) {
case '+':
case '-':
case '*':
case '/':
case '\\':
case '&':
case '|':
case '(':
case ')':
case ' ':
case ',':
flag = true;
break;
}
if (flag) break;
}
a = e.left(i);
e = e.after(i-1);
x = a.vall();
return x;
}
long big_endian(const char * lword) {
static int is_big_endian = -1;
if (is_big_endian > 0) {
return *((long *)lword);
} else if (is_big_endian == 0 ) {
return (*lword & 0xff) | ((*(lword+1) << 8) & 0xff00) |
((*(lword+1) << 16) & 0xff0000) | ((*(lword+1) << 24) & 0xff000000);
} else {
long test = 0;
*((char *)&test) = 1;
is_big_endian = (test == 1)? 0 : 1;
return big_endian(lword);
}
}
double get_val_d(Str & e, int & s, Str & err) {
double x;
Str a;
switch (e.chr(0)) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return use_val_d(e,s,err);
case '$':
err = "hex numbers for floating-point constants not allowed";
s = -1;
x = 0;
return x;
case '%':
err = "bin numbers for floating-point constants not allowed";
s = -1;
x = 0;
return x;
case 34:
err = "characters for floating-point constants not allowed";
s = -1;
x = 0;
return x;
case '(':
e = e.after(0);
x = eval_d(e,s);
return x;
case '-':
e = e.after(0);
x = get_val_d(e,s,err);
x = -x;
return x;
default:
unsigned int i;
for (i = 0; i < e.length(); i++) {
bool flag = false;
switch (e.chr(i)) {
case '+':
case '-':
case '*':
case '/':
case '\\':
case '&':
case '|':
case '(':
case ')':
flag = true;
break;
}
if (flag) break;
}
a = e.left(i);
e = e.after(i-1);
x = find_label_d(a,s,err);
return x;
}
}
unsigned long long get_val_i(Str & e, int & s, Str & err) {
unsigned long long x;
Str a;
unsigned long j;
switch (e.chr(0)) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return use_val_i(e,s,err);
case '$':
e = "0x"+e.after(0);
return use_val_i(e,s,err);
case '%':
e = "0b"+e.after(0);
return use_val_i(e,s,err);
case 34:
j = (e.after(0)).index((char)34) + 1;
if ( j == (unsigned long)~0 ) {
err = "missing quotation mark in '"+e+"'";
s = -1;
x = 0;
} else {
a = e.sub(1,j);
e = e.after(j);
if ( a.length() > 4 || a.length()==0 ) {
err = "operand '"+a+"' out of range";
s = -1;
x = 0;
} else {
char tmp[4] = { 0,0,0,0 };
for ( unsigned long i = 0; i < a.length() ; i++) {
tmp[3-i] = a.chr(a.length()-(i+1));
}
x = (unsigned long long) big_endian(tmp);
}
}
return x;
case '(':
e = e.after(0);
x = eval_i(e,s);
return x;
case '-':
e = e.after(0);
x = get_val_i(e,s,err);
x = -x;
return x;
default:
unsigned long i;
for (i = 0; i < e.length(); i++) {
bool flag = false;
switch (e.chr(i)) {
case '+':
case '-':
case '*':
case '/':
case '\\':
case '&':
case '|':
case '(':
case ')':
flag = true;
break;
}
if (flag) break;
}
a = e.left(i);
e = e.after(i-1);
x = find_label_i(a,s,err);
// last_exp_had_lbl = true;
return x;
}
}
unsigned long long eval_i(Str & e, int & s) { // mit s==1
unsigned long long x;
unsigned long long y;
Str err;
x = 0;
while (e.length() && s==1) {
switch (e.chr(0)) {
case ')':
e = e.after(0);
return x;
case '*':
e = e.after(0);
y = get_val_i(e,s,err);
x = x * y;
break;
case '+':
e = e.after(0);
y = get_val_i(e,s,err);
x = x + y;
break;
case '-':
e = e.after(0);
y = get_val_i(e,s,err);
x = x - y;
break;
case '&':
e = e.after(0);
y = get_val_i(e,s,err);
x = x & y;
break;
case '|':
e = e.after(0);
y = get_val_i(e,s,err);
x = x | y;
break;
case '\\':
e = e.after(0);
y = get_val_i(e,s,err);
x = x ^ y;
break;
case '/':
e = e.after(0);
y = get_val_i(e,s,err);
if ( y == 0 && s==0 ) {
err = "division by zero in expression";
s = 1;
} else if ( s == -1 || s == 0 ) {
x = 0;
} else {
x = x / y;
}
break;
default:
x = get_val_i(e,s,err);
}
}
if ( s != -1 ) {
return x;
} else {
norm_err(err);
s = 0;
return 0;
}
}
double eval_d(Str & e, int & s) { // mit s==1
double x;
double y;
Str err;
x = 0;
while (e.length() && s==1) {
switch (e.chr(0)) {
case ')':
e = e.after(0);
return x;
case '*':
e = e.after(0);
y = get_val_d(e,s,err);
x = x * y;
break;
case '+':
e = e.after(0);
y = get_val_d(e,s,err);
x = x + y;
break;
case '-':
e = e.after(0);
y = get_val_d(e,s,err);
x = x - y;
break;
case '&':
err = "no '&' operator defined for floating point numbers";
s = 1;
break;
case '|':
err = "no '|' operator defined for floating point numbers";
s = 1;
break;
case '\\':
err = "no '\\' operator defined for floating point numbers";
s = 1;
break;
case '/':
e = e.after(0);
y = get_val_d(e,s,err);
if ( y == 0 && s==0 ) {
err = "division by zero in expression";
s = 1;
} else if ( s == -1 || s == 0 ) {
x = 0;
} else {
x = x / y;
}
break;
default:
x = get_val_d(e,s,err);
}
}
if ( s != -1 ) {
return x;
} else {
norm_err(err);
s = 0;
return 0;
}
}
int cmp_label( const void * ap, const void * bp) {
const Symbol * a = (const Symbol *)ap;
const Symbol * b = (const Symbol *)bp;
if (a->isfloat) {
if (b->isfloat) {
if (a->fvalue < b->fvalue) return -1;
if (a->fvalue == b->fvalue) return 0;
return 1;
} else {
return 1;
}
} else {
if (b->isfloat) {
return -1;
} else {
if (a->ivalue < b->ivalue) return -1;
if (a->ivalue == b->ivalue) return 0;
return 1;
}
}
}
void unused_labels(void) {
bool f = true;
AVLItem<Symbol> * p = l_arr.get_head();
while (p) {
if (! p->numerical) {
if (! p->accessed) {
if (f) {
f = false;
cerr << "following non-numerical labels were never used: \n";
}
cerr << p->name << '\n';
}
}
p = l_arr.get_next(p);
}
return;
}
int set_label(Symbol & y) {
int s = 1;
Str e(akt_line->para);
e = npara(e);
unsigned long long x = eval_i(e,s);
y.isfloat = false;
switch (s) {
case 1:
y.ivalue = x;
y.resolved = true;
y.numerical = true;
break;
case 0:
case -1:
y.ivalue = 0;
}
return s;
}
void init_lbl(void) {
if (akt_line->label.length()) {
AVLItem<Symbol> * y = l_arr.find(Symbol(akt_line->label));
if (y) {
if (akt_line->obc == "SET") {
if ( 1 != set_label(*y)) {
norm_err("SET cannot resolve reference(s) in '"+akt_line->para+"'");
}
akt_line->obc = "";
} else {
norm_err("double definition of label '"+akt_line->label+"'");
}
} else {
AVLItem<Symbol> * p = new AVLItem<Symbol>;
p->name = akt_line->label;
p->isfloat = false;
l_arr.insert(p);
if (akt_line->label.right(1) == ".") {
akt_line->label = "";
}
if (akt_line->obc == "EQU") {
p->reference = akt_line;
p->numerical = true;
} else if (akt_line->obc == "SET") {
if ( 1 != set_label(*p)) {
norm_err("SET cannot resolve reference(s) in '"+akt_line->para+"'");
}
akt_line->obc = "";
} else {
p->ivalue = adr;
p->resolved = true;
p->numerical = false;
}
}
}
}
NibStr & hrval(unsigned long long x, int n) { // n==0 means 1 nibble
static NibStr res;
res.clear();
if (n < 15) {
if ( x >= ((unsigned long long)0x10 << (n*4)) ) {
op_rng_err();
return res;
}
}
res = NibStr(x, n+1);
return res;
}
NibStr & rel_jmp(const Str & target, int offset, int nibs) {
static NibStr res;
static Str t;
int x;
int diff;
res.clear();
t = target;
if ( t.length() ) {
int s = 1;
x = (int) eval_i(t,s);
if ( s==1 ) {
diff = x-(adr+offset);
int msn = (diff & (0xf << (nibs*4))) >> (nibs*4);
if ( (diff > -1 && msn > 7 ) ||
(diff < 0 && msn < 8 ) ) {
op_rng_err();
} else {
res = NibStr((unsigned long long)diff, nibs+1);
}
}
} else {
res = NibStr((unsigned long long)0,2);
}
return res;
}
NibStr & fval(double x) {
static NibStr res(16);
char * src = DtoR(x);
for (int i = 0; i < 16; i++) {
res.poke(i, (unsigned long) ((*src++) - '0'), 1);
}
return res;
}
NibStr & hval(unsigned long long x, int n) {
static NibStr tmp;
static NibStr res;
tmp = hrval(x, n);
res = tmp;
for (unsigned long i = 0; i < res.length(); i++) {
res.poke(i, tmp.peek(res.length()-(i+1), 1), 1);
}
return res;
}
NibStr & hgval(unsigned long long x, int n) { // n==0 means 1 nibble
static NibStr res;
res = hval(x, n);
for (unsigned long i = 0; i < res.length() ; i++) {
res.poke(i, (unsigned long long) rev_nibs[(int)res.peek(i,1)], 1);
}
return res;
}
void get_p1val(int & s, unsigned long long & x) {
last_ext_ref.clear();
s = 1;
static Str e;
e = p1.right(p1.length()-1);
x = eval_i(e,s);
}
void get_p1lbl(int & s, unsigned long long & x) {
last_exp_had_lbl = false;
last_ext_ref.clear();
s = 1;
Str e(p1);
x = eval_i(e,s);
}
int sd1_mode(const Str & x, const Str & y) {
if (x.length() != 1 || y.length() != 1) return -1;
switch (x.chr(0)) {
case 'a':
switch (y.chr(0)) {
case 'c':
return 6;
case 'b':
return 8;
default:
return -1;
}
case 'b':
switch (y.chr(0)) {
case 'a':
return 4;
case 'c':
return 9;
default:
return -1;
}
case 'c':
switch( y.chr(0)) {
case 'b':
return 5;
case 'd':
return 7;
case 'a':
return 10;
default:
return -1;
}
case 'd':
switch( y.chr(0)) {
case 'c':
return 11;
default:
return -1;
}
}
return -1;
}
int sd2_mode(const Str & x, const Str & y) {
if (x.length() != 1 || y.length() != 1) return -1;
switch (x.chr(0)) {
case 'a':
switch( y.chr(0)) {
case 'c':
return 2;
case 'a':
return 4;
case 'b':
return 8;
default:
return -1;
}
case 'b':
switch( y.chr(0)) {
case 'a':
return 0;
case 'b':
return 5;
case 'c':
return 9;
default:
return -1;
}
case 'c':
switch( y.chr(0)) {
case 'b':
return 1;
case 'd':
return 3;
case 'c':
return 6;
case 'a':
return 10;
default:
return -1;
}
case 'd':
switch( y.chr(0)) {
case 'd':
return 7;
case 'c':
return 11;
default:
return -1;
}
}
return -1;
}
int sd3_mode(const Str & x, const Str & y) {
if (x.length() != 1 || y.length() != 1) return -1;
switch( x.chr(0) ) {
case 'a':
switch( y.chr(0) ) {
case 'c':
return 2;
case 'b':
return 8;
default:
return -1;
}
case 'b':
switch( y.chr(0) ) {
case 'a':
return 0;
case 'c':
return 9;
default:
return -1;
}
case 'c':
switch( y.chr(0)) {
case 'b':
return 1;
case 'd':
return 3;
case 'a':
return 10;
default:
return -1;
}
case 'd':
switch( y.chr(0)) {
case 'c':
return 11;
default:
return -1;
}
}
return -1;
}
int sd4_mode(const Str & x, const Str & y) {
if (x.length() != 1 || y.length() != 1) return -1;
switch( x.chr(0) ) {
case 'a':
switch( y.chr(0)) {
case 'c':
return 14;
default:
return -1;
}
case 'b':
switch( y.chr(0)) {
case 'a':
return 12;
default:
return -1;
}
case 'c':
switch( y.chr(0)) {
case 'b':
return 13;
case 'd':
return 15;
default:
return -1;
}
case 'd':
return -1;
}
return -1;
}
int sd5_mode(const Str & x) {
switch( x.chr(0) ) {
case 'a':
return 4;
case 'b':
return 5;
case 'c':
return 6;
case 'd':
return 7;
}
return -1;
}
int sd6_mode(const Str & x) {
switch( x.chr(0) ) {
case 'a':
return 12;
case 'b':
return 13;
case 'c':
return 14;
case 'd':
return 15;
}
return -1;
}
int sd7_mode(const Str & x, const Str & y) {
switch( x.chr(0) ) {
case 'a':
switch( y.chr(0)) {
case 'c':
return 10;
case 'b':
return 12;
default:
return -1;
}
case 'b':
switch( y.chr(0)) {
case 'a':
return 8;
case 'c':
return 13;
default:
return -1;
}
case 'c':
switch( y.chr(0) ) {
case 'b':
return 9;
case 'd':
return 11;
case 'a':
return 14;
default:
return -1;
}
case 'd':
switch( y.chr(0)) {
case 'c':
return 15;
default:
return -1;
}
}
return -1;
}
int sd8_mode(const Str & x, const Str & y) {
switch(x.chr(0)) {
case 'a':
switch( y.chr(0)) {
case 'c':
return 2;
case 'b':
return 0;
default:
return -1;
}
case 'b':
switch( y.chr(0) ) {
case 'a':
return 0;
case 'c':
return 1;
default:
return -1;
}
case 'c':
switch( y.chr(0) ) {
case 'b':
return 1;
case 'd':
return 3;
case 'a':
return 2;
default:
return -1;
}
case 'd':
switch( y.chr(0)) {
case 'c':
return 3;
default:
return -1;
}
}
return -1;
}
int sd9_mode(const Str & x,const Str & y) {
switch( x.chr(0) ) {
case 'a':
switch( y.chr(0) ) {
case 'b':
return 4;
case 'c':
return 2;
default:
return -1;
}
case 'b':
switch( y.chr(0)) {
case 'a':
return 0;
case 'c':
return 5;
default:
return -1;
}
case 'c':
switch( y.chr(0)) {
case 'b':
return 1;
case 'd':
return 3;
case 'a':
return 6;
default:
return -1;
}
case 'd':
switch( y.chr(0)) {
case 'c':
return 7;
default:
return -1;
}
}
return -1;
}
int sd10_mode(const Str & x,const Str & y) {
switch( x.chr(0) ) {
case 'a':
switch( y.chr(0) ) {
case 'b':
return 0;
case 'c':
return 6;
default:
return -1;
}
case 'b':
switch( y.chr(0)) {
case 'a':
return 4;
case 'c':
return 1;
default:
return -1;
}
case 'c':
switch( y.chr(0)) {
case 'b':
return 5;
case 'd':
return 7;
case 'a':
return 2;
default:
return -1;
}
case 'd':
switch( y.chr(0) ) {
case 'c':
return 3;
default:
return -1;
}
}
return -1;
}
int adr_mode_l(Str & t) {
if (! t.length()) return 0;
static Str p;
p = t;
p.to_lower();
if ( p.length()==1 && p.chr(0) >= 'a' && p.chr(0) < 'e' ) {
t = p;
return 1;
} else if ( p=="d0" || p=="d1" ) {
t = p;
return 2;
} else if ( p=="(d0)" || p=="(d1)" ) {
t = p;
return 3;
} else if ( p.chr(0) == '#' ) {
return 4;
} else if ( p.length() == 2 && p >= "r0" && p < "r5" ) {
t = p;
return 5;
} else if ( p=="p" ) {
t = p;
return 6;
} else if ( p== "st" ) {
t = p;
return 7;
} else if ( p=="hst" ) {
t = p;
return 8;
} else if ( p=="in" ) {
t = p;
return 9;
} else if ( p=="out") {
t = p;
return 10;
} else if ( p.left(2) == "c." ) {
int x = (p.after(1)).val();
if ( x >= 0 && x <= 15 ) {
t = p;
return 11;
} else {
return -1;
}
} else if ( p== "(a)" ) {
t = p;
return 12;
} else {
return -1;
}
}
NibStr & line_nibs(void) {
static NibStr result;
result.clear();
static Str obc;
obc = akt_line->obc;
static Str para;
para = akt_line->para;
static Str a;
a = para;
p1 = npara(a);
p2 = npara(a);
static Str p3;
p3 = npara(a);
int smod = adr_mode_l(p1);
int dmod = adr_mode_l(p2);
int alp_ext = akt_line->alp_ext;
int num_ext = akt_line->num_ext;
bool cod = false;
if (obc.length() == 0) {
cod = true;
} else if (obc == "MOVE") {
if (smod == 1 && dmod == 1) {
int x = sd1_mode(p1,p2);
if (x >= 0) {
if (num_ext == 4) {
result = NibStr((unsigned long) 0xd + (x << 4), 2);
cod = true;
} else if (alp_ext >= 0) {
result = NibStr((unsigned long) 0xa + ((alp_ext+8) << 4) + (x << 8), 3 );
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if (smod == 7 && p2=="c") {
if (alp_ext != 3) {
ill_siz_err();
} else {
result = NibStr((unsigned long)0x90 , 2);
cod = true;
}
} else if (p1 == "c" && dmod == 7) {
if (alp_ext != 3) {
ill_siz_err();
} else {
result = NibStr((unsigned long)0xa0 , 2);
cod = true;
}
} else if ( (p1=="a" || p1=="c") && dmod==2 ) {
int x = 0;
if (p1 == "c") x += 4;
if (p2 == "d1") x += 1;
if (num_ext == 3 ) x += 8;
if (num_ext == 4) {
result = NibStr((unsigned long)0x31 + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else if (smod == 3 && (p2=="a" || p2 == "c")) {
if (num_ext == 4 || num_ext == 1 ) {
int x = 2;
if (num_ext == 1) x += 8;
if (p2 == "c") x += 4;
if (p1 == "(d1)") x += 1;
result = NibStr((unsigned long)0x41 + (x << 8) , 3);
cod = true;
} else if (alp_ext >= 0) {
int x = 2;
if (p2 == "c") x += 4;
if (p1 == "(d1)") x += 1;
result = NibStr((unsigned long)0x51 + (x << 8) + (alp_ext << 12), 4);
cod = true;
} else if (num_ext >= 0) {
int x = 10;
if (p2 == "c") x += 4;
if (p1 == "(d1)") x += 1;
result = NibStr((unsigned long)0x51 + (x << 8) + (num_ext << 12), 4);
cod = true;
} else {
ill_siz_err();
}
} else if (dmod == 3 && (p1 == "a" || p1 == "c")) {
if (num_ext == 4 || num_ext == 1) {
int x = 0;
if (num_ext == 1) x += 8;
if (p1 == "c") x += 4;
if (p2 == "(d1)") x += 1;
result = NibStr((unsigned long)0x41 + (x << 8), 3);
cod = true;
} else if (alp_ext >= 0) {
int x = 0;
if (p1 == "c") x += 4;
if (p2 == "(d1)") x += 1;
result = NibStr((unsigned long)0x51 + (x << 8) + (alp_ext << 12), 4);
cod = true;
} else if (num_ext >= 0) {
int x = 8;
if (p1 == "c") x += 4;
if (p2 == "(d1)") x += 1;
result = NibStr((unsigned long)0x51 + (x << 8) + (num_ext << 12), 4);
cod = true;
} else {
ill_siz_err();
}
} else if (smod == 4) {
if (dmod == 2) {
if (num_ext == 4) {
result = NibStr(7);
} else if (num_ext == 3) {
result = NibStr(6);
} else if (num_ext == 1) {
result = NibStr(4);
} else if (alp_ext == -2) {
akt_line->num_ext = 4;
result = NibStr(7);
// obj.relocs.add_tail(adr + 2);
} else {
ill_siz_err();
}
} else if (dmod == 6) {
if (num_ext == 0) {
result = NibStr(2);
} else {
ill_siz_err();
}
} else if (p2 == "c" || p2 == "c.p") {
if (num_ext >= 0) {
result = NibStr(num_ext + 3);
} else if (alp_ext == -2) {
akt_line->num_ext = 4;
result = NibStr(7);
// obj.relocs.add_tail(adr + 2);
} else {
ill_siz_err();
}
} else if (p2 == "a" || p2 == "a.p") {
if (num_ext >= 0) {
result = NibStr(num_ext + 6);
} else if (alp_ext == -2) {
akt_line->num_ext = 4;
result = NibStr(10);
// obj.relocs.add_tail(adr + 5);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( (p1 == "a" || p1 == "c") && dmod==5 ) {
if (num_ext == 15) {
int x = 0;
if (p1 == "c") x += 8;
x += p2.chr(p2.length()-1) - '0';
result = NibStr((unsigned long)0x01 + (x << 8), 3);
cod = true;
} else if (alp_ext > -1 || num_ext == 4) {
int x = p2.chr(p2.length()-1) - '0';
if (p1 == "c") x += 8;
if (num_ext == 4) alp_ext = 15;
result = NibStr((unsigned long)0xa18 + (alp_ext << 12) + (x << 20), 6);
cod = true;
} else {
ill_siz_err();
}
} else if ( (p2 == "a" || p2 == "c") && smod == 5) {
if (num_ext == 15) {
int x = 0;
if (p2 == "c") x += 8;
x += p1.chr(p1.length()-1) - '0';
result = NibStr((unsigned long)0x11 + (x << 8), 3);
cod = true;
} else if (alp_ext > -1 || num_ext == 4) {
int x = p1.chr(p1.length()-1) - '0';
if (p2 == "c") x += 8;
if (num_ext == 4) alp_ext = 15;
result = NibStr((unsigned long)0xa18 + (alp_ext << 12) + (1 << 16) + (x << 20), 6);
cod = true;
} else {
ill_siz_err();
}
} else if ( smod == 9 && (p2=="a" || p2 == "c") ) {
if (num_ext != 3) {
ill_siz_err();
} else {
int x = 2;
if (p2=="c") x += 1;
result = NibStr((unsigned long)0x08 + (x << 8), 3);
cod = true;
}
} else if (dmod==10 && p1 == "c") {
if (num_ext == 2) {
result = NibStr((unsigned long)0x108 , 3);
cod = true;
} else if (alp_ext == 4) {
result = NibStr((unsigned long)0x008 , 3);
cod = true;
} else {
ill_siz_err();
}
} else if (p1 == "p" && dmod == 11) {
if (num_ext != 0) {
ill_siz_err();
} else {
int x = (p2.after(1)).val();
result = NibStr((unsigned long)0xc08 + (x << 12) , 4);
cod = true;
}
} else if ( p2=="p" && smod==11 ) {
if ( num_ext != 0 ) {
ill_siz_err();
} else {
int x = (p1.after(1)).val();
result = NibStr((unsigned long)0xd08 + (x << 12), 4);
cod = true;
}
} else if ( p1=="pc" && (p2=="a" || p2=="c") ) {
if ( num_ext == 4 ) {
cod = true;
if ( p2=="a" ) {
result = NibStr((unsigned long)0x4b18 , 4);
} else {
result = NibStr((unsigned long)0x5b18 , 4);
}
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "EXG" ) {
if ( (smod == 5 && dmod != 5) || (smod != 5 && dmod == 5) ) {
if ( smod == 5 ) {
int tmp = dmod;
dmod = smod;
smod = tmp;
Str t = p2;
p2 = p1;
p1 = t;
}
if ( p1=="c" || p1=="a" ) {
if ( num_ext == 15 ) {
int x = 0;
if ( p1=="c" ) {
x += 8;
}
x += p2.chr(p2.length()-1) - '0';
result = NibStr((unsigned long)0x21 + (x << 8) , 3);
cod = true;
} else if ( alp_ext > -1 || num_ext == 4 ) {
int x = p2.chr(p2.length()-1) - '0';
if ( p1=="c" ) {
x += 8;
}
if ( num_ext == 4 ) {
alp_ext = 15;
}
result = NibStr((unsigned long)0xa18+(alp_ext << 12)+(2 << 16)+(x << 20), 6);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( (smod==2 && dmod != 2) || (smod != 2 && dmod == 2)) {
if ( num_ext == 4 || num_ext == 3 ) {
if ( smod == 2 ) {
int tmp = dmod;
dmod = smod;
smod = tmp;
Str t = p1;
p1 = p2;
p2 = t;
}
if ( p1 == "a" || p1 == "c" ) {
int x = 2;
if ( p1 == "c" ) {
x += 4;
}
if ( p2 == "d1" ) {
x += 1;
}
if ( num_ext==3 ) {
x += 8;
}
result = NibStr((unsigned long)0x31 + (x << 8) , 3);
cod = true;
} else {
ill_add_err();
}
} else {
ill_siz_err();
}
} else if ( smod==1 && dmod==1 ) {
if ( p1 > p2 ) {
Str t = p2;
p2 = p1;
p1 = t;
}
int x;
if ( p1=="a" && p2=="b" ) {
x=12;
} else if ( p1=="b" && p2=="c" ) {
x=13;
} else if ( p1=="a" && p2=="c" ) {
x=14;
} else if ( p1=="c" && p2=="d" ) {
x=15;
} else {
ill_add_err();
x=0;
}
if ( x > 0 ) {
if ( num_ext == 4 ) {
result = NibStr((unsigned long)0xd + (x << 4) , 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xa + ((alp_ext+8) << 4) + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
}
} else if ( (smod==11) ^ (dmod==11) ) {
if ( smod==11 ) {
int tmp = dmod;
dmod = smod;
smod = tmp;
Str t = p2;
p2 = p1;
p1 = t;
}
if ( smod==6 ) {
int x = (p2.after(1)).val();
result = NibStr((unsigned long)0xf08 + (x << 12) , 4);
cod = true;
} else {
ill_add_err();
}
} else if ( (p1=="pc") ^ (p2=="pc") ) {
if ( num_ext == 4 ) {
if ( p1 == "pc" ) {
Str t = p2;
p2 = p1;
p1 = t;
}
if ( p1=="a" ) {
result = NibStr((unsigned long)0x6b18 , 4);
cod = true;
} else if ( p1=="c" ) {
result = NibStr((unsigned long)0x7b18 , 4);
cod = true;
} else {
ill_add_err();
}
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "ADD" ) {
if ( smod==4 && dmod==2 ) {
result = NibStr(3);
} else if ( smod==4 && dmod==1 ) {
if ( alp_ext > -1 || num_ext == 4 ) {
result = NibStr(6);
} else {
ill_siz_err();
}
} else if ( smod==1 && dmod==1 ) {
int x = sd2_mode(p1,p2);
if ( x >= 0 ) {
if ( num_ext == 4 ) {
result = NibStr((unsigned long)0xc + (x << 4) , 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xa + (alp_ext << 4) + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( p1=="p+1" && p2=="c" ) {
if ( num_ext==4 ) {
result = NibStr((unsigned long)0x908 , 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "SUB" ) {
if ( smod==1 && dmod==1 ) {
int x = sd3_mode(p1,p2);
if ( x >= 0 ) {
if ( num_ext==4 ) {
result = NibStr((unsigned long)0xe + (x << 4) , 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xb + (alp_ext << 4) + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( smod==4 && dmod==2 ) {
result = NibStr(3);
} else if ( smod==4 && dmod==1 ) {
if ( alp_ext > -1 || num_ext == 4 ) {
result = NibStr(6);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "SUBR" ) {
if ( smod==1 && dmod==1 ) {
int x = sd4_mode(p1,p2);
if ( x >= 0 ) {
if ( num_ext == 4) {
result = NibStr((unsigned long)0xe + (x << 4) , 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xb + (alp_ext << 4) + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else if ( obc == "INC" ) {
if ( smod==1 && dmod==0 ) {
if ( num_ext==4 ) {
result = NibStr((unsigned long)0xe + (sd5_mode(p1) << 4), 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xb + (alp_ext << 4) + (sd5_mode(p1) << 8), 3);
cod = true;
} else {
ill_siz_err();
}
} else if ( smod==6 && dmod==0 ) {
if ( num_ext==0 ) {
result = NibStr((unsigned long)0xc0 , 2);
cod = true;
} else {
ill_siz_err();
}
} else if ( smod==2 && dmod==0 ) {
if ( num_ext == 4 ) {
int x = 6;
if ( p1 == "d1") {
x += 1;
}
result = NibStr((unsigned long)0x1 + (x << 4) , 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "DEC" ) {
if ( smod==1 && dmod==0 ) {
if ( num_ext==4 ) {
result = NibStr((unsigned long)0xc + (sd6_mode(p1) << 4), 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xa + (alp_ext << 4) + (sd6_mode(p1) << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else if ( smod == 6 && dmod == 0 ) {
if ( num_ext==0 ) {
result = NibStr((unsigned long)0xd0 , 2);
cod = true;
} else {
ill_siz_err();
}
} else if ( smod == 2 && dmod == 0 ) {
if ( num_ext==4 ) {
int x = 8;
if ( p1=="d1" ) {
x += 4;
}
result = NibStr((unsigned long)0x1 + (x << 4) , 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "OR" ) {
if ( smod==1 && dmod==1 ) {
int x = sd7_mode(p1,p2);
if ( num_ext==4 ) {
result = NibStr((unsigned long)0xfe0 + (x << 12) , 4);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xe0 + (alp_ext << 8) + (x << 12) , 4);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "AND" ) {
if ( smod==1 && dmod==1 ) {
int x = sd7_mode(p1,p2) - 8;
if ( x >= 0 ) {
if ( num_ext==4 ) {
result = NibStr((unsigned long)0xfe0 + (x << 12) , 4);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xe0 + (alp_ext << 8) + (x << 12) , 4);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else if ( obc == "CLR" ) {
if ( dmod==0 ) {
if ( smod == 7) {
if ( num_ext == 2 ) {
result = NibStr((unsigned long)0x80 , 2);
cod = true;
} else {
ill_siz_err();
}
} else if ( smod==1 ) {
int x = sd5_mode(p1) - 4;
if ( num_ext == 4 ) {
result = NibStr((unsigned long)0xd + (x << 4), 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xa + ((alp_ext+8) << 4) + (x << 8), 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( dmod==8 && smod==4 ) {
result = NibStr(3);
} else {
ill_add_err();
}
} else if ( obc == "NEG" ) {
if ( smod==1 && dmod==0 ) {
int x = sd5_mode(p1) + 4;
if ( num_ext == 4 ) {
result = NibStr((unsigned long)0xf + (x << 4) , 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xb + ((alp_ext+8) << 4) + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "NOT" ) {
if ( smod==1 && dmod==0 ) {
int x = sd5_mode(p1) + 8;
if ( num_ext == 4) {
result = NibStr((unsigned long)0xf + (x << 4), 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xb + ((alp_ext+8) << 4) + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "LSL" ) {
if ( p1=="#4" && dmod==1 ) {
int x = sd5_mode(p2) - 4;
if ( num_ext == 4 ) {
result = NibStr((unsigned long)0xf + (x << 4), 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xb + ((alp_ext+8) << 4) + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else if ( p1 == "#1" && dmod==1 ) {
int x = sd5_mode(p2);
if ( num_ext==4 ) {
result = NibStr((unsigned long)0xc + (x << 4) , 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xa + (alp_ext << 4) + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "LSR" ) {
if ( p1=="#4" && dmod==1 ) {
int x = sd5_mode(p2);
if ( num_ext == 4) {
result = NibStr((unsigned long)0xf + (x << 4) , 2);
cod = true;
} else if ( alp_ext >= 0 ) {
result = NibStr((unsigned long)0xb + ((alp_ext+8) << 4) + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else if ( p1=="#1" && dmod==1 ) {
int x = sd5_mode(p2) + 8;
if ( num_ext==15 || (num_ext == -1 && alp_ext == -1)) {
result = NibStr((unsigned long)0x18 + (x << 8) , 3);
cod = true;
} else if ( num_ext==4 || alp_ext > -1 ) {
if ( num_ext==4 ) {
alp_ext = 15;
}
x -= 12;
result = NibStr((unsigned long)0x918 + (alp_ext << 12) + (x << 16) , 5);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "ROL") {
if ( p1=="#4" && dmod==1 ) {
int x = sd5_mode(p2) - 4;
if ( num_ext==15 ) {
result = NibStr((unsigned long)0x18 + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "ROR" ) {
if ( p1=="#4" && dmod==1 ) {
int x = sd5_mode(p2);
if ( num_ext == 15 ) {
result = NibStr((unsigned long)0x18 + (x << 8) , 3);
cod = true;
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "BCLR") {
if ( smod==4 && (p2=="c" || p2=="a") ) {
result = NibStr(5);
} else if ( smod==4 && dmod==7 ) {
result = NibStr(3);
} else {
ill_add_err();
}
} else if ( obc == "BSET" ) {
if ( smod==4 && (p2=="c" || p2=="a") ) {
result = NibStr(5);
} else if ( smod==4 && dmod==7 ) {
result = NibStr(3);
} else {
ill_add_err();
}
} else if ( obc == "BCS" || obc == "BCC" ) {
if ( smod == -1 && dmod==0 ) {
if ( num_ext==1 || num_ext == -1 ) {
result = NibStr(3);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "RTCC" ) {
result = NibStr((unsigned long)0x005 , 3);
cod = true;
} else if ( obc == "RTCS" ) {
result = NibStr((unsigned long)0x004 , 3);
cod = true;
} else if ( obc == "BRA" ) {
if ( smod == -1 && dmod==0 ) {
if ( num_ext==2 || num_ext == -1 ) {
result = NibStr(4);
} else if ( num_ext==3 ) {
result = NibStr(6);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "BSR" ) {
if ( smod==-1 && dmod==0 ) {
if ( num_ext==2 || num_ext == -1 ) {
result = NibStr(4);
} else if ( num_ext==3 ) {
result = NibStr(6);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "JMP" ) {
if ( smod==-1 && dmod==0 ) {
if ( num_ext == -1 ) {
result = NibStr(7);
} else {
ill_siz_err();
}
} else if ( smod==12 && dmod==0 ) {
if ( num_ext == -1 ) {
result = NibStr((unsigned long)0xc808, 4);
cod = true;
} else {
ill_siz_err();
}
} else if ( p1=="a" || p1=="c" ) {
if ( num_ext == 4 || num_ext == -1) {
cod = true;
if ( p1 == "a") {
result = NibStr((unsigned long)0x2b18, 4);
} else {
result = NibStr((unsigned long)0x3b18, 4);
}
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "JSR" ) {
if ( smod == -1 && dmod==0 ) {
if ( num_ext == -1 ) {
result = NibStr(7);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( obc == "BEQ" || obc == "RTEQ" ) {
int ddmod = adr_mode_l(p3);
if ( (obc == "BEQ" && ddmod == -1) || (obc == "RTEQ" && ddmod == 0) ) {
if ( smod==4 && dmod==8 ) {
if ( num_ext==0 || num_ext == -1 ) {
result = NibStr(5);
} else {
ill_siz_err();
}
} else if ( smod==4 && dmod==6) {
if ( num_ext == 0 || num_ext == -1 ) {
result = NibStr(5);
} else {
ill_siz_err();
}
} else if ( smod==1 && dmod==1 ) {
if ( sd8_mode(p1,p2) >= 0) {
if ( num_ext==4 || alp_ext >= 0) {
result = NibStr(5);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( smod==1 && p2=="0" ) {
if ( num_ext==4 || alp_ext >= 0) {
result = NibStr(5);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else if ( obc == "BNE" || obc == "RTNE" ) {
int ddmod = adr_mode_l(p3);
if ( (obc == "BNE" && ddmod == -1) || (obc == "RTNE" && ddmod == 0) ) {
if ( smod==4 && dmod==6 ) {
if ( num_ext==0 || num_ext == -1 ) {
result = NibStr(5);
} else {
ill_siz_err();
}
} else if ( smod==1 && dmod==1 ) {
if ( sd8_mode(p1,p2) >= 0 ) {
if ( num_ext==4 || alp_ext >= 0) {
result = NibStr(5);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else if ( smod==1 && p2=="0" ) {
if ( num_ext==4 || alp_ext>=0 ) {
result = NibStr(5);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else if ( obc == "BLT" || obc == "RTLT" ) {
int ddmod = adr_mode_l(p3);
if ( (obc == "BLT" && ddmod == -1) || (obc == "RTLT" && ddmod == 0) ) {
if ( smod==1 && dmod==1 ) {
if ( sd9_mode(p1,p2) >= 0 ) {
if ( num_ext==4 || alp_ext >= 0 ) {
result = NibStr(5);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else if ( obc == "BLE" || obc == "RTLE" ) {
int ddmod = adr_mode_l(p3);
if ( (obc == "BLE" && ddmod == -1) || (obc == "RTLE" && ddmod == 0) ) {
if ( smod==1 && dmod==1 ) {
if ( sd9_mode(p1,p2) >= 0 ) {
if ( num_ext==4 || alp_ext >= 0 ) {
result = NibStr(5);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else if ( obc == "BGT" || obc == "RTGT" ) {
int ddmod = adr_mode_l(p3);
if ( (obc == "BGT" && ddmod == -1) || (obc == "RTGT" && ddmod ==0) ) {
if ( smod==1 && dmod==1 ) {
if ( sd10_mode(p1,p2) >= 0 ) {
if ( num_ext==4 || alp_ext >= 0) {
result = NibStr(5);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else if ( obc == "BGE" || obc == "RTGE" ) {
int ddmod = adr_mode_l(p3);
if ( (obc == "BGE" && ddmod == -1) || (obc == "RTGE" && ddmod == 0) ) {
if ( smod==1 && dmod==1 ) {
if ( sd10_mode(p1,p2) >= 0) {
if ( num_ext==4 || alp_ext >= 0 ) {
result = NibStr(5);
} else {
ill_siz_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else if ( obc == "BBC" || obc == "RTBC" ) {
if ( num_ext == -1 ) {
int ddmod = adr_mode_l(p3);
if ( (obc == "BBC" && ddmod == -1) || (obc == "RTBC" && ddmod == 0) ) {
if ( smod==4 && dmod==7 ) {
result = NibStr(5);
} else if ( smod==4 && (p2=="c" || p2=="a") ) {
result = NibStr(7);
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else {
ill_siz_err();
}
} else if ( obc == "BBS" || obc == "RTBS" ) {
if ( num_ext == -1 ) {
int ddmod = adr_mode_l(p3);
if ( (obc == "BBS" && ddmod == -1) || (obc == "RTBS" && ddmod == 0) ) {
if ( smod==4 && dmod==7 ) {
result = NibStr(5);
} else if ( smod==4 && (p2=="c" || p2=="a") ) {
result = NibStr(7);
} else {
ill_add_err();
}
} else {
ill_add_err();
}
} else {
ill_siz_err();
}
} else if ( smod == 0 && dmod==0 ) {
if ( obc == "RTNSXM" ) {
result = NibStr((unsigned long)0x00 , 2);
cod = true;
} else if ( obc == "RTN" ) {
result = NibStr((unsigned long)0x10 , 2);
cod = true;
} else if ( obc == "RTNSC" ) {
result = NibStr((unsigned long)0x20 , 2);
cod = true;
} else if ( obc == "RTNCC" ) {
result = NibStr((unsigned long)0x30 , 2);
cod = true;
} else if ( obc == "SETHEX" ) {
result = NibStr((unsigned long)0x40 , 2);
cod = true;
} else if ( obc == "SETDEC" ) {
result = NibStr((unsigned long)0x50 , 2);
cod = true;
} else if ( obc == "PUSH" ) {
result = NibStr((unsigned long)0x60 , 2);
cod = true;
} else if ( obc == "POP" ) {
result = NibStr((unsigned long)0x70 , 2);
cod = true;
} else if ( obc == "NOP4" ) {
result = NibStr((unsigned long)0x0036 , 4);
cod = true;
} else if ( obc == "UNCNFG" ) {
result = NibStr((unsigned long)0x408 , 3);
cod = true;
} else if ( obc == "CONFIG" ) {
result = NibStr((unsigned long)0x508 , 3);
cod = true;
} else if ( obc == "C=ID" ) {
result = NibStr((unsigned long)0x608 , 3);
cod = true;
} else if ( obc == "SHUTDN" ) {
result = NibStr((unsigned long)0x708 , 3);
cod = true;
} else if ( obc == "INTON" ) {
result = NibStr((unsigned long)0x0808 , 4);
cod = true;
} else if ( obc == "RSI" ) {
result = NibStr((unsigned long)0x01808 , 5);
cod = true;
} else if ( obc == "RTI" ) {
result = NibStr((unsigned long)0xf0 , 2);
cod = true;
} else if ( obc == "BUSCD" ) {
result = NibStr((unsigned long)0xe808 , 4);
cod = true;
} else if ( obc == "INTOFF" ) {
result = NibStr((unsigned long)0xf808 , 4);
cod = true;
} else if ( obc == "RESET" ) {
result = NibStr((unsigned long)0xa08 , 3);
cod = true;
} else if ( obc == "BUSCC" ) {
result = NibStr((unsigned long)0xb08 , 3);
cod = true;
} else if ( obc == "SREQ?" ) {
result = NibStr((unsigned long)0xe08 , 3);
cod = true;
} else if ( obc == "INCLUDE" ) {
cod = true;
} else if ( obc == "RELTAB" ) {
result = NibStr(obj.relocs.length() * 5 + 5);
unsigned long offset = 0;
ListItem<Reloc> * p = obj.relocs.get_head();
while (p) {
result.poke(offset , p->offset, 5);
offset += 5;
p = p->get_next();
}
result.poke( offset , (unsigned long)0, 5);
static bool relwarn = true;
if (relwarn) {
relwarn = false;
cerr << "WARNING: RELTAB pseudo-op used, relocation table\n"
" is dumped & cleared.\n";
}
obj.relocs.clear();
cod = true;
} else {
norm_err("unknown opcode '"+obc+"'");
}
} else if ( obc == "DC" || obc == "DCR" || obc == "DCG" ) {
if ( alp_ext == -2) num_ext = akt_line->num_ext = 4;
if ( num_ext >= 0 ) {
int i = nrof_paras(para);
result = NibStr(i*(num_ext+1));
} else {
ill_siz_err();
}
} else if ( obc == "DCF" ) {
int i = nrof_paras(para);
result = NibStr(i*16);
} else if ( obc == "TEXT" || obc == "TEXTR") {
if ( num_ext == -1 ) {
if ( p1.chr(0) == 34 && p1.chr(p1.length()-1) == 34 ) {
Str a = p1.sub(1,p1.length()-1);
a.implode_escape_sequences();
result = NibStr(a.length() * 2);
cod = true;
bool rflag = false;
if ( obc == "TEXTR" ) {
rflag = true;
}
const char * c = (char *)a;
for (unsigned long i=0; i < a.length(); i++) {
char z = *c++;
if (!rflag) z = ((z & 0xf) << 4) | ((z & 0xf0) >> 4);
result.poke(i*2, (unsigned long)z, 2);
}
} else {
norm_err("missing quotation mark in '"+p1+"'");
}
} else {
ill_siz_err();
}
} else if ( obc == "INCLUDE" ) {
cod = true;
} else if ( obc == "AKTFILE" ) {
cod = true;
} else if ( obc == "EQU" ) {
cod = true;
} else if ( obc == "XDEF" ) {
if (exe_flag) {
norm_err("XDEF pseudo-op ignored due to '-exe' switch");
cod = true;
}
} else if ( obc == "XREF" ) {
if (exe_flag) {
norm_err("XREF pseudo-op ignored due to '-exe' switch");
cod = true;
}
} else {
norm_err("unknown opcode '"+obc +"'");
cod = true;
}
akt_line->binlen = result.length();
if ( cod ) {
akt_line->encoded = true;
// akt_line->para = "";
// akt_line->obc = obc;
}
return result;
}
void line_nibs2(void) {
int s;
unsigned long long x;
int y;
if ( ! akt_line->encoded ) {
static Str obc;
obc = akt_line->obc;
static Str para;
para = akt_line->para;
static Str a;
a = para;
p1 = npara(a);
p2 = npara(a);
static Str p3;
p3 = npara(a);
int smod = adr_mode_l(p1);
int dmod = adr_mode_l(p2);
int num_ext = akt_line->num_ext;
int alp_ext = akt_line->alp_ext;
if ( obc == "MOVE" ) {
get_p1val(s,x);
if ( s==1 ) {
if ( dmod==2 ) {
y = 9;
if ( p2=="d1" ) {
y += 4;
}
if ( num_ext == 4 ) {
y += 2;
} else if ( num_ext==3 ) {
y += 1;
}
obj.body.poke( adr, (unsigned long)0x1 + (y << 4), 2);
insert_imm_val(adr+2, hrval(x,num_ext), (alp_ext == -2));
} else if ( dmod == 6 ) {
obj.body.poke( adr, (unsigned long)0x2, 1);
insert_imm_val( adr+1, hrval(x,0));
} else if ( p2 == "c" || p2 == "c.p" ) {
obj.body.poke( adr, (unsigned long)0x3 + (num_ext << 4), 2);
insert_imm_val( adr+2, hrval(x,num_ext), (alp_ext == -2));
} else if ( p2 == "a" || p2 == "a.p" ) {
obj.body.poke( adr, (unsigned long)0x2808 + (num_ext << 16), 5);
insert_imm_val( adr+5, hrval(x,num_ext), (alp_ext == -2));
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
}
} else if ( obc == "ADD" ) {
if ( dmod == 2 ) {
get_p1val(s,x);
x--;
y = 6;
if ( p2 == "d1" ) {
y += 1;
}
obj.body.poke( adr, (unsigned long)0x1 + (y << 4), 2);
insert_imm_val( adr+2, hrval(x,0));
} else {
get_p1val(s,x);
int w = (int) x;
w--;
if ( w < 16 && w > -1) {
if ( num_ext == 4 ) {
alp_ext = 15;
}
obj.body.poke(adr, (unsigned long)0x818+(alp_ext << 12) +
((sd5_mode(p2)-4) << 16), 5);
insert_imm_val( adr+5, hrval(w,0));
} else {
op_rng_err();
}
}
} else if ( obc == "SUB" ) {
if ( dmod == 2 ) {
get_p1val(s,x);
x--;
y = 8;
if ( p2=="d1" ) {
y += 4;
}
obj.body.poke( adr, (unsigned long)0x1 + (y << 4), 2);
insert_imm_val(adr+2, hrval(x,0));
} else {
get_p1val(s,x);
int w = (int) x;
w--;
if ( w < 16 && w > -1 ) {
if ( num_ext == 4 ) {
alp_ext = 15;
}
obj.body.poke(adr, (unsigned long)0x818+ (alp_ext << 12) +
((sd5_mode(p2)+4) << 16), 5);
insert_imm_val(adr+5, hrval(w,0));
} else {
op_rng_err();
}
}
} else if ( obc == "CLR" ) {
get_p1val(s,x);
obj.body.poke( adr, (unsigned long)0x28, 2);
insert_imm_val( adr+2, hrval(x,0));
} else if ( obc == "BCLR" ) {
get_p1val(s,x);
if ( p2 == "c") {
obj.body.poke( adr, (unsigned long)0x8808, 4);
insert_imm_val( adr+4, hrval(x,0));
} else if ( p2=="a" ) {
obj.body.poke( adr, (unsigned long)0x4808, 4);
insert_imm_val( adr+4, hrval(x,0));
} else if ( dmod==7 ) {
obj.body.poke( adr, (unsigned long)0x48, 2);
insert_imm_val( adr+2, hrval(x,0));
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "BSET" ) {
get_p1val(s,x);
if ( p2 == "c" ) {
obj.body.poke( adr, (unsigned long)0x9808, 4);
insert_imm_val( adr+4, hrval(x,0));
} else if ( p2 == "a" ) {
obj.body.poke( adr, (unsigned long)0x5808, 4);
insert_imm_val(adr+4, hrval(x,0));
} else if ( dmod==7 ) {
obj.body.poke( adr, (unsigned long)0x58, 2);
insert_imm_val( adr+2, hrval(x,0));
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "BCS" || obc == "BCC" ) {
if ( obc == "BCC" ) {
obj.body.poke( adr, (unsigned long)0x5, 1);
obj.body.insert( adr+1, rel_jmp(p1,1,1));
} else if ( obc == "BCS" ) {
obj.body.poke( adr, (unsigned long)0x4, 1);
obj.body.insert(adr+1, rel_jmp(p1,1,1));
}
} else if ( obc == "BRA" ) {
if ( num_ext==2 || num_ext == -1 ) {
obj.body.poke( adr, (unsigned long)0x6, 1);
obj.body.insert( adr+1, rel_jmp(p1,1,2));
} else if ( num_ext==3 ) {
obj.body.poke( adr, (unsigned long)0xc8, 2);
obj.body.insert( adr+2, rel_jmp(p1,2,3));
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "BSR") {
if ( num_ext==2 || num_ext == -1 ) {
obj.body.poke( adr, (unsigned long)0x7, 1);
obj.body.insert(adr+1, rel_jmp(p1,4,2));
} else if ( num_ext==3 ) {
obj.body.poke( adr, (unsigned long)0xe8, 2);
obj.body.insert( adr+2, rel_jmp(p1,6,3));
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "JMP" ) {
get_p1lbl(s,x);
obj.body.poke( adr, (unsigned long)0xd8, 2);
insert_imm_adr(adr+2, hrval(x,4), true);
} else if ( obc == "JSR" ) {
get_p1lbl(s,x);
obj.body.poke( adr, (unsigned long)0xf8, 2);
insert_imm_adr(adr+2, hrval(x,4), true);
} else if ( obc == "BEQ" || obc == "RTEQ" ) {
if ( smod==4 && dmod==8 ) {
get_p1val(s,x);
obj.body.poke( adr, (unsigned long)0x38, 2);
insert_imm_val( adr+2, hrval(x,0));
obj.body.insert( adr+3, rel_jmp(p3,3,1));
} else if ( smod==4 && dmod==6 ) {
get_p1val(s,x);
obj.body.poke( adr, (unsigned long)0x98, 2);
insert_imm_val( adr+2, hrval(x,0));
obj.body.insert( adr+3, rel_jmp(p3,3,1));
} else if ( smod==1 && dmod==1 ) {
int x = sd8_mode(p1,p2);
if ( num_ext==4 ) {
obj.body.poke( adr, (unsigned long)0xa8 + (x << 8), 3);
obj.body.insert( adr+3, rel_jmp(p3,3,1));
} else if ( alp_ext >= 0 ) {
obj.body.poke( adr, (unsigned long)0x9 + (alp_ext << 4) + (x << 8), 3);
obj.body.insert( adr+3, rel_jmp(p3,3,1));
}
} else if ( smod==1 && p2=="0" ) {
if ( num_ext==4 ) {
obj.body.poke( adr, (unsigned long)0xa8 + ((sd5_mode(p1)+4) << 8), 3);
obj.body.insert( adr+3, rel_jmp(p3,3,1));
} else if ( alp_ext >= 0 ) {
obj.body.poke( adr, (unsigned long)0x9+(alp_ext << 4)+((sd5_mode(p1)+4) << 8), 3);
obj.body.insert( adr+3, rel_jmp(p3,3,1));
}
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "BNE" || obc == "RTNE" ) {
if ( smod==4 && dmod==6 ) {
get_p1val(s,x);
obj.body.poke( adr, (unsigned long)0x88, 2);
insert_imm_val( adr+2, hrval(x,0));
obj.body.insert( adr+3, rel_jmp(p3,3,1));
} else if ( smod==1 && dmod==1 ) {
int x = sd8_mode(p1,p2);
if ( num_ext == 4) {
obj.body.poke( adr, (unsigned long)0xa8 + ((x+4) << 8), 3);
obj.body.insert( adr+3, rel_jmp(p3,3,1));
} else if ( alp_ext >= 0 ) {
obj.body.poke( adr, (unsigned long)0x9 + (alp_ext << 4) + ((x+4) << 8), 3);
obj.body.insert( adr+3, rel_jmp(p3,3,1));
}
} else if ( smod==1 && p2=="0" ) {
if ( num_ext==4 ) {
obj.body.poke( adr, (unsigned long)0xa8 + ((sd5_mode(p1)+8) << 8), 3);
obj.body.insert( adr+3, rel_jmp(p3,3,1));
} else if ( alp_ext >= 0 ) {
obj.body.poke( adr, (unsigned long)0x9 + (alp_ext << 4) + ((sd5_mode(p1)+8) << 8),3);
obj.body.insert( adr+3, rel_jmp(p3,3,1));
}
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "BLT" || obc == "RTLT") {
int x = sd9_mode(p1,p2);
if ( num_ext == 4 ) {
obj.body.poke( adr, (unsigned long)0xb8 + (x << 8), 3);
obj.body.insert(adr+3 , rel_jmp(p3,3,1));
} else if ( alp_ext >= 0) {
obj.body.poke( adr, (unsigned long)0x9 + ((alp_ext+8) << 4) + (x << 8), 3);
obj.body.insert(adr+3 , rel_jmp(p3,3,1));
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "BLE" || obc == "RTLE" ) {
int x = sd9_mode(p1,p2) + 8;
if ( num_ext == 4 ) {
obj.body.poke( adr, (unsigned long)0xb8 + (x << 8), 3);
obj.body.insert(adr+3 , rel_jmp(p3,3,1));
} else if ( alp_ext >= 0 ) {
obj.body.poke( adr, (unsigned long)0x9 + ((alp_ext+8) << 4) + (x << 8), 3);
obj.body.insert(adr+3 , rel_jmp(p3,3,1));
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "BGT" || obc == "RTGT" ) {
int x = sd10_mode(p1,p2);
if ( num_ext==4 ) {
obj.body.poke( adr, (unsigned long)0xb8 + (x << 8), 3);
obj.body.insert(adr+3 , rel_jmp(p3,3,1));
} else if ( alp_ext >= 0 ) {
obj.body.poke( adr, (unsigned long)0x9 + ((alp_ext+8) << 4) + (x << 8), 3);
obj.body.insert(adr+3 , rel_jmp(p3,3,1));
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "BGE" || obc == "RTGE" ) {
int x = sd10_mode(p1,p2) + 8;
if ( num_ext == 4 ) {
obj.body.poke( adr, (unsigned long)0xb8 + (x << 8), 3);
obj.body.insert(adr+3 , rel_jmp(p3,3,1));
} else if ( alp_ext >= 0 ) {
obj.body.poke( adr, (unsigned long)0x9 + ((alp_ext+8) << 4) + (x << 8), 3);
obj.body.insert(adr+3 , rel_jmp(p3,3,1));
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "BBC" || obc == "RTBC" ) {
get_p1val(s,x);
if ( smod == 4 && dmod == 7 ) {
obj.body.poke( adr, (unsigned long)0x68, 2);
insert_imm_val(adr+2, hrval(x,0));
obj.body.insert(adr+3, rel_jmp(p3,3,1));
} else if ( smod==4 && p2=="c" ) {
obj.body.poke( adr, (unsigned long)0xa808, 4);
insert_imm_val(adr+4, hrval(x,0));
obj.body.insert(adr+5, rel_jmp(p3,5,1));
} else if ( smod==4 && p2=="a" ) {
obj.body.poke( adr, (unsigned long)0x6808, 4);
insert_imm_val(adr+4, hrval(x,0));
obj.body.insert(adr+5, rel_jmp(p3,5,1));
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "BBS" || obc == "RTBS" ) {
get_p1val(s,x);
if ( smod==4 && dmod==7 ) {
obj.body.poke( adr, (unsigned long)0x78, 2);
insert_imm_val( adr+2, hrval(x,0));
obj.body.insert( adr+3, rel_jmp(p3,3,1));
} else if ( smod==4 && p2=="c" ) {
obj.body.poke( adr, (unsigned long)0xb808, 4);
insert_imm_val(adr+4, hrval(x,0));
obj.body.insert(adr+5, rel_jmp(p3,5,1));
} else if ( smod==4 && p2=="a" ) {
obj.body.poke( adr, (unsigned long)0x7808, 4);
insert_imm_val(adr+4, hrval(x,0));
obj.body.insert(adr+5, rel_jmp(p3,5,1));
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
} else if ( obc == "DC" ) {
int i = 0;
while (para.length()) {
Str e = npara(para);
s=1;
unsigned long long x = eval_i(e,s);
if (s == 1) {
obj.body.insert( adr + i, hval(x,num_ext));
}
i += num_ext + 1;
}
} else if ( obc == "DCF" ) {
int i = 0;
while (para.length()) {
Str e = npara(para);
s=1;
double x = eval_d(e,s);
if (s == 1) {
obj.body.insert( adr + i, fval(x));
}
i += 16;
}
} else if ( obc == "DCR" ) {
int i = 0;
while (para.length()) {
last_ext_ref.clear();
Str e = npara(para);
s = 1;
unsigned long long x = eval_i(e,s);
if ( s == 1 ) {
insert_imm_val( adr + i, hrval(x,num_ext), (alp_ext == -2));
}
i += num_ext + 1;
}
} else if ( obc == "DCG" ) {
int i = 0;
while (para.length()) {
Str e = npara(para);
s = 1;
unsigned long long x = eval_i(e,s);
if ( s == 1 ) {
obj.body.insert( adr + i, hgval(x,num_ext));
}
i += num_ext + 1;
}
} else if (obc == "XDEF" ) {
AVLItem<Symbol> * p = l_arr.find(Symbol(p1));
if (! p) {
norm_err("cannot XDEF undefined label '"+p1+"'");
} else {
if (p->external) {
norm_err("value of label to XDEF must be known at time of assembly");
} else {
obj.exports.insert( *((Symbol *)p) ); // makes a copy!
}
}
} else if (obc == "XREF" ) {
Symbol * sym = l_arr.find(Symbol(p1));
if ( !sym ) {
AVLItem<Symbol> * p = new AVLItem<Symbol> (p1);
p->isfloat = false;
p->resolved = true;
p->external = true;
p->numerical = false;
l_arr.insert(p);
}
} else {
norm_err("internal error with opcode '"+obc+"', please report this bug.");
}
}
return;
}
int find_mac(const Str & a) {
int i;
for ( i=0; i < macros; i++ ) {
if ( a == m_name[i] ) break;
}
if ( i == macros ) {
return -1;
} else {
return i;
}
}
int read_file(Str f_name) {
int line;
Str src_label;
Str src_obc;
Str src_ext;
Str src_para;
Str a;
Str mac;
Str mac_src[5];
Str mac_rpl[5];
int mac_ll = 0;
bool macflag = false;
if (verbose) {
cerr << "reading '" << f_name << "' \n";
}
line = 1;
src.add_tail(SourceLine("", "AKTFILE", "", f_name+(char)1+"1"+(char)1 ));
ifstream * f;
f = new ifstream( (char *)f_name);
if (f->fail()) {
delete f;
f_name = incdir_name + f_name;
f = new ifstream( (char *)f_name);
if (f->fail()) {
delete f;
fatal_err("couldn't open source-file '"+f_name+"'");
return 20;
}
}
while ( ! f->eof() ) {
if ( macflag ) {
int x = mac.index(0);
if ( x != -1) {
a = mac.before (x);
mac = mac.after (x);
for (int i = 0; i < 5; i++) {
if ( mac_src[i] == "" ) break;
for (;;) {
unsigned int z = a.index(mac_src[i]);
if ( z == (unsigned long)~0 ) break;
a = a.before(z) + mac_rpl[i] + a.after(z-1+mac_src[i].length());
}
}
for (;;) {
unsigned int z = a.index("?cnt?");
if ( z == (unsigned long)~0 ) break;
a = a.before(z) + NtoStr(mac_count) + a.after(z+4);
}
} else {
macflag = false;
a = " AKTFILE "+f_name+","+NtoStr(mac_ll+1);
line = mac_ll;
}
} else {
char lbuf[200];
f->getline (lbuf, 200);
// cout << "LINE=<" << lbuf << ">\n";
if (f->eof()) break;
if (f->fail()) {
set_error("error while reading file '"+f_name+"'","");
return 20;
}
/* pre-processor synch support by ATR */
if (*lbuf == '#') {
char incfile[strlen(lbuf)];
sscanf(lbuf, "# %d \"%[^\"]", &line, incfile);
f_name = incfile;
*lbuf = '\0';
src.add_tail(SourceLine("", "AKTFILE", "", f_name+(char)1+NtoStr(line-1)+(char)1 ));
}
a = Str(lbuf);
}
src_label.clear();
{
char i = a.chr(0);
if ( i != (char)0 && i != (char)9 && i != (char)32 && i != (char)54 ) {
src_label = nparas(a);
if ( src_label.chr(0) == 46 ) {
src_label = last_label + src_label + ".";
} else {
if ( src_label.chr(src_label.length()-1) != '.' ) {
last_label = src_label;
}
}
}
}
src_obc.clear();
src_ext.clear();
Str b = nparas(a);
unsigned long x = b.rindex('.');
if ( x != (unsigned long)~0 ) {
src_obc = b.before(x);
src_obc.to_upper();
src_ext = b.after(x);
} else {
b.to_upper();
if ( b == "MACRO" ) {
if (no_mac) {
set_error("FATAL ERROR: MACRO directive used, but macro support disabled","");
return 20;
}
mac_ll = line;
m_name[macros] = src_label;
m_name[macros].to_upper();
src_label = "";
for (int i = 0; i < 5; i++) {
b = nparas(a);
if (! b.length() ) break;
m_para[macros*5+i] = b;
}
while (! f->eof() ) {
char lbuf[200];
f->getline(lbuf,200);
if (f->eof()) break;
if (f->fail()) {
set_error("error while reading file '"+f_name+"'","");
return 20;
}
a = Str(lbuf);
mac_ll++;
b = a;
b.to_upper();
if ( nparas(b) == "ENDMAC" ) break;
m_txt[macros] = m_txt[macros]+a+(char)0;
}
macros++;
src_obc = "AKTFILE";
a = f_name+","+NtoStr(mac_ll+1);
} else {
int z;
if (no_mac) {
z = -1;
} else {
z = find_mac(b);
}
if ( z < 0 ) {
src_obc = b;
} else {
mac_count++;
macflag = true;
mac_ll = line;
mac = m_txt[z];
for ( int i=0 ; i < 5; i++) {
mac_src[i] = m_para[z*5+i];
b = nparas(a);
if ( b == "") break;
mac_rpl[i] = b;
if ( b == mac_src[i] ) {
cerr << "ERROR: macro parameter replacement includes original\n";
macflag = false;
}
}
a = "";
}
}
}
src_para.clear();
for (;;) {
b = nparas(a);
if ( ! b.length() ) break;
src_para += b;
src_para += (char)1;
}
ListItem<SourceLine> * lis = new ListItem<SourceLine> (
SourceLine(src_label, src_obc, src_ext, src_para) );
if (lis == 0) return 20;
src.add_tail(lis);
line++;
src_obc.to_upper();
if ( src_obc == "INCLUDE" ) {
if (macflag) {
fatal_err("INCLUDE directives are not allowed inside macros!");
return 20;
}
a = src_para;
a = npara(a);
lis->para = "";
streampos f_pos = f->tellg();
delete f;
a = a.next_word();
if (verbose) {
cerr << " \r";
}
if (read_file(a)) {
add_error("unable to read complete file '"+f_name+"'","");
return 20;
}
if (verbose) {
cerr << "reading '" << f_name << "' \r";
}
f = new ifstream ((char *)f_name);
if (f == 0 || f->fail()) {
set_error("unable to reopen source file ",(char *)f_name);
return 20;
}
f->seekg(f_pos);
src.add_tail(SourceLine("", "AKTFILE", "",
f_name+(char)1+NtoStr(line)+(char)1) );
}
if ((line & 0xff) == 0) {
if (verbose) {
cerr << "reading '" << f_name << "' line " << line << '\r';
}
}
}
if (verbose) {
cerr << " \r";
}
delete f;
return 0;
}
int read_source(void) {
return read_file(src_name);
}
void def_macs(void) {
if (! no_mac) {
m_name = new Str[max_macros];
m_txt = new Str[max_macros];
m_para = new Str [max_macros*5];
macros = 0;
}
}
void pass1(void) {
// due to a bug in the GNU linker triggered by gcc-2.6.3 optimization,
// don't make this a static initializer:
Symbol default_labels[] = {
Symbol("XM", (unsigned long long) 1),
Symbol("SB", (unsigned long long) 2),
Symbol("SR", (unsigned long long) 4),
Symbol("MP", (unsigned long long) 8)
};
Symbol * l = default_labels;
for (int i = 0; i < 4; i++) {
l->numerical = true;
l_arr.insert(*l);
l++;
}
adr = 0;
obj.body.clear();
line = 0;
akt_line = src.get_head();
while (akt_line) {
// if (akt_line->label.length()) cerr << "label = " << akt_line->label << '\n';
init_lbl();
obj.body += line_nibs();
adr += akt_line->binlen;
if ((line & 0xff) == 0 && verbose) {
cerr << "pass 1: " << line << " \r";
}
line++;
akt_line = akt_line->get_next();
}
nib_len = adr;
if (verbose) {
cerr << " \r";
}
}
void pass2(void) {
adr = 0;
tmp_lbl = true;
akt_line = src.get_head();
line = 0;
while (akt_line) {
if (akt_line->label.length()) {
last_label = akt_line->label;
//cerr << "last_label = " << last_label << '\n';
}
line_nibs2();
adr += akt_line->binlen;
if ((line & 0xff) == 0 && verbose) {
cerr << "pass 2: " << line << " \r";
}
line++;
akt_line = akt_line->get_next();
}
if (adr != nib_len) {
cerr << "ERROR: file length changed between passes (" << nib_len <<
" / " << adr << ")\n";
}
if (verbose) {
cerr << " \r";
}
}
void passn(void) {
int msc = 0;
int sc;
for (sc = 0; sc < l_arr.size(); sc++) {
bool solv_rdy = true;
msc = 1;
AVLItem<Symbol> * p = l_arr.get_head();
while (p) {
if (! p->resolved) {
if ( p->numerical ) {
SourceLine * ref_line = p->reference;
int s = 1;
Str e(ref_line->para);
e = npara(e);
double xf = 0.0;
unsigned long long xi = 0;
if (p->isfloat) {
xf = eval_d(e,s);
} else {
xi = eval_i(e,s);
}
switch (s) {
case 0:
solv_rdy = false;
msc++;
break;
case 1:
if (p->isfloat) {
p->fvalue = xf;
} else {
p->ivalue = xi;
}
p->resolved = true;
break;
case -1:
p->ivalue = 0;
break;
}
}
}
p = l_arr.get_next(p);
}
if (verbose) {
cerr << "pass n[" << sc << "]\r";
}
if (solv_rdy || sc>msc) break;
}
if (verbose) {
cerr << " \r";
}
if (sc > msc) {
cerr << "unresolvable reference(s) between following labels:\n";
AVLItem<Symbol> * p = l_arr.get_head();
while (p) {
if (! p->resolved) {
cerr << p->name << '\n';
}
p = l_arr.get_next(p);
}
}
}
Str cli_arg (int argc, int & aktarg, char ** argv) {
if (aktarg+1 < argc) {
aktarg++;
return Str(argv[aktarg]);
} else {
return "";
}
}
static Str syntax = Str("class invocation syntax:\n"
"class [-o <objectname>] [-i <include-directory>] \n"
" [-exe] [-ul] [-macros] [-mm max_macros] <source-name> \n"
);
int get_cli_line(int argc, char ** argv) {
int aktarg = 1;
while (aktarg < argc) {
Str a(argv[aktarg]);
if (a.chr(0) != '-') {
src_name = a;
} else if (a == "-a") {
src_name = cli_arg(argc, aktarg, argv);
} else if (a == "-o" ) {
obj.name = cli_arg(argc, aktarg, argv);
} else if (a == "-i" ) {
incdir_name = cli_arg(argc, aktarg, argv);
if (incdir_name.chr(incdir_name.length()-1) != '/') {
incdir_name += '/';
}
} else if (a == "-mm" ) {
max_macros = cli_arg(argc, aktarg, argv).val();
} else if (a == "-ul" ) {
ul_list = true;
} else if (a == "-exe") {
exe_flag = true;
} else if (a == "-macros") {
no_mac = false;
} else if (a == "-v") {
verbose = true;
} else {
cerr << syntax;
fatal_err("unknown command-line parameter '"+a+"'");
return 20;
}
aktarg++;
}
if ( src_name == "" ) {
cerr << syntax;
fatal_err("no source-file specified");
return 20;
}
if ( obj.name == "" ) {
obj.name = no_ext(src_name)+".o";
}
return 0;
}
int main (int argc, char ** argv) {
if (get_cli_line(argc, argv)) {
disp_error();
return 20;
}
if (verbose) {
cerr << "CLASS " << (version_tag+1) << "\nwritten by Lutz Vieweg 1991-1994\n";
}
def_macs();
if (read_source()) {
disp_error();
return 20;
}
pass1();
passn();
pass2();
#ifdef OBSOLETE_LIBGXX
BOstream of;
of.open(obj.name, ios::out | ios::binary);
#else
ofstream of( obj.name, ios::out | ios::binary );
#endif
if (of.fail()) {
cerr << "FATAL ERROR: unable to open output file '" << obj.name << "'\n";
return 20;
}
int status = 0;
if (exe_flag) {
of.write( (char *)obj.body , (obj.body.length()+1) >> 1 );
status = of.fail();
if (verbose) {
cerr << "assembled " << src_name << " to executable ";
}
} else {
#ifndef OBSOLETE_LIBGXX
BOstream bof(of);
bof << obj;
status = bof.fail();
#else
of << obj;
status = of.fail();
#endif
if (verbose) {
cerr << "assembled " << src_name << " to object-file ";
}
}
if (verbose) {
cerr << obj.name << " (" << nib_len << " nibbles)\n";
}
if (status) {
cerr << "FATAL ERROR: write operation on file '" << obj.name << "' failed\n";
return 20;
}
if (ul_list) {
unused_labels();
}
return !!error_count;
}
syntax highlighted by Code2HTML, v. 0.9.1