[comp.sys.m6809] 6809 disassembler

psb@eecea.eece.ksu.edu (Phil Buckland) (04/08/89)

Does anyone on the net know where I can acquire a public domain disassembler
for the 6809?  I would prefer a disassembler which runs under UNIX, but would
accept one for MS-DOS machines.  Please respond by E-mail.  Thanks in
advance.

	Phil Buckland		psb@eecea.eece.ksu.edu

knudsen@ihlpl.ATT.COM (Knudsen) (04/11/89)

In article <613@eecea.eece.ksu.edu>, psb@eecea.eece.ksu.edu (Phil Buckland) writes:

> for the 6809?  I would prefer a disassembler which runs under UNIX, but would
> accept one for MS-DOS machines.  Please respond by E-mail.  Thanks in

Uh, say, have you considered running under OS9?
Good ASSemblers and C compiler there too.

I did see the source for a two-pass disassembler some years ago on the
net.  Of course it was for OS9, but you could convert it U**x (I
think it was in C), and even to Mess-DOS if you don't use your real
name on the Net ;-).
-- 
Mike Knudsen  Bell Labs(AT&T)   att!ihlpl!knudsen
Round and round the while() loop goes;
"Whether it stops," Turing says, "no one knows!"

psb@eecea.eece.ksu.edu (Phil Buckland) (04/12/89)

In article <10049@ihlpl.ATT.COM> knudsen@ihlpl.ATT.COM (Knudsen) writes:
>In article <613@eecea.eece.ksu.edu>, psb@eecea.eece.ksu.edu (Phil Buckland)
> writes:
>> for the 6809?  I would prefer a disassembler which runs under UNIX, but
>> would accept one for MS-DOS machines.  Please respond by E-mail.  Thanks in
>
>Uh, say, have you considered running under OS9?
>Good ASSemblers and C compiler there too.

	I am responsible for repairing computer (and related) equipment for
the college of engineering here at KSU.  I have a terminal which uses the 6809
and for which I'd like to have the code in ROM disassembled, to aid in the
development of test routines to repair said terminal.  Since I only have access
to UNIX and MS-DOS machines here, running under OS9 is not possible. *sigh*

Phil Buckland			psb@eecea.eece.ksu.edu

wynkoop@esquire.UUCP (Brett Wynkoop) (04/13/89)

>
>	I am responsible for repairing computer (and related) equipment for
>the college of engineering here at KSU.  I have a terminal which uses the 6809
>and for which I'd like to have the code in ROM disassembled, to aid in the
>development of test routines to repair said terminal.  Since I only have access
>to UNIX and MS-DOS machines here, running under OS9 is not possible. *sigh*
>
>Phil Buckland			psb@eecea.eece.ksu.edu


Greeting-
     I think getting a Radio Shack color computer, disk drives and OS9 (For
which I know of a few very good PD dissamblers) might be cheaper than
getting a dissambelr that runs under MS-DOS or Unix.  The COCO can be had
for about $150 mail order, and a floppy controler can be had for $75-130
depending on features desired.  OS-9 will set you back about another $85.

-Brett

archambe@sombre.iro.umontreal.ca (Benoit Archambault) (05/13/89)

	Here's disa 1.00 as you requested. You can compile the source
	code as follows: cc disa.c -O -o disa

	This version does not disassemble the code between the
	start of OS-9 modules and the entry point. It will be
	fixed with the futur versions.

	Please feel free to make any comments.

						Have fun !

------------------------------CUT HERE---------------------------------

/* ****************************************************	*/
/*			disa  1.00			*/
/*		6809 disassembler for UNIX		*/
/*		Written by: Benoit Archambault		*/
/*							*/
/*		Use hereby authorized by anyone		*/
/*		except sale.				*/
/*							*/
/* archambe@iro.umontreal.ca		May 1989	*/
/* **************************************************** */ 

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
/*
	Modes d'adressages du 6809
*/
#define IMMEDIAT		0
#define DIRECT			1
#define INDEXE			2
#define ETENDU			3
#define INHERENT		4
#define	REL			5
#define UNKNOWN			7
#define	PSEUDO			8

/*
	Champs de la table des instructions
*/
#define MNEMONIQUE		0
#define OPCODE			1
#define LONGUEUR		2
#define CYCLE			3
#define MODE			4
#define NCALL			92
#define INOMBRE			97
#define BNOMBRE			34

/*
	Erreurs et conditions
*/
#define FALSE			0
#define TRUE			1
#define OK			1
#define BAD			-1

/*
	Modes d'adressage indexe du 6809
*/
#define INC_1			0x00
#define INC_2			0x01
#define DEC_1			0x02
#define DEC_2			0x03
#define NO_OFFSET		0x04
#define B_OFFSET		0x05
#define A_OFFSET		0x06
#define D_OFFSET		0x0b
#define HUIT_BIT_OFFSET		0x08
#define SEIZE_BIT_OFFSET	0x09
#define HUIT_OFFSET_PC		0x0c
#define SEIZE_OFFSET_PC		0x0d
#define ETENDU_INDIRECT		0x0f

/*
	Entete d'un module OS-9
*/
#define	PGRM_MODULE		1
#define	SUBRT_MODULE		2
#define	MULTI_MODULE		3
#define	DATA_MODULE		4
#define	USER_MODULE		5
#define	SYSTEM_MODULE		12
#define	FILEMAN_MODULE		13
#define	DRIVER_MODULE		14
#define	DD_MODULE		15
#define	DATA_CODE		0
#define	OBJECT_CODE		1
#define	BASIC09			2
#define	PASCAL			3
#define	COBOL			4
#define	FUTURE			5
#define	SYNC			0
#define	MODULE_SIZE		2
#define	NAME_OFFSET		4
#define	TYPE_LANGUAGE		6
#define	ATT_REVISION		7
#define	HEADER_CHECK		8
#define	EXECUTION_OFFSET	9
#define	STORAGE_SIZE		11


/*
	Champs des instructions
*/
typedef struct {
	char *mnemonique;
	int opcode[5];
	int longueur[5];
	int cycle[5];
	int mode[5];
} Elements ;


/*
	Champs des branchements relatifs
*/
typedef struct {
	char *mnemonique;
	int opcode;
	int longueur;
	int cycle;
} Branchement ;



/*
	Champs d'un module
*/
struct	os9module {
	int	sync;
	int	msize;
	int	nameoff;
	int	typelang;
	int	attrev;
	int	headcheck;
	int	execoff;
	int	datasize;
};


/*
	Champs d'un appel systeme
*/
typedef struct {
	char	*call;
	int	callcode;
} Syscall;


/*
	Champs d'une ligne desassemble
*/
struct ligne {
	char	pcstr[16];
	char	codestr[16];
	char	istr[8];
	char	oprstr[16];
	char	cyclestr[8];
};


/*
	Initialisation de la tables des instructions
*/
Elements base[] = {
{ "abx",  {0x00,0x00,0x00,0,0x3a}, {0,0,0,0,1}, {0,0,0,0,3}, {0,0,0,0,1} },
{ "adca", {0x89,0x99,0xa9,0xb9,0}, {2,2,2,2,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "adcb", {0xc9,0xd9,0xe9,0xf9,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "adda", {0x8b,0x9b,0xab,0xbb,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "addb", {0xcb,0xdb,0xeb,0xfb,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "addd", {0xc3,0xd3,0xe3,0xf3,0}, {3,2,2,3,0}, {4,6,6,7,0}, {1,1,1,1,0} },
{ "anda", {0x84,0x94,0xa4,0xb4,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "andb", {0xc4,0xd4,0xe4,0xf4,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "andcc",{0x1c,0x00,0x00,0x00,0}, {2,0,0,0,0}, {3,0,0,0,0}, {1,0,0,0,0} },
{ "asla", {0x00,0x00,0x00,0,0x48}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "aslb", {0x00,0x00,0x00,0,0x58}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "asl" , {0x00,0x08,0x68,0x78,0}, {0,2,2,3,0}, {0,6,6,7,0}, {0,1,1,1,0} },
{ "asra", {0x00,0x00,0x00,0,0x47}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "asrb", {0x00,0x00,0x00,0,0x57}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "asr" , {0x00,0x07,0x67,0x77,0}, {0,2,2,3,0}, {0,6,6,7,0}, {0,1,1,1,0} },
{ "bita", {0x85,0x95,0xa5,0xb5,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "bitb", {0xc5,0xd5,0xe5,0xf5,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "clra", {0x00,0x00,0x00,0,0x4f}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "clrb", {0x00,0x00,0x00,0,0x5f}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "clr" , {0x00,0x0f,0x6f,0x7f,0}, {0,2,2,3,0}, {0,6,6,7,0}, {0,1,1,1,0} },
{ "cmpa", {0x81,0x91,0xa1,0xb1,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "cmpb", {0xc1,0xd1,0xe1,0xf1,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "cmpx", {0x8c,0x9c,0xac,0xbc,0}, {3,2,2,3,0}, {4,6,6,7,0}, {1,1,1,1,0} },
{ "cmpd", {0x1083,0x1093,0x10a3,0x10b3,0},{4,3,3,4,0},{5,7,7,8,0},{1,1,1,1,0}},
{ "cmps", {0x118c,0x119c,0x11ac,0x11bc,0},{4,3,3,4,0},{5,7,7,8,0},{1,1,1,1,0}},
{ "cmpu", {0x1183,0x1193,0x11a3,0x11b3,0},{4,3,3,4,0},{5,7,7,8,0},{1,1,1,1,0}},
{ "cmpy", {0x118c,0x119c,0x11ac,0x11bc,0},{4,3,3,4,0},{5,7,7,8,0},{1,1,1,1,0}},
{ "coma", {0x00,0x00,0x00,0,0x43}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "comb", {0x00,0x00,0x00,0,0x53}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "com" , {0x00,0x03,0x63,0x73,0}, {0,2,2,3,0}, {0,6,6,7,0}, {0,1,1,1,0} },
{ "cwai", {0x3c,0x00,0x00,0x00,0}, {1,0,0,0,0}, {20,0,0,0,0},{1,0,0,0,0} },
{ "daa" , {0x00,0x00,0x00,0,0x19}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "deca", {0x00,0x00,0x00,0,0x4a}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "decb", {0x00,0x00,0x00,0,0x5a}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "dec" , {0x00,0x0a,0x6a,0x7a,0}, {0,2,2,3,0}, {0,6,6,7,0}, {0,1,1,1,0} },
{ "eora", {0x88,0x98,0xa8,0xb8,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "eorb", {0xc8,0xd8,0xe8,0xf8,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "exg" , {0x1e,0x00,0x00,0x00,0}, {2,0,0,0,0}, {8,0,0,0,0}, {1,0,0,0,0} },
{ "inca", {0x00,0x00,0x00,0,0x4c}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "incb", {0x00,0x00,0x00,0,0x5c}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "inc" , {0x00,0x0c,0x6c,0x7c,0}, {0,2,2,3,0}, {0,6,6,7,0}, {0,1,1,1,0} },
{ "jmp" , {0x00,0x0e,0x6e,0x7e,0}, {0,2,2,3,0}, {0,3,3,4,0}, {0,1,1,1,0} },
{ "jsr" , {0x00,0x9d,0xad,0xbd,0}, {0,2,2,3,0}, {0,7,7,8,0}, {0,1,1,1,0} },
{ "lda" , {0x86,0x96,0xa6,0xb6,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "ldb" , {0xc6,0xd6,0xe6,0xf6,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "ldd" , {0xcc,0xdc,0xec,0xfc,0}, {3,2,2,3,0}, {3,5,5,6,0}, {1,1,1,1,0} },
{ "lds" , {0x10ce,0x10de,0x10ee,0x10fe,0},{4,3,3,4,0},{4,6,6,7,0},{1,1,1,1,0}},
{ "ldy" , {0x108e,0x109e,0x10ae,0x10be,0},{4,3,3,4,0},{4,6,6,7,0},{1,1,1,1,0}},
{ "ldu" , {0xce,0xde,0xee,0xfe,0}, {3,2,2,3,0}, {3,5,5,6,0}, {1,1,1,1,0} },
{ "ldx" , {0x8e,0x9e,0xae,0xbe,0}, {3,2,2,3,0}, {3,5,5,6,0}, {1,1,1,1,0} },
{ "leas", {0x00,0x00,0x32,0x00,0}, {0,0,2,0,0}, {0,0,4,0,0}, {0,0,1,0,0} },
{ "leau", {0x00,0x00,0x33,0x00,0}, {0,0,2,0,0}, {0,0,4,0,0}, {0,0,1,0,0} },
{ "leax", {0x00,0x00,0x30,0x00,0}, {0,0,2,0,0}, {0,0,4,0,0}, {0,0,1,0,0} },
{ "leay", {0x00,0x00,0x31,0x00,0}, {0,0,2,0,0}, {0,0,4,0,0}, {0,0,1,0,0} },
{ "lsra", {0x00,0x00,0x00,0,0x44}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "lsrb", {0x00,0x00,0x00,0,0x54}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "lsr" , {0x00,0x04,0x64,0x74,0}, {0,2,2,3,0}, {0,6,6,7,0}, {0,1,1,1,0} },
{ "mul" , {0x00,0x00,0x00,0,0x3d}, {0,0,0,0,1},{0,0,0,0,11}, {0,0,0,0,1} },
{ "nega", {0x00,0x00,0x00,0,0x40}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "negb", {0x00,0x00,0x00,0,0x50}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "neg" , {0x00,0x00,0x60,0x70,0}, {0,2,2,3,0}, {0,6,6,7,0}, {0,1,1,1,0} },
{ "nop" , {0x00,0x00,0x00,0,0x12}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "ora" , {0x8a,0x9a,0xaa,0xba,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "orb" , {0xca,0xda,0xea,0xfa,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "orcc", {0x1a,0x00,0x00,0x00,0}, {2,0,0,0,0}, {3,0,0,0,0}, {1,0,0,0,0} },
{ "pshs", {0x34,0x00,0x00,0x00,0}, {2,0,0,0,0}, {5,0,0,0,0}, {1,0,0,0,0} },
{ "pshu", {0x36,0x00,0x00,0x00,0}, {2,0,0,0,0}, {5,0,0,0,0}, {1,0,0,0,0} },
{ "puls", {0x35,0x00,0x00,0x00,0}, {2,0,0,0,0}, {5,0,0,0,0}, {1,0,0,0,0} },
{ "pulu", {0x37,0x00,0x00,0x00,0}, {2,0,0,0,0}, {5,0,0,0,0}, {1,0,0,0,0} },
{ "rola", {0x00,0x00,0x00,0,0x49}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "rolb", {0x00,0x00,0x00,0,0x59}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "rol" , {0x00,0x09,0x69,0x79,0}, {0,2,2,3,0}, {0,6,6,7,0}, {0,1,1,1,0} },
{ "rora", {0x00,0x00,0x00,0,0x46}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "rorb", {0x00,0x00,0x00,0,0x56}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "ror" , {0x00,0x06,0x66,0x76,0}, {0,2,2,3,0}, {0,6,6,7,0}, {0,1,1,1,0} },
{ "rti" , {0x00,0x00,0x00,0,0x3b}, {0,0,0,0,1}, {0,0,0,0,6}, {0,0,0,0,1} },
{ "rts" , {0x00,0x00,0x00,0,0x39}, {0,0,0,0,1}, {0,0,0,0,5}, {0,0,0,0,1} },
{ "sbca", {0x82,0x92,0xa2,0xb2,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "sbcb", {0xc2,0xd2,0xe2,0xf2,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "sex" , {0x00,0x00,0x00,0,0x1d}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "sta" , {0x00,0x97,0xa7,0xb7,0}, {0,2,2,3,0}, {0,4,4,5,0}, {0,1,1,1,0} },
{ "stb" , {0x00,0xd7,0xe7,0xf7,0}, {0,2,2,3,0}, {0,4,4,5,0}, {0,1,1,1,0} },
{ "std" , {0x00,0xdd,0xed,0xfd,0}, {0,2,2,3,0}, {0,5,5,6,0}, {0,1,1,1,0} },
{ "stx" , {0x00,0x9f,0xaf,0xbf,0}, {0,2,2,3,0}, {0,5,5,6,0}, {0,1,1,1,0} },
{ "stu" , {0x00,0xdf,0xef,0xff,0}, {0,2,2,3,0}, {0,5,5,6,0}, {0,1,1,1,0} },
{ "sts" , {0x0000,0x10df,0x10ef,0x10ff,0},{0,3,3,4,0},{0,6,6,7,0},{0,1,1,1,0}},
{ "sty" , {0x0000,0x109f,0x10af,0x10bf,0},{0,3,3,4,0},{0,6,6,7,0},{0,1,1,1,0}},
{ "suba", {0x80,0x90,0xa0,0xb0,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "subb", {0xc0,0xd0,0xe0,0xf0,0}, {2,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "subd", {0x83,0x93,0xa3,0xb3,0}, {3,2,2,3,0}, {2,4,4,5,0}, {1,1,1,1,0} },
{ "swi" , {0x00,0x00,0x00,0,0x3f}, {0,0,0,0,1}, {0,0,0,0,19}, {0,0,0,0,1} },
{ "os9" , {0x00,0x00,0x00,0,0x103f},{0,0,0,0,3}, {0,0,0,0,20},{0,0,0,0,1} },
{ "swi3", {0x00,0x00,0x00,0,0x113f},{0,0,0,0,2}, {0,0,0,0,20},{0,0,0,0,1} },
{ "sync", {0x00,0x00,0x00,0,0x13}, {0,0,0,0,1}, {0,0,0,0,4}, {0,0,0,0,1} },
{ "tfr" , {0x1f,0x00,0x00,0,0x00}, {2,0,0,0,0}, {6,0,0,0,0}, {1,0,0,0,0} },
{ "tsta", {0x00,0x00,0x00,0,0x4d}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "tstb", {0x00,0x00,0x00,0,0x5d}, {0,0,0,0,1}, {0,0,0,0,2}, {0,0,0,0,1} },
{ "tst" , {0x00,0x0d,0x6d,0x7d,0}, {0,2,2,3,0}, {0,6,6,7,0}, {0,1,1,1,0} },
};


/*
	Initialisation de la table des branchements relatifs
*/
Branchement saut[]= {
{ "bcc", 0x24, 2, 3 },
{ "lbcc", 0x1024, 4, 5 },
{ "bcs", 0x25, 2, 3 },
{ "lbcs", 0x1025, 4, 5 },
{ "beq", 0x27, 2, 3 },
{ "lbeq", 0x1027, 4, 5 },
{ "bge", 0x2c, 2, 3 },
{ "lbge", 0x102c, 4, 5 },
{ "bgt", 0x2e, 2, 3 },
{ "lbgt", 0x102e, 4, 5 },
{ "bhi", 0x22, 2, 3 },
{ "lbhi", 0x1022, 4, 5 },
{ "ble", 0x2f, 2, 3 },
{ "lble", 0x102f, 4, 5 },
{ "bls", 0x23, 2, 3 },
{ "lbls", 0x1023, 4, 5 },
{ "blt", 0x2d, 2, 3 },
{ "lblt", 0x102d, 4, 5 },
{ "bmi", 0x2b, 2, 3 },
{ "lbmi", 0x102d, 4, 5 },
{ "bne", 0x26, 2, 3 },
{ "lbne", 0x1026, 4, 5 },
{ "bpl", 0x2a, 2, 3 },
{ "lbpl", 0x102a, 4, 5 },
{ "bra", 0x20, 2, 3 },
{ "lbra", 0x16, 3, 5 },
{ "brn", 0x21, 2, 3 },
{ "lbrn", 0x1021, 4, 5 },
{ "bsr", 0x8d, 2, 7 },
{ "lbsr", 0x17, 3, 9 },
{ "bvc", 0x28, 2, 3 },
{ "lbvc", 0x1028, 4, 5 },
{ "bvs", 0x29, 2, 3 },
{ "lbvs", 0x1029, 4, 5 },
};

/*
	Initialisation de la table des appels systeme
*/
Syscall call[]= {
	{"F$Alarm", 0x1e},
	{"F$AllBit", 0x13},
	{"F$Chain", 0x05},
	{"F$CmpNam", 0x11},
	{"F$CpyMem", 0x1b},
	{"F$CRC", 0x17},
	{"F$DelBit", 0x14},
	{"F$Exit", 0x06},
	{"F$Fork", 0x03},
	{"F$GBlkMp", 0x19},
	{"F$GModDr", 0x1a},
	{"F$GPrDsc", 0x18},
	{"F$Icpt", 0x09},
	{"F$ID", 0x0c},
	{"F$Link", 0x00},
	{"F$Load", 0x01},
	{"F$Mem", 0x07},
	{"F$NMLink", 0x21},
	{"F$NMLoad", 0x22},
	{"F$Perr", 0x0f},
	{"F$PrsNam", 0x10},
	{"F$SchBit", 0x12},
	{"F$Send", 0x08},
	{"F$Sleep", 0x0a},
	{"F$SPrior", 0x0d},
	{"F$SSWI", 0x0e},
	{"F$STime", 0x16},
	{"F$SUser", 0x1c},
	{"F$Time", 0x15},
	{"F$UnLink", 0x02},
	{"F$UnLoad", 0x1d},
	{"F$Wait", 0x04},
	{"I$Attach", 0x80},
	{"I$Chgdir", 0x86},
	{"I$Close", 0x8f},
	{"I$Create", 0x83},
	{"I$Delete", 0x87},
	{"I$DeletX", 0x90},
	{"I$Detach", 0x81},
	{"I$Dup", 0x82},
	{"I$GetStt", 0x8d},
	{"I$MakDir", 0x85},
	{"I$Open", 0x84},
	{"I$Read", 0x89},
	{"I$ReadLn", 0x8b},
	{"I$Seek", 0x88},
	{"I$SetStt", 0x8e},
	{"I$Write", 0x8a},
	{"I$WritLn", 0x8c},
	{"F$All64", 0x30},
	{"F$AlHRam", 0x53},
	{"F$AllImg", 0x3a},
	{"F$AllPrc", 0x4b},
	{"F$AllRam", 0x39},
	{"F$AllTsk", 0x3f},
	{"F$AProc", 0x3c},
	{"F$Boot", 0x35},
	{"F$BtMem", 0x36},
	{"F$ClrBlk", 0x50},
	{"F$DATLog", 0x44},
	{"F$DelImg", 0x3b},
	{"F$DelPrc", 0x4c},
	{"F$DelRAM", 0x51},
	{"F$DelTsk", 0x40},
	{"F$ELink", 0x4d},
	{"F$FModul", 0x4e},
	{"F$Find64", 0x2f},
	{"F$FreeHB", 0x3e},
	{"F$FreeLB", 0x3d},
	{"F$GCMDir", 0x52},
	{"F$GProcP", 0x37},
	{"F$IODel", 0x33},
	{"F$IOQu", 0x2b},
	{"F$IRQ", 0x2a},
	{"F$LDABX", 0x49},
	{"F$LDAXY", 0x46},
	{"F$LDDDXY", 0x48},
	{"F$MapBlk", 0x4f},
	{"F$Move", 0x38},
	{"F$NProc", 0x2d},
	{"F$RelTsk", 0x43},
	{"F$ResTsk", 0x42},
	{"F$Ret64", 0x31},
	{"F$SetImg", 0x3c},
	{"F$SetTsk", 0x41},
	{"F$SLink", 0x34},
	{"F$SRqMem", 0x28},
	{"F$SRtMem", 0x29},
	{"F$SSvc", 0x32},
	{"F$STABX", 0x4a},
	{"F$VIRQ", 0x27},
	{"F$VModul", 0x2e},
};

struct ligne sl, *outline= &sl;

int	pc;
int	line;		/* Ligne dans la table des instructions */
int	position;	/* Position dans les modes d'adressages */
int	iindex;		/* Octet d'indexage */
int	pcflag=1, codeflag=1, cycleflag=1; /* Flag d'options */
main (argc, argv)
	int	argc;
	char	*argv[];
{
	int	os9flag=1, binflag=0, errflag=0;
	int	fetch[5], flenght=0, type, i, c;
	long	offset= 0L;
	char	nom[32], titre[32], filename;
	struct	os9module module, *os9file= &module;
	struct	stat buffer, *fbuffer= &buffer;
	FILE	*fp, *fopen();
	extern	char	*optarg;
	extern	int	optind, opterr;

	opterr=0;
	while ((c= getopt(argc, argv, "9bphec")) != EOF)
		switch (c) {
			case '9':
				binflag=0;
				os9flag=1;
				break;

			case 'b':
				os9flag=0;
				binflag=1;
				break;


			case 'p':
				pcflag=0;
				break;

			case 'c':
				codeflag=0;
				break;

			case 'e':
				cycleflag=0;
				break;

			case 'h':
				++errflag;
				break;

			case '?':
				++errflag;
		}

	if (errflag || argc < 2)
		usage();

	if ((fp= fopen(argv[optind], "r")) == NULL) {
		fprintf (stderr, "can't open '%s'\n", argv[optind]);
		exit(0);
	}

	if (os9flag) {
		if ((c= os9stat(argv[optind], os9file)) == -1) {
			fprintf (stderr, "'%s' is not an OS-9 module\n",argv[optind]);
			exit(0);
		}

		offset= os9file->execoff;
		pc= os9file->execoff;

		while (pc < os9file->msize-3) {
			fseek (fp, offset, 0);
			flenght= 0;
			while ((c= getc(fp)) != EOF && flenght<5) {
				fetch[flenght]= c;
				++flenght;
			}

			type= ifetch(fetch, flenght);
			operand(fetch, position, type);
			code (fetch, type);
			format(outline);
			pc += type;
			offset= pc;
		}
		fetch[0]= getc(fp);
		fetch[1]= getc(fp);
		fetch[2]= getc(fp);
		pformat("emod", "\0");
		pformat("equ", "*");
		fclose(fp);
	}

	if (binflag) {
		stat (argv[optind], fbuffer);
		pc=0;
		while (pc < fbuffer->st_size) {
			flenght= 0;
			fseek(fp, offset, 0);
			while ((c= getc(fp)) != EOF && flenght<5) {
				fetch[flenght]= c;
				++flenght;
			}

			type= ifetch(fetch, flenght);
			operand(fetch, position, type);
			code(fetch, type);
			format(outline);
			pc += type;
			offset= pc;
		}
		printf ("\n-- End of file\n");
		fclose(fp);
	}
}
/*
	Cette procedure trouve la longueur
	d'une instruction legale contenue
	dans le tampon d'instruction.
*/

int ifetch (fetch, len)
	int	fetch[], len;
{
	int	opcode, tmp, lenght=0, type;

	opcode= fetch[0];
	if (opcode == 0x10 || opcode == 0x11) {
		opcode= fetch[1]+256*opcode;
		if (len < 3)
			return(BAD);
	}

	type= search(opcode);

	switch (type) {

		case REL:
			lenght= saut[line].longueur;
			sprintf(outline->istr, "%s", saut[line].mnemonique);
			sprintf(outline->cyclestr, "~%d", saut[line].cycle);
			position= REL;
			break;

		case OK:
			if (position == INDEXE) {
				if (opcode > 0xff)
					tmp= fetch[2];
				else
					tmp= fetch[1];
				iindex= tmp;
				if (tmp > 0x7f) {
					tmp= tmp&0x0f;
					if (tmp == 0x08 || tmp == 0x0c)
						lenght= 1;
					if (tmp==0x0d ||tmp==0x0f|| tmp==0x09)
						lenght=2;
				}
			}
			lenght += base[line].longueur[position];
			sprintf(outline->istr, "%s",  base[line].mnemonique);
			sprintf(outline->cyclestr, "~%d", base[line].cycle[position]);
			break;

		case UNKNOWN:
			position= UNKNOWN;
			lenght= 1;
			sprintf(outline->istr, "fcb");
			outline->cyclestr[0]= '\0';
			break;
	}
	return(lenght);
}
/*
	Cette procedure recherche l'instruction
	contenue dans le tampon d'instruction
	et verifie qu'elle fait partie du jeu
	d'instruction du 6809.
*/

int search(instruction)
	int	instruction;
{
	int	j, k, flag= FALSE;

	for (k=0; k<INOMBRE && flag == FALSE; ++k)
	for (j=0; j<=INHERENT && flag == FALSE; ++j)
		if ((instruction == base[k].opcode[j]) && base[k].mode[j])
			flag= TRUE;

	if ( flag == TRUE) {
		line= --k;
		position= --j;
		return(OK);
	}

	for (k=0; k<BNOMBRE && flag == FALSE; ++k)
		if (instruction == saut[k].opcode)
			flag= TRUE;


	if ( flag == TRUE) {
		line= --k;
		return(REL);
	}

	return(UNKNOWN);
}
/*
	Cette procedure trouve l'operande
	d'une instruction en fonction de
	son mode d'adressage.
*/

int operand (fetch, mode, lenght)
	int	fetch[], mode, lenght;
{
	static	char *exgtfr[]= {"d","x","y","u","s","pc","\0","\0","a","b",					"cc","dp"};
	static	char *pushpull[]= {"cc,","a,","b,","dp,","x,","y,","u,","pc,"};
	static	char regs[]= {'x', 'y', 'u', 's' };
	char	tmp[32];
	short	offset, mask, i;

	switch (mode) {

	/* Mode d'adressage relatif (BNE, BEQ, LBCC ...) */

		case REL:
			if (lenght > 2)
				offset= fetch[lenght-2]*256+fetch[lenght-1];
			else  {
				offset= fetch[1];
				if (offset > 0x7f)
					offset |= 0xff00;
			}
			sprintf(outline->oprstr,">%04x",(offset+pc+lenght)&0xffff);
			break;

		case UNKNOWN:
			sprintf(outline->oprstr, "$%02x", fetch[0]);
			break;

		case INHERENT:
			if (fetch[0]== 0x10 && fetch[1]== 0x3f) {
				offset= 0;
				while (offset != NCALL) {
					if (fetch[2]== call[offset].callcode) {
						sprintf(outline->oprstr, "%s", call[offset].call);
						break;
					}
					++offset;
					sprintf(outline->oprstr, "$%02x", fetch[2]);
				}
			}
			else
				outline->oprstr[0]= '\0';
			break;

	/* Mode d'adressage direct (LDA  <00 ...) */

		case DIRECT:
			sprintf (outline->oprstr, "<%02x", fetch[lenght-1]);
			break;

	/* Mode d'adressage etendu (LDA >0000 ...) */

		case ETENDU:
		sprintf(outline->oprstr,">%04x",fetch[lenght-2]*256+fetch[lenght-1]);
		break;

	/* Mode d'adressage IMMEDIAT (LDA #$7F, LDX #$0000 ...)
	   Trappe speciale pour instruction PSHS, PSHU, EXG et TFR */

		case IMMEDIAT:
			if (fetch[0] == 0x1e || fetch[0] == 0x1f) {
				sprintf(outline->oprstr,"%s,%s", exgtfr[fetch[1]>>4] , exgtfr[fetch[1]&0x0f]);
				break;
			}

			if (fetch[0] >= 0x34 && fetch[0] <= 0x38) {
				outline->oprstr[0]= '\0';
				switch (fetch[0]&0x01) {

				case 0:

				for(mask= 0x80, i=7; i>=0; mask >>=1, --i)
					if(fetch[1]&mask)
						strcat(outline->oprstr, pushpull[i]);
				break;

				case 1:
				for(mask= 0x01, i=0; i< 8; mask <<=1, ++i)
					if(fetch[1]&mask)
						strcat(outline->oprstr, pushpull[i]);
				break;
				}
			outline->oprstr[(strlen(outline->oprstr))-1]= '\0';
			break;
			}

			if (lenght > 2)
				sprintf(outline->oprstr,"#$%04x",fetch[lenght-2]*256+fetch[lenght-1]);

			else
				sprintf(outline->oprstr,"#$%02x",fetch[1]);
			break;

	/* Mode d'adressage indexe (LDA ,x+ STD ,y++ ... ) */

		case INDEXE:
			if (iindex < 128) {
				if ((iindex & 0x10))
					sprintf(outline->oprstr,"-%d,%c",(((iindex|0xe0)^0xff)&0x0f)+1, regs[(iindex&0x60)>>5]);
				else
					sprintf(outline->oprstr,"%d,%c",(iindex&0x0f), regs[(iindex&0x60)>>5]);
			}

			else {
				switch((iindex & 0x0f)) {

					case INC_1:
						sprintf(outline->oprstr,",%c+",regs[(iindex&0x60)>>5]);
						break;

					case INC_2:
						sprintf(outline->oprstr,",%c++",regs[(iindex&0x60)>>5]);
						break;

					case DEC_1:
						sprintf(outline->oprstr,",-%c",regs[(iindex&0x60)>>5]);
						break;

					case DEC_2:
						sprintf(outline->oprstr,",--%c",regs[(iindex&0x60)>>5]);
						break;

					case NO_OFFSET:
						sprintf(outline->oprstr,",%c",regs[(iindex&0x60)>>5]);
						break;

					case B_OFFSET:
						sprintf(outline->oprstr,"b,%c",regs[(iindex&0x60)>>5]);
						break;

					case A_OFFSET:
						sprintf(outline->oprstr,"a,%c",regs[(iindex&0x60)>>5]);
						break;

					case D_OFFSET:
						sprintf(outline->oprstr,"d,%c",regs[(iindex&0x60)>>5]);
						break;

					case HUIT_BIT_OFFSET:
						if (fetch[lenght-1] > 0x7f)
							fetch[lenght-1]= fetch[lenght-1]-0x100;
						sprintf(outline->oprstr,"%d,%c",fetch[lenght-1], regs[(iindex&0x60)>>5]);
						break;

					case SEIZE_BIT_OFFSET:
						sprintf(outline->oprstr,"$%04x,%c",fetch[lenght-1]+256*fetch[lenght-2], regs[(iindex&0x60)>>5]);
						break;

					case HUIT_OFFSET_PC:
						if (fetch[lenght-1] > 0x7f)
							fetch[lenght-1] |= 0xff00;
						sprintf(outline->oprstr,">%04x,pcr",fetch[lenght-1]+pc+lenght);
						break;

					case SEIZE_OFFSET_PC:
						sprintf(outline->oprstr,">%04x,pcr",(fetch[lenght-1]+fetch[lenght-2]*256+pc+lenght)&0xffff);
						break;

					case ETENDU_INDIRECT:
						sprintf(outline->oprstr,"$%04x",fetch[lenght-1]+256*fetch[lenght-2]);
						break;

				}
				if ((iindex&0x10)) {
					sprintf(tmp, "[%s]", outline->oprstr);
					sprintf(outline->oprstr, "%s", tmp);
				}
			}

			break;
	}
}
/*
	Lit l'entete d'un module OS-9
*/


os9stat (filename, os9file) 
	struct	os9module *os9file;
	char	*filename;
{
	FILE	*fp, *fopen();
	int	i, c;

	if ((fp= fopen(filename, "r")) == NULL)
		return(-1);

	for (i=SYNC; i< STORAGE_SIZE+2;++i ) {
		switch (i) {

			case SYNC:
			case MODULE_SIZE:
			case NAME_OFFSET:
			case EXECUTION_OFFSET:
			case STORAGE_SIZE:
				c= getc(fp);
				break;

			case SYNC+1:
				os9file->sync= getc(fp)+256*c;
				break;

			case MODULE_SIZE+1:
				os9file->msize= getc(fp)+256*c;
				break;

			case NAME_OFFSET+1:
				os9file->nameoff= getc(fp)+256*c;
				break;

			case TYPE_LANGUAGE:
				os9file->typelang= getc(fp);
				break;

			case ATT_REVISION:
				os9file->attrev= getc(fp);
				break;

			case HEADER_CHECK:
				os9file->headcheck= getc(fp);
				break;

			case EXECUTION_OFFSET+1:
				os9file->execoff= getc(fp)+256*c;
				break;

			case STORAGE_SIZE+1:
				os9file->datasize= getc(fp)+256*c;
				break;
		}
	}
	fclose(fp);
	if (os9file->sync != 0x87cd)
		return(-1);
	return(0);
}
/*
	Formatte une ligne de code
*/
format(line)
	struct ligne *line;
{
	if (pcflag) {
		sprintf (line->pcstr, "%04x", pc);
		printf ("%s", line->pcstr);
		space (8-strlen(line->pcstr));
	}

	if (codeflag) {
		printf ("%s", line->codestr);
		space (16-strlen(line->codestr));
	}

	printf ("%s", line->istr);
	space (8-strlen(line->istr));

	printf ("%s", line->oprstr);
	space (16-strlen(line->oprstr));

	if (cycleflag) {
		printf ("%s", line->cyclestr);
		space (8-strlen(line->cyclestr));
	}

	printf ("\n");
}


space (n)
	int	n;
{
	int	i;

	for (i=0; i<n; ++i)
		printf (" ");
}
pformat(s1, s2)
	char	*s1, *s2;
{
	space (24);
	printf ("%s", s1);
	space (8-strlen(s1));
	printf ("%s\n", s2);
}
code (fetch, lenght)
	int	fetch[], lenght;
{
	int	i;
	char	tmp[16];

	outline->codestr[0]= '\0';
	for (i=0; i<lenght; ++i) {
		sprintf (tmp, "%02x", fetch[i]&0xffff);
		strcat (outline->codestr, tmp);
	}
}
usage()
{
	fprintf (stderr, "COMMAND:    disa\n");
	fprintf (stderr, "USAGE:      Disassemble 6809 code\n");
	fprintf (stderr, "SYNTAX:     disa -9bhepc [file]\n");
	fprintf (stderr, "\nOPTIONS:    -9   OS-9 module\n");
	fprintf (stderr, "            -b   binairy file\n");
	fprintf (stderr, "            -p   Don't print PC\n");
	fprintf (stderr, "            -e   Don't print number of cycles\n");
	fprintf (stderr, "            -c   Don't print instruction codes\n");
	fprintf (stderr, "            -h   Print this message\n");
        exit(0);
}

------------------------------CUT HERE--------------------------------
-- 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Benoit Archambault                                                         +
+ Universite de Montreal, Dep. I.R.O. Y-202, C.P. 6128, succursale A         +
+ Montreal (Quebec) H3C 3J7, (514) 343-7480, archambe@iro.umontreal.ca       +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++