/* LSYMEDIT (GED) -- Layout Part Symbol Edit Functions */ /* LSYMEDIT (GED) -- Layoutbauteil Edititierfunktionen */ /* -- INTENDED FOR KEY-CALL USE -- */ /* // Copyright (c) 1993-2012 Oliver Bartels F+E, Muenchen // Author: Manfred Baumeister // Changes History: // rl (120427) RELEASED FOR BAE V7.8. // rl (101019) RELEASED FOR BAE V7.6. // rl (100310) ENHANCEMENT: // Added edit batch call function. // rl (091021) RELEASED FOR BAE V7.4. // rl (081014) RELEASED FOR BAE V7.2. // rl (071029) RELEASED FOR BAE V7.0. // rl (060829) RELEASED FOR BAE V6.8. // rl (050906) RELEASED FOR BAE V6.6. // rl (040811) RELEASED FOR BAE V6.4. // rl (031204) ENHANCEMENT: // Added pin matrix placement support. // Added alphabetic pin indexing support. // rl (030904) RELEASED FOR BAE V6.2. // rl (021209) RELEASED FOR BAE V6.0. // rl (020724) ENHANCEMENT: // Added enhanced dialog boxes to place pinrow/pinlist and pin // macro change functions. // rl (020618) RELEASED FOR BAE V5.4. // rl (010625) RELEASED FOR BAE V5.0. // rl (010529) BUGFIX: // Fixed problem with malfunctional decremental pin numbering. // rl (010503) ENHANCEMENT: // Added optional parameter settings from bae.ini file. // rl (000525) RELEASED FOR BAE V4.6. // rl (991216) ENHANCEMENT: // Pin number step value introduced. // rl (990625) RELEASED FOR BAE V4.4. // rl (980910) RELEASED FOR BAE V4.2. // mb (980712) ENHANCEMENT: // Pulldown menu delimiters introduced. // mb (980712) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (970929) RELEASED FOR BAE V4.0. // mb (970127) BAEV3.4 BUGFIX/WORKAROUND: // Padstack macro selection for placepinlist function // corrected (i.e. adapted to new BAE V3.4 feature for // selecting padstack macro library file). // mb (960919) RELEASED FOR BAE V3.4. // mb (960209) ENHANCEMENT: // Pin name start pattern query introduced to placepins // function. // mb (951004) ENHANCEMENT: // Pin rotate option introduced to placepinrow function. // mb (95) RELEASED FOR BAE V3.2. // mb (94) RELEASED FOR BAE V3.0. // mb (94) ENHANCEMENT: // Introduced Change Pin Macro function // mb (94) ORIGINAL CODING: // Integrated LPLCPINL, LPLCPINR, LSINSPCK, LSYMORIG. // mb (93) RELEASED FOR BAE V2.6. // mb (93) ORIGINAL CODING. // // DESCRIPTION // // The lsymedit User Language program activates a menu with // advanced layout symbol edit functions such as setting the // part origin and/or the insertion pick, placing pin lists // and/or pin rows, changing the element boundaries, etc. */ // Includes #include "baeparam.ulh" // User Language BAE param. access #include "pop.ulh" // User Language popup utilities #include "lay.ulh" // User Language layout utilities // Disable undo state request #pragma ULCALLERNOUNDO // INI file parameter name definitions #define PAR_BEL "LSEDBEL_GED" // Boundary enlarge length #define PAR_INSPTXTS "LSINSPTXTS_GED"// Insertion pick text size // Messages string UPRABORT = M_UPRABORT(); string REPORIGSET = M("Neuer Nullpunkt wurde gesetzt.", "New origin has been set."); string REPPICKSET = M("Neuer Bestueckpick wurde gesetzt.", "New insertion pick has been set."); string REPSTKHD = M("Padstacks / %s %s :","Padstacks / %s %s :"); string REPSTKCHG = M(" Pin-Padstack-Makros getauscht.", " pin padstack macros have been changed."); string REPPINCWRN = M("Mehr als %d Pins in eine Richtung! Fortfahren ?", "More than %d pins in one direction! Continue ?"); string REPPATDIR = M("Endname '%s' vor Startname '%s'!", "End name '%s' before start name '%s'"); string REPPATWRN = M("Name '%s' enthaelt Zeichen ausserhalb der Zeichenmenge!", "Name '%s' contains characters not defined in set!"); string UPRFCT = M("Symbol-Editier-Funktion selektieren!", "Select Symbol Edit Function!"); string UPRFCT1 = M("&Sichern und Laden Naechstes", "Save and Load &Next"); string UPRFCT2 = M("%Workspace &kleiner","%&Shrink Workspace"); string UPRFCT3 = M("Workspace &groesser","&Enlarge Workspace"); string UPRFCT4 = M("%&Nullpunkt setzen","%Set &Origin"); string UPRFCT5 = M("&Bestueckpick setzen","Set &Insertion Pick"); string UPRFCT6 = M("%Pin-/Text&liste platzieren","%Place Pin/Text &List"); string UPRFCT7 = M("Pin-/Text&reihe/-matrix platzieren", "Place Pin/Text &Row/Matrix"); string UPRFCT8 = M("Pin&makros tauschen","Change Pin &Macros"); string UPRFCT9 = M("%&Edit Batch aufrufen","C&all Edit Batch"); string UPRORIGFCT = M("Nullpunkt-Position selektieren!", "Select Origin Position!"); string UPRORIG1 = M("Pin '&1'","Pin '&1'"); string UPRORIG2 = M("Pin &Schwerpunkt","Pin &Gravity Point"); string UPRREPTEXT = M("Text auf Bestueckdatenlage ersetzen ? ", "Replace Text on Insertion Data Layer ? "); string UPRNAMSPAT = M("%Start-Pattern fuer Pinnamen : ", "%Pin Name Start Pattern : "); string UPRNAMEPAT = M("%End-Pattern fuer Pinnamen : ", "%Pin Name End Pattern : "); string UPRSTKPROJ = M("Padstacks in Projektdatei :", "Padstacks in Project File :"); string UPRSTKDB = M("Padstacks in Bibliothek :","Library Padstacks :"); string UPRDPINDAT = M("Pinplatzierungsdaten","Pin Placement Data"); string UPRDTXTDAT = M("Textplatzierungsdaten","Text Placement Data"); string UPRPINPAT = M("Pinnamen : ","Pin Names : "); string UPRTXTPAT = M("Texte : ","Texts : "); string UPRPINLIST = M("&Pinliste","&Pin List"); string UPRTXTLIST = M("&Textliste","&Text List"); string UPRPINROW = M("Pin&reihe","Pin &Row"); string UPRPINMAT = M("Pin&matrix X-Index && Y-Index", "Pin &Matrix X Index && Y Index"); string UPRPINMATI = M("Pinmatrix durchlaufender &Index", "Pin Matrix Single Name &Index"); string UPRPINRC = M("Pins pro Reihe :","Pins per Row :"); string UPRTXTRC = M("Texte pro Reihe :","Texts per Row :"); string UPRTXTROW = M("&Textreihe","&Text Row"); string UPRTXTMAT = M("T&extmatrix X-Index && Y-Index", "T&ext Matrix X Index && Y Index"); string UPRTXTMATI = M("Te&xtmatrix durchlaufender &Index", "Te&xt Matrix Single Name Index"); string UPRCPMODE = M("Gegenpinreihe :","Counter Pin Row :"); string UPRCTMODE = M("Gegentextreihe :","Counter Text Row :"); string UPRCPMODE1 = M("&keine","&none"); string UPRCPMODE2 = M("&Gleiche Orientierung","&Same orientation"); string UPRCPMODE3 = M("Pin&drehung 180 Grad","Pin &rotation 180 degree"); string UPRDPIN1 = M("von :","from :"); string UPRDPIN2 = M("bis :","to :"); string UPRDPINSEP = M("+","+"); string UPRDPINSTEP = M("Zaehlschrittweite :","Count stepping :"); string UPRPINNUMW = M("Index-/Nummernbreite :","Index/Number width :"); string UPRPINNUMW1 = M("&Std. (1, 2, ...)","&Std. (1, 2, ...)"); string UPRPINNUMW2 = M("&2 (01, 02, ...)","&2 (01, 02, ...)"); string UPRPINNUMW3 = M("&3 (001, 002, ...)","&3 (001, 002, ...)"); string UPRPINNUMW4 = M("&4 (0001, 0002, ...)","&4 (0001, 0002, ...)"); string UPRPINNUMW5 = M("ASCII (a, b, ..., z, aa, ab, ...)", "ASCII (a, b, ..., z, aa, ab, ...)"); string UPRASCSET = M("Zeichenmenge :","Character Set :"); string UPRALLASC = M("a-z","a-z"); string UPRLAYOK = M("Letzte Lage","Last Layer"); string UPRINDEX1 = M("Index 1","Index 1"); string UPRINDEX2 = M("Index 2","Index 2"); string UPRDINDEX1 = M("Richtung 1 Namensindex :", "Direction 1 Name Index :"); string UPRDINDEX2 = M("Richtung 2 Namensindex :", "Direction 2 Name Index :"); string UPRPIN1 = M("Nummer des ersten Pins ? ", "Number of First Pin ? "); string UPRPIN2 = M("Nummer des letzten Pins ? ", "Number of Last Pin ? "); string UPRPINSTEP = M("Zaehlschritte zwischen Pins (1,2,3...) ? ", "Count steps between pins (1,2,3...) ? "); string UPRPINMAC = M("Pin Padstack Makro (<.>:Library) ? ", "Pin Padstack Macro (<.>:Library) ? "); string UPRPINMACL = M("Pin Padstack Makro in '%s' ? ", "Pin Padstack Macro in '%s' ? "); string UPRDPINMAC = M("Pin Padstack Makro :", "Pin Padstack Macro :"); string UPRREPLACE = M("Pin '%s' ersetzen ? ","Replace Pin '%s' ? "); string UPRPOS2 = M("Zweite Pinposition waehlen ('%s'/'%s')!", "Select Second Pin Position ('%s'/'%s')!"); string UPRMPOS1 = M("Zweite Pinposition Richtung 1 waehlen ('%s'/'%s')!", "Select Second Pin Direction 1 Position ('%s'/'%s')!"); string UPRMPOS2 = M("Zweite Pinposition Richtung 2 waehlen ('%s'/'%s')!", "Select Second Pin Direction 2 Position ('%s'/'%s')!"); string UPRCPPOS = M("Erste Pinposition der Gegenreihe waehlen ('%s'/'%s')!", "Select First Counter Row Pin Position ('%s'/'%s')!"); string UPRTXT2 = M("Zweite Textposition waehlen ('%s')!", "Select Second Text Position ('%s')!"); string UPRMTXT1 = M("Zweite Textposition Richtung 1 waehlen ('%s')!", "Select Second Text Direction 1 Position ('%s')!"); string UPRMTXT2 = M("Zweite Textposition Richtung 2 waehlen ('%s')!", "Select Second Text Direction 2 Position ('%s')!"); string UPRCPTXT = M("Erste Textposition der Gegenreihe waehlen ('%s')!", "Select First Counter Row Text Position ('%s')!"); string UPRTLAY = M("Lage fuer Text waehlen!","Select Text Layer!"); string UPROLDSTK = M("Auszutauschendes Padstack Makro ? ", "Padstack Macro to be Changed ? "); string UPRNEWSTK = M("Neues Padstack Makro in '%s' ? ", "New Padstack Macro in '%s' ? "); string UPRDNEWSTK = M("Neues Padstack Makro :", "New Padstack Macro :"); string ERRINVNUM = M("Ungueltige Pinnummer!", "Invalid pin number!"); string ERRINVPINMAC = M("Ungueltiger Pinmakroname!", "Invalid pin macro name!"); string ERRTXTLEN = M("Maximallaenge "+itoa(MAXTEXTLEN)+" ueberschritten ('%s')!", "Maximum length "+itoa(MAXTEXTLEN)+" violated ('%s'!"); string ERRNAMELEN = M("Maximallaenge "+itoa(MAXKEYLEN)+" ueberschritten ('%s')!", "Maximum length "+itoa(MAXKEYLEN)+"violated ('%s'!"); string ERRMULPIN = M("Pin '%s' ist bereits platziert!", "Pin '%s' already placed!"); string ERRNOORIG = M("Kein Nullpunkt-Pin gefunden!", "No origin pin found!"); string ERRTEXT = M("Text konnte nicht erzeugt werden!", "Error placing text!"); string ERRNOMACRO = M("Pin-Makro '%s' in Bibliothek '%s' nicht vorhanden!", "Pin macro '%s' not available in library '%s'!"); string ERRNOCOPY = M("Pin-Makro '%s' konnte nicht uebernommen werden!", "Could not copy macro '%s' into database!"); string ERRPLACE = M("Fehler beim Platzieren des Pins '%s'!", "Error placing pin '%s'!"); string ERRSELPIN = M("Fehler beim Selektieren des Pins '%s'!", "Error selecting pin '%s'!"); string ERRINPVAL = M_ERRINPVAL(); // Global User Language program variables #define UL_LOADNEXT "loadnext" // ULP: Load Next Element #define UL_LAYEDBAT "layedbat" // ULP: Layout Edit Batch // Global variables double BEL = bae_inidblval(PAR_BEL,0.00635) /* Boundary enlarge length 1/4" */; #define COLFIN 2 // Fade in color value #define INSPICKTXT "$" // Insertion pick text double INSPICKTXTS = bae_inidblval(PAR_INSPTXTS,0.00254) /* Insertion pick text size */; string pinmacro = "" /* Library pin macro name */; int ddbclass = bae_planddbclass() /* SCM plan DDB class */; #define ALLASC "abcdefghijklmnopqrstuvwxyz" // All characters #define PINWRN 100 // Pin count warning threshold #define GV_PINMACRO "pinmacro" // Pin macro name #define GV_CHARSET1 "charset1" // Text/pin name character set 1 #define GV_CHARSET2 "charset2" // Text/pin name character set 2 #define GV_MATMODE "tpmatmode" // Text/pin row mode #define GV_MATI1START "tpmat1start" // Text/pin row index 1 start #define GV_MATI1END "tpmat1end" // Text/pin row index 1 end #define GV_MATN1START "tpmat1nstart" // Text/pin row name 1 start #define GV_MATN1END "tpmat1nend" // Text/pin row name 1 end #define GV_MAT1STEP "tpmat1step" // Text/pin row step 1 #define GV_MAT1IDX "tpmat1idx" // Text/pin row index 1 mode #define GV_MATI2START "tpmat2start" // Text/pin row index 2 start #define GV_MATI2END "tpmat2end" // Text/pin row index 2 end #define GV_MATN2START "tpmat2nstart" // Text/pin row name 2 start #define GV_MATN2END "tpmat2nend" // Text/pin row name 2 end #define GV_MAT2STEP "tpmat2step" // Text/pin row step 2 #define GV_MAT2IDX "tpmat2idx" // Text/pin row index 2 mode #define GV_MATPREF "tpmatpref" // Text/pin row prefix #define GV_MATINF "tpmatinf" // Text/pin row infix #define GV_MATSUFF "tpmatsuff" // Text/pin row suffix #define GV_MATCPM "tpmatcpm" // Text/pin counter row #define GV_LASTLAY "tpmatlay" // Text last layer double PI = cvtangle(180.0,1,2) /* (Constant) PI value */; // Main program void main() { string p_dis = ddbclass==DDBCLLPRT ? "" : "," /* Part functions disable */; // Ask for layout symbol edit function type bae_defmenusel(-1); bae_promptdialog(UPRFCT); switch (bae_askmenu(10,UPRFCT1,UPRFCT2,UPRFCT3,UPRFCT4, p_dis+UPRFCT5,UPRFCT6,UPRFCT7,p_dis+UPRFCT8,UPRFCT9,UPRABORT)) { // Save and Load Next case 0 : // Save current element bae_clriactqueue(); call(MNU_GEDSAVELEM); // Run the load next element program runulprog(UL_LOADNEXT); break; // Workspace shrink case 1 : // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); baewsshrink(1); break; // Workspace enlarge case 2 : // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); baewsresize(BEL,1); break; // Set origin case 3 : setorigintype(); break; // Set insertion pick case 4 : inspicktext(); break; // Place pin list case 5 : placepins(0); break; // Place pin row/matrix case 6 : placepins(1); break; // Change pin macros case 7 : changepinmacs(); break; // Edit batch call case 8 : // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Run the symbol edit batch program bae_storetextiact(3,"call"); runulprog(UL_LAYEDBAT); break; // Abort on default default : } } // Layout symbol origin routines void setorigintype() /* // Set the origin according to a pin selector function */ { index L_NREF nref /* Named reference index */; double ox,oy /* Origin coordinates */; int pincnt = 0 /* Pin count */; int gridlock /* Grid lock mode */; // Abort if invalid element if (ddbclass!=DDBCLLPRT) error_class(); forall (nref) pincnt++; // Test if pin coordinates are matched if (pincnt<=0) error(ERRNOORIG); // Select the mode bae_defmenusel(-1); bae_promptdialog(UPRORIGFCT); switch (bae_askmenu(3,UPRORIG1,UPRORIG2,UPRABORT)) { // Pin 1 case 0 : // Init the pin count pincnt=0; // Init the coordinates ox=bae_planwslx()-10.0; oy=bae_planwslx()-10.0; // Search pin '1' forall (nref where nref.NAME=="1") { // Pin 1 found; set new origin ox=nref.X; oy=nref.Y; // Increment the pin count pincnt++; // Stop the search break; } break; // Pin gravity point case 1 : // Init the pin count pincnt=0; // Init the coordinates ox=oy=0.0; // Loop thru all pins forall (nref) { // Update the origin coordinates ox+=nref.X; oy+=nref.Y; // Increment the pin count pincnt++; } // Test the pin count if (pincnt>0) { // Calculate the origin coordinates ox/=pincnt; oy/=pincnt; } break; // Abort on default default : error_abort(); } // Test if pin coordinates are matched if (pincnt<=0) error(ERRNOORIG); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Free grid lock if not yet free if (gridlock=bae_getgridlock()) bae_setgridlock(0); // Set the origin bae_clriactqueue(); bae_storemouseiact(1,ox,oy,0,LMB); call(MNU_GEDPARORIG); // Restore the grid lock bae_setgridlock(gridlock); // Done bae_prtdialog(REPORIGSET); } // Layout symbol insertion pick routines void inspicktext() /* // Place insertion pick text */ { int inspicklayer /* Insertion pick layer number */; // Set default layer inspicklayer= ged_getlaydefmode()==2 ? ged_getlayerdefault() : ged_getpickpreflay(); // Select the insertion pick layer if (ged_asklayer(inspicklayer,3)) // Abort return; // Test if insertion data layer contains text already if (istextonlayer(inspicklayer)) { // Text on insertion layer; verify replace if (!verify(UPRREPTEXT,0)) // Abort error_abort(); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Delete text from layer dellayertext(inspicklayer); } else { // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); } layerfadein(inspicklayer,COLFIN,1); // Store the insertion pick text if (ged_storetext(INSPICKTXT, bae_planwsnx(),bae_planwsny(),0.0,INSPICKTXTS,inspicklayer,0)) // Error placing text error(ERRTEXT); ged_setlayerdefault(inspicklayer); // Done bae_prtdialog(REPPICKSET); } int istextonlayer(int layer) /* // Test if text placed on specified layer // Return value : // zero if no text placed on layer or nonzero else // Parameters : // int layer : Layer to test for placed text */ { index L_TEXT txt /* Text index */; // Test if given layer contains text forall (txt where txt.LAYER==layer) // Text placed on layer return(1); // Return the no text placed code return(0); } void dellayertext(int layer) /* // Delete all text from specified layer // Parameters : // int layer : Layer to test for placed text */ { index L_FIGURE fig /* Figure list index */; index L_FIGURE dfig /* Delete figure list element */; // Test if given layer contains text forall (fig where fig.TYP==L_FIGTEXT && fig.LAYER==layer && !(fig.FIXED&2)) { // Delete this text dfig=fig; ged_delelem(dfig); } } // Pin macro functions void changepinmacs() /* // Change pin macros of currently loaded layout symbol */ { index L_FIGURE fig /* Figure list index */; string oldstack /* Old padstack macro name */; string newstack = "" /* New padstack macro name */; int selcnt = 0 /* Padstack selections count */; string fn /* File name buffer */; double pcol = 23.0 /* Parameter column */; double dialwidth /* Dialog box width */; double dialheight /* Dialog box height */; double baseheight /* Dialog box base height */; double cy /* Dialog box current y coordinate */; int repflag = 1 /* Repeat flag */; int macidx = (-1) /* Makro field dialog box item idx. */; // Abort if invalid element if (ddbclass!=DDBCLLPRT) error_class(); // Select old padstack macro if ((oldstack=askstackmacro(UPROLDSTK))=="" || oldstack==UINPOPABORT) error_abort(); // Check if dialog box support if (bae_dialclr()) { // Select new padstack macro if (bae_askddbename(newstack,bae_planfname(), DDBCLLSTK,msgstring(UPRNEWSTK,convstring(bae_planfname(),1)))) error_abort(); } else { baseheight=DIAL_TOPMARG+2.0*DIAL_CTRVSTEP+2.0*DIAL_SEPVSTEP+ DIAL_BUTVSTEP; do { bae_dialclr(); dial_getboxsizemin(3041,dialwidth,dialheight, DIAL_LEFTMARG+44.0+DIAL_RIGHTSMARG,baseheight+8.6, DIAL_LEFTMARG+40.0,baseheight+2.0); pcol=(dialwidth-DIAL_LEFTMARG-DIAL_RIGHTSMARG)/2.0+1.0; // Build the dialog box cy=DIAL_TOPMARG; // Store pin macro edit controls dial_label(0.0,cy,UPRDNEWSTK); macidx=dial_namestring(oldstack,MAXKEYLEN,pcol,cy); dial_label(0.0,cy,UPRSTKPROJ); bae_dialadvcontrol(PA_VSEP|PA_VBRDREL,0,0,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+pcol-1.5,cy,0.0,DIAL_BOTSMARG,""); dial_label(pcol,cy,UPRSTKDB); cy+=DIAL_CTRVSTEP; // Store project padstack list box bae_dialadvcontrol( PA_LB|PA_OKSEL|PA_HSCROLL|PA_VBRDREL,macidx,0,(-1), 0.0,0.0,0.0,"",0,DIAL_LEFTMARG,cy,pcol-3.0, DIAL_BOTEMARG,""); // Store list box entries dial_lbddbclass(bae_planfname(),DDBCLLSTK,0); // Store library padstack list box bae_dialadvcontrol( PA_LB|PA_OKSEL|PA_HBRDREL|PA_HSCROLL|PA_VBRDREL,macidx, 0,(-1),0.0,0.0,0.0,"",0,DIAL_LEFTMARG+pcol,cy, DIAL_RIGHTEMARG,DIAL_BOTEMARG,""); cy+=dialheight-baseheight; // Store list box entries newstack=""; fn=strgetvarfilename(lay_libfname()); catext(fn,DDBEXT); dial_lbddbclass(fn,DDBCLLSTK,0); dial_hsep(cy); dial_okabort(cy); // Display dialog box bae_setintpar(16,3041); switch (bae_dialaskparams( "!"+UPRDNEWSTK,0,dialwidth,cy)) { // Done case 0 : bae_dialgetdata(macidx,0,0.0,newstack); if (newstack=="") return; repflag=0; break; // Resize case (-2) : break; default : return; } } // Stop if no further repeat requests while (repflag); } // Done if equal padstack macros selected if (oldstack==newstack) return; // Reset group bae_clriactqueue(); call(MNU_GEDGRPRESE); // Loop thru all padstacks with old macro forall (fig where !(fig.FIXED&2) && fig.NREF.MACRO.NAME==oldstack) { // Set the group flag if (ged_elemgrpchg(fig,1)) errormsg(ERRSELPIN,fig.NAME); selcnt++; } // Test if any stack selected if (!selcnt) return; // Perform the group macro name call bae_clriactqueue(); bae_storetextiact(1,newstack); call(MNU_GEDGRPMACN); // Reset group bae_clriactqueue(); call(MNU_GEDGRPRESE); // Done bae_prtdialog(itoa(selcnt)+REPSTKCHG); } string askstackmacro(string prompt) /* // Ask for padstack macro of current element // Return value : // padstack macro name or empty string if no element selected // Parameters : // string prompt : Prompt string */ { index L_MACRO macro /* Macro index */; index L_NREF nref /* Named reference index */; STRINGS headl /* Header string list */; int headn = 2 /* Header string count */; STRINGS entryl /* Entry string list */; int entryn = 0 /* Entry list */; string macname /* Macro name */; int i /* Loop control variable */; // Build the padstack macro list forall (macro where macro.CLASS==DDBCLLSTK) { // Store macro to entry list if used forall (nref where nref.MACRO.NAME==macro.NAME) { macname=macro.NAME; for (i=entryn;i>0;i--) if (entryl[i-1]>macname) entryl[i]=entryl[i-1]; else break; entryl[i]=macname; entryn++; break; } } // Define the header headl[headn-1]=""; sprintf(headl[0],REPSTKHD, ddbclassname(bae_planddbclass()),bae_planename()); // Activate the popup and return the padstack name bae_setintpar(16,3087); return(popupmenu(1,prompt, headl,headn,entryl,entryn,UINPOPABORT,0,0,1,0,0,0,UINPOPABORT)); } // Pin placement functions void placepins(int rowflag) /* // Place pins // Parameters : // int rowflag : Pin row/matrix placement request flag */ { index L_FIGURE fig /* Figure list index */; index L_NREF nref /* Named reference index */; STRINGS idxl1 /* First index name list */; int idxn1 /* First index name count */; STRINGS idxl2 /* Second index name list */; int idxn2 /* Second index name count */; string fn /* File name buffer */; double pcol = 23.0 /* Parameter column */; double cx /* Dialog box current x coordinate */; double cy /* Dialog box current y coordinate */; double dialheight /* Dialog box height */; double baseheight /* Dialog box base height */; int boxid /* Dialog box ID */; string msg /* Message buffer */; int res /* Dialog box query result */; int repflag = 1 /* Repeat flag */; int txtflag /* Text placement flag */; int matmode /* Matrix placement mode */; int pinrcnt = 2 /* Pin per row count */; int cpmode /* Counter pin row mode */; int prcidx = (-1) /* Pin count dialog box item idx. */; int cpidx = (-1) /* Counter row dialog box item idx. */; int matidx = (-1) /* Matrix flag dialog box item idx. */; int spatidx = (-1) /* Pat. field dialog box item idx. */; int mpatidx = (-1) /* Pat. field dialog box item idx. */; int epatidx = (-1) /* Pat. field dialog box item idx. */; int macidx = (-1) /* Makro field dialog box item idx. */; int fn1idx = (-1) /* 1st num. dialog box item idx. */; int ln1idx = (-1) /* 1st num. dialog box item idx. */; int st1idx = (-1) /* 1st step dialog box item idx. */; int nw1idx = (-1) /* 1st width dialog box item idx. */; int cs1idx = (-1) /* 1st char set dialog box item idx. */; int fn2idx = (-1) /* 2nd num. dialog box item idx. */; int ln2idx = (-1) /* 2nd num. dialog box item idx. */; int st2idx = (-1) /* 2nd step dialog box item idx. */; int nw2idx = (-1) /* 2nd width dialog box item idx. */; int cs2idx = (-1) /* 2nd char set dialog box item idx. */; string spattern /* Pin name start pattern */; string mpattern /* Pin name middle pattern */; string epattern /* Pin name end pattern */; string charset1 /* Character set 1 */; string charset2 /* Character set 2 */; string fnam1 /* First pin name */; string lnam1 /* Last pin name */; int fnum1 /* First pin number */; int lnum1 /* Last pin number */; int step1 /* Pin step value */; int numw1 /* Pin number width */; string fnam2 /* First pin name */; string lnam2 /* Last pin name */; int fnum2 /* First pin number */; int lnum2 /* Last pin number */; int step2 /* Pin step value */; int numw2 /* Pin number width */; int strmode /* String edit mode */; int oldnumw /* Old pin number width */; int lastlay /* Last text layer */; // Get last data if (varget(GV_CHARSET1,charset1)) charset1=ALLASC; if (varget(GV_CHARSET2,charset2)) charset2=ALLASC; if (varget(GV_MATMODE,matmode) || (ddbclass!=DDBCLLPRT && matmode<3)) matmode=(ddbclass==DDBCLLPRT ? 0 : 3); if (varget(GV_MATI1START,fnum1)) fnum1=1; if (varget(GV_MATI1END,lnum1)) lnum1=2; if (varget(GV_MATN1START,fnam1)) fnam1=""; if (varget(GV_MATN1END,lnam1)) lnam1=""; if (varget(GV_MAT1STEP,step1)) step1=1; if (varget(GV_MAT1IDX,numw1)) numw1=0; if (varget(GV_MATI2START,fnum2)) fnum2=1; if (varget(GV_MATI2END,lnum2)) lnum2=2; if (varget(GV_MATN2START,fnam2)) fnam2=""; if (varget(GV_MATN2END,lnam2)) lnam2=""; if (varget(GV_MAT2STEP,step2)) step2=1; if (varget(GV_MAT2IDX,numw2)) numw2=0; if (varget(GV_MATPREF,spattern)) spattern=""; if (varget(GV_MATINF,mpattern)) mpattern=""; if (varget(GV_MATSUFF,epattern)) epattern=""; if (varget(GV_MATCPM,cpmode)) cpmode=0; if (varget(GV_LASTLAY,lastlay)) lastlay=LAYERINV; // Search next free number if (matmode==0) { while (lay_nrefsearch(spattern+itoa(fnum1)+epattern,fig)==0) fnum1++; // Guess for the new last number assuming two pin rows lnum1=fnum1==1 ? 2 : (fnum1-1)*2 ; } // Check if dialog box support if (bae_dialclr()) { // Ask for pin name start pattern bae_setmousetext(""); spattern=bae_readedittext(UPRNAMSPAT,"",10); // Check if abort request if (spattern==UINPOPABORT) error_abort(); // Ask for pin name end pattern epattern=bae_readedittext(UPRNAMEPAT,"",10); // Check if abort request if (epattern==UINPOPABORT) error_abort(); // Ask for first and last pin number if (askint(fnum1,UPRPIN1,10) || fnum1<=0 || askint(lnum1,UPRPIN2,10) || lnum1<=0 || askint(step1,UPRPINSTEP,10) || step1<=0) error(ERRINVNUM); // Select pin/padstack macro if (bae_askddbename( pinmacro,bae_planfname(),DDBCLLSTK,UPRPINMAC) || pinmacro=="." && bae_askddbename(pinmacro,lay_libfname(), DDBCLLSTK,msgstring(UPRPINMACL,convstring(lay_libfname(),1)))) error_abort(); // Test if selected padstack macro is available if (ddbcheck(bae_planfname(),DDBCLLSTK,pinmacro) && ddbcheck(lay_libfname(),DDBCLLSTK,pinmacro)) { sprintf(msg,ERRNOMACRO,pinmacro, strgetvarfilename(lay_libfname)); error(msg); } } else { // Perform the input loop do { bae_dialclr(); if (matmode>=3) { boxid=3117; } else { baseheight=DIAL_TOPMARG+12*DIAL_CTRVSTEP+ DIAL_BUTVSTEP+2.0*DIAL_SEPVSTEP; boxid=3116; bae_setintpar(16,boxid); if (bae_getdblpar(8,dialheight)) dialheight=baseheight+5.0; else bae_getdblpar(9,dialheight); if (dialheight<(baseheight+2.0)) dialheight=baseheight+2.0; } // Build the dialog box cy= DIAL_TOPMARG+((matmode==1 || matmode==4) ? 0.0 : 0.5); // Store pin name pattern controls cx=DIAL_LEFTMARG; dial_label(0.0,cy,matmode>=3 ? UPRTXTPAT : UPRPINPAT); cx+=10.0; strmode=PA_STR|(matmode<3 ? PA_CHKNAME : 0); spatidx=bae_dialaddcontrol(strmode,0,0,0,0.0,0.0,0.0, spattern,(matmode<3 ? MAXKEYLEN : MAXTEXTLEN)-1, cx,cy,12.0,""); cx+=13.0; dial_label(cx,cy,UPRDPINSEP); cx+=2.0; if (matmode==1 || matmode==4) { dial_label(cx,cy,UPRINDEX1); cx+=5.0; } else { dial_label(cx,cy-0.5,UPRDPIN1); dial_label(cx,cy+0.5,UPRDPIN2); cx+=4.5; if (numw1<5) { fn1idx=bae_dialaddcontrol( PA_INT|PA_CHKLL,0,0,fnum1,0.0,0.0, 0.0,"",20,cx,cy-0.5,4.0,""); ln1idx=bae_dialaddcontrol( PA_INT|PA_CHKLL,0,0,lnum1,0.0,0.0, 0.0,"",20,cx,cy+0.5,4.0,""); } else { fn1idx=bae_dialaddcontrol(strmode, 0,0,0,0.0,0.0,0.0,fnam1,20, cx,cy-0.5,4.0,""); ln1idx=bae_dialaddcontrol(strmode, 0,0,0,0.0,0.0,0.0,lnam1,20, cx,cy+0.5,4.0,""); } cx+=5.0; } dial_label(cx,cy,UPRDPINSEP); cx+=2.0; if (matmode==1 || matmode==4) { mpatidx=bae_dialaddcontrol(strmode, 0,0,0,0.0,0.0,0.0,mpattern, (matmode<3 ? MAXKEYLEN : MAXTEXTLEN)-1, cx,cy,5.0,""); cx+=6.0; dial_label(cx,cy,UPRDPINSEP); cx+=2.0; dial_label(cx,cy,UPRINDEX2); cx+=5.0; dial_label(cx,cy,UPRDPINSEP); cx+=2.0; } epatidx=bae_dialaddcontrol(strmode,0,0,0,0.0,0.0,0.0, epattern,(matmode<3 ? MAXKEYLEN : MAXTEXTLEN)-1, cx,cy,12.0,""); if (matmode==1 || matmode==4) cy+=DIAL_CTRVSTEP+DIAL_SEPVSTEP; else cy+=2.0*DIAL_CTRVSTEP+DIAL_SEPVSTEP; cx=DIAL_LEFTMARG; if (matmode==1 || matmode==4) { dial_hsep(cy); dial_label(0.0,cy,UPRDINDEX1); cy+=DIAL_CTRVSTEP; dial_label(0.0,cy,UPRDPIN1); cx+=4.5; if (numw1<5) { fn1idx=bae_dialaddcontrol( PA_INT|PA_CHKLL,0,0, fnum1,0.0,0.0,0.0,"",20,cx,cy,4.0,""); cx+=5.0; } else { fn1idx=bae_dialaddcontrol(strmode,0, 0,0,0.0,0.0,0.0,fnam1,20,cx,cy,4.0,""); cx+=5.0; } dial_label(cx,cy,UPRDPIN2); cx+=4.5; if (numw1<5) { ln1idx=bae_dialaddcontrol( PA_INT|PA_CHKLL,0,0, lnum1,0.0,0.0,0.0,"",20,cx,cy,4.0,""); cx+=6.0; } else { ln1idx=bae_dialaddcontrol(strmode,0, 0,0,0.0,0.0,0.0,lnam1,20,cx,cy,4.0,""); cx+=6.0; } } if (matmode==2 || matmode==5) { dial_label( cx,cy,matmode>=3 ? UPRTXTRC : UPRPINRC); cx+=11.0; prcidx=bae_dialaddcontrol(PA_INT|PA_CHKLL,1,0, pinrcnt,0.0,0.0,0.0,"",20, DIAL_LEFTMARG+cx,cy,4.0,""); cx+=7.0; } if (numw1<5) { dial_label(cx!=0.0 ? pcol : 0.0,cy,UPRDPINSTEP); cx+=21.5; st1idx=bae_dialaddcontrol(PA_INT|PA_CHKLL,1,0, step1,0.0,0.0,0.0,"",20,DIAL_LEFTMARG+cx+ (cx!=21.5 ? 0.0 : 1.5), cy,4.0,""); } if (cx!=0.0) cy+=DIAL_CTRVSTEP; // Store pin number width controls dial_label(0.0,cy,UPRPINNUMW); nw1idx=bae_dialaddcontrol(PA_SB,0,0,numw1, 0.0,0.0,0.0,"",0,DIAL_LEFTMARG+pcol,cy,20.0,""); dial_sbentry(1,0,UPRPINNUMW1); dial_sbentry(1,2,UPRPINNUMW2); dial_sbentry(1,3,UPRPINNUMW3); dial_sbentry(1,4,UPRPINNUMW4); dial_sbentry(1,5,UPRPINNUMW5); cy+=DIAL_CTRVSTEP; if (numw1==5) { dial_label(0.0,cy,UPRASCSET); cs1idx=bae_dialaddcontrol(strmode, 0,0,0,0.0,0.0,0.0,charset1,80, DIAL_LEFTMARG+pcol,cy,20.0,""); bae_dialaddcontrol(PA_ACT,0,2,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+45.0,cy,0.0,UPRALLASC); cy+=DIAL_CTRVSTEP; } if (matmode==1 || matmode==4) { dial_hsep(cy); dial_label(0.0,cy,UPRDINDEX2); cy+=DIAL_CTRVSTEP; cx=DIAL_LEFTMARG; dial_label(0.0,cy,UPRDPIN1); cx+=4.5; if (numw2<5) { fn2idx=bae_dialaddcontrol( PA_INT|PA_CHKLL,0,0, fnum2,0.0,0.0,0.0,"",20,cx,cy,4.0,""); cx+=5.0; } else { fn2idx=bae_dialaddcontrol(strmode,0, 0,0,0.0,0.0,0.0,fnam2,20,cx,cy,4.0,""); cx+=5.0; } dial_label(cx,cy,UPRDPIN2); cx+=4.5; if (numw2<5) { ln2idx=bae_dialaddcontrol( PA_INT|PA_CHKLL,0,0, lnum2,0.0,0.0,0.0,"",20,cx,cy,4.0,""); dial_label(pcol,cy,UPRDPINSTEP); st2idx=bae_dialaddcontrol( PA_INT|PA_CHKLL,1,0,step2,0.0,0.0, 0.0,"",20,cx+27.5,cy,4.0,""); } else { ln2idx=bae_dialaddcontrol(strmode,0, 0,0,0.0,0.0,0.0,lnam2,20,cx,cy,4.0,""); } cy+=DIAL_CTRVSTEP; // Store pin number width controls dial_label(0.0,cy,UPRPINNUMW); nw2idx=bae_dialaddcontrol(PA_SB,0,0,numw2,0.0, 0.0,0.0,"",0,DIAL_LEFTMARG+pcol,cy,20.0,""); dial_sbentry(1,0,UPRPINNUMW1); dial_sbentry(1,2,UPRPINNUMW2); dial_sbentry(1,3,UPRPINNUMW3); dial_sbentry(1,4,UPRPINNUMW4); dial_sbentry(1,5,UPRPINNUMW5); cy+=DIAL_CTRVSTEP; if (numw2==5) { dial_label(0.0,cy,UPRASCSET); cs2idx=bae_dialaddcontrol(strmode,0, 0,0,0.0,0.0,0.0,charset2,80, DIAL_LEFTMARG+pcol,cy,20.0,""); bae_dialaddcontrol(PA_ACT,0,3,0,0.0, 0.0,0.0,"",0,DIAL_LEFTMARG+45.0,cy, 0.0,UPRALLASC); cy+=DIAL_CTRVSTEP; } } else if ((matmode==0 || matmode==3) && rowflag && numw1<5) { // Store counter pin row mode controls dial_label( 0.0,cy,matmode>=3 ? UPRCTMODE : UPRCPMODE); cpidx=bae_dialaddcontrol(PA_SB,0,0,cpmode,0.0, 0.0,0.0,"",0,DIAL_LEFTMARG+pcol,cy,20.0,""); dial_sbentry(0,0,UPRCPMODE1); dial_sbentry(0,1,UPRCPMODE2); dial_sbentry(0,2,UPRCPMODE3); cy+=DIAL_CTRVSTEP; } if (matmode<3) { dial_hsep(cy); // Store pin macro edit controls if (varget(GV_PINMACRO,pinmacro)) { pinmacro=""; forall (nref) { pinmacro=nref.MACRO.NAME; break; } } dial_label(0.0,cy,UPRDPINMAC); macidx=bae_dialaddcontrol(PA_STR|PA_CHKNAME,0, 0,0,0.0,0.0,0.0,pinmacro,MAXKEYLEN, DIAL_LEFTMARG+pcol,cy,20.0,""); cy+=DIAL_CTRVSTEP; dial_label(0.0,cy,UPRSTKPROJ); bae_dialadvcontrol(PA_VSEP|PA_VBRDREL,0,0,0, 0.0,0.0,0.0,"",0,DIAL_LEFTMARG+pcol-1.5,cy, 0.0,rowflag ? 0.0 : DIAL_BOTSMARG+0.1,""); dial_label(pcol,cy,UPRSTKDB); cy+=DIAL_CTRVSTEP; // Store project padstack list box bae_dialadvcontrol( PA_LB|PA_OKSEL|PA_HSCROLL|PA_VBRDREL,macidx,0, (-1),0.0,0.0,0.0,"",0,DIAL_LEFTMARG,cy,20.0, 2.0*DIAL_SEPVSTEP+DIAL_BUTVSTEP+0.2,""); // Store list box entries dial_lbddbclass(bae_planfname(),DDBCLLSTK,0); // Store library padstack list box bae_dialadvcontrol( PA_LB|PA_OKSEL|PA_HSCROLL|PA_VBRDREL,macidx,0, (-1),0.0,0.0,0.0,"",0,DIAL_LEFTMARG+pcol,cy, 20.0,2.0*DIAL_SEPVSTEP+DIAL_BUTVSTEP+0.2,""); cy=dialheight-2.0*DIAL_SEPVSTEP-DIAL_BUTVSTEP; // Store list box entries fn=strgetvarfilename(lay_libfname()); catext(fn,DDBEXT); dial_lbddbclass(fn,DDBCLLSTK,0); } dial_hsep(cy); // Store OK button bae_dialaddcontrol(PA_OK, 0,0,0,0.0,0.0,0.0,"",0,DIAL_LEFTMARG,cy,0.0,""); if (matmode>=3 && lastlay!=LAYERINV) { bae_dialaddcontrol(PA_ACT,0,4,0,0.0,0.0, 0.0,"",0,DIAL_LEFTMARG+5.0,cy,0.0,UPRLAYOK); bae_dialaddcontrol(PA_ABORT,0,0,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+15.0,cy,0.0,""); } else { // Store abort button bae_dialaddcontrol(PA_ABORT,0,0,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+5.0,cy,0.0,""); } if (rowflag) { matidx=bae_dialaddcontrol(PA_SB,0,0,matmode,0.0, 0.0,0.0,"",0,DIAL_LEFTMARG+pcol,cy,25.0,""); if (ddbclass==DDBCLLPRT) { dial_sbentry(1,0,UPRPINROW); dial_sbentry(1,1,UPRPINMAT); dial_sbentry(1,2,UPRPINMATI); } dial_sbentry(1,3,UPRTXTROW); dial_sbentry(1,4,UPRTXTMAT); dial_sbentry(1,5,UPRTXTMATI); } else { if (ddbclass==DDBCLLPRT) { matidx=bae_dialaddcontrol(PA_SB,0,0, matmode,0.0,0.0,0.0,"",0, DIAL_LEFTMARG+pcol,cy,25.0,""); dial_sbentry(1,0,UPRPINLIST); dial_sbentry(1,3,UPRTXTLIST); } } cy+=DIAL_BUTVSTEP+DIAL_SEPVSTEP; // Display dialog box bae_setintpar(16,boxid); switch (res=bae_dialaskparams( matmode>=3 ? UPRDTXTDAT : ("!"+UPRDPINDAT),0, DIAL_LEFTMARG+((matmode==1 || matmode==4) ? 60.0 : 50.0)+DIAL_RIGHTSMARG,cy)) { // Done case 0 : lastlay=LAYERINV; case 4 : // Resize case (-2) : if (matmode<3) { bae_dialgetdata(macidx,0,0.0,pinmacro); strlower(pinmacro); } bae_dialgetdata(spatidx,0,0.0,spattern); bae_dialgetdata(epatidx,0,0.0,epattern); if (matmode==2 || matmode==5) bae_dialgetdata(prcidx,pinrcnt,0.0,""); if (numw1<5) { bae_dialgetdata(fn1idx,fnum1,0.0,""); bae_dialgetdata(ln1idx,lnum1,0.0,""); if (matmode==0 || matmode==3) bae_dialgetdata( cpidx,cpmode,0.0,""); bae_dialgetdata(st1idx,step1,0.0,""); } else { bae_dialgetdata(fn1idx,0,0.0,fnam1); bae_dialgetdata(ln1idx,0,0.0,lnam1); bae_dialgetdata(cs1idx,0,0.0,charset1); } if (matmode==1 || matmode==4) { bae_dialgetdata( mpatidx,0,0.0,mpattern); if (numw2<5) { bae_dialgetdata( fn2idx,fnum2,0.0,""); bae_dialgetdata( ln2idx,lnum2,0.0,""); bae_dialgetdata( st2idx,step2,0.0,""); } else { bae_dialgetdata( fn2idx,0,0.0,fnam2); bae_dialgetdata( ln2idx,0,0.0,lnam2); bae_dialgetdata( cs2idx,0,0.0,charset2); } bae_dialgetdata(nw2idx,numw2,0.0,""); } bae_dialgetdata(nw1idx,numw1,0.0,""); if (matmode<3) { if (pinmacro=="") { bae_msgbox(2,ERRINVPINMAC,""); break; } // Store settings for next call varset(GV_PINMACRO,pinmacro); } // Build and check first index list if ((idxn1=buildidxlist(fnum1,lnum1,step1, numw1,fnam1,lnam1,charset1,cpmode,idxl1))==0) break; if ((matmode==1 || matmode==4) && (idxn2=buildidxlist(fnum2,lnum2,step2, numw2,fnam2,lnam2,charset2,0,idxl2))==0) break; if (res!=(-2)) repflag=0; break; // Parameter toggle case 1 : case 2 : case 3 : if (matmode<3) bae_dialgetdata(macidx,0,0.0,pinmacro); bae_dialgetdata(spatidx,0,0.0,spattern); bae_dialgetdata(epatidx,0,0.0,epattern); if (matmode==2 || matmode==5) bae_dialgetdata(prcidx,pinrcnt,0.0,""); oldnumw=numw1; bae_dialgetdata(nw1idx,numw1,0.0,""); if (oldnumw<5) { bae_dialgetdata(fn1idx,fnum1,0.0,""); bae_dialgetdata(ln1idx,lnum1,0.0,""); if (numw1==5) { fnam1="a"; lnam1="b"; } if (matmode==0 || matmode==2) bae_dialgetdata( cpidx,cpmode,0.0,""); bae_dialgetdata(st1idx,step1,0.0,""); } else { bae_dialgetdata(fn1idx,0,0.0,fnam1); bae_dialgetdata(ln1idx,0,0.0,lnam1); bae_dialgetdata(cs1idx,0,0.0,charset1); } if (matmode==1 || matmode==4) { bae_dialgetdata( mpatidx,0,0.0,mpattern); oldnumw=numw2; bae_dialgetdata(nw2idx,numw2,0.0,""); if (oldnumw<5) { bae_dialgetdata( fn2idx,fnum2,0.0,""); bae_dialgetdata( ln2idx,lnum2,0.0,""); if (numw2==5) { fnam2="a"; lnam2="b"; } bae_dialgetdata( st2idx,step2,0.0,""); } else { bae_dialgetdata( fn2idx,0,0.0,fnam2); bae_dialgetdata( ln2idx,0,0.0,lnam2); bae_dialgetdata( cs2idx,0,0.0,charset2); } } if (matidx!=(-1)) bae_dialgetdata(matidx,matmode,0.0,""); // Store settings for next call varset(GV_PINMACRO,pinmacro); if (res==2) charset1=ALLASC; else if (res==3) charset2=ALLASC; break; default : return; } if (matmode<3) { strlower(spattern); strlower(mpattern); strlower(epattern); strlower(fnam1); strlower(lnam1); strlower(charset1); strlower(fnam2); strlower(lnam2); strlower(charset2); } } // Stop if no further repeat requests while (repflag); } // Remove spaces from patterns strdelchr(spattern," \t",1,MAXPNLEN); strdelchr(mpattern," \t",1,MAXPNLEN); strdelchr(epattern," \t",1,MAXPNLEN); // Store settings for next call varset(GV_CHARSET1,charset1); varset(GV_CHARSET2,charset2); varset(GV_MATMODE,matmode); varset(GV_MATI1START,fnum1); varset(GV_MATI1END,lnum1); varset(GV_MATN1START,fnam1); varset(GV_MATN1END,lnam1); varset(GV_MAT1STEP,step1); varset(GV_MAT1IDX,numw1); varset(GV_MATI2START,fnum2); varset(GV_MATI2END,lnum2); varset(GV_MATN2START,fnam2); varset(GV_MATN2END,lnam2); varset(GV_MAT2STEP,step2); varset(GV_MAT2IDX,numw2); varset(GV_MATPREF,spattern); varset(GV_MATINF,mpattern); varset(GV_MATSUFF,epattern); varset(GV_MATCPM,cpmode); txtflag=matmode>=3 ? 1 : 0; // Test the pin row placement request flag if (rowflag) { switch (matmode) { // Place the pin/text row case 0 : case 3 : placepinrow( spattern,epattern,idxl1,idxn1,cpmode,txtflag,lastlay); break; // Place the pin/text matrix with X and Y name index case 1 : case 4 : placepinmat(spattern,mpattern,epattern, idxl1,idxn1,idxl2,idxn2,txtflag,lastlay); break; // Place the pin/text matrix with single name index case 2 : case 5 : placepinmati( spattern,epattern,idxl1,idxn1,pinrcnt,txtflag,lastlay); break; } } else { // Place the pin list placepinlist(spattern,epattern,idxl1,idxn1,txtflag,lastlay); } // Done bae_prtdialog(""); } void placepinlist( string spattern,string epattern,string idxl[],int idxn,int txtflag,int lastlay) /* // Place a list of pins // Parameters : // string spattern : Pin name start pattern // string epattern : Pin name end pattern // string idxl[] : Pin name list // int idxn : Pin name count // int txtflag : Text placement mode // int lastlay : Text last layer */ { index L_FIGURE fig /* Figure list index */; index L_FIGURE lastfig /* Last figure list element */; index L_FIGURE newfig /* New figure list element */; string pinname /* Pin name */; int replaceflag /* Pin replace flag */; string prompt /* Prompt string */; int lastexists /* Last element exists flag */; int layer /* Layer code */; int i /* Loop control variable */; if (txtflag) { if (lastlay!=LAYERINV) { layer=lastlay; } else { layer=gettextlayer(); varset(GV_LASTLAY,layer); } } // Loop for all pins for (i=0;i(txtflag ? MAXTEXTLEN : MAXKEYLEN)) errormsg(txtflag ? ERRTXTLEN : ERRNAMELEN,pinname); // Get the last element lastexists=lay_lastfigelem(lastfig)==0 ? 1 : 0; if (txtflag) { bae_clriactqueue(); placetext(pinname,layer); } else { // Test if pin is already placed if (lay_nrefsearch(pinname,fig)==0) { // Pin found; ask if replace is required sprintf(prompt,UPRREPLACE,pinname); if (!(replaceflag=verify(prompt,0))) // Continue with next pin continue; } else { // Reset the pin replace flag replaceflag=0; } // Place the pin bae_clriactqueue(); bae_storetextiact(1,pinname); if (replaceflag) bae_storetextiact(1,M_UINYES()); bae_storetextiact(1,pinmacro); call(MNU_GEDADDPART); } bae_clriactqueue(); // Check if aborted if (lay_lastfigelem(newfig)!=0 || (lastexists && newfig==lastfig)) error_abort(); } } void placepinrow(string spattern,string epattern, string idxl[],int idxn,int cpmode,int txtflag,int lastlay) /* // Place a row of pins // Parameters : // string spattern : Pin name start pattern // string epattern : Pin name end pattern // string idxl : Pin name list // int idxn : Pin name count // int cpmode : Counter pin row mode // int txtflag : Text placement mode // int lastlay : Text last layer */ { index L_FIGURE lastfig /* Last figure list element */; index L_FIGURE newfig /* New figure list element */; string msg /* Message buffer */; string pinname /* Pin name */; double px,py /* Pin placement coordinates */; double x1,y1 /* First pin coordinates */; double x2,y2 /* Second pin coordinates */; double xstep,ystep /* Pin grid steps */; double ang /* Placement angle */; double size /* Placement size */; int mirr /* Placement mirroring */; int lastexists /* Last element exists flag */; int layer /* Layer code */; int i /* Loop control variable */; if (txtflag) { if (lastlay!=LAYERINV) { layer=lastlay; } else { layer=gettextlayer(); varset(GV_LASTLAY,layer); } } for (i=0;i(txtflag ? MAXTEXTLEN : MAXKEYLEN)) errormsg(txtflag ? ERRTXTLEN : ERRNAMELEN,pinname); if (i==0) { // Get the last element lastexists=lay_lastfigelem(lastfig)==0 ? 1 : 0; // Place first pin bae_clriactqueue(); if (txtflag) { placetext(pinname,layer); } else { if (lay_nrefsearch(pinname,newfig)==0) errormsg(ERRMULPIN,pinname); bae_storetextiact(1,pinname); bae_storetextiact(1,pinmacro); bae_callmenu(MNU_GEDADDPART); } bae_clriactqueue(); // Check if aborted if (lay_lastfigelem(newfig)!=0 || (lastexists && newfig==lastfig)) error_abort(); // Get the placement data x1=newfig.X; y1=newfig.Y; ang=newfig.ANGLE; size=newfig.SIZE; mirr=newfig.MIRROR; } else { // Check if second position if (i==1) { // Select second coordinate if (txtflag) sprintf(msg,UPRTXT2,pinname); else sprintf(msg,UPRPOS2,pinname,pinmacro); if (bae_promptdialog(msg), bae_inpoint(x1,y1,x2,y2,2)) error_abort(); // Calculate grid steps xstep=x2-x1; ystep=y2-y1; if (xstep==0.0 && ystep==0.0) error(ERRINPVAL); } px=x1+i*xstep; py=y1+i*ystep; if (txtflag) { if (ged_storetext( pinname,px,py,ang,size,layer,mirr)) errormsg(ERRTEXT,pinname); } else { // Store pin switch (ged_storepart( pinname,pinmacro,px,py,ang,mirr)) { // Placement ok case 0 : case 1 : break; // Macro already placed case (-3) : errormsg(ERRMULPIN,pinname); // Macro not in library case (-4) : sprintf(msg,ERRNOMACRO,pinmacro, strgetvarfilename(lay_libfname)); error(msg); // Error copying macro to jobfile case (-6) : errormsg(ERRNOCOPY,pinmacro); // Other error default : errormsg(ERRPLACE,pinname); } } } } // Check if counter pin row if (cpmode) { // Check if pin rotation if (cpmode==2) { ang+=PI; if (ang>=2.0*PI) ang-=2.0*PI; } // Use other direction xstep=(-xstep); ystep=(-ystep); for (i=0;i(txtflag ? MAXTEXTLEN : MAXKEYLEN)) errormsg( txtflag ? ERRTXTLEN : ERRNAMELEN,pinname); if (i==0 && j==0) { // Get the last element lastexists=lay_lastfigelem(lastfig)==0 ? 1 : 0; // Place first pin bae_clriactqueue(); if (txtflag) { placetext(pinname,layer); } else { if (lay_nrefsearch(pinname,newfig)==0) errormsg(ERRMULPIN,pinname); bae_storetextiact(1,pinname); bae_storetextiact(1,pinmacro); bae_callmenu(MNU_GEDADDPART); } bae_clriactqueue(); // Check if aborted if (lay_lastfigelem(newfig)!=0 || (lastexists && newfig==lastfig)) error_abort(); // Get the placement data x1=newfig.X; y1=newfig.Y; ang=newfig.ANGLE; mirr=newfig.MIRROR; size=newfig.SIZE; continue; } // Check if second position of first direction if (i==0 && j==1) { // Select second coordinate if (txtflag) sprintf(msg,UPRMTXT1,pinname); else sprintf(msg,UPRMPOS1,pinname,pinmacro); if (bae_promptdialog(msg), bae_inpoint(x1,y1,x2,y2,2)) error_abort(); // Calculate grid steps xstep1=x2-x1; ystep1=y2-y1; if (xstep1==0.0 && ystep1==0.0) error(ERRINPVAL); } // Check if second position of second direction if (i==1 && j==0) { // Select second coordinate if (txtflag) sprintf(msg,UPRMTXT2,pinname); else sprintf(msg,UPRMPOS2,pinname,pinmacro); if (bae_promptdialog(msg), bae_inpoint(x1,y1,x2,y2,2)) error_abort(); // Calculate grid steps xstep2=x2-x1; ystep2=y2-y1; if (xstep2==0.0 && ystep2==0.0) error(ERRINPVAL); } px=x1+j*xstep1+i*xstep2; py=y1+j*ystep1+i*ystep2; if (txtflag) { if (ged_storetext( pinname,px,py,ang,size,layer,mirr)) errormsg(ERRTEXT,pinname); } else { // Store pin switch (ged_storepart( pinname,pinmacro,px,py,ang,mirr)) { // Placement ok case 0 : case 1 : break; // Macro already placed case (-3) : errormsg(ERRMULPIN,pinname); // Macro not in library case (-4) : sprintf(msg,ERRNOMACRO,pinmacro, strgetvarfilename(lay_libfname)); error(msg); // Error copying macro to jobfile case (-6) : errormsg(ERRNOCOPY,pinmacro); // Other error default : errormsg(ERRPLACE,pinname); } } } } } void placepinmati(string spattern,string epattern, string idxl[],int idxn,int rowcnt,int txtflag,int lastlay) /* // Place pin matrix // Parameters : // string spattern : Pin name start pattern // string epattern : Pin name end pattern // string idxl : Pin name list // int idxn : Pin name count // int rowcnt : Pins per row count // int txtflag : Text placement mode // int lastlay : Text last layer */ { index L_FIGURE lastfig /* Last figure list element */; index L_FIGURE newfig /* New figure list element */; string msg /* Message string */; string pinname /* Pin name */; double px,py /* Pin placement coordinates */; double x1,y1 /* First pin coordinates */; double x2,y2 /* Second pin coordinates */; double xstep1,ystep1 /* Pin grid direction 1 steps */; double xstep2,ystep2 /* Pin grid direction 2 steps */; double ang /* Pin placement angle */; double size /* Placement size */; int mirr /* Pin placement mirroring */; int lastexists /* Last element exists flag */; int rstep = 0 /* Row step */; int rows = 0 /* Row count */; int layer /* Layer code */; int i /* Loop control variable */; if (txtflag) { if (lastlay!=LAYERINV) { layer=lastlay; } else { layer=gettextlayer(); varset(GV_LASTLAY,layer); } } xstep1=ystep1=xstep2=ystep2=0.0; for (i=0;i(txtflag ? MAXTEXTLEN : MAXKEYLEN)) errormsg(txtflag ? ERRTXTLEN : ERRNAMELEN,pinname); if (i==0) { // Get the last element lastexists=lay_lastfigelem(lastfig)==0 ? 1 : 0; // Place first pin bae_clriactqueue(); if (txtflag) { placetext(pinname,layer); } else { if (lay_nrefsearch(pinname,newfig)==0) errormsg(ERRMULPIN,pinname); bae_storetextiact(1,pinname); bae_storetextiact(1,pinmacro); bae_callmenu(MNU_GEDADDPART); } bae_clriactqueue(); // Check if aborted if (lay_lastfigelem(newfig)!=0 || (lastexists && newfig==lastfig)) error_abort(); // Get the placement data x1=newfig.X; y1=newfig.Y; ang=newfig.ANGLE; mirr=newfig.MIRROR; size=newfig.SIZE; } else { // Check if second position of first direction if (i==1) { // Select second coordinate if (txtflag) sprintf(msg,UPRMTXT1,pinname); else sprintf(msg,UPRMPOS1,pinname,pinmacro); if (bae_promptdialog(msg), bae_inpoint(x1,y1,x2,y2,2)) error_abort(); // Calculate grid steps xstep1=x2-x1; ystep1=y2-y1; if (xstep1==0.0 && ystep1==0.0) error(ERRINPVAL); } if (rstep>=rowcnt) { rstep=0; rows++; } // Check if second position of second direction if (rstep==0 && rows==1) { // Select second coordinate if (txtflag) sprintf(msg,UPRMTXT2,pinname); else sprintf(msg,UPRMPOS2,pinname,pinmacro); if (bae_promptdialog(msg), bae_inpoint(x1,y1,x2,y2,2)) error_abort(); // Calculate grid steps xstep2=x2-x1; ystep2=y2-y1; if (xstep2==0.0 && ystep2==0.0) error(ERRINPVAL); } px=x1+rstep*xstep1+rows*xstep2; py=y1+rstep*ystep1+rows*ystep2; if (txtflag) { if (ged_storetext( pinname,px,py,ang,size,layer,mirr)) errormsg(ERRTEXT,pinname); } else { // Store pin switch (ged_storepart( pinname,pinmacro,px,py,ang,mirr)) { // Placement ok case 0 : case 1 : break; // Macro already placed case (-3) : errormsg(ERRMULPIN,pinname); // Macro not in library case (-4) : sprintf(msg,ERRNOMACRO,pinmacro, strgetvarfilename(lay_libfname)); error(msg); // Error copying macro to jobfile case (-6) : errormsg(ERRNOCOPY,pinmacro); // Other error default : errormsg(ERRPLACE,pinname); } } } } } int buildidxlist(int fnum,int lnum,int step,int numw,string fnam,string lnam, string charset,int cpmode,string idxl[]) /* // Build index name list // Return value : // Number of names in list or zero on error // Parameters : // int fnum : First pin number // int lnum : Last pin number // int step : Pin step value // int numw : Pin number width value // string fnam : First pin name // string lnam : Last pin name // string charset : Character set // int cpmode : Counter pin row mode // string idxl[] : Index name return list */ { string msg /* Message string */; string cname /* Current name */; int cn /* Character count */; int pinrng /* Pin range */; int pincnt /* Pin count */; int cntdir /* Pin number count direction */; int nlen /* Name length */; int spos /* String scan position */; int setpos /* Character set scan position */; int i /* Loop control variable */; // Check if number index if (numw<5) { // Loop for all pins pincnt=(fabs(lnum-fnum)+step)/step; pinrng=pincnt*step; cntdir=lnum>fnum ? 1 :(-1); for (i=0,pincnt=0;i=0;spos--) { for (setpos=0;setpos=cn) { sprintf(msg,REPPATWRN,lnam); bae_msgbox(2,msg,""); return(0); } } // Store first name cname=fnam; idxl[0]=cname=fnam; pincnt=1; while (cname!=lnam) { nlen=strlen(cname); for (spos=nlen-1;spos>=0;spos--) { for (setpos=0;setpos=cn) { sprintf(msg,REPPATWRN,fnam); bae_msgbox(2,msg,""); return(0); } if (setpos<(cn-1)) { cname[spos]=charset[setpos+1]; break; } cname[spos]=charset[0]; } if (spos<0) cname=strextract(charset[0],0,0)+cname; idxl[pincnt]=cname; pincnt++; if (pincnt==(PINWRN+1)) { sprintf(msg,REPPINCWRN,PINWRN); if (bae_msgboxverify(msg,"")!=1) return(0); } } return(pincnt); } int gettextlayer() /* // Ask for text layer // Return value : // layer code */ { int layer /* Layer code */; // Get layer default mode switch (ged_getlaydefmode()) { case 1 : layer=ged_getpickpreflay(); break; case 2 : layer=ged_getlayerdefault(); break; case 0 : default : // Select any layer if (bae_promptdialog(UPRTLAY),ged_asklayer(layer,7)) // Abort selected error_abort(); } layerfadein(layer,COLFIN,1); return(layer); } void placetext(string tstr,int layer) /* // Place text // Parameters : // string tstr : Text string // int layer : Text layer code */ { int oldlaydefmode /* Old layer default mode */; // Get layer default mode oldlaydefmode=ged_getlaydefmode(); ged_setlaydefmode(0); ged_setlayerdefault(layer); if (layer>=DOCLAYBASE) { bae_storemenuiact(1,7+lay_menulaylinecnt(),LMB); bae_storetextiact(1,layselname(layer)); } else if (layer>=POWLAYBASE) { bae_storemenuiact(1,6+lay_menulaylinecnt(),LMB); bae_storemenuiact(1,layer-POWLAYBASE,LMB); } else if (layer>=0) { bae_storemenuiact(1,lay_menulaylinecnt(),LMB); bae_storetextiact(1,itoa(layer+1)); } else if (layer==LAYERALL) { bae_storemenuiact(1,1+lay_menulaylinecnt(),LMB); } else if (layer==LAYERTOP) { bae_storemenuiact(1,2+lay_menulaylinecnt(),LMB); } else if (layer==LAYERBTW) { bae_storemenuiact(1,3+lay_menulaylinecnt(),LMB); } else { ged_setlaydefmode(oldlaydefmode); error_abort(); } bae_storetextiact(1,tstr); bae_callmenu(MNU_GEDADDTEXT); ged_setlaydefmode(oldlaydefmode); } static string layselname(int layer) /* // Get the layer selection name for given layer code // Return value : // layer selection name // Parameters : // int layer : Layer code */ { string layname /* Documentary layer name */; if (layer>=DOCLAYBASE) sprintf(layname,"d%ds%s",((layer-DOCLAYBASE)/DOCLAYSHIFT)+1, (layer&0x02) ? "a" : (layer&0x01) ? "2" : "1"); else if (layer==(-5)) layname="ps"; else layname=itoa(layer+1); // Return the layer selection name return(layname); } // User Language program end