/****************************************************************/ /* */ /* GALAsm.c - enthält GAL-Assembler */ /* */ /* compilieren: cc GALAsm.c */ /* */ /****************************************************************/ #include "exec/types.h" #include "exec/memory.h" #include #include #include #include "GALer.h" extern int linenum, MaxFuseAdr; extern int GenJedec, GenFuse, GenChip, GenPin; extern UBYTE *actptr, *buffend, GadgetSBuff[60]; extern struct JedecStruct Jedec; struct Pin actPin; struct GAL_OLMC OLMC[8]; /*Diese Arrays geben an in welche Spalte der ent- */ /*sprechende Pin eingekoppelt (bzw. rückgekoppelt)*/ /*wird. Für die invertierende Einkopplung ist 1 zu*/ /*addieren, um die entsprechende Spalte zu erhalten*/ /* -1: keine Einkopplung auf Fuse-Matrix vorhanden */ /*GAL16V8:*/ int PinToFuse16Mode1[20] = { 2, 0, 4, 8,12,16,20,24,28,-1, 30,26,22,18,-1,-1,14,10, 6,-1 }; int PinToFuse16Mode2[20] = { 2, 0, 4, 8,12,16,20,24,28,-1, 30,-1,26,22,18,14,10, 6,-1,-1 }; int PinToFuse16Mode3[20] = { -1, 0, 4, 8,12,16,20,24,28,-1, -1,30,26,22,18,14,10, 6, 2,-1 }; /*GAL20V8:*/ int PinToFuse20Mode1[24] = { 2, 0, 4, 8,12,16,20,24,28,32,36,-1, 38,34,30,26,22,-1,-1,18,14,10, 6,-1 }; int PinToFuse20Mode2[24] = { 2, 0, 4, 8,12,16,20,24,28,32,36,-1, 38,34,-1,30,26,22,18,14,10,-1, 6,-1 }; int PinToFuse20Mode3[24] = { -1, 0, 4, 8,12,16,20,24,28,32,36,-1, -1,38,34,30,26,22,18,14,10, 6, 2,-1 }; /*dieses Array gibt an in welcher Zeile der*/ /*erste Eingang der OLMC-Zelle liegt*/ int ToOLMC[8] = { 56,48,40,32,24,16, 8, 0 }; UBYTE PinNames[24][10]; UBYTE ModeErrorStr[] = {"Modus x: Pin xx"}; LONG fsize; UBYTE *fbuff; int num_of_pins, num_of_col, modus, gal_type; int pinnameflag = 0; /* AssembleInputFile: Eingabe-Datei assemblieren Aufruf: AssembleInputFile(); */ AssembleInputFile() { UBYTE chr, filenamebuff[64]; UBYTE *bool_start; char prevOp; int i, j, k, l, n, m; int oldMaxFuseAdr, max_chr; int pass, pin_num, bool_linenum; int actOLMC, row_offset; if (MyRequest(LOAD_REQ,(UBYTE *)"Bitte Namen des Source-Files eingeben")) { strcpy(&filenamebuff,&GadgetSBuff); /*.pld an Dateinamen anfügen*/ strcat(&filenamebuff,(UBYTE *)".pld"); fsize=FileSize(&filenamebuff); switch (fsize) { case -1L: { ErrorReq(1); return(-1); break; } case -2L: { ErrorReq(2); return(-2); break; } case 0L: { ErrorReq(4); return(-4); break; } } if ((fbuff=(UBYTE *)AllocMem(fsize,MEMF_PUBLIC))) { if ((ReadFile(&filenamebuff,fsize,fbuff))) { PrintText((UBYTE *)"Datei ist geladen"); actptr = fbuff; buffend = fbuff+fsize; linenum = 1; for (n=0; n>(7-m)) & 0x1; } actptr++; n++; if (actptr>buffend) { /*Fileende erreicht ?*/ AsmError(2); /*ja, dann Fehler*/ return(-1); } } /*Pin-Namen in "PinNames" eintragen*/ pinnameflag = 0; /*Pinnamen ungültig*/ GetNextLine(); for (n=0; nACW erstellen*/ modus = 0; /*und Modus bestimmen*/ for (n=0; n<8; n++) { /*alle OLMCs untersuchen*/ if (OLMC[n].PinType == REGOUT) { /*OLMC als Reg. vorhanden?*/ modus = MODE3; /*ja, dann MUß Mode3 vorliegen*/ Jedec.GALSYN = 0; /*SYN- und AC0-Bit setzen*/ Jedec.GALAC0 = 1; break; } } if (!modus) { for (n=0; n<8; n++) { if (OLMC[n].PinType == TRIOUT) { /*OLMC als Tri. vorhanden?*/ modus = MODE2; /*ja, dann Mode2*/ Jedec.GALSYN = 1; /*SYN- und AC0-Bit setzen*/ Jedec.GALAC0 = 1; break; } } } if (!modus) { modus = MODE1; /*noch kein Mode? dann Mode1*/ Jedec.GALSYN = 1; /*SYN- und AC0-Bit setzen*/ Jedec.GALAC0 = 0; } /*falls Modus 1 voliegt alle*/ /*Ausgänge deren Typ nicht an-*/ /*gegeben wurde in komb. Ausgänge*/ /*umwandeln*/ /*falls Modus 2 oder 3 vorliegt*/ /*alle Ausgänge deren Typ nicht an-*/ /*gegeben wurde in Tristate mit per-*/ for (n=0; n<8; n++) { /*manenter Freischaltung umwandeln*/ if (OLMC[n].PinType == COM_TRI_OUT) { if (modus == MODE1) { OLMC[n].PinType = COMOUT; } else { OLMC[n].PinType = TRIOUT; OLMC[n].TriCon = TRI_VCC; } } } /*überprüfen ob Verstöße gegen den*/ /*ermittelten Modus vorliegen*/ if (modus == MODE1) { for (n=0; n<8; n++) { if (OLMC[n].PinType == INPUT) { if (gal_type == GAL16V8) { pin_num = n + 12; if ((pin_num == 15) || (pin_num == 16)) { linenum = OLMC[n].LineNum; AsmError(18); return(-1); } } if (gal_type == GAL20V8) { pin_num = n + 15; if ((pin_num == 18) || (pin_num == 19)) { linenum = OLMC[n].LineNum; AsmError(19); return(-1); } } } } } if (modus == MODE2) { for (n=0; n<8; n++) { if (OLMC[n].PinType == INPUT) { if (gal_type == GAL16V8) { pin_num = n + 12; if ((pin_num == 12) || (pin_num == 19)) { linenum = OLMC[n].LineNum; AsmError(20); return(-1); } } if (gal_type == GAL20V8) { pin_num = n + 15; if ((pin_num == 15) || (pin_num == 22)) { linenum = OLMC[n].LineNum; AsmError(21); return(-1); } } } } } /*ACW erstellen: SYN und AC0 sind*/ /*bereits festgelegt*/ for (n=0; n= 12) && (actPin.p_Pin <= 19)) || ((gal_type == GAL20V8) && (actPin.p_Pin >= 15) && (actPin.p_Pin <= 22)) ) { if (gal_type == GAL16V8) n=actPin.p_Pin-12; if (gal_type == GAL20V8) n=actPin.p_Pin-15; if (chr != 'E') { /*keine Tristate-Freigabe?*/ /*mehrfache Zuweisung?*/ if ((!OLMC[n].PinType) || (OLMC[n].PinType == INPUT)) { if (actPin.p_Neg) OLMC[n].Active = ACTIVE_LOW; else OLMC[n].Active = ACTIVE_HIGH; switch (chr) { case 'T': { OLMC[n].PinType = TRIOUT; break; } case 'R': { OLMC[n].PinType = REGOUT; break; } case 0x00:{ OLMC[n].PinType = COM_TRI_OUT; break; } } } else { AsmError(16); return(-1); } } else { if (OLMC[n].PinType == TRIOUT) { if (actPin.p_Neg) { /*kein '/' bei Tri.-Kontr.!*/ AsmError(32); return(-1); } if (OLMC[n].TriCon) { /*Tri.-Kontrolle doppelt?*/ AsmError(22); return(-1); } OLMC[n].TriCon = TRICON; /*Tri.-Kontrolle angegeben*/ } if ((!OLMC[n].PinType) || (OLMC[n].PinType == INPUT)) { AsmError(17); /*zuerst Tri.Kon.?*/ return(-1); /*dann Fehler*/ } if (OLMC[n].PinType == REGOUT) { /*Register? dann Fehler*/ AsmError(23); return(-1); } if (OLMC[n].PinType == COM_TRI_OUT) { /*kein klares .T?*/ AsmError(24); return(-1); } } } else { AsmError(15); return(-1); } } if (*actptr != '=') { /* '=' ?*/ AsmError(14); /*nein, dann Fehler*/ return(-1); } loop2: actptr++; if (GetNextChar(FALSE)) { /*Dateiende?*/ AsmError(2); /*ja, dann Fehler*/ return(-1); } IsPinName(); if (!actPin.p_Pin) { /*Pinname?*/ AsmError(11); /*nein, dann Fehler*/ return(-1); } if (actPin.p_Pin==NC_PIN) { /*NC als Pinname?*/ AsmError(12); /*ja, dann Fehler*/ return(-1); } if (GetNextChar(FALSE)) { /*Dateiende?*/ AsmError(2); /*ja, dann Fehler*/ return(-1); } /*kein Vcc/GND in den*/ /*Boolean-Gleichungen*/ if ((actPin.p_Pin == num_of_pins) || (actPin.p_Pin == num_of_pins/2)) { if (chr != 'E') { AsmError(25); /*Vcc/GND dann Fehler*/ return(-1); } } if (!pass) { /*Pass 1?*/ if ( ((gal_type == GAL16V8) /*OLMC-Pin?*/ && (actPin.p_Pin >= 12) && (actPin.p_Pin <= 19)) || ((gal_type == GAL20V8) && (actPin.p_Pin >= 15) && (actPin.p_Pin <= 22)) ) { if (gal_type == GAL16V8) n=actPin.p_Pin-12; if (gal_type == GAL20V8) n=actPin.p_Pin-15; if (!OLMC[n].PinType) { /*OLMC bereits def.?*/ OLMC[n].PinType = INPUT; /*nein, dann Eingang*/ OLMC[n].LineNum = linenum; /*Zeile merken*/ } } } /*im 2.Durchlauf Fuse-Matrix*/ /*erstellen; chr = T,R,E oder 0x00*/ if (pass) { if (chr != 'E') { if (!row_offset) { /*Zeilenoffset noch 0?*/ if ( (modus != MODE1) && (OLMC[actOLMC].PinType != REGOUT)) { row_offset = 1; } } } /*auf Verstoß gegen Modus prüfen*/ pin_num = actPin.p_Pin; if (modus == MODE1) { /*Verstoß gegen Mode 1?*/ if ((gal_type==GAL16V8) && ((pin_num==15) || (pin_num==16))) { AsmError(18); return(-1); } if ((gal_type==GAL20V8) && ((pin_num==18) || (pin_num==19))) { AsmError(19); return(-1); } } if (modus == MODE2) { /*Verstoß gegen Mode 2?*/ if ((gal_type==GAL16V8) && ((pin_num==12) || (pin_num==19))) { AsmError(20); return(-1); } if ((gal_type==GAL20V8) && ((pin_num==15) || (pin_num==22))) { AsmError(21); return(-1); } } if (modus == MODE3) { /*Verstoß gegen Mode 3?*/ if ((gal_type==GAL16V8) && ((pin_num==1) || (pin_num==11))) { AsmError(26); return(-1); } if ((gal_type==GAL20V8) && ((pin_num==1) || (pin_num==13))) { AsmError(27); return(-1); } } /*wenn Tristate-Kontrolle und GND*/ /*dann Fuse-Zeile auf 0 setzen */ if (chr == 'E') { if (prevOp == '+') { /*max. 1 Produktterm*/ AsmError(29); /*mehr, dann Fehler*/ return(-1); } if ((pin_num == num_of_pins) || (pin_num == num_of_pins/2)) { if (!prevOp && (*actptr != '*' ) && (*actptr != '+')) { if (pin_num == num_of_pins/2) { m = ToOLMC[actOLMC] * num_of_col; for (n=m; n' ') && (*actptr<='~')) return(0); /*Zeichen gefunden?*/ else actptr++; } } if (actptr>buffend) return(1); /*Fileende erreicht?*/ } } /*Zeiger auf zächste Zeile holen Ergebins: 0:Zeile gefunden, actptr=Zeiger auf diese Zeile 1:File-Ende erreicht */ GetNextLine() { for(;;) { if (*actptr == 0x0A) { actptr++; linenum++; return(0); } if (actptr>buffend) return(1); /*Fileende erreicht*/ actptr++; } } /* gibt Fehlermeldungen des GAL-Assemblers aus und gibt Speicher für File-Puffer wieder frei */ AsmError(errornum) int errornum; { FreeMem(fbuff,fsize); MyRequest(ERR_REQ,(UBYTE *)"Fehler in der Eingabe-Datei"); PrintErrorLine(linenum); switch (errornum) { case 1: { PrintText((UBYTE *)"Zeile 1: GAL-Typ erwartet"); break; } case 2: { PrintText((UBYTE *)"unerwartetes Ende der Eingabe-Datei"); break; } case 3: { PrintText((UBYTE *)"habe nach '/' Pinnamen erwartet"); break; } case 4: { PrintText((UBYTE *)"Pinname hat mehr als 8 Buchstaben und Ziffern"); break; } case 5: { PrintText((UBYTE *)"unerlaubtes Zeichen bei Pin-Definition"); break; } case 6: { PrintText((UBYTE *)"VCC/GND-Zuweisung nur an den entsprechenden Pins erlaubt"); break; } case 7: { PrintText((UBYTE *)"für VCC-Pin Zuweisung VCC erwartet"); break; } case 8: { PrintText((UBYTE *)"für GND-Pin Zuweisung GND erwartet"); break; } case 9: { PrintText((UBYTE *)"gleicher Pinname kommt mehrfach vor"); break; } case 10: { PrintText((UBYTE *)"unerlaubte Verwendung von '/'"); break; } case 11: { PrintText((UBYTE *)"unbekannter Pin-Name in den Boolean-Gleichungen"); break; } case 12: { PrintText((UBYTE *)"NC (Not Connected) in Boolean-Gleichungen nicht erlaubt"); break; } case 13: { PrintText((UBYTE *)"nach '.' wird ein 'T', 'E' oder 'R' erwartet"); break; } case 14: { PrintText((UBYTE *)"'=' wurde erwartet"); break; } case 15: { PrintText((UBYTE *)"Pin kann nicht als Ausgang programmiert werden"); break; } case 16: { PrintText((UBYTE *)"gleicher Pin ist mehrfach als Ausgang definiert worden"); break; } case 17: { PrintText((UBYTE *)"Tristate-Kontrolle: Tristate-Ausgang noch nicht definiert"); break; } case 18: { PrintText((UBYTE *)"Betriebsmodus 1: Pins 15,16 können nicht als Eingang verwendet werden"); break; } case 19: { PrintText((UBYTE *)"Betriebsmodus 1: Pins 18,19 können nicht als Eingang verwendet werden"); break; } case 20: { PrintText((UBYTE *)"Betriebsmodus 2: Pins 12,19 können nicht als Eingang verwendet werden"); break; } case 21: { PrintText((UBYTE *)"Betriebsmodus 2: Pins 15,22 können nicht als Eingang verwendet werden"); break; } case 22: { PrintText((UBYTE *)"Tristate-Kontrolle wurde mehrfach angegeben"); break; } case 23: { PrintText((UBYTE *)"Tristate-Kontrolle wurde auf Registerausgang angewendet"); break; } case 24: { PrintText((UBYTE *)"Tristate-Kontrolle ohne vorheriges '.T'"); break; } case 25: { PrintText((UBYTE *)"Ausdrücke VCC und GND nur zur Tristate-Kontrolle erlaubt (x.E = ...)"); break; } case 26: { PrintText((UBYTE *)"Betriebsmodus 3: Pins 1,11 für 'Clock' und '/OE' reserviert"); break; } case 27: { PrintText((UBYTE *)"Betriebsmodus 3: Pins 1,13 für 'Clock' und '/OE' reserviert"); break; } case 28: { PrintText((UBYTE *)"VCC und GND nicht in boolschen Ausdrücken erlaubt"); break; } case 29: { PrintText((UBYTE *)"bei der Tristate-Kontrolle ist nur EIN Produktterm erlaubt"); break; } case 30: { PrintText((UBYTE *)"maximal 8 Produktterme erlaubt"); break; } case 31: { PrintText((UBYTE *)"maximal 7 Produktterme erlaubt"); break; } case 32: { PrintText((UBYTE *)"vor 'name.E' ist kein '/' erlaubt"); break; } } } /****************************************************************/ /* ab hier stehen die Routinen, die für der Erstellung der */ /* Dokumentations-Files zuständig sind */ /****************************************************************/ /* erstelle das Chip-File*/ WriteChipFile() { UBYTE filenamebuff[64]; FILE *fp; int n; if (MyRequest(SAVE_REQ,(UBYTE *)"Bitte Namen für Chip-Datei eingeben")) { strcpy(&filenamebuff,&GadgetSBuff); /*.chp an Dateinamen anfügen*/ strcat(&filenamebuff,(UBYTE *)".chp"); if (fp=fopen(&filenamebuff,(UBYTE *)"w")) { fprintf(fp,"\n\n"); WriteSpaces(fp,32); if (gal_type == GAL16V8) fprintf(fp,"GAL16V8\n\n"); else fprintf(fp,"GAL20V8\n\n"); WriteSpaces(fp,26); fprintf(fp,"-------\\___/-------\n"); for (n=0; n= 12) && (n <= 19)) || ((gal_type == GAL20V8) && (n >= 15) && (n <= 22)) ) { if (gal_type == GAL16V8) k = n-12; else k = n-15; if (OLMC[k].PinType != INPUT) if (OLMC[k].PinType) fprintf(fp,"| Output\n"); else fprintf(fp,"| NC\n"); else fprintf(fp,"| Input\n"); } else { if (!flag) fprintf(fp,"| Input\n"); } } if (fclose(fp)==EOF) ErrorReq(8); /*Datei läßt sich nicht schließem*/ } } } /* erstelle das Fuse-File*/ WriteFuseFile() { UBYTE filenamebuff[64]; FILE *fp; int n, row, col, pin; int xor, ac1; if (MyRequest(SAVE_REQ,(UBYTE *)"Bitte Namen für Fuse-Datei eingeben")) { strcpy(&filenamebuff,&GadgetSBuff); /*.fus an Dateinamen anfügen*/ strcat(&filenamebuff,(UBYTE *)".fus"); if (fp=fopen(&filenamebuff,(UBYTE *)"w")) { if (gal_type == GAL16V8) pin = 19; else pin = 22; for (row=0; row