/* code51.c */
/*****************************************************************************/
/* AS-Portierung                                                             */
/*                                                                           */
/* Codegenerator fuer MCS-51/252 Prozessoren                                 */
/*                                                                           */
/* Historie:  5. 6.1996 Grundsteinlegung                                     */
/*            9. 8.1998 kurze 8051-Bitadressen wurden im 80251-Sourcemodus   */
/*                      immer lang gemacht                                   */
/*           24. 8.1998 Kodierung fuer MOV dir8,Rm war falsch (Fehler im     */
/*                      Manual!)                                             */
/*            2. 1.1998 ChkPC-Routine entfernt                               */
/*                                                                           */
/*****************************************************************************/

#include "stdinc.h"
#include <string.h>
#include <ctype.h>

#include "bpemu.h"
#include "strutil.h"
#include "chunks.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmallg.h"
#include "codepseudo.h"
#include "codevars.h"
#include "asmitree.h"

/*-------------------------------------------------------------------------*/
/* Daten */

typedef struct
         { 
          CPUVar MinCPU;
          Word Code;
         } FixedOrder;

#define ModNone (-1)
#define ModReg 1
#define MModReg (1<<ModReg)
#define ModIReg8 2
#define MModIReg8 (1<<ModIReg8)
#define ModIReg 3
#define MModIReg (1<<ModIReg)
#define ModInd 5
#define MModInd (1<<ModInd)
#define ModImm 7
#define MModImm (1<<ModImm)
#define ModImmEx 8
#define MModImmEx (1<<ModImmEx)
#define ModDir8 9
#define MModDir8 (1<<ModDir8)
#define ModDir16 10
#define MModDir16 (1<<ModDir16)
#define ModAcc 11
#define MModAcc (1<<ModAcc)
#define ModBit51 12
#define MModBit51 (1<<ModBit51)
#define ModBit251 13
#define MModBit251 (1<<ModBit251)

#define MMod51 (MModReg+MModIReg8+MModImm+MModAcc+MModDir8)
#define MMod251 (MModIReg+MModInd+MModImmEx+MModDir16)

#define AccOrderCnt 6
#define FixedOrderCnt 5
#define CondOrderCnt 13
#define BCondOrderCnt 3

#define AccReg 11


static FixedOrder *FixedOrders;
static FixedOrder *AccOrders;
static FixedOrder *CondOrders;
static FixedOrder *BCondOrders;
static PInstTable InstTable;

static Byte AdrVals[5];
static Byte AdrPart,AdrSize;
static ShortInt AdrMode,OpSize;
static Boolean MinOneIs0;

static Boolean SrcMode,BigEndian;

static SimpProc SaveInitProc;
static CPUVar CPU87C750,CPU8051,CPU8052,CPU80C320,
       CPU80501,CPU80502,CPU80504,CPU80515,CPU80517,
       CPU80251;

/*-------------------------------------------------------------------------*/
/* Adressparser */

   	static void SetOpSize(ShortInt NewSize)
BEGIN
   if (OpSize==-1) OpSize=NewSize;
   else if (OpSize!=NewSize)
    BEGIN
     WrError(1131); AdrMode=ModNone; AdrCnt=0;
    END
END

	static Boolean DecodeReg(char *Asc, Byte *Erg,Byte *Size)
BEGIN
   static Byte Masks[3]={0,1,3};

   char *Start;
   int alen=strlen(Asc);
   Boolean IO;

   if (strcasecmp(Asc,"DPX")==0)
    BEGIN
     *Erg=14; *Size=2; return True;
    END

   if (strcasecmp(Asc,"SPX")==0)
    BEGIN
     *Erg=15; *Size=2; return True;
    END

   if ((alen>=2) AND (toupper(*Asc)=='R'))
    BEGIN
     Start=Asc+1; *Size=0;
    END
   else if ((MomCPU>=CPU80251) AND (alen>=3) AND (toupper(*Asc)=='W') AND (toupper(Asc[1])=='R'))
    BEGIN
     Start=Asc+2; *Size=1;
    END
   else if ((MomCPU>=CPU80251) AND (alen>=3) AND (toupper(*Asc)=='D') AND (toupper(Asc[1])=='R'))
    BEGIN
     Start=Asc+2; *Size=2;
    END
   else return False;

   *Erg=ConstLongInt(Start,&IO);
   if (NOT IO) return False;
   else if (((*Erg) & Masks[*Size])!=0) return False;
   else
    BEGIN
     (*Erg) >>= (*Size);
     switch (*Size)
      BEGIN
       case 0: return (((*Erg)<8) OR ((MomCPU>=CPU80251) AND ((*Erg)<16)));
       case 1: return ((*Erg)<16);
       case 2: return (((*Erg)<8) OR ((*Erg)==14) OR ((*Erg)==15));
       default: return False;
      END
    END
END

	static void ChkMask(Word Mask, Word ExtMask)
BEGIN
   if ((AdrMode!=ModNone) AND ((Mask & (1 << AdrMode))==0))
    BEGIN
     if ((ExtMask & (1 << AdrMode))==0) WrError(1350); else WrError(1505);
     AdrCnt=0; AdrMode=ModNone;
    END
END

   	static void DecodeAdr(char *Asc_O, Word Mask)
BEGIN
   Boolean OK,FirstFlag;
   Byte HSize;
   Word H16;
   int SegType;
   char *PPos,*MPos,*DispPos,Save='\0';
   LongWord H32;
   String Asc,Part;
   Word ExtMask;

   strmaxcpy(Asc,Asc_O,255);

   AdrMode=ModNone; AdrCnt=0;

   ExtMask=MMod251 & Mask;
   if (MomCPU<CPU80251) Mask &= MMod51;

   if (*Asc=='\0') return;

   if (strcasecmp(Asc,"A")==0)
    BEGIN
     if ((Mask & MModAcc)==0)
      BEGIN
       AdrMode=ModReg; AdrPart=AccReg;
      END
     else AdrMode=ModAcc;
     SetOpSize(0);
     ChkMask(Mask,ExtMask); return;
    END

   if (*Asc=='#')
    BEGIN
     if ((OpSize==-1) AND (MinOneIs0)) OpSize=0;
     switch (OpSize)
      BEGIN
       case -1:
        WrError(1132);
        break;
       case 0:
        AdrVals[0]=EvalIntExpression(Asc+1,Int8,&OK);
        if (OK)
         BEGIN
          AdrMode=ModImm; AdrCnt=1;
         END
        break;
       case 1:
        H16=EvalIntExpression(Asc+1,Int16,&OK);
        if (OK)
         BEGIN
          AdrVals[0]=Hi(H16); AdrVals[1]=Lo(H16);
          AdrMode=ModImm; AdrCnt=2;
         END
        break;
       case 2:
        FirstPassUnknown=False;
        H32=EvalIntExpression(Asc+1,Int32,&OK);
        if (FirstPassUnknown) H32 &= 0xffff;
        if (OK)
         BEGIN
          AdrVals[1] = H32 & 0xff; 
          AdrVals[0] = (H32 >> 8) & 0xff;
          H32 >>= 16; 
          if (H32==0) AdrMode=ModImm;
          else if ((H32==1) OR (H32==0xffff)) AdrMode=ModImmEx;
          else WrError(1132);
          if (AdrMode!=ModNone) AdrCnt=2;
         END
        break;
      END
     ChkMask(Mask,ExtMask); return;
    END

   if (DecodeReg(Asc,&AdrPart,&HSize))
    BEGIN
     if ((MomCPU>=CPU80251) AND ((Mask & MModReg)==0))
      if ((HSize==0) AND (AdrPart==AccReg)) AdrMode=ModAcc;
      else AdrMode=ModReg;
     else AdrMode=ModReg;
     SetOpSize(HSize);
     ChkMask(Mask,ExtMask); return;
    END

   if (*Asc=='@')
    BEGIN
     PPos=strchr(Asc,'+'); MPos=strchr(Asc,'-');
     if ((MPos!=Nil) AND ((MPos<PPos) OR (PPos==Nil))) PPos=MPos;
     if (PPos!=Nil) 
      BEGIN
       Save=(*PPos); *PPos='\0';
      END
     if (DecodeReg(Asc+1,&AdrPart,&HSize))
      BEGIN
       if (PPos==Nil)
        BEGIN
         H32=0; OK=True;
        END
       else
        BEGIN
         *PPos=Save; DispPos=PPos; if (*DispPos=='+') DispPos++;
         H32=EvalIntExpression(DispPos,SInt16,&OK);
        END
       if (OK)
        switch (HSize)
         BEGIN
          case 0:
           if ((AdrPart>1) OR (H32!=0)) WrError(1350);
           else AdrMode=ModIReg8;
           break;
          case 1:
           if (H32==0)
	    BEGIN
	     AdrMode=ModIReg; AdrSize=0;
            END
           else
            BEGIN
             AdrMode=ModInd; AdrSize=0;
             AdrVals[1] = H32 & 0xff; 
             AdrVals[0] = (H32 >> 8) & 0xff;
             AdrCnt=2;
            END
           break;
          case 2:
           if (H32==0)
	    BEGIN
	     AdrMode=ModIReg; AdrSize=2;
            END
           else
            BEGIN
             AdrMode=ModInd; AdrSize=2;
             AdrVals[1] = H32 & 0xff; 
             AdrVals[0] = (H32 >> 8) & 0xff;
             AdrCnt=2;
            END
           break;
         END
      END
     else WrError(1350);
     if (PPos!=Nil) *PPos=Save;
     ChkMask(Mask,ExtMask); return;
    END

   FirstFlag=False;
   SegType=(-1); PPos=QuotPos(Asc,':');
   if (PPos!=Nil)
    if (MomCPU<CPU80251)
     BEGIN
      WrError(1350); return;
     END
    else
     BEGIN
      SplitString(Asc,Part,Asc,PPos);
      if (strcasecmp(Part,"S")==0) SegType=(-2);
      else
       BEGIN
        FirstPassUnknown=False;
        SegType=EvalIntExpression(Asc,UInt8,&OK);
        if (NOT OK) return;
        if (FirstPassUnknown) FirstFlag=True;
       END
     END

   FirstPassUnknown=False;
   switch (SegType)
    BEGIN
     case -2:
      H32=EvalIntExpression(Asc,UInt9,&OK);
      ChkSpace(SegIO);
      if (FirstPassUnknown) H32=(H32 & 0xff) | 0x80;
      break;
     case -1:
      H32=EvalIntExpression(Asc,UInt24,&OK);
     default:
      H32=EvalIntExpression(Asc,UInt16,&OK);
    END
   if (FirstPassUnknown) FirstFlag=True;

   if ((SegType==-2) OR ((SegType==-1) AND ((TypeFlag & (1 << SegIO))!=0)))
    BEGIN
     if (ChkRange(H32,0x80,0xff))
      BEGIN
       AdrMode=ModDir8; AdrVals[0]=H32 & 0xff; AdrCnt=1;
      END
    END

   else
    BEGIN
     if (SegType>=0) H32 += ((LongWord)SegType) << 16;
     if (FirstFlag)
      if ((MomCPU<CPU80251) OR ((Mask & ModDir16)==0)) H32 &= 0xff;
      else H32 &= 0xffff;
     if (((H32<128) OR ((H32<256) AND (MomCPU<CPU80251))) AND ((Mask & MModDir8)!=0))
      BEGIN
       if (MomCPU<CPU80251) ChkSpace(SegData);
       AdrMode=ModDir8; AdrVals[0]=H32 &0xff; AdrCnt=1;
      END
     else if ((MomCPU<CPU80251) OR (H32>0xffff)) WrError(1925);
     else
      BEGIN
       AdrMode=ModDir16; AdrCnt=2;
       AdrVals[1] = H32 & 0xff; 
       AdrVals[0] = (H32 >> 8) & 0xff;
      END
    END

   ChkMask(Mask,ExtMask);
END

	static ShortInt DecodeBitAdr(char *Asc, LongInt *Erg, Boolean MayShorten)
BEGIN
   Boolean OK;
   char *PPos,Save;

   if (MomCPU<CPU80251)
    BEGIN
     *Erg=EvalIntExpression(Asc,UInt8,&OK);
     if (OK)
      BEGIN
       ChkSpace(SegBData);
       return ModBit51;
      END
     else return ModNone;
    END
   else
    BEGIN
     PPos=RQuotPos(Asc,'.');
     if (PPos==Nil)
      BEGIN
       FirstPassUnknown=False;
       *Erg=EvalIntExpression(Asc,Int32,&OK);
       if (FirstPassUnknown) (*Erg)&=0x070000ff;
#ifdef __STDC__
       if (((*Erg)&0xf8ffff00u)!=0)
#else
       if (((*Erg)&0xf8ffff00)!=0)
#endif
        BEGIN
	 WrError(1510); OK=False;
        END
      END
     else
      BEGIN
       Save=(*PPos); *PPos='\0'; DecodeAdr(Asc,MModDir8); *PPos=Save;
       if (AdrMode==ModNone) OK=False;
       else
        BEGIN
         *Erg=EvalIntExpression(PPos+1,UInt3,&OK)<<24;
         if (OK) (*Erg)+=AdrVals[0];
        END
      END
     if (NOT OK) return ModNone;
     else if (MayShorten)
      if (((*Erg)&0x87)==0x80)
       BEGIN
        *Erg=((*Erg)&0xf8)+((*Erg)>>24); return ModBit51;
       END
      else if (((*Erg)&0xf0)==0x20)
       BEGIN
        *Erg=(((*Erg)&0x0f)<<3)+((*Erg)>>24); return ModBit51;
       END
      else return ModBit251;
     else return ModBit251;
    END
END

        static Boolean Chk504(LongInt Adr)
BEGIN
   return ((MomCPU==CPU80504) AND ((Adr & 0x7ff)==0x7fe));
END

	static Boolean NeedsPrefix(Word Opcode)
BEGIN
   return (((Opcode&0x0f)>=6) AND ((SrcMode!=0)!=((Hi(Opcode)!=0)!=0)));
END

	static void PutCode(Word Opcode)
BEGIN
   if (((Opcode&0x0f)<6) OR ((SrcMode!=0)!=((Hi(Opcode)==0)!=0)))
    BEGIN
     BAsmCode[0]=Lo(Opcode); CodeLen=1;
    END
   else
    BEGIN
     BAsmCode[0]=0xa5; BAsmCode[1]=Lo(Opcode); CodeLen=2;
    END
END

/*-------------------------------------------------------------------------*/
/* Einzelfaelle */

        static void DecodeMOV(Word Index)
BEGIN
   LongInt AdrLong;
   Byte HSize,HReg;
   Integer AdrInt;

   if (ArgCnt!=2) WrError(1110);
   else if ((strcasecmp(ArgStr[1],"C")==0) OR (strcasecmp(ArgStr[1],"CY")==0))
    BEGIN
     switch (DecodeBitAdr(ArgStr[2],&AdrLong,True))
      BEGIN
       case ModBit51:
        PutCode(0xa2);
        BAsmCode[CodeLen] = AdrLong & 0xff;
        CodeLen++;
        break;
       case ModBit251:
        PutCode(0x1a9);
        BAsmCode[CodeLen  ] = 0xa0 +(AdrLong >> 24);
        BAsmCode[CodeLen+1] = AdrLong & 0xff;
        CodeLen+=2;
        break;
      END
    END
   else if ((strcasecmp(ArgStr[2],"C")==0) OR (strcasecmp(ArgStr[2],"CY")==0))
    BEGIN
     switch (DecodeBitAdr(ArgStr[1],&AdrLong,True))
      BEGIN
       case ModBit51:
        PutCode(0x92);
        BAsmCode[CodeLen] = AdrLong & 0xff;
        CodeLen++;
        break;
       case ModBit251:
        PutCode(0x1a9);
        BAsmCode[CodeLen  ] = 0x90 + (AdrLong >> 24);
        BAsmCode[CodeLen+1] = AdrLong & 0xff;
        CodeLen+=2;
        break;
      END
    END
   else if (strcasecmp(ArgStr[1],"DPTR")==0)
    BEGIN
     SetOpSize(1); DecodeAdr(ArgStr[2],MModImm);
     switch (AdrMode)
      BEGIN
       case ModImm:
        PutCode(0x90);
        memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
        CodeLen+=AdrCnt;
        break;
      END
    END
   else
    BEGIN
     DecodeAdr(ArgStr[1],MModAcc+MModReg+MModIReg8+MModIReg+MModInd+MModDir8+MModDir16);
     switch (AdrMode)
      BEGIN
       case ModAcc:
        DecodeAdr(ArgStr[2],MModReg+MModIReg8+MModIReg+MModInd+MModDir8+MModDir16+MModImm);
        switch (AdrMode)
         BEGIN
          case ModReg:
           if ((AdrPart<8) AND (NOT SrcMode)) PutCode(0xe8+AdrPart);
           else if (MomCPU<CPU80251) WrError(1505);
           else
            BEGIN
             PutCode(0x17c);
             BAsmCode[CodeLen++] = (AccReg << 4) + AdrPart;
            END
           break;
          case ModIReg8:
           PutCode(0xe6+AdrPart);
           break;
          case ModIReg:
           PutCode(0x17e);
           BAsmCode[CodeLen++] = (AdrPart << 4) + 0x09 + AdrSize;
           BAsmCode[CodeLen++] = (AccReg << 4);
           break;
          case ModInd:
           PutCode(0x109+(AdrSize << 4));
           BAsmCode[CodeLen++] = (AccReg << 4) + AdrPart;
           memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
           CodeLen+=AdrCnt;
           break;
          case ModDir8:
           PutCode(0xe5);
           BAsmCode[CodeLen++] = AdrVals[0];
           break;
          case ModDir16:
           PutCode(0x17e);
           BAsmCode[CodeLen++] = (AccReg << 4) + 0x03;
           memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
           CodeLen+=AdrCnt;
           break;
          case ModImm:
           PutCode(0x74);
           BAsmCode[CodeLen++]=AdrVals[0];
           break;
         END
        break;
       case ModReg:
        HReg=AdrPart;
        DecodeAdr(ArgStr[2],MModReg+MModIReg8+MModIReg+MModInd+MModDir8+MModDir16+MModImm+MModImmEx);
        switch (AdrMode)
         BEGIN
          case ModReg:
           if ((OpSize==0) AND (AdrPart==AccReg) AND (HReg<8)) PutCode(0xf8+HReg);
           else if ((OpSize==0) AND (HReg==AccReg) AND (AdrPart<8)) PutCode(0xe8+AdrPart);
           else if (MomCPU<CPU80251) WrError(1505);
           else             
            BEGIN
             PutCode(0x17c+OpSize); 
             if (OpSize==2) BAsmCode[CodeLen-1]++;
             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
            END
           break;
          case ModIReg8:
           if ((OpSize!=0) OR (HReg!=AccReg)) WrError(1350);
           else PutCode(0xe6+AdrPart);
           break;
          case ModIReg:
           if (OpSize==0)
            BEGIN
             PutCode(0x17e);
             BAsmCode[CodeLen++] = (AdrPart << 4) + 0x09 + AdrSize;
             BAsmCode[CodeLen++] = HReg << 4;
            END
           else if (OpSize==1)
            BEGIN
             PutCode(0x10b);
             BAsmCode[CodeLen++] = (AdrPart << 4) + 0x08 + AdrSize;
             BAsmCode[CodeLen++] = HReg << 4;
            END
           else WrError(1350);
           break;
          case ModInd:
           if (OpSize==2) WrError(1350);
           else
            BEGIN
             PutCode(0x109+(AdrSize << 4)+(OpSize << 6));
             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
             memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
             CodeLen+=AdrCnt;
            END
           break;
          case ModDir8:
           if ((OpSize==0) AND (HReg==AccReg))
            BEGIN
             PutCode(0xe5);
             BAsmCode[CodeLen++] = AdrVals[0];
            END
           else if ((OpSize==0) AND (HReg<8) AND (NOT SrcMode))
            BEGIN
             PutCode(0xa8+HReg);
             BAsmCode[CodeLen++] = AdrVals[0];
            END
           else if (MomCPU<CPU80251) WrError(1505);
           else
            BEGIN
             PutCode(0x17e);
             BAsmCode[CodeLen++] = 0x01 + (HReg << 4) + (OpSize << 2);
             if (OpSize==2) BAsmCode[CodeLen-1]+=4;
             BAsmCode[CodeLen++] = AdrVals[0];
            END
           break;
          case ModDir16: 
           PutCode(0x17e);
           BAsmCode[CodeLen++] = 0x03 + (HReg << 4) + (OpSize << 2);
           if (OpSize==2) BAsmCode[CodeLen-1]+=4;
           memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
           CodeLen+=AdrCnt;
           break;
          case ModImm:
           if ((OpSize==0) AND (HReg==AccReg))
            BEGIN
             PutCode(0x74);
             BAsmCode[CodeLen++] = AdrVals[0];
            END
           else if ((OpSize==0) AND (HReg<8) AND (NOT SrcMode))
            BEGIN
             PutCode(0x78+HReg);
             BAsmCode[CodeLen++] = AdrVals[0];
            END
           else if (MomCPU<CPU80251) WrError(1505);
           else
            BEGIN
             PutCode(0x17e);
             BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2);
             memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
             CodeLen+=AdrCnt;
            END
           break;
          case ModImmEx:
           PutCode(0x17e);
           BAsmCode[CodeLen++]=0x0c + (HReg << 4);
           memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
           CodeLen+=AdrCnt;
           break;
         END
        break;
       case ModIReg8:
        SetOpSize(0); HReg=AdrPart;
        DecodeAdr(ArgStr[2],MModAcc+MModDir8+MModImm);
        switch (AdrMode)
         BEGIN
          case ModAcc:
           PutCode(0xf6+HReg);
           break;
          case ModDir8:
           PutCode(0xa6+HReg);
           BAsmCode[CodeLen++]=AdrVals[0];
           break;
          case ModImm:
           PutCode(0x76+HReg);
           BAsmCode[CodeLen++]=AdrVals[0];
           break;
         END
        break;
       case ModIReg:
        HReg=AdrPart; HSize=AdrSize;
        DecodeAdr(ArgStr[2],MModReg);
        switch (AdrMode)
         BEGIN
          case ModReg:
           if (OpSize==0)
            BEGIN
             PutCode(0x17a);
             BAsmCode[CodeLen++] = (HReg << 4) + 0x09 + HSize;
             BAsmCode[CodeLen++] = AdrPart << 4;
            END
           else if (OpSize==1)
            BEGIN
             PutCode(0x11b);
             BAsmCode[CodeLen++] = (HReg << 4) + 0x08 + HSize;
             BAsmCode[CodeLen++] = AdrPart << 4;
            END
           else WrError(1350);
         END
        break;
       case ModInd:
        HReg=AdrPart; HSize=AdrSize;
        AdrInt=(((Word)AdrVals[0])<<8)+AdrVals[1];
        DecodeAdr(ArgStr[2],MModReg);
        switch (AdrMode)
         BEGIN
          case ModReg:
           if (OpSize==2) WrError(1350);
           else
            BEGIN
             PutCode(0x119 + (HSize << 4) + (OpSize << 6));
             BAsmCode[CodeLen++] = (AdrPart << 4) + HReg;
             BAsmCode[CodeLen++] = Hi(AdrInt);
             BAsmCode[CodeLen++] = Lo(AdrInt);
            END
         END
        break;
       case ModDir8:
        MinOneIs0=True; HReg=AdrVals[0];
        DecodeAdr(ArgStr[2],MModReg+MModIReg8+MModDir8+MModImm);
        switch (AdrMode)
         BEGIN
          case ModReg:
           if ((OpSize==0) AND (AdrPart==AccReg))
            BEGIN
             PutCode(0xf5);
             BAsmCode[CodeLen++] = HReg;
            END
           else if ((OpSize==0) AND (AdrPart<8) AND (NOT SrcMode))
            BEGIN
             PutCode(0x88+AdrPart);
             BAsmCode[CodeLen++] = HReg;
            END
           else if (MomCPU<CPU80251) WrError(1505);
           else
            BEGIN
             PutCode(0x17a);
             BAsmCode[CodeLen++] = 0x01 + (AdrPart << 4) + (OpSize << 2);
             if (OpSize==2) BAsmCode[CodeLen-1]+=4;
             BAsmCode[CodeLen++] = HReg;
            END
           break;
          case ModIReg8:
           PutCode(0x86+AdrPart);
           BAsmCode[CodeLen++] = HReg;
           break;
          case ModDir8:
           PutCode(0x85);
           BAsmCode[CodeLen++] = AdrVals[0];
           BAsmCode[CodeLen++] = HReg;
           break;
          case ModImm:
           PutCode(0x75);
           BAsmCode[CodeLen++] = HReg;
           BAsmCode[CodeLen++] = AdrVals[0];
           break;
         END
        break;
       case ModDir16:
        AdrInt=(((Word)AdrVals[0]) << 8) + AdrVals[1];
        DecodeAdr(ArgStr[2],MModReg);
        switch (AdrMode)
         BEGIN
          case ModReg:
           PutCode(0x17a);
           BAsmCode[CodeLen++]=0x03 + (AdrPart << 4) + (OpSize << 2);
           if (OpSize==2) BAsmCode[CodeLen-1]+=4;
           BAsmCode[CodeLen++] = Hi(AdrInt);
           BAsmCode[CodeLen++] = Lo(AdrInt);
           break;
         END
        break;
      END
    END
END

	static void DecodeLogic(Word Index)
BEGIN
   Boolean InvFlag;
   Byte HReg;
   LongInt AdrLong;
   int z;

   /* Index: ORL=0 ANL=1 XRL=2 */

   if (ArgCnt!=2) WrError(1110);
   else if ((strcasecmp(ArgStr[1],"C")==0) OR (strcasecmp(ArgStr[1],"CY")==0))
    BEGIN
     if (Index==2) WrError(1350);
     else
      BEGIN
       HReg=Index << 4;
       InvFlag=(*ArgStr[2]=='/');
       if (InvFlag) strcpy(ArgStr[2],ArgStr[2]+1);
       switch (DecodeBitAdr(ArgStr[2],&AdrLong,True))
        BEGIN
         case ModBit51:
          PutCode((InvFlag) ? 0xa0+HReg : 0x72+HReg);
          BAsmCode[CodeLen++] = AdrLong & 0xff;
          break;
         case ModBit251:
          PutCode(0x1a9);
          BAsmCode[CodeLen++] = ((InvFlag) ? 0xe0 : 0x70) + HReg + (AdrLong >>24);
          BAsmCode[CodeLen++] = AdrLong & 0xff;
          break;
        END
      END
    END
   else
    BEGIN
     z=(Index << 4)+0x40;
     DecodeAdr(ArgStr[1],MModAcc+MModReg+MModDir8);
     switch (AdrMode)
      BEGIN
       case ModAcc:
        DecodeAdr(ArgStr[2],MModReg+MModIReg8+MModIReg+MModDir8+MModDir16+MModImm);
        switch (AdrMode)
         BEGIN
          case ModReg:
           if ((AdrPart<8) AND (NOT SrcMode)) PutCode(z+8+AdrPart);
           else
            BEGIN
             PutCode(z+0x10c);
             BAsmCode[CodeLen++] = AdrPart + (AccReg << 4);
            END
           break;
          case ModIReg8:
           PutCode(z+6+AdrPart);
           break;
          case ModIReg:
           PutCode(z+0x10e);
           BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4);
           BAsmCode[CodeLen++] = AccReg << 4;
           break;
          case ModDir8:
           PutCode(z+0x05);
           BAsmCode[CodeLen++] = AdrVals[0];
           break;
          case ModDir16:
           PutCode(0x10e + z);
           BAsmCode[CodeLen++] = 0x03 + (AccReg << 4);
           memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
           CodeLen+=AdrCnt;
           break;
          case ModImm:
           PutCode(z+0x04);
           BAsmCode[CodeLen++] = AdrVals[0];
           break;
         END
        break;
       case ModReg:
        if (MomCPU<CPU80251) WrError(1350);
        else
         BEGIN
          HReg=AdrPart;
          DecodeAdr(ArgStr[2],MModReg+MModIReg8+MModIReg+MModDir8+MModDir16+MModImm);
          switch (AdrMode)
           BEGIN
            case ModReg:
             if (OpSize==2) WrError(1350);
             else
              BEGIN
               PutCode(z+0x10c+OpSize);
               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
              END
             break;
            case ModIReg8:
             if ((OpSize!=0) OR (HReg!=AccReg)) WrError(1350);
             else PutCode(z+0x06+AdrPart);
             break;
            case ModIReg:
             if (OpSize!=0) WrError(1350);
             else
              BEGIN
               PutCode(0x10e + z);
               BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4);
               BAsmCode[CodeLen++] = HReg << 4;
              END
             break;
            case ModDir8:
             if ((OpSize==0) AND (HReg==AccReg))
              BEGIN
               PutCode(0x05+z);
               BAsmCode[CodeLen++] = AdrVals[0];
              END
             else if (OpSize==2) WrError(1350);
             else
              BEGIN
               PutCode(0x10e + z);
               BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 1;
               BAsmCode[CodeLen++] = AdrVals[0];
              END
             break;
            case ModDir16:
             if (OpSize==2) WrError(1350);
             else
              BEGIN
               PutCode(0x10e + z);
               BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 3;
               memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
               CodeLen+=AdrCnt;
              END
             break;
            case ModImm:
             if ((OpSize==0) AND (HReg==AccReg))
              BEGIN
               PutCode(0x04+z);
               BAsmCode[CodeLen++] = AdrVals[0];
              END
             else if (OpSize==2) WrError(1350);
             else
              BEGIN
               PutCode(0x10e + z);
               BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2);
               memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
               CodeLen+=AdrCnt;
              END
             break;
           END
         END
        break;
       case ModDir8:
        HReg=AdrVals[0]; SetOpSize(0);
        DecodeAdr(ArgStr[2],MModAcc+MModImm);
        switch (AdrMode)
         BEGIN
          case ModAcc:
           PutCode(z+0x02);
           BAsmCode[CodeLen++] = HReg;
           break;
          case ModImm:
           PutCode(z+0x03);
           BAsmCode[CodeLen++] = HReg;
           BAsmCode[CodeLen++] = AdrVals[0];
           break;
         END
        break;
      END
    END
END

	static void DecodeMOVC(Word Index)
BEGIN
   if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],MModAcc);
     switch (AdrMode)
      BEGIN
       case ModAcc:
        if (strcasecmp(ArgStr[2],"@A+DPTR")==0) PutCode(0x93);
        else if (strcasecmp(ArgStr[2],"@A+PC")==0) PutCode(0x83);
        else WrError(1350);
        break;
      END
    END
END

	static void DecodeMOVH(Word Index)
BEGIN
   Byte HReg;

   if (ArgCnt!=2) WrError(1110);
   else if (MomCPU<CPU80251) WrError(1500);
   else
    BEGIN
     DecodeAdr(ArgStr[1],MModReg);
     switch (AdrMode)
      BEGIN
       case ModReg:
        if (OpSize!=2) WrError(1350);
        else
         BEGIN
          HReg=AdrPart; OpSize--;
          DecodeAdr(ArgStr[2],MModImm);
          switch (AdrMode)
           BEGIN
            case ModImm:
             PutCode(0x17a);
             BAsmCode[CodeLen++] = 0x0c + (HReg << 4);
             memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
             CodeLen+=AdrCnt;
             break;
           END
         END
        break;
      END
    END
END

	static void DecodeMOVZS(Word Index)
BEGIN
   Byte HReg;
   int z;

   z=Ord(Memo("MOVS")) << 4;
   if (ArgCnt!=2) WrError(1110);
   else if (MomCPU<CPU80251) WrError(1500);
   else
    BEGIN
     DecodeAdr(ArgStr[1],MModReg);
     switch (AdrMode)
      BEGIN
       case ModReg:
        if (OpSize!=1) WrError(1350);
        else
         BEGIN
          HReg=AdrPart; OpSize--;
          DecodeAdr(ArgStr[2],MModReg);
          switch (AdrMode)
           BEGIN
            case ModReg:
             PutCode(0x10a+z);
             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
             break;
           END
         END
        break;
      END
    END
   return;
END

	static void DecodeMOVX(Word Index)
BEGIN
   int z;

   if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     z=0;
     if ((strcasecmp(ArgStr[2],"A")==0) OR ((MomCPU>=CPU80251) AND (strcasecmp(ArgStr[2],"R11")==0)))
      BEGIN
       z=0x10; strcpy(ArgStr[2],ArgStr[1]); strmaxcpy(ArgStr[1],"A",255);
      END
     if ((strcasecmp(ArgStr[1],"A")!=0) AND ((MomCPU<CPU80251) OR (strcasecmp(ArgStr[2],"R11")==0))) WrError(1350);
     else if (strcasecmp(ArgStr[2],"@DPTR")==0) PutCode(0xe0+z);
     else
      BEGIN
       DecodeAdr(ArgStr[2],MModIReg8);
       switch (AdrMode)
        BEGIN
         case ModIReg8:
         PutCode(0xe2+AdrPart+z);
         break;
        END
      END
    END
END

	static void DecodeStack(Word Index)
BEGIN
   int z;

   /* Index: PUSH=0 POP=1 PUSHW=2 */

   z=(Index&1) << 4;
   if (ArgCnt!=1) WrError(1110);
   else
    BEGIN
     if (*ArgStr[1]=='#') SetOpSize(Ord(Index==2));
     if (z==0x10) DecodeAdr(ArgStr[1],MModDir8+MModReg);
     else DecodeAdr(ArgStr[1],MModDir8+MModReg+MModImm);
     switch (AdrMode)
      BEGIN
       case ModDir8:
        PutCode(0xc0+z);
        BAsmCode[CodeLen++] = AdrVals[0];
        break;
       case ModReg:
        if (MomCPU<CPU80251) WrError(1505);
        else
         BEGIN
          PutCode(0x1ca+z);
          BAsmCode[CodeLen++] = 0x08 + (AdrPart << 4) + OpSize + (Ord(OpSize == 2));
         END
        break;
       case ModImm:
        if (MomCPU<CPU80251) WrError(1505);
        else
         BEGIN
          PutCode(0x1ca);
          BAsmCode[CodeLen++] = 0x02 + (OpSize << 2);
          memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
          CodeLen+=AdrCnt;
         END
        break;
      END
    END
END

	static void DecodeXCH(Word Index)
BEGIN
   Byte HReg;

   if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],MModAcc+MModReg+MModIReg8+MModDir8);
     switch (AdrMode)
      BEGIN
       case ModAcc:
        DecodeAdr(ArgStr[2],MModReg+MModIReg8+MModDir8);
        switch (AdrMode)
         BEGIN
          case ModReg:
           if (AdrPart>7) WrError(1350);
           else PutCode(0xc8+AdrPart);
           break;
          case ModIReg8:
           PutCode(0xc6+AdrPart);
           break;
          case ModDir8:
           PutCode(0xc5);
           BAsmCode[CodeLen++] = AdrVals[0];
           break;
         END
        break;
       case ModReg:
        if ((OpSize!=0) OR (AdrPart>7)) WrError(1350);
        else
         BEGIN
          HReg=AdrPart;
          DecodeAdr(ArgStr[2],MModAcc);
          switch (AdrMode)
           BEGIN
            case ModAcc:
             PutCode(0xc8+HReg);
             break;
           END
         END
        break;
       case ModIReg8:
        HReg=AdrPart;
        DecodeAdr(ArgStr[2],MModAcc);
        switch (AdrMode)
         BEGIN
          case ModAcc:
           PutCode(0xc6+HReg);
           break;
         END
        break;
       case ModDir8:
        HReg=AdrVals[0];
        DecodeAdr(ArgStr[2],MModAcc);
        switch (AdrMode)
         BEGIN
          case ModAcc:
           PutCode(0xc5);
           BAsmCode[CodeLen++] = HReg;
           break;
         END
        break;
      END
    END
END

	static void DecodeXCHD(Word Index)
BEGIN
   Byte HReg;

   if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],MModAcc+MModIReg8);
     switch (AdrMode)
      BEGIN
       case ModAcc:
        DecodeAdr(ArgStr[2],MModIReg8);
        switch (AdrMode)
         BEGIN
          case ModIReg8:
           PutCode(0xd6+AdrPart);
           break;
         END
        break;
       case ModIReg8:
        HReg=AdrPart;
        DecodeAdr(ArgStr[2],MModAcc);
        switch (AdrMode)
         BEGIN
          case ModAcc:
           PutCode(0xd6+HReg);
           break;
         END
        break;
      END
    END
END

	static void DecodeABranch(Word Index)
BEGIN
   Boolean OK;
   LongInt AdrLong;

   /* Index: AJMP=0 ACALL=1 */

   if (ArgCnt!=1) WrError(1110);
   else
    BEGIN
     AdrLong=EvalIntExpression(ArgStr[1],Int24,&OK);
     if (OK)
      if ((NOT SymbolQuestionable) AND (((EProgCounter()+2) >> 11)!=(AdrLong >> 11))) WrError(1910);
      else if (Chk504(EProgCounter())) WrError(1900);
      else
       BEGIN
        ChkSpace(SegCode);
        PutCode(0x01 + (Index << 4) + ((Hi(AdrLong) & 7) << 5));
        BAsmCode[CodeLen++]=Lo(AdrLong);
       END
    END
END

	static void DecodeLBranch(Word Index)
BEGIN
   LongInt AdrLong;
   Boolean OK;

   /* Index: LJMP=0 LCALL=1 */

   if (ArgCnt!=1) WrError(1110);
   else if (MomCPU<CPU8051) WrError(1500);
   else if (*ArgStr[1]=='@')
    BEGIN
     DecodeAdr(ArgStr[1],MModIReg);
     switch (AdrMode)
      BEGIN
       case ModIReg:
        if (AdrSize!=0) WrError(1350);
        else
         BEGIN
          PutCode(0x189 + (Index << 4));
          BAsmCode[CodeLen++] = 0x04 + (AdrPart << 4);
         END
        break;
      END
    END
   else
    BEGIN
     AdrLong=EvalIntExpression(ArgStr[1],Int24,&OK);
     if (OK)
      if ((MomCPU>=CPU80251) AND (((EProgCounter()+3) >> 16)!=(AdrLong >> 16))) WrError(1910);
      else
       BEGIN
        ChkSpace(SegCode);
        PutCode(0x02 + (Index << 4));
        BAsmCode[CodeLen++] = (AdrLong >> 8) & 0xff;
        BAsmCode[CodeLen++] = AdrLong & 0xff;
       END
    END
END

        static void DecodeEBranch(Word Index)
BEGIN
   LongInt AdrLong;
   Boolean OK;

   /* Index: AJMP=0 ACALL=1 */

   if (ArgCnt!=1) WrError(1110);
   else if (MomCPU<CPU80251) WrError(1500);
   else if (*ArgStr[1]=='@')
    BEGIN
     DecodeAdr(ArgStr[1],MModIReg);
     switch (AdrMode)
      BEGIN
       case ModIReg:
        if (AdrSize!=2) WrError(1350);
        else
         BEGIN
          PutCode(0x189 + (Index << 4));
          BAsmCode[CodeLen++] = 0x08 + (AdrPart << 4);
         END
        break;
      END
    END
   else
    BEGIN
     AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
     if (OK)
      BEGIN
       ChkSpace(SegCode);
       PutCode(0x18a + (Index << 4));
       BAsmCode[CodeLen++] = (AdrLong >> 16) & 0xff;
       BAsmCode[CodeLen++] = (AdrLong >>  8) & 0xff;
       BAsmCode[CodeLen++] =  AdrLong        & 0xff;
      END
    END
END

	static void DecodeJMP(Word Index)
BEGIN
   LongInt AdrLong,Dist;
   Boolean OK;

   if (ArgCnt!=1) WrError(1110);
   else if (strcasecmp(ArgStr[1],"@A+DPTR")==0) PutCode(0x73);
   else if (*ArgStr[1]=='@')
    BEGIN
     DecodeAdr(ArgStr[1],MModIReg);
     switch (AdrMode)
      BEGIN
       case ModIReg:
        PutCode(0x189);
        BAsmCode[CodeLen++] = 0x04 + (AdrSize << 1) + (AdrPart << 4);
        break;
      END
    END
   else
    BEGIN
     AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
     if (OK)
      BEGIN
       Dist=AdrLong-(EProgCounter()+2);
       if ((Dist<=127) AND (Dist>=-128))
        BEGIN
         PutCode(0x80);
         BAsmCode[CodeLen++] = Dist & 0xff;
        END
       else if ((NOT Chk504(EProgCounter())) AND ((AdrLong >> 11)==((EProgCounter()+2) >> 11)))
        BEGIN
         PutCode(0x01 + ((Hi(AdrLong) & 7) << 5));
         BAsmCode[CodeLen++] = Lo(AdrLong);
        END
       else if (MomCPU<CPU8051) WrError(1910);
       else if (((EProgCounter()+3) >> 16)==(AdrLong >> 16))
        BEGIN
         PutCode(0x02);
         BAsmCode[CodeLen++] = Hi(AdrLong); 
         BAsmCode[CodeLen++] = Lo(AdrLong);
        END
       else if (MomCPU<CPU80251) WrError(1910);
       else
        BEGIN
         PutCode(0x18a);
         BAsmCode[CodeLen++] =(AdrLong >> 16) & 0xff;
         BAsmCode[CodeLen++] =(AdrLong >>  8) & 0xff;
         BAsmCode[CodeLen++] = AdrLong        & 0xff;
        END
      END
    END
END

	static void DecodeCALL(Word Index)
BEGIN
   LongInt AdrLong;
   Boolean OK;

     if (ArgCnt!=1) WrError(1110);
     else if (*ArgStr[1]=='@')
      BEGIN
       DecodeAdr(ArgStr[1],MModIReg);
       switch (AdrMode)
        BEGIN
         case ModIReg:
          PutCode(0x199);
          BAsmCode[CodeLen++] = 0x04 + (AdrSize << 1) + (AdrPart << 4);
          break;
        END
      END
     else
      BEGIN
       AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
       if (OK)
	BEGIN
	 if ((NOT Chk504(EProgCounter())) AND ((AdrLong >> 11)==((EProgCounter()+2) >> 11)))
	  BEGIN
	   PutCode(0x11 + ((Hi(AdrLong) & 7) << 5));
	   BAsmCode[CodeLen++] = Lo(AdrLong);
	  END
         else if (MomCPU<CPU8051) WrError(1910);
         else if ((AdrLong >> 16)!=((EProgCounter()+3) >> 16)) WrError(1910);
         else
	  BEGIN
	   PutCode(0x12);
	   BAsmCode[CodeLen++] = Hi(AdrLong);
	   BAsmCode[CodeLen++] = Lo(AdrLong);
	  END
	END
      END
END

	static void DecodeDJNZ(Word Index)
BEGIN
   LongInt AdrLong;
   Boolean OK,Questionable;

   if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     AdrLong=EvalIntExpression(ArgStr[2],UInt24,&OK); 
     Questionable=SymbolQuestionable;
     if (OK)
      BEGIN
       DecodeAdr(ArgStr[1],MModReg+MModDir8);
       switch (AdrMode)
        BEGIN
         case ModReg:
          if ((OpSize!=0) OR (AdrPart>7)) WrError(1350);
          else
           BEGIN
            AdrLong-=EProgCounter()+2+Ord(NeedsPrefix(0xd8+AdrPart));
            if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370);
            else
             BEGIN
              PutCode(0xd8+AdrPart);
              BAsmCode[CodeLen++] = AdrLong & 0xff;
             END
           END
          break;
         case ModDir8:
          AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(0xd5));
          if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370);
          else
           BEGIN
            PutCode(0xd5);
            BAsmCode[CodeLen++] = AdrVals[0];
            BAsmCode[CodeLen++] = Lo(AdrLong);
           END
          break;
        END
      END
    END
END

	static void DecodeCJNE(Word Index)
BEGIN
   LongInt AdrLong;
   Boolean OK,Questionable;
   Byte HReg;

   if (ArgCnt!=3) WrError(1110);
   else
    BEGIN
     AdrLong=EvalIntExpression(ArgStr[3],UInt24,&OK);
     Questionable=SymbolQuestionable;
     if (OK)
      BEGIN
       DecodeAdr(ArgStr[1],MModAcc+MModIReg8+MModReg);
       switch (AdrMode)
        BEGIN
         case ModAcc:
          DecodeAdr(ArgStr[2],MModDir8+MModImm);
          switch (AdrMode)
           BEGIN
            case ModDir8:
             AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(0xb5));
             if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370);
             else
              BEGIN
               PutCode(0xb5);
               BAsmCode[CodeLen++] = AdrVals[0];
               BAsmCode[CodeLen++] = AdrLong & 0xff;
              END
             break;
            case ModImm:
             AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(0xb5));
             if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370);
             else
              BEGIN
               PutCode(0xb4);
               BAsmCode[CodeLen++] = AdrVals[0];
               BAsmCode[CodeLen++] = AdrLong & 0xff;
              END
             break;
           END
          break;
         case ModReg:
          if ((OpSize!=0) OR (AdrPart>7)) WrError(1350);
          else
           BEGIN
            HReg=AdrPart;
            DecodeAdr(ArgStr[2],MModImm);
            switch (AdrMode)
             BEGIN
              case ModImm:
               AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(0xb8+HReg));
               if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370);
               else
                BEGIN
                 PutCode(0xb8+HReg);
                 BAsmCode[CodeLen++] = AdrVals[0];
                 BAsmCode[CodeLen++] = AdrLong & 0xff;
                END
               break;
             END
           END
          break;
         case ModIReg8:
          HReg=AdrPart; SetOpSize(0);
          DecodeAdr(ArgStr[2],MModImm);
          switch (AdrMode)
           BEGIN
            case ModImm:
             AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(0xb6+HReg));
             if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370);
             else
              BEGIN
               PutCode(0xb6+HReg);
               BAsmCode[CodeLen++] = AdrVals[0];
               BAsmCode[CodeLen++] = AdrLong & 0xff;
              END
             break;
           END
          break;
        END
      END
    END
END

	static void DecodeADD(Word Index)
BEGIN
   Byte HReg;

   if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],MModAcc+MModReg);
     switch (AdrMode)
      BEGIN
       case ModAcc:
        DecodeAdr(ArgStr[2],MModImm+MModDir8+MModDir16+MModIReg8+MModIReg+MModReg);
        switch (AdrMode)
         BEGIN
          case ModImm:
           PutCode(0x24); BAsmCode[CodeLen++] = AdrVals[0];
           break;
          case ModDir8:
           PutCode(0x25); BAsmCode[CodeLen++] = AdrVals[0];
           break;
          case ModDir16:
           PutCode(0x12e);
           BAsmCode[CodeLen++] = (AccReg << 4) + 3;
           memcpy(BAsmCode+CodeLen,AdrVals,2);
           CodeLen+=2;
           break;
          case ModIReg8:
           PutCode(0x26+AdrPart);
           break;
          case ModIReg:
           PutCode(0x12e);
           BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4);
           BAsmCode[CodeLen++] = AccReg << 4;
           break;
          case ModReg:
           if ((AdrPart<8) AND (NOT SrcMode)) PutCode(0x28+AdrPart);
           else if (MomCPU<CPU80251) WrError(1505);
           else
            BEGIN
             PutCode(0x12c);
             BAsmCode[CodeLen++] = AdrPart + (AccReg << 4);
            END;
           break;
         END
        break;
       case ModReg:
        if (MomCPU<CPU80251) WrError(1505);
        else
         BEGIN
          HReg=AdrPart;
          DecodeAdr(ArgStr[2],MModImm+MModReg+MModDir8+MModDir16+MModIReg8+MModIReg);
          switch (AdrMode)
           BEGIN
            case ModImm:
             if ((OpSize==0) AND (HReg==AccReg))
              BEGIN
               PutCode(0x24);
               BAsmCode[CodeLen++] = AdrVals[0];
              END
             else
              BEGIN
               PutCode(0x12e);
               BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2);
               memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
               CodeLen+=AdrCnt;
              END
             break;
            case ModReg:
             PutCode(0x12c+OpSize); 
             if (OpSize==2) BAsmCode[CodeLen-1]++;
             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
             break;
            case ModDir8:
             if (OpSize==2) WrError(1350);
             else if ((OpSize==0) AND (HReg==AccReg))
              BEGIN
               PutCode(0x25);
               BAsmCode[CodeLen++] = AdrVals[0];
              END
             else
              BEGIN
               PutCode(0x12e);
               BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 1;
               BAsmCode[CodeLen++] = AdrVals[0];
              END
             break;
            case ModDir16:
             if (OpSize==2) WrError(1350);
             else
              BEGIN
               PutCode(0x12e);
               BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 3;
               memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
               CodeLen+=AdrCnt;
              END
             break;
            case ModIReg8:
             if ((OpSize!=0) OR (HReg!=AccReg)) WrError(1350);
             else PutCode(0x26+AdrPart);
             break;
            case ModIReg:
             if (OpSize!=0) WrError(1350);
             else
              BEGIN
               PutCode(0x12e);
               BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4);
               BAsmCode[CodeLen++] = HReg << 4;
              END
             break;
           END
         END
        break;
      END
    END
END

	static void DecodeSUBCMP(Word Index)
BEGIN
   int z;
   Byte HReg;

   /* Index: SUB=0 CMP=1 */

   z=0x90+(Index<<5);
   if (ArgCnt!=2) WrError(1110);
   else if (MomCPU<CPU80251) WrError(1500);
   else
    BEGIN
     DecodeAdr(ArgStr[1],MModReg);
     switch (AdrMode)
      BEGIN
       case ModReg:
        HReg=AdrPart;
        if (Memo("CMP"))
        DecodeAdr(ArgStr[2],MModImm+MModImmEx+MModReg+MModDir8+MModDir16+MModIReg);
        else
         DecodeAdr(ArgStr[2],MModImm+MModReg+MModDir8+MModDir16+MModIReg);
        switch (AdrMode)
         BEGIN
          case ModImm:
           PutCode(0x10e + z);
           BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2);
           memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
           CodeLen+=AdrCnt;
           break;
          case ModImmEx:
           PutCode(0x10e + z);
           BAsmCode[CodeLen++] = (HReg << 4) + 0x0c;
           memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
           CodeLen+=AdrCnt;
           break;
          case ModReg:
           PutCode(0x10c + z + OpSize);
           if (OpSize==2) BAsmCode[CodeLen-1]++;
           BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
           break;
          case ModDir8:
           if (OpSize==2) WrError(1350);
           else
            BEGIN
             PutCode(0x10e + z);
             BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 1;
             BAsmCode[CodeLen++] = AdrVals[0];
            END
           break;
          case ModDir16:
           if (OpSize==2) WrError(1350);
           else
            BEGIN
             PutCode(0x10e + z);
             BAsmCode[CodeLen++] = (HReg << 4) + (OpSize << 2) + 3;
             memcpy(BAsmCode+CodeLen,AdrVals,AdrCnt);
             CodeLen+=AdrCnt;
            END
           break;
          case ModIReg:
           if (OpSize!=0) WrError(1350);
           else
            BEGIN
             PutCode(0x10e + z);
             BAsmCode[CodeLen++] = 0x09 + AdrSize + (AdrPart << 4);
             BAsmCode[CodeLen++] = HReg << 4;
            END
           break;
         END
        break;
      END
    END
END

	static void DecodeADDCSUBB(Word Index)
BEGIN
   Byte HReg;

   /* Index: ADDC=0 SUBB=1 */

   if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     DecodeAdr(ArgStr[1],MModAcc);
     switch (AdrMode)
      BEGIN
       case ModAcc:
        HReg=0x30+(Index*0x60);
        DecodeAdr(ArgStr[2],MModReg+MModIReg8+MModDir8+MModImm);
        switch (AdrMode)
         BEGIN
          case ModReg:
           if (AdrPart>7) WrError(1350);
           else PutCode(HReg+0x08+AdrPart);
           break;
          case ModIReg8:
           PutCode(HReg+0x06+AdrPart);
           break;
          case ModDir8:
           PutCode(HReg+0x05);
           BAsmCode[CodeLen++] = AdrVals[0];
           break;
          case ModImm:
           PutCode(HReg+0x04);
           BAsmCode[CodeLen++] = AdrVals[0];
           break;
         END
        break;
      END
    END
END

	static void DecodeINCDEC(Word Index)
BEGIN
   Byte HReg;
   int z;
   Boolean OK;

   /* Index: INC=0 DEC=1 */

   if (ArgCnt==1) strmaxcpy(ArgStr[++ArgCnt],"#1",255);
   z=Index << 4;
   if (ArgCnt!=2) WrError(1110);
   else if (*ArgStr[2]!='#') WrError(1350);
   else
    BEGIN
     FirstPassUnknown=False;
     HReg=EvalIntExpression(ArgStr[2]+1,UInt3,&OK);
     if (FirstPassUnknown) HReg=1;
     if (OK)
      BEGIN
       OK=True;
       if (HReg==1) HReg=0;
       else if (HReg==2) HReg=1;
       else if (HReg==4) HReg=2;
       else OK=False;
       if (NOT OK) WrError(1320);
       else if (strcasecmp(ArgStr[1],"DPTR")==0)
        BEGIN
         if (Index==1) WrError(1350);
         else if (HReg!=0) WrError(1320);
         else PutCode(0xa3);
        END
       else
        BEGIN
         DecodeAdr(ArgStr[1],MModAcc+MModReg+MModDir8+MModIReg8);
         switch (AdrMode)
          BEGIN
           case ModAcc:
            if (HReg==0) PutCode(0x04+z);
            else if (MomCPU<CPU80251) WrError(1320);
            else
             BEGIN
              PutCode(0x10b+z);
              BAsmCode[CodeLen++] = (AccReg << 4) + HReg;
             END
            break;
           case ModReg:
            if ((OpSize==0) AND (AdrPart==AccReg) AND (HReg==0)) PutCode(0x04+z);
            else if ((AdrPart<8) AND (OpSize==0) AND (HReg==0) AND (NOT SrcMode)) PutCode(0x08+z+AdrPart);
            else if (MomCPU<CPU80251) WrError(1505);
            else
             BEGIN
              PutCode(0x10b+z);
              BAsmCode[CodeLen++] = (AdrPart << 4) + (OpSize << 2) + HReg;
              if (OpSize==2) BAsmCode[CodeLen-1]+=4;
             END
            break;
           case ModDir8:
            if (HReg!=0) WrError(1320);
            else
             BEGIN
              PutCode(0x05+z);
              BAsmCode[CodeLen++] = AdrVals[0];
             END
            break;
           case ModIReg8:
            if (HReg!=0) WrError(1320);
            else PutCode(0x06+z+AdrPart);
            break;
          END
        END
      END
    END
END

	static void DecodeMULDIV(Word Index)
BEGIN
   int z;
   Byte HReg;

   /* Index: DIV=0 MUL=1 */

   z=Index << 5;
   if ((ArgCnt<1) OR (ArgCnt>2)) WrError(1110);
   else if (ArgCnt==1) 
    BEGIN
     if (strcasecmp(ArgStr[1],"AB")!=0) WrError(1350);
     else PutCode(0x84+z);
    END
   else
    BEGIN
     DecodeAdr(ArgStr[1],MModReg);
     switch (AdrMode)
      BEGIN
       case ModReg:
        HReg=AdrPart;
        DecodeAdr(ArgStr[2],MModReg);
        switch (AdrMode)
         BEGIN
          case ModReg:
           if (MomCPU<CPU80251) WrError(1505);
           else if (OpSize==2) WrError(1350);
           else
            BEGIN
             PutCode(0x18c+z+OpSize);
             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
            END
           break;
         END
        break;
      END
    END
END

	static void DecodeBits(Word Index)
BEGIN
   LongInt AdrLong;
   int z;

   /* Index: CPL=0 CLR=1 SETB=2 */

   z=Index<<4;
   if (ArgCnt!=1) WrError(1110);
   else if (strcasecmp(ArgStr[1],"A")==0)
    BEGIN
     if (Memo("SETB")) WrError(1350);
     else PutCode(0xf4-z);
    END
   else if ((strcasecmp(ArgStr[1],"C")==0) OR (strcasecmp(ArgStr[1],"CY")==0))
    PutCode(0xb3+z);
   else 
    switch (DecodeBitAdr(ArgStr[1],&AdrLong,True))
     BEGIN
      case ModBit51:
       PutCode(0xb2+z);
       BAsmCode[CodeLen++] = AdrLong & 0xff;
       break;
      case ModBit251:
       PutCode(0x1a9);
       BAsmCode[CodeLen++] = 0xb0 + z + (AdrLong >> 24);
       BAsmCode[CodeLen++] = AdrLong & 0xff;
       break;
     END
END

	static void DecodeShift(Word Index)
BEGIN
   int z;

   /* Index: SRA=0 SRL=1 SLL=3 */

   if (ArgCnt!=1) WrError(1110);
   else if (MomCPU<CPU80251) WrError(1500);
   else
    BEGIN
     z=Index<<4;
     DecodeAdr(ArgStr[1],MModReg);
     switch (AdrMode)
      BEGIN
       case ModReg:
        if (OpSize==2) WrError(1350);
        else
         BEGIN
          PutCode(0x10e + z);
          BAsmCode[CodeLen++] = (AdrPart << 4) + (OpSize << 2);
         END
        break;
      END
    END
END

	static void DecodeCond(Word Index)
BEGIN
   FixedOrder *FixedZ=CondOrders+Index;
   LongInt AdrLong;
   Boolean OK;

   if (ArgCnt!=1) WrError(1110);
   else if (MomCPU<FixedZ->MinCPU) WrError(1500);
   else
    BEGIN
     AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK);
     if (OK)
      BEGIN
       AdrLong-=EProgCounter()+2+Ord(NeedsPrefix(FixedZ->Code));
       if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT SymbolQuestionable)) WrError(1370);
       else
        BEGIN
         ChkSpace(SegCode);
         PutCode(FixedZ->Code);
         BAsmCode[CodeLen++] = AdrLong & 0xff;
        END
      END
    END
END

        static void DecodeBCond(Word Index)
BEGIN
   FixedOrder *FixedZ=BCondOrders+Index;
   LongInt AdrLong,BitLong;
   Boolean OK,Questionable;

   if (ArgCnt!=2) WrError(1110);
   else
    BEGIN
     AdrLong=EvalIntExpression(ArgStr[2],UInt24,&OK);
     Questionable=SymbolQuestionable;
     if (OK)
      BEGIN
       ChkSpace(SegCode);
       switch (DecodeBitAdr(ArgStr[1],&BitLong,True))
        BEGIN
         case ModBit51:
          AdrLong-=EProgCounter()+3+Ord(NeedsPrefix(FixedZ->Code));
          if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370);
          else
           BEGIN
            PutCode(FixedZ->Code);
            BAsmCode[CodeLen++] = BitLong & 0xff;
            BAsmCode[CodeLen++] = AdrLong & 0xff;
           END
          break;
         case ModBit251:
          AdrLong-=EProgCounter()+4+Ord(NeedsPrefix(0x1a9));
          if (((AdrLong<-128) OR (AdrLong>127)) AND (NOT Questionable)) WrError(1370);
          else
           BEGIN
            PutCode(0x1a9);
            BAsmCode[CodeLen++] = FixedZ->Code+(BitLong >> 24);
            BAsmCode[CodeLen++] = BitLong & 0xff;
            BAsmCode[CodeLen++] = AdrLong & 0xff;
           END
          break;
        END
      END
    END
END

	static void DecodeAcc(Word Index)
BEGIN
   FixedOrder *FixedZ=AccOrders+Index;

   if (ArgCnt!=1) WrError(1110);
   else if (MomCPU<FixedZ->MinCPU) WrError(1500);
   else
    BEGIN
     DecodeAdr(ArgStr[1],MModAcc);
     switch (AdrMode)
      BEGIN
       case ModAcc: 
        PutCode(FixedZ->Code);
        break;
      END
    END;
END

	static void DecodeFixed(Word Index)
BEGIN
   FixedOrder *FixedZ=FixedOrders+Index;

   if (ArgCnt!=0) WrError(1110);
   else if (MomCPU<FixedZ->MinCPU) WrError(1500);
   else PutCode(FixedZ->Code);
END


	static void DecodeSFR(Word Index)
BEGIN
   Word AdrByte;
   Boolean OK;
   int z,DSeg;
   String s;

   FirstPassUnknown=False;
   if (ArgCnt!=1) WrError(1110);
   else if ((Memo("SFRB")) AND (MomCPU>=CPU80251)) WrError(1500);
   else
    BEGIN
     if (MomCPU>=CPU80251) AdrByte=EvalIntExpression(ArgStr[1],UInt9,&OK);
     else AdrByte=EvalIntExpression(ArgStr[1],UInt8,&OK);
     if ((OK) AND (NOT FirstPassUnknown))
      BEGIN
       PushLocHandle(-1);
       DSeg=(MomCPU>=CPU80251)?(SegIO):(SegData);
       EnterIntSymbol(LabPart,AdrByte,DSeg,False);
       if (MakeUseList)
        if (AddChunk(SegChunks+DSeg,AdrByte,1,False)) WrError(90);
       if (Memo("SFRB"))
        BEGIN
         if (AdrByte>0x7f)
          BEGIN
           if ((AdrByte & 7)!=0) WrError(220);
          END
         else
          BEGIN
           if ((AdrByte & 0xe0)!=0x20) WrError(220);
           AdrByte=(AdrByte-0x20) << 3;
          END
         for (z=0; z<8; z++)
          BEGIN
           sprintf(s,"%s.%c",LabPart,z+'0');
           EnterIntSymbol(s,AdrByte+z,SegBData,False);
          END
         if (MakeUseList)
          if (AddChunk(SegChunks+SegBData,AdrByte,8,False)) WrError(90);
         sprintf(ListLine,"=%sH-",HexString(AdrByte,2));
         strmaxcat(ListLine,HexString(AdrByte+7,2),255);
         strmaxcat(ListLine,"H",255);
        END
       else sprintf(ListLine,"=%sH",HexString(AdrByte,2));
       PopLocHandle();
      END
    END
END

	static void DecodeBIT(Word Index)
BEGIN
   LongInt AdrLong;

   if (MomCPU>=CPU80251)
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else if (DecodeBitAdr(ArgStr[1],&AdrLong,False)==ModBit251)
      BEGIN
       EnterIntSymbol(LabPart,AdrLong,SegNone,False);
       sprintf(ListLine,"=%sH.%s",HexString(AdrLong&0xff,2),HexString(AdrLong>>24,1));
      END
    END
   else CodeEquate(SegBData,0,0xff);
END

	static void DecodePORT(Word Index)
BEGIN
   if (MomCPU<CPU80251) WrError(1500);
   else CodeEquate(SegIO,0,0x1ff);
END

/*-------------------------------------------------------------------------*/
/* dynamische Codetabellenverwaltung */

   	static void AddFixed(char *NName, Word NCode, CPUVar NCPU)
BEGIN
   if (InstrZ>=FixedOrderCnt) exit(255);
   FixedOrders[InstrZ].Code=NCode; 
   FixedOrders[InstrZ].MinCPU=NCPU;
   AddInstTable(InstTable,NName,InstrZ++,DecodeFixed);
END

   	static void AddAcc(char *NName, Word NCode, CPUVar NCPU)
BEGIN
   if (InstrZ>=AccOrderCnt) exit(255);
   AccOrders[InstrZ].Code=NCode; 
   AccOrders[InstrZ].MinCPU=NCPU;
   AddInstTable(InstTable,NName,InstrZ++,DecodeAcc);
END

   	static void AddCond(char *NName, Word NCode, CPUVar NCPU)
BEGIN
   if (InstrZ>=CondOrderCnt) exit(255);
   CondOrders[InstrZ].Code=NCode;
   CondOrders[InstrZ].MinCPU=NCPU;
   AddInstTable(InstTable,NName,InstrZ++,DecodeCond);
END

   	static void AddBCond(char *NName, Word NCode, CPUVar NCPU)
BEGIN
   if (InstrZ>=BCondOrderCnt) exit(255);
   BCondOrders[InstrZ].Code=NCode;
   BCondOrders[InstrZ].MinCPU=NCPU;
   AddInstTable(InstTable,NName,InstrZ++,DecodeBCond);
END

	static void InitFields(void)
BEGIN
   InstTable=CreateInstTable(203);
   AddInstTable(InstTable,"MOV"  , 0,DecodeMOV);
   AddInstTable(InstTable,"ANL"  , 1,DecodeLogic);
   AddInstTable(InstTable,"ORL"  , 0,DecodeLogic);
   AddInstTable(InstTable,"XRL"  , 2,DecodeLogic);
   AddInstTable(InstTable,"MOVC" , 0,DecodeMOVC);
   AddInstTable(InstTable,"MOVH" , 0,DecodeMOVH);
   AddInstTable(InstTable,"MOVZ" , 0,DecodeMOVZS);
   AddInstTable(InstTable,"MOVS" , 0,DecodeMOVZS); 
   AddInstTable(InstTable,"MOVX" , 0,DecodeMOVX);
   AddInstTable(InstTable,"POP"  , 1,DecodeStack);
   AddInstTable(InstTable,"PUSH" , 0,DecodeStack);
   AddInstTable(InstTable,"PUSHW", 2,DecodeStack);
   AddInstTable(InstTable,"XCH"  , 0,DecodeXCH);
   AddInstTable(InstTable,"XCHD" , 0,DecodeXCHD);
   AddInstTable(InstTable,"AJMP" , 0,DecodeABranch);
   AddInstTable(InstTable,"ACALL", 1,DecodeABranch);
   AddInstTable(InstTable,"LJMP" , 0,DecodeLBranch);
   AddInstTable(InstTable,"LCALL", 1,DecodeLBranch);
   AddInstTable(InstTable,"EJMP" , 0,DecodeEBranch);
   AddInstTable(InstTable,"ECALL", 1,DecodeEBranch);
   AddInstTable(InstTable,"JMP"  , 0,DecodeJMP);
   AddInstTable(InstTable,"CALL" , 0,DecodeCALL);
   AddInstTable(InstTable,"DJNZ" , 0,DecodeDJNZ);
   AddInstTable(InstTable,"CJNE" , 0,DecodeCJNE);
   AddInstTable(InstTable,"ADD"  , 0,DecodeADD);
   AddInstTable(InstTable,"SUB"  , 0,DecodeSUBCMP);
   AddInstTable(InstTable,"CMP"  , 1,DecodeSUBCMP);
   AddInstTable(InstTable,"ADDC" , 0,DecodeADDCSUBB);
   AddInstTable(InstTable,"SUBB" , 1,DecodeADDCSUBB);
   AddInstTable(InstTable,"INC"  , 0,DecodeINCDEC);
   AddInstTable(InstTable,"DEC"  , 1,DecodeINCDEC);
   AddInstTable(InstTable,"MUL"  , 1,DecodeMULDIV);
   AddInstTable(InstTable,"DIV"  , 0,DecodeMULDIV);
   AddInstTable(InstTable,"CLR"  , 1,DecodeBits);
   AddInstTable(InstTable,"CPL"  , 0,DecodeBits);
   AddInstTable(InstTable,"SETB" , 2,DecodeBits);
   AddInstTable(InstTable,"SRA"  , 0,DecodeShift);
   AddInstTable(InstTable,"SRL"  , 1,DecodeShift);
   AddInstTable(InstTable,"SLL"  , 3,DecodeShift);
   AddInstTable(InstTable,"SFR"  , 0,DecodeSFR);
   AddInstTable(InstTable,"SFRB" , 1,DecodeSFR);
   AddInstTable(InstTable,"BIT"  , 0,DecodeBIT);
   AddInstTable(InstTable,"PORT" , 0,DecodePORT);

   FixedOrders=(FixedOrder *) malloc(FixedOrderCnt*sizeof(FixedOrder)); 
   InstrZ=0;
   AddFixed("NOP" ,0x0000,CPU87C750);
   AddFixed("RET" ,0x0022,CPU87C750);
   AddFixed("RETI",0x0032,CPU87C750);
   AddFixed("ERET",0x01aa,CPU80251);
   AddFixed("TRAP",0x01b9,CPU80251);

   AccOrders=(FixedOrder *) malloc(AccOrderCnt*sizeof(FixedOrder)); 
   InstrZ=0;
   AddAcc("DA"  ,0x00d4,CPU87C750);
   AddAcc("RL"  ,0x0023,CPU87C750);
   AddAcc("RLC" ,0x0033,CPU87C750);
   AddAcc("RR"  ,0x0003,CPU87C750);
   AddAcc("RRC" ,0x0013,CPU87C750);
   AddAcc("SWAP",0x00c4,CPU87C750);

   CondOrders=(FixedOrder *) malloc(CondOrderCnt*sizeof(FixedOrder));
   InstrZ=0;
   AddCond("JC"  ,0x0040,CPU87C750);
   AddCond("JE"  ,0x0168,CPU80251);
   AddCond("JG"  ,0x0138,CPU80251);
   AddCond("JLE" ,0x0128,CPU80251);
   AddCond("JNC" ,0x0050,CPU87C750);
   AddCond("JNE" ,0x0178,CPU80251);
   AddCond("JNZ" ,0x0070,CPU87C750);
   AddCond("JSG" ,0x0118,CPU80251);
   AddCond("JSGE",0x0158,CPU80251);
   AddCond("JSL" ,0x0148,CPU80251);
   AddCond("JSLE",0x0108,CPU80251);
   AddCond("JZ"  ,0x0060,CPU87C750);
   AddCond("SJMP",0x0080,CPU87C750);

   BCondOrders=(FixedOrder *) malloc(BCondOrderCnt*sizeof(FixedOrder));
   InstrZ=0;
   AddBCond("JB" ,0x0020,CPU87C750);
   AddBCond("JBC",0x0010,CPU87C750);
   AddBCond("JNB",0x0030,CPU87C750);
END

	static void DeinitFields(void)
BEGIN
   DestroyInstTable(InstTable);
   free(FixedOrders);
   free(AccOrders);
   free(CondOrders);
   free(BCondOrders);
END

/*-------------------------------------------------------------------------*/
/* Instruktionsdecoder */

	static Boolean DecodePseudo(void)
BEGIN

   return False;
END

	static void MakeCode_51(void)
BEGIN
   CodeLen=0; DontPrint=False; OpSize=(-1); MinOneIs0=False;

   /* zu ignorierendes */

   if (*OpPart=='\0') return;

   /* Pseudoanweisungen */

   if (DecodePseudo()) return;

   if (DecodeIntelPseudo(BigEndian)) return;

   /* suchen */

   if (NOT LookupInstTable(InstTable,OpPart)) WrXError(1200,OpPart);
END

	static Boolean IsDef_51(void)
BEGIN
   switch (*OpPart)
    BEGIN
     case 'B': return Memo("BIT");
     case 'S': if (Memo("SFR")) return True;
               if (MomCPU>=CPU80251) return False;
               return Memo("SFRB");
     case 'P': if (MomCPU>=CPU80251) return Memo("PORT");
               else return False;
     default : return False;
    END
END

        static void InitPass_51(void)
BEGIN
   SaveInitProc();
   SetFlag(&SrcMode,SrcModeName,False);
   SetFlag(&BigEndian,BigEndianName,False);
END

        static void SwitchFrom_51(void)
BEGIN
   DeinitFields(); ClearONOFF();
END

	static void SwitchTo_51(void)
BEGIN
   TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False;

   PCSymbol="$"; HeaderID=0x31; NOPCode=0x00;
   DivideChars=","; HasAttrs=False;

   if (MomCPU>=CPU80251)
    BEGIN
     ValidSegs=(1<<SegCode)|(1<<SegIO);
     Grans[SegCode ]=1; ListGrans[SegCode ]=1; SegInits[SegCode ]=0;
     SegLimits[SegCode ] = 0xffffffl;
     Grans[SegIO   ]=1; ListGrans[SegIO   ]=1; SegInits[SegIO   ]=0;
     SegLimits[SegIO   ] = 0x1ff;
    END
   else
    BEGIN
     ValidSegs=(1<<SegCode)|(1<<SegData)|(1<<SegIData)|(1<<SegXData)|(1<<SegBData);
     Grans[SegCode ]=1; ListGrans[SegCode ]=1; SegInits[SegCode ]=0;
     SegLimits[SegCode ] = (MomCPU == CPU87C750) ? 0x7ff : 0xffff;
     Grans[SegData ]=1; ListGrans[SegData ]=1; SegInits[SegData ]=0x30;
     SegLimits[SegData ] = 0xff;
     Grans[SegIData]=1; ListGrans[SegIData]=1; SegInits[SegIData]=0x80;
     SegLimits[SegIData] = 0xff;
     Grans[SegXData]=1; ListGrans[SegXData]=1; SegInits[SegXData]=0;
     SegLimits[SegXData] = 0xffff;
     Grans[SegBData]=1; ListGrans[SegBData]=1; SegInits[SegBData]=0;
     SegLimits[SegBData] = 0xff;
    END

   MakeCode=MakeCode_51; IsDef=IsDef_51;

   InitFields(); SwitchFrom=SwitchFrom_51;
   AddONOFF("SRCMODE"  , &SrcMode  , SrcModeName  , False);
   AddONOFF("BIGENDIAN", &BigEndian, BigEndianName, False);
END


	void code51_init(void)
BEGIN
   CPU87C750 =AddCPU("87C750",SwitchTo_51);
   CPU8051   =AddCPU("8051"  ,SwitchTo_51);
   CPU8052   =AddCPU("8052"  ,SwitchTo_51);
   CPU80C320 =AddCPU("80C320",SwitchTo_51);
   CPU80501  =AddCPU("80C501",SwitchTo_51);
   CPU80502  =AddCPU("80C502",SwitchTo_51);
   CPU80504  =AddCPU("80C504",SwitchTo_51);
   CPU80515  =AddCPU("80515" ,SwitchTo_51);
   CPU80517  =AddCPU("80517" ,SwitchTo_51);
   CPU80251  =AddCPU("80C251",SwitchTo_51);

   SaveInitProc=InitPassProc;
   InitPassProc=InitPass_51;
END
