#ifndef __ARITH_C #define __ARITH_C /* arith.c ************************************************ Makros zur Benutzung des Arithmetik-Prozessors im 80C517x DIVL Quotient und Rest einer long- und einer int-Zahl DIV Quotient und Rest zweier int-Zahlen MUL Produkt zweier int-Zahlen SHL Links-Schieben einer long-Zahl SHR Rechts-Schieben einer long-Zahl NOR Normalisieren einer long-Zahl Achtung: (1) * Da bei Makros keine Typenprüfung erfolgt, muss * man die jeweils übergebenen Parameter sorgfältig prüfen. (2) * Man darf nur Variablen und keine Konstanten übergeben * */ /* sfr ARCON=0xEF; sfr MD0=0xE9; sfr MD1=0xEA; sfr MD2=0xEB; sfr MD3=0xEC; sfr MD4=0xED; sfr MD5=0xEE; */ /* DIVL Division einer 32-Bit-Zahl durch eine 16-Bit Zahl ********************************************************* Aufruf DIVL(dd,ds,qu,re) EIN dd unsigned long ds unsigned int AUS qu unsigned long re unsigned int Division kann durch DIV0-Makro getestet werden */ #define DIVL(dd,ds,qu,re) \ MD0=*((unsigned char *)&dd+3);\ MD1=*((unsigned char *)&dd+2);\ MD2=*((unsigned char *)&dd+1);\ MD3=*((unsigned char *)&dd);\ MD4=*((unsigned char *)&ds+1);\ MD5=*((unsigned char *)&ds);\ *((unsigned char *)&qu+3)=MD0;\ *((unsigned char *)&qu+2)=MD1;\ *((unsigned char *)&qu+1)=MD2;\ *((unsigned char *)&qu)=MD3;\ *((unsigned char *)&re+1)=MD4;\ *((unsigned char *)&re)=MD5 /* DIV Division einer 16-Bit-Zahl durch eine 16-Bit Zahl ********************************************************* Aufruf DIVL(dd,ds,qu,re) EIN dd unsigned int ds unsigned int AUS qu unsigned int re unsigned int */ #define DIV(dd,ds,qu,re) \ MD0=*((unsigned char *)&dd+1);\ MD1=*((unsigned char *)&dd);\ MD4=*((unsigned char *)&ds+1);\ MD5=*((unsigned char *)&ds);\ *((unsigned char *)&qu+1)=MD0;\ *((unsigned char *)&qu)=MD1;\ *((unsigned char *)&re+1)=MD4;\ *((unsigned char *)&re)=MD5 /* DIV0 Testen, ob Division durch Null erfolgt ist ********************************************************* Aufruf DIV0() in Vergleichsoperationen */ #define DIV0() (ARCON&0x40) /* MUL Multiplikation zweiter 16-Bit Zahlen ********************************************************* Aufruf MUL(md,mr,pr) EIN md unsigned int mr unsigned int AUS pr unsigned long Ein Überlauf kann mit MUL0 getestet werden */ #define MUL(md,mr,pr) \ MD0=*((unsigned char *)&md+1);\ MD4=*((unsigned char *)&mr+1);\ MD1=*((unsigned char *)&md);\ MD5=*((unsigned char *)&mr);\ *((unsigned char *)&pr+3)=MD0;\ *((unsigned char *)&pr+2)=MD1;\ *((unsigned char *)&pr+1)=MD2;\ *((unsigned char *)&pr)=MD3 /* MUL0 Testen, ob Multiplikation eine Überlauf bedingt hat ********************************************************* Aufruf MUL0() in Vergleichsoperationen */ #define MUL0() DIV0 /* SHL Links-Schieben einer 32-Bit-Zahl ********************************************************* Aufruf SHL(op,er,sch) EIN op unsigned long Zahl sch unsigned int Anzahl der Schiebeschritte AUS er unsigned int Ergebnis */ #define SHL(op,er,sch) \ MD0=*((unsigned char *)&op+3);\ MD1=*((unsigned char *)&op+2);\ MD2=*((unsigned char *)&op+1);\ MD3=*((unsigned char *)&op);\ ARCON=sch;\ *((unsigned char *)&er+3)=MD0;\ *((unsigned char *)&er+2)=MD1;\ *((unsigned char *)&er+1)=MD2;\ *((unsigned char *)&er)=MD3 /* SHR Rechts-Schieben einer 32-Bit-Zahl ********************************************************* Aufruf SHR(op,er,sch) EIN op unsigned long Zahl sch unsigned int Anzahl der Schiebeschritte AUS er unsigned int Ergebnis */ #define SHR(op,er,sch) \ MD0=*((unsigned char *)&op+3);\ MD1=*((unsigned char *)&op+2);\ MD2=*((unsigned char *)&op+1);\ MD3=*((unsigned char *)&op);\ ARCON=0x20|sch;\ *((unsigned char *)&er+3)=MD0;\ *((unsigned char *)&er+2)=MD1;\ *((unsigned char *)&er+1)=MD2;\ *((unsigned char *)&er)=MD3 /* NOR Normalisieren einer 32-Bit-Zahl ********************************************************* Aufruf NOR(op,er,sch) EIN op unsigned long Zahl AUS er unsigned int Ergebnis sch unsigned char Anzahl der Schiebeschritte */ #define NOR(op,er,sch) \ MD0=*((unsigned char *)&op+3);\ MD1=*((unsigned char *)&op+2);\ MD2=*((unsigned char *)&op+1);\ MD3=*((unsigned char *)&op);\ ARCON&=0xE0;\ *((unsigned char *)&er+3)=MD0;\ *((unsigned char *)&er+2)=MD1;\ *((unsigned char *)&er+1)=MD2;\ *((unsigned char *)&er)=MD3;\ *sch=ARCON&0x1F #ifdef LDEBUG void ldebug_arith(void) { unsigned long la, lb; unsigned int ia, ib, ic, id; /* zunächst die normale ganzzahlige Division */ la=10; ia=2; lb = la/ia; /* 1280 us */ ib = la%ia; /* 1268 us */ DIVL(la,ia,lb,ib); /* 24 us */ ia=12; ib=5; MUL(ia,ib,la); /* 16 us */ la=1; SHL(la,lb,15); /* 18 us */ la=0x8000; SHL(la,lb,1); /* 18 us */ la=0x80000000; SHR(la,lb,15); /* 18 us */ } void main(void) { while (1) ldebug_arith(); } #endif LDEBUG #endif __ARITH_C