/*****************************************************************************
**
**  Name:  asm16.h
**
**  Description:
**     This is a assembler class header
**
**  Status:  
**
**  $Log:   S:/tbird/mt2_186/dad186/asm16.h_v  $
** 
**    Rev 1.0   16 Dec 1996 15:13:36   Judy
** Initial revision.
** 
**    Rev 1.1   25 May 1993 12:04:50   ernie
** Changed dasmSym to be system-wide global
** 
**    Rev 1.0   08 Apr 1993 09:41:38   doug
** Initial revision.
** 
**    Rev 1.1   30 Mar 1993 16:11:56   ernie
** (for mindy): added symbol support
** 
**    Rev 1.0   12 Mar 1993 09:53:48   mindy
** Initial revision.
** 
**  $Header:   S:/tbird/mt2_186/dad186/asm16.h_v   1.0   16 Dec 1996 15:13:36   Judy  $
**
**  Copyright (C) 1993 Microtek International.  All rights reserved.
**
*****************************************************************************/

#define _ASM16_

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include <object.h>

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


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

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
/* This class is created to allow us to use the dictionary in the
   container classes. Each possible opcode will have a matching
   OpcodeInfo object that contains the base opcode value and
   an opcode group.  The opcode group determines which addressing
   modes are valid for the given opcode.
 */ 
_CLASSDEF(OpcodeInfo)
class OpcodeInfo: public Object {
public:
   enum OPGROUP { OG1,  OG2,  OG3,  OG4,  OG5,  OG6,  OG7,  OG8,  OG9,  OG10,
                  OG11, OG12, OG13, OG14, OG15, OG16, OG17, OG18, OG19, OG20,
                  OG21, OG22, OG23, OG24, OG25, OG26, OG27, OG28, OG29, OG30};

    OpcodeInfo(OPGROUP grp, int value);
    ~OpcodeInfo() {};
    OPGROUP Group() const { return group; };
    U8 opValue() const { return opcodeValue; };
    virtual classType isA() const { return 444; };  /* !!! make up a #??? */
    virtual char _FAR *nameOf() const;
    virtual hashValueType hashValue() const { return 0; };
    virtual int isEqual( const Object& ) const { return 0; };
    virtual void printOn( ostream& ) const;
protected:
   OPGROUP group;
   U8 opcodeValue;
};


_CLASSDEF(AsmInfo)
class AsmInfo : public AsmDasmBase {
public:
   AsmInfo(DESCRIPTOR addr);
   RETCODE Asm(LPSTR userAsm, LPSTR *outAsm);
   RETCODE SetStartAddress(DESCRIPTOR addr);
   RETCODE GetStartAddress(DESCRIPTOR *addr);
   U16 InstructionLength();

   /* Which one of these routines to call is determined by the opcode
      group value found in the OpcodeInfo object retrived using the
      opcode text from the dictionary.
      Each routines check the ADDRESS_MODE filled in by ParseString
      to determine if addressing mode is valid or not.
      NOTE: These are made public so I can made an array of function
            pointers so I don't need to have a 20 some case switch statement.
    */      
   RETCODE OpGrp1(OpcodeInfo info);
   RETCODE OpGrp2(OpcodeInfo info);
   RETCODE OpGrp3(OpcodeInfo info);
   RETCODE OpGrp4(OpcodeInfo info);
   RETCODE OpGrp5(OpcodeInfo info);
   RETCODE OpGrp6(OpcodeInfo info);
   RETCODE OpGrp7(OpcodeInfo info);
   RETCODE OpGrp8(OpcodeInfo info);
   RETCODE OpGrp9(OpcodeInfo info);
   RETCODE OpGrp10(OpcodeInfo info);
   RETCODE OpGrp11(OpcodeInfo info);
   RETCODE OpGrp12(OpcodeInfo info);
   RETCODE OpGrp13(OpcodeInfo info);
   RETCODE OpGrp14(OpcodeInfo info);
   RETCODE OpGrp15(OpcodeInfo info);
   RETCODE OpGrp16(OpcodeInfo info);
   RETCODE OpGrp17(OpcodeInfo info);
   RETCODE OpGrp18(OpcodeInfo info);
   RETCODE OpGrp19(OpcodeInfo info);
   RETCODE OpGrp20(OpcodeInfo info);
   RETCODE OpGrp21(OpcodeInfo info);
   RETCODE OpGrp22(OpcodeInfo info);
   RETCODE OpGrp23(OpcodeInfo info); 
   RETCODE OpGrp24(OpcodeInfo info); 
   RETCODE OpGrp25(OpcodeInfo info); 
   RETCODE OpGrp26(OpcodeInfo info); 
   RETCODE OpGrp27(OpcodeInfo info); 
   RETCODE OpGrp28(OpcodeInfo info); 
   RETCODE OpGrp29(OpcodeInfo info); 
   RETCODE OpGrp30(OpcodeInfo info); 
      
private:
   /* ParseString will tokenize the input.  This routine will
      also determine what it can about the address mode.  It can
      fills in most of the ADDRESS_MODE information.
   */      
   RETCODE ParseString(LPSTR buffer);

   /* FIlls in the next byte of the hexCode using codePtr and incrementing
      instLength by one. */
   VOID PutNextCodeByte(U8 val);
   VOID PutCodeBytes(U32 val, U8 numBytes);

   /* Writes out instLength number of bytes from hexCode to memory
      starting at pcAddress. */
   RETCODE WriteCodeBuffer();

   U8 ModOpcodeForIndexReg(U8 opcode);
   RETCODE CalculateDisplacement(U32 effAddr, BOOLEAN longBranch);
   
   RETCODE DetermineSize(LPSTR text, U32 *data);
   RETCODE DetermineEffectiveAddress(LPSTR text, U32 *data, BOOLEAN *symFound);
   RETCODE DecodePshlist();
   RETCODE DecodePullist();
   RETCODE DetermineIndexRegister(char ch);

   VOID HandleExt(LPSTR extAddr);
   VOID HandleMask(LPSTR mask);
      
   BOOLEAN      maskedTransfer;

   U8           numTokens;
   LPSTR        tokens[20];         /* PSHLIST could contains many tokens */
};


#ifdef __cplusplus
extern "C" {
#endif
                        /****************************
                         *                          *
                         *        PROTOTYPES        *
                         *                          *
                         ****************************/

RETCODE EXPORT AsmInit(VOID);


#ifdef __cplusplus
}
#endif
/******************************** E O F ***********************************/
