/***************************************************************************
**
**  Name:  dsinfo16.cpp
**
**  Description:
**     This is a disassembler class file
**
**  Status:  
**
**  $Log:   S:/tbird/mt2_186/dad186/dsinfo16.cpv  $
** 
**    Rev 1.0   16 Dec 1996 15:13:48   Judy
** Initial revision.
** 
**    Rev 1.14   20 Jun 1994 17:15:18   nghia
** Fixed typo - AdrAddToAddressOverflow.
** 
**    Rev 1.13   15 Jun 1994 10:43:40   nghia
** Added IncStartAddressOverFlow()
** 
**    Rev 1.12   10 Jun 1994 17:12:42   nghia
** Added member function to return instLength.
** 
**    Rev 1.11   28 Mar 1994 10:29:22   nghia
** Support DadCurrentDasmAddr() routine.
** Added StartAddress() member function definition.
** 
**    Rev 1.10   28 Feb 1994 17:15:46   marilyn
** Moved maxOutput routines to the address server. Updated interfaces.
** 
**    Rev 1.9   27 Oct 1993 17:54:28   nghia
** Fixed PPR 9039 - Invalid dasm instruction format
** - jsr _Startup (#####)jsr
** - jsr 0x123456 (should be 20 bits max)
** - jsr 0x123456,Z (IND20 should be 20 bits max).
** 
**    Rev 1.8   18 Oct 1993 11:29:08   mindy
** should of checked pulm too
** 
**    Rev 1.7   17 Oct 1993 13:58:00   mindy
** push data count calculated wrong
** 
**    Rev 1.6   17 Oct 1993 13:04:40   mindy
** EXT text being put in tmpBuf but not added to buffer
** 
**    Rev 1.5   27 Jul 1993 17:14:12   john
** Decreased the number of spaces between the symbolic jsr target and
** the numeric target display.
** 
**    Rev 1.4   23 Jul 1993 15:25:10   ernie
** Added transfer=TRUE to RTI, RTS, and the 20-bit address forms of JSR.
** This fixes problems with source-level stepping thru these instructions.
** 
**    Rev 1.3   22 Jul 1993 10:32:36   ernie
** (For Mindy):
** Changed symbol lookup algorithm for EXT address mode.  Now attempts to
** look up 20-bit EXT addresses rather than just printing the hex address.
** 
**    Rev 1.2   09 Jun 1993 09:02:24   ernie
** Fixed indentation error
** 
**    Rev 1.1   25 May 1993 12:07:44   ernie
** Changed dasmSym to be system-wide global
** 
**    Rev 1.0   08 Apr 1993 09:42:20   doug
** Initial revision.
** 
**    Rev 1.2   07 Apr 1993 17:47:30   mindy
** a) round starting address down to an even address
** b) error recovery rounds instLength up to an even number.
** 
**    Rev 1.1   30 Mar 1993 16:12:30   ernie
** (for mindy): added symbol support
** 
**    Rev 1.0   12 Mar 1993 09:51:30   mindy
** Initial revision.
** 
**  $Header:   S:/tbird/mt2_186/dad186/dsinfo16.cpv   1.0   16 Dec 1996 15:13:48   Judy  $
**
**  Copyright (C) 1993 Microtek International.  All rights reserved.
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/

#include "stdio.h"
#include "string.h"

#ifndef _DADDEF16_
#include "daddef16.h"
#endif

#ifndef _DAD_SERVER_
#include "dasm.h"
#endif

#ifndef _DSINFO16_
#include "dsinfo16.h"
#endif

#ifndef _ADDR_
#include "addr.h"
#endif

#ifndef _SYMBLSVR_
#include "symblsvr.h"
#endif

#ifndef _HEAP_
#include "heap.h"
#endif

#ifndef _TBIRDMEM_
#include "tbirdmem.h"
#endif

                       /****************************
                        *                          *
                        *     EXTERNALS            *
                        *                          *
                        ****************************/


                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
 
#define L_TEXT		"l"
#define ABA_TEXT	"aba"
#define ABX_TEXT	"abx"
#define ABY_TEXT	"aby"
#define ABZ_TEXT	"abz"
#define ACED_TEXT	"aced"
#define ACE_TEXT	"ace"
#define ADCD_TEXT	"adcd"
#define ADCE_TEXT	"adce"
#define ADC_TEXT	"adc"
#define ADDD_TEXT	"addd"
#define ADDE_TEXT	"adde"
#define ADD_TEXT	"add"
#define ADE_TEXT	"ade"
#define ADX_TEXT	"adx"
#define ADY_TEXT	"ady"
#define ADZ_TEXT	"adz"
#define AEX_TEXT	"aex"
#define AEY_TEXT	"aey"
#define AEZ_TEXT	"aez"
#define AIS_TEXT	"ais"
#define AIS_TEXT	"ais"
#define AIX_TEXT	"aix"
#define AIY_TEXT	"aiy"
#define AIZ_TEXT	"aiz"
#define ANDD_TEXT	"andd"
#define ANDE_TEXT	"ande"
#define ANDP_TEXT	"andp"
#define AND_TEXT	"and"
#define ASLD_TEXT	"asld"
#define ASLE_TEXT	"asle"
#define ASLM_TEXT	"aslm"
#define ASL_TEXT	"asl"
#define ASRD_TEXT	"asrd"
#define ASRE_TEXT	"asre"
#define ASRM_TEXT	"asrm"
#define ASR_TEXT	"asr"
#define BCC_TEXT	"bcc"
#define BCLR_TEXT	"bclr"
#define BCS_TEXT	"bcs"
#define BEQ_TEXT	"beq"
#define BGE_TEXT	"bge"
#define BGND_TEXT	"bgnd"
#define BGT_TEXT	"bgt"
#define BHI_TEXT	"bhi"
#define BIT_TEXT	"bit"
#define BLE_TEXT	"ble"
#define BLS_TEXT	"bls"
#define BLT_TEXT	"blt"
#define BMI_TEXT	"bmi"
#define BNE_TEXT	"bne"
#define BPL_TEXT	"bpl"
#define BRA_TEXT	"bra"
#define BRCLR_TEXT	"brclr"
#define BRN_TEXT	"brn"
#define BRSET_TEXT	"brset"
#define BSET_TEXT	"bset"
#define BSR_TEXT	"bsr"
#define BVC_TEXT	"bvc"
#define BVS_TEXT	"bvs"
#define CBA_TEXT	"cba"
#define CLRD_TEXT	"clrd"
#define CLRE_TEXT	"clre"
#define CLRM_TEXT	"clrm"
#define CLR_TEXT	"clr"
#define CMP_TEXT	"cmp"
#define COMD_TEXT	"comd"
#define COME_TEXT	"come"
#define COM_TEXT	"com"
#define CPD_TEXT	"cpd"
#define CPE_TEXT	"cpe"
#define CPS_TEXT	"cps"
#define CPX_TEXT	"cpx"
#define CPY_TEXT	"cpy"
#define CPZ_TEXT	"cpz"
#define DAA_TEXT	"daa"
#define DEC_TEXT	"dec"
#define EDIVS_TEXT	"edivs"
#define EDIV_TEXT	"ediv"
#define EMULS_TEXT	"emuls"
#define EMUL_TEXT	"emul"
#define EORD_TEXT	"eord"
#define EORE_TEXT	"eore"
#define EOR_TEXT	"eor"
#define FDIV_TEXT	"fdiv"
#define FMULS_TEXT	"fmuls"
#define IDIV_TEXT	"idiv"
#define INC_TEXT	"inc"
#define JMP_TEXT	"jmp"
#define JSR_TEXT	"jsr"
#define LBCC_TEXT	L_TEXT BCC_TEXT
#define LBCS_TEXT	L_TEXT BCS_TEXT
#define LBEQ_TEXT	L_TEXT BEQ_TEXT
#define LBEV_TEXT	"lbev"
#define LBGE_TEXT	L_TEXT BGE_TEXT
#define LBGT_TEXT	L_TEXT BGT_TEXT
#define LBHI_TEXT	L_TEXT BHI_TEXT
#define LBLE_TEXT	L_TEXT BLE_TEXT
#define LBLS_TEXT	L_TEXT BLS_TEXT
#define LBLT_TEXT	L_TEXT BLT_TEXT
#define LBMI_TEXT	L_TEXT BMI_TEXT
#define LBMV_TEXT	"lbmv"
#define LBNE_TEXT	L_TEXT BNE_TEXT
#define LBPL_TEXT	L_TEXT BPL_TEXT
#define LBRA_TEXT	L_TEXT BRA_TEXT
#define LBRN_TEXT	L_TEXT BRN_TEXT
#define LBSR_TEXT	L_TEXT BSR_TEXT
#define LBVC_TEXT	L_TEXT BVC_TEXT
#define LBVS_TEXT	L_TEXT BVS_TEXT
#define LDA_TEXT	"lda"
#define LDD_TEXT	"ldd"
#define LDED_TEXT	"lded"
#define LDE_TEXT	"lde"
#define LDHI_TEXT	"ldhi"
#define LDS_TEXT	"lds"
#define LDX_TEXT	"ldx"
#define LDY_TEXT	"ldy"
#define LDZ_TEXT	"ldz"
#define LPSTOP_TEXT	"lpstop"
#define LSRD_TEXT	"lsrd"
#define LSRE_TEXT	"lsre"
#define LSR_TEXT	"lsr"
#define MAC_TEXT	"mac"
#define MOVB_TEXT	"movb"
#define MOVW_TEXT	"movw"
#define MUL_TEXT	"mul"
#define NEGD_TEXT	"negd"
#define NEGE_TEXT	"nege"
#define NEG_TEXT	"neg"
#define NOP_TEXT	"nop"
#define ORA_TEXT	"ora"
#define ORD_TEXT	"ord"
#define ORE_TEXT	"ore"
#define ORP_TEXT	"orp"
#define PSHA_TEXT	"psha"
#define PSHB_TEXT	"pshb"
#define PSHMAC_TEXT	"pshmac"
#define PSHM_TEXT	"pshm"
#define PULA_TEXT	"pula"
#define PULB_TEXT	"pulb"
#define PULMAC_TEXT	"pulmac"
#define PULM_TEXT	"pulm"
#define RMAC_TEXT	"rmac"
#define ROLD_TEXT	"rold"
#define ROLE_TEXT	"role"
#define ROL_TEXT	"rol"
#define RORD_TEXT	"rord"
#define RORE_TEXT	"rore"
#define ROR_TEXT	"ror"
#define RTI_TEXT	"rti"
#define RTS_TEXT	"rts"
#define SBA_TEXT	"sba"
#define SBCD_TEXT	"sbcd"
#define SBCE_TEXT	"sbce"
#define SBC_TEXT	"sbc"
#define SDE_TEXT	"sde"
#define STAB_TEXT	"stab"
#define STA_TEXT	"sta"
#define STD_TEXT	"std"
#define STED_TEXT	"sted"
#define STS_TEXT	"sts"
#define STX_TEXT	"stx"
#define STY_TEXT	"sty"
#define STZ_TEXT	"stz"
#define SUBD_TEXT	"subd"
#define SUBE_TEXT	"sube"
#define SUB_TEXT	"sub"
#define SWI_TEXT	"swi"
#define SXT_TEXT	"sxt"
#define TAB_TEXT	"tab"
#define TAP_TEXT	"tap"
#define TBA_TEXT	"tba"
#define TBEK_TEXT	"tbek"
#define TBSK_TEXT	"tbsk"
#define TBXK_TEXT	"tbxk"
#define TBYK_TEXT	"tbyk"
#define TBZK_TEXT	"tbzk"
#define TDE_TEXT	"tde"
#define TDMSK_TEXT	"tdmsk"
#define TDP_TEXT	"tdp"
#define TEDM_TEXT	"tedm"
#define TED_TEXT	"ted"
#define TEKB_TEXT	"tekb"
#define TEM_TEXT	"tem"
#define TMER_TEXT	"tmer"
#define TMET_TEXT	"tmet"
#define TMXED_TEXT	"tmxed"
#define TPA_TEXT	"tpa"
#define TPD_TEXT	"tpd"
#define TSTD_TEXT	"tstd"
#define TSTE_TEXT	"tste"
#define TST_TEXT	"tst"
#define TSKB_TEXT	"tskb"
#define TSX_TEXT	"tsx"
#define TSY_TEXT	"tsy"
#define TSZ_TEXT	"tsz"
#define TXKB_TEXT	"txkb"
#define TXS_TEXT	"txs"
#define TXY_TEXT	"txy"
#define TXZ_TEXT	"txz"
#define TYS_TEXT	"tys"
#define TYX_TEXT	"tyx"
#define TYKB_TEXT	"tykb"
#define TYZ_TEXT	"tyz"
#define TZS_TEXT	"tzs"
#define TZKB_TEXT	"tzkb"
#define TZX_TEXT	"tzx"
#define TZY_TEXT	"tzy"
#define WAI_TEXT	"wai"
#define XGAB_TEXT	"xgab"
#define XGDE_TEXT	"xgde"
#define XGDX_TEXT	"xgdx"
#define XGDY_TEXT	"xgdy"
#define XGDZ_TEXT	"xgdz"
#define XGEX_TEXT	"xgex"
#define XGEY_TEXT	"xgey"
#define XGEZ_TEXT	"xgez"

typedef RETCODE (DasmInfo::*OPCODE_FUNC)();
static OPCODE_FUNC opcodeFunctions[256] = {
/*00*/&DasmInfo::Com,  &DasmInfo::Dec,   &DasmInfo::Neg,  &DasmInfo::Inc,
/*04*/&DasmInfo::Asl,  &DasmInfo::Clr,   &DasmInfo::Tst,  &DasmInfo::Opcd07, 
/*08*/&DasmInfo::Bclr, &DasmInfo::Bset,  &DasmInfo::Brclr,&DasmInfo::Brset,
/*0C*/&DasmInfo::Rol,  &DasmInfo::Asr,   &DasmInfo::Ror,  &DasmInfo::Lsr,
/*10*/&DasmInfo::Com,  &DasmInfo::Dec,   &DasmInfo::Neg,  &DasmInfo::Inc,
/*14*/&DasmInfo::Asl,  &DasmInfo::Clr,   &DasmInfo::Tst,  &DasmInfo::Opcd17, 
/*18*/&DasmInfo::Bclr, &DasmInfo::Bset,  &DasmInfo::Brclr,&DasmInfo::Brset,
/*1C*/&DasmInfo::Rol,  &DasmInfo::Asr,   &DasmInfo::Ror,  &DasmInfo::Lsr,
/*20*/&DasmInfo::Com,  &DasmInfo::Dec,   &DasmInfo::Neg,  &DasmInfo::Inc,
/*24*/&DasmInfo::Asl,  &DasmInfo::Clr,   &DasmInfo::Tst,  &DasmInfo::Opcd27, 
/*28*/&DasmInfo::Bclr, &DasmInfo::Bset,  &DasmInfo::Brclr,&DasmInfo::Brset,
/*2C*/&DasmInfo::Rol,  &DasmInfo::Asr,   &DasmInfo::Ror,  &DasmInfo::Lsr,
/*30*/&DasmInfo::Com,  &DasmInfo::Dec,   &DasmInfo::Neg,  &DasmInfo::Inc,
/*34*/&DasmInfo::Asl,  &DasmInfo::Clr,   &DasmInfo::Tst,  &DasmInfo::Opcd37, 
/*38*/&DasmInfo::Bclr, &DasmInfo::Bset,  &DasmInfo::Brclr,&DasmInfo::Brset,
/*3C*/&DasmInfo::Rol,  &DasmInfo::Asr,   &DasmInfo::Ror,  &DasmInfo::Lsr,
/*40*/&DasmInfo::Sub,  &DasmInfo::Add,   &DasmInfo::Sbc,  &DasmInfo::Adc,
/*44*/&DasmInfo::Eor,  &DasmInfo::Lda,   &DasmInfo::And,  &DasmInfo::Or,
/*48*/&DasmInfo::Cmp,  &DasmInfo::Bit,   &DasmInfo::Store,&DasmInfo::Jmp,
/*4C*/&DasmInfo::Cpx,  &DasmInfo::Cpy,   &DasmInfo::Cpz,  &DasmInfo::Cps,
/*50*/&DasmInfo::Sub,  &DasmInfo::Add,   &DasmInfo::Sbc,  &DasmInfo::Adc,
/*54*/&DasmInfo::Eor,  &DasmInfo::Lda,   &DasmInfo::And,  &DasmInfo::Or,
/*58*/&DasmInfo::Cmp,  &DasmInfo::Bit,   &DasmInfo::Store,&DasmInfo::Jmp,
/*5C*/&DasmInfo::Cpx,  &DasmInfo::Cpy,   &DasmInfo::Cpz,  &DasmInfo::Cps,
/*60*/&DasmInfo::Sub,  &DasmInfo::Add,   &DasmInfo::Sbc,  &DasmInfo::Adc,
/*64*/&DasmInfo::Eor,  &DasmInfo::Lda,   &DasmInfo::And,  &DasmInfo::Or,
/*68*/&DasmInfo::Cmp,  &DasmInfo::Bit,   &DasmInfo::Store,&DasmInfo::Jmp,
/*6C*/&DasmInfo::Cpx,  &DasmInfo::Cpy,   &DasmInfo::Cpz,  &DasmInfo::Cps,
/*70*/&DasmInfo::Sub,  &DasmInfo::Add,   &DasmInfo::Sbc,  &DasmInfo::Adc,
/*74*/&DasmInfo::Eor,  &DasmInfo::Lda,   &DasmInfo::And,  &DasmInfo::Or,
/*78*/&DasmInfo::Cmp,  &DasmInfo::Bit,   &DasmInfo::Store,&DasmInfo::Opcd7b,
/*7C*/&DasmInfo::Opcd7c,&DasmInfo::Cpy,   &DasmInfo::Cpz,  &DasmInfo::Cps,
/*80*/&DasmInfo::Sub,  &DasmInfo::Add,   &DasmInfo::Sbc,  &DasmInfo::Adc,
/*84*/&DasmInfo::Eor,  &DasmInfo::Lda,   &DasmInfo::And,  &DasmInfo::Or,
/*88*/&DasmInfo::Cmp,  &DasmInfo::Jsr,   &DasmInfo::Store,&DasmInfo::Brset,
/*8C*/&DasmInfo::Stx,  &DasmInfo::Sty,   &DasmInfo::Stz,  &DasmInfo::Sts,
/*90*/&DasmInfo::Sub,  &DasmInfo::Add,   &DasmInfo::Sbc,  &DasmInfo::Adc,
/*94*/&DasmInfo::Eor,  &DasmInfo::Lda,   &DasmInfo::And,  &DasmInfo::Or,
/*98*/&DasmInfo::Cmp,  &DasmInfo::Jsr,   &DasmInfo::Store,&DasmInfo::Brset,
/*9C*/&DasmInfo::Stx,  &DasmInfo::Sty,   &DasmInfo::Stz,  &DasmInfo::Sts,
/*A0*/&DasmInfo::Sub,  &DasmInfo::Add,   &DasmInfo::Sbc,  &DasmInfo::Adc,
/*A4*/&DasmInfo::Eor,  &DasmInfo::Lda,   &DasmInfo::And,  &DasmInfo::Or,
/*A8*/&DasmInfo::Cmp,  &DasmInfo::Jsr,   &DasmInfo::Store,&DasmInfo::Brset,
/*AC*/&DasmInfo::Stx,  &DasmInfo::Sty,   &DasmInfo::Stz,  &DasmInfo::Sts,
/*B0*/&DasmInfo::OpcdB0,&DasmInfo::OpcdB1,&DasmInfo::OpcdB2,&DasmInfo::OpcdB3,
/*B4*/&DasmInfo::OpcdB4,&DasmInfo::OpcdB5,&DasmInfo::OpcdB6,&DasmInfo::OpcdB7,
/*B8*/&DasmInfo::OpcdB8,&DasmInfo::OpcdB9,&DasmInfo::OpcdBA,&DasmInfo::OpcdBB,
/*BC*/&DasmInfo::OpcdBC,&DasmInfo::OpcdBD,&DasmInfo::OpcdBE,&DasmInfo::OpcdBF,
/*C0*/&DasmInfo::Sub,  &DasmInfo::Add,   &DasmInfo::Sbc,  &DasmInfo::Adc,
/*C4*/&DasmInfo::Eor,  &DasmInfo::Lda,   &DasmInfo::And,  &DasmInfo::Or,
/*C8*/&DasmInfo::Cmp,  &DasmInfo::Bit,   &DasmInfo::Store,&DasmInfo::Brclr,
/*CC*/&DasmInfo::Ldx,  &DasmInfo::Ldy,   &DasmInfo::Ldz,  &DasmInfo::Lds,
/*D0*/&DasmInfo::Sub,  &DasmInfo::Add,   &DasmInfo::Sbc,  &DasmInfo::Adc,
/*D4*/&DasmInfo::Eor,  &DasmInfo::Lda,   &DasmInfo::And,  &DasmInfo::Or,
/*D8*/&DasmInfo::Cmp,  &DasmInfo::Bit,   &DasmInfo::Store,&DasmInfo::Brclr,
/*DC*/&DasmInfo::Ldx,  &DasmInfo::Ldy,   &DasmInfo::Ldz,  &DasmInfo::Lds,
/*E0*/&DasmInfo::Sub,  &DasmInfo::Add,   &DasmInfo::Sbc,  &DasmInfo::Adc,
/*E4*/&DasmInfo::Eor,  &DasmInfo::Lda,   &DasmInfo::And,  &DasmInfo::Or,
/*E8*/&DasmInfo::Cmp,  &DasmInfo::Bit,   &DasmInfo::Store,&DasmInfo::Brclr,
/*EC*/&DasmInfo::Ldx,  &DasmInfo::Ldy,   &DasmInfo::Ldz,  &DasmInfo::Lds,
/*F0*/&DasmInfo::Sub,  &DasmInfo::Add,   &DasmInfo::Sbc,  &DasmInfo::Adc,
/*F4*/&DasmInfo::Eor,  &DasmInfo::Lda,   &DasmInfo::And,  &DasmInfo::Or,
/*F8*/&DasmInfo::Cmp,  &DasmInfo::Bit,   &DasmInfo::OpcdFA,&DasmInfo::OpcdFB,
/*FC*/&DasmInfo::Ldx,  &DasmInfo::Ldy,   &DasmInfo::Ldz,  &DasmInfo::Lds
};

static U32 cacheStartOffset = 0xffffffffL;
static LPU8 memCacheBuf = NULL;


                        /***************************
                        *                          *
                        *    PROTOTYPES            *
                        *                          *
                        ***************************/

                         /***************************
                         *                          *
                         *     EXECUTABLE CODE      *
                         *                          *
                         ***************************/
/***************************  PUBLIC METHODS  *******************************/
DasmInfo::DasmInfo(DESCRIPTOR addr){
   CommonInitialization();
   AdrDuplicateAddress(addr,&pcAddress);
}

void far *AsmDasmBase::operator new(size_t size){
   return(TMalloc(size));
}

void AsmDasmBase::operator delete(void far *p){
   if( ((DasmInfo *)p)->pcAddress )
      AdrDestroyAddress(((DasmInfo *)p)->pcAddress);
   TFree((LPSTR)p);	
}

BOOLEAN AsmDasmBase::ValidInstruction() {
   return( instLength && (addrMode.type != DC_ERR) );
}

U8 AsmDasmBase::InstLength() {
   return instLength;
}   

DasmInfo::DasmInfo(){
   AdrCreateAddress(&pcAddress);
   AdrSetAddrOffset(pcAddress,0L);
   CommonInitialization();
}

RETCODE DasmInfo::Disassemble(LPSTR buffer, U16 numInst) {
   RETCODE err;
   for(LOOP_VAR i=0; i<numInst; i++) {
      if((err=DecodeMemory())!=GOOD) return(err);

      // !!! dataCycles needs to be adjusted to account for data access
      //     size vs bus width, etc
         
      PrintInfo(buffer);

   /* add InstLength to address */
      if((err=IncStartAddressOverFlow())!=GOOD) return(err);
   }
   return GOOD;
}

RETCODE DasmInfo::Disassemble(LPSTR buffer, U8 bytes[6]) {
   for(LOOP_VAR i=0; i<6; i++) hexCode[i] = bytes[i];
   CommonInitialization();
   DecodeBytes();
   PrintInfo(buffer);
   return(GOOD);
}

RETCODE DasmInfo::DecodeMemory() {
   RETCODE err;
   if((err=FillCodeBuffer())!=GOOD) return(err);
   DecodeBytes();
   return(GOOD);
}

RETCODE DasmInfo::StartAddress(DESCRIPTOR addr) {
   return(AdrCopyAddress(pcAddress, addr));
}

RETCODE DasmInfo::SetStartAddress(DESCRIPTOR addr) {
   U32 offset;
   RETCODE err;
   if( pcAddress ) AdrDestroyAddress(pcAddress);
   if((err=AdrGetAddrOffset(addr,&offset))!=GOOD) return(err);
   offset &= 0xfffffffeL;
   if((err=AdrDuplicateAddress(addr,&pcAddress))!=GOOD) return(err);
   if((err=AdrSetAddrOffset(pcAddress,offset))!=GOOD) return(err);
   return(GOOD);   
}

RETCODE DasmInfo::GetStartAddress(DESCRIPTOR *addr) {
   return(AdrDuplicateAddress(pcAddress, addr));
}

RETCODE DasmInfo::IncStartAddress() {
   return AdrAddToAddress(pcAddress, instLength);
}

RETCODE DasmInfo::IncStartAddress(U32 offset) {
   return AdrAddToAddress(pcAddress, offset);
}

RETCODE DasmInfo::IncStartAddressOverFlow() {
   return AdrAddToAddressOverflow(pcAddress, instLength);
}

BOOLEAN DasmInfo::StartAddressInRange(DESCRIPTOR range) {
   BOOLEAN inRange = FALSE;
   if( AdrIsAddrInRange(pcAddress, range, &inRange) != GOOD ) return(FALSE);
   return( inRange );
}
   
RETCODE DasmInfo::Com() {
   if( (preByte == PAGE0) && (opcode == 0x30) ) {
      strcpy(mnemonic,MOVB_TEXT);
      return(HandleIxpToExt());
   }
   else if( (preByte == PAGE3) && (opcode == 0x20) ) {
      strcpy(mnemonic,SWI_TEXT);
      dataCycles = 3;
      return(GOOD);
   }
   else if( (preByte == PAGE3) && (opcode == 0x30) ) {
      strcpy(mnemonic,SUBE_TEXT);
      return(HandleImmed16());
   }
   else {
      strcpy(mnemonic,COM_TEXT);
      dataCycles++;
      Group6Mnemonic();
      return(Group6Address());
   }
}

RETCODE DasmInfo::Dec() {
   if( (preByte == PAGE0) && (opcode == 0x31) ) {
      strcpy(mnemonic,MOVW_TEXT);
      return(HandleIxpToExt());
   }
   else if( (preByte == PAGE3) && (opcode == 0x21) ) {
      strcpy(mnemonic,DAA_TEXT);
      return(GOOD);
   }
   else if( (preByte == PAGE3) && (opcode == 0x31) ) {
      strcpy(mnemonic,ADDE_TEXT);
      return(HandleImmed16());
   }
   else {
      strcpy(mnemonic,DEC_TEXT);
      dataCycles++;
      Group6Mnemonic();
      return(Group6Address());
   }
}

RETCODE DasmInfo::Neg() {
   if( (preByte == PAGE0) && (opcode == 0x32) ) {
      strcpy(mnemonic,MOVB_TEXT);
      return(HandleExtToIxp());
   }
   else if( (preByte == PAGE3) && (opcode == 0x22) ) {
      strcpy(mnemonic,ACE_TEXT);
      return(GOOD);
   }
   else if( (preByte == PAGE3) && (opcode == 0x32) ) {
      strcpy(mnemonic,SBCE_TEXT);
      return(HandleImmed16());
   }
   else {
      strcpy(mnemonic,NEG_TEXT);
      dataCycles++;
      Group6Mnemonic();
      return(Group6Address());
   }
}

RETCODE DasmInfo::Inc() {
   if( (preByte == PAGE0) && (opcode == 0x33) ) {
      strcpy(mnemonic,MOVW_TEXT);
      return(HandleExtToIxp());
   }
   else if( (preByte == PAGE3) && (opcode == 0x23) ) {
      strcpy(mnemonic,ACED_TEXT);
      return(GOOD);
   }
   else if( (preByte == PAGE3) && (opcode == 0x33) ) {
      strcpy(mnemonic,ADCE_TEXT);
      return(HandleImmed16());
   }
   else {
      strcpy(mnemonic,INC_TEXT);
      dataCycles++;
      Group6Mnemonic();
      return(Group6Address());
   }
}

RETCODE DasmInfo::Asl() {
   if( (preByte == PAGE0) && (opcode == 0x34) ) {
      U8 tmp;
      strcpy(mnemonic,PSHM_TEXT);
      addrMode.type = PSHLIST;
      tmp = addrMode.data = (U32)(GetNextCodeByte());
      for(LOOP_VAR i=0; i < 8; i++, tmp>>=1 ) 
         if( tmp & 0x1 ) dataCycles++;
      return(GOOD);
   }
   else if( (preByte == PAGE3) && (opcode == 0x24) ) {
      strcpy(mnemonic,MUL_TEXT);
      return(GOOD);
   }
   else if( (preByte == PAGE3) && (opcode == 0x34) ) {
      strcpy(mnemonic,EORE_TEXT);
      return(HandleImmed16());
   }
   else {
      strcpy(mnemonic,ASL_TEXT);
      dataCycles++;
      Group6Mnemonic();
      return(Group6Address());
   }
}

RETCODE DasmInfo::Clr(){
   if( (preByte == PAGE0) && (opcode == 0x35) ) {
      U8 tmp;
      strcpy(mnemonic,PULM_TEXT);
      addrMode.type = PULLIST;
      tmp = addrMode.data = (U32)(GetNextCodeByte());
      for(LOOP_VAR i=0; i < 8; i++, tmp>>1 ) 
         if( tmp & 0x1 ) dataCycles++;
      return(GOOD);
   }
   else if( (preByte == PAGE3) && (opcode == 0x25) ) {
      strcpy(mnemonic,EMUL_TEXT);
      return(GOOD);
   }
   else if( (preByte == PAGE3) && (opcode == 0x35) ) {
      strcpy(mnemonic,LDE_TEXT);
      return(HandleImmed16());
   }
   else {
      strcpy(mnemonic,CLR_TEXT);
      Group6Mnemonic();
      return(Group6Address());
   }
}

RETCODE DasmInfo::Tst(){
   if( (preByte == PAGE0) && (opcode == 0x36) ) {
      strcpy(mnemonic,BSR_TEXT);
      dataCycles += 2;
      callType = INST_CALL;
      return(HandleRel8(TRUE));
   }
   else if( (preByte == PAGE3) && (opcode == 0x26) ) {
      strcpy(mnemonic,EMULS_TEXT);
      return(GOOD);
   }
   else if( (preByte == PAGE3) && (opcode == 0x36) ) {
      strcpy(mnemonic,ANDE_TEXT);
      return(HandleImmed16());
   }
   else {
      strcpy(mnemonic,TST_TEXT);
      Group6Mnemonic();
      return(Group6Address());
   }
}

RETCODE DasmInfo::Opcd07() {
   if( preByte == PAGE3 ) {
      strcpy(mnemonic,TBA_TEXT);
      return(GOOD);
   }
   return(FlagError());
}

RETCODE DasmInfo::Opcd17() {
   if( preByte == PAGE3 ) {
      strcpy(mnemonic,TAB_TEXT);
      return(GOOD);
   }
   return(FlagError());
}

RETCODE DasmInfo::Opcd27() {
   if( preByte == PAGE3 ) {
      strcpy(mnemonic,FMULS_TEXT);
      return(GOOD);
   }
   return(FlagError());
}

RETCODE DasmInfo::Opcd37() {
   if( preByte == PAGE3 ) {
      strcpy(mnemonic,ORE_TEXT);
      return(HandleImmed16());
   }
   return(FlagError());
}

RETCODE DasmInfo::Bclr(){
   if( preByte == PAGE3 ) {
      switch((opcode>>4)&0x3) {
         case 0x0:
            strcpy(mnemonic,PSHA_TEXT);
            dataCycles++;
            return GOOD;
         case 0x1:
            strcpy(mnemonic,PSHB_TEXT);
            dataCycles++;
            return GOOD;
         case 0x2:
            strcpy(mnemonic,EDIV_TEXT);
            return GOOD;
         case 0x3:
            strcpy(mnemonic,CPE_TEXT);
            return(HandleImmed16());
      }
   }
   if( (preByte == PAGE1) && (opcode == 0x38) ) return(FlagError());
   strcpy(mnemonic,BCLR_TEXT);
   dataCycles += 2;
   if( preByte == PAGE2 ) {
      mnemonic[4] = 'w';
      mnemonic[5] = '\0';
   }
   dataCycles++;
   return(MaskedAddress());
}

RETCODE DasmInfo::Bset(){
   if( preByte == PAGE3 ) {
      switch((opcode>>4)&0x3) {
         case 0x0:
            strcpy(mnemonic,PULA_TEXT);
            dataCycles++;
            return GOOD;
         case 0x1:
            strcpy(mnemonic,PULB_TEXT);
            dataCycles++;
            return GOOD;
         case 0x2:
            strcpy(mnemonic,EDIVS_TEXT);
            return GOOD;
         default:
            return(FlagError());
      }
   }
   if( (preByte == PAGE1) && (opcode == 0x39) ) return(FlagError());
   strcpy(mnemonic,BSET_TEXT);
   dataCycles += 2;
   if( preByte == PAGE2 ) {
      mnemonic[4] = 'w';
      mnemonic[5] = '\0';
   }
   dataCycles++;
   return(MaskedAddress());
}

RETCODE DasmInfo::Brclr(){
   RETCODE err;
   if( (preByte == PAGE1) || (preByte == PAGE2) ) return(FlagError());
   if( preByte == PAGE3 ) {
      switch(opcode) {
         case 0x0a:
            strcpy(mnemonic,SBA_TEXT);
            return GOOD;
         case 0x1a:
            strcpy(mnemonic,XGAB_TEXT);
            return GOOD;
         case 0x2a:
            strcpy(mnemonic,IDIV_TEXT);
            return GOOD;
         case 0x3a:
            strcpy(mnemonic,ANDP_TEXT);
            return(HandleImmed16());
         default:
            return(FlagError());
      }
   }
   conditional = TRUE;
   strcpy(mnemonic,BRCLR_TEXT);
   if((err=MaskedAddress())!=GOOD) return(err);
   U32 tmpAddr = addrMode.effAddr;
   if( (addrMode.type == EXT)
      || (addrMode.size == WORDSIZE) ) 
      err = HandleRel16(FALSE);
   else
      err = HandleRel8(FALSE);
   addrMode.effAddr2 = addrMode.effAddr;
   addrMode.effAddr = tmpAddr;
   return(err);
}

RETCODE DasmInfo::Brset(){
   RETCODE err;
   if( (preByte == PAGE1) || (preByte == PAGE2) ) return(FlagError());
   if( preByte == PAGE3 ) {
      switch(opcode) {
         case 0x0b:
            strcpy(mnemonic,ABA_TEXT);
            return GOOD;
         case 0x1b:
            strcpy(mnemonic,CBA_TEXT);
            return GOOD;
         case 0x2b:
            strcpy(mnemonic,FDIV_TEXT);
            return GOOD;
         case 0x3b:
            strcpy(mnemonic,ORP_TEXT);
            return(HandleImmed16());
         case 0x8b:
            conditional = TRUE;
            strcpy(mnemonic,LBMI_TEXT);
            return(HandleRel16(TRUE));
         default:
            return(FlagError());
      }
   }
   conditional = TRUE;
   strcpy(mnemonic,BRSET_TEXT);
   if((err=MaskedAddress())!=GOOD) return(err);
   U32 tmpAddr = addrMode.effAddr;
   if( (addrMode.type == EXT)
      || (addrMode.size == WORDSIZE) ) 
      err = HandleRel16(FALSE);
   else
      err = HandleRel8(FALSE);
   addrMode.effAddr2 = addrMode.effAddr;
   addrMode.effAddr = tmpAddr;
   return(err);
}

RETCODE DasmInfo::Rol(){
   if( (preByte == PAGE0) && (opcode == 0x3c) ) {
      strcpy(mnemonic,AIX_TEXT);
      return(HandleImmed8());
   }
   else if( (preByte == PAGE3) && (opcode == 0x3c) ) {
      strcpy(mnemonic,AIX_TEXT);
      return(HandleImmed16());
   }
   else if( (preByte == PAGE3) && (opcode == 0x2c) ) {
      strcpy(mnemonic,TPD_TEXT);
      return(GOOD);
   }
   else {
      strcpy(mnemonic,ROL_TEXT);
      dataCycles++;
      Group6Mnemonic();
      return(Group6Address());
   }
}

RETCODE DasmInfo::Asr(){
   if( (preByte == PAGE0) && (opcode == 0x3d) ) {
      strcpy(mnemonic,AIY_TEXT);
      return(HandleImmed8());
   }
   else if( (preByte == PAGE3) && (opcode == 0x3d) ) {
      strcpy(mnemonic,AIY_TEXT);
      return(HandleImmed16());
   }
   else if( (preByte == PAGE3) && (opcode == 0x2d) ) {
      strcpy(mnemonic,TDP_TEXT);
      return(GOOD);
   }
   else {
      strcpy(mnemonic,ASR_TEXT);
      dataCycles++;
      Group6Mnemonic();
      return(Group6Address());
   }
}

RETCODE DasmInfo::Ror(){
   if( (preByte == PAGE0) && (opcode == 0x3e) ) {
      strcpy(mnemonic,AIZ_TEXT);
      return(HandleImmed8());
   }
   else if( (preByte == PAGE3) && (opcode == 0x3e) ) {
      strcpy(mnemonic,AIZ_TEXT);
      return(HandleImmed16());
   }
   else if( (preByte == PAGE3) && (opcode == 0x2e) ) return(FlagError());
   else {
      strcpy(mnemonic,ROR_TEXT);
      dataCycles++;
      Group6Mnemonic();
      return(Group6Address());
   }
}

RETCODE DasmInfo::Lsr(){
   if( (preByte == PAGE0) && (opcode == 0x3f) ) {
      strcpy(mnemonic,AIS_TEXT);
      return(HandleImmed8());
   }
   else if( (preByte == PAGE3) && (opcode == 0x3f) ) {
      strcpy(mnemonic,AIS_TEXT);
      return(HandleImmed16());
   }
   else if( (preByte == PAGE3) && (opcode == 0x2f) ) {
      strcpy(mnemonic,TDMSK_TEXT);
      return(GOOD);
   }
   else {
      strcpy(mnemonic,LSR_TEXT);
      dataCycles++;
      Group6Mnemonic();
      return(Group6Address());
   }
}

RETCODE DasmInfo::Sub(){
   if( (preByte == PAGE2) && (opcode == 0x70) ) {
      strcpy(mnemonic,COME_TEXT);
      return(GOOD);
   }
   else if( (opcode == 0x80) || (opcode == 0x90) || (opcode == 0xa0) ) {
      if( preByte == PAGE1 ) return(FlagError());
      if( (preByte == PAGE3) && (opcode == 0xa0) ) return(FlagError());
      if( preByte == PAGE3 ) {
         RETCODE err = HandleRel16(TRUE);
         if( opcode == 0x80 ) 
            strcpy(mnemonic,LBRA_TEXT);
         else {
            conditional = TRUE;
            strcpy(mnemonic,LBMV_TEXT);
         }
         return(err);
      }
   }
   else if( (preByte == PAGE2) && (opcode == 0xf0) ) {
      strcpy(mnemonic,COMD_TEXT);
      return(GOOD);
   }
   strcpy(mnemonic,SUB_TEXT);
   Opcode4XToFXMnemonic(3);
   return(Opcode4XToFXAddress());
}

RETCODE DasmInfo::Add(){
   if( (preByte == PAGE2) && (opcode == 0x71) ) {
      strcpy(mnemonic,LDED_TEXT);
      return(HandleExt());
   }
   else if( (opcode == 0x81) || (opcode == 0x91) || (opcode == 0xa1) ) {
      if( preByte == PAGE1 ) return(FlagError());
      if( (preByte == PAGE3) && (opcode == 0xa1) ) return(FlagError());
      if( preByte == PAGE3 ) {
         RETCODE err = HandleRel16(TRUE);
         if( opcode == 0x81 ) 
            strcpy(mnemonic,LBRN_TEXT);
         else {
            conditional = TRUE;
            strcpy(mnemonic,LBEV_TEXT);
         }
         return(err);
      }
   }
   else if( (preByte == PAGE2) && (opcode == 0xf1) ) {
      strcpy(mnemonic,LPSTOP_TEXT);
      return(GOOD);
   }
   strcpy(mnemonic,ADD_TEXT);
   Opcode4XToFXMnemonic(3);
   return(Opcode4XToFXAddress());
}

RETCODE DasmInfo::Sbc(){
   if( (preByte == PAGE2) && (opcode == 0x72) ) {
      strcpy(mnemonic,NEGE_TEXT);
      return(GOOD);
   }
   else if( (opcode == 0x82) || (opcode == 0x92) || (opcode == 0xa2) ) {
      if( preByte == PAGE1 ) return(FlagError());
      if( (preByte == PAGE3) && (opcode == 0x82) ) {
         RETCODE err = HandleRel16(TRUE);
         conditional = TRUE;
         strcpy(mnemonic,LBHI_TEXT);
         return(err);
      }
      if( preByte == PAGE3 ) return(FlagError());
   }
   else if( (preByte == PAGE2) && (opcode == 0xf2) ) {
      strcpy(mnemonic,NEGD_TEXT);
      return(GOOD);
   }
   strcpy(mnemonic,SBC_TEXT);
   Opcode4XToFXMnemonic(3);
   return(Opcode4XToFXAddress());
}

RETCODE DasmInfo::Adc(){
   if( (preByte == PAGE2) && (opcode == 0x73) ) {
      strcpy(mnemonic,STED_TEXT);
      return(HandleExt());
   }
   else if( (opcode == 0x83) || (opcode == 0x93) || (opcode == 0xa3) ) {
      if( preByte == PAGE1 ) return(FlagError());
      if( (preByte == PAGE3) && (opcode == 0x83) ) {
         RETCODE err = HandleRel16(TRUE);
         conditional = TRUE;
         strcpy(mnemonic,LBLS_TEXT);
         return(err);
      }
      if( preByte == PAGE3 ) return(FlagError());
   }
   else if( (preByte == PAGE2) && (opcode == 0xf3) ) {
      strcpy(mnemonic,WAI_TEXT);
      return(GOOD);
   }
   strcpy(mnemonic,ADC_TEXT);
   Opcode4XToFXMnemonic(3);
   return(Opcode4XToFXAddress());
}

RETCODE DasmInfo::Eor(){
   if( (preByte == PAGE2) && (opcode == 0x74) ) {
      strcpy(mnemonic,ASLE_TEXT);
      return(GOOD);
   }
   else if( (opcode == 0x84) || (opcode == 0x94) || (opcode == 0xa4) ) {
      if( preByte == PAGE1 ) return(FlagError());
      if( (preByte == PAGE3) && (opcode == 0x84) ) {
         RETCODE err = HandleRel16(TRUE);
         conditional = TRUE;
         strcpy(mnemonic,LBCC_TEXT);
         return(err);
      }
      if( preByte == PAGE3 ) return(FlagError());
   }
   else if( (preByte == PAGE2) && (opcode == 0xf4) ) {
      strcpy(mnemonic,ASLD_TEXT);
      return(GOOD);
   }
   strcpy(mnemonic,EOR_TEXT);
   Opcode4XToFXMnemonic(3);
   return(Opcode4XToFXAddress());
}

RETCODE DasmInfo::Lda(){
   if( (preByte == PAGE2) && (opcode == 0x75) ) {
      strcpy(mnemonic,CLRE_TEXT);
      return(GOOD);
   }
   else if( (opcode == 0x85) || (opcode == 0x95) || (opcode == 0xa5) ) {
      if( preByte == PAGE1 ) return(FlagError());
      if( (preByte == PAGE3) && (opcode == 0x85) ) {
         RETCODE err = HandleRel16(TRUE);
         conditional = TRUE;
         strcpy(mnemonic,LBCS_TEXT);
         return(err);
      }
      if( preByte == PAGE3 ) return(FlagError());
   }
   else if( (preByte == PAGE2) && (opcode == 0xf5) ) {
      strcpy(mnemonic,CLRD_TEXT);
      return(GOOD);
   }
   strcpy(mnemonic,LDA_TEXT);
   Opcode4XToFXMnemonic(2);
   return(Opcode4XToFXAddress());
}

RETCODE DasmInfo::And(){
   if( (preByte == PAGE2) && (opcode == 0x76) ) {
      strcpy(mnemonic,TSTE_TEXT);
      return(GOOD);
   }
   else if( (opcode == 0x86) || (opcode == 0x96) || (opcode == 0xa6) ) {
      if( preByte == PAGE1 ) return(FlagError());
      if( (preByte == PAGE3) && (opcode == 0x96) ) return(FlagError());
      if( (preByte == PAGE3) && (opcode == 0x86) ) {
         RETCODE err = HandleRel16(TRUE);
         conditional = TRUE;
         strcpy(mnemonic,LBNE_TEXT);
         return(err);
      }
      if( (preByte == PAGE3) && (opcode == 0xa6) ) {
         strcpy(mnemonic,BGND_TEXT);
         return(GOOD);
      }
   }
   else if( (preByte == PAGE2) && (opcode == 0xf6) ) {
      strcpy(mnemonic,TSTD_TEXT);
      return(GOOD);
   }
   strcpy(mnemonic,AND_TEXT);
   Opcode4XToFXMnemonic(3);
   return(Opcode4XToFXAddress());
}

RETCODE DasmInfo::Or(){
   if( (preByte == PAGE2) && (opcode == 0x77) ) {
      strcpy(mnemonic,RTI_TEXT);
      transfer = TRUE;
      dataCycles += 2;
      return(GOOD);
   }
   else if( (opcode == 0x87) || (opcode == 0x97) || (opcode == 0xa7) ) {
      if( preByte == PAGE1 ) return(FlagError());
      if( (preByte == PAGE3) && (opcode == 0x87) ) {
         RETCODE err = HandleRel16(TRUE);
         conditional = TRUE;
         strcpy(mnemonic,LBEQ_TEXT);
         return(err);
      }
      if( preByte == PAGE3 ) return(FlagError());
   }
   else if( (preByte == PAGE2) && (opcode == 0xf7) ) {
      strcpy(mnemonic,RTS_TEXT);
      callType = INST_RETURN;
      transfer = TRUE;
      dataCycles += 2;
      return(GOOD);
   }
   strcpy(mnemonic,ORA_TEXT);
   Opcode4XToFXMnemonic(2);
   return(Opcode4XToFXAddress());
}

RETCODE DasmInfo::Cmp(){
   if( (preByte == PAGE2) && (opcode == 0x78) ) {
      strcpy(mnemonic,ADE_TEXT);
      return(GOOD);
   }
   else if( (opcode == 0x88) || (opcode == 0x98) || (opcode == 0xa8) ) {
      if( preByte == PAGE1 ) return(FlagError());
      if( (preByte == PAGE3) && (opcode == 0x88) ) {
         RETCODE err = HandleRel16(TRUE);
         conditional = TRUE;
         strcpy(mnemonic,LBVC_TEXT);
         return(err);
      }
      if( preByte == PAGE3 ) return(FlagError());
   }
   else if( (preByte == PAGE2) && (opcode == 0xf8) ) {
      strcpy(mnemonic,SXT_TEXT);
      return(GOOD);
   }
   strcpy(mnemonic,CMP_TEXT);
   Opcode4XToFXMnemonic(2);
   if( (mnemonic[2] == 'd') || (mnemonic[2] == 'e') )
      mnemonic[1] = 'p';/* kludge so I can use same opcode mnemonic routine */
   return(Opcode4XToFXAddress());
}

RETCODE DasmInfo::Bit(){
   if( (preByte == PAGE2) && (opcode == 0x79) ) {
      strcpy(mnemonic,SDE_TEXT);
      return(GOOD);
   }
   if( preByte == PAGE3 ) return(FlagError());
   if( (preByte == PAGE2) && (opcode == 0xf9) ) {
      strcpy(mnemonic,LBSR_TEXT);
      dataCycles += 2;
      callType = INST_CALL;
      return(HandleRel16(TRUE));
   }
   strcpy(mnemonic,BIT_TEXT);
   Opcode4XToFXMnemonic(3);
   return(Opcode4XToFXAddress());
}

RETCODE DasmInfo::Store(){
   if( (preByte == PAGE0) && (opcode == 0x7a) ) {
      strcpy(mnemonic,JMP_TEXT);
      return(HandleExt20());
   }
   if( (preByte == PAGE2) && (opcode == 0x7a) ) {
      strcpy(mnemonic,XGDE_TEXT);
      return(GOOD);
   }
   if( (opcode == 0x8a) || (opcode == 0x9a) || (opcode == 0xaa) ) {
      if( preByte == PAGE1 ) return(FlagError());
      if( (preByte == PAGE3) && (opcode == 0x8a) ) {
         RETCODE err = HandleRel16(TRUE);
         conditional = TRUE;
         strcpy(mnemonic,LBPL_TEXT);
         return(err);
      }
      if( preByte == PAGE3 ) return(FlagError());
   }
   strcpy(mnemonic,STA_TEXT);
   Opcode4XToFXMnemonic(2);
   return(Opcode4XToFXAddress());
}

RETCODE DasmInfo::Jmp(){
   if(preByte != PAGE0) return(FlagError());
   strcpy(mnemonic,JMP_TEXT);
   return(HandleIndex20());
}

RETCODE DasmInfo::Jsr(){
   if( (preByte == PAGE3) && (opcode == 0x89) ) {
      strcpy(mnemonic,LBVS_TEXT);
      return(HandleRel16(TRUE));
   }
   if(preByte != PAGE0) return(FlagError());
   strcpy(mnemonic,JSR_TEXT);
   callType = INST_CALL;
   transfer = TRUE;
   return(HandleIndex20());
}

RETCODE DasmInfo::Cpx(){
   strcpy(mnemonic,CPX_TEXT);
   if(preByte == PAGE0) return(HandleIndex8());
   if(preByte == PAGE1) return(HandleIndex16());
   if( preByte == PAGE2 ) {
      switch(opcode) {
         case 0x4c: strcpy(mnemonic,NOP_TEXT); break;
         case 0x5c: strcpy(mnemonic,TXY_TEXT); break;
         case 0x6c: strcpy(mnemonic,TXZ_TEXT); break;
      }
   }
   else {
      switch(opcode) {
         case 0x4c: strcpy(mnemonic,XGEX_TEXT); break;
         case 0x5c: strcpy(mnemonic,XGEY_TEXT); break;
         case 0x6c: strcpy(mnemonic,XGEZ_TEXT); break;
      }
   }
   return(GOOD);
}
         
RETCODE DasmInfo::Opcd7b(){
   RETCODE err;
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,MAC_TEXT);
                  err = HandleImmed8();
                  addrMode.type = XOYO;
                  return(err);
      case PAGE2: strcpy(mnemonic,TDE_TEXT); return(GOOD);
      default: return(FlagError());
   }
   
}

RETCODE DasmInfo::Opcd7c(){
   strcpy(mnemonic,CPX_TEXT);
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,ADDE_TEXT);
                  return(HandleImmed8());
      case PAGE1: return(HandleExt());
      case PAGE2: strcpy(mnemonic,ROLE_TEXT); return(GOOD);
      case PAGE3: return(HandleImmed16());
   }
   return(FlagError());
}

RETCODE DasmInfo::OpcdB0(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BRA_TEXT);
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,LDHI_TEXT); /* not really ext but inh !!! */
                  dataCycles += 4;  /* reads enough  memory to fill H and I */
                  return(GOOD);
      case PAGE3: strcpy(mnemonic,SUBD_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdB1(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BRN_TEXT);
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,TEDM_TEXT);
                  return(GOOD);
      case PAGE3: strcpy(mnemonic,ADDD_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdB2(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BHI_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,TEM_TEXT);
                  return(GOOD);
      case PAGE3: strcpy(mnemonic,SBCD_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdB3(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BLS_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,TMXED_TEXT);
                  return(GOOD);
      case PAGE3: strcpy(mnemonic,ADCD_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}
RETCODE DasmInfo::OpcdB4(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BCC_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,TMER_TEXT);
                  return(GOOD);
      case PAGE3: strcpy(mnemonic,EORD_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdB5(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BCS_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,TMET_TEXT);
                  return(GOOD);
      case PAGE3: strcpy(mnemonic,LDD_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdB6(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BNE_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,ASLM_TEXT);
                  return(GOOD);
      case PAGE3: strcpy(mnemonic,ANDD_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdB7(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BEQ_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,CLRM_TEXT);
                  return(GOOD);
      case PAGE3: strcpy(mnemonic,ORD_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdB8(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BVC_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,PSHMAC_TEXT);
                  dataCycles += 6;
                  return(GOOD);
      case PAGE3: strcpy(mnemonic,CPD_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdB9(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BVS_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,PULMAC_TEXT);
                  dataCycles += 6;
                  return(GOOD);
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdBA(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BPL_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,ASRM_TEXT);
                  return(GOOD);
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdBB(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BMI_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE2: strcpy(mnemonic,TEKB_TEXT);
                  return(GOOD);
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdBC(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BGE_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE1: strcpy(mnemonic,STX_TEXT);
                  return(HandleExt());
      case PAGE3: strcpy(mnemonic,LDX_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdBD(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BLT_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE1: strcpy(mnemonic,STY_TEXT);
                  return(HandleExt());
      case PAGE3: strcpy(mnemonic,LDY_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdBE(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BGT_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE1: strcpy(mnemonic,STZ_TEXT);
                  return(HandleExt());
      case PAGE3: strcpy(mnemonic,LDZ_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdBF(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,BLE_TEXT);
                  conditional = TRUE; 
                  return(HandleRel8(TRUE));
      case PAGE1: strcpy(mnemonic,STS_TEXT);
                  return(HandleExt());
      case PAGE3: strcpy(mnemonic,LDS_TEXT);
                  return(HandleImmed16());
      default: return(FlagError());
   }
}

RETCODE DasmInfo::OpcdFA(){
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,JSR_TEXT);
                  callType = INST_CALL;
                  transfer = TRUE;
                  return(HandleExt20());
      case PAGE1: strcpy(mnemonic,STAB_TEXT);
                  return(HandleExt());
      case PAGE2: strcpy(mnemonic,TBEK_TEXT);
                  return(GOOD);
      case PAGE3: strcpy(mnemonic,STD_TEXT);
                  return(HandleExt());
   }
   return(FlagError());
}

RETCODE DasmInfo::OpcdFB(){
   RETCODE err;
   switch(preByte) {
      case PAGE0: strcpy(mnemonic,RMAC_TEXT);
                  dataCycles += 1;   /* !!! how many iterations??? */
                  err = HandleImmed8();
                  addrMode.type = XOYO;
                  return(err);
      case PAGE2: strcpy(mnemonic,TED_TEXT);
                  return(GOOD);
      default:    return(FlagError());
   }
}

RETCODE DasmInfo::Cpy(){
   RETCODE err=GOOD;
   strcpy(mnemonic,CPY_TEXT);
   switch( preByte ) {
      case PAGE0:
         if( opcode == 0x7d ) return(FlagError());
         return(HandleIndex8());
      case PAGE1:
         if( opcode == 0x7d ) return(HandleExt());
         return(HandleIndex16());
      case PAGE2:
         switch(opcode) {
            case 0x4d: strcpy(mnemonic,TYX_TEXT); break;
            case 0x5d: err = FlagError(); break;
            case 0x6d: strcpy(mnemonic,TYZ_TEXT); break;
            case 0x7d: strcpy(mnemonic,ASRE_TEXT); break;
         }
         break;
      case PAGE3:
         switch(opcode) {
            case 0x4d: strcpy(mnemonic,AEX_TEXT); break;
            case 0x5d: strcpy(mnemonic,AEY_TEXT); break;
            case 0x6d: strcpy(mnemonic,AEZ_TEXT); break;
            case 0x7d: err = HandleImmed16();
         }
   }
   return(err);
}

RETCODE DasmInfo::Cpz(){
   RETCODE err = GOOD;
   strcpy(mnemonic,CPZ_TEXT);
   switch( preByte ) {
      case PAGE0:
         if( opcode == 0x7e ) return(FlagError());
         return(HandleIndex8());
      case PAGE1:
         if( opcode == 0x7e ) return(HandleExt());
         return(HandleIndex16());
      case PAGE2:
         switch(opcode) {
            case 0x4e: strcpy(mnemonic,TZX_TEXT); break;
            case 0x5e: strcpy(mnemonic,TZY_TEXT); break;
            case 0x6e: err = FlagError(); break;
            case 0x7e: strcpy(mnemonic,RORE_TEXT); break;
         }
         break;
      case PAGE3:
         switch(opcode) {
            case 0x4e: strcpy(mnemonic,TXS_TEXT); break;
            case 0x5e: strcpy(mnemonic,TYS_TEXT); break;
            case 0x6e: strcpy(mnemonic,TZS_TEXT); break;
            case 0x7e: err = HandleImmed16();
         }
   }
   return(err);
}

RETCODE DasmInfo::Cps(){
   RETCODE err=GOOD;
   strcpy(mnemonic,CPS_TEXT);
   switch( preByte ) {
      case PAGE0:
         if( opcode == 0x7f ) return(FlagError());
         return(HandleIndex8());
      case PAGE1:
         if( opcode == 0x7f ) return(HandleExt());
         return(HandleIndex16());
      case PAGE2:
         switch(opcode) {
            case 0x4f: strcpy(mnemonic,TSX_TEXT); break;
            case 0x5f: strcpy(mnemonic,TSY_TEXT); break;
            case 0x6f: strcpy(mnemonic,TSZ_TEXT); break;
            case 0x7f: strcpy(mnemonic,LSRE_TEXT); break;
         }
         break;
      case PAGE3:
         switch(opcode) {
            case 0x4f: strcpy(mnemonic,ABX_TEXT); break;
            case 0x5f: strcpy(mnemonic,ABY_TEXT); break;
            case 0x6f: strcpy(mnemonic,ABZ_TEXT); break;
            case 0x7f: err = HandleImmed16();
         }
   }
   return(err);
}

RETCODE DasmInfo::Ldx(){
   strcpy(mnemonic,LDX_TEXT);
   switch (preByte) {
      case PAGE0: if( opcode == 0xfc ) {
                     strcpy(mnemonic,ADDD_TEXT);
                     return(HandleImmed8());
                  }
                  return(HandleIndex8());
      case PAGE1: if( opcode == 0xfc ) return(HandleExt());
                  return(HandleIndex16());
      case PAGE2: if( opcode == 0xfc ) {
                     strcpy(mnemonic,ROLD_TEXT);
                     return(GOOD);
                  }
                  return(FlagError());
      case PAGE3:                  
         switch(opcode) {
            case 0xcc: strcpy(mnemonic,XGDX_TEXT); break;
            case 0xdc: strcpy(mnemonic,XGDY_TEXT); break;
            case 0xec: strcpy(mnemonic,XGDZ_TEXT); break;
            case 0xfc: strcpy(mnemonic,TPA_TEXT); break;
         }
   }
   return(GOOD);
}

RETCODE DasmInfo::Ldy(){
   strcpy(mnemonic,LDY_TEXT);
   switch (preByte) {
      case PAGE0: if( opcode == 0xfd ) return(FlagError());
                  return(HandleIndex8());
      case PAGE1: if( opcode == 0xfd ) return(HandleExt());
                  return(HandleIndex16());
      case PAGE2: if( opcode == 0xfd ) {
                     strcpy(mnemonic,ASRD_TEXT);
                     return(GOOD);
                  }
                  return(FlagError());
      case PAGE3:                  
         switch(opcode) {
            case 0xcd: strcpy(mnemonic,ADX_TEXT); break;
            case 0xdd: strcpy(mnemonic,ADY_TEXT); break;
            case 0xed: strcpy(mnemonic,ADZ_TEXT); break;
            case 0xfd: strcpy(mnemonic,TAP_TEXT); break;
         }
   }
   return(GOOD);
}

RETCODE DasmInfo::Ldz(){
   strcpy(mnemonic,LDZ_TEXT);
   switch (preByte) {
      case PAGE0: if( opcode == 0xfe ) return(FlagError());
                  return(HandleIndex8());
      case PAGE1: if( opcode == 0xfe ) return(HandleExt());
                  return(HandleIndex16());
      case PAGE2: if( opcode == 0xfe ) {
                     strcpy(mnemonic,RORD_TEXT);
                     return(GOOD);
                  }
      case PAGE3: if( opcode == 0xfe ) {  /* MOVB ext->ext */
                     strcpy(mnemonic,MOVB_TEXT);
                     return(HandleExtToExt());
                  }
   }
   return(FlagError());
}

RETCODE DasmInfo::Lds(){
   strcpy(mnemonic,LDS_TEXT);
   switch (preByte) {
      case PAGE0: if( opcode == 0xff ) return(FlagError());
                  return(HandleIndex8());
      case PAGE1: if( opcode == 0xff ) return(HandleExt());
                  return(HandleIndex16());
      case PAGE2: if( opcode == 0xff ) {
                     strcpy(mnemonic,LSRD_TEXT);
                     return(GOOD);
                  }
      case PAGE3: if( opcode == 0xff ) {  /* MOVW ext->ext */
                     strcpy(mnemonic,MOVW_TEXT);
                     return(HandleExtToExt());
                  }
   }
   return(FlagError());
}

RETCODE DasmInfo::Stx(){
   strcpy(mnemonic,STX_TEXT);
   switch (preByte) {
      case PAGE0: return(HandleIndex8());
      case PAGE1: return(HandleIndex16());
      case PAGE3:                  
         switch(opcode) {
            case 0x8c: strcpy(mnemonic,LBGE_TEXT); return(HandleRel16(TRUE));
            case 0x9c: strcpy(mnemonic,TBXK_TEXT); break;
            case 0xac: strcpy(mnemonic,TXKB_TEXT); break;
         }
	 return(GOOD);
      default: return(FlagError());
   }
}

RETCODE DasmInfo::Sty(){
   strcpy(mnemonic,STY_TEXT);
   switch (preByte) {
      case PAGE0: return(HandleIndex8());
      case PAGE1: return(HandleIndex16());
      case PAGE3:                  
         switch(opcode) {
            case 0x8d: strcpy(mnemonic,LBLT_TEXT); return(HandleRel16(TRUE));
            case 0x9d: strcpy(mnemonic,TBYK_TEXT); break;
            case 0xad: strcpy(mnemonic,TYKB_TEXT); break;
         }
	 return(GOOD);
      default: return(FlagError());
   }
}

RETCODE DasmInfo::Stz(){
   strcpy(mnemonic,STZ_TEXT);
   switch (preByte) {
      case PAGE0: return(HandleIndex8());
      case PAGE1: return(HandleIndex16());
      case PAGE3:                  
         switch(opcode) {
            case 0x8e: strcpy(mnemonic,LBGT_TEXT); return(HandleRel16(TRUE));
            case 0x9e: strcpy(mnemonic,TBZK_TEXT); break;
            case 0xae: strcpy(mnemonic,TZKB_TEXT); break;
         }
	 return(GOOD);
      default: return(FlagError());
   }
}

RETCODE DasmInfo::Sts(){
   strcpy(mnemonic,STS_TEXT);
   switch (preByte) {
      case PAGE0: return(HandleIndex8());
      case PAGE1: return(HandleIndex16());
      case PAGE3:                  
         switch(opcode) {
            case 0x8f: strcpy(mnemonic,LBLE_TEXT); return(HandleRel16(TRUE));
            case 0x9f: strcpy(mnemonic,TBSK_TEXT); break;
            case 0xaf: strcpy(mnemonic,TSKB_TEXT); break;
         }
	 return(GOOD);
      default: return(FlagError());
   }
}

/**************************  PROTECTED METHODS  ******************************/
VOID DasmInfo::PrintInfo(LPSTR buffer) {
   U8 colCnt = 0;
   char tmpBuff[256];
   U32 maxOutputAddr;
   LOOP_VAR i;
   
   if(AdrConvAddressToTextWithParams(pcAddress,FALSE,TRUE,tmpBuff) != GOOD )
      return;
   if(AdrGetMaxOutputAddrOffset(pcAddress,&maxOutputAddr) != GOOD)
      return;
   colCnt += strlen(tmpBuff);     
   strcat(buffer,tmpBuff);
   strcat(buffer,"  ");
   for( i=0; i < instLength; i+=2 ) {
      U16 wrdData = (hexCode[i]<<8) + hexCode[i+1];
      sprintf(tmpBuff,"%04X ", wrdData);
      colCnt += strlen(tmpBuff);     
      strcat(buffer,tmpBuff);
   }
   for( ; colCnt < 28; colCnt++ ) strcat(buffer," ");
   if( addrMode.type != DC_ERR ) {
      sprintf(tmpBuff,"%s",mnemonic);
      colCnt += strlen(tmpBuff);     
      strcat(buffer,tmpBuff);
      for( ; colCnt < 35; colCnt++ ) strcat(buffer," ");
   }
   // NOTES: Nghia - 01/27/93
   // Effective Address will be masked to the cpuMaxOuputAddress - 20bits
   //
   switch( addrMode.type ) {
      case ACCOFF:
         strcat(buffer,"E,");
         PrintIndexRegister(buffer);
         break;
      case EXT:
         // Can't look up word size EXT address because it's not
         // the entire address the upper 4 bits are in EK.
         if (addrMode.size == WORDSIZE) {
            sprintf(tmpBuff,"0x%04X",(U16)addrMode.effAddr);
            strcat(buffer,tmpBuff);
         }
         else {
            if (LookupAddrSymbol(buffer) != GOOD ) {
               sprintf(tmpBuff,"0x%05lX",
                       (U32)(addrMode.effAddr & maxOutputAddr));
               strcat(buffer,tmpBuff);
            }
         }
	      break;
      case IMMED:
         // Looking up immediates wouldn't be too helpful
         // since only enumerations are stored in the symbol
         // table and there could be 4000 definiations for
         // any number. Outputting the wrong name would
         // be worst than just leaving the numeric value.
         if( addrMode.size == BYTESIZE ) {
            if( addrMode.data > 16 )
               sprintf(tmpBuff,"#0x%02X",(U8)addrMode.data);
            else
               sprintf(tmpBuff,"#%d",(U8)addrMode.data);
         } else 
            sprintf(tmpBuff,"#0x%04X",(U16)addrMode.data);
         strcat(buffer,tmpBuff);
         break;
      case INDEX:
         if( addrMode.size == BYTESIZE ) {
            if( addrMode.data > 16 )
               sprintf(tmpBuff,"0x%02X,",(U8)addrMode.data);
            else
               sprintf(tmpBuff,"%d,",(U8)addrMode.data);
         }
         else if( addrMode.size == WORDSIZE )
            sprintf(tmpBuff,"0x%04X,",(U16)addrMode.data);
         else
            sprintf(tmpBuff,"0x%05lX,",
                    (U32)(addrMode.data & maxOutputAddr));
         strcat(buffer,tmpBuff);
         PrintIndexRegister(buffer);
         break;
      case ABS:
         if (LookupAddrSymbol(buffer) != GOOD ) {
            sprintf(tmpBuff,"0x%05lX",
                    (U32)(addrMode.effAddr & maxOutputAddr));
            strcat(buffer,tmpBuff);
         }
         break;
      case PSHLIST: 
         U8 regs = (U8)addrMode.data;
         BOOLEAN firstFound=FALSE;
         if(regs & 0x1) strcat(buffer,(firstFound++ ? ",D" : "D"));
         if(regs & 0x2) strcat(buffer,(firstFound++ ? ",E" : "E"));
         if(regs & 0x4) strcat(buffer,(firstFound++ ? ",X" : "X"));
         if(regs & 0x8) strcat(buffer,(firstFound++ ? ",Y" : "Y"));
         if(regs & 0x10) strcat(buffer,(firstFound++ ? ",Z" : "Z"));
         if(regs & 0x20) strcat(buffer,(firstFound++ ? ",K" : "K"));
         if(regs & 0x40) strcat(buffer,(firstFound++?",CCR":"CCR"));
         if(regs & 0x80) strcat(buffer,"<<BAD BIT SET>>");
         break;
      case PULLIST: 
         regs = (U8)addrMode.data;
         firstFound=FALSE;
         if(regs & 0x1) strcat(buffer,(firstFound++ ? ",CCR" : "CCR"));
         if(regs & 0x2) strcat(buffer,(firstFound++ ? ",K" : "K"));
         if(regs & 0x4) strcat(buffer,(firstFound++ ? ",Z" : "Z"));
         if(regs & 0x8) strcat(buffer,(firstFound++ ? ",Y" : "Y"));
         if(regs & 0x10) strcat(buffer,(firstFound++ ? ",X" : "X"));
         if(regs & 0x20) strcat(buffer,(firstFound++ ? ",E" : "E"));
         if(regs & 0x40) strcat(buffer,(firstFound++?",D":"D"));
         if(regs & 0x80) strcat(buffer,"<<BAD BIT SET>>");
         break;
      case XOYO:
         sprintf(tmpBuff,"%d,%d",(U8)((addrMode.data>>4)&0xF),
                                   (U8)(addrMode.data&0xF));
         strcat(buffer,tmpBuff);
         break;
      case I_TO_E:
           if( addrMode.data > 16 )
              sprintf(tmpBuff,"0x%02X,X,0x%04X",(U8)addrMode.data,
                      (U16)addrMode.effAddr);
           else
              sprintf(tmpBuff,"%d,X,0x%04X",(U8)addrMode.data,
                      (U16)addrMode.effAddr);
           strcat(buffer,tmpBuff);
           break;
      case E_TO_I:
           if( addrMode.data > 16 )
              sprintf(tmpBuff,"0x%04X,0x%02X,X",(U16)addrMode.effAddr,
                      (U8)addrMode.data);
           else
              sprintf(tmpBuff,"0x%04X,%d,X",(U16)addrMode.effAddr,
                      (U8)addrMode.data);
           strcat(buffer,tmpBuff);
           break;
      case E_TO_E:
           sprintf(tmpBuff,"0x%04X,0x%04X",(U16)addrMode.effAddr,
                   (U16)addrMode.effAddr2);
           strcat(buffer,tmpBuff);
           break;
      case DC_ERR:
         strcat(buffer,"dc    ");
         for(LOOP_VAR i=0; i < instLength; i++) {
            if( i ) strcat(buffer,",");
            sprintf(tmpBuff," 0x%02X",hexCode[i]);
            strcat(buffer,tmpBuff);
         }
         break;
   }
   if( addrMode.maskedInst ) {
      /* bclr/bset or brclr/brset instructions */
      if( addrMode.maskSize == BYTESIZE ) {
         if( addrMode.mask > 16 )
            sprintf(tmpBuff,",#0x%02X",(U8)addrMode.mask);
         else
            sprintf(tmpBuff,",#%d",(U8)addrMode.mask);
      } else 
         sprintf(tmpBuff,",#0x%04X",(U16)addrMode.mask);
      strcat(buffer,tmpBuff);
      /* brclr/brset instructions */
      if( transfer ) {
         strcat(buffer,",");
         addrMode.effAddr =  addrMode.effAddr2;
         if(LookupAddrSymbol(buffer) != GOOD ) {
            sprintf(tmpBuff,"%05lX",
                    (U32)(addrMode.effAddr & maxOutputAddr));
            strcat(buffer,tmpBuff);
         }
      }
   }
   strcat(buffer,"\r\n");
}
   
VOID DasmInfo::PrintIndexRegister(LPSTR buffer) {
   switch(addrMode.reg) {
      case XREG: strcat(buffer,"X"); break;
      case YREG: strcat(buffer,"Y"); break;
      case ZREG: strcat(buffer,"Z"); break;
   }
}

VOID DasmInfo::CommonInitialization() {
   codePtr = hexCode;
   addrMode.type = INH;	
   addrMode.maskedInst = FALSE;
   transfer = FALSE;
   conditional = FALSE;
   callType = INST_NONE;
   instLength = 0;
   dataCycles = 0;
}

/***************************  PRIVATE  METHODS  *****************************/
VOID DasmInfo::DecodeBytes() {
   opcode = GetNextCodeByte();
   if( (opcode == 0x17) || (opcode == 0x27) || (opcode == 0x37) ){
      preByte = (PREBYTE)opcode;
      opcode = GetNextCodeByte();
   }
   else preByte = PAGE0;
   
   (this->*opcodeFunctions[opcode])();
}

// Return the next byte in the hexCode array and increment the number
// of bytes used.
U8 DasmInfo::GetNextCodeByte() {
   instLength++;
   return(*codePtr++);
}

RETCODE DasmInfo::HandleImmed16() { 
   addrMode.type = IMMED;
   addrMode.size = WORDSIZE;
   addrMode.data = (U32)((GetNextCodeByte() << 8) + GetNextCodeByte());
   return(GOOD);
}

RETCODE DasmInfo::HandleImmed8() {
   addrMode.type = IMMED;
   addrMode.size = BYTESIZE;
   addrMode.data = (U32)GetNextCodeByte();
   return(GOOD);
}

RETCODE DasmInfo::HandleIndex16() {
   addrMode.type = INDEX;
   addrMode.size = WORDSIZE;
   addrMode.data = (U32)((GetNextCodeByte() << 8) + GetNextCodeByte());
   DetermineIndexRegister();
   return(GOOD);
}

RETCODE DasmInfo::HandleIndex20() {
   addrMode.type = INDEX;   /* get ind20 offset */
   addrMode.size = LONGSIZE;
   addrMode.data = (U32)( (U32)GetNextCodeByte() << 16 ) ;
   addrMode.data += (U32)( (U32)GetNextCodeByte() << 8 ) ;
   addrMode.data += (U32)GetNextCodeByte();
   DetermineIndexRegister();
   return(GOOD);
}

RETCODE DasmInfo::HandleIndex8() {
   addrMode.type = INDEX;
   addrMode.size = BYTESIZE;
   addrMode.data = (U32)GetNextCodeByte();
   DetermineIndexRegister();
   return(GOOD);
}

RETCODE DasmInfo::HandleExtToIxp() {
   dataCycles = 2;
   addrMode.type = E_TO_I;
   addrMode.data = (U32)GetNextCodeByte();
   addrMode.effAddr = (U32)((GetNextCodeByte() << 8) + GetNextCodeByte());
   return(GOOD);
}

RETCODE DasmInfo::HandleIxpToExt() {
   dataCycles = 2;
   addrMode.type = I_TO_E;
   addrMode.data = (U32)GetNextCodeByte();
   addrMode.effAddr = (U32)((GetNextCodeByte() << 8) + GetNextCodeByte());
   return(GOOD);
}

RETCODE DasmInfo::HandleExt() {
   addrMode.type = EXT;
   dataCycles++;
   addrMode.size = WORDSIZE;
   /* get ext address */
   addrMode.effAddr = (U32)((GetNextCodeByte() << 8) + GetNextCodeByte());
   return(GOOD);
}

RETCODE DasmInfo::HandleExt20() {
   addrMode.type = EXT;   /* get ext20 address */
   dataCycles++;
   addrMode.size = LONGSIZE;
   transfer = TRUE;
   addrMode.effAddr = (U32)( (U32)GetNextCodeByte() << 16 ) ;
   addrMode.effAddr += (U32)( (U32)GetNextCodeByte() << 8 ) ;
   addrMode.effAddr += (U32)GetNextCodeByte();
   return(GOOD);
}

RETCODE DasmInfo::HandleAccOffset() {
   addrMode.type = ACCOFF;
   DetermineIndexRegister();
   return(GOOD);
}

// Check the incoming relOff against limitValue and calculate the
// effective address accordingly. This routine sets the transfer flag
// to TRUE; changes the addrMode.type field if changeType is TRUE and sets
// the addrMode.effAddr to calculated address given the starting address
// and relOff.
RETCODE DasmInfo::HandleRel(BOOLEAN changeType, U16 relOff, U16 limitValue) {
   RETCODE err;
   U32 modPc;
   DESCRIPTOR pcCopy;
   transfer = TRUE;
   if( changeType ) addrMode.type = ABS;
   if((err=AdrDuplicateAddress(pcAddress, &pcCopy))!=GOOD)  {
      FlagError();
      return err;
   }
   if( relOff > limitValue ) {
      if( limitValue == 0x7f ) addrMode.effAddr = 0xffffff00;
      else addrMode.effAddr = 0xffff0000;
      addrMode.effAddr |= (U32)relOff;
   }
   else
      addrMode.effAddr = (U32)relOff;

   if((err=AdrAddToAddress(pcCopy, 6L))!=GOOD)  {
      FlagError();
      return err;
   }
   if((err=AdrGetAddrOffset(pcCopy,&modPc))!=GOOD) {
      FlagError();
      return err;
   }
   addrMode.effAddr += modPc;
   if((err=AdrDestroyAddress(pcCopy))!=GOOD) {
      FlagError();
      return(err);
   }   
   return(GOOD);
}

// Fetchs one byte of relative offset.
RETCODE DasmInfo::HandleRel8(BOOLEAN changeType) {
   U16 relOff;
   relOff = GetNextCodeByte();
   return(HandleRel(changeType,relOff,0x7f));
}

// Fetchs two bytes of relative offset.
RETCODE DasmInfo::HandleRel16(BOOLEAN changeType) {
    U16 relOff;
    relOff = (U16)((GetNextCodeByte() << 8) + GetNextCodeByte());
   return(HandleRel(changeType,relOff,0x7fff));
}

RETCODE DasmInfo::HandleExtToExt() {
   addrMode.type = E_TO_E;
   addrMode.effAddr = (U32)((GetNextCodeByte() << 8) + GetNextCodeByte());
   addrMode.effAddr2 = (U32)((GetNextCodeByte() << 8) + GetNextCodeByte());
   dataCycles = 2;
   return(GOOD);
}

// Flag an error by setting type to DC_ERR then print routine
// can use instLength and hexCode to print out the bytes gobbled.
RETCODE DasmInfo::FlagError(){
   addrMode.type = DC_ERR;
   instLength = (instLength+2) & 0xfffffffeL;  // round up to even count
   return(ER_DAD_INVALID_OPCODE);
}

//    Operand Group 6 contains the following opcodes:
//   ASL       ASR       CLR       COM       DEC      INC      LSR
//   NEG       ROL       ROR       STS       STX      STY      STZ
//   TST
// Group6 - doesn't have any special meaning just my numbering scheme
// for organizing the opcodes.  The Mnemonic routine checks to see if
// the opcode desired is ASLA or ASLW or ASLB or just ASL (for example).
// 
//
VOID DasmInfo::Group6Mnemonic(){
   mnemonic[4] = '\0';   /* null out 5th byte incase we fill in 4th one */
   if( preByte == PAGE2 ) {
      mnemonic[3] = 'w';
      dataCycles++;
   }
   else if( preByte == PAGE3 ) {
      if( (opcode & 0x30) == 0 )
         mnemonic[3] = 'a';
      else
         mnemonic[3] = 'b';
   }
}

// This address check routine checks the indicated bits to see
// which addressing mode the opcode selected.
RETCODE DasmInfo::Group6Address() {
   U8 bits = (opcode >> 4) & 3;
   if( bits == 3 ) HandleExt();
   else {
      if( preByte == PAGE0 ) HandleIndex8();
      else if( (preByte == PAGE1) || (preByte == PAGE2) ) HandleIndex16();
   }
   return(GOOD);
}

// Opcodes $4X thru $FX.  Not exclusively!  This group of opcodes
// had a common set of bits to indicate which opcode mnemonic to
// use.  For example SUBA, SUBD, SUBE or SUBB.  Index is passed
// in to handle changing both the four letter opcodes and the
// three letter opcodes. 
VOID DasmInfo::Opcode4XToFXMnemonic(U8 index){
   U16 bits = (opcode >> 6) & 0x3;
   mnemonic[index+1] = '\0';
   mnemonic[index+2] = '\0';
   if( bits == 1 ) {
      if( preByte == PAGE3 ) 
         mnemonic[index] = 'e';
      else
         mnemonic[3] = 'a';
   }
   else if( (bits == 2) || (preByte == PAGE3) )
      mnemonic[index] = 'd';
   else
      mnemonic[3] = 'b';
}

// Check common opcode bits and preByte to determine which addressing
// mode is being used.
RETCODE DasmInfo::Opcode4XToFXAddress() {
   U8 bits = (opcode >> 4) & 3;
   if( bits != 3 ) {
      switch (preByte) {
         case PAGE0: HandleIndex8(); break;
         case PAGE3:
         case PAGE1: HandleIndex16(); break;
         case PAGE2: HandleAccOffset(); break;
      }
   }
   else {
      switch (preByte) {
         case PAGE0: HandleImmed8(); break;
         case PAGE1: 
         case PAGE3: HandleExt(); break;
      }
   }
   return(GOOD);
}

// Determine which index register is being used.
RETCODE DasmInfo::DetermineIndexRegister() {
   U8 bits = (opcode >> 4) & 3;
   dataCycles++;
   switch(bits) {
      case 0:  addrMode.reg = XREG; break;
      case 1:  addrMode.reg = YREG; break;
      case 2:  addrMode.reg = ZREG; break;
   }
   return(GOOD);
}

// Determines the addressing mode for the instructions that
// use masks.  (i.e.: bclr, bset, brclr and brset).
RETCODE DasmInfo::MaskedAddress() {
   U8 bits = (opcode >> 4) & 3;
   addrMode.maskedInst = TRUE;
   addrMode.maskSize = BYTESIZE;
   addrMode.mask = (U16)GetNextCodeByte();
   if( preByte == PAGE2 ) {  /* word size mask */
      addrMode.mask <<= 8;
      addrMode.mask += GetNextCodeByte();
      addrMode.maskSize = WORDSIZE;
   }
   if( bits == 3 ) HandleExt();
   else {
      if( (preByte == PAGE1) /*bclr/bset case*/
         || ((opcode&0xc0)!=0x00) /* brclr/brset */ ) HandleIndex8();
      else HandleIndex16();
   }
   return(GOOD);
}

#define MAX_INST_SIZE 6
#define PAGESIZE 256
// fill hexCode array by reading 6 bytes from pc and initializes
// DasmInfo structure state.
RETCODE DasmInfo::FillCodeBuffer() {
   RETCODE err;
   DESCRIPTOR pcAddr;
   BOOLEAN fillCache = FALSE;
   U32 offset;
   GetStartAddress(&pcAddr);
   if ((err = AdrGetAddrOffset(pcAddr,&offset)) != GOOD) return err;
   if( cacheStartOffset == 0xffffffffL ) fillCache = TRUE;
   else {
      if( (offset >= cacheStartOffset)
          && ((offset+MAX_INST_SIZE) <= (cacheStartOffset+PAGESIZE-1))) {
         U16 cacheOffset = (U16) (offset - cacheStartOffset);
         memmove(hexCode,memCacheBuf+cacheOffset,MAX_INST_SIZE);
      }
      else {
         /*
         ** our requested data is not completely in the memory cache,
         ** so get a new cache.
         */
         if ((err = FreeDasmCache()) != GOOD) return err;
         fillCache = TRUE;
      }
   }
   if( fillCache ) {
      if ((err = MemReadSized(pcAddr,PAGESIZE,&memCacheBuf,WORD_SIZE,
            CACHE_USE)) != GOOD) {
         TFree(memCacheBuf);
         AdrDestroyAddress(pcAddr);
         memCacheBuf = NULL;
         return err;
      }
      cacheStartOffset = offset;
      memmove(hexCode,memCacheBuf,MAX_INST_SIZE);
   }

   AdrDestroyAddress(pcAddr);
   CommonInitialization();
   return(GOOD) ;
}

/* The offset to lookup is in addrMode.effAddr. */

RETCODE DasmInfo::LookupAddrSymbol(LPSTR buffer) {
   BOOLEAN needEndParen = FALSE;
   BOOLEAN dasmSym;
   DESCRIPTOR  dadAddr;
   RETCODE err = GOOD, firstErr;
   U8 operandName[MAX_SYMNAME_LENGTH];
   if ((err = DadGetDasmSymbol(&dasmSym)) != GOOD) return(err);
   if((err=AdrCreateAddress(&dadAddr))!=GOOD) return(err);
   if((err=AdrSetAddrOffset(dadAddr, addrMode.effAddr))!= GOOD ) {
      AdrDestroyAddress(dadAddr);
      return(err);
   }
   if( dasmSym ) {
      MEM_ADDR_CLASS memoryClass;
      SYM_TYPE_TYPE symbolType;
      SYM_DESCRIPTOR outputSymbol,funcDescriptor,moduleDescriptor;
      U32 offset;
      DESCRIPTOR symNameDesc;
      if(SymMapAddr2Symbol(dadAddr,&memoryClass,&symbolType,
         &offset,&outputSymbol,&funcDescriptor,&moduleDescriptor) == GOOD){
         if( outputSymbol != NULL_SYMBOL ) {
            if((err=SymGetSymbolName(outputSymbol,&symNameDesc))==GOOD){
               strcat(buffer, (LPSTR)symNameDesc);
               if( offset ) {
                  wsprintf(operandName," + %ld",offset);
                  strcat(buffer,operandName);
               }
               strcat(buffer,"  (");
               needEndParen = TRUE;
               err = TFree((LPSTR)symNameDesc);
            }
         }
      }
   }
   firstErr = err;
   if ((err = AdrConvAddressToTextWithParams(dadAddr,FALSE,TRUE,
         operandName)) == GOOD) {
      strcat(buffer,operandName);
   }
   else firstErr = err;
   if( needEndParen ) strcat(buffer,")");
   err = AdrDestroyAddress(dadAddr);
   if( firstErr == GOOD ) firstErr = err;
   return firstErr;
}

RETCODE FreeDasmCache(VOID) {
   RETCODE err;
   if ((cacheStartOffset != 0xffffffffL) && (memCacheBuf != NULL)) {
      if ((err = TFree((LPSTR)memCacheBuf)) != GOOD) return err;
      cacheStartOffset = 0xffffffffL;
      memCacheBuf = NULL;
   }
   return GOOD;
}
