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 +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++