#include "dis48.h"

#ifdef ANSI
char	*Real(char *mem, NAddr *addr, char *out);
char	*Complex(char *mem, NAddr *addr, char *out);
char	*String(char *mem, NAddr *addr, char *out);
char	*Array(char *mem, NAddr *addr, char *out);
char	*List(char *mem, NAddr *addr, char *out);
char	*GlobalName(char *mem, NAddr *addr, char *out);
char	*LocalName(char *mem, NAddr *addr, char *out);
char	*Program(char *mem, NAddr *addr, char *out);
char	*Algebraic(char *mem, NAddr *addr, char *out);
char	*BinaryInt(char *mem, NAddr *addr, char *out);
char	*Graphic(char *mem, NAddr *addr, char *out);
char	*Tagged(char *mem, NAddr *addr, char *out);
char	*Unit(char *mem, NAddr *addr, char *out);
char	*Xlib(char *mem, NAddr *addr, char *out);
char	*Directory(char *mem, NAddr *addr, char *out);
char	*Library(char *mem, NAddr *addr, char *out);
char	*Backup(char *mem, NAddr *addr, char *out);
char	*Command(char *mem, NAddr *addr, char *out);
char	*Address(char *mem, NAddr *addr, char *out);
char	*LongReal(char *mem, NAddr *addr, char *out);
char	*LongComplex(char *mem, NAddr *addr, char *out);
char	*LinkedArray(char *mem, NAddr *addr, char *out);
char	*Character(char *mem, NAddr *addr, char *out);
char	*Code(char *mem, NAddr *addr, char *out);
char	*LibraryData(char *mem, NAddr *addr, char *out);
#else
char	*Real();
char	*Complex();
char	*String();
char	*Array();
char	*List();
char	*GlobalName();
char	*LocalName();
char	*Program();
char	*Algebraic();
char	*BinaryInt();
char	*Graphic();
char	*Tagged();
char	*Unit();
char	*Xlib();
char	*Directory();
char	*Library();
char	*Backup();
char	*Command();
char	*Address();
char	*LongReal();
char	*LongComplex();
char	*LinkedArray();
char	*Character();
char	*Code();
char	*LibraryData();
#endif

struct objfunc {
	NAddr	addr;
#ifdef ANSI
	char	*(*func)(char *mem, NAddr *addr, char *out);
#else
	char	*(*func)();
#endif
} objects[] = {
	{0x02933, Real},
	{0x02977, Complex},
	{0x02a2c, String},
	{0x029e8, Array},	/* Real */
	{0x029e8, Array},	/* Complex */
	{0x02a74, List},
	{0x02e48, GlobalName},
	{0x02e6d, LocalName},
	{0x02d9d, Program},
	{0x02ab8, Algebraic},
	{0x02a4e, BinaryInt},
	{0x02b1e, Graphic},
	{0x02afc, Tagged},
	{0x02ada, Unit},
	{0x02e92, Xlib},
	{0x02a96, Directory},
	{0x02b40, Library},
	{0x02b62, Backup},
	{0x02e92, Command},	/* Function */
	{0x02e92, Command},
	{0x02911, Address},
	{0x02955, LongReal},
	{0x0299d, LongComplex},
	{0x02a0a, LinkedArray},
	{0x029bf, Character},
	{0x02dcc, Code},
	{0x02b88, LibraryData},
	{0, NULL}
};

NAddr
#ifdef ANSI
Object(char *mem, NAddr addr, char *out)
#else
Object(mem, addr, out)
char	*mem;
NAddr	addr;
char	*out;
#endif
{
	NAddr		n;
	NAddr		a;
	struct objfunc	*op;
	
	a = addr;
	n = GetInt(mem, &a, 5);
	for (op = objects; op->addr != 0; op++)
		if (op->addr == n)
			break;
			
	if (op->addr == 0) {
		(void) AppendStr(out, "Unknown Object");
		return(addr);
	}
	
	(*op->func)(mem, &a, out);
	return(a);
}

char *
#ifdef ANSI
Number(char *mem, NAddr *addr, char *out, int fl, int xl)
#else
Number(mem, addr, out, fl, xl)
char	*mem;
NAddr	*addr;
char	*out;
int	fl;
int	xl;
#endif
{
	int	fi, xi;
	Nybble	s, ip, xs;
	Nybble	x[5];
	Nybble	f[14];
	
	for (xi = 0; xi < xl; xi++)
		x[xi] = GetNybble(mem, (*addr)++);
		
	xs = GetNybble(mem, (*addr)++);
	
	for (fi = 0; fi < fl; fi++)
		f[fi] = GetNybble(mem, (*addr)++);
		
	ip = GetNybble(mem, (*addr)++);
	s = GetNybble(mem, (*addr)++);
	APPEND_CHAR(out, (s == 0) ? '+' : '-');
	APPEND_CHAR(out, hex[ip]);
	APPEND_CHAR(out, '.');
	while (--fi >= 0)
		APPEND_CHAR(out, hex[f[fi]]);
	
	APPEND_CHAR(out, 'E');
	APPEND_CHAR(out, (xs == 0) ? '+' : '-');
	while (--xi >= 0)
		APPEND_CHAR(out, hex[x[xi]]);	
		
	TERMINATE(out);
	return(out);
}

char *
#ifdef ANSI
Real(char *mem, NAddr *addr, char *out)
#else
Real(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(Number(mem, addr, out, 11, 2));
}

char *
#ifdef ANSI
Complex(char *mem, NAddr *addr, char *out)
#else
Complex(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	APPEND_CHAR(out, '(');
	out = Number(mem, addr, out, 11, 2);
	APPEND_COMMA(out);
	out = Number(mem, addr, out, 11, 2);
	APPEND_CHAR(out, ')');
	return(out);
}

char *
#ifdef ANSI
LongReal(char *mem, NAddr *addr, char *out)
#else
LongReal(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(Number(mem, addr, out, 14, 4));
}

char *
#ifdef ANSI
LongComplex(char *mem, NAddr *addr, char *out)
#else
LongComplex(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	APPEND_CHAR(out, '(');
	out = Number(mem, addr, out, 14, 4);
	APPEND_COMMA(out);
	out = Number(mem, addr, out, 14, 4);
	APPEND_CHAR(out, ')');
	return(out);
}

char *
#ifdef ANSI
String(char *mem, NAddr *addr, char *out)
#else
String(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	int	n;
	int	lim;
	char	c;
	NAddr	a;
	
	n = GetInt(mem, addr, 5) - 5;
	out = AppendStr(out, "String(");
	out = AppendDecInt(out, n);
	out = AppendStr(out, ") ");
	lim = (n > 16) ? 16 : n;
	a = *addr;
	out = AppendHexNyb(out, mem, &a, lim);
	if (lim < n)
		out = AppendStr(out, "...");
	
	out = AppendStr(out, " \"");
	lim /= 2;
	a = *addr;
	while (--lim >= 0) {
		c = GetInt(mem, &a, 2);
		if ((c < ' ') || (c > '~'))
			c = '.';
			
		APPEND_CHAR(out, c);
	}
	
	APPEND_CHAR(out, '"');
	TERMINATE(out);
	*addr += n;
	return(out);
}

char	*
#ifdef ANSI
Array(char *mem, NAddr *addr, char *out)
#else
Array(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char	*
#ifdef ANSI
List(char *mem, NAddr *addr, char *out)
#else
List(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char	*
#ifdef ANSI
GlobalName(char *mem, NAddr *addr, char *out)
#else
GlobalName(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char	*
#ifdef ANSI
LocalName(char *mem, NAddr *addr, char *out)
#else
LocalName(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char	*
#ifdef ANSI
Program(char *mem, NAddr *addr, char *out)
#else
Program(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char	*
#ifdef ANSI
Algebraic(char *mem, NAddr *addr, char *out)
#else
Algebraic(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char	*
#ifdef ANSI
BinaryInt(char *mem, NAddr *addr, char *out)
#else
BinaryInt(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	int	n;
	
	out = AppendStr(out, "BinInt(");
	n = GetInt(mem, addr, 5);
	n -= 5;
	out = AppendDecInt(out, n);
	out = AppendStr(out, ") ");
	out = AppendHexNyb(out, mem, addr, n);
	TERMINATE(out);
	return(out);
}

char *
#ifdef ANSI
Graphic(char *mem, NAddr *addr, char *out)
#else
Graphic(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char *
#ifdef ANSI
Tagged(char *mem, NAddr *addr, char *out)
#else
Tagged(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char *
#ifdef ANSI
Unit(char *mem, NAddr *addr, char *out)
#else
Unit(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char *
#ifdef ANSI
Xlib(char *mem, NAddr *addr, char *out)
#else
Xlib(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char *
#ifdef ANSI
Directory(char *mem, NAddr *addr, char *out)
#else
Directory(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char *
#ifdef ANSI
Library(char *mem, NAddr *addr, char *out)
#else
Library(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char *
#ifdef ANSI
Backup(char *mem, NAddr *addr, char *out)
#else
Backup(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char *
#ifdef ANSI
Command(char *mem, NAddr *addr, char *out)
#else
Command(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}


char	*
#ifdef ANSI
Address(char *mem, NAddr *addr, char *out)
#else
Address(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	out = AppendStr(out, "Address(5) ");
	out = AppendHexNyb(out, mem, addr, 5);
	TERMINATE(out);
	return(out);
}

char	*
#ifdef ANSI
LinkedArray(char *mem, NAddr *addr, char *out)
#else
LinkedArray(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char	*
#ifdef ANSI
Character(char *mem, NAddr *addr, char *out)
#else
Character(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	int	c;
	NAddr	a;
	
	out = AppendStr(out, "Character(2) ");
	a = *addr;
	out = AppendHexNyb(out, mem, addr, 2);
	out = AppendStr(out, " '");
	c = GetInt(mem, &a, 2);
	if ((c < ' ') || (c > '~'))
		c = '.';
	
	APPEND_CHAR(out, c);
	APPEND_CHAR(out, '\'');
	TERMINATE(out);
	return(out);
}

char	*
#ifdef ANSI
Code(char *mem, NAddr *addr, char *out)
#else
Code(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}

char	*
#ifdef ANSI
LibraryData(char *mem, NAddr *addr, char *out)
#else
LibraryData(mem, addr, out)
char	*mem;
NAddr	*addr;
char	*out;
#endif
{
	return(out);
}
