/* codeh8_3.c */
/*****************************************************************************/
/* AS-Portierung                                                             */
/*                                                                           */
/* Codegenerator H8/300(L/H)                                                 */
/*                                                                           */
/* Historie: 22.11.1996 Grundsteinlegung                                     */
/*           15.10.1998 TRAPA nachgetragen                                   */
/*            3. 1.1999 ChkPC-Anpassung                                      */
/*                                                                           */
/*****************************************************************************/

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

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

#define FixedOrderCount 4
#define ConditionCount 20
#define ShiftOrderCount 8
#define LogicOrderCount 3
#define MulOrderCount 4
#define Bit1OrderCount 10
#define Bit2OrderCount 4

#define ModNone (-1)
#define ModReg 0
#define MModReg (1 << ModReg)
#define ModImm 1
#define MModImm (1 << ModImm)
#define ModAbs8 2
#define MModAbs8 (1 << ModAbs8)
#define ModAbs16 3
#define MModAbs16 (1 << ModAbs16)
#define ModAbs24 4
#define MModAbs24 (1 << ModAbs24)
#define MModAbs (MModAbs8+MModAbs16+MModAbs24)
#define ModIReg 5
#define MModIReg (1 << ModIReg)
#define ModPreDec 6
#define MModPreDec (1 << ModPreDec)
#define ModPostInc 7
#define MModPostInc (1 << ModPostInc)
#define ModInd16 8
#define MModInd16 (1 << ModInd16)
#define ModInd24 9
#define MModInd24 (1 << ModInd24)
#define ModIIAbs 10
#define MModIIAbs (1 << ModIIAbs)
#define MModInd (MModInd16+MModInd24)

typedef struct
         { 
          char *Name;
          Word Code;
         } FixedOrder;

typedef struct
         { 
          char *Name;
          Byte Code;
         } Condition;


static ShortInt OpSize;     /* Groesse=8*(2^OpSize) */
static ShortInt AdrMode;    /* Ergebnisadressmodus */
static Byte AdrPart;        /* Adressierungsmodusbits im Opcode */
static Word AdrVals[6];     /* Adressargument */

static CPUVar CPUH8_300L;
static CPUVar CPU6413308,CPUH8_300;
static CPUVar CPU6413309,CPUH8_300H;
static Boolean CPU16;	    /* keine 32-Bit-Register */

static Condition  *Conditions;
static FixedOrder *FixedOrders;
static FixedOrder *ShiftOrders;
static FixedOrder *LogicOrders;
static FixedOrder *MulOrders;
static FixedOrder *Bit1Orders;
static FixedOrder *Bit2Orders;

/*-------------------------------------------------------------------------*/
/* dynamische Belegung/Freigabe Codetabellen */

	static void AddFixed(char *NName, Word NCode)
BEGIN
   if (InstrZ>=FixedOrderCount) exit(255);
   FixedOrders[InstrZ].Name=NName;
   FixedOrders[InstrZ++].Code=NCode;
END

	static void AddCond(char *NName, Byte NCode)
BEGIN
   if (InstrZ>=ConditionCount) exit(255);
   Conditions[InstrZ].Name=NName;
   Conditions[InstrZ++].Code=NCode;
END

	static void AddShift(char *NName, Word NCode)
BEGIN
   if (InstrZ>=ShiftOrderCount) exit(255);
   ShiftOrders[InstrZ].Name=NName;
   ShiftOrders[InstrZ++].Code=NCode;
END

	static void AddLogic(char *NName, Word NCode)
BEGIN
   if (InstrZ>=LogicOrderCount) exit(255);
   LogicOrders[InstrZ].Name=NName;
   LogicOrders[InstrZ++].Code=NCode;
END

	static void AddMul(char *NName, Word NCode)
BEGIN
   if (InstrZ>=MulOrderCount) exit(255);
   MulOrders[InstrZ].Name=NName;
   MulOrders[InstrZ++].Code=NCode;
END

	static void AddBit1(char *NName, Word NCode)
BEGIN
   if (InstrZ>=Bit1OrderCount) exit(255);
   Bit1Orders[InstrZ].Name=NName;
   Bit1Orders[InstrZ++].Code=NCode;
END

	static void AddBit2(char *NName, Word NCode)
BEGIN
   if (InstrZ>=Bit2OrderCount) exit(255);
   Bit2Orders[InstrZ].Name=NName;
   Bit2Orders[InstrZ++].Code=NCode;
END

	static void InitFields(void)
BEGIN
   FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCount); InstrZ=0;
   AddFixed("NOP",0x0000); AddFixed("RTE",0x5670);
   AddFixed("RTS",0x5470); AddFixed("SLEEP",0x0180);

   Conditions=(Condition *) malloc(sizeof(Condition)*ConditionCount); InstrZ=0;
   AddCond("BRA",0x0); AddCond("BT" ,0x0);
   AddCond("BRN",0x1); AddCond("BF" ,0x1);
   AddCond("BHI",0x2); AddCond("BLS",0x3);
   AddCond("BCC",0x4); AddCond("BHS",0x4);
   AddCond("BCS",0x5); AddCond("BLO",0x5);
   AddCond("BNE",0x6); AddCond("BEQ",0x7);
   AddCond("BVC",0x8); AddCond("BVS",0x9);
   AddCond("BPL",0xa); AddCond("BMI",0xb);
   AddCond("BGE",0xc); AddCond("BLT",0xd);
   AddCond("BGT",0xe); AddCond("BLE",0xf);

   ShiftOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*ShiftOrderCount); InstrZ=0;
   AddShift("ROTL" ,0x1280); AddShift("ROTR" ,0x1380);
   AddShift("ROTXL",0x1200); AddShift("ROTXR",0x1300);
   AddShift("SHAL" ,0x1080); AddShift("SHAR" ,0x1180);
   AddShift("SHLL" ,0x1000); AddShift("SHLR" ,0x1100);

   LogicOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*LogicOrderCount); InstrZ=0;
   AddLogic("OR",0); AddLogic("XOR",1); AddLogic("AND",2);

   MulOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*MulOrderCount); InstrZ=0;
   AddMul("DIVXS",3); AddMul("DIVXU",1); AddMul("MULXS",2); AddMul("MULXU",0);

   Bit1Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*Bit1OrderCount); InstrZ=0;
   AddBit1("BAND",0x16); AddBit1("BIAND",0x96);
   AddBit1("BOR" ,0x14); AddBit1("BIOR" ,0x94);
   AddBit1("BXOR",0x15); AddBit1("BIXOR",0x95);
   AddBit1("BLD" ,0x17); AddBit1("BILD" ,0x97);
   AddBit1("BST" ,0x07); AddBit1("BIST" ,0x87);

   Bit2Orders=(FixedOrder *) malloc(sizeof(FixedOrder)*Bit2OrderCount); InstrZ=0;
   AddBit2("BCLR",2); AddBit2("BNOT",1); AddBit2("BSET",0); AddBit2("BTST",3);
END

	static void DeinitFields(void)
BEGIN
   free(FixedOrders);
   free(Conditions);
   free(ShiftOrders);
   free(LogicOrders);
   free(MulOrders);
   free(Bit1Orders);
   free(Bit2Orders);
END

/*-------------------------------------------------------------------------*/
/* Adressparsing */

typedef enum {SizeNone,Size8,Size16,Size24} MomSize_t;
static MomSize_t MomSize;

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

	static Boolean IsNum(char Inp, Byte *Erg)
BEGIN
   if ((Inp<'0') OR (Inp>'7')) return False;
   else
    BEGIN
     *Erg=Inp-AscOfs; return True;
    END
END

	static Boolean DecodeReg(char *Asc, Byte *Erg, ShortInt *Size)
BEGIN
   if (strcasecmp(Asc,"SP")==0)
    BEGIN
     *Erg=7; *Size=(Maximum) ? 2 : 1; return True;
    END

   else if ((strlen(Asc)==3) AND (toupper(*Asc)=='R') AND (IsNum(Asc[1],Erg)))
    if (toupper(Asc[2])=='L')
     BEGIN
      *Erg+=8; *Size=0; return True;
     END
    else if (toupper(Asc[2])=='H')
     BEGIN
      *Size=0; return True;
     END
    else return False;

   else if ((strlen(Asc)==2) AND (IsNum(Asc[1],Erg)))
    if (toupper(*Asc)=='R')
     BEGIN
      *Size=1; return True;
     END
    else if (toupper(*Asc)=='E')
     BEGIN
      *Erg+=8; *Size=1; return True;
     END
    else return False;

   else if ((strlen(Asc)==3) AND (toupper(*Asc)=='E') AND (toupper(Asc[1])=='R') AND (IsNum(Asc[2],Erg)))
    BEGIN
     *Size=2; return True;
    END
   else return False;
END

        static void CutSize(char *Asc)
BEGIN
   int l=strlen(Asc);

   if ((l>=2) AND (Asc[l-2]==':') AND (Asc[l-1]=='8'))
    BEGIN
     Asc[l-2]='\0'; MomSize=Size8;
    END
   else if ((l>=3) AND (Asc[l-3]==':'))
    BEGIN
     if ((Asc[l-2]=='1') AND (Asc[l-1]=='6'))
      BEGIN
       Asc[l-3]='\0'; MomSize=Size16;
      END
     else if ((Asc[l-2]=='2') AND (Asc[l-1]=='4'))
      BEGIN
       Asc[l-3]='\0'; MomSize=Size24;
      END
    END
END

	static Byte DecodeBaseReg(char *Asc, Byte *Erg)
BEGIN
   ShortInt HSize;

   if (NOT DecodeReg(Asc,Erg,&HSize)) return 0;
   if ((HSize==0) OR ((HSize==1) AND (*Erg>7)))
    BEGIN
     WrError(1350); return 1;
    END;
   if ((CPU16) != (HSize==1))
    BEGIN
     WrError(1505); return 1;
    END
   return 2;
END

	static Boolean Is8(LongInt Address)
BEGIN
   if (CPU16) return (((Address >> 8)&0xff)==0xff);
   else return (((Address >> 8)&0xffff)==0xffff);
END

	static Boolean Is16(LongInt Address)
BEGIN
   return (CPU16) ? (True) : (((Address>=0) AND (Address<=0x7fff)) OR ((Address>=0xff8000) AND (Address<=0xffffff)));
END

	static void DecideVAbsolute(LongInt Address, Word Mask)
BEGIN
   /* bei Automatik Operandengroesse festlegen */

   if (MomSize==SizeNone)
    BEGIN
     if (Is8(Address)) MomSize=Size8;
     else if (Is16(Address)) MomSize=Size16;
     else MomSize=Size24;
    END

   /* wenn nicht vorhanden, eins rauf */

   if ((MomSize==Size8)  AND ((Mask & MModAbs8)==0)) MomSize=Size16;
   if ((MomSize==Size16) AND ((Mask & MModAbs16)==0)) MomSize=Size24;

   /* entsprechend Modus Bytes ablegen */

   switch (MomSize)
    BEGIN
     case Size8:
      if (NOT Is8(Address)) WrError(1925);
      else
       BEGIN
        AdrCnt=2; AdrVals[0]=Address & 0xff; AdrMode=ModAbs8;
       END
      break;
     case Size16:
      if (NOT Is16(Address)) WrError(1925);
      else
       BEGIN
        AdrCnt=2; AdrVals[0]=Address & 0xffff; AdrMode=ModAbs16;
       END
      break;
     case Size24:
      AdrCnt=4;
      AdrVals[1]=Address & 0xffff;
      AdrVals[0]=Lo(Address >> 16);
      AdrMode=ModAbs24;
      break;
     default:
      WrError(10000);
    END
END

	static void DecideAbsolute(char *Asc, Word Mask)
BEGIN
   LongInt Addr;
   Boolean OK;

   Addr=EvalIntExpression(Asc,Int32,&OK);
   if (OK) DecideVAbsolute(Addr,Mask);
END


	static void ChkAdr(Word Mask)
BEGIN
   if (CPU16)
    if (((AdrMode==ModReg) AND (OpSize==2))
    OR  ((AdrMode==ModReg) AND (OpSize==1) AND (AdrPart>7))
    OR  (AdrMode==ModAbs24)
    OR  (AdrMode==ModInd24))
     BEGIN
      WrError(1505); AdrMode=ModNone; AdrCnt=0;
     END
   if ((AdrMode!=ModNone) AND ((Mask & (1 << AdrMode))==0))
    BEGIN
     WrError(1350); AdrMode=ModNone; AdrCnt=0;
    END
END

	static void DecodeAdr(char *Asc, Word Mask)
BEGIN
   ShortInt HSize;
   Byte HReg;
   LongInt HLong;
   Boolean OK;
   char *p;
   LongInt DispAcc;
   String Part;
   int l;

   AdrMode=ModNone; AdrCnt=0; MomSize=SizeNone;

   /* immediate ? */

   if (*Asc=='#')
    BEGIN
     switch (OpSize)
      BEGIN
       case -1:
        WrError(1132);
        break;
       case 0:
	HReg=EvalIntExpression(Asc+1,Int8,&OK);
	if (OK)
	 BEGIN
	  AdrCnt=2; AdrVals[0]=HReg; AdrMode=ModImm;
	 END
        break;
       case 1:
	AdrVals[0]=EvalIntExpression(Asc+1,Int16,&OK);
	if (OK)
	 BEGIN
	  AdrCnt=2; AdrMode=ModImm;
	 END
        break;
       case 2:
	HLong=EvalIntExpression(Asc+1,Int32,&OK);
	if (OK)
	 BEGIN
	  AdrCnt=4;
	  AdrVals[0]=HLong >> 16;
	  AdrVals[1]=HLong & 0xffff;
	  AdrMode=ModImm;
	 END
        break;
       default:
        WrError(1130);
      END
     ChkAdr(Mask); return;
    END

   /* Register ? */

   if (DecodeReg(Asc,&HReg,&HSize))
    BEGIN
     AdrMode=ModReg; AdrPart=HReg; SetOpSize(HSize); ChkAdr(Mask); return;
    END

   /* indirekt ? */

   if (*Asc=='@')
    BEGIN
     strcpy(Asc,Asc+1);

     if (*Asc=='@')
      BEGIN
       AdrVals[0]=EvalIntExpression(Asc+1,UInt8,&OK) & 0xff;
       if (OK)
	BEGIN
	 AdrCnt=1; AdrMode=ModIIAbs;
	END
       ChkAdr(Mask); return;
      END

     switch (DecodeBaseReg(Asc,&AdrPart))
      BEGIN
       case 1:
        ChkAdr(Mask); return;
       case 2:
	AdrMode=ModIReg; ChkAdr(Mask); return;
      END

     if (*Asc=='-')
      switch (DecodeBaseReg(Asc+1,&AdrPart))
       BEGIN
        case 1:
         ChkAdr(Mask); return;
        case 2:
	 AdrMode=ModPreDec; ChkAdr(Mask); return;
       END

     if (Asc[l=strlen(Asc)-1]=='+')
      BEGIN
       Asc[l]='\0';
       switch (DecodeBaseReg(Asc,&AdrPart))
        BEGIN
         case 1:
          ChkAdr(Mask); return;
         case 2:
	  AdrMode=ModPostInc; ChkAdr(Mask); return;
        END
       Asc[l]='+';
      END

     if (IsIndirect(Asc))
      BEGIN
       strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0';
       AdrPart=0xff; DispAcc=0;
       do
        BEGIN
	 p=QuotPos(Asc,',');
         if (p==Nil)
          BEGIN
           strmaxcpy(Part,Asc,255); *Asc='\0';
          END
         else
          BEGIN
           *p='\0'; strmaxcpy(Part,Asc,255); strmaxcpy(Asc,p+1,255);
          END 
	 switch (DecodeBaseReg(Part,&HReg))
          BEGIN
	   case 2:
            if (AdrPart!=0xff)
	     BEGIN
	      WrError(1350); ChkAdr(Mask); return;
	     END
	    else AdrPart=HReg;
            break;
	   case 1:
            ChkAdr(Mask); return;
	   case 0:
            CutSize(Part);
	    DispAcc+=EvalIntExpression(Part,Int32,&OK);
	    if (NOT OK) 
             BEGIN
              ChkAdr(Mask); return;
             END
            break;
	  END
        END
       while (*Asc!='\0');
       if (AdrPart==0xff) DecideVAbsolute(DispAcc,Mask);
       else
        BEGIN
         if ((CPU16) AND ((DispAcc & 0xffff8000)==0x8000)) DispAcc+=0xffff0000;
         if (MomSize==SizeNone)
          MomSize=((DispAcc>=-32768) AND (DispAcc<=32767)) ? Size16 : Size24;
         switch (MomSize)
          BEGIN
           case Size8:
            WrError(1130); break;
           case Size16:
	    if (DispAcc<-32768) WrError(1315);
	    else if (DispAcc>32767) WrError(1320);
            else
	     BEGIN
	      AdrCnt=2; AdrVals[0]=DispAcc & 0xffff; AdrMode=ModInd16;
	     END
            break;
           case Size24:
	    AdrVals[1]=DispAcc & 0xffff; AdrVals[0]=Lo(DispAcc >> 16);
	    AdrCnt=4; AdrMode=ModInd24;
	    break;
           default:
            WrError(10000);
          END
        END
      END
     else
      BEGIN
       CutSize(Asc);
       DecideAbsolute(Asc,Mask);
      END
     ChkAdr(Mask); return;
    END

   CutSize(Asc);
   DecideAbsolute(Asc,Mask);
   ChkAdr(Mask);
END

	static LongInt ImmVal(void)
BEGIN
   switch (OpSize)
    BEGIN
     case 0: return Lo(AdrVals[0]);
     case 1: return AdrVals[0];
     case 2: return (((LongInt)AdrVals[0]) << 16)+AdrVals[1];
     default: WrError(10000); return 0;
    END
END

/*-------------------------------------------------------------------------*/

	static Boolean DecodePseudo(void)
BEGIN
   return False;
END

	static void MakeCode_H8_3(void)
BEGIN
   int z;
   Word Mask;
   ShortInt HSize;
   LongInt AdrLong;
   Byte HReg,OpCode;
   Boolean OK;

   CodeLen=0; DontPrint=False; OpSize=(-1);

   /* zu ignorierendes */

   if (Memo("")) return;

   /* Pseudoanweisungen */

   if (DecodePseudo()) return;

   /* Attribut verwursten */

   if (*AttrPart!='\0')
    BEGIN
     if (strlen(AttrPart)!=1)
      BEGIN
       WrError(1105); return;
      END
     switch (toupper(*AttrPart))
      BEGIN
       case 'B': SetOpSize(0); break;
       case 'W': SetOpSize(1); break;
       case 'L': SetOpSize(2); break;
       case 'Q': SetOpSize(3); break;
       case 'S': SetOpSize(4); break;
       case 'D': SetOpSize(5); break;
       case 'X': SetOpSize(6); break;
       case 'P': SetOpSize(7); break;
       default:
        WrError(1107); return;
      END
    END

   if (DecodeMoto16Pseudo(OpSize,True)) return;

   /* Anweisungen ohne Argument */

   for (z=0; z<FixedOrderCount; z++)
    if (Memo(FixedOrders[z].Name))
     BEGIN
      if (ArgCnt!=0) WrError(1110);
      else if (*AttrPart!='\0') WrError(1100);
      else
       BEGIN
        CodeLen=2; WAsmCode[0]=FixedOrders[z].Code;
       END;
      return;
     END

   if (Memo("EEPMOV"))
    BEGIN
     if (OpSize==-1) OpSize=Ord(NOT CPU16);
     if (OpSize>1) WrError(1130);
     else if (ArgCnt!=0) WrError(1110);
     else if ((OpSize==1) AND (CPU16)) WrError(1500);
     else
      BEGIN
       CodeLen=4;
       WAsmCode[0]=(OpSize==0) ? 0x7b5c : 0x7bd4;
       WAsmCode[1]=0x598f;
      END
     return;
    END

   /* Datentransfer */

   if (Memo("MOV"))
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else
      BEGIN
       DecodeAdr(ArgStr[2],MModReg+MModIReg+MModPreDec+MModInd+MModAbs);
       switch (AdrMode)
        BEGIN
         case ModReg:
	  HReg=AdrPart;
	  Mask=MModReg+MModIReg+MModPostInc+MModInd+MModAbs+MModImm;
	  if (OpSize!=0) Mask-=MModAbs8;
	  DecodeAdr(ArgStr[1],Mask);
	  switch (AdrMode)
           BEGIN
	    case ModReg:
	     z=OpSize; if (z==2) z=3;
	     CodeLen=2; WAsmCode[0]=0x0c00+(z << 8)+(AdrPart << 4)+HReg;
	     if (OpSize==2) WAsmCode[0]+=0x80;
	     break;
	    case ModIReg:
	     switch (OpSize)
              BEGIN
	       case 0:
	        CodeLen=2; WAsmCode[0]=0x6800+(AdrPart << 4)+HReg;
	        break;
	       case 1:
	        CodeLen=2; WAsmCode[0]=0x6900+(AdrPart << 4)+HReg;
	        break;
	       case 2:
                CodeLen=4; WAsmCode[0]=0x0100;
	        WAsmCode[1]=0x6900+(AdrPart << 4)+HReg;
	        break;
	      END
             break;
	    case ModPostInc:
	     switch (OpSize)
              BEGIN
	       case 0:
	        CodeLen=2; WAsmCode[0]=0x6c00+(AdrPart << 4)+HReg;
	        break;
	       case 1:
	        CodeLen=2; WAsmCode[0]=0x6d00+(AdrPart << 4)+HReg;
	        break;
	       case 2:
                CodeLen=4; WAsmCode[0]=0x0100;
	        WAsmCode[1]=0x6d00+(AdrPart << 4)+HReg;
	        break;
	      END
             break;
	    case ModInd16:
	     switch (OpSize)
              BEGIN
	       case 0:
	        CodeLen=4; WAsmCode[0]=0x6e00+(AdrPart << 4)+HReg;
	        WAsmCode[1]=AdrVals[0];
	        break;
	       case 1:
	        CodeLen=4; WAsmCode[0]=0x6f00+(AdrPart << 4)+HReg;
	        WAsmCode[1]=AdrVals[0];
	        break;
	       case 2:
                CodeLen=6; WAsmCode[0]=0x0100;
	        WAsmCode[1]=0x6f00+(AdrPart << 4)+HReg;
	        WAsmCode[2]=AdrVals[0];
	        break;
	      END
             break;
	    case ModInd24:
	     switch (OpSize)
              BEGIN
	       case 0:
	        CodeLen=8;
	        WAsmCode[0]=0x7800+(AdrPart << 4);
	        WAsmCode[1]=0x6a20+HReg;
	        memcpy(WAsmCode+2,AdrVals,AdrCnt);
	        break;
	       case 1:
	        CodeLen=8;
	        WAsmCode[0]=0x7800+(AdrPart << 4);
	        WAsmCode[1]=0x6b20+HReg;
	        memcpy(WAsmCode+2,AdrVals,AdrCnt);
	        break;
	       case 2:
                CodeLen=10; WAsmCode[0]=0x0100;
	        WAsmCode[1]=0x7800+(AdrPart << 4);
	        WAsmCode[2]=0x6b20+HReg;
	        memcpy(WAsmCode+3,AdrVals,AdrCnt);
	        break;
	      END
             break;
	    case ModAbs8:
	     CodeLen=2; WAsmCode[0]=0x2000+(((Word)HReg) << 8)+Lo(AdrVals[0]);
	     break;
	    case ModAbs16:
	     switch (OpSize)
              BEGIN
	       case 0:
	        CodeLen=4; WAsmCode[0]=0x6a00+HReg;
	        WAsmCode[1]=AdrVals[0];
	        break;
	       case 1:
	        CodeLen=4; WAsmCode[0]=0x6b00+HReg;
	        WAsmCode[1]=AdrVals[0];
	        break;
	       case 2:
                CodeLen=6; WAsmCode[0]=0x0100;
	        WAsmCode[1]=0x6b00+HReg;
	        WAsmCode[2]=AdrVals[0];
	        break;
	      END
             break;
	    case ModAbs24:
	     switch (OpSize)
              BEGIN
	       case 0:
	        CodeLen=6; WAsmCode[0]=0x6a20+HReg;
	        memcpy(WAsmCode+1,AdrVals,AdrCnt);
	        break;
	       case 1:
	        CodeLen=6; WAsmCode[0]=0x6b20+HReg;
	        memcpy(WAsmCode+1,AdrVals,AdrCnt);
	        break;
	       case 2:
                CodeLen=8; WAsmCode[0]=0x0100;
	        WAsmCode[1]=0x6b20+HReg;
	        memcpy(WAsmCode+2,AdrVals,AdrCnt);
	        break;
	      END
             break;
	    case ModImm:
	     switch (OpSize)
              BEGIN
	       case 0:
	        CodeLen=2; WAsmCode[0]=0xf000+(((Word)HReg) << 8)+Lo(AdrVals[0]);
	        break;
	       case 1:
                CodeLen=4; WAsmCode[0]=0x7900+HReg; WAsmCode[1]=AdrVals[0];
	        break;
	       case 2:
                CodeLen=6; WAsmCode[0]=0x7a00+HReg;
                memcpy(WAsmCode+1,AdrVals,AdrCnt);
	        break;
	      END
             break;
	   END
	  break;
         case ModIReg:
	  HReg=AdrPart;
	  DecodeAdr(ArgStr[1],MModReg);
	  if (AdrMode!=ModNone)
	   switch (OpSize)
            BEGIN
	     case 0:
	      CodeLen=2; WAsmCode[0]=0x6880+(HReg << 4)+AdrPart;
	      break;
	     case 1:
	      CodeLen=2; WAsmCode[0]=0x6980+(HReg << 4)+AdrPart;
	      break;
	     case 2:
	      CodeLen=4; WAsmCode[0]=0x0100;
	      WAsmCode[1]=0x6980+(HReg << 4)+AdrPart;
	      break;
	    END
	   break;
         case ModPreDec:
	  HReg=AdrPart;
	  DecodeAdr(ArgStr[1],MModReg);
	  if (AdrMode!=ModNone)
	   switch (OpSize)
            BEGIN
	     case 0:
	      CodeLen=2; WAsmCode[0]=0x6c80+(HReg << 4)+AdrPart;
	      break;
	     case 1:
	      CodeLen=2; WAsmCode[0]=0x6d80+(HReg << 4)+AdrPart;
	      break;
	     case 2:
	      CodeLen=4; WAsmCode[0]=0x0100;
	      WAsmCode[1]=0x6d80+(HReg << 4)+AdrPart;
	      break;
	    END
	  break;
         case ModInd16:
	  HReg=AdrPart; WAsmCode[1]=AdrVals[0];
	  DecodeAdr(ArgStr[1],MModReg);
	  if (AdrMode!=ModNone)
	   switch (OpSize)
            BEGIN
	     case 0:
	      CodeLen=4; WAsmCode[0]=0x6e80+(HReg << 4)+AdrPart;
	      break;
	     case 1:
	      CodeLen=4; WAsmCode[0]=0x6f80+(HReg << 4)+AdrPart;
	      break;
	     case 2:
	      CodeLen=6; WAsmCode[0]=0x0100; WAsmCode[2]=WAsmCode[1];
	      WAsmCode[1]=0x6f80+(HReg << 4)+AdrPart;
	      break;
	    END
	   break;
         case ModInd24:
	  HReg=AdrPart; memcpy(WAsmCode+2,AdrVals,4);
	  DecodeAdr(ArgStr[1],MModReg);
	  if (AdrMode!=ModNone)
 	   switch (OpSize)
            BEGIN
	     case 0:
	      CodeLen=8; WAsmCode[0]=0x7800+(HReg << 4);
	      WAsmCode[1]=0x6aa0+AdrPart;
	      break;
	     case 1:
	      CodeLen=8; WAsmCode[0]=0x7800+(HReg << 4);
	      WAsmCode[1]=0x6ba0+AdrPart;
	      break;
	     case 2:
	      CodeLen=10; WAsmCode[0]=0x0100;
	      WAsmCode[4]=WAsmCode[3]; WAsmCode[3]=WAsmCode[2];
	      WAsmCode[1]=0x7800+(HReg << 4);
	      WAsmCode[2]=0x6ba0+AdrPart;
	      break;
	    END
	  break;
         case ModAbs8:
	  HReg=Lo(AdrVals[0]);
	  DecodeAdr(ArgStr[1],MModReg);
	  if (AdrMode!=ModNone)
	   switch (OpSize)
            BEGIN
	     case 0:
	      CodeLen=2; WAsmCode[0]=0x3000+(((Word)AdrPart) << 8)+HReg;
	      break;
	     case 1:
	      CodeLen=4;
	      WAsmCode[0]=0x6b80+AdrPart; WAsmCode[1]=0xff00+HReg;
	      break;
	     case 2:
	      CodeLen=6; WAsmCode[0]=0x0100;
	      WAsmCode[1]=0x6b80+AdrPart; WAsmCode[2]=0xff00+HReg;
	      break;
	    END
	  break;
         case ModAbs16:
	  WAsmCode[1]=AdrVals[0];
	  DecodeAdr(ArgStr[1],MModReg);
	  if (AdrMode!=ModNone)
	   switch (OpSize)
            BEGIN
	     case 0:
	      CodeLen=4; WAsmCode[0]=0x6a80+AdrPart;
	      break;
	     case 1:
	      CodeLen=4; WAsmCode[0]=0x6b80+AdrPart;
	      break;
	     case 2:
	      CodeLen=6; WAsmCode[0]=0x0100; WAsmCode[2]=WAsmCode[1];
	      WAsmCode[1]=0x6b80+AdrPart;
	      break;
	    END
	  break;
         case ModAbs24:
	  memcpy(WAsmCode+1,AdrVals,4);
	  DecodeAdr(ArgStr[1],MModReg);
	  if (AdrMode!=ModNone)
	   switch (OpSize)
            BEGIN
	     case 0:
	      CodeLen=6; WAsmCode[0]=0x6aa0+AdrPart;
	      break;
	     case 1:
	      CodeLen=6; WAsmCode[0]=0x6ba0+AdrPart;
	      break;
	     case 2:
	      CodeLen=8; WAsmCode[0]=0x0100;
	      WAsmCode[3]=WAsmCode[2]; WAsmCode[2]=WAsmCode[1];
	      WAsmCode[1]=0x6ba0+AdrPart;
	      break;
	    END
	  break;
        END
      END
     return;
    END

   if ((Memo("MOVTPE")) OR (Memo("MOVFPE")))
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else if (MomCPU<=CPUH8_300L) WrError(1500);
     else
      BEGIN
       if (Memo("MOVTPE"))
	BEGIN
	 strcpy(ArgStr[3],ArgStr[2]); strcpy(ArgStr[2],ArgStr[1]); 
         strcpy(ArgStr[1],ArgStr[3]);
	END
       DecodeAdr(ArgStr[2],MModReg);
       if (AdrMode!=ModNone)
	if (OpSize!=0) WrError(1130);
	else
	 BEGIN
	  HReg=AdrPart; DecodeAdr(ArgStr[1],MModAbs16);
	  if (AdrMode!=ModNone)
	   BEGIN
	    CodeLen=4; WAsmCode[0]=0x6a40+HReg; WAsmCode[1]=AdrVals[0];
	    if (Memo("MOVTPE")) WAsmCode[0]+=0x80;
	   END
	 END
      END
     return;
    END

   if ((Memo("PUSH")) OR (Memo("POP")))
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else
      BEGIN
       z=Ord(Memo("PUSH"));
       DecodeAdr(ArgStr[1],MModReg);
       if (AdrMode!=ModNone)
	if (OpSize==0) WrError(1130);
	else if ((CPU16) AND (OpSize==2)) WrError(1500);
	else
	 BEGIN
	  if (OpSize==2) WAsmCode[0]=0x0100;
	  CodeLen=2*OpSize;
	  WAsmCode[(CodeLen-2) >> 1]=0x6d70+(z << 7)+AdrPart;
	 END
      END
     return;
    END

   if ((Memo("LDC")) OR (Memo("STC")))
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else
      BEGIN
       if (Memo("STC"))
	BEGIN
	 strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]);
         strcpy(ArgStr[2],ArgStr[3]);
	 z=0x80;
	END
       else z=0;
       if (strcasecmp(ArgStr[2],"CCR")!=0) WrError(1350);
       else
	BEGIN
	 SetOpSize(0);
	 Mask=MModReg+MModIReg+MModInd+MModAbs16+MModAbs24;
	 if (Memo("LDC")) Mask+=MModImm+MModPostInc;
	 else Mask+=MModPreDec;
	 DecodeAdr(ArgStr[1],Mask);
	 switch (AdrMode)
          BEGIN
	   case ModReg:
	    CodeLen=2;
	    WAsmCode[0]=0x0300+AdrPart-(z << 1);
	    break;
	   case ModIReg:
	    CodeLen=4; WAsmCode[0]=0x0140;
	    WAsmCode[1]=0x6900+z+(AdrPart << 4);
	    break;
	   case ModPostInc:
           case ModPreDec:
	    CodeLen=4; WAsmCode[0]=0x0140;
	    WAsmCode[1]=0x6d00+z+(AdrPart << 4);
	    break;
	   case ModInd16:
	    CodeLen=6; WAsmCode[0]=0x0140; WAsmCode[2]=AdrVals[0];
	    WAsmCode[1]=0x6f00+z+(AdrPart << 4);
	    break;
	   case ModInd24:
	    CodeLen=10; WAsmCode[0]=0x0140; WAsmCode[1]=0x7800+(AdrPart << 4);
	    WAsmCode[2]=0x6b20+z; memcpy(WAsmCode+3,AdrVals,AdrCnt);
	    break;
	   case ModAbs16:
	    CodeLen=6; WAsmCode[0]=0x0140; WAsmCode[2]=AdrVals[0];
	    WAsmCode[1]=0x6b00+z;
	    break;
	   case ModAbs24:
	    CodeLen=8; WAsmCode[0]=0x0140; 
	    WAsmCode[1]=0x6b20+z; memcpy(WAsmCode+2,AdrVals,AdrCnt);
	    break;
	   case ModImm:
	    CodeLen=2; WAsmCode[0]=0x0700+Lo(AdrVals[0]);
	    break;
	  END
	END
      END
     return;
    END

   /* Arithmetik mit 2 Operanden */

   if ((Memo("ADD")) OR (Memo("SUB")))
    BEGIN
     z=Ord(Memo("SUB"));
     if (ArgCnt!=2) WrError(1110);
     else
      BEGIN
       DecodeAdr(ArgStr[2],MModReg);
       if (AdrMode!=ModNone)
	BEGIN
	 HReg=AdrPart;
	 DecodeAdr(ArgStr[1],MModReg+MModImm);
	 if (AdrMode!=ModNone)
	  if ((CPU16) AND ((OpSize>1) OR ((OpSize==1) AND (AdrMode==ModImm)))) WrError(1500);
	  else switch (AdrMode)
           BEGIN
	    case ModImm:
	     switch (OpSize)
              BEGIN
	       case 0:
                if (z==1) WrError(1350);
	        else
	         BEGIN
	          CodeLen=2; WAsmCode[0]=0x8000+(((Word)HReg) << 8)+Lo(AdrVals[0]);
	         END
                break;
	       case 1:
	        CodeLen=4; WAsmCode[1]=AdrVals[0];
	        WAsmCode[0]=0x7910+(z << 5)+HReg;
	        break;
	       case 2:
	        CodeLen=6; memcpy(WAsmCode+1,AdrVals,4);
	        WAsmCode[0]=0x7a10+(z << 5)+HReg;
	        break;
	      END
             break;
	    case ModReg:
	     switch (OpSize)
              BEGIN
	       case 0:
	        CodeLen=2; WAsmCode[0]=0x0800+(z << 12)+(AdrPart << 4)+HReg;
	        break;
	       case 1:
	        CodeLen=2; WAsmCode[0]=0x0900+(z << 12)+(AdrPart << 4)+HReg;
	        break;
	       case 2:
                CodeLen=2; WAsmCode[0]=0x0a00+(z << 12)+0x80+(AdrPart << 4)+HReg;
	        break;
	      END
	     break;
	   END
        END
      END
     return;
    END

   if (Memo("CMP"))
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else
      BEGIN
       DecodeAdr(ArgStr[2],MModReg);
       if (AdrMode!=ModNone)
	BEGIN
	 HReg=AdrPart;
	 DecodeAdr(ArgStr[1],MModReg+MModImm);
	 if (AdrMode!=ModNone)
	  if ((CPU16) AND ((OpSize>1) OR ((OpSize==1) AND (AdrMode==ModImm)))) WrError(1500);
	  else switch (AdrMode)
           BEGIN
	    case ModImm:
	     switch (OpSize)
              BEGIN
	       case 0:
	        CodeLen=2; WAsmCode[0]=0xa000+(((Word)HReg) << 8)+Lo(AdrVals[0]);
	        break;
	       case 1:
	        CodeLen=4; WAsmCode[1]=AdrVals[0];
	        WAsmCode[0]=0x7920+HReg;
	        break;
	       case 2:
	        CodeLen=6; memcpy(WAsmCode+1,AdrVals,4);
	        WAsmCode[0]=0x7a20+HReg;
	      END
	     break;
	    case ModReg:
	     switch (OpSize)
              BEGIN
	       case 0:
	        CodeLen=2; WAsmCode[0]=0x1c00+(AdrPart << 4)+HReg;
	        break;
	       case 1:
	        CodeLen=2; WAsmCode[0]=0x1d00+(AdrPart << 4)+HReg;
	        break;
	       case 2:
	        CodeLen=2; WAsmCode[0]=0x1f80+(AdrPart << 4)+HReg;
	        break;
	      END
             break;
	   END
	END
      END
     return;
    END

   for (z=0; z<LogicOrderCount; z++)
    if (strncmp(OpPart,LogicOrders[z].Name,strlen(LogicOrders[z].Name))==0)
     switch (OpPart[strlen(LogicOrders[z].Name)])
      BEGIN
       case '\0':
        if (ArgCnt!=2) WrError(1110);
        else
         BEGIN
          DecodeAdr(ArgStr[2],MModReg);
          if (AdrMode!=ModNone)
           if ((CPU16) AND (OpSize>0)) WrError(1500);
           else
            BEGIN
             HReg=AdrPart; DecodeAdr(ArgStr[1],MModImm+MModReg);
             switch (AdrMode)
              BEGIN
               case ModImm:
                switch (OpSize)
                 BEGIN
                  case 0:
                   CodeLen=2;
   	           WAsmCode[0]=0xc000+(((Word)LogicOrders[z].Code) << 12)+(((Word)HReg) << 8)+Lo(AdrVals[0]);
                   break;
                  case 1:
                   CodeLen=4; WAsmCode[1]=AdrVals[0];
                   WAsmCode[0]=0x7940+(((Word)LogicOrders[z].Code) << 4)+HReg;
                   break;
                  case 2:
                   CodeLen=6; memcpy(WAsmCode+1,AdrVals,AdrCnt);
                   WAsmCode[0]=0x7a40+(((Word)LogicOrders[z].Code) << 4)+HReg;
                   break;
                 END
                break;
               case ModReg:
                switch (OpSize)
                 BEGIN
                  case 0:
                   CodeLen=2; WAsmCode[0]=0x1400+(((Word)LogicOrders[z].Code) << 8)+(AdrPart << 4)+HReg;
                   break;
                  case 1:
                   CodeLen=2; WAsmCode[0]=0x6400+(((Word)LogicOrders[z].Code) << 8)+(AdrPart << 4)+HReg;
                   break;
                  case 2:
                   CodeLen=4; WAsmCode[0]=0x01f0;
	           WAsmCode[1]=0x6400+(((Word)LogicOrders[z].Code) << 8)+(AdrPart << 4)+HReg;
                   break;
                 END
                break;
              END
            END
         END
        return;
       case 'C':
        SetOpSize(0);
        if (ArgCnt!=2) WrError(1110);
        else if (strcasecmp(ArgStr[2],"CCR")!=0) WrError(1350);
        else
         BEGIN
          DecodeAdr(ArgStr[1],MModImm);
          if (AdrMode!=ModNone)
           BEGIN
            CodeLen=2;
            WAsmCode[0]=0x0400+(((Word)LogicOrders[z].Code) << 8)+Lo(AdrVals[0]);
           END
         END
        return;
      END

   if ((Memo("ADDX")) OR (Memo("SUBX")))
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else
      BEGIN
       DecodeAdr(ArgStr[2],MModReg);
       if (AdrMode!=ModNone)
	if (OpSize!=0) WrError(1130);
	else
         BEGIN
          HReg=AdrPart;
          DecodeAdr(ArgStr[1],MModImm+MModReg);
	  switch (AdrMode)
           BEGIN
            case ModImm:
             CodeLen=2; WAsmCode[0]=0x9000+(((Word)HReg) << 8)+Lo(AdrVals[0]);
             if (Memo("SUBX")) WAsmCode[0]+=0x2000;
             break;
            case ModReg:
             CodeLen=2; WAsmCode[0]=0x0e00+(AdrPart << 4)+HReg;
             if (Memo("SUBX")) WAsmCode[0]+=0x1000;
             break;
           END
         END
      END
     return;
    END

   if ((Memo("ADDS")) OR (Memo("SUBS")))
    BEGIN
     if (ArgCnt!=2) WrError(1110);
     else
      BEGIN
       DecodeAdr(ArgStr[2],MModReg);
       if (AdrMode!=ModNone)
        if (((CPU16) AND (OpSize!=1)) OR ((NOT CPU16) AND (OpSize!=2))) WrError(1130);
        else
         BEGIN
          HReg=AdrPart;
          DecodeAdr(ArgStr[1],MModImm);
          if (AdrMode!=ModNone)
           BEGIN
            AdrLong=ImmVal();
            if ((AdrLong!=1) AND (AdrLong!=2) AND (AdrLong!=4)) WrError(1320);
            else
             BEGIN
              switch (AdrLong)
               BEGIN
                case 1: WAsmCode[0]=0x0b00; break;
	        case 2: WAsmCode[0]=0x0b80; break;
	        case 4: WAsmCode[0]=0x0b90; break;
               END
              CodeLen=2; WAsmCode[0]+=HReg;
              if (Memo("SUBS")) WAsmCode[0]+=0x1000;
	     END
           END
         END
      END
     return;
    END

   for (z=0; z<MulOrderCount; z++)
    if (Memo(MulOrders[z].Name))
     BEGIN
      if (ArgCnt!=2) WrError(1110);
      else
       BEGIN
        if (OpSize!=-1) OpSize++;
        DecodeAdr(ArgStr[2],MModReg);
        if (AdrMode!=ModNone)
         if (OpSize==0) WrError(1130);
         else if ((CPU16) AND (OpSize==2)) WrError(1500);
         else
          BEGIN
           HReg=AdrPart; OpSize--;
           DecodeAdr(ArgStr[1],MModReg);
           if (AdrMode!=ModNone)
            BEGIN
             if ((MulOrders[z].Code & 2)==2)
              BEGIN
               CodeLen=4; WAsmCode[0]=0x01c0;
  	       if ((MulOrders[z].Code & 1)==1) WAsmCode[0]+=0x10;
              END
             else CodeLen=2;
             WAsmCode[CodeLen >> 2]=0x5000
                              +(((Word)OpSize) << 9)
			      +(((Word)MulOrders[z].Code & 1) << 8)
			      +(AdrPart << 4)+HReg;
            END
          END
       END
      return;
     END

   /* Bitoperationen */

   for (z=0; z<Bit1OrderCount; z++)
    if (Memo(Bit1Orders[z].Name))
     BEGIN
      OpCode=0x60+(Bit1Orders[z].Code & 0x7f);
      if (ArgCnt!=2) WrError(1110);
      else
       BEGIN
        if (*ArgStr[1]!='#') WrError(1350);
        else
         BEGIN
          HReg=EvalIntExpression(ArgStr[1]+1,UInt3,&OK);
          if (OK)
           BEGIN
            DecodeAdr(ArgStr[2],MModReg+MModIReg+MModAbs8);
            if (AdrMode!=ModNone)
             if (OpSize>0) WrError(1130);
             else switch (AdrMode)
              BEGIN
               case ModReg:
       	        CodeLen=2;
       	        WAsmCode[0]=(((Word)OpCode) << 8)+(Bit1Orders[z].Code & 0x80)+(HReg << 4)+AdrPart;
                break;
               case ModIReg:
                CodeLen=4;
                WAsmCode[0]=0x7c00+(AdrPart << 4);
                WAsmCode[1]=(((Word)OpCode) << 8)+(Bit1Orders[z].Code & 0x80)+(HReg << 4);
                if (OpCode<0x70) WAsmCode[0]+=0x100;
                break;
               case ModAbs8:
                CodeLen=4;
                WAsmCode[0]=0x7e00+Lo(AdrVals[0]);
                WAsmCode[1]=(((Word)OpCode) << 8)+(Bit1Orders[z].Code & 0x80)+(HReg << 4);
                if (OpCode<0x70) WAsmCode[0]+=0x100;
                break;
              END
           END
         END
       END
      return;
     END

   for (z=0; z<Bit2OrderCount; z++)
    if (Memo(Bit2Orders[z].Name))
     BEGIN
      if (ArgCnt!=2) WrError(1110);
      else
       BEGIN
        if (*ArgStr[1]=='#')
         BEGIN
          OpCode=Bit2Orders[z].Code+0x70;
          HReg=EvalIntExpression(ArgStr[1]+1,UInt3,&OK);
         END
        else
         BEGIN
          OpCode=Bit2Orders[z].Code+0x60;
          OK=DecodeReg(ArgStr[1],&HReg,&HSize);
          if (NOT OK) WrError(1350);
          if ((OK) AND (HSize!=0))
           BEGIN
            WrError(1130); OK=False;
           END
         END
        if (OK)
         BEGIN
          DecodeAdr(ArgStr[2],MModReg+MModIReg+MModAbs8);
          if (AdrMode!=ModNone)
           if (OpSize>0) WrError(1130);
           else switch (AdrMode)
            BEGIN
             case ModReg:
              CodeLen=2;
              WAsmCode[0]=(((Word)OpCode) << 8)+(HReg << 4)+AdrPart;
              break;
             case ModIReg:
              CodeLen=4;
              WAsmCode[0]=0x7d00+(AdrPart << 4);
              WAsmCode[1]=(((Word)OpCode) << 8)+(HReg << 4);
              if (Bit2Orders[z].Code==3) WAsmCode[0]-=0x100;
              break;
             case ModAbs8:
              CodeLen=4;
              WAsmCode[0]=0x7f00+Lo(AdrVals[0]);
              WAsmCode[1]=(((Word)OpCode) << 8)+(HReg << 4);
              if (Bit2Orders[z].Code==3) WAsmCode[0]-=0x100;
              break;
            END
         END
       END
      return;
     END

   /* Read/Modify/Write-Operationen */

   if ((Memo("INC")) OR (Memo("DEC")))
    BEGIN
     if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
     else
      BEGIN
       DecodeAdr(ArgStr[ArgCnt],MModReg);
       if (AdrMode!=ModNone)
	if ((OpSize>0) AND (CPU16)) WrError(1500);
	else
	 BEGIN
	  HReg=AdrPart;
	  if (ArgCnt==1)
	   BEGIN
	    OK=True; z=1;
	   END
	  else
	   BEGIN
	    DecodeAdr(ArgStr[1],MModImm);
	    OK=(AdrMode==ModImm);
	    if (OK)
	     BEGIN
	      z=ImmVal();
	      if (z<1)
	       BEGIN
		WrError(1315); OK=False;
	       END
	      else if (((OpSize==0) AND (z>1)) OR (z>2))
	       BEGIN
		WrError(1320); OK=False;
	       END
	     END
	   END
	  if (OK)
	   BEGIN
	    CodeLen=2; z--;
	    switch (OpSize)
             BEGIN
	      case 0:WAsmCode[0]=0x0a00+HReg; break;
	      case 1:WAsmCode[0]=0x0b50+HReg+(z << 7); break;
	      case 2:WAsmCode[0]=0x0b70+HReg+(z << 7);
	     END
	    if (Memo("DEC")) WAsmCode[0]+=0x1000;
	   END
	 END
      END
     return;
    END

   for (z=0; z<ShiftOrderCount; z++)
    if (Memo(ShiftOrders[z].Name))
     BEGIN
      if (ArgCnt!=1) WrError(1110);
      else
       BEGIN
        DecodeAdr(ArgStr[1],MModReg);
        if (AdrMode!=ModNone)
         if ((OpSize>0) AND (CPU16)) WrError(1500);
         else
          BEGIN
           CodeLen=2;
           switch (OpSize)
            BEGIN
             case 0: WAsmCode[0]=ShiftOrders[z].Code+AdrPart; break;
             case 1: WAsmCode[0]=ShiftOrders[z].Code+AdrPart+0x10; break;
             case 2: WAsmCode[0]=ShiftOrders[z].Code+AdrPart+0x30; break;
            END
          END
       END
      return;
     END

   if ((Memo("NEG")) OR (Memo("NOT")))
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else
      BEGIN
       DecodeAdr(ArgStr[1],MModReg);
       if (AdrMode!=ModNone)
	if ((OpSize>0) AND (CPU16)) WrError(1500);
	else
	 BEGIN
	  CodeLen=2;
	  switch (OpSize)
           BEGIN
	    case 0:WAsmCode[0]=0x1700+AdrPart; break;
	    case 1:WAsmCode[0]=0x1710+AdrPart; break;
	    case 2:WAsmCode[0]=0x1730+AdrPart; break;
	   END
	  if (Memo("NEG")) WAsmCode[0]+=0x80;
	 END
      END
     return;
    END

   if ((Memo("EXTS")) OR (Memo("EXTU")))
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else if (CPU16) WrError(1500);
     else
      BEGIN
       DecodeAdr(ArgStr[1],MModReg);
       if (AdrMode!=ModNone)
	if ((OpSize!=1) AND (OpSize!=2)) WrError(1130);
	else
	 BEGIN
	  CodeLen=2;
	  switch (OpSize)
           BEGIN
	    case 1: WAsmCode[0]=(Memo("EXTS")) ? 0x17d0 : 0x1750; break;
	    case 2: WAsmCode[0]=(Memo("EXTS")) ? 0x17f0 : 0x1770; break;
	   END
	  WAsmCode[0]+=AdrPart;
	 END
      END
     return;
    END

   if ((Memo("DAA")) OR (Memo("DAS")))
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else
      BEGIN
       DecodeAdr(ArgStr[1],MModReg);
       if (AdrMode!=ModNone)
        if (OpSize!=0) WrError(1130);
        else
         BEGIN
          CodeLen=2;
          WAsmCode[0]=0x0f00+AdrPart;
          if (Memo("DAS")) WAsmCode[0]+=0x1000;
         END
      END
     return;
    END

   /* Spruenge */

   for (z=0; z<ConditionCount; z++)
    if (Memo(Conditions[z].Name))
     BEGIN
      if (ArgCnt!=1) WrError(1110);
      else if ((OpSize!=-1) AND (OpSize!=4) AND (OpSize!=2)) WrError(1130);
      else
       BEGIN
        AdrLong=EvalIntExpression(ArgStr[1],Int24,&OK)-(EProgCounter()+2);
        if (OK)
         BEGIN
          if (OpSize==-1)
          if ((AdrLong>=-128) AND (AdrLong<=127)) OpSize=4;
          else
           BEGIN
            OpSize=2; AdrLong-=2;
           END
          else if (OpSize==2) AdrLong-=2;
          if (OpSize==2)
           BEGIN
            if ((NOT SymbolQuestionable) AND ((AdrLong<-32768) OR (AdrLong>32767))) WrError(1370);
            else if (CPU16) WrError(1500);
            else
             BEGIN
              CodeLen=4;
              WAsmCode[0]=0x5800+(Conditions[z].Code << 4); WAsmCode[1]=AdrLong & 0xffff;
             END
           END
          else
           BEGIN
            if ((NOT SymbolQuestionable) AND ((AdrLong<-128) OR (AdrLong>127))) WrError(1370);
            else
             BEGIN
              CodeLen=2;
              WAsmCode[0]=0x4000+(((Word)Conditions[z].Code) << 8)+(AdrLong & 0xff);
             END
           END
         END
       END
      return;
     END

   if ((Memo("JMP")) OR (Memo("JSR")))
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else
      BEGIN
       z=Ord(Memo("JSR")) << 10;
       DecodeAdr(ArgStr[1],MModIReg+((CPU16)?MModAbs16:MModAbs24)+MModIIAbs);
       switch (AdrMode)
        BEGIN
         case ModIReg:
	  CodeLen=2; WAsmCode[0]=0x5900+z+(AdrPart << 4);
	  break;
         case ModAbs16:
	  CodeLen=4; WAsmCode[0]=0x5a00+z; WAsmCode[1]=AdrVals[0];
	  break;
         case ModAbs24:
	  CodeLen=4; WAsmCode[0]=0x5a00+z+Lo(AdrVals[0]);
	  WAsmCode[1]=AdrVals[1];
	  break;
         case ModIIAbs:
	  CodeLen=2; WAsmCode[0]=0x5b00+z+Lo(AdrVals[0]);
	  break;
        END
      END
     return;
    END

   if (Memo("BSR"))
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else if ((OpSize!=-1) AND (OpSize!=4) AND (OpSize!=2)) WrError(1130);
     else
      BEGIN
       AdrLong=EvalIntExpression(ArgStr[1],Int24,&OK)-(EProgCounter()+2);
       if (OK)
	BEGIN
	 if (OpSize==-1)
	 if ((AdrLong>=-128) AND (AdrLong<=127)) OpSize=4;
	 else
	  BEGIN
	   OpSize=2; AdrLong-=2;
	  END
	 else if (OpSize==2) AdrLong-=2;
	 if (OpSize==2)
	  BEGIN
	   if ((NOT SymbolQuestionable) AND ((AdrLong<-32768) OR (AdrLong>32767))) WrError(1370);
	   else if (CPU16) WrError(1500);
	   else
	    BEGIN
	     CodeLen=4;
	     WAsmCode[0]=0x5c00; WAsmCode[1]=AdrLong & 0xffff;
	    END
	  END
	 else
	  BEGIN
	   if ((AdrLong<-128) OR (AdrLong>127)) WrError(1370);
	   else
	    BEGIN
	     CodeLen=2;
	     WAsmCode[0]=0x5500+(AdrLong & 0xff);
	    END
	  END
	END
      END
     return;
    END

   if (Memo("TRAPA"))
    BEGIN
     if (ArgCnt!=1) WrError(1110);
     else if (MomCPU<CPU6413309) WrError(1500);
     else
      BEGIN
       if (*ArgStr[1]=='#') strcpy(ArgStr[1],ArgStr[1]+1);
       WAsmCode[0]=EvalIntExpression(ArgStr[1],UInt2,&OK)<<4;
       if (OK)
        BEGIN
         WAsmCode[0]+=0x5700; CodeLen=2;
        END
      END
     return;
    END

   WrXError(1200,OpPart);
END

	static Boolean IsDef_H8_3(void)
BEGIN
   return False;
END

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

	static void SwitchTo_H8_3(void)
BEGIN
   TurnWords=True; ConstMode=ConstModeMoto; SetIsOccupied=False;

   PCSymbol="*"; HeaderID=0x68; NOPCode=0x0000;
   DivideChars=","; HasAttrs=True; AttrChars=".";

   ValidSegs=1<<SegCode;
   Grans[SegCode]=1; ListGrans[SegCode]=2; SegInits[SegCode]=0;
   SegLimits[SegCode] = (MomCPU <= CPUH8_300) ? 0xffff : 0xffffffl;

   MakeCode=MakeCode_H8_3; IsDef=IsDef_H8_3;
   SwitchFrom=SwitchFrom_H8_3; InitFields();
   AddONOFF("MAXMODE", &Maximum   , MaximumName   ,False);
   AddONOFF("PADDING", &DoPadding , DoPaddingName ,False);
   AddMoto16PseudoONOFF();

   CPU16=(MomCPU<=CPUH8_300);

   SetFlag(&DoPadding,DoPaddingName,False);
END

	void codeh8_3_init(void)
BEGIN
   CPUH8_300L=AddCPU("H8/300L"   ,SwitchTo_H8_3);
   CPU6413308=AddCPU("HD6413308" ,SwitchTo_H8_3);
   CPUH8_300 =AddCPU("H8/300"    ,SwitchTo_H8_3);
   CPU6413309=AddCPU("HD6413309" ,SwitchTo_H8_3);
   CPUH8_300H=AddCPU("H8/300H"   ,SwitchTo_H8_3);
END
