737 lines
24 KiB
C
737 lines
24 KiB
C
/* 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
|