aboutsummaryrefslogtreecommitdiffstats
path: root/code65.c
diff options
context:
space:
mode:
Diffstat (limited to 'code65.c')
-rw-r--r--code65.c736
1 files changed, 736 insertions, 0 deletions
diff --git a/code65.c b/code65.c
new file mode 100644
index 0000000..69ccc93
--- /dev/null
+++ b/code65.c
@@ -0,0 +1,736 @@
+/* code65.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* Codegenerator 65xx/MELPS740 */
+/* */
+/* Historie: 17. 8.1996 Grundsteinlegung */
+/* 17.11.1998 ungueltiges Register wurde bei Indizierung nicht ab- */
+/* gefangen */
+/* 2. 1.1999 ChkPC umgestellt */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+
+#include "bpemu.h"
+#include "strutil.h"
+#include "asmdef.h"
+#include "asmpars.h"
+#include "asmsub.h"
+#include "codepseudo.h"
+#include "codevars.h"
+
+/*---------------------------------------------------------------------------*/
+
+#define ModZA 0 /* aa */
+#define ModA 1 /* aabb */
+#define ModZIX 2 /* aa,X */
+#define ModIX 3 /* aabb,X */
+#define ModZIY 4 /* aa,Y */
+#define ModIY 5 /* aabb,Y */
+#define ModIndX 6 /* (aa,X) */
+#define ModIndY 7 /* (aa),Y */
+#define ModInd16 8 /* (aabb) */
+#define ModImm 9 /* #aa */
+#define ModAcc 10 /* A */
+#define ModNone 11 /* */
+#define ModInd8 12 /* (aa) */
+#define ModSpec 13 /* \aabb */
+
+typedef struct
+ {
+ char *Name;
+ Byte CPUFlag;
+ Byte Code;
+ } FixedOrder;
+
+typedef struct
+ {
+ char *Name;
+ Integer Codes[ModSpec+1];
+ } NormOrder;
+
+typedef struct
+ {
+ char *Name;
+ Byte CPUFlag;
+ Byte Code;
+ } CondOrder;
+
+#define FixedOrderCount 37
+#define NormOrderCount 51
+#define CondOrderCount 9
+
+
+static Boolean CLI_SEI_Flag,ADC_SBC_Flag;
+
+static FixedOrder *FixedOrders;
+static NormOrder *NormOrders;
+static CondOrder *CondOrders;
+
+static SimpProc SaveInitProc;
+static CPUVar CPU6502,CPU65SC02,CPU65C02,CPUM740,CPU6502U;
+static LongInt SpecPage;
+
+static ShortInt ErgMode;
+static Byte AdrVals[2];
+
+/*---------------------------------------------------------------------------*/
+
+ static void AddFixed(char *NName, Byte NFlag, Byte NCode)
+BEGIN
+ if (InstrZ>=FixedOrderCount) exit(255);
+ FixedOrders[InstrZ].Name=NName;
+ FixedOrders[InstrZ].CPUFlag=NFlag;
+ FixedOrders[InstrZ++].Code=NCode;
+END
+
+ static void AddNorm(char *NName, Word ZACode, Word ACode, Word ZIXCode,
+ Word IXCode, Word ZIYCode, Word IYCode, Word IndXCode,
+ Word IndYCode, Word Ind16Code, Word ImmCode, Word AccCode,
+ Word NoneCode, Word Ind8Code, Word SpecCode)
+BEGIN
+ if (InstrZ>=NormOrderCount) exit(255);
+ NormOrders[InstrZ].Name=NName;
+ NormOrders[InstrZ].Codes[ModZA]=ZACode;
+ NormOrders[InstrZ].Codes[ModA]=ACode;
+ NormOrders[InstrZ].Codes[ModZIX]=ZIXCode;
+ NormOrders[InstrZ].Codes[ModIX]=IXCode;
+ NormOrders[InstrZ].Codes[ModZIY]=ZIYCode;
+ NormOrders[InstrZ].Codes[ModIY]=IYCode;
+ NormOrders[InstrZ].Codes[ModIndX]=IndXCode;
+ NormOrders[InstrZ].Codes[ModIndY]=IndYCode;
+ NormOrders[InstrZ].Codes[ModInd16]=Ind16Code;
+ NormOrders[InstrZ].Codes[ModImm]=ImmCode;
+ NormOrders[InstrZ].Codes[ModAcc]=AccCode;
+ NormOrders[InstrZ].Codes[ModNone]=NoneCode;
+ NormOrders[InstrZ].Codes[ModInd8]=Ind8Code;
+ NormOrders[InstrZ++].Codes[ModSpec]=SpecCode;
+END
+
+ static void AddCond(char *NName, Byte NFlag, Byte NCode)
+BEGIN
+ if (InstrZ>=CondOrderCount) exit(255);
+ CondOrders[InstrZ].Name=NName;
+ CondOrders[InstrZ].CPUFlag=NFlag;
+ CondOrders[InstrZ++].Code=NCode;
+END
+
+ static void InitFields(void)
+BEGIN
+ Boolean Is740=(MomCPU==CPUM740);
+
+ FixedOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCount); InstrZ=0;
+ AddFixed("RTS", 31, 0x60); AddFixed("RTI", 31, 0x40);
+ AddFixed("TAX", 31, 0xaa); AddFixed("TXA", 31, 0x8a);
+ AddFixed("TAY", 31, 0xa8); AddFixed("TYA", 31, 0x98);
+ AddFixed("TXS", 31, 0x9a); AddFixed("TSX", 31, 0xba);
+ AddFixed("DEX", 31, 0xca); AddFixed("DEY", 31, 0x88);
+ AddFixed("INX", 31, 0xe8); AddFixed("INY", 31, 0xc8);
+ AddFixed("PHA", 31, 0x48); AddFixed("PLA", 31, 0x68);
+ AddFixed("PHP", 31, 0x08); AddFixed("PLP", 31, 0x28);
+ AddFixed("PHX", 6, 0xda); AddFixed("PLX", 6, 0xfa);
+ AddFixed("PHY", 6, 0x5a); AddFixed("PLY", 6, 0x7a);
+ AddFixed("BRK", 31, 0x00); AddFixed("STP", 8, 0x42);
+ AddFixed("SLW", 8, 0xc2); AddFixed("FST", 8, 0xe2);
+ AddFixed("WIT", 8, 0xc2); AddFixed("CLI", 31, 0x58);
+ AddFixed("SEI", 31, 0x78); AddFixed("CLC", 31, 0x18);
+ AddFixed("SEC", 31, 0x38); AddFixed("CLD", 31, 0xd8);
+ AddFixed("SED", 31, 0xf8); AddFixed("CLV", 31, 0xb8);
+ AddFixed("CLT", 8, 0x12); AddFixed("SET", 8, 0x32);
+ AddFixed("JAM", 16, 0x02); AddFixed("CRS", 16, 0x02);
+ AddFixed("KIL", 16, 0x02);
+
+
+ NormOrders=(NormOrder *) malloc(sizeof(NormOrder)*NormOrderCount); InstrZ=0;
+ /* ZA A ZIX IX ZIY IY @X @Y (n16) imm ACC NON (n8) spec */
+ AddNorm("NOP",0x1004,0x100c,0x1014,0x101c, -1, -1, -1, -1, -1,0x1080, -1,0x1fea, -1, -1);
+ AddNorm("LDA",0x1fa5,0x1fad,0x1fb5,0x1fbd, -1,0x1fb9,0x1fa1,0x1fb1, -1,0x1fa9, -1, -1,0x06b2, -1);
+ AddNorm("LDX",0x1fa6,0x1fae, -1, -1,0x1fb6,0x1fbe, -1, -1, -1,0x1fa2, -1, -1, -1, -1);
+ AddNorm("LDY",0x1fa4,0x1fac,0x1fb4,0x1fbc, -1, -1, -1, -1, -1,0x1fa0, -1, -1, -1, -1);
+ AddNorm("STA",0x1f85,0x1f8d,0x1f95,0x1f9d, -1,0x1f99,0x1f81,0x1f91, -1, -1, -1, -1,0x0692, -1);
+ AddNorm("STX",0x1f86,0x1f8e, -1, -1,0x1f96, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("STY",0x1f84,0x1f8c,0x1f94, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("STZ",0x0664,0x069c,0x0674,0x069e, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("ADC",0x1f65,0x1f6d,0x1f75,0x1f7d, -1,0x1f79,0x1f61,0x1f71, -1,0x1f69, -1, -1,0x0672, -1);
+ AddNorm("SBC",0x1fe5,0x1fed,0x1ff5,0x1ffd, -1,0x1ff9,0x1fe1,0x1ff1, -1,0x1fe9, -1, -1,0x06f2, -1);
+ AddNorm("MUL", -1, -1,0x0862, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("DIV", -1, -1,0x08e2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("AND",0x1f25,0x1f2d,0x1f35,0x1f3d, -1,0x1f39,0x1f21,0x1f31, -1,0x1f29, -1, -1,0x0632, -1);
+ AddNorm("ORA",0x1f05,0x1f0d,0x1f15,0x1f1d, -1,0x1f19,0x1f01,0x1f11, -1,0x1f09, -1, -1,0x0612, -1);
+ AddNorm("EOR",0x1f45,0x1f4d,0x1f55,0x1f5d, -1,0x1f59,0x1f41,0x1f51, -1,0x1f49, -1, -1,0x0652, -1);
+ AddNorm("COM",0x0844, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("BIT",0x1f24,0x1f2c,0x0634,0x063c, -1, -1, -1, -1, -1,0x0689, -1, -1, -1, -1);
+ AddNorm("TST",0x0864, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("ASL",0x1f06,0x1f0e,0x1f16,0x1f1e, -1, -1, -1, -1, -1, -1,0x1f0a,0x1f0a, -1, -1);
+ AddNorm("LSR",0x1f46,0x1f4e,0x1f56,0x1f5e, -1, -1, -1, -1, -1, -1,0x1f4a,0x1f4a, -1, -1);
+ AddNorm("ROL",0x1f26,0x1f2e,0x1f36,0x1f3e, -1, -1, -1, -1, -1, -1,0x1f2a,0x1f2a, -1, -1);
+ AddNorm("ROR",0x1f66,0x1f6e,0x1f76,0x1f7e, -1, -1, -1, -1, -1, -1,0x1f6a,0x1f6a, -1, -1);
+ AddNorm("RRF",0x0882, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("TSB",0x0604,0x060c, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("TRB",0x0614,0x061c, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("INC",0x1fe6,0x1fee,0x1ff6,0x1ffe, -1, -1, -1, -1, -1, -1,(Is740)?0x0e3a:0x0e1a,
+ (Is740)?0x0e3a:0x0e1a,
+ -1, -1);
+ AddNorm("DEC",0x1fc6,0x1fce,0x1fd6,0x1fde, -1, -1, -1, -1, -1, -1,(Is740)?0x0e1a:0x0e3a,
+ (Is740)?0x0e1a:0x0e3a,
+ -1, -1);
+ AddNorm("CMP",0x1fc5,0x1fcd,0x1fd5,0x1fdd, -1,0x1fd9,0x1fc1,0x1fd1, -1,0x1fc9, -1, -1,0x06d2, -1);
+ AddNorm("CPX",0x1fe4,0x1fec, -1, -1, -1, -1, -1, -1, -1,0x1fe0, -1, -1, -1, -1);
+ AddNorm("CPY",0x1fc4,0x1fcc, -1, -1, -1, -1, -1, -1, -1,0x1fc0, -1, -1, -1, -1);
+ AddNorm("JMP", -1,0x1f4c, -1, -1, -1, -1,0x067c, -1,0x1f6c, -1, -1, -1,0x08b2, -1);
+ AddNorm("JSR", -1,0x1f20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,0x0802,0x0822);
+ AddNorm("SLO",0x1007,0x100f,0x1017,0x101f, -1,0x101b,0x1003,0x1013, -1, -1, -1, -1, -1, -1);
+ AddNorm("ANC", -1, -1, -1, -1, -1, -1, -1, -1, -1,0x100b, -1, -1, -1, -1);
+ AddNorm("RLA",0x1027,0x102f,0x1037,0x103f, -1,0x103b,0x1023,0x1033, -1, -1, -1, -1, -1, -1);
+ AddNorm("SRE",0x1047,0x104f,0x1057,0x105f, -1,0x105b,0x1043,0x1053, -1, -1, -1, -1, -1, -1);
+ AddNorm("ASR", -1, -1, -1, -1, -1, -1, -1, -1, -1,0x104b, -1, -1, -1, -1);
+ AddNorm("RRA",0x1067,0x106f,0x1077,0x107f, -1,0x107b,0x1063,0x1073, -1, -1, -1, -1, -1, -1);
+ AddNorm("ARR", -1, -1, -1, -1, -1, -1, -1, -1, -1,0x106b, -1, -1, -1, -1);
+ AddNorm("SAX",0x1087,0x108f, -1, -1,0x1097, -1,0x1083, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("ANE", -1, -1, -1, -1, -1, -1, -1, -1, -1,0x108b, -1, -1, -1, -1);
+ AddNorm("SHA", -1, -1, -1,0x1093, -1,0x109f, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("SHS", -1, -1, -1, -1, -1,0x109b, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("SHY", -1, -1, -1, -1, -1,0x109c, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("SHX", -1, -1, -1,0x109e, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("LAX",0x10a7,0x10af, -1, -1,0x10b7,0x10bf,0x10a3,0x10b3, -1, -1, -1, -1, -1, -1);
+ AddNorm("LXA", -1, -1, -1, -1, -1, -1, -1, -1, -1,0x10ab, -1, -1, -1, -1);
+ AddNorm("LAE", -1, -1, -1, -1, -1,0x10bb, -1, -1, -1, -1, -1, -1, -1, -1);
+ AddNorm("DCP",0x10c7,0x10cf,0x10d7,0x10df, -1,0x10db,0x10c3,0x10d3, -1, -1, -1, -1, -1, -1);
+ AddNorm("SBX", -1, -1, -1, -1, -1, -1, -1, -1, -1,0x10cb, -1, -1, -1, -1);
+ AddNorm("ISB",0x10e7,0x10ef,0x10f7,0x10ff, -1,0x10fb,0x10e3,0x10f3, -1, -1, -1, -1, -1, -1);
+
+ CondOrders=(CondOrder *) malloc(sizeof(CondOrder)*CondOrderCount); InstrZ=0;
+ AddCond("BEQ", 31, 0xf0);
+ AddCond("BNE", 31, 0xd0);
+ AddCond("BPL", 31, 0x10);
+ AddCond("BMI", 31, 0x30);
+ AddCond("BCC", 31, 0x90);
+ AddCond("BCS", 31, 0xb0);
+ AddCond("BVC", 31, 0x50);
+ AddCond("BVS", 31, 0x70);
+ AddCond("BRA", 14, 0x80);
+END
+
+ static void DeinitFields(void)
+BEGIN
+ free(FixedOrders);
+ free(NormOrders);
+ free(CondOrders);
+END
+
+/*---------------------------------------------------------------------------*/
+
+ static void ChkZero(char *Asc, Byte *erg)
+BEGIN
+ if ((strlen(Asc)>1) AND ((*Asc=='<') OR (*Asc=='>')))
+ BEGIN
+ *erg=Ord(*Asc=='<')+1; strcpy(Asc,Asc+1);
+ END
+ else *erg=0;
+END
+
+ static Boolean DecodePseudo(void)
+BEGIN
+#define ASSUME740Count 1
+ static ASSUMERec ASSUME740s[ASSUME740Count]=
+ {{"SP", &SpecPage, 0, 0xff, -1}};
+
+ if (Memo("ASSUME"))
+ BEGIN
+ if (MomCPU!=CPUM740) WrError(1500);
+ else CodeASSUME(ASSUME740s,ASSUME740Count);
+ return True;
+ END
+
+ return False;
+END
+
+ static void ChkFlags(void)
+BEGIN
+ /* Spezialflags ? */
+
+ CLI_SEI_Flag=(Memo("CLI") OR Memo("SEI"));
+ ADC_SBC_Flag=(Memo("ADC") OR Memo("SBC"));
+END
+
+ static Boolean CPUAllowed(Byte Flag)
+BEGIN
+ return (((Flag >> (MomCPU-CPU6502))&1)==1);
+END
+
+ static void InsNOP(void)
+BEGIN
+ memmove(BAsmCode,BAsmCode+1,CodeLen);
+ CodeLen++; BAsmCode[0]=NOPCode;
+END
+
+ static Boolean IsAllowed(Word Val)
+BEGIN
+ return (CPUAllowed(Hi(Val)) AND (Val!=0xffff));
+END
+
+ static void ChkZeroMode(ShortInt Mode)
+BEGIN
+ int OrderZ;
+
+ for (OrderZ=0; OrderZ<NormOrderCount; OrderZ++)
+ if (Memo(NormOrders[OrderZ].Name))
+ BEGIN
+ if (IsAllowed(NormOrders[OrderZ].Codes[Mode]))
+ BEGIN
+ ErgMode=Mode; AdrCnt--;
+ END
+ return;
+ END
+END
+
+ static void MakeCode_65(void)
+BEGIN
+ Word OrderZ;
+ Byte AdrByte;
+ Integer AdrInt;
+ Word AdrWord;
+ String s1;
+ Boolean ValOK,b;
+ Byte ZeroMode;
+
+ CodeLen=0; DontPrint=False;
+
+ /* zu ignorierendes */
+
+ if (Memo("")) { ChkFlags(); return; }
+
+ /* Pseudoanweisungen */
+
+ if (DecodePseudo()) { ChkFlags(); return; }
+
+ if (DecodeMotoPseudo(False)) { ChkFlags(); return; }
+
+ /* Anweisungen ohne Argument */
+
+ for (OrderZ=0; OrderZ<FixedOrderCount; OrderZ++)
+ if (Memo(FixedOrders[OrderZ].Name))
+ BEGIN
+ if (ArgCnt!=0) WrError(1110);
+ else if (NOT CPUAllowed(FixedOrders[OrderZ].CPUFlag)) WrError(1500);
+ else
+ BEGIN
+ CodeLen=1;
+ BAsmCode[0]=FixedOrders[OrderZ].Code;
+ if (Memo("BRK")) BAsmCode[CodeLen++]=NOPCode;
+ else if (MomCPU==CPUM740)
+ BEGIN
+ if (Memo("PLP")) BAsmCode[CodeLen++]=NOPCode;
+ if ((ADC_SBC_Flag) AND (Memo("SEC") OR Memo("CLC") OR Memo("CLD"))) InsNOP();
+ END
+ END
+ ChkFlags(); return;
+ END
+
+ if ((Memo("SEB")) OR (Memo("CLB")))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (MomCPU!=CPUM740) WrError(1500);
+ else
+ BEGIN
+ AdrByte=EvalIntExpression(ArgStr[1],UInt3,&ValOK);
+ if (ValOK)
+ BEGIN
+ BAsmCode[0]=0x0b+(AdrByte << 5)+(Ord(Memo("CLB")) << 4);
+ if (strcasecmp(ArgStr[2],"A")==0) CodeLen=1;
+ else
+ BEGIN
+ BAsmCode[1]=EvalIntExpression(ArgStr[2],UInt8,&ValOK);
+ if (ValOK)
+ BEGIN
+ CodeLen=2; BAsmCode[0]+=4;
+ END
+ END
+ END
+ END
+ ChkFlags(); return;
+ END
+
+ if ((Memo("BBC")) OR (Memo("BBS")))
+ BEGIN
+ if (ArgCnt!=3) WrError(1110);
+ else if (MomCPU!=CPUM740) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[0]=EvalIntExpression(ArgStr[1],UInt3,&ValOK);
+ if (ValOK)
+ BEGIN
+ BAsmCode[0]=(BAsmCode[0] << 5)+(Ord(Memo("BBC")) << 4)+3;
+ b=(strcasecmp(ArgStr[2],"A")!=0);
+ if (NOT b) ValOK=True;
+ else
+ BEGIN
+ BAsmCode[0]+=4;
+ BAsmCode[1]=EvalIntExpression(ArgStr[2],UInt8,&ValOK);
+ END
+ if (ValOK)
+ BEGIN
+ AdrInt=EvalIntExpression(ArgStr[3],Int16,&ValOK)-(EProgCounter()+2+Ord(b)+Ord(CLI_SEI_Flag));
+ if (ValOK)
+ if (((AdrInt>127) OR (AdrInt<-128)) AND (NOT SymbolQuestionable)) WrError(1370);
+ else
+ BEGIN
+ CodeLen=2+Ord(b);
+ BAsmCode[CodeLen-1]=AdrInt & 0xff;
+ if (CLI_SEI_Flag) InsNOP();
+ END
+ END
+ END
+ END
+ ChkFlags(); return;
+ END
+
+ if (((strlen(OpPart)==4)
+ AND (OpPart[3]>='0') AND (OpPart[3]<='7')
+ AND ((strncmp(OpPart,"BBR",3)==0) OR (strncmp(OpPart,"BBS",3)==0))))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (MomCPU!=CPU65C02) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[1]=EvalIntExpression(ArgStr[1],UInt8,&ValOK);
+ if (ValOK)
+ BEGIN
+ BAsmCode[0]=((OpPart[3]-'0') << 4)+(Ord(OpPart[2]=='S') << 7)+15;
+ AdrInt=EvalIntExpression(ArgStr[2],UInt16,&ValOK)-(EProgCounter()+3);
+ if (ValOK)
+ if (((AdrInt>127) OR (AdrInt<-128)) AND (NOT SymbolQuestionable)) WrError(1370);
+ else
+ BEGIN
+ CodeLen=3;
+ BAsmCode[2]=AdrInt & 0xff;
+ END
+ END
+ END
+ ChkFlags(); return;
+ END
+
+ if (((strlen(OpPart)==4)
+ AND (OpPart[3]>='0') AND (OpPart[3]<='7')
+ AND ((strncmp(OpPart,"RMB",3)==0) OR (strncmp(OpPart,"SMB",3)==0))))
+ BEGIN
+ if (ArgCnt!=1) WrError(1110);
+ else if (MomCPU!=CPU65C02) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[1]=EvalIntExpression(ArgStr[1],UInt8,&ValOK);
+ if (ValOK)
+ BEGIN
+ BAsmCode[0]=((OpPart[3]-'0') << 4)+(Ord(*OpPart=='S') << 7)+7;
+ CodeLen=2;
+ END
+ END
+ ChkFlags(); return;
+ END
+
+ if (Memo("LDM"))
+ BEGIN
+ if (ArgCnt!=2) WrError(1110);
+ else if (MomCPU!=CPUM740) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[0]=0x3c;
+ BAsmCode[2]=EvalIntExpression(ArgStr[2],UInt8,&ValOK);
+ if (ValOK)
+ if (*ArgStr[1]!='#') WrError(1350);
+ else
+ BEGIN
+ BAsmCode[1]=EvalIntExpression(ArgStr[1]+1,Int8,&ValOK);
+ if (ValOK) CodeLen=3;
+ END
+ END
+ ChkFlags(); return;
+ END
+
+ /* normale Anweisungen: Adressausdruck parsen */
+
+ ErgMode=(-1);
+
+ if (ArgCnt==0)
+ BEGIN
+ AdrCnt=0; ErgMode=ModNone;
+ END
+
+ else if (ArgCnt==1)
+ BEGIN
+ /* 1. Akkuadressierung */
+
+ if (strcasecmp(ArgStr[1],"A")==0)
+ BEGIN
+ AdrCnt=0; ErgMode=ModAcc;
+ END
+
+ /* 2. immediate ? */
+
+ else if (*ArgStr[1]=='#')
+ BEGIN
+ AdrVals[0]=EvalIntExpression(ArgStr[1]+1,Int8,&ValOK);
+ if (ValOK)
+ BEGIN
+ ErgMode=ModImm; AdrCnt=1;
+ END
+ END
+
+ /* 3. Special Page ? */
+
+ else if (*ArgStr[1]=='\\')
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[1]+1,UInt16,&ValOK);
+ if (ValOK)
+ if (Hi(AdrWord)!=SpecPage) WrError(1315);
+ else
+ BEGIN
+ ErgMode=ModSpec; AdrVals[0]=Lo(AdrWord); AdrCnt=1;
+ END
+ END
+
+ /* 4. X-indirekt ? */
+
+ else if ((strlen(ArgStr[1])>=5) AND (strcasecmp(ArgStr[1]+strlen(ArgStr[1])-3,",X)")==0))
+ BEGIN
+ if (*ArgStr[1]!='(') WrError(1350);
+ else
+ BEGIN
+ strmaxcpy(s1,ArgStr[1]+1,255); s1[strlen(s1)-3]='\0';
+ ChkZero(s1,&ZeroMode);
+ if (Memo("JMP"))
+ BEGIN
+ AdrWord=EvalIntExpression(s1,UInt16,&ValOK);
+ if (ValOK)
+ BEGIN
+ AdrVals[0]=Lo(AdrWord); AdrVals[1]=Hi(AdrWord);
+ ErgMode=ModIndX; AdrCnt=2;
+ END
+ END
+ else
+ BEGIN
+ AdrVals[0]=EvalIntExpression(s1,UInt8,&ValOK);
+ if (ValOK)
+ BEGIN
+ ErgMode=ModIndX; AdrCnt=1;
+ END
+ END
+ END
+ END
+
+ else
+ BEGIN
+ /* 5. indirekt absolut ? */
+
+ if (IsIndirect(ArgStr[1]))
+ BEGIN
+ strcpy(s1,ArgStr[1]+1); s1[strlen(s1)-1]='\0';
+ ChkZero(s1,&ZeroMode);
+ if (ZeroMode==2)
+ BEGIN
+ AdrVals[0]=EvalIntExpression(s1,UInt8,&ValOK);
+ if (ValOK)
+ BEGIN
+ ErgMode=ModInd8; AdrCnt=1;
+ END
+ END
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(s1,UInt16,&ValOK);
+ if (ValOK)
+ BEGIN
+ ErgMode=ModInd16; AdrCnt=2;
+ AdrVals[0]=Lo(AdrWord); AdrVals[1]=Hi(AdrWord);
+ if ((ZeroMode==0) AND (AdrVals[1]==0)) ChkZeroMode(ModInd8);
+ END
+ END
+ END
+
+ /* 6. absolut */
+
+ else
+ BEGIN
+ ChkZero(ArgStr[1],&ZeroMode);
+ if (ZeroMode==2)
+ BEGIN
+ AdrVals[0]=EvalIntExpression(ArgStr[1],UInt8,&ValOK);
+ if (ValOK)
+ BEGIN
+ ErgMode=ModZA; AdrCnt=1;
+ END
+ END
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(ArgStr[1],UInt16,&ValOK);
+ if (ValOK)
+ BEGIN
+ ErgMode=ModA; AdrCnt=2;
+ AdrVals[0]=Lo(AdrWord); AdrVals[1]=Hi(AdrWord);
+ if ((ZeroMode==0) AND (AdrVals[1]==0)) ChkZeroMode(ModZA);
+ END
+ END
+ END
+ END
+ END
+
+ else if (ArgCnt==2)
+ BEGIN
+ /* 7. Y-indirekt ? */
+
+ if ((IsIndirect(ArgStr[1])) AND (strcasecmp(ArgStr[2],"Y")==0))
+ BEGIN
+ strcpy(s1,ArgStr[1]+1); s1[strlen(s1)-1]='\0';
+ ChkZero(s1,&ZeroMode);
+ AdrVals[0]=EvalIntExpression(s1,UInt8,&ValOK);
+ if (ValOK)
+ BEGIN
+ ErgMode=ModIndY; AdrCnt=1;
+ END
+ END
+
+ /* 8. X,Y-indiziert ? */
+
+ else
+ BEGIN
+ strcpy(s1,ArgStr[1]);
+ ChkZero(s1,&ZeroMode);
+ if (ZeroMode==2)
+ BEGIN
+ AdrVals[0]=EvalIntExpression(s1,UInt8,&ValOK);
+ if (ValOK)
+ BEGIN
+ AdrCnt=1;
+ if (strcasecmp(ArgStr[2],"X")==0) ErgMode=ModZIX;
+ else if (strcasecmp(ArgStr[2],"Y")==0) ErgMode=ModZIY;
+ else WrXError(1445,ArgStr[2]);
+ END
+ END
+ else
+ BEGIN
+ AdrWord=EvalIntExpression(s1,Int16,&ValOK);
+ if (ValOK)
+ BEGIN
+ AdrCnt=2;
+ AdrVals[0]=Lo(AdrWord); AdrVals[1]=Hi(AdrWord);
+ if (strcasecmp(ArgStr[2],"X")==0) ErgMode=ModIX;
+ else if (strcasecmp(ArgStr[2],"Y")==0) ErgMode=ModIY;
+ else WrXError(1445,ArgStr[2]);
+ if (ErgMode != -1)
+ BEGIN
+ if ((AdrVals[1]==0) AND (ZeroMode==0))
+ ChkZeroMode((strcasecmp(ArgStr[2],"X")==0)?ModZIX:ModZIY);
+ END
+ END
+ END
+ END
+ END
+
+ else
+ BEGIN
+ WrError(1110);
+ ChkFlags(); return;
+ END;
+
+ /* in Tabelle nach Opcode suchen */
+
+ for (OrderZ=0; OrderZ<NormOrderCount; OrderZ++)
+ if (Memo(NormOrders[OrderZ].Name))
+ BEGIN
+ if ((ErgMode==-1)) WrError(1350);
+ else
+ BEGIN
+ if (NormOrders[OrderZ].Codes[ErgMode]==-1)
+ BEGIN
+ if (ErgMode==ModZA) ErgMode=ModA;
+ if (ErgMode==ModZIX) ErgMode=ModIX;
+ if (ErgMode==ModZIY) ErgMode=ModIY;
+ if (ErgMode==ModInd8) ErgMode=ModInd16;
+ AdrVals[AdrCnt++]=0;
+ END
+ if (NormOrders[OrderZ].Codes[ErgMode]==-1) WrError(1350);
+ else if (NOT CPUAllowed(Hi(NormOrders[OrderZ].Codes[ErgMode]))) WrError(1500);
+ else
+ BEGIN
+ BAsmCode[0]=Lo(NormOrders[OrderZ].Codes[ErgMode]);
+ memcpy(BAsmCode+1,AdrVals,AdrCnt);
+ CodeLen=AdrCnt+1;
+ if ((ErgMode==ModInd16) AND (MomCPU!=CPU65C02) AND (BAsmCode[1]==0xff))
+ BEGIN
+ WrError(1900); CodeLen=0;
+ END
+ END
+ END
+ ChkFlags(); return;
+ END
+
+ /* relativer Sprung ? */
+
+ if (ErgMode==ModZA)
+ BEGIN
+ ErgMode=ModA; AdrVals[1]=0;
+ END
+ if (ErgMode==ModA)
+ for (OrderZ=0; OrderZ<CondOrderCount; OrderZ++)
+ if (Memo(CondOrders[OrderZ].Name))
+ BEGIN
+ AdrInt=(((Integer)AdrVals[1])<<8)+AdrVals[0];
+ AdrInt-=EProgCounter()+2;
+ if (NOT CPUAllowed(CondOrders[OrderZ].CPUFlag)) WrError(1500);
+ else if (((AdrInt>127) OR (AdrInt<-128)) AND (NOT SymbolQuestionable)) WrError(1370);
+ else
+ BEGIN
+ BAsmCode[0]=CondOrders[OrderZ].Code; BAsmCode[1]=AdrInt & 0xff;
+ CodeLen=2;
+ END
+ ChkFlags(); return;
+ END
+
+ WrXError(1200,OpPart);
+END
+
+ static void InitCode_65(void)
+BEGIN
+ SaveInitProc();
+ CLI_SEI_Flag=False;
+ ADC_SBC_Flag=False;
+END
+
+ static Boolean IsDef_65(void)
+BEGIN
+ return False;
+END
+
+ static void SwitchFrom_65(void)
+BEGIN
+ DeinitFields();
+END
+
+ static void SwitchTo_65(void)
+BEGIN
+ TurnWords=False; ConstMode=ConstModeMoto; SetIsOccupied=(MomCPU==CPUM740);
+
+ PCSymbol="*"; HeaderID=0x11; NOPCode=0xea;
+ DivideChars=","; HasAttrs=False;
+
+ ValidSegs=1<<SegCode;
+ Grans[SegCode]=1; ListGrans[SegCode]=1; SegInits[SegCode]=0;
+ SegLimits[SegCode] = 0xffff;
+
+ MakeCode=MakeCode_65; IsDef=IsDef_65;
+ SwitchFrom=SwitchFrom_65; InitFields();
+END
+
+ void code65_init(void)
+BEGIN
+ CPU6502 =AddCPU("6502" ,SwitchTo_65);
+ CPU65SC02=AddCPU("65SC02" ,SwitchTo_65);
+ CPU65C02 =AddCPU("65C02" ,SwitchTo_65);
+ CPUM740 =AddCPU("MELPS740" ,SwitchTo_65);
+ CPU6502U =AddCPU("6502UNDOC",SwitchTo_65);
+
+ SaveInitProc=InitPassProc; InitPassProc=InitCode_65;
+END