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/code8x30x.c

560 lines
14 KiB
C

/* code8x30x.c */
/*****************************************************************************/
/* AS-Portierung */
/* */
/* Codegenerator Signetics 8X30x */
/* */
/* Historie: 25. 6.1997 Grundsteinlegung */
/* 3. 1.1999 ChkPC-Anpassung */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "nls.h"
#include "chunks.h"
#include "bpemu.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
/*****************************************************************************/
#define AriOrderCnt 4
typedef struct
{
char *Name;
Word Code;
} FixedOrder;
static CPUVar CPU8x300,CPU8x305;
static FixedOrder *AriOrders;
/*-------------------------------------------------------------------------*/
static int InstrZ;
static void AddAri(char *NName, Word NCode)
BEGIN
if (InstrZ>=AriOrderCnt) exit(255);
AriOrders[InstrZ].Name=NName;
AriOrders[InstrZ++].Code=NCode;
END
static void InitFields(void)
BEGIN
AriOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*AriOrderCnt); InstrZ=0;
AddAri("MOVE",0); AddAri("ADD",1); AddAri("AND",2); AddAri("XOR",3);
END
static void DeinitFields(void)
BEGIN
free(AriOrders);
END
/*-------------------------------------------------------------------------*/
static Boolean DecodeReg(char *Asc, Word *Erg, ShortInt *ErgLen)
BEGIN
Boolean OK;
Word Acc;
LongInt Adr;
char *z;
*ErgLen=(-1);
if (strcasecmp(Asc,"AUX")==0)
BEGIN
*Erg=0; return True;
END
if (strcasecmp(Asc,"OVF")==0)
BEGIN
*Erg=8; return True;
END
if (strcasecmp(Asc,"IVL")==0)
BEGIN
*Erg=7; return True;
END
if (strcasecmp(Asc,"IVR")==0)
BEGIN
*Erg=15; return True;
END
if ((toupper(*Asc)=='R') AND (strlen(Asc)>1) AND (strlen(Asc)<4))
BEGIN
Acc=0; OK=True;
for (z=Asc+1; *z!='\0'; z++)
if (OK)
if ((*z<'0') OR (*z>'7')) OK=False;
else Acc=(Acc << 3)+(*z-'0');
if ((OK) AND (Acc<32))
BEGIN
if ((MomCPU==CPU8x300) AND (Acc>9) AND (Acc<15))
BEGIN
WrXError(1445,Asc); return False;
END
else *Erg=Acc;
return True;
END
END
if ((strlen(Asc)==4) AND (strncasecmp(Asc+1,"IV",2)==0) AND (Asc[3]>='0') AND (Asc[3]<='7'))
if (toupper(*Asc)=='L')
BEGIN
*Erg=Asc[3]-'0'+0x10; return True;
END
else if (toupper(*Asc)=='R')
BEGIN
*Erg=Asc[3]-'0'+0x18; return True;
END
/* IV - Objekte */
Adr=EvalIntExpression(Asc,UInt24,&OK);
if (OK)
BEGIN
*ErgLen=Adr & 7;
*Erg=0x10+((Adr & 0x10) >> 1)+((Adr & 0x700) >> 8);
return True;
END
else return False;
END
static char *HasDisp(char *Asc)
BEGIN
int Lev;
char *z;
int l=strlen(Asc);
if (Asc[l-1]==')')
BEGIN
z=Asc+l-2; Lev=0;
while ((z>=Asc) AND (Lev!=-1))
BEGIN
switch (*z)
BEGIN
case '(': Lev--; break;
case ')': Lev++; break;
END
if (Lev!=-1) z--;
END
if (Lev!=-1)
BEGIN
WrError(1300); return Nil;
END
END
else z=Nil;
return z;
END
static Boolean GetLen(char *Asc, Word *Erg)
BEGIN
Boolean OK;
FirstPassUnknown=False;
*Erg=EvalIntExpression(Asc,UInt4,&OK); if (NOT OK) return False;
if (FirstPassUnknown) *Erg=8;
if (NOT ChkRange(*Erg,1,8)) return False;
*Erg&=7; return True;
END
/*-------------------------------------------------------------------------*/
/* Symbol: 00AA0ORL */
static Boolean DecodePseudo(void)
BEGIN
LongInt Adr,Ofs,Erg;
Word Len;
Boolean OK;
if ((Memo("LIV")) OR (Memo("RIV")))
BEGIN
Erg=0x10*Ord(Memo("RIV"));
if (ArgCnt!=3) WrError(1110);
else
BEGIN
Adr=EvalIntExpression(ArgStr[1],UInt8,&OK);
if (OK)
BEGIN
Ofs=EvalIntExpression(ArgStr[2],UInt3,&OK);
if (OK)
if (GetLen(ArgStr[3],&Len))
BEGIN
PushLocHandle(-1);
EnterIntSymbol(LabPart,Erg+(Adr << 16)+(Ofs << 8)+(Len & 7),SegNone,False);
PopLocHandle();
END
END
END
return True;
END
return False;
END
static void MakeCode_8x30X(void)
BEGIN
Boolean OK;
Word SrcReg,DestReg;
ShortInt SrcLen,DestLen;
LongInt Op;
Word Rot,Adr;
int z;
char *p;
String tmp;
CodeLen=0; DontPrint=False;
/* zu ignorierendes */
if (Memo("")) return;
/* Pseudoanweisungen */
if (DecodePseudo()) return;
/* eingebaute Makros */
if (Memo("NOP")) /* NOP = MOVE AUX,AUX */
BEGIN
if (ArgCnt!=0) WrError(1110);
else
BEGIN
WAsmCode[0]=0x0000; CodeLen=1;
END
return;
END
if (Memo("HALT")) /* HALT = JMP * */
BEGIN
if (ArgCnt!=0) WrError(1110);
else
BEGIN
WAsmCode[0]=0xe000+(EProgCounter() & 0x1fff); CodeLen=1;
END
return;
END
if ((Memo("XML")) OR (Memo("XMR")))
BEGIN
if (ArgCnt!=1) WrError(1110);
else if (MomCPU<CPU8x305) WrError(1500);
else
BEGIN
Adr=EvalIntExpression(ArgStr[1],Int8,&OK);
if (OK)
BEGIN
WAsmCode[0]=0xca00+(Ord(Memo("XER")) << 8)+(Adr & 0xff);
CodeLen=1;
END
END
return;
END
/* Datentransfer */
if (Memo("SEL"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
Op=EvalIntExpression(ArgStr[1],UInt24,&OK);
if (OK)
BEGIN
WAsmCode[0]=0xc700+((Op & 0x10) << 7)+((Op >> 16) & 0xff);
CodeLen=1;
END
END
return;
END
if (Memo("XMIT"))
BEGIN
if ((ArgCnt!=2) AND (ArgCnt!=3)) WrError(1110);
else if (DecodeReg(ArgStr[2],&SrcReg,&SrcLen))
if (SrcReg<16)
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
Adr=EvalIntExpression(ArgStr[1],Int8,&OK);
if (OK)
BEGIN
WAsmCode[0]=0xc000+(SrcReg << 8)+(Adr & 0xff);
CodeLen=1;
END
END
END
else
BEGIN
if (ArgCnt==2)
BEGIN
Rot=0xffff; OK=True;
END
else OK=GetLen(ArgStr[3],&Rot);
if (OK)
BEGIN
if (Rot==0xffff)
Rot=(SrcLen==-1) ? 0 : SrcLen;
if ((SrcLen!=-1) AND (Rot!=SrcLen)) WrError(1131);
else
BEGIN
Adr=EvalIntExpression(ArgStr[1],Int5,&OK);
if (OK)
BEGIN
WAsmCode[0]=0xc000+(SrcReg << 8)+(Rot << 5)+(Adr & 0x1f);
CodeLen=1;
END
END
END
END
return;
END
/* Arithmetik */
for (z=0; z<AriOrderCnt; z++)
if (Memo(AriOrders[z].Name))
BEGIN
if ((ArgCnt!=2) AND (ArgCnt!=3)) WrError(1110);
else if (DecodeReg(ArgStr[ArgCnt],&DestReg,&DestLen))
if (DestReg<16) /* Ziel Register */
BEGIN
if (ArgCnt==2) /* wenn nur zwei Operanden und Ziel Register... */
BEGIN
p=HasDisp(ArgStr[1]); /* kann eine Rotation dabei sein */
if (p!=Nil)
BEGIN /* jau! */
strcpy(tmp,p+1); tmp[strlen(tmp)-1]='\0';
Rot=EvalIntExpression(tmp,UInt3,&OK);
if (OK)
BEGIN
*p='\0';
if (DecodeReg(ArgStr[1],&SrcReg,&SrcLen))
if (SrcReg>=16) WrXError(1445,ArgStr[1]);
else
BEGIN
WAsmCode[0]=(AriOrders[z].Code << 13)+(SrcReg << 8)+(Rot << 5)+DestReg;
CodeLen=1;
END
END
END
else /* noi! */
BEGIN
if (DecodeReg(ArgStr[1],&SrcReg,&SrcLen))
BEGIN
WAsmCode[0]=(AriOrders[z].Code << 13)+(SrcReg << 8)+DestReg;
if ((SrcReg>=16) AND (SrcLen!=-1)) WAsmCode[0]+=SrcLen << 5;
CodeLen=1;
END
END
END
else /* 3 Operanden --> Quelle ist I/O */
BEGIN
if (GetLen(ArgStr[2],&Rot))
if (DecodeReg(ArgStr[1],&SrcReg,&SrcLen))
if (SrcReg<16) WrXError(1445,ArgStr[1]);
else if ((SrcLen!=-1) AND (SrcLen!=Rot)) WrError(1131);
else
BEGIN
WAsmCode[0]=(AriOrders[z].Code << 13)+(SrcReg << 8)+(Rot << 5)+DestReg;
CodeLen=1;
END
END
END
else /* Ziel I/O */
BEGIN
if (ArgCnt==2) /* 2 Argumente: Laenge=Laenge Ziel */
BEGIN
Rot=DestLen; OK=True;
END
else /* 3 Argumente: Laenge=Laenge Ziel+Angabe */
BEGIN
OK=GetLen(ArgStr[2],&Rot);
if (OK)
BEGIN
if (FirstPassUnknown) Rot=DestLen;
if (DestLen==-1) DestLen=Rot;
OK=Rot==DestLen;
if (NOT OK) WrError(1131);
END
END
if (OK)
if (DecodeReg(ArgStr[1],&SrcReg,&SrcLen))
BEGIN
if ((Rot==0xffff))
Rot=((SrcLen==-1)) ? 0 : SrcLen;
if ((DestReg>=16) AND (SrcLen!=-1) AND (SrcLen!=Rot)) WrError(1131);
else
BEGIN
WAsmCode[0]=(AriOrders[z].Code << 13)+(SrcReg << 8)+(Rot << 5)+DestReg;
CodeLen=1;
END
END
END
return;
END
if (Memo("XEC"))
BEGIN
if ((ArgCnt!=1) AND (ArgCnt!=2)) WrError(1110);
else
BEGIN
p=HasDisp(ArgStr[1]);
if (p==Nil) WrError(1350);
else
BEGIN
strcpy(tmp,p+1); tmp[strlen(tmp)-1]='\0';
if (DecodeReg(tmp,&SrcReg,&SrcLen))
BEGIN
*p='\0';
if (SrcReg<16)
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
WAsmCode[0]=EvalIntExpression(ArgStr[1],UInt8,&OK);
if (OK)
BEGIN
WAsmCode[0]+=0x8000+(SrcReg << 8);
CodeLen=1;
END
END
END
else
BEGIN
if (ArgCnt==1)
BEGIN
Rot=0xffff; OK=True;
END
else OK=GetLen(ArgStr[2],&Rot);
if (OK)
BEGIN
if (Rot==0xffff)
Rot=(SrcLen==-1) ? 0 : SrcLen;
if ((SrcLen!=-1) AND (Rot!=SrcLen)) WrError(1131);
else
BEGIN
WAsmCode[0]=EvalIntExpression(ArgStr[1],UInt5,&OK);
if (OK)
BEGIN
WAsmCode[0]+=0x8000+(SrcReg << 8)+(Rot << 5);
CodeLen=1;
END
END
END
END
END
END
END
return;
END
/* Spruenge */
if (Memo("JMP"))
BEGIN
if (ArgCnt!=1) WrError(1110);
else
BEGIN
WAsmCode[0]=EvalIntExpression(ArgStr[1],UInt13,&OK);
if (OK)
BEGIN
WAsmCode[0]+=0xe000; CodeLen=1;
END
END
return;
END
if (Memo("NZT"))
BEGIN
if ((ArgCnt!=2) AND (ArgCnt!=3)) WrError(1110);
else if (DecodeReg(ArgStr[1],&SrcReg,&SrcLen))
if (SrcReg<16)
BEGIN
if (ArgCnt!=2) WrError(1110);
else
BEGIN
Adr=EvalIntExpression(ArgStr[2],UInt13,&OK);
if (OK)
if ((NOT SymbolQuestionable) AND ((Adr >> 8)!=(EProgCounter() >> 8))) WrError(1910);
else
BEGIN
WAsmCode[0]=0xa000+(SrcReg << 8)+(Adr & 0xff);
CodeLen=1;
END
END
END
else
BEGIN
if (ArgCnt==2)
BEGIN
Rot=0xffff; OK=True;
END
else OK=GetLen(ArgStr[2],&Rot);
if (OK)
BEGIN
if (Rot==0xffff)
Rot=(SrcLen==-1) ? 0 : SrcLen;
if ((SrcLen!=-1) AND (Rot!=SrcLen)) WrError(1131);
else
BEGIN
Adr=EvalIntExpression(ArgStr[ArgCnt],UInt13,&OK);
if (OK)
if ((NOT SymbolQuestionable) AND ((Adr >> 5)!=(EProgCounter() >> 5))) WrError(1910);
else
BEGIN
WAsmCode[0]=0xa000+(SrcReg << 8)+(Rot << 5)+(Adr & 0x1f);
CodeLen=1;
END
END
END
END
return;
END;
WrXError(1200,OpPart);
END
static Boolean IsDef_8x30X(void)
BEGIN
return (Memo("LIV") OR Memo("RIV"));
END
static void SwitchFrom_8x30X()
BEGIN
DeinitFields();
END
static void SwitchTo_8x30X(void)
BEGIN
TurnWords=False; ConstMode=ConstModeMoto; SetIsOccupied=False;
PCSymbol="*"; HeaderID=0x3a; NOPCode=0x0000;
DivideChars=","; HasAttrs=False;
ValidSegs=1<<SegCode;
Grans[SegCode]=2; ListGrans[SegCode]=2; SegInits[SegCode]=0;
SegLimits[SegCode] = 0x1fff;
MakeCode=MakeCode_8x30X; IsDef=IsDef_8x30X;
SwitchFrom=SwitchFrom_8x30X; InitFields();
END
void code8x30x_init(void)
BEGIN
CPU8x300=AddCPU("8x300",SwitchTo_8x30X);
CPU8x305=AddCPU("8x305",SwitchTo_8x30X);
END