dect
/
asl
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asl/code6816.c

1074 lines
35 KiB
C

/* code6816.c */
/*****************************************************************************/
/* AS-Portierung */
/* */
/* Codegeneratormodul CPU16 */
/* */
/* Historie: 15.10.1996 Grundsteinlegung */
/* 2. 1.1999 ChkPC-Anpassung */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include "nls.h"
#include "bpemu.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "codepseudo.h"
#include "codevars.h"
/*---------------------------------------------------------------------------*/
typedef struct
{
char *Name;
Word Code;
} FixedOrder;
typedef struct
{
char *Name;
ShortInt Size;
Word Code,ExtCode;
Byte AdrMask,ExtShift;
} GenOrder;
typedef struct
{
char *Name;
Word Code1,Code2;
} EmuOrder;
#define FixedOrderCnt 140
#define RelOrderCnt 18
#define LRelOrderCnt 3
#define GenOrderCnt 66
#define AuxOrderCnt 12
#define ImmOrderCnt 4
#define ExtOrderCnt 3
#define EmuOrderCnt 6
#define RegCnt 7
#define ModNone (-1)
#define ModDisp8 0
#define MModDisp8 (1 << ModDisp8)
#define ModDisp16 1
#define MModDisp16 (1 << ModDisp16)
#define ModDispE 2
#define MModDispE (1 << ModDispE)
#define ModAbs 3
#define MModAbs (1 << ModAbs)
#define ModImm 4
#define MModImm (1 << ModImm)
#define ModImmExt 5
#define MModImmExt (1 << ModImmExt)
#define ModDisp20 ModDisp16
#define MModDisp20 MModDisp16
#define ModAbs20 ModAbs
#define MModAbs20 MModAbs
static ShortInt OpSize;
static ShortInt AdrMode;
static Byte AdrPart;
static Byte AdrVals[4];
static LongInt Reg_EK;
static SimpProc SaveInitProc;
static FixedOrder *FixedOrders;
static FixedOrder *RelOrders;
static FixedOrder *LRelOrders;
static GenOrder *GenOrders;
static FixedOrder *AuxOrders;
static FixedOrder *ImmOrders;
static FixedOrder *ExtOrders;
static EmuOrder *EmuOrders;
static char **Regs;
static CPUVar CPU6816;
/*-------------------------------------------------------------------------*/
static void AddFixed(char *NName, Word NCode)
BEGIN
if (InstrZ>=FixedOrderCnt) exit(255);
FixedOrders[InstrZ].Name=NName;
FixedOrders[InstrZ++].Code=NCode;
END
static void AddRel(char *NName, Word NCode)
BEGIN
if (InstrZ>=RelOrderCnt) exit(255);
RelOrders[InstrZ].Name=NName;
RelOrders[InstrZ++].Code=NCode;
END
static void AddLRel(char *NName, Word NCode)
BEGIN
if (InstrZ>=LRelOrderCnt) exit(255);
LRelOrders[InstrZ].Name=NName;
LRelOrders[InstrZ++].Code=NCode;
END
static void AddGen(char *NName, ShortInt NSize, Word NCode,
Word NExtCode, Byte NShift, Byte NMask)
BEGIN
if (InstrZ>=GenOrderCnt) exit(255);
GenOrders[InstrZ].Name=NName;
GenOrders[InstrZ].Code=NCode;
GenOrders[InstrZ].ExtCode=NExtCode;
GenOrders[InstrZ].Size=NSize;
GenOrders[InstrZ].AdrMask=NMask;
GenOrders[InstrZ++].ExtShift=NShift;
END
static void AddAux(char *NName, Word NCode)
BEGIN
if (InstrZ>=AuxOrderCnt) exit(255);
AuxOrders[InstrZ].Name=NName;
AuxOrders[InstrZ++].Code=NCode;
END
static void AddImm(char *NName, Word NCode)
BEGIN
if (InstrZ>=ImmOrderCnt) exit(255);
ImmOrders[InstrZ].Name=NName;
ImmOrders[InstrZ++].Code=NCode;
END
static void AddExt(char *NName, Word NCode)
BEGIN
if (InstrZ>=ExtOrderCnt) exit(255);
ExtOrders[InstrZ].Name=NName;
ExtOrders[InstrZ++].Code=NCode;
END
static void AddEmu(char *NName, Word NCode1, Word NCode2)
BEGIN
if (InstrZ>=EmuOrderCnt) exit(255);
EmuOrders[InstrZ].Name=NName;
EmuOrders[InstrZ].Code1=NCode1;
EmuOrders[InstrZ++].Code2=NCode2;
END
static void InitFields(void)
BEGIN
FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ=0;
AddFixed("ABA" ,0x370b); AddFixed("ABX" ,0x374f);
AddFixed("ABY" ,0x375f); AddFixed("ABZ" ,0x376f);
AddFixed("ACE" ,0x3722); AddFixed("ACED" ,0x3723);
AddFixed("ADE" ,0x2778); AddFixed("ADX" ,0x37cd);
AddFixed("ADY" ,0x37dd); AddFixed("ADZ" ,0x37ed);
AddFixed("AEX" ,0x374d); AddFixed("AEY" ,0x375d);
AddFixed("AEZ" ,0x376d); AddFixed("ASLA" ,0x3704);
AddFixed("ASLB" ,0x3714); AddFixed("ASLD" ,0x27f4);
AddFixed("ASLE" ,0x2774); AddFixed("ASLM" ,0x27b6);
AddFixed("LSLB" ,0x3714); AddFixed("LSLD" ,0x27f4);
AddFixed("LSLE" ,0x2774); AddFixed("LSLA" ,0x3704);
AddFixed("ASRA" ,0x370d); AddFixed("ASRB" ,0x371d);
AddFixed("ASRD" ,0x27fd); AddFixed("ASRE" ,0x277d);
AddFixed("ASRM" ,0x27ba); AddFixed("BGND" ,0x37a6);
AddFixed("CBA" ,0x371b); AddFixed("CLRA" ,0x3705);
AddFixed("CLRB" ,0x3715); AddFixed("CLRD" ,0x27f5);
AddFixed("CLRE" ,0x2775); AddFixed("CLRM" ,0x27b7);
AddFixed("COMA" ,0x3700); AddFixed("COMB" ,0x3710);
AddFixed("COMD" ,0x27f0); AddFixed("COME" ,0x2770);
AddFixed("DAA" ,0x3721); AddFixed("DECA" ,0x3701);
AddFixed("DECB" ,0x3711); AddFixed("EDIV" ,0x3728);
AddFixed("EDIVS" ,0x3729); AddFixed("EMUL" ,0x3725);
AddFixed("EMULS" ,0x3726); AddFixed("FDIV" ,0x372b);
AddFixed("FMULS" ,0x3727); AddFixed("IDIV" ,0x372a);
AddFixed("INCA" ,0x3703); AddFixed("INCB" ,0x3713);
AddFixed("LPSTOP",0x27f1); AddFixed("LSRA" ,0x370f);
AddFixed("LSRB" ,0x371f); AddFixed("LSRD" ,0x27ff);
AddFixed("LSRE" ,0x277f); AddFixed("MUL" ,0x3724);
AddFixed("NEGA" ,0x3702); AddFixed("NEGB" ,0x3712);
AddFixed("NEGD" ,0x27f2); AddFixed("NEGE" ,0x2772);
AddFixed("NOP" ,0x274c); AddFixed("PSHA" ,0x3708);
AddFixed("PSHB" ,0x3718); AddFixed("PSHMAC",0x27b8);
AddFixed("PULA" ,0x3709); AddFixed("PULB" ,0x3719);
AddFixed("PULMAC",0x27b9); AddFixed("ROLA" ,0x370c);
AddFixed("ROLB" ,0x371c); AddFixed("ROLD" ,0x27fc);
AddFixed("ROLE" ,0x277c); AddFixed("RORA" ,0x370e);
AddFixed("RORB" ,0x371e); AddFixed("RORD" ,0x27fe);
AddFixed("RORE" ,0x277e); AddFixed("RTI" ,0x2777);
AddFixed("RTS" ,0x27f7); AddFixed("SBA" ,0x370a);
AddFixed("SDE" ,0x2779); AddFixed("SWI" ,0x3720);
AddFixed("SXT" ,0x27f8); AddFixed("TAB" ,0x3717);
AddFixed("TAP" ,0x37fd); AddFixed("TBA" ,0x3707);
AddFixed("TBEK" ,0x27fa); AddFixed("TBSK" ,0x379f);
AddFixed("TBXK" ,0x379c); AddFixed("TBYK" ,0x379d);
AddFixed("TBZK" ,0x379e); AddFixed("TDE" ,0x277b);
AddFixed("TDMSK" ,0x372f); AddFixed("TDP" ,0x372d);
AddFixed("TED" ,0x27fb); AddFixed("TEDM" ,0x27b1);
AddFixed("TEKB" ,0x27bb); AddFixed("TEM" ,0x27b2);
AddFixed("TMER" ,0x27b4); AddFixed("TMET" ,0x27b5);
AddFixed("TMXED" ,0x27b3); AddFixed("TPA" ,0x37fc);
AddFixed("TPD" ,0x372c); AddFixed("TSKB" ,0x37af);
AddFixed("TSTA" ,0x3706); AddFixed("TSTB" ,0x3716);
AddFixed("TSTD" ,0x27f6); AddFixed("TSTE" ,0x2776);
AddFixed("TSX" ,0x274f); AddFixed("TSY" ,0x275f);
AddFixed("TSZ" ,0x276f); AddFixed("TXKB" ,0x37ac);
AddFixed("TXS" ,0x374e); AddFixed("TXY" ,0x275c);
AddFixed("TXZ" ,0x276c); AddFixed("TYKB" ,0x37ad);
AddFixed("TYS" ,0x375e); AddFixed("TYX" ,0x274d);
AddFixed("TYZ" ,0x276d); AddFixed("TZKB" ,0x37ae);
AddFixed("TZS" ,0x376e); AddFixed("TZX" ,0x274e);
AddFixed("TZY" ,0x275e); AddFixed("WAI" ,0x27f3);
AddFixed("XGAB" ,0x371a); AddFixed("XGDE" ,0x277a);
AddFixed("XGDX" ,0x37cc); AddFixed("XGDY" ,0x37dc);
AddFixed("XGDZ" ,0x37ec); AddFixed("XGEX" ,0x374c);
AddFixed("XGEY" ,0x375c); AddFixed("XGEZ" ,0x376c);
AddFixed("DES" ,0x3fff); AddFixed("INS" ,0x3f01);
AddFixed("DEX" ,0x3cff); AddFixed("INX" ,0x3c01);
AddFixed("DEY" ,0x3dff); AddFixed("INY" ,0x3d01);
AddFixed("PSHX" ,0x3404); AddFixed("PULX" ,0x3510);
AddFixed("PSHY" ,0x3408); AddFixed("PULY" ,0x3508);
RelOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*RelOrderCnt); InstrZ=0;
AddRel("BCC", 4); AddRel("BCS", 5); AddRel("BEQ", 7);
AddRel("BGE",12); AddRel("BGT",14); AddRel("BHI", 2);
AddRel("BLE",15); AddRel("BLS", 3); AddRel("BLT",13);
AddRel("BMI",11); AddRel("BNE", 6); AddRel("BPL",10);
AddRel("BRA", 0); AddRel("BRN", 1); AddRel("BVC", 8);
AddRel("BVS", 9); AddRel("BHS", 4); AddRel("BLO", 5);
LRelOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*LRelOrderCnt); InstrZ=0;
AddLRel("LBEV",0x3791); AddLRel("LBMV",0x3790); AddLRel("LBSR",0x27f9);
GenOrders=(GenOrder *) malloc(sizeof(GenOrder)*GenOrderCnt); InstrZ=0;
AddGen("ADCA",0,0x43,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("ADCB",0,0xc3,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("ADCD",1,0x83,0xffff,0x20,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("ADCE",1,0x03,0xffff,0x20, MModImm+ MModDisp16+MModAbs );
AddGen("ADDA",0,0x41,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("ADDB",0,0xc1,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("ADDD",1,0x81, 0xfc,0x20,MModDisp8+MModImm+MModImmExt+MModDisp16+MModAbs+MModDispE);
AddGen("ADDE",1,0x01, 0x7c,0x20, MModImm+MModImmExt+MModDisp16+MModAbs );
AddGen("ANDA",0,0x46,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("ANDB",0,0xc6,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("ANDD",1,0x86,0xffff,0x20,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("ANDE",1,0x06,0xffff,0x20, MModImm+ MModDisp16+MModAbs );
AddGen("ASL" ,0,0x04,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("ASLW",0,0x04,0xffff,0x10, MModDisp16+MModAbs );
AddGen("LSL" ,0,0x04,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("LSLW",0,0x04,0xffff,0x10, MModDisp16+MModAbs );
AddGen("ASR" ,0,0x0d,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("ASRW",0,0x0d,0xffff,0x10, MModDisp16+MModAbs );
AddGen("BITA",0,0x49,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("BITB",0,0xc9,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("CLR" ,0,0x05,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("CLRW",0,0x05,0xffff,0x10, MModDisp16+MModAbs );
AddGen("CMPA",0,0x48,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("CMPB",0,0xc8,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("COM" ,0,0x00,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("COMW",0,0x00,0xffff,0x10, MModDisp16+MModAbs );
AddGen("CPD" ,1,0x88,0xffff,0x20,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("CPE" ,1,0x08,0xffff,0x20, MModImm+ MModDisp16+MModAbs );
AddGen("DEC" ,0,0x01,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("DECW",0,0x01,0xffff,0x10, MModDisp16+MModAbs );
AddGen("EORA",0,0x44,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("EORB",0,0xc4,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("EORD",1,0x84,0xffff,0x20,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("EORE",1,0x04,0xffff,0x20, MModImm+ MModDisp16+MModAbs );
AddGen("INC" ,0,0x03,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("INCW",0,0x03,0xffff,0x10, MModDisp16+MModAbs );
AddGen("LDAA",0,0x45,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("LDAB",0,0xc5,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("LDD" ,1,0x85,0xffff,0x20,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("LDE" ,1,0x05,0xffff,0x20, MModImm+ MModDisp16+MModAbs );
AddGen("LSR" ,0,0x0f,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("LSRW",0,0x0f,0xffff,0x10, MModDisp16+MModAbs );
AddGen("NEG" ,0,0x02,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("NEGW",0,0x02,0xffff,0x10, MModDisp16+MModAbs );
AddGen("ORAA",0,0x47,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("ORAB",0,0xc7,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("ORD" ,1,0x87,0xffff,0x20,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("ORE" ,1,0x07,0xffff,0x20, MModImm+ MModDisp16+MModAbs );
AddGen("ROL" ,0,0x0c,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("ROLW",0,0x0c,0xffff,0x10, MModDisp16+MModAbs );
AddGen("ROR" ,0,0x0e,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("RORW",0,0x0e,0xffff,0x10, MModDisp16+MModAbs );
AddGen("SBCA",0,0x42,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("SBCB",0,0xc2,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("SBCD",1,0x82,0xffff,0x20,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("SBCE",1,0x02,0xffff,0x20, MModImm+ MModDisp16+MModAbs );
AddGen("STAA",0,0x4a,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs+MModDispE);
AddGen("STAB",0,0xca,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs+MModDispE);
AddGen("STD" ,1,0x8a,0xffff,0x20,MModDisp8+ MModDisp16+MModAbs+MModDispE);
AddGen("STE" ,1,0x0a,0xffff,0x20, MModDisp16+MModAbs );
AddGen("SUBA",0,0x40,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("SUBB",0,0xc0,0xffff,0x00,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("SUBD",1,0x80,0xffff,0x20,MModDisp8+MModImm+ MModDisp16+MModAbs+MModDispE);
AddGen("SUBE",1,0x00,0xffff,0x20, MModImm+ MModDisp16+MModAbs );
AddGen("TST" ,0,0x06,0xffff,0x00,MModDisp8+ MModDisp16+MModAbs );
AddGen("TSTW",0,0x06,0xffff,0x10, MModDisp16+MModAbs );
AuxOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*AuxOrderCnt); InstrZ=0;
AddAux("CPS",0x4f); AddAux("CPX",0x4c); AddAux("CPY",0x4d); AddAux("CPZ",0x4e);
AddAux("LDS",0xcf); AddAux("LDX",0xcc); AddAux("LDY",0xcd); AddAux("LDZ",0xce);
AddAux("STS",0x8f); AddAux("STX",0x8c); AddAux("STY",0x8d); AddAux("STZ",0x8e);
ImmOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*ImmOrderCnt); InstrZ=0;
AddImm("AIS",0x3f); AddImm("AIX",0x3c); AddImm("AIY",0x3d); AddImm("AIZ",0x3e);
ExtOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*ExtOrderCnt); InstrZ=0;
AddExt("LDED",0x2771); AddExt("LDHI",0x27b0);AddExt("STED",0x2773);
EmuOrders=(EmuOrder *) malloc(sizeof(EmuOrder)*EmuOrderCnt); InstrZ=0;
AddEmu("CLC",0x373a,0xfeff); AddEmu("CLI",0x373a,0xff1f); AddEmu("CLV",0x373a,0xfdff);
AddEmu("SEC",0x373b,0x0100); AddEmu("SEI",0x373b,0x00e0); AddEmu("SEV",0x373b,0x0200);
Regs=(char **) malloc(sizeof(char *)*RegCnt);
Regs[0]="D"; Regs[1]="E"; Regs[2]="X"; Regs[3]="Y";
Regs[4]="Z"; Regs[5]="K"; Regs[6]="CCR";
END
static void DeinitFields(void)
BEGIN
free(FixedOrders);
free(RelOrders);
free(LRelOrders);
free(GenOrders);
free(AuxOrders);
free(ImmOrders);
free(ExtOrders);
free(EmuOrders);
free(Regs);
END
/*-------------------------------------------------------------------------*/
typedef enum {ShortDisp,LongDisp,NoDisp} DispType;
static void ChkAdr(Byte Mask)
BEGIN
if ((AdrMode!=ModNone) AND ((Mask AND (1 << AdrMode))==0))
BEGIN
WrError(1350);
AdrMode=ModNone; AdrCnt=0;
END
END
static void SplitSize(char *Asc, DispType *Erg)
BEGIN
if (strlen(Asc)<1) *Erg=NoDisp;
else if (*Asc=='>') *Erg=LongDisp;
else if (*Asc=='<') *Erg=ShortDisp;
else *Erg=NoDisp;
END
static void DecodeAdr(int Start, int Stop, Boolean LongAdr, Byte Mask)
BEGIN
Integer V16;
LongInt V32;
Boolean OK;
String s;
DispType Size;
AdrMode=ModNone; AdrCnt=0;
Stop-=Start-1;
if (Stop<1)
BEGIN
WrError(1110); return;
END
/* immediate ? */
if (*ArgStr[Start]=='#')
BEGIN
strmaxcpy(s,ArgStr[Start]+1,255); SplitSize(s,&Size);
switch (OpSize)
BEGIN
case -1: WrError(1132); break;
case 0:
AdrVals[0]=EvalIntExpression(s,Int8,&OK);
if (OK)
BEGIN
AdrCnt=1; AdrMode=ModImm;
END
break;
case 1:
V16=EvalIntExpression(s,(Size==ShortDisp)?SInt8:Int16,&OK);
if ((Size==NoDisp) AND (V16>=-128) AND (V16<=127) AND ((Mask & MModImmExt)!=0))
Size=ShortDisp;
if (OK)
if (Size==ShortDisp)
BEGIN
AdrVals[0]=Lo(V16);
AdrCnt=1; AdrMode=ModImmExt;
END
else
BEGIN
AdrVals[0]=Hi(V16);
AdrVals[1]=Lo(V16);
AdrCnt=2; AdrMode=ModImm;
END
break;
case 2:
V32=EvalIntExpression(s,Int32,&OK);
if (OK)
BEGIN
AdrVals[0]=(V32 >> 24) & 0xff;
AdrVals[1]=(V32 >> 16) & 0xff;
AdrVals[2]=(V32 >> 8) & 0xff;
AdrVals[3]=V32 & 0xff;
AdrCnt=4; AdrMode=ModImm;
END
break;
END
ChkAdr(Mask); return;
END
/* zusammengesetzt ? */
if (Stop==2)
BEGIN
AdrPart=0xff;
if (strcasecmp(ArgStr[Start+1],"X")==0) AdrPart=0x00;
else if (strcasecmp(ArgStr[Start+1],"Y")==0) AdrPart=0x10;
else if (strcasecmp(ArgStr[Start+1],"Z")==0) AdrPart=0x20;
else WrXError(1445,ArgStr[Start+1]);
if (AdrPart!=0xff)
if (strcasecmp(ArgStr[Start],"E")==0) AdrMode=ModDispE;
else
BEGIN
SplitSize(ArgStr[Start],&Size);
if (Size==ShortDisp)
V32=EvalIntExpression(ArgStr[Start],UInt8,&OK);
else if (LongAdr)
V32=EvalIntExpression(ArgStr[Start],SInt20,&OK);
else
V32=EvalIntExpression(ArgStr[Start],SInt16,&OK);
if (OK)
BEGIN
if (Size==NoDisp)
if ((V32>=0) AND (V32<=255) AND ((Mask & MModDisp8)!=0)) Size=ShortDisp;
if (Size==ShortDisp)
BEGIN
AdrVals[0]=V32 & 0xff;
AdrCnt=1; AdrMode=ModDisp8;
END
else if (LongAdr)
BEGIN
AdrVals[0]=(V32 >> 16) & 0x0f;
AdrVals[1]=(V32 >> 8) & 0xff;
AdrVals[2]=V32 & 0xff;
AdrCnt=3; AdrMode=ModDisp16;
END
else
BEGIN
AdrVals[0]=(V32 >> 8) & 0xff;
AdrVals[1]=V32 & 0xff;
AdrCnt=2; AdrMode=ModDisp16;
END
END
END
ChkAdr(Mask); return;
END
/* absolut ? */
else
BEGIN
SplitSize(ArgStr[Start],&Size);
V32=EvalIntExpression(ArgStr[Start],UInt20,&OK);
if (OK)
if (LongAdr)
BEGIN
AdrVals[0]=(V32 >> 16) & 0xff;
AdrVals[1]=(V32 >> 8) & 0xff;
AdrVals[2]=V32 & 0xff;
AdrMode=ModAbs; AdrCnt=3;
END
else
BEGIN
if ((V32 >> 16)!=Reg_EK) WrError(110);
AdrVals[0]=(V32 >> 8) & 0xff;
AdrVals[1]=V32 & 0xff;
AdrMode=ModAbs; AdrCnt=2;
END
ChkAdr(Mask); return;
END
END
/*-------------------------------------------------------------------------*/
static Boolean DecodePseudo(void)
BEGIN
#define ASSUME6816Count 1
static ASSUMERec ASSUME6816s[ASSUME6816Count]=
{{"EK" , &Reg_EK , 0 , 0xff , 0x100}};
if (Memo("ASSUME"))
BEGIN
CodeASSUME(ASSUME6816s,ASSUME6816Count);
return True;
END
return False;
END
static void MakeCode_6816(void)
BEGIN
int z,z2;
Boolean OK;
Byte Mask;
LongInt AdrLong;
CodeLen=0; DontPrint=False; AdrCnt=0; OpSize=(-1);
/* zu ignorierendes */
if (Memo("")) return;
/* Pseudoanweisungen */
if (DecodePseudo()) return;
if (DecodeMotoPseudo(True)) return;
/* Anweisungen ohne Argument */
for (z=0; z<FixedOrderCnt; z++)
if Memo(FixedOrders[z].Name)
BEGIN
if (ArgCnt!=0) WrError(1110);
else
BEGIN
BAsmCode[0]=Hi(FixedOrders[z].Code); BAsmCode[1]=Lo(FixedOrders[z].Code);
CodeLen=2;
END
return;
END
for (z=0; z<EmuOrderCnt; z++)
if Memo(EmuOrders[z].Name)
BEGIN
if (ArgCnt!=0) WrError(1110);
else
BEGIN
BAsmCode[0]=Hi(EmuOrders[z].Code1); BAsmCode[1]=Lo(EmuOrders[z].Code1);
BAsmCode[2]=Hi(EmuOrders[z].Code2); BAsmCode[3]=Lo(EmuOrders[z].Code2);
CodeLen=4;
END
return;
END
/* Datentransfer */
for (z=0; z<AuxOrderCnt; z++)
if (Memo(AuxOrders[z].Name))
BEGIN
if ((ArgCnt<1) OR (ArgCnt>2)) WrError(1110);
else
BEGIN
OpSize=1;
DecodeAdr(1,ArgCnt,False,(*OpPart=='S'?0:MModImm)+MModDisp8+MModDisp16+MModAbs);
switch (AdrMode)
BEGIN
case ModDisp8:
BAsmCode[0]=AuxOrders[z].Code+AdrPart;
BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
case ModDisp16:
BAsmCode[0]=0x17;
BAsmCode[1]=AuxOrders[z].Code+AdrPart;
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
break;
case ModAbs:
BAsmCode[0]=0x17;
BAsmCode[1]=AuxOrders[z].Code+0x30;
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
break;
case ModImm:
BAsmCode[0]=0x37; BAsmCode[1]=AuxOrders[z].Code+0x30;
if (*OpPart=='L') BAsmCode[1]-=0x40;
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
break;
END
END
return;
END
for (z=0; z<ExtOrderCnt; z++)
if (Memo(ExtOrders[z].Name))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
OpSize=1; DecodeAdr(1,1,False,MModAbs);
switch (AdrMode)
BEGIN
case ModAbs:
BAsmCode[0]=Hi(ExtOrders[z].Code); BAsmCode[1]=Lo(ExtOrders[z].Code);
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
break;
END
END
return;
END
if ((Memo("PSHM")) OR (Memo("PULM")))
BEGIN
if (ArgCnt<1) WrError(1110);
else
BEGIN
OK=True; Mask=0;
for (z=1; z<=ArgCnt; z++)
if (OK)
BEGIN
z2=0; NLS_UpString(ArgStr[z]);
while ((z2<RegCnt) AND (strcmp(ArgStr[z],Regs[z2])!=0)) z2++;
if (z2>=RegCnt)
BEGIN
WrXError(1445,ArgStr[z]); OK=False;
END
else if (Memo("PSHM")) Mask+=(1 << z2);
else Mask+=(1 << (RegCnt-1-z2));
END
if (OK)
BEGIN
BAsmCode[0]=0x34+Ord(Memo("PULM")); BAsmCode[1]=Mask;
CodeLen=2;
END
END
return;
END
if ((Memo("MOVB")) OR (Memo("MOVW")))
BEGIN
z=Ord(Memo("MOVW"));
if (ArgCnt==2)
BEGIN
DecodeAdr(1,1,False,MModAbs);
if (AdrMode==ModAbs)
BEGIN
memcpy(BAsmCode+2,AdrVals,2);
DecodeAdr(2,2,False,MModAbs);
if (AdrMode==ModAbs)
BEGIN
memcpy(BAsmCode+4,AdrVals,2);
BAsmCode[0]=0x37; BAsmCode[1]=0xfe + z; /* ANSI :-0 */
CodeLen=6;
END
END
END
else if (ArgCnt!=3) WrError(1110);
else if (strcasecmp(ArgStr[2],"X")==0)
BEGIN
BAsmCode[1]=EvalIntExpression(ArgStr[1],SInt8,&OK);
if (OK)
BEGIN
DecodeAdr(3,3,False,MModAbs);
if (AdrMode==ModAbs)
BEGIN
memcpy(BAsmCode+2,AdrVals,2);
BAsmCode[0]=0x30+z;
CodeLen=4;
END
END
END
else if (strcasecmp(ArgStr[3],"X")==0)
BEGIN
BAsmCode[3]=EvalIntExpression(ArgStr[2],SInt8,&OK);
if (OK)
BEGIN
DecodeAdr(1,1,False,MModAbs);
if (AdrMode==ModAbs)
BEGIN
memcpy(BAsmCode+1,AdrVals,2);
BAsmCode[0]=0x32+z;
CodeLen=4;
END
END
END
else WrError(1350);
return;
END
/* Arithmetik */
for (z=0; z<GenOrderCnt; z++)
if (Memo(GenOrders[z].Name))
BEGIN
if ((ArgCnt<1) OR (ArgCnt>2)) WrError(1110);
else
BEGIN
OpSize=GenOrders[z].Size;
DecodeAdr(1,ArgCnt,False,GenOrders[z].AdrMask);
switch (AdrMode)
BEGIN
case ModDisp8:
BAsmCode[0]=GenOrders[z].Code+AdrPart;
BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
case ModDisp16:
BAsmCode[0]=0x17+GenOrders[z].ExtShift;
BAsmCode[1]=GenOrders[z].Code+(OpSize << 6)+AdrPart;
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
break;
case ModDispE:
BAsmCode[0]=0x27; BAsmCode[1]=GenOrders[z].Code+AdrPart;
CodeLen=2;
break;
case ModAbs:
BAsmCode[0]=0x17+GenOrders[z].ExtShift;
BAsmCode[1]=GenOrders[z].Code+(OpSize << 6)+0x30;
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
break;
case ModImm:
if (OpSize==0)
BEGIN
BAsmCode[0]=GenOrders[z].Code+0x30;
BAsmCode[1]=AdrVals[0]; CodeLen=2;
END
else
BEGIN
BAsmCode[0]=0x37; BAsmCode[1]=GenOrders[z].Code+0x30;
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
END
break;
case ModImmExt:
BAsmCode[0]=GenOrders[z].ExtCode;
BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
END
END
return;
END
for (z=0; z<ImmOrderCnt; z++)
if (Memo(ImmOrders[z].Name))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
OpSize=1; DecodeAdr(1,1,False,MModImm+MModImmExt);
switch (AdrMode)
BEGIN
case ModImm:
BAsmCode[0]=0x37; BAsmCode[1]=ImmOrders[z].Code;
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
break;
case ModImmExt:
BAsmCode[0]=ImmOrders[z].Code; BAsmCode[1]=AdrVals[0]; CodeLen=2;
break;
END
END
return;
END
if ((Memo("ANDP")) OR (Memo("ORP")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
OpSize=1; DecodeAdr(1,1,False,MModImm);
switch (AdrMode)
BEGIN
case ModImm:
BAsmCode[0]=0x37; BAsmCode[1]=0x3a+Ord(Memo("ORP"));
memcpy(BAsmCode+2,AdrVals,AdrCnt); CodeLen=2+AdrCnt;
break;
END
END
return;
END
if ((Memo("MAC")) OR (Memo("RMAC")))
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
z=EvalIntExpression(ArgStr[1],UInt4,&OK);
if (OK)
BEGIN
BAsmCode[1]=EvalIntExpression(ArgStr[2],UInt4,&OK);
if (OK)
BEGIN
BAsmCode[1]+=(z << 4);
BAsmCode[0]=0x7b+(Ord(Memo("RMAC")) << 7);
CodeLen=2;
END
END
END
return;
END
/* Bitoperationen */
if ((Memo("BCLR")) OR (Memo("BSET")))
BEGIN
if ((ArgCnt<2) OR (ArgCnt>3)) WrError(1110);
else
BEGIN
OpSize=0; z=Ord(Memo("BSET"));
DecodeAdr(ArgCnt,ArgCnt,False,MModImm);
switch (AdrMode)
BEGIN
case ModImm:
Mask=AdrVals[0];
DecodeAdr(1,ArgCnt-1,False,MModDisp8+MModDisp16+MModAbs);
switch (AdrMode)
BEGIN
case ModDisp8:
BAsmCode[0]=0x17; BAsmCode[1]=0x08+z+AdrPart;
BAsmCode[2]=Mask; BAsmCode[3]=AdrVals[0];
CodeLen=4;
break;
case ModDisp16:
BAsmCode[0]=0x08+z+AdrPart; BAsmCode[1]=Mask;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
CodeLen=2+AdrCnt;
break;
case ModAbs:
BAsmCode[0]=0x38+z; BAsmCode[1]=Mask;
memcpy(BAsmCode+2,AdrVals,AdrCnt);
CodeLen=2+AdrCnt;
break;
END
break;
END
END
return;
END
if ((Memo("BCLRW")) OR (Memo("BSETW")))
BEGIN
if ((ArgCnt<2) OR (ArgCnt>3)) WrError(1110);
else
BEGIN
OpSize=1; z=Ord(Memo("BSETW"));
DecodeAdr(ArgCnt,ArgCnt,False,MModImm);
switch (AdrMode)
BEGIN
case ModImm:
memcpy(BAsmCode+2,AdrVals,AdrCnt);
DecodeAdr(1,ArgCnt-1,False,MModDisp16+MModAbs);
switch (AdrMode)
BEGIN
case ModDisp16:
BAsmCode[0]=0x27; BAsmCode[1]=0x08+z+AdrPart;
memcpy(BAsmCode+4,AdrVals,AdrCnt);
CodeLen=4+AdrCnt;
break;
case ModAbs:
BAsmCode[0]=0x27; BAsmCode[1]=0x38+z;
memcpy(BAsmCode+4,AdrVals,AdrCnt);
CodeLen=4+AdrCnt;
break;
END
END
END
return;
END
if ((Memo("BRCLR")) OR (Memo("BRSET")))
BEGIN
if ((ArgCnt<3) OR (ArgCnt>4)) WrError(1110);
else
BEGIN
z=Ord(Memo("BRSET"));
OpSize=0; DecodeAdr(ArgCnt-1,ArgCnt-1,False,MModImm);
if (AdrMode==ModImm)
BEGIN
BAsmCode[1]=AdrVals[0];
AdrLong=EvalIntExpression(ArgStr[ArgCnt],UInt20,&OK)-EProgCounter()-6;
if (OK)
BEGIN
OK=SymbolQuestionable;
DecodeAdr(1,ArgCnt-2,False,MModDisp8+MModDisp16+MModAbs);
switch (AdrMode)
BEGIN
case ModDisp8:
if ((AdrLong>=-128) AND (AdrLong<127))
BEGIN
BAsmCode[0]=0xcb-(z << 6)+AdrPart;
BAsmCode[2]=AdrVals[0];
BAsmCode[3]=AdrLong & 0xff;
CodeLen=4;
END
else if ((NOT OK) AND ((AdrLong<-0x8000l) OR (AdrLong>0x7fffl))) WrError(1370);
else
BEGIN
BAsmCode[0]=0x0a+AdrPart+z;
BAsmCode[2]=0;
BAsmCode[3]=AdrVals[0];
BAsmCode[4]=(AdrLong >> 8) & 0xff;
BAsmCode[5]=AdrLong & 0xff;
CodeLen=6;
END
break;
case ModDisp16:
if ((NOT OK) AND ((AdrLong<-0x8000l) OR (AdrLong>0x7fffl))) WrError(1370);
else
BEGIN
BAsmCode[0]=0x0a+AdrPart+z;
memcpy(BAsmCode+2,AdrVals,2);
BAsmCode[4]=(AdrLong >> 8) & 0xff;
BAsmCode[5]=AdrLong & 0xff;
CodeLen=6;
END
break;
case ModAbs:
if ((NOT OK) AND ((AdrLong<-0x8000l) OR (AdrLong>0x7fffl))) WrError(1370);
else
BEGIN
BAsmCode[0]=0x3a+z;
memcpy(BAsmCode+2,AdrVals,2);
BAsmCode[4]=(AdrLong >> 8) & 0xff;
BAsmCode[5]=AdrLong & 0xff;
CodeLen=6;
END
break;
END
END
END
END
return;
END
/* Spruenge */
if ((Memo("JMP")) OR (Memo("JSR")))
BEGIN
if ((ArgCnt<1) OR (ArgCnt>2)) WrError(1110);
else
BEGIN
OpSize=1;
DecodeAdr(1,ArgCnt,True,MModAbs20+MModDisp20);
switch (AdrMode)
BEGIN
case ModAbs20:
BAsmCode[0]=0x7a+(Ord(Memo("JSR")) << 7);
memcpy(BAsmCode+1,AdrVals,AdrCnt);
CodeLen=1+AdrCnt;
break;
case ModDisp20:
BAsmCode[0]=(Memo("JMP"))?0x4b:0x89;
BAsmCode[0]+=AdrPart;
memcpy(BAsmCode+1,AdrVals,AdrCnt);
CodeLen=1+AdrCnt;
break;
END
END
return;
END
for (z=0; z<RelOrderCnt; z++)
if ((Memo(RelOrders[z].Name)) OR ((*OpPart=='L') AND (strcmp(OpPart+1,RelOrders[z].Name)==0)))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK)-EProgCounter()-6;
if ((AdrLong&1)==1) WrError(1325);
else if (*OpPart=='L')
if ((NOT SymbolQuestionable) AND ((AdrLong>0x7fffl) OR (AdrLong<-0x8000l))) WrError(1370);
else
BEGIN
BAsmCode[0]=0x37; BAsmCode[1]=RelOrders[z].Code+0x80;
BAsmCode[2]=(AdrLong >> 8) & 0xff;
BAsmCode[3]=AdrLong & 0xff;
CodeLen=4;
END
else
if ((NOT SymbolQuestionable) AND ((AdrLong>0x7fl) OR (AdrLong<-0x80l))) WrError(1370);
else
BEGIN
BAsmCode[0]=0xb0+RelOrders[z].Code;
BAsmCode[1]=AdrLong & 0xff;
CodeLen=2;
END
END
return;
END
for (z=0; z<LRelOrderCnt; z++)
if (Memo(LRelOrders[z].Name))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK)-EProgCounter()-6;
if ((AdrLong&1)==1) WrError(1325);
else if ((NOT SymbolQuestionable) AND ((AdrLong>0x7fffl) OR (AdrLong<-0x8000l))) WrError(1370);
else
BEGIN
BAsmCode[0]=Hi(LRelOrders[z].Code); BAsmCode[1]=Lo(LRelOrders[z].Code);
BAsmCode[2]=(AdrLong >> 8) & 0xff;
BAsmCode[3]=AdrLong & 0xff;
CodeLen=4;
END
END
return;
END
if (Memo("BSR"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
AdrLong=EvalIntExpression(ArgStr[1],UInt24,&OK)-EProgCounter()-6;
if ((AdrLong&1)==1) WrError(1325);
else if ((NOT SymbolQuestionable) AND ((AdrLong>0x7fl) OR (AdrLong<-0x80l))) WrError(1370);
else
BEGIN
BAsmCode[0]=0x36;
BAsmCode[1]=AdrLong & 0xff;
CodeLen=2;
END
END
return;
END
WrXError(1200,OpPart);
END
static void InitCode_6816(void)
BEGIN
SaveInitProc();
Reg_EK=0;
END
static Boolean IsDef_6816(void)
BEGIN
return False;
END
static void SwitchFrom_6816(void)
BEGIN
DeinitFields();
END
static void SwitchTo_6816(void)
BEGIN
TurnWords=False; ConstMode=ConstModeMoto; SetIsOccupied=False;
PCSymbol="*"; HeaderID=0x65; NOPCode=0x274c;
DivideChars=","; HasAttrs=False;
ValidSegs=(1<<SegCode);
Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
SegLimits[SegCode] = 0xfffffl;
MakeCode=MakeCode_6816; IsDef=IsDef_6816;
SwitchFrom=SwitchFrom_6816;
InitFields();
END
void code6816_init(void)
BEGIN
CPU6816=AddCPU("68HC16",SwitchTo_6816);
SaveInitProc=InitPassProc; InitPassProc=InitCode_6816;
END