diff options
Diffstat (limited to 'code65.c')
-rw-r--r-- | code65.c | 736 |
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 |