diff --git a/log/src/gate.c b/log/src/gate.c new file mode 100644 index 0000000000000000000000000000000000000000..c2a6dd1d09358f054836d7248e5e5d7b7ba9c317 --- /dev/null +++ b/log/src/gate.c @@ -0,0 +1,527 @@ + +#include <p2c/p2c.h> + +/*================ INSIDEGATE ==================*/ +/*= =*/ +/*= Check if inside a gate's "yellow box." =*/ +/*= =*/ +/*================================================*/ + +/* new version by Tim Edwards, Dec 1996 */ + +static int insidegate(log_grec *g, short x, short y) +{ + short xx1, xx2, yy1, yy2, z; + short loc_x1, loc_x2; + log_krec *WITH; + + x = (x - g->x) * log_scale0; + y = (y - g->y) * log_scale0; + WITH = g->kind; + loc_x1 = WITH->x1; + loc_x2 = WITH->x2; + + /* Modify x1 position for length of text on TO/FROM-type gates */ + + if (WITH->flag.U3.named && g->sig > 0) + { + char STR1[256]; + short xwid = m_strwidth(NULL, strrtrim(strcpy(STR1, + gg.signaltab[g->sig - 1].name))) - NAMEGAP; + + if (WITH->flag.U3.nright) + { + if (xwid > loc_x2) loc_x2 = xwid; + } + else + { + if (-xwid < loc_x1) loc_x1 = -xwid; + } + } + + if (g->rot == 0) + { + return (loc_x1 <= x && x <= loc_x2 && WITH->y1 <= y && y <= WITH->y2); + } + else + { + z = g->rot; + xx1 = loc_x1 * log_rotxx[z] + WITH->y1 * log_rotyx[z]; + xx2 = loc_x2 * log_rotxx[z] + WITH->y2 * log_rotyx[z]; + sortshints(&xx1, &xx2); + yy1 = loc_x1 * log_rotxy[z] + WITH->y1 * log_rotyy[z]; + yy2 = loc_x2 * log_rotxy[z] + WITH->y2 * log_rotyy[z]; + sortshints(&yy1, &yy2); + return (xx1 <= x && x <= xx2 && yy1 <= y && y <= yy2); + } +} + +#define rtn "ERAGATE" + +/*================== ERAGATE ===================*/ +/*= =*/ +/*= Erase a gate (including LED's and other =*/ +/*= "magic" stuff) using grid coordinates. =*/ +/*= =*/ +/*================================================*/ + +static void eragate(log_grec *g) +{ + log_grec *g1, *g2; + + if (g->conflict || g->oconflict) + { + g1 = gateconflictbase; + g2 = NULL; + while (g1 != NULL && g1 != g) + { + g2 = g1; + g1 = g1->confnext; + } + + if (g1 == NULL) + report(10, rtn); + else if (g2 == NULL) + gateconflictbase = g->confnext; + else + g2->confnext = g->confnext; + g->conflict = false; + g->conflict1 = false; + g->conflict2 = false; + g->oconflict = false; + } + drawgatec(g->x, g->y, g->g, gg.color.backgr); + gsignallabel(g->x, g->y, g, gg.color.backgr); + if (g->kind->numpnums > 0) + drawpnums(g, gg.color.backgr); + drawgatedotsc(g->x, g->y, g->g, gg.color.backgr); + calltoolgate(g, act_erasegate); +} + +#undef rtn + +/*================== LINKGATE ==================*/ +/*= =*/ +/*= Add a gate to the gate list. =*/ +/*= =*/ +/*================================================*/ + +static void linkgate(log_grec **g) +{ + (*g)->next = gg.gbase[gg.curpage - 1]; + gg.gbase[gg.curpage - 1] = *g; + chpageplace((int)gg.curpage, (*g)->x - (*g)->kind->bbmax, + (*g)->y - (*g)->kind->bbmax, (*g)->x + (*g)->kind->bbmax, + (*g)->y + (*g)->kind->bbmax); +} + +/*=================== NEWGATE ==================*/ +/*= =*/ +/*= Create a gate. =*/ +/*= =*/ +/*================================================*/ + +static void newgptr(log_grec **g) +{ + if (freegate == NULL) + { + *g = (log_grec *)Malloc(sizeof(log_grec)); + } + else + { + *g = freegate; + freegate = freegate->next; + } +} + + +static void newgate2(log_grec **g, short gt, short sig, log_gattrrec *attrs) +{ + short i; + char name[256]; + + newgptr(g); + (*g)->g = gt; + (*g)->rot = gt / log_kindoffset; + (*g)->kind = kind[(gt & (log_kindoffset - 1)) - 1]; + (*g)->vars = (na_long)0; + (*g)->conflict = false; + (*g)->conflict1 = false; + (*g)->conflict2 = false; + (*g)->oconflict = false; + (*g)->dimcolor = false; + (*g)->pin = (log_nrec **)Malloc((*g)->kind->numpins * sizeof(log_nrec *)); + (*g)->pinpos = (log_pinposrec *) + Malloc((*g)->kind->numpins * sizeof(log_pinposrec)); + if (attrs != NULL) + copyattrs(&(*g)->attr, attrs, (*g)->kind->numattrs, (*g)->kind->attr); + else + newattrs(&(*g)->attr, (*g)->kind->numattrs, (*g)->kind->attr); + + if (sig != 0) + { + (*g)->sig = sig; + } + else if ((*g)->kind->simtype == simtype_common) + { + *name = '\0'; + i = 1; + while ((*g)->kind->proc[i - 1] != '\0') + { + sprintf(name + strlen(name), "%c", (*g)->kind->proc[i - 1]); + i++; + } + (*g)->sig = getsignal(0, name); + } + else + { + (*g)->sig = 0; + } + (*g)->info = (na_long)0; + (*g)->temp = (na_long)0; + gg.actflag = (attrs != NULL); + calltoolgate(*g, act_newgate); +} + + +static void newgate(log_grec **g, short gt) +{ + newgate2(g, gt, 0, NULL); +} + + +/*================ COPYGATE ====================*/ +/*= =*/ +/*= Make a copy of a gate (unlinked). =*/ +/*= =*/ +/*================================================*/ + +static void copygate(log_grec *old, log_grec **g) +{ + long i, FORLIM; + + newgptr(g); + **g = *old; + if ((*g)->conflict || (*g)->oconflict) + { + (*g)->confnext = gateconflictbase; + gateconflictbase = *g; + } + (*g)->pin = (log_nrec **)Malloc((*g)->kind->numpins * sizeof(log_nrec *)); + FORLIM = (*g)->kind->numpins; + for (i = 0; i < FORLIM; i++) + (*g)->pin[i] = old->pin[i]; + (*g)->pinpos = (log_pinposrec *) + Malloc((*g)->kind->numpins * sizeof(log_pinposrec)); + FORLIM = (*g)->kind->numpins; + for (i = 0; i < FORLIM; i++) + (*g)->pinpos[i] = old->pinpos[i]; + copyattrs(&(*g)->attr, old->attr, (*g)->kind->numattrs, (*g)->kind->attr); + (*g)->info = (na_long)0; + gg.actgate2 = old; + calltoolgate(*g, act_copygate); +} + + +/*================== UNLKGATE ==================*/ +/*= =*/ +/*= Remove a gate from gate list. =*/ +/*= =*/ +/*================================================*/ + +static void unlkgate(log_grec **g) +{ + log_grec *g1; + + g1 = gg.gbase[gg.curpage - 1]; + while (g1 != NULL && g1->next != *g) + g1 = g1->next; + if (g1 == NULL) + gg.gbase[gg.curpage - 1] = (*g)->next; + else + g1->next = (*g)->next; + chpageplace((int)gg.curpage, (*g)->x - (*g)->kind->bbmax, + (*g)->y - (*g)->kind->bbmax, (*g)->x + (*g)->kind->bbmax, + (*g)->y + (*g)->kind->bbmax); +} + + +/*=============== DISPOSEGATE ==================*/ +/*= =*/ +/*= Dispose of a gate. =*/ +/*= =*/ +/*================================================*/ + +static void disposegptr(log_grec **g) +{ + (*g)->next = freegate; + freegate = *g; +} + + +#define rtn "DISPOSEGATE" + + +static void disposegate(log_grec **g) +{ + log_grec *g1, *g2; + + if ((*g)->conflict || (*g)->oconflict) + { + g1 = gateconflictbase; + g2 = NULL; + while (g1 != NULL && g1 != *g) + { + g2 = g1; + g1 = g1->confnext; + } + if (g1 == NULL) + report(10, rtn); + else if (g2 == NULL) + gateconflictbase = (*g)->confnext; + else + g2->confnext = (*g)->confnext; + } + if (*g == gg.probegate) + gg.probegate = NULL; + calltoolgate(*g, act_disposegate); + disposeattrs(&(*g)->attr, (*g)->kind->numattrs, (*g)->kind->attr); + Free((*g)->pin); + Free((*g)->pinpos); + disposegptr(g); +} + +#undef rtn + +/*================ CLOSERGATE ==================*/ +/*= =*/ +/*= Find which gate (if any) is under cursor. =*/ +/*= Also checks for textual labels. =*/ +/*= =*/ +/*================================================*/ + +static void closergate(short x, short y) +{ + if (gg.textinvisible) + gg.nearlabel = NULL; + else { + gg.nearlabel = gg.lbase[gg.curpage - 1]; + while (gg.nearlabel != NULL && + (x < gg.nearlabel->x || + x > gg.nearlabel->x + m_strwidth(logfont_lfont, + gg.nearlabel->name) / gg.scale || + y < gg.nearlabel->y || y > gg.nearlabel->y + 2)) { + gg.nearlabel = gg.nearlabel->next; + } + } + if (gg.nearlabel != NULL) { + gg.nearbox = NULL; + gg.neargate = NULL; + return; + } + if (!gg.textinvisible) { + gg.nearbox = gg.bbase[gg.curpage - 1]; + while (gg.nearbox != NULL && + ((x != gg.nearbox->x1 && x != gg.nearbox->x2 && + y != gg.nearbox->y1 && + y != gg.nearbox->y2) || x < gg.nearbox->x1 || + x > gg.nearbox->x2 || y < gg.nearbox->y1 || y > gg.nearbox->y2)) + gg.nearbox = gg.nearbox->next; + } else + gg.nearbox = NULL; + if (gg.nearbox != NULL) + { + gg.neargate = NULL; + return; + } + gg.neargate = gg.gbase[gg.curpage - 1]; + while (gg.neargate != NULL && !insidegate(gg.neargate, x, y)) + gg.neargate = gg.neargate->next; +} + +#define rtn "CHGGATE" + + +static void chggate(log_grec *g, int i, log_nrec *oldnode, log_nrec *n) +{ + log_hwrec *hw; + log_vwrec *vw; + log_grec *g1; + short j, k, savepg, pg, x, y, FORLIM; + + if (gg.traceflag) + fprintf(tracefile, "Change gate %ld pin %d to node %ld\n", + (long)g, i, (long)n); + j = i; + do + { + if (g->pin[j - 1] == oldnode) + { + switchnode(&g->pin[j - 1], n); + /* if (j <> i) then */ + /*unsafe optimization*/ + x = g->pinpos[j - 1].x; + y = g->pinpos[j - 1].y; + hw = gg.hwbase[gg.curpage - 1]; + while (hw != NULL) + { + if (hw->x1 <= x && x <= hw->x2 && hw->y == y && hw->node == oldnode) + chghw(hw, oldnode, n); + hw = hw->next; + } + vw = gg.vwbase[gg.curpage - 1]; + while (vw != NULL) + { + if (vw->y1 <= y && y <= vw->y2 && vw->x == x && vw->node == oldnode) + chgvw(vw, oldnode, n); + vw = vw->next; + } + g1 = gg.gbase[gg.curpage - 1]; + while (g1 != NULL) + { + if (g1 != g && P_imax2((long)abs(g1->x - x), (long)abs(g1->y - y)) <= + g1->kind->bbmax) { + FORLIM = g1->kind->numpins; + for (k = 1; k <= FORLIM; k++) { + if (x == g1->pinpos[k - 1].x && y == g1->pinpos[k - 1].y && + g1->pin[k - 1] == oldnode) + chggate(g1, k, oldnode, n); + } + } + g1 = g1->next; + } + } + j = g->kind->pin[j - 1].c; + } while (j != i && j != 0); + if (i != 1 || g->kind->simtype != simtype_common || g->sig == 0 || + gg.signaltab[g->sig - 1].np != oldnode) + return; + switchnode(&gg.signaltab[g->sig - 1].np, n); + savepg = gg.curpage; + FORLIM = gg.numpages; + for (pg = 1; pg <= FORLIM; pg++) + { + gg.curpage = pg; + g1 = gg.gbase[gg.curpage - 1]; + while (g1 != NULL) + { + if (g1->kind->simtype == simtype_common && g1->sig == g->sig && + g1->pin[0] == oldnode) + chggate(g1, 1, oldnode, n); + g1 = g1->next; + } + } + gg.curpage = savepg; +} + +#undef rtn + +static void chggatepin(log_grec *g, short i, log_nrec **oldnode, log_nrec **savenode) +{ + log_nrec *n; + log_hwrec *hw; + log_vwrec *vw; + log_grec *g1; + short j, x, y, FORLIM; + + if (gg.traceflag) + fprintf(tracefile, "Change gate %ld pin %d from node %ld\n", + (long)g, i, (long)(*oldnode)); + x = g->pinpos[i - 1].x; + y = g->pinpos[i - 1].y; + hw = gg.hwbase[gg.curpage - 1]; + while (hw != NULL) + { + if (hw->x1 <= x && x <= hw->x2 && hw->y == y && hw->node == *oldnode) + { + delgetnode(savenode, oldnode, &n); + if (n != *oldnode) + chghw(hw, *oldnode, n); + } + hw = hw->next; + } + vw = gg.vwbase[gg.curpage - 1]; + while (vw != NULL) + { + if (vw->y1 <= y && y <= vw->y2 && vw->x == x && vw->node == *oldnode) + { + delgetnode(savenode, oldnode, &n); + if (n != *oldnode) + chgvw(vw, *oldnode, n); + } + vw = vw->next; + } + g1 = gg.gbase[gg.curpage - 1]; + while (g1 != NULL) + { + if (g1 != g && + P_imax2((long)abs(g1->x - x), (long)abs(g1->y - y)) <= g1->kind->bbmax) + { + FORLIM = g1->kind->numpins; + for (j = 1; j <= FORLIM; j++) + { + if (x == g1->pinpos[j - 1].x && y == g1->pinpos[j - 1].y && + g1->pin[j - 1] == *oldnode) { + delgetnode(savenode, oldnode, &n); + if (n != *oldnode) + chggate(g1, j, *oldnode, n); + } + } + } + g1 = g1->next; + } +} + + +static void disconnectgate(log_grec *g) +{ + log_nrec *savenode; + short i, j; + log_nrec **oldnode; + long done[log_maxpins / 32 + 2]; + short FORLIM; + long SET[9]; + + if (gg.traceflag) + fprintf(tracefile, "Disconnect gate %ld\n", (long)g); + stamp(&g->kind->simtype->netstamp); + calltoolgate(g, act_disconnectgate); + oldnode = (log_nrec **)Malloc(g->kind->numpins * sizeof(log_nrec *)); + FORLIM = g->kind->numpins; + for (i = 0; i < FORLIM; i++) + { + oldnode[i] = g->pin[i]; + stamp(&oldnode[i]->simtype->netstamp); + switchnode(&g->pin[i], NULL); + } + P_expset(done, 0L); + FORLIM = g->kind->numpins; + for (i = 1; i <= FORLIM; i++) + { + if (!P_inset(i, done)) + { + j = i; + if (i == 1 && g->kind->simtype == simtype_common && g->sig != 0) + savenode = NULL; + else + savenode = oldnode[i - 1]; + do { + chggatepin(g, j, &oldnode[i - 1], &savenode); + P_addset(done, j); + j = g->kind->pin[j - 1].c; + } while (j != i && j != 0); + } + } + unlkgate(&g); +} + + +static void delgate(log_grec *g) +{ + clipon(); + eragate(g); + disconnectgate(g); + disposegate(&g); + clipoff(); +} + diff --git a/log/src/label.c b/log/src/label.c new file mode 100644 index 0000000000000000000000000000000000000000..8ab234f0fe3b7012b71dc7b45bdf53bd05bf183a --- /dev/null +++ b/log/src/label.c @@ -0,0 +1,388 @@ + +#include <p2c/p2c.j> + +/** + * @param lbl: list of character to parse + * @param numattrs: number of found attributs + * @param attr: vector containing parsed attributs + */ +static void parselabel(na_strlist_t **lbl, short *numattrs, log_kattrrec **attr) +{ + short j, j1, j2, j3, yy, maxx; + na_strlist_t *l1, *l2, *l3, *attrnames; + char buf[256]; + int haveprec; + log_kattrrec *WITH; + char STR1[256]; + char STR2[256]; + short FORLIM; + + j = 1; + *numattrs = 0; + attrnames = NULL; + l1 = *lbl; + // boucle qui compte le nombre d'attribut + while (l1 != NULL) { + j = strposc(l1->s, ':', 1L); + if (j != 0 && j != strpos2(l1->s, "::", 1)) + (*numattrs)++; + + l1->value = (na_long)strlen(l1->s); + l1 = l1->next; + } + *attr = (log_kattrrec *)Malloc(*numattrs * kattrrecsize); + maxx = 0; + l1 = *lbl; + j = 1; + yy = 0; + // On parcours de nouveau la liste de string + while (l1 != NULL) + { + j1 = strposc(l1->s, ':', 1L); + // Si c'est bien un attribut + if (j1 != 0 && j1 != strpos2(l1->s, "::", 1)) + { + WITH = &(*attr)[j - 1]; + WITH->vr = 0; + WITH->vra = 0; + strcpy(STR1, strltrim(l1->s)); + strcpy(l1->s, STR1); // TODO optimiser + // elimine les [ ] si autour de l'attribut + while (l1->s[0] == '[') + { + j2 = strposc(l1->s, ']', 1L); + if (j2 < 3) + continue; + l2 = strlist_append(&attrnames, strpart(STR1, l1->s, 2, j2 - 1)); + l2->value = (na_long)((long)j); + strcpy_overlap(l1->s, l1->s + j2); + strcpy(STR1, strltrim(l1->s)); + strcpy(l1->s, STR1); // TODO optimiser + } + j2 = strposc(l1->s, ';', 1L); + if (j2 != 0 && j2 < j1) + { + sprintf(buf, "%.*s", j2 - 1, l1->s); + strrtrim(buf); + j3 = 1; + // Recherche si l'attribut à déjà été défini + while (j3 < j && WITH->vra == 0) + { + if ((*attr)[j3 - 1].dtype == 'V') + { + l2 = (*attr)[j3 - 1].UU.U86.v; + while (l2 != NULL && strcicmp(l2->s, buf) != 0) + l2 = l2->next; + + if (l2 != NULL) { + WITH->vr = (long)l2->value; + WITH->vra = j3; + } + } + j3++; + } + strcpy_overlap(l1->s, l1->s + j2); + } + if (l1->s[0] == ' ') + { + strcpy(STR1, strltrim(l1->s)); + strcpy(l1->s, STR1); // TODO optimiser + } + WITH->prec = 0; + haveprec = false; + while (isdigit(l1->s[0])) + { + WITH->prec = WITH->prec * 10 + l1->s[0] - 48; + haveprec = true; + strcpy_overlap(l1->s, l1->s + 1); + } + if (l1->s[0] == ' ') + { + strcpy(STR1, strltrim(l1->s)); + strcpy(l1->s, STR1); + } + WITH->opt = false; + do + { + WITH->dtype = toupper(l1->s[0]); + if (l1->s[0] != ':') + { + do + { + strcpy_overlap(l1->s, l1->s + 1); + } + while (l1->s[0] == ' '); + } + if (WITH->dtype == 'O') + WITH->opt = true; + + } + while (WITH->dtype == 'O'); + + if (WITH->dtype == 'F' || WITH->dtype == 'U' || WITH->dtype == 'R') + { + *WITH->UU.U82.u = '\0'; + if (WITH->dtype == 'F' || WITH->dtype == 'U') + { + while (l1->s[0] != ',' && l1->s[0] != ':') + { + if (l1->s[0] != ' ' && strlen(WITH->UU.U82.u) < 3) + sprintf(WITH->UU.U82.u + strlen(WITH->UU.U82.u), "%c", l1->s[0]); + + strcpy_overlap(l1->s, l1->s + 1); + } + if (l1->s[0] == ',') + strcpy_overlap(l1->s, l1->s + 1); + + strcpy(STR1, strltrim(l1->s)); + strcpy(l1->s, STR1); + } + *buf = '\0'; + while (l1->s[0] != ':') + { + sprintf(buf + strlen(buf), "%c", l1->s[0]); + strcpy_overlap(l1->s, l1->s + 1); + } + WITH->UU.U82.r = 0.0; + WITH->blnk = true; + if (*buf != '\0') + { + readreal(buf, &WITH->UU.U82.r); + WITH->blnk = false; + } + if (!haveprec) + WITH->prec = 0; + + } + else if (WITH->dtype == 'I') + { + WITH->UU.U73.i1 = 0; + WITH->blnk = true; + while (isdigit(l1->s[0])) + { + WITH->UU.U73.i1 = WITH->UU.U73.i1 * 10 + l1->s[0] - 48; + strcpy_overlap(l1->s, l1->s + 1); + WITH->blnk = false; + } + if (!haveprec) + WITH->prec = 1; + + } + else if (WITH->dtype == 'H') + { + WITH->UU.U73.i1 = 0; + j1 = 0; + WITH->blnk = true; + while ((l1->s[0] >= 'a' && l1->s[0] <= 'f') || + (l1->s[0] >= 'A' && l1->s[0] <= 'F') || isdigit(l1->s[0])) + { + WITH->UU.U73.i1 = WITH->UU.U73.i1 * 10 + l1->s[0] - 48; + if (l1->s[0] >= 'A') + WITH->UU.U73.i1 -= 7; + + if (l1->s[0] >= 'a') + WITH->UU.U73.i1 -= 32; + + strcpy_overlap(l1->s, l1->s + 1); + j1++; + WITH->blnk = false; + } + if (!haveprec) + { + if (j1 != 0) + WITH->prec = j1; + else + WITH->prec = 1; + } + } + else if (WITH->dtype == 'C') + { + j1 = strposc(l1->s, ':', 1L); + sprintf(buf, "%.*s", j1 - 1, l1->s); + strrtrim(buf); + strcpy_overlap(l1->s, l1->s + j1 - 1); + if (!haveprec) + WITH->prec = 255; + + if (strlen(buf) > WITH->prec) + buf[WITH->prec] = '\0'; + + WITH->UU.c = (char *)Malloc(WITH->prec + 1L); + strcpy(WITH->UU.c, buf); + WITH->blnk = (*buf == '\0'); + } + else if (WITH->dtype == 'A') + { + j1 = strposc(l1->s, ':', 1L); + sprintf(buf, "%.*s", j1 - 1, l1->s); + strrtrim(buf); + strcpy_overlap(l1->s, l1->s + j1 - 1); + WITH->prec = 255; + WITH->UU.sp = strdup(buf); + WITH->blnk = (*buf == '\0'); + } + else if (WITH->dtype == 'B') + { + WITH->blnk = false; + if (l1->s[0] == 'y' || l1->s[0] == 'Y' || l1->s[0] == 't' || l1->s[0] == 'T') + WITH->UU.b = true; + else if (l1->s[0] == 'n' || l1->s[0] == 'N' || l1->s[0] == 'f' || l1->s[0] == 'F') + WITH->UU.b = false; + else + WITH->blnk = true; + + if (l1->s[0] == 'x' || l1->s[0] == 'X' || l1->s[0] == 'f' || + l1->s[0] == 'F' || l1->s[0] == 't' || l1->s[0] == 'T') + WITH->prec = 2; + else + WITH->prec = 1; + } + else if (WITH->dtype == 'V') + { + strlist_init(&l2); + WITH->UU.U86.nv = 0; + do + { + *buf = '\0'; + while (l1->s[0] != ',' && l1->s[0] != ':') + { + sprintf(buf + strlen(buf), "%c", l1->s[0]); + strcpy_overlap(l1->s, l1->s + 1); + } + if (l1->s[0] == ',') + strcpy_overlap(l1->s, l1->s + 1); + + l3= strlist_append(&l2,strcpy(STR1, strltrim(strrtrim(strcpy(STR2, buf))))); + l3->value = (na_long)((long)WITH->UU.U86.nv); + WITH->UU.U86.nv++; + strcpy(STR1, strltrim(l1->s)); + strcpy(l1->s, STR1); + } + while (l1->s[0] != ':'); + WITH->UU.U86.v = l2; + WITH->blnk = false; + if (haveprec) + WITH->UU.U86.dv = WITH->prec; + else + WITH->UU.U86.dv = 0; + + WITH->prec = 1; + } + else + { + WITH->dtype = 'R'; + WITH->UU.U82.r = 0.0; + WITH->blnk = true; + if (!haveprec) + WITH->prec = 0; + } + if (WITH->blnk) + WITH->opt = true; + + j1 = strposc(l1->s, ':', 1L); + strcpy_overlap(l1->s, l1->s + j1); + j++; + WITH->y = yy; + if (strlen(l1->s) > maxx) + maxx = strlen(l1->s); + + } + j1 = 1; + while (j1 < strlen(l1->s)) + { + if (l1->s[j1 - 1] == ':' && l1->s[j1] == ':') + strcpy_overlap(l1->s + j1 - 1, l1->s + j1); + j1++; + } + yy++; + l1 = l1->next; + } + if (attrnames != NULL) { + l1 = strlist_insert(lbl, ""); + l1->kind = '\001'; + l1->value = (void *)attrnames; + } + FORLIM = *numattrs; + for (j = 0; j < FORLIM; j++) + (*attr)[j].x = maxx + 1; +} + +/*================== ERALABEL ==================*/ +/*= =*/ +/*= Erase a text label from the screen. =*/ +/*= =*/ +/*================================================*/ + +static void eralabel(log_lrec *l) +{ + m_color((long)gg.color.backgr); + m_drawstr(l->x * gg.scale - gg.xoff, l->y * gg.scale - gg.yoff + 2, + logfont_lfont, l->name); +} + + +/*================== XORLABEL ==================*/ +/*= =*/ +/*= XOR a text label onto the screen. =*/ +/*= =*/ +/*================================================*/ + +static void xorlabel(short x, short y, log_lrec *l) +{ + m_colormode((long)m_xor); + m_color((long)gg.color.labeltext); + m_drawstr(x * gg.scale - gg.xoff, y * gg.scale - gg.yoff + 2, logfont_lfont, + l->name); + m_colormode((long)m_normal); +} + +/*================== NEWLABEL ==================*/ +/*= =*/ +/*= Create a Label. =*/ +/*= =*/ +/*================================================*/ + +static void linklabel(log_lrec *l) +{ + l->next = gg.lbase[gg.curpage - 1]; + gg.lbase[gg.curpage - 1] = l; + stamp(&gg.labelstamp); +} + + +static void newlabel(log_lrec **l) +{ + *l = (log_lrec *)Malloc(sizeof(log_lrec)); + (*l)->temp = (na_long)0; + linklabel(*l); +} + + +/*================ DISPLABEL ===================*/ +/*= =*/ +/*= Dispose of a text label. =*/ +/*= =*/ +/*================================================*/ + +static void unlinklabel(log_lrec *l) +{ + log_lrec *l1; + + l1 = gg.lbase[gg.curpage - 1]; + while (l1 != NULL && l1->next != l) + l1 = l1->next; + if (l1 == NULL) + gg.lbase[gg.curpage - 1] = l->next; + else + l1->next = l->next; + chpageplace((int)gg.curpage, l->x, l->y, l->x + l->w, l->y + 2); + stamp(&gg.labelstamp); +} + + +static void displabel(log_lrec **l) +{ + unlinklabel(*l); + Free(*l); +} + diff --git a/log/src/log.c b/log/src/log.c index 8e0de4da12a8d3367f28140b603f1e5eca85eddd..8be65cc8cb359f7a51f8223e49b01a80df9a890d 100644 --- a/log/src/log.c +++ b/log/src/log.c @@ -18,14 +18,10 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - + the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ /* - - - Logic Simulator Version 4.1 For HP 9836C @@ -33,8 +29,6 @@ Copyright (c) 1985 David Gillespie - - */ @@ -315,10 +309,6 @@ typedef struct baseptrs { - - - - /* 0*/ /* If the pen is in "this" sector, */ /* 1*/ @@ -603,93 +593,6 @@ extern void nc_cursor_on (); extern void nc_cursor_off (); - -/*================= INITSCREEN =================*/ -/*= =*/ -/*= Initialize color graphics, graphics tablet, =*/ -/*= low-level flags & variables =*/ -/*= =*/ -/*================================================*/ - -static void initcolormap() -{ - m_setcolor((long)log_gray, 4L, 4L, 4L); - m_setcolor((long)log_red, 15L, 0L, 0L); - m_setcolor((long)log_green, 0L, 15L, 0L); - m_setcolor((long)log_yellow, 15L, 15L, 0L); - if (eightcolors) { - m_setcolor((long)log_cred8, 15L, 0L, 0L); - m_setcolor((long)log_black8, 0L, 0L, 0L); - } else { - m_setcolor((long)log_mred, 11L, 0L, 0L); - m_setcolor((long)log_orange, 15L, 9L, 0L); - } - m_setcolor((long)log_cyan, 0L, 15L, 15L); - m_setcolor((long)log_white, 15L, 15L, 15L); - m_setcolor((long)log_black, 0L, 0L, 0L); - m_setcolor((long)log_pink, 15L, 9L, 9L); - m_setcolor((long)log_dyellow, 12L, 12L, 0L); - m_setcolor((long)log_xgreen, 0L, 13L, 0L); - m_setcolor((long)log_dcyan, 0L, 10L, 10L); - m_setcolor((long)log_dred, 8L, 0L, 0L); - m_setcolor((long)log_lgray, 10L, 10L, 10L); - m_setcolor((long)log_cred, 15L, 0L, 0L); - m_vseecolors(0L, 16L, rcolormap, gcolormap, bcolormap); -} - - -static void fixcolormap() -{ - m_vsetcolors(0L, 16L, rcolormap, gcolormap, bcolormap); - recolor_log_cursors(gg.color.cursor, true); -} - - - -static void initscreen() -{ - m_init_screen(); - m_upside_down(); - m_setlinestyle(1L, 0xf0f0L); - m_setlinestyle(2L, 0xaaaaL); - m_setfont(logfont_lfont); - init_X_screen(); - onescreen = nc_alphashared(); - eightcolors = (m_maxcolor <= 7); - - txacross = nc_curWindow->width - 1; - txdown = nc_curWindow->height - 1; - across = m_across; - down = m_down; - baseline = down - 53; /* Position of baseline on screen */ - line1 = down - 43; /* Position of first text line in menu */ - line2 = down - 23; /* Position of second text line in menu */ - histdown = down - 26; - histdivsacross = (double)(across - histleft) / histdivision; - histvalrange = (double)histdown / histdivision * 5; - kindgroupsize = (across - 160) / kindgroupspacing; - kindgroupleft = (across - kindgroupsize * kindgroupspacing) / 2; - kindgroupright = kindgroupleft + kindgroupsize * kindgroupspacing; - kindgroupstart = kindgroupleft + kindgroupspacing / 2; - kindgroupbase = (baseline + down) / 2; - - printf("\200\210"); - SETRUNLIGHT(' '); - - cursorflag = false; - gg.stillnear = true; -} - - -static void initscreen2() -{ - initscreen(); - m_clear(); - m_graphics_on(); -} - - - static char *ioresult_message(char *Result, long iores) { char s[81]; @@ -737,47 +640,6 @@ static void warning() } -/*================== NOBLINK ===================*/ -/*= =*/ -/*= Turn off the stupid blinking Alpha cursor. =*/ -/*= =*/ -/*================================================*/ - -static void noblink() -{ - nc_cursXY(-1, -1); - /* oldx := xpos; -oldy := ypos; -xpos := -1; -ypos := -1; -call(updatecursorhook); -xpos := oldx; -ypos := oldy; */ -} - - - - -static void clearalpha() -{ - if (!onescreen) - { - printf("\f"); - noblink(); - m_alpha_off(); - } - nk_gotoxy(0, 0); -} - - -static void showalpha() -{ - m_graphics_off(); - m_alpha_on(); -} - - - static void clearshowalpha (); /*=================== REPORT ===================*/ @@ -815,3694 +677,942 @@ static void report(short num, char *s) } -/*=================== LINE =====================*/ +/*================== SETMODE ===================*/ /*= =*/ -/*= Draw a line in grid coordinates. =*/ +/*= Draw a word in the "mode" location of =*/ +/*= the menu area. =*/ /*= =*/ /*================================================*/ -static void line(short x1, short y1, short x2, short y2) -{ - m_drawline(x1 * gg.scale - gg.xoff, y1 * gg.scale - gg.yoff, - x2 * gg.scale - gg.xoff, y2 * gg.scale - gg.yoff); -} - - -/*=================== HLINE ====================*/ -/*= =*/ -/*= Draw a horizontal line in grid coordinates. =*/ -/*= =*/ -/*= =*/ -/*================================================*/ +static void refreditmode (); -static void hline(short x1, short x2, short y) +static void log_setmode(const char *s) { - short yy; + time_t h; + char *cp; - yy = y * gg.scale - gg.yoff; - m_drawline(x1 * gg.scale - gg.xoff, (long)yy, x2 * gg.scale - gg.xoff, (long)yy); + remcursor(); + clipoff(); + m_color((long)gg.color.backgr); + if (gg.showpage > 0) + drawstr2(across + menux3, line2, modename); + refreditmode(); /*may have been trashed by previous mode name*/ + if (*s != '\0') + { + strcpy(modename, s); + modeflag = true; + m_color((long)gg.color.selword); + } + else + { + if (gg.probekind != NULL) + { + strcpy(modename, gg.probekind->name); + m_color((long)gg.color.selword); + } + else + { + time(&h); + cp = ctime(&h); + sprintf(modename, "%.5s", cp + 11); + modetime = timers_sysclock() / 6000; + if (!strcmp(modename, "00:00")) + strcpy(modename, "__@/ "); + m_color((long)gg.color.menuword); + } + modeflag = false; + modeprobekind = gg.probekind; + } + if (gg.showpage > 0) + drawstr2(across + menux3, line2, modename); } -/*=================== VLINE ====================*/ -/*= =*/ -/*= Draw a vertical line in grid coordinates. =*/ -/*= =*/ -/*= =*/ -/*================================================*/ - -static void vline(short x, short y1, short y2) +static void dounits(char *s, double *r) { - short xx; - - xx = x * gg.scale - gg.xoff; - m_drawline((long)xx, y1 * gg.scale - gg.yoff, (long)xx, - y2 * gg.scale - gg.yoff); -} - - -/*=================== POINT ====================*/ -/*= =*/ -/*= Draw a point in grid coordinates. =*/ -/*= =*/ -/*================================================*/ + char ch; -static void point(short x, short y) -{ - m_drawpoint(x * gg.scale - gg.xoff, y * gg.scale - gg.yoff); + if (*s == '\0') + return; + ch = s[0]; + if (ch >= 'a') + ch -= 32; + if (ch == 'F') + { + *r *= 1e-15; + return; + } + if (ch == 'P') + { + *r *= 1e-12; + return; + } + if (ch == 'N') + { + *r *= 1e-9; + return; + } + if (ch == 'U') + { + *r *= 1e-6; + return; + } + if (ch == 'K') + { + *r *= 1e3; + return; + } + if (ch == 'G') + { + *r *= 1e9; + return; + } + if (ch == 'T') + { + *r *= 1e12; + return; + } + if (ch != 'M') + return; + if (strlen(s) >= 3 && (s[1] == 'E' || s[1] == 'e') && + (s[2] == 'G' || s[2] == 'g')) + *r *= 1e6; + else + *r *= 1e-3; } -/*=================== RECT =====================*/ -/*= =*/ -/*= Draw a rectangle in grid coordinates. =*/ -/*= =*/ -/*================================================*/ - -static void rect(short x1, short y1, short x2, short y2) +static void readreal(char *s_, double *r) { - m_drawrect(x1 * gg.scale - gg.xoff, y1 * gg.scale - gg.yoff, - x2 * gg.scale - gg.xoff, y2 * gg.scale - gg.yoff); -} - -/*==================== BOX =====================*/ -/*= =*/ -/*= Draw a filled rectangle in grid coords. =*/ -/*= =*/ -/*================================================*/ + char s[256]; + long i; + char *STR1; + char STR2[256]; -static void box(short x1, short y1, short x2, short y2) -{ - m_fillrect(x1 * gg.scale - gg.xoff, y1 * gg.scale - gg.yoff, - x2 * gg.scale - gg.xoff, y2 * gg.scale - gg.yoff); + strcpy(s, s_); + if (!(*s != '\0' && + (s[0] == '.' || s[0] == '+' || s[0] == '-' || isdigit(s[0])))) + return; + *r = strtod(s, &STR1); + i = STR1 - s + 1; + strcpy_overlap(s, s + i - 1); + strcpy(STR2, strltrim(s)); + strcpy(s, STR2); + dounits(s, r); } -/*================= DRAWSTR2 ===================*/ -/*= =*/ -/*= Draw a text string. =*/ -/*= =*/ -/*================================================*/ -static void drawstr2(short x, short y, char *s) +static void strwordx(char *buf, char *wrd) { - long save; + size_t i; + char STR1[256]; + char STR2[256]; - if (m_curcolor() < 16) + strcpy(STR1, strltrim(strrtrim(strcpy(STR2, buf)))); + strcpy(buf, STR1); + if (*buf != '"') { - save = m_curcolor(); - m_color((long)gg.color.backgr); - m_fillrect(x - 1L, y - 2L, x + m_strwidth(logfont_lfont, s), y + 9L); - m_color(save); + strword(buf, wrd); + return; } - m_move((long)x, (long)y); - m_displaytext(s); + i = strposc(buf, '"', 2L); + if (i == 0) + i = strlen(buf) + 1; + strpart(wrd, buf, 2, i - 1); + strcpy_overlap(buf, buf + i); } -static void rightstr2(short x, short y, char *s) +static void getword(char *buf, char *wrd) { - long save; + char STR1[256]; + char STR2[256]; - if (m_curcolor() < 16) + strcpy(STR1, strltrim(strrtrim(strcpy(STR2, buf)))); + strcpy(buf, STR1); + if (*buf == '"') + strwordx(buf, wrd); + else { - save = m_curcolor(); - m_color((long)gg.color.backgr); - m_fillrect(x + m_strwidth(logfont_lfont, s) - 1, y - 2L, x + 1L, y + 9L); - m_color(save); + strwordx(buf, wrd); + strupper(wrd, wrd); } - m_rightstr((long)x, (long)y, logfont_lfont, s); } -static void centerstr2(short x, short y, char *s) +static long getint(char *s, long def) { - short w; - long save; + char w[10]; + long i, j, sign; + int valid; + long FORLIM; - if (m_curcolor() < 16) + getword(s, w); + if (*w == '-') { - save = m_curcolor(); - m_color((long)gg.color.backgr); - w = m_strwidth(logfont_lfont, s) / 2 + 2; - m_fillrect((long)(x - w), y - 2L, (long)(x + w), y + 9L); - m_color(save); + strcpy_overlap(w, w + 1); + sign = -1; + } + else + { + sign = 1; + } + j = 0; + valid = true; + FORLIM = strlen(w); + for (i = 0; i < FORLIM; i++) + { + if (w[i] < '0' || w[i] > '9') + valid = false; + else + j = j * 10 + w[i] - 48; } - m_centerstr((long)x, (long)y, logfont_lfont, s); -} + if (*w != '\0' && valid) + return (j * sign); + else + return def; +} -/*================= DRAWNUM1 ===================*/ -/*= =*/ -/*= Draw a single digit at the specified =*/ -/*= position (screen coordinates). =*/ -/*= =*/ -/*================================================*/ -static void drawnum1(short x, short y, short n) +static void pgetint(char *buf, long *i, long def) { - char s[2]; - - m_move((long)x, (long)y); - strcpy(s, " "); - s[0] = n + '0'; - m_displaytext(s); + *i = getint(buf, def); } -/*================= DRAWNUM2 ===================*/ -/*= =*/ -/*= Draw a two-digit number at the specified =*/ -/*= position (screen coordinates). =*/ -/*= =*/ -/*================================================*/ - -static void drawnum2(short x, short y, short n) +static double getreal(char *s, double def) { - char s[3]; + char w[81]; + double r; - m_move((long)x, (long)y); - strcpy(s, " "); - if (n >= 10) - s[0] = n / 10 + '0'; - s[1] = n % 10 + '0'; - m_displaytext(s); + getword(s, w); + r = def; + TRY(try1); + readreal(w, &r); + RECOVER(try1); + if (P_escapecode == -20) + _Escape(P_escapecode); + r = def; + ENDTRY(try1); + return r; } - -static void xformcoords(log_grec *g, short *x, short *y) +static void pgetreal(char *buf, double *r, double def) { - short xx, yy; - - if (g == NULL) - { - *x = *x * gg.scale - gg.xoff; - *y = *y * gg.scale - gg.yoff; - return; - } - xx = *x * gg.scale; - yy = *y * gg.scale; - *x = g->x * gg.scale - gg.xoff + - (log_rotxx[g->rot] * xx + log_rotyx[g->rot] * yy) / log_scale0; - *y = g->y * gg.scale - gg.yoff + - (log_rotxy[g->rot] * xx + log_rotyy[g->rot] * yy) / log_scale0; + *r = getreal(buf, def); } -static void plainxformcoords(log_grec *g, short *x, short *y) +static void getbool(char *buf, int *b) { - short xx; + char w[17]; - if (g == NULL) + getword(buf, w); + if (!strcmp(w, "ON") || !strcmp(w, "YES") || !strcmp(w, "Y") || + !strcmp(w, "RABBITS")) + { /*avoid*/ + *b = true; + return; + } + if (!strcmp(w, "OFF") || !strcmp(w, "NO") || !strcmp(w, "N")) { - *x *= log_scale0; - *y *= log_scale0; + *b = false; return; } - xx = *x; - *x = g->x * log_scale0 + log_rotxx[g->rot] * xx + log_rotyx[g->rot] * *y; - *y = g->y * log_scale0 + log_rotxy[g->rot] * xx + log_rotyy[g->rot] * *y; + + if (!strcmp(w, "?")) + tempverbose = true; + else if (*w == '\0') + *b = !*b; } -/*================== CLIPON ====================*/ +/*================= SORTSHINTS =================*/ /*= =*/ -/*= Allow drawing only in the working area. =*/ +/*= Put two shortint variables into increasing =*/ +/*= numerical order. =*/ /*= =*/ /*================================================*/ -static void clipon() +static void sortshints(short *x, short *y) { - m_clip(0L, 0L, (long)across, baseline - 1L); + short temp; + + if (*x <= *y) + return; + temp = *x; + *x = *y; + *y = temp; } -/*================== CLIPOFF ===================*/ +/*================= TESTPROBE ==================*/ /*= =*/ -/*= Allow drawing in working area and menus. =*/ +/*= Find which wire, pin, or gate the Probe =*/ +/*= is touching and set PROBENODE or =*/ +/*= PROBEGATE to its address. =*/ /*= =*/ /*================================================*/ -static void clipoff() +static void unprobe() { - m_noclip(); + gg.probenode = NULL; + gg.probegate = NULL; + gg.probepin = 0; + gg.probesimtype = NULL; + gg.probekind = NULL; + gg.probehwire = NULL; + gg.probevwire = NULL; + probeflag = false; } -/*================== UERASE ====================*/ -/*= =*/ -/*= Erase a rectangular area of the screen =*/ -/*= using screen coordinates. =*/ -/*= =*/ -/*================================================*/ -static void uerase(short x1, short y1, short x2, short y2) +static log_krec *peninkind(short xx, short yy) { - m_color((long)gg.color.backgr); - m_fillrect((long)x1, (long)y1, (long)x2, (long)y2); -} - - -/*=================== ERASE ====================*/ -/*= =*/ -/*= Erase a rectangular area of the screen =*/ -/*= using grid coordinates. =*/ -/*= =*/ -/*================================================*/ + log_krec *Result; + short i; -static void erase(short x1, short y1, short x2, short y2) -{ - m_color((long)gg.color.backgr); - box(x1, y1, x2, y2); + Result = NULL; + if (!(P_ibetween((long)kindgroupleft, (long)xx, kindgroupright - 1L) && + P_ibetween((long)baseline, (long)yy, (long)down))) + return Result; + i = kindgroup[(xx - kindgroupleft) / kindgroupspacing]; + if (i > 0) + return (kind[(i & (log_kindoffset - 1)) - 1]); + return Result; } -/*================ NORABBITS ===================*/ -/*= =*/ -/*= Make sure there are no rabbits on the =*/ -/*= screen. =*/ -/*= =*/ -/*================================================*/ - -static void norabbits() +static void testprobe(short xx, short yy) { - short i; + log_grec *g; + log_krec *k; + short i, x, y; + log_hwrec *hw; + log_vwrec *vw; + short FORLIM; - clipoff(); - for (i = 0; i < rabtabsize; i++) + x = (xx + gg.hscale + gg.xoff) / gg.scale; + y = (yy + gg.hscale + gg.yoff) / gg.scale; + unprobe(); + if (gg.showpage > 0 && !gg.invisible && !gg.showconflicts) { - if (rabtable[i].next == 1) + if (gg.incircuit) + { + g = gg.gbase[gg.curpage - 1]; + while (g != NULL && gg.probegate == NULL) + { + k = g->kind; + if (g->x >= x - k->bbmax && g->x <= x + k->bbmax && + g->y >= y - k->bbmax && g->y <= y + k->bbmax) + { + if (insidegate(g, x, y)) + { + gg.probegate = g; + } + else if (g->kind->simtype->simtype >= 8) + { + FORLIM = g->kind->numpins; + for (i = 1; i <= FORLIM; i++) { + if (x == g->pinpos[i - 1].x && y == g->pinpos[i - 1].y) + { + gg.probegate = g; + gg.probenode = g->pin[i - 1]; + gg.probepin = i; + } + } + } + } + g = g->next; + } + hw = gg.hwbase[gg.curpage - 1]; + while (hw != NULL && gg.probenode == NULL) + { + if (hw->x1 <= x && x <= hw->x2 && hw->y == y) + { + gg.probehwire = hw; + gg.probenode = hw->node; + } + hw = hw->next; + } + vw = gg.vwbase[gg.curpage - 1]; + while (vw != NULL && gg.probenode == NULL) + { + if (vw->y1 <= y && y <= vw->y2 && vw->x == x) + { + gg.probevwire = vw; + gg.probenode = vw->node; + } + vw = vw->next; + } + } + else { - m_bunny((long)rabtable[i].x, (long)rabtable[i].y); - rabtable[i].next = 0; + gg.probekind = peninkind(xx, yy); } } - rabflag = false; + if (gg.probegate != NULL) + gg.probekind = gg.probegate->kind; + if (gg.probenode != NULL) + gg.probesimtype = gg.probenode->simtype; + else if (gg.probekind != NULL) + gg.probesimtype = gg.probekind->simtype; } -/*================ ADDRABBIT ===================*/ -/*= =*/ -/*= Draw a rabbit on the screen. =*/ -/*= =*/ -/*================================================*/ - -static void addrabbit() +static void checkprobe(short xx, short yy) { - short i, j, rx, ry; - int nogood; - rablistrec *WITH; + short x, y; - clipoff(); - j = -1; - for (i = 1; i <= rabtabsize; i++) + x = (xx + gg.hscale + gg.xoff) / gg.scale; + y = (yy + gg.hscale + gg.yoff) / gg.scale; + if (gg.probegate != NULL && + (gg.probegate->x < x - gg.probekind->bbmax || + gg.probegate->x > x + gg.probekind->bbmax || + gg.probegate->y < y - gg.probekind->bbmax || + gg.probegate->y > y + gg.probekind->bbmax)) { - if (rabtable[i - 1].next == 0) - j = i; + unprobe(); + return; } - if (j == -1) + + if (gg.probekind != NULL && gg.probegate == NULL && + peninkind(xx, yy) != gg.probekind) { - j = P_rand(&gg.rndseed, (long)rabtabsize) + 1; - m_bunny((long)rabtable[j - 1].x, (long)rabtable[j - 1].y); - rabtable[j - 1].next = 0; + unprobe(); + return; } - do - { - rx = P_rand(&gg.rndseed, across - 24L); - ry = P_rand(&gg.rndseed, baseline - 40L) + down - baseline + 30; - nogood = false; - for (i = 0; i < rabtabsize; i++) - { - WITH = &rabtable[i]; - if (WITH->next == 1) - { - if (WITH->x + 24 >= rx && WITH->x <= rx + 24 && WITH->y + 26 >= ry && - WITH->y <= ry + 26) - nogood = true; - } - } - } while (nogood); - rabtable[j - 1].next = 1; - rabtable[j - 1].x = rx; - rabtable[j - 1].y = ry; - m_bunny((long)rx, (long)ry); - rabflag = true; - rabtime = timers_sysclock(); -} + if (gg.probehwire != NULL && + (gg.probehwire->x1 > x || x > gg.probehwire->x2 || + gg.probehwire->y != y)) + unprobe(); + else if (gg.probevwire != NULL && + (gg.probevwire->y1 > y || y > gg.probevwire->y2 || + gg.probevwire->x != x)) + unprobe(); +} -/*================== HVLINE ====================*/ -/*= =*/ -/*= Attempt to force a line to be horizontal =*/ -/*= or vertical. If possible, second pair =*/ -/*= of coordinates is changed appropriately. =*/ -/*= =*/ -/*= Returns true if possible, false if not. =*/ -/*= =*/ -/*================================================*/ -static int hvline(short x1, short y1, short *x2, short *y2) +static void stamp(long *i) { - int Result; - - Result = true; - if (x1 == *x2 && y1 == *y2) - return false; - if (abs(*x2 - x1) > abs(*y2 - y1) && abs(*y2 - y1) < abs(*x2 - x1) / 3 + 20) - { /*7/14/88*/ - *y2 = y1; - return Result; - } - if (abs(*y2 - y1) <= abs(*x2 - x1) || - abs(*x2 - x1) >= abs(*y2 - y1) / 3 + 20) - /*7/14/88*/ - return false; - *x2 = x1; - return Result; + gg.curstamp++; + *i = gg.curstamp; } -/*=================== FIXXY ====================*/ -/*= =*/ -/*= Adjust screen coordinates so that they are =*/ -/*= aligned to the nearest grid point. =*/ -/*= =*/ -/*================================================*/ - -static void fixxy(short *x, short *y) +static void send_general(log_tool *sim, char *act) { - *x = (*x + gg.xoff + gg.hscale) / gg.scale * gg.scale - gg.xoff; - *y = (*y + gg.yoff + gg.hscale) / gg.scale * gg.scale - gg.yoff; + char savefunc[17]; + + strcpy(savefunc, gg.genfunc); + strcpy(gg.genfunc, act); + calltool(sim, act_general); + strcpy(gg.genfunc, savefunc); } -/*================ NOCROSSHAIR =================*/ -/*= =*/ -/*= Turn off crosshair (no effect until next =*/ -/*= call of CURSOR). =*/ -/*= =*/ -/*================================================*/ -static void nocrosshair() +static void send_gennode(log_nrec *n, char *act) { - chairflag2 = false; -} + char savefunc[17]; + strcpy(savefunc, gg.genfunc); + strcpy(gg.genfunc, act); + calltoolnode(n, act_gennode); + strcpy(gg.genfunc, savefunc); +} -/*================= CROSSHAIR ==================*/ -/*= =*/ -/*= Move the crosshair to a particular position =*/ -/*= in grid coordinates. =*/ -/*= =*/ -/*================================================*/ -static void crosshair(short x, short y) +static void send_genkind(log_krec *k, char *act) { - chairx = x * gg.scale - gg.xoff; - chairy = y * gg.scale - gg.yoff; - chairflag2 = true; -} + char savefunc[17]; -/*================= XORCURSOR ==================*/ -/*= =*/ -/*= Draw the cursor on the screen. =*/ -/*= The exact shape drawn depends upon the =*/ -/*= current mode. =*/ -/*= If the cursor is already on the screen, it =*/ -/*= is removed. =*/ -/*= =*/ -/*= Possible cursors: =*/ -/*= Arrow (normal). =*/ -/*= Probe (if Logic Probe mode). =*/ -/*= Big crosshair (if "Grid" mode on). =*/ -/*= Long arrow (if Copy command). =*/ -/*= Scissors (if Delete command). =*/ -/*= Rectangle (if Paste command). =*/ -/*= Green line (if drawing a wire). =*/ -/*= Rabbit (if Rabbit mode). =*/ -/*= =*/ -/*================================================*/ - -static void xorcursor() -{ - long curcm; - short cx0, cy0; - - gg.cx_min = 0; - gg.cx_max = across; - gg.cy_min = 0; - gg.cy_max = baseline - 1; - curcm = m_curcolormode(); - m_colormode((long)m_xor); - m_color((long)gg.color.cursor); - if (!chairflag || cursortype == grid) - { - if (cursortype != normal && cursy < baseline) - { - switch (cursortype) - { + strcpy(savefunc, gg.genfunc); + strcpy(gg.genfunc, act); + calltoolkind(k, act_genkind); + strcpy(gg.genfunc, savefunc); +} - case grid: - choose_log_cursor(0); - if (chairflag) { - m_drawline(cursx1 - 3L, cursy1 - 5L, cursx1 + 3L, cursy1 + 5L); - m_drawline(cursx1 - 3L, cursy1 + 5L, cursx1 + 3L, cursy1 - 5L); - } - cx0 = (cursx + gg.xoff) / gg.scale * gg.scale - gg.xoff; - cy0 = (cursy + gg.yoff) / gg.scale * gg.scale - gg.yoff; - m_drawline(0L, (long)cy0, (long)across, (long)cy0); - m_drawline((long)cx0, 0L, (long)cx0, baseline - 1L); - break; - case delete__: - choose_log_cursor(2); - break; +static void send_gengate(log_grec *g, char *act) +{ + char savefunc[17]; - case copy_: - choose_log_cursor(1); - break; + strcpy(savefunc, gg.genfunc); + strcpy(gg.genfunc, act); + calltoolgate(g, act_gengate); + strcpy(gg.genfunc, savefunc); +} - case boxcursor: - choose_log_cursor(4); - break; - case paste: - choose_log_cursor(0); - cx0 = (cursx + gg.xoff + 2) / gg.scale; - cy0 = (cursy + gg.yoff + 2) / gg.scale; - m_saveclip(); - m_clip(0L, 0L, (long)across, baseline - 1L); - gg.cx_min = cx0; - gg.cx_max = cx0 + copybuf.dxcopy; - gg.cy_min = cy0; - gg.cy_max = cy0 + copybuf.dycopy; - rect(gg.cx_min, gg.cy_min, gg.cx_max, gg.cy_max); - m_unclip(); - break; +static void send_all(char *act) +{ + log_tool *tp; + char savefunc[17]; - default: - break; - } - } - else - { - if (rabbits && !avoidrabbits && cursy < baseline) - { - choose_log_cursor(0); - if (cursx < 45) - m_bunny(0L, cursy - 17L); - else - m_bunny(cursx - 45L, cursy - 17L); - } - else if (gg.probemode) - { - choose_log_cursor(3); - } - else - { - choose_log_cursor(0); - } - } - } - if (chairflag) + strcpy(savefunc, gg.genfunc); + tp = gg.toolbase; + while (tp != NULL) { - if (rbandflag) - { - choose_log_cursor(0); - if (vlsi) - m_color((long)gg.color.wire[curwcolor - log_wcol_normal]); - else - m_color((long)gg.color.xwire); - m_drawline((long)cursx1, (long)cursy1, (long)cursx2, (long)cursy2); - } - else + if (tp->ready && tp->simulator) { - choose_log_cursor(0); + strcpy(gg.genfunc, act); + calltool(tp, act_general); } + tp = tp->next; } - oldcursortype = cursortype; - m_colormode(curcm); - - /*and (cursy < baseline)*/ + strcpy(gg.genfunc, savefunc); } -/*================= HIDECURSOR =================*/ -/*= =*/ -/*= Used to remove cursor from screen while =*/ -/*= drawing graphics. =*/ -/*= =*/ -/*================================================*/ - -static void hidecursor() +static void send_allnodes(char *act) { - if (cursorflag) - xorcursor(); + log_tool *tp; + char savefunc[17]; + + strcpy(savefunc, gg.genfunc); + tp = gg.toolbase; + while (tp != NULL) + { + if (tp->ready && tp->simulator) + { + strcpy(gg.genfunc, act); + gg.actnode = NULL; + calltool(tp, act_gennode); + } + tp = tp->next; + } + strcpy(gg.genfunc, savefunc); } -static void hidecursor_hook() +static void send_allkinds(char *act) { - if (!cursorhide) - hidecursor(); - cursorhide = true; + log_tool *tp; + char savefunc[17]; + + strcpy(savefunc, gg.genfunc); + tp = gg.toolbase; + while (tp != NULL) + { + if (tp->ready && tp->simulator) + { + strcpy(gg.genfunc, act); + gg.actkind = NULL; + calltool(tp, act_genkind); + } + tp = tp->next; + } + strcpy(gg.genfunc, savefunc); } -static void unhidecursor_hook() +static void send_allgates(char *act) { - if (cursorhide) - hidecursor(); - cursorhide = false; + log_tool *tp; + char savefunc[17]; + + strcpy(savefunc, gg.genfunc); + tp = gg.toolbase; + while (tp != NULL) + { + if (tp->ready && tp->simulator) + { + strcpy(gg.genfunc, act); + gg.actgate = NULL; + calltool(tp, act_gengate); + } + tp = tp->next; + } + strcpy(gg.genfunc, savefunc); } -static void hidecursorrect_hook(long x1, long y1, long x2, long y2) +static long glowcol(log_nrec *n, long def) { - if (!cursorhide && x1 <= gg.cx_max && x2 >= gg.cx_min && y1 <= gg.cy_max && - y2 >= gg.cy_min) - hidecursor_hook(); + gg.actx = def; + calltoolnode(n, act_glowcol); + return (gg.actx); } -/*================ DRAWCURSOR ==================*/ -/*= =*/ -/*= Position the cursor to a particular point =*/ -/*= (screen coordinates). =*/ -/*= =*/ -/*================================================*/ - -static void drawcursor(short x, short y) +static void resetmessages() { - if (x != cursx || y != cursy || !cursorflag || cursortype != oldcursortype) - { - if (cursorflag && !cursorhide) - xorcursor(); - cursx = x; - cursy = y; - cursx1 = chairx; - cursy1 = chairy; - cursx2 = x; - cursy2 = y; - chairflag = chairflag2; - if (chairflag) - { - chairflag = true; - fixxy(&cursx2, &cursy2); - rbandflag = (abs(cursx1 - cursx2) + abs(cursy1 - cursy2) >= gg.scale && - hvline(cursx1, cursy1, &cursx2, &cursy2)); - } - xorcursor(); - } - else + short opos; + + opos = messagepos; + messagepos = topmessagepos; + messageright = 0; + if (messagepos != opos) { - if (!cursorflag && !cursorhide) - xorcursor(); + calltools(act_clearmsg); + stamp(&gg.msgstamp); } - cursorflag = true; - cursorhide = false; } -/*================= REMCURSOR ==================*/ + +/*==================== PEN =====================*/ +/*= =*/ +/*= Find the position of the pen. Returns: =*/ +/*= D, D0 if the pen is/was down; =*/ +/*= N, N0 if the pen is/was near; =*/ +/*= DN, UP if the pen is pressed/released; =*/ +/*= NR if pen remains near; =*/ +/*= OFFSCREEN if pen is off the screen edge; =*/ +/*= PX, PY, PX0, PY0 = new/old position; =*/ +/*= FX, FY = position in grid coordinates; =*/ +/*= MENUBOX = menu box number (0-15); =*/ /*= =*/ -/*= Take the cursor off the screen. =*/ +/*= Also draws the cursor, runs logic probe, =*/ +/*= and handles Rabbit mode. =*/ /*= =*/ /*================================================*/ -static void remcursor() +static void show_events() { - prevcursorflag = cursorflag; - if (cursorflag) - xorcursor(); - cursorflag = false; - cursorhide = false; + /*zEMBED + char buf[30]; + extern int m_events_received; + static int old_events, old_serial, old_time; + int serial, time = timers_sysclock() / 200; + sprintf(buf, "%d", m_events_received); + m_color(log_red); + if (m_events_received > old_events) + drawstr2(5, 20, buf); + old_events = m_events_received; + sprintf(buf, "%d", serial = XNextRequest(m_display)); + if (serial > old_serial && time != old_time) + drawstr2(5, 29, buf), + old_serial = serial + 2, + old_time = time; + */ } -/*================ RESTORECURSOR ===============*/ +/*================== POLLKBD2 ==================*/ /*= =*/ -/*= Restore the cursor to its previous on/off =*/ -/*= status. =*/ +/*= Return TRUE if a key has been pressed =*/ +/*= (via keyboard or menu boxes). =*/ /*= =*/ /*================================================*/ -static void restorecursor() +static int pollkbd2() { - if (prevcursorflag != cursorflag) - xorcursor(); - cursorflag = prevcursorflag; + return (nk_keybufsize() != 0 || pushedbackkey != '\0'); } -/*================== SETMODE ===================*/ -/*= =*/ -/*= Draw a word in the "mode" location of =*/ -/*= the menu area. =*/ -/*= =*/ -/*================================================*/ - -static void refreditmode (); - -static void log_setmode(const char *s) +static void pen() { - time_t h; - char *cp; - remcursor(); - clipoff(); - m_color((long)gg.color.backgr); - if (gg.showpage > 0) - drawstr2(across + menux3, line2, modename); - refreditmode(); /*may have been trashed by previous mode name*/ - if (*s != '\0') - { - strcpy(modename, s); - modeflag = true; - m_color((long)gg.color.selword); - } - else - { - if (gg.probekind != NULL) - { - strcpy(modename, gg.probekind->name); - m_color((long)gg.color.selword); - } - else - { - time(&h); - cp = ctime(&h); - sprintf(modename, "%.5s", cp + 11); - modetime = timers_sysclock() / 6000; - if (!strcmp(modename, "00:00")) - strcpy(modename, "__@/ "); - m_color((long)gg.color.menuword); - } - modeflag = false; - modeprobekind = gg.probekind; - } - if (gg.showpage > 0) - drawstr2(across + menux3, line2, modename); -} +#define ALERTNESS 2 /* Time to get bored (in cs) */ +#define DOZETIME 5 /* Time to sleep after nodding off */ + long x, y; + short i, rx, ry, cred; + /* static int pollkbd2(void); */ + static int oldx, oldy; + static long awake; + long now; + char rval, gval, bval; -static void dounits(char *s, double *r) -{ - char ch; - if (*s == '\0') - return; - ch = s[0]; - if (ch >= 'a') - ch -= 32; - if (ch == 'F') + /* the following section improves idling behavior */ + /* contributed by Nick Bailey (een6njb@sun.leeds.ac.uk) */ + + /* Keep on your toes if s/he's still twitching about! */ + now = timers_sysclock(); + if (gg.t.x!=oldx || gg.t.y!=oldy || pollkbd2() || gg.busyflag) { - *r *= 1e-15; - return; + awake = now; + oldx = gg.t.x; oldy = gg.t.y; } - if (ch == 'P') - { - *r *= 1e-12; - return; - } - if (ch == 'N') - { - *r *= 1e-9; - return; - } - if (ch == 'U') - { - *r *= 1e-6; - return; - } - if (ch == 'K') - { - *r *= 1e3; - return; - } - if (ch == 'G') - { - *r *= 1e9; - return; - } - if (ch == 'T') - { - *r *= 1e12; - return; - } - if (ch != 'M') - return; - if (strlen(s) >= 3 && (s[1] == 'E' || s[1] == 'e') && - (s[2] == 'G' || s[2] == 'g')) - *r *= 1e6; - else - *r *= 1e-3; -} - - -static void readreal(char *s_, double *r) -{ - char s[256]; - long i; - char *STR1; - char STR2[256]; - - strcpy(s, s_); - if (!(*s != '\0' && - (s[0] == '.' || s[0] == '+' || s[0] == '-' || isdigit(s[0])))) - return; - *r = strtod(s, &STR1); - i = STR1 - s + 1; - strcpy_overlap(s, s + i - 1); - strcpy(STR2, strltrim(s)); - strcpy(s, STR2); - dounits(s, r); -} - - -static void strwordx(char *buf, char *wrd) -{ - short i; - char STR1[256]; - char STR2[256]; - - strcpy(STR1, strltrim(strrtrim(strcpy(STR2, buf)))); - strcpy(buf, STR1); - if (*buf != '"') - { - strword(buf, wrd); - return; - } - i = strposc(buf, '"', 2L); - if (i == 0) - i = strlen(buf) + 1; - strpart(wrd, buf, 2, i - 1); - strcpy_overlap(buf, buf + i); -} - - -static void getword(char *buf, char *wrd) -{ - char STR1[256]; - char STR2[256]; - - strcpy(STR1, strltrim(strrtrim(strcpy(STR2, buf)))); - strcpy(buf, STR1); - if (*buf == '"') - strwordx(buf, wrd); - else - { - strwordx(buf, wrd); - strupper(wrd, wrd); - } -} - - -static long getint(char *s, long def) -{ - char w[10]; - long i, j, sign; - int valid; - long FORLIM; - - getword(s, w); - if (*w == '-') - { - strcpy_overlap(w, w + 1); - sign = -1; - } - else - { - sign = 1; - } - j = 0; - valid = true; - FORLIM = strlen(w); - for (i = 0; i < FORLIM; i++) - { - if (w[i] < '0' || w[i] > '9') - valid = false; - else - j = j * 10 + w[i] - 48; - } - - if (*w != '\0' && valid) - return (j * sign); - else - return def; -} - - -static void pgetint(char *buf, long *i, long def) -{ - *i = getint(buf, def); -} - + /* Be friendly when not running something important */ + if (now-awake > (unsigned long)ALERTNESS) + microsleep((unsigned long)10000*DOZETIME); -static double getreal(char *s, double def) -{ - char w[81]; - double r; + /* end of idling-improvement section */ - getword(s, w); - r = def; - TRY(try1); - readreal(w, &r); - RECOVER(try1); + TRY(try3); + gg.t0 = gg.t; + m_readpen(&gg.t); + show_events(); + gg.stillnear = (gg.stillnear && gg.t.near_); + gg.incircuit = (gg.t.y < baseline && gg.showpage > 0); + RECOVER(try3); if (P_escapecode == -20) _Escape(P_escapecode); - r = def; - ENDTRY(try1); - return r; -} - -static void pgetreal(char *buf, double *r, double def) -{ - *r = getreal(buf, def); -} - - -static void getbool(char *buf, int *b) -{ - char w[17]; - - getword(buf, w); - if (!strcmp(w, "ON") || !strcmp(w, "YES") || !strcmp(w, "Y") || - !strcmp(w, "RABBITS")) - { /*avoid*/ - *b = true; - return; - } - if (!strcmp(w, "OFF") || !strcmp(w, "NO") || !strcmp(w, "N")) + printf("Graphics tablet error\n"); + m_init_pen(tabletaddr); + m_alpha_on(); + ENDTRY(try3); + if (snapflag && gg.incircuit) { - *b = false; - return; + gg.t.x = (gg.t.x + gg.hscale + gg.xoff) / gg.scale * gg.scale - gg.xoff; + gg.t.y = (gg.t.y + gg.hscale + gg.yoff) / gg.scale * gg.scale - gg.yoff; } - - if (!strcmp(w, "?")) - tempverbose = true; - else if (*w == '\0') - *b = !*b; -} - - -/*================= SORTSHINTS =================*/ -/*= =*/ -/*= Put two shortint variables into increasing =*/ -/*= numerical order. =*/ -/*= =*/ -/*================================================*/ - -static void sortshints(short *x, short *y) -{ - short temp; - - if (*x <= *y) - return; - temp = *x; - *x = *y; - *y = temp; -} - - -/*================ INSIDEGATE ==================*/ -/*= =*/ -/*= Check if inside a gate's "yellow box." =*/ -/*= =*/ -/*================================================*/ - -/* new version by Tim Edwards, Dec 1996 */ - -static int insidegate(log_grec *g, short x, short y) -{ - short xx1, xx2, yy1, yy2, z; - short loc_x1, loc_x2; - log_krec *WITH; - x = (x - g->x) * log_scale0; - y = (y - g->y) * log_scale0; - WITH = g->kind; - loc_x1 = WITH->x1; - loc_x2 = WITH->x2; + if (gg.t.x < 0) + gg.t.x = 0; + else if (gg.t.x > across) + gg.t.x = across; - /* Modify x1 position for length of text on TO/FROM-type gates */ + if (gg.t.y < 0) + gg.t.y = 0; + else if (gg.t.y > down) + gg.t.y = down; - if (WITH->flag.U3.named && g->sig > 0) + if (gg.t.near_ && !gg.t.depressed) { - char STR1[256]; - short xwid = m_strwidth(NULL, strrtrim(strcpy(STR1, - gg.signaltab[g->sig - 1].name))) - NAMEGAP; - - if (WITH->flag.U3.nright) - { - if (xwid > loc_x2) loc_x2 = xwid; - } - else + rx = gg.t.x * 5 / across; + ry = gg.t.y * 5 / down; + if (rx != rablist[rabstate].x || ry != rablist[rabstate].y) { - if (-xwid < loc_x1) loc_x1 = -xwid; - } - } - - if (g->rot == 0) - { - return (loc_x1 <= x && x <= loc_x2 && WITH->y1 <= y && y <= WITH->y2); - } - else - { - z = g->rot; - xx1 = loc_x1 * log_rotxx[z] + WITH->y1 * log_rotyx[z]; - xx2 = loc_x2 * log_rotxx[z] + WITH->y2 * log_rotyx[z]; - sortshints(&xx1, &xx2); - yy1 = loc_x1 * log_rotxy[z] + WITH->y1 * log_rotyy[z]; - yy2 = loc_x2 * log_rotxy[z] + WITH->y2 * log_rotyy[z]; - sortshints(&yy1, &yy2); - return (xx1 <= x && x <= xx2 && yy1 <= y && y <= yy2); - } -} - - -/*================= TESTPROBE ==================*/ -/*= =*/ -/*= Find which wire, pin, or gate the Probe =*/ -/*= is touching and set PROBENODE or =*/ -/*= PROBEGATE to its address. =*/ -/*= =*/ -/*================================================*/ - -static void unprobe() -{ - gg.probenode = NULL; - gg.probegate = NULL; - gg.probepin = 0; - gg.probesimtype = NULL; - gg.probekind = NULL; - gg.probehwire = NULL; - gg.probevwire = NULL; - probeflag = false; -} - - -static log_krec *peninkind(short xx, short yy) -{ - log_krec *Result; - short i; - - Result = NULL; - if (!(P_ibetween((long)kindgroupleft, (long)xx, kindgroupright - 1L) && - P_ibetween((long)baseline, (long)yy, (long)down))) - return Result; - i = kindgroup[(xx - kindgroupleft) / kindgroupspacing]; - if (i > 0) - return (kind[(i & (log_kindoffset - 1)) - 1]); - return Result; -} - - -static void testprobe(short xx, short yy) -{ - log_grec *g; - log_krec *k; - short i, x, y; - log_hwrec *hw; - log_vwrec *vw; - short FORLIM; - - x = (xx + gg.hscale + gg.xoff) / gg.scale; - y = (yy + gg.hscale + gg.yoff) / gg.scale; - unprobe(); - if (gg.showpage > 0 && !gg.invisible && !gg.showconflicts) - { - if (gg.incircuit) - { - g = gg.gbase[gg.curpage - 1]; - while (g != NULL && gg.probegate == NULL) - { - k = g->kind; - if (g->x >= x - k->bbmax && g->x <= x + k->bbmax && - g->y >= y - k->bbmax && g->y <= y + k->bbmax) - { - if (insidegate(g, x, y)) - { - gg.probegate = g; - } - else if (g->kind->simtype->simtype >= 8) - { - FORLIM = g->kind->numpins; - for (i = 1; i <= FORLIM; i++) { - if (x == g->pinpos[i - 1].x && y == g->pinpos[i - 1].y) - { - gg.probegate = g; - gg.probenode = g->pin[i - 1]; - gg.probepin = i; - } - } - } - } - g = g->next; - } - hw = gg.hwbase[gg.curpage - 1]; - while (hw != NULL && gg.probenode == NULL) - { - if (hw->x1 <= x && x <= hw->x2 && hw->y == y) - { - gg.probehwire = hw; - gg.probenode = hw->node; - } - hw = hw->next; - } - vw = gg.vwbase[gg.curpage - 1]; - while (vw != NULL && gg.probenode == NULL) - { - if (vw->y1 <= y && y <= vw->y2 && vw->x == x) - { - gg.probevwire = vw; - gg.probenode = vw->node; - } - vw = vw->next; - } - } - else - { - gg.probekind = peninkind(xx, yy); - } - } - if (gg.probegate != NULL) - gg.probekind = gg.probegate->kind; - if (gg.probenode != NULL) - gg.probesimtype = gg.probenode->simtype; - else if (gg.probekind != NULL) - gg.probesimtype = gg.probekind->simtype; -} - - -static void checkprobe(short xx, short yy) -{ - short x, y; - - x = (xx + gg.hscale + gg.xoff) / gg.scale; - y = (yy + gg.hscale + gg.yoff) / gg.scale; - if (gg.probegate != NULL && - (gg.probegate->x < x - gg.probekind->bbmax || - gg.probegate->x > x + gg.probekind->bbmax || - gg.probegate->y < y - gg.probekind->bbmax || - gg.probegate->y > y + gg.probekind->bbmax)) - { - unprobe(); - return; - } - - if (gg.probekind != NULL && gg.probegate == NULL && - peninkind(xx, yy) != gg.probekind) - { - unprobe(); - return; - } - - if (gg.probehwire != NULL && - (gg.probehwire->x1 > x || x > gg.probehwire->x2 || - gg.probehwire->y != y)) - unprobe(); - else if (gg.probevwire != NULL && - (gg.probevwire->y1 > y || y > gg.probevwire->y2 || - gg.probevwire->x != x)) - unprobe(); -} - - - -/** - * @param lbl: list of character to parse - * @param numattrs: number of found attributs - * @param attr: vector containing parsed attributs - */ -static void parselabel(na_strlist_t **lbl, short *numattrs, log_kattrrec **attr) -{ - short j, j1, j2, j3, yy, maxx; - na_strlist_t *l1, *l2, *l3, *attrnames; - char buf[256]; - int haveprec; - log_kattrrec *WITH; - char STR1[256]; - char STR2[256]; - short FORLIM; - - j = 1; - *numattrs = 0; - attrnames = NULL; - l1 = *lbl; - // boucle qui compte le nombre d'attribut - while (l1 != NULL) { - j = strposc(l1->s, ':', 1L); - if (j != 0 && j != strpos2(l1->s, "::", 1)) - (*numattrs)++; - - l1->value = (na_long)strlen(l1->s); - l1 = l1->next; - } - *attr = (log_kattrrec *)Malloc(*numattrs * kattrrecsize); - maxx = 0; - l1 = *lbl; - j = 1; - yy = 0; - // On parcours de nouveau la liste de string - while (l1 != NULL) - { - j1 = strposc(l1->s, ':', 1L); - // Si c'est bien un attribut - if (j1 != 0 && j1 != strpos2(l1->s, "::", 1)) - { - WITH = &(*attr)[j - 1]; - WITH->vr = 0; - WITH->vra = 0; - strcpy(STR1, strltrim(l1->s)); - strcpy(l1->s, STR1); // TODO optimiser - // elimine les [ ] si autour de l'attribut - while (l1->s[0] == '[') - { - j2 = strposc(l1->s, ']', 1L); - if (j2 < 3) - continue; - l2 = strlist_append(&attrnames, strpart(STR1, l1->s, 2, j2 - 1)); - l2->value = (na_long)((long)j); - strcpy_overlap(l1->s, l1->s + j2); - strcpy(STR1, strltrim(l1->s)); - strcpy(l1->s, STR1); // TODO optimiser - } - j2 = strposc(l1->s, ';', 1L); - if (j2 != 0 && j2 < j1) - { - sprintf(buf, "%.*s", j2 - 1, l1->s); - strrtrim(buf); - j3 = 1; - // Recherche si l'attribut à déjà été défini - while (j3 < j && WITH->vra == 0) - { - if ((*attr)[j3 - 1].dtype == 'V') - { - l2 = (*attr)[j3 - 1].UU.U86.v; - while (l2 != NULL && strcicmp(l2->s, buf) != 0) - l2 = l2->next; - - if (l2 != NULL) { - WITH->vr = (long)l2->value; - WITH->vra = j3; - } - } - j3++; - } - strcpy_overlap(l1->s, l1->s + j2); - } - if (l1->s[0] == ' ') - { - strcpy(STR1, strltrim(l1->s)); - strcpy(l1->s, STR1); // TODO optimiser - } - WITH->prec = 0; - haveprec = false; - while (isdigit(l1->s[0])) - { - WITH->prec = WITH->prec * 10 + l1->s[0] - 48; - haveprec = true; - strcpy_overlap(l1->s, l1->s + 1); - } - if (l1->s[0] == ' ') - { - strcpy(STR1, strltrim(l1->s)); - strcpy(l1->s, STR1); - } - WITH->opt = false; + i = abs(rablist[rabstate].next) - 1; do { - WITH->dtype = toupper(l1->s[0]); - if (l1->s[0] != ':') - { - do - { - strcpy_overlap(l1->s, l1->s + 1); - } - while (l1->s[0] == ' '); - } - if (WITH->dtype == 'O') - WITH->opt = true; - - } - while (WITH->dtype == 'O'); - - if (WITH->dtype == 'F' || WITH->dtype == 'U' || WITH->dtype == 'R') - { - *WITH->UU.U82.u = '\0'; - if (WITH->dtype == 'F' || WITH->dtype == 'U') - { - while (l1->s[0] != ',' && l1->s[0] != ':') - { - if (l1->s[0] != ' ' && strlen(WITH->UU.U82.u) < 3) - sprintf(WITH->UU.U82.u + strlen(WITH->UU.U82.u), "%c", l1->s[0]); - - strcpy_overlap(l1->s, l1->s + 1); - } - if (l1->s[0] == ',') - strcpy_overlap(l1->s, l1->s + 1); - - strcpy(STR1, strltrim(l1->s)); - strcpy(l1->s, STR1); - } - *buf = '\0'; - while (l1->s[0] != ':') - { - sprintf(buf + strlen(buf), "%c", l1->s[0]); - strcpy_overlap(l1->s, l1->s + 1); - } - WITH->UU.U82.r = 0.0; - WITH->blnk = true; - if (*buf != '\0') - { - readreal(buf, &WITH->UU.U82.r); - WITH->blnk = false; - } - if (!haveprec) - WITH->prec = 0; - - } - else if (WITH->dtype == 'I') - { - WITH->UU.U73.i1 = 0; - WITH->blnk = true; - while (isdigit(l1->s[0])) - { - WITH->UU.U73.i1 = WITH->UU.U73.i1 * 10 + l1->s[0] - 48; - strcpy_overlap(l1->s, l1->s + 1); - WITH->blnk = false; - } - if (!haveprec) - WITH->prec = 1; - - } - else if (WITH->dtype == 'H') - { - WITH->UU.U73.i1 = 0; - j1 = 0; - WITH->blnk = true; - while ((l1->s[0] >= 'a' && l1->s[0] <= 'f') || - (l1->s[0] >= 'A' && l1->s[0] <= 'F') || isdigit(l1->s[0])) - { - WITH->UU.U73.i1 = WITH->UU.U73.i1 * 10 + l1->s[0] - 48; - if (l1->s[0] >= 'A') - WITH->UU.U73.i1 -= 7; - - if (l1->s[0] >= 'a') - WITH->UU.U73.i1 -= 32; - - strcpy_overlap(l1->s, l1->s + 1); - j1++; - WITH->blnk = false; - } - if (!haveprec) - { - if (j1 != 0) - WITH->prec = j1; - else - WITH->prec = 1; - } - } - else if (WITH->dtype == 'C') - { - j1 = strposc(l1->s, ':', 1L); - sprintf(buf, "%.*s", j1 - 1, l1->s); - strrtrim(buf); - strcpy_overlap(l1->s, l1->s + j1 - 1); - if (!haveprec) - WITH->prec = 255; - - if (strlen(buf) > WITH->prec) - buf[WITH->prec] = '\0'; - - WITH->UU.c = (char *)Malloc(WITH->prec + 1L); - strcpy(WITH->UU.c, buf); - WITH->blnk = (*buf == '\0'); - } - else if (WITH->dtype == 'A') - { - j1 = strposc(l1->s, ':', 1L); - sprintf(buf, "%.*s", j1 - 1, l1->s); - strrtrim(buf); - strcpy_overlap(l1->s, l1->s + j1 - 1); - WITH->prec = 255; - WITH->UU.sp = strdup(buf); - WITH->blnk = (*buf == '\0'); - } - else if (WITH->dtype == 'B') - { - WITH->blnk = false; - if (l1->s[0] == 'y' || l1->s[0] == 'Y' || l1->s[0] == 't' || l1->s[0] == 'T') - WITH->UU.b = true; - else if (l1->s[0] == 'n' || l1->s[0] == 'N' || l1->s[0] == 'f' || l1->s[0] == 'F') - WITH->UU.b = false; - else - WITH->blnk = true; - - if (l1->s[0] == 'x' || l1->s[0] == 'X' || l1->s[0] == 'f' || - l1->s[0] == 'F' || l1->s[0] == 't' || l1->s[0] == 'T') - WITH->prec = 2; - else - WITH->prec = 1; - } - else if (WITH->dtype == 'V') + i++; + } while ((rablist[i].x != rx || rablist[i].y != ry) && + rablist[i].next < 0); + if (rablist[i].x == rx && rablist[i].y == ry) { - strlist_init(&l2); - WITH->UU.U86.nv = 0; - do + if (i == rablistsize) { - *buf = '\0'; - while (l1->s[0] != ',' && l1->s[0] != ':') + remcursor(); + rabbits = !rabbits; + if (rabbits && !gg.quiet) { - sprintf(buf + strlen(buf), "%c", l1->s[0]); - strcpy_overlap(l1->s, l1->s + 1); + i = 1; + x = timers_sysclock(); + do + { + y = discomadness[i - 1].time; + BEEPER(discomadness[i - 1].note, (int)y); + do + { + } while (timers_sysclock() <= x + y); + /* nothing */ + i++; + x = timers_sysclock(); + } while (y != 0); } - if (l1->s[0] == ',') - strcpy_overlap(l1->s, l1->s + 1); - - l3= strlist_append(&l2,strcpy(STR1, strltrim(strrtrim(strcpy(STR2, buf))))); - l3->value = (na_long)((long)WITH->UU.U86.nv); - WITH->UU.U86.nv++; - strcpy(STR1, strltrim(l1->s)); - strcpy(l1->s, STR1); - } - while (l1->s[0] != ':'); - WITH->UU.U86.v = l2; - WITH->blnk = false; - if (haveprec) - WITH->UU.U86.dv = WITH->prec; - else - WITH->UU.U86.dv = 0; - - WITH->prec = 1; - } - else - { - WITH->dtype = 'R'; - WITH->UU.U82.r = 0.0; - WITH->blnk = true; - if (!haveprec) - WITH->prec = 0; - } - if (WITH->blnk) - WITH->opt = true; - - j1 = strposc(l1->s, ':', 1L); - strcpy_overlap(l1->s, l1->s + j1); - j++; - WITH->y = yy; - if (strlen(l1->s) > maxx) - maxx = strlen(l1->s); - - } - j1 = 1; - while (j1 < strlen(l1->s)) - { - if (l1->s[j1 - 1] == ':' && l1->s[j1] == ':') - strcpy_overlap(l1->s + j1 - 1, l1->s + j1); - j1++; - } - yy++; - l1 = l1->next; - } - if (attrnames != NULL) { - l1 = strlist_insert(lbl, ""); - l1->kind = '\001'; - l1->value = (void *)attrnames; - } - FORLIM = *numattrs; - for (j = 0; j < FORLIM; j++) - (*attr)[j].x = maxx + 1; -} - - -static void stamp(long *i) -{ - gg.curstamp++; - *i = gg.curstamp; -} - - -static void newtool(log_tool **t, char *name) -{ - log_tool *t2; - - *t = (log_tool *)Malloc(sizeof(log_tool)); - strcpy((*t)->name, name); - (*t)->ready = false; - (*t)->simulator = false; - (*t)->keep = false; - (*t)->nostatus = false; - (*t)->fname = NULL; - (*t)->comment = (char *)Malloc(256); - *(*t)->comment = '\0'; - (*t)->info = (na_long)0; - (*t)->nlbl = NULL; - (*t)->hlbl = NULL; - (*t)->shortname = (char *)Malloc(33); - strcpy((*t)->shortname, name); - stamp(&(*t)->netstamp); - (*t)->deltatime = 0.0; - t2 = gg.toolbase; - while (t2 != NULL && t2->next != NULL) - t2 = t2->next; - if (t2 == NULL) - gg.toolbase = *t; - else - t2->next = *t; - (*t)->next = NULL; -} - - -static log_tool *findtool(char *name_) -{ - log_tool *Result; - char name[17]; - log_tool *lp; - char savefunc[17]; - char saveargs[256]; - char suffix[51]; - void (*proc) (log_action_t *act); - int ready; - cnfrec *cnfp; - - strcpy(name, name_); - strcpy(savefunc, gg.func); - strcpy(saveargs, gg.funcarg); - lp = gg.toolbase; - while (lp != NULL && strcmp(lp->name, name)) - lp = lp->next; - if (lp == NULL) - newtool(&lp, name); - if (!lp->ready) - { - sprintf(suffix, "LOG_%s_PROC", name); - ready = newci_findprocedure2(suffix, (void(**) ())(&proc)); - if (gg.traceflag) - fprintf(tracefile, "Findtool to load: %s - %s.\n", suffix, lp->fname); - - if (!ready && lp->fname != NULL) - { - TRY(try2); - newci_fixfname(lp->fname, "code", ""); - if (gg.traceflag) - fprintf(tracefile, "Findtool, loading %s\n", lp->fname); - newci_loadprogram(lp->fname); - RECOVER(try2); - if (P_escapecode == -20) - _Escape(P_escapecode); - ENDTRY(try2); - ready = newci_findprocedure2(suffix, (void(**) ())(&proc)); - if (gg.traceflag) - fprintf(tracefile, "Findtool, ready=%s\n", ready ? " TRUE" : "FALSE"); - } - - if (ready) - { - lp->proc = proc; - gg.action = act_init; - gg.acttool = lp; - (*proc)(&gg); - if (lp->ready) - { - cnfp = cnfbase; - while (cnfp != NULL) - { - if (!strcmp(cnfp->tool, name)) - { - doingcnffunction = true; - gg.action = act_cnf; - strcpy(gg.funcarg, cnfp->s); - getword(gg.funcarg, gg.func); - (*proc)(&gg); - doingcnffunction = false; - } - cnfp = cnfp->next; - } - gg.action = act_color; - (*proc)(&gg); - gg.action = act_endinit; - (*proc)(&gg); - lp->nexttstep = 0.0; - lp->nnumattrs = 0; - lp->nattr = NULL; - if (lp->nlbl != NULL) - parselabel(&lp->nlbl, &lp->nnumattrs, &lp->nattr); - lp->hnumattrs = 0; - lp->hattr = NULL; - if (lp->hlbl != NULL) - parselabel(&lp->hlbl, &lp->hnumattrs, &lp->hattr); - } - } - } - Result = lp; - strcpy(gg.func, savefunc); - strcpy(gg.funcarg, saveargs); - return Result; -} - - -static void calltool(log_tool *t, log_actionkinds act) -{ - log_tool *savetool; - - savetool = gg.acttool; - gg.action = act; - gg.acttool = t; - (*t->proc)(&gg); - gg.acttool = savetool; -} - - -static void calltoolgate(log_grec *g, log_actionkinds act) -{ - gg.actgate = g; - calltool(g->kind->simtype, act); -} - - -static void calltoolnode(log_nrec *n, log_actionkinds act) -{ - gg.actnode = n; - calltool(n->simtype, act); -} - -static void calltoolkind(log_krec *k, log_actionkinds act) -{ - gg.actkind = k; - calltool(k->simtype, act); -} - -static void calltools(log_actionkinds act) -{ - log_tool *tp; - - tp = gg.toolbase; - while (tp != NULL) - { - if (tp->ready) - calltool(tp, act); - tp = tp->next; - } -} - - -static void callsimtools(log_actionkinds act) -{ - log_tool *tp; - - tp = gg.toolbase; - while (tp != NULL) - { - if (tp->ready && tp->simulator) - calltool(tp, act); - tp = tp->next; - } -} - - -static void send_general(log_tool *sim, char *act) -{ - char savefunc[17]; - - strcpy(savefunc, gg.genfunc); - strcpy(gg.genfunc, act); - calltool(sim, act_general); - strcpy(gg.genfunc, savefunc); -} - - -static void send_gennode(log_nrec *n, char *act) -{ - char savefunc[17]; - - strcpy(savefunc, gg.genfunc); - strcpy(gg.genfunc, act); - calltoolnode(n, act_gennode); - strcpy(gg.genfunc, savefunc); -} - - -static void send_genkind(log_krec *k, char *act) -{ - char savefunc[17]; - - strcpy(savefunc, gg.genfunc); - strcpy(gg.genfunc, act); - calltoolkind(k, act_genkind); - strcpy(gg.genfunc, savefunc); -} - - -static void send_gengate(log_grec *g, char *act) -{ - char savefunc[17]; - - strcpy(savefunc, gg.genfunc); - strcpy(gg.genfunc, act); - calltoolgate(g, act_gengate); - strcpy(gg.genfunc, savefunc); -} - - -static void send_all(char *act) -{ - log_tool *tp; - char savefunc[17]; - - strcpy(savefunc, gg.genfunc); - tp = gg.toolbase; - while (tp != NULL) - { - if (tp->ready && tp->simulator) - { - strcpy(gg.genfunc, act); - calltool(tp, act_general); - } - tp = tp->next; - } - strcpy(gg.genfunc, savefunc); -} - - -static void send_allnodes(char *act) -{ - log_tool *tp; - char savefunc[17]; - - strcpy(savefunc, gg.genfunc); - tp = gg.toolbase; - while (tp != NULL) - { - if (tp->ready && tp->simulator) - { - strcpy(gg.genfunc, act); - gg.actnode = NULL; - calltool(tp, act_gennode); - } - tp = tp->next; - } - strcpy(gg.genfunc, savefunc); -} - - -static void send_allkinds(char *act) -{ - log_tool *tp; - char savefunc[17]; - - strcpy(savefunc, gg.genfunc); - tp = gg.toolbase; - while (tp != NULL) - { - if (tp->ready && tp->simulator) - { - strcpy(gg.genfunc, act); - gg.actkind = NULL; - calltool(tp, act_genkind); - } - tp = tp->next; - } - strcpy(gg.genfunc, savefunc); -} - - -static void send_allgates(char *act) -{ - log_tool *tp; - char savefunc[17]; - - strcpy(savefunc, gg.genfunc); - tp = gg.toolbase; - while (tp != NULL) - { - if (tp->ready && tp->simulator) - { - strcpy(gg.genfunc, act); - gg.actgate = NULL; - calltool(tp, act_gengate); - } - tp = tp->next; - } - strcpy(gg.genfunc, savefunc); -} - -static void closetool(log_tool *tp) -{ - if (tp->ready) - calltool(tp, act_exit); - tp->ready = false; -} - - -static void closetools() -{ - log_tool *tp; - - tp = gg.toolbase; - while (tp != NULL) - { - closetool(tp); - tp = tp->next; - } -} - - -static long glowcol(log_nrec *n, long def) -{ - gg.actx = def; - calltoolnode(n, act_glowcol); - return (gg.actx); -} - - -static void resetmessages() -{ - short opos; - - opos = messagepos; - messagepos = topmessagepos; - messageright = 0; - if (messagepos != opos) - { - calltools(act_clearmsg); - stamp(&gg.msgstamp); - } -} - - -/*================ CLEARSCREEN =================*/ -/*= =*/ -/*= Clear the screen. =*/ -/*= =*/ -/*================================================*/ - -static void clearscreen() -{ - remcursor(); - m_noclip(); - m_vsetcolors((long)gg.color.backgr, 1L, &rcolormap[gg.color.backgr], - &gcolormap[gg.color.backgr], &bcolormap[gg.color.backgr]); - m_color((long)gg.color.backgr); - m_fillrect(0L, 0L, (long)across, (long)down); - fixcolormap(); - resetmessages(); - bottomcount = 0; - gg.showpage = 0; -} - - -static void clearshowalpha() -{ - if (onescreen) - clearscreen(); - printf("\f"); - nk_gotoxy(0, 0); - noblink(); - showalpha(); -} - - -/*==================== PEN =====================*/ -/*= =*/ -/*= Find the position of the pen. Returns: =*/ -/*= D, D0 if the pen is/was down; =*/ -/*= N, N0 if the pen is/was near; =*/ -/*= DN, UP if the pen is pressed/released; =*/ -/*= NR if pen remains near; =*/ -/*= OFFSCREEN if pen is off the screen edge; =*/ -/*= PX, PY, PX0, PY0 = new/old position; =*/ -/*= FX, FY = position in grid coordinates; =*/ -/*= MENUBOX = menu box number (0-15); =*/ -/*= =*/ -/*= Also draws the cursor, runs logic probe, =*/ -/*= and handles Rabbit mode. =*/ -/*= =*/ -/*================================================*/ - -static void show_events() -{ - /*zEMBED - char buf[30]; - extern int m_events_received; - static int old_events, old_serial, old_time; - int serial, time = timers_sysclock() / 200; - sprintf(buf, "%d", m_events_received); - m_color(log_red); - if (m_events_received > old_events) - drawstr2(5, 20, buf); - old_events = m_events_received; - sprintf(buf, "%d", serial = XNextRequest(m_display)); - if (serial > old_serial && time != old_time) - drawstr2(5, 29, buf), - old_serial = serial + 2, - old_time = time; - */ -} - - -/*================== POLLKBD2 ==================*/ -/*= =*/ -/*= Return TRUE if a key has been pressed =*/ -/*= (via keyboard or menu boxes). =*/ -/*= =*/ -/*================================================*/ - -static int pollkbd2() -{ - return (nk_keybufsize() != 0 || pushedbackkey != '\0'); -} - - -static void pen() -{ - -#define ALERTNESS 2 /* Time to get bored (in cs) */ -#define DOZETIME 5 /* Time to sleep after nodding off */ - - long x, y; - short i, rx, ry, cred; - /* static int pollkbd2(void); */ - static int oldx, oldy; - static long awake; - long now; - char rval, gval, bval; - - - /* the following section improves idling behavior */ - /* contributed by Nick Bailey (een6njb@sun.leeds.ac.uk) */ - - /* Keep on your toes if s/he's still twitching about! */ - now = timers_sysclock(); - if (gg.t.x!=oldx || gg.t.y!=oldy || pollkbd2() || gg.busyflag) - { - awake = now; - oldx = gg.t.x; oldy = gg.t.y; - } - /* Be friendly when not running something important */ - if (now-awake > (unsigned long)ALERTNESS) - microsleep((unsigned long)10000*DOZETIME); - - /* end of idling-improvement section */ - - TRY(try3); - gg.t0 = gg.t; - m_readpen(&gg.t); - show_events(); - gg.stillnear = (gg.stillnear && gg.t.near_); - gg.incircuit = (gg.t.y < baseline && gg.showpage > 0); - RECOVER(try3); - if (P_escapecode == -20) - _Escape(P_escapecode); - printf("Graphics tablet error\n"); - m_init_pen(tabletaddr); - m_alpha_on(); - ENDTRY(try3); - if (snapflag && gg.incircuit) - { - gg.t.x = (gg.t.x + gg.hscale + gg.xoff) / gg.scale * gg.scale - gg.xoff; - gg.t.y = (gg.t.y + gg.hscale + gg.yoff) / gg.scale * gg.scale - gg.yoff; - } - - if (gg.t.x < 0) - gg.t.x = 0; - else if (gg.t.x > across) - gg.t.x = across; - - if (gg.t.y < 0) - gg.t.y = 0; - else if (gg.t.y > down) - gg.t.y = down; - - if (gg.t.near_ && !gg.t.depressed) - { - rx = gg.t.x * 5 / across; - ry = gg.t.y * 5 / down; - if (rx != rablist[rabstate].x || ry != rablist[rabstate].y) - { - i = abs(rablist[rabstate].next) - 1; - do - { - i++; - } while ((rablist[i].x != rx || rablist[i].y != ry) && - rablist[i].next < 0); - if (rablist[i].x == rx && rablist[i].y == ry) - { - if (i == rablistsize) - { - remcursor(); - rabbits = !rabbits; - if (rabbits && !gg.quiet) - { - i = 1; - x = timers_sysclock(); - do - { - y = discomadness[i - 1].time; - BEEPER(discomadness[i - 1].note, (int)y); - do - { - } while (timers_sysclock() <= x + y); - /* nothing */ - i++; - x = timers_sysclock(); - } while (y != 0); - } - rabstate = 0; - } else - rabstate = i; - } else - rabstate = 0; - } - } - else - { - rabstate = 0; - } - - if (gg.probemode) - { - if (cursx != gg.t.x || cursy != gg.t.y) - { - if (gg.probesimtype != NULL) - checkprobe((int)gg.t.x, (int)gg.t.y); - probeflag = false; - drawcursor((int)gg.t.x, (int)gg.t.y); - } - else - { - if (!cursorflag) - drawcursor((int)gg.t.x, (int)gg.t.y); - if (!probeflag) - { - testprobe((int)gg.t.x, (int)gg.t.y); - probeflag = true; - } - } - - if (!gg.t.near_ && briefprobe) - { - remcursor(); - gg.probemode = false; - } - } - else - { - briefprobe = false; - if (gg.probesimtype != NULL) - unprobe(); - if (gg.t.near_) - drawcursor((int)gg.t.x, (int)gg.t.y); - else - remcursor(); - } - cred = gg.color.conflict; - if (anyconflicts && (cred == log_cred || cred == log_cred8) && - (rcolormap[cred] == 255 || gcolormap[cred] == 255 || - bcolormap[cred] == 255)) - { - x = timers_sysclock() * 6 % 137 + 119; - rval = (char)(x * rcolormap[cred] / 255); - gval = (char)(x * gcolormap[cred] / 255); - bval = (char)(x * bcolormap[cred] / 255); - m_vsetcolors((long)cred, 1L, (unsigned char *) &rval, - (unsigned char *) &gval, (unsigned char *) &bval); - } - - if (gg.t.moving) - { - gg.fastspeed = gg.fastmin; - fastsavetime = timers_sysclock(); - } - else if (gg.fastspeed < gg.fastmax && - timers_sysclock() > fastsavetime + gg.fastrate) - { - gg.fastspeed++; - fastsavetime = timers_sysclock(); - } - gg.gridx = (gg.t.x + gg.hscale + gg.xoff) / gg.scale; - gg.gridy = (gg.t.y + gg.hscale + gg.yoff) / gg.scale; -} - - -/*================= JUSTTAP ====================*/ -/*= =*/ -/*= Return TRUE if pen was tapped. Return =*/ -/*= FALSE if pen was held and/or moved. =*/ -/*= =*/ -/*================================================*/ - -static int justtap() -{ - long t0; - short tx, ty; - - t0 = timers_sysclock() + tapdelay; - tx = gg.t.x; - ty = gg.t.y; - do - { - pen(); - } while (gg.t.depressed && labs(gg.t.x - tx) <= taptolerance && - labs(gg.t.y - ty) <= taptolerance && timers_sysclock() <= t0); - return (!gg.t.depressed); -} - - -/*================== TESTKEY2 ==================*/ -/*= =*/ -/*= Return the most recently pressed key. =*/ -/*= =*/ -/*================================================*/ - -static char testkey2() -{ - if (pushedbackkey != '\0') - return pushedbackkey; - else if (pollkbd2()) - return (nk_testkey(0)); - else - return ' '; -} - - -/*================== INKEY2 ====================*/ -/*= =*/ -/*= Return a keystroke. Key is removed from =*/ -/*= the buffer. =*/ -/*= =*/ -/*================================================*/ - -static char inkey2() -{ - char ch; - - do - { - } while (!pollkbd2()); - if (pushedbackkey != '\0') - { - realkey = pushedbackkey; - pushedbackkey = '\0'; - } - else - { - realkey = nk_getkey(); - } - ch = realkey; - if ((ch & 255) >= 168 && (ch & 255) <= 239 && nk_capslock) - { - if ((ch & 255) <= 193) - { - ch += 46; - } else if ((ch & 255) >= 214) - { - ch -= 46; - } - } - gg.fastspeed = gg.fastmin; - return ch; -} - - -static void inkey3(char *ch) -{ - *ch = inkey2(); -} - - -static char inkey4() -{ - /* undo CAPSLOCK key */ - char ch; - - ch = inkey2(); - if (!nk_capslock) - return ch; - if (isupper(ch)) - ch += 32; - else if (islower(ch)) - ch -= 32; - return ch; -} - - -static void ungetkey2(char ch) -{ - pushedbackkey = ch; -} - - -/*=============== WAITFORKEY ===================*/ -/*= =*/ -/*= Wait until a key is pressed (but ignore it) =*/ -/*= =*/ -/*================================================*/ - -static void waitforkey() -{ - char ch; - - while (pollkbd2()) - ch = inkey2(); - do - { - pen(); - } while (!(pollkbd2() || (gg.t.dn && gg.t.off))); - if (pollkbd2()) - ch = inkey2(); -} - - -/*=================== INBOX ====================*/ -/*= =*/ -/*= Return TRUE if cursor is inside a certain =*/ -/*= rectangular area (screen coordinates). =*/ -/*= =*/ -/*================================================*/ - -static int inbox(short x, short y, short x1, short y1) -{ - return (gg.t.x >= x && gg.t.y >= y && gg.t.x <= x + x1 && gg.t.y <= y + y1); -} - - -/*================ UDRAWGATEC ==================*/ -/*= =*/ -/*= Draw a gate of specified color at a =*/ -/*= certain position (screen coordinates). =*/ -/*= =*/ -/*================================================*/ - -static void drawvector2(log_vectorrec *v, long x1, long y1, long x2, long y2) -{ - long diam, savecol, coord; - - switch (v->vkind) - { - - case 'v': - m_drawline(x1, y1, x2, y2); - break; - - case 'C': - diam = P_imax2(labs(x1 - x2), labs(y1 - y2)); - switch (diam) - { - - case 3: - if (x1 == x2) - { - coord = P_imin2(y1, y2); - m_move2(x1, coord); - m_draw(x1 + 2, coord + 1); - m_draw(x1 + 2, coord + 2); - m_draw(x1, coord + 3); - m_draw(x1 - 2, coord + 2); - m_draw(x1 - 2, coord + 1); - m_draw(x1, coord); - } - else if (y1 == y2) - { - coord = P_imin2(x1, x2); - m_move2(coord, y1); - m_draw(coord + 1, y1 + 2); - m_draw(coord + 2, y1 + 2); - m_draw(coord + 3, y1); - m_draw(coord + 2, y1 - 2); - m_draw(coord + 1, y1 - 2); - m_draw(coord, y1); - } - else - { - m_circle((x1 + x2) / 2, (y1 + y2) / 2, 1L); - } - break; - - case 5: - if (x1 == x2) - { - coord = P_imin2(y1, y2); - m_move2(x1, coord); - m_draw(x1 + 3, coord + 1); - m_draw(x1 + 3, coord + 4); - m_draw(x1, coord + 5); - m_draw(x1 - 3, coord + 4); - m_draw(x1 - 3, coord + 1); - m_draw(x1, coord); - } - else if (y1 == y2) - { - coord = P_imin2(x1, x2); - m_move2(coord, y1); - m_draw(coord + 1, y1 + 3); - m_draw(coord + 4, y1 + 3); - m_draw(coord + 5, y1); - m_draw(coord + 4, y1 - 3); - m_draw(coord + 1, y1 - 3); - m_draw(coord, y1); - } - else - { - m_circle((x1 + x2) / 2, (y1 + y2) / 2, 2L); - } - break; - - default: - m_circle((x1 + x2) / 2, (y1 + y2) / 2, diam / 2); - break; - } - break; - - case 'e': - savecol = m_curcolor(); - m_color(m_trans); - m_ellipse((x1 + x2) / 2, (y1 + y2) / 2, (x1 - x2) / 2, (y1 - y2) / 2, - savecol); - m_color(savecol); - break; - - case 'E': - m_ellipse((x1 + x2) / 2, (y1 + y2) / 2, (x1 - x2) / 2, (y1 - y2) / 2, - m_curcolor()); - break; - - case 'r': /*should do a true roundrect*/ - m_drawrect(x1, y1, x2, y2); - break; - } -} - - -static void drawvector4(log_vectorrec *v, long x1, long y1, long x2, long y2, long x3, long y3, long x4, long y4) -{ - long xarr[4], yarr[4]; - - switch (v->vkind) - { - - case 'c': - m_bezier(x1, y1, x2, y2, x3, y3, x4, y4); - break; - - case 'F': - xarr[0] = x1; - yarr[0] = y1; - xarr[1] = x2; - yarr[1] = y2; - xarr[2] = x3; - yarr[2] = y3; - xarr[3] = x4; - yarr[3] = y4; - m_fillpoly(4L, (int *) xarr, (int *) yarr); - break; - } -} - - -#define big1 "0.,+123-456*789/\0()^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " -#define big2 "0.,\000123-456\000789 " - - -static void drawtext(log_vectorrec *v, long scale, long rot, long xx, long yy) -{ - long sc, i, j, tx, ty; - char mode; - char buf[256]; - long FORLIM; - - sc = v->UU.U116.tsize * scale; - if (sc >= log_scale0 * 70) - { - tx = (v->UU.U116.torg % 3 - 1) * log_rotxx[rot] + - (v->UU.U116.torg / 3 - 1) * log_rotyx[rot]; - ty = (v->UU.U116.torg % 3 - 1) * log_rotxy[rot] + - (v->UU.U116.torg / 3 - 1) * log_rotyy[rot]; - i = strposc(v->UU.U116.sp, '$', 1L); - if (i > 0 && i < strlen(v->UU.U116.sp)) - { - strcpy(buf, v->UU.U116.sp); - mode = 'X'; - while (i <= strlen(buf)) { - if (buf[i - 1] == '$' && i < strlen(buf)) - { - switch (toupper(buf[i])) - { - - case '$': - strcpy_overlap(buf + i - 1, buf + i); - i++; - break; - - case 'P': - case 'B': - case 'O': - case 'X': - mode = toupper(buf[i]); /*close enough*/ - strcpy_overlap(buf + i - 1, buf + i + 1); - break; - - default: - i++; - break; - } - continue; - } - switch (mode) - { - - case 'P': - j = strposc("0.,+123-456*789/E()^", buf[i - 1], 1L); - if (j > 0) - buf[i - 1] = (char)(j + 147); - break; - - case 'B': - j = strposc("0.,+123-456*789/\0()^ABCDEFGHIJKLMNOPQRSTUVWXYZ", - toupper(buf[i - 1]), 1L); - if (j > 20) - buf[i - 1] = (char)(j + 147); - else if (j > 0) - buf[i - 1] = (char)(j + 127); - break; - - case 'O': - j = strposc("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", - toupper(buf[i - 1]), 1L); - if (j > 0) - buf[i - 1] = (char)(j + 213); - break; - } - i++; - } - switch (tx) - { - - case -1: - m_drawstr(xx, yy - (ty + 1) * 3, NULL, buf); - break; - - case 0: - m_centerstr(xx, yy - (ty + 1) * 3, NULL, buf); - break; - - case 1: - m_rightstr(xx, yy - (ty + 1) * 3, NULL, buf); - break; - } - return; - } - switch (tx) - { - - case -1: - m_drawstr(xx, yy - (ty + 1) * 3, NULL, v->UU.U116.sp); - break; - - case 0: - m_centerstr(xx, yy - (ty + 1) * 3, NULL, v->UU.U116.sp); - break; - - case 1: - m_rightstr(xx, yy - (ty + 1) * 3, NULL, v->UU.U116.sp); - break; - } - return; - } - if (sc < log_scale0 * 40) - return; - if (sc >= log_scale0 * 50) { - if (!strsubset(v->UU.U116.sp, big1)) - return; - buf[strlen(v->UU.U116.sp)] = '\0'; - FORLIM = strlen(v->UU.U116.sp); - for (i = 0; i < FORLIM; i++) { - j = strposc(big1, v->UU.U116.sp[i], 1L); - if (j <= 20) - buf[i] = (char)(j + 127); - else if (j <= 46) - buf[i] = (char)(j + 147); - else if (j <= 72) - buf[i] = (char)(j + 121); - else - buf[i] = ' '; - } - tx = (v->UU.U116.torg % 3 - 1) * log_rotxx[rot] + - (v->UU.U116.torg / 3 - 1) * log_rotyx[rot]; - ty = (v->UU.U116.torg % 3 - 1) * log_rotxy[rot] + - (v->UU.U116.torg / 3 - 1) * log_rotyy[rot]; - switch (tx) - { - - case -1: - m_drawstr(xx, yy - (ty + 2) * 2, NULL, buf); - break; - - case 0: - m_centerstr(xx, yy - (ty + 2) * 2, NULL, buf); - break; - - case 1: - m_rightstr(xx, yy - (ty + 2) * 2, NULL, buf); - break; - } - return; - } - if (!strsubset(v->UU.U116.sp, big2)) - return; - buf[strlen(v->UU.U116.sp)] = '\0'; - FORLIM = strlen(v->UU.U116.sp); - for (i = 0; i < FORLIM; i++) - { - j = strposc(big2, v->UU.U116.sp[i], 1L); - if (j <= 15) - buf[i] = (char)(j + 193); - else - buf[i] = ' '; - } - tx = (v->UU.U116.torg % 3 - 1) * log_rotxx[rot] + - (v->UU.U116.torg / 3 - 1) * log_rotyx[rot]; - ty = (v->UU.U116.torg % 3 - 1) * log_rotxy[rot] + - (v->UU.U116.torg / 3 - 1) * log_rotyy[rot]; - switch (tx) - { - - case -1: - m_drawstr(xx, yy - (ty + 1) * 2 - 3, NULL, buf); - break; - - case 0: - m_centerstr(xx, yy - (ty + 1) * 2 - 3, NULL, buf); - break; - - case 1: - m_rightstr(xx, yy - (ty + 1) * 2 - 3, NULL, buf); - break; - } -} - -#undef big1 -#undef big2 - - -static void plaindrawgatec(short x, short y, short g, short c) -{ - short i, z, rxx, rxy, ryx, ryy; - log_krec *k; - int hascolor; - short FORLIM; - log_vectorrec *WITH1; - - k = kind[(g & (log_kindoffset - 1)) - 1]; - z = log_scale0 * k->bbmax + 2; - if (x < -z || x > across + z || y < -z || y > down + z) - return; - hidecursor(); - hascolor = (c != gg.color.backgr && c != gg.color.conflict); - m_color((long)c); - if (g < log_kindoffset) - { - FORLIM = k->numvects; - for (i = 0; i < FORLIM; i++) - { - WITH1 = &k->vector[i]; - switch (WITH1->vkind) - { - - case '1': - if (hascolor) - m_color((long)c); - break; - - case '2': - if (hascolor) - m_color((long)gategreen); - break; - - case '3': - if (hascolor) - m_color((long)gateyellow); - break; - - case '4': - if (hascolor) - m_color((long)gatered); - break; - - case '5': - if (hascolor) - m_color((long)gateorange); - break; - - case '6': - if (hascolor) - m_color((long)gateblack); - break; - - case '7': - if (hascolor) - m_color((long)gatewhite); - break; - - case 'v': - case 'C': - case 'e': - case 'E': - case 'r': - drawvector2(&k->vector[i], (long)(x + WITH1->x1), - (long)(y + WITH1->y1), (long)(x + WITH1->UU.U99.x2), - (long)(y + WITH1->UU.U99.y2)); - break; - - case 'c': - case 'F': - drawvector4(&k->vector[i], (long)(x + WITH1->x1), - (long)(y + WITH1->y1), (long)(x + WITH1->UU.U99.x2), - (long)(y + WITH1->UU.U99.y2), (long)(x + WITH1->UU.U99.x3), - (long)(y + WITH1->UU.U99.y3), (long)(x + WITH1->UU.U99.x4), - (long)(y + WITH1->UU.U99.y4)); - break; - - case 't': - drawtext(&k->vector[i], (long)log_scale0, 0L, (long)(x + WITH1->x1), - (long)(y + WITH1->y1)); - break; - } - } - } - else - { - z = g / log_kindoffset; - rxx = log_rotxx[z]; - rxy = log_rotxy[z]; - ryx = log_rotyx[z]; - ryy = log_rotyy[z]; - FORLIM = k->numvects; - for (i = 0; i < FORLIM; i++) - { - WITH1 = &k->vector[i]; - switch (WITH1->vkind) - { - - case '1': - if (hascolor) - m_color((long)c); - break; - - case '2': - if (hascolor) - m_color((long)gategreen); - break; - - case '3': - if (hascolor) - m_color((long)gateyellow); - break; - - case '4': - if (hascolor) - m_color((long)gatered); - break; - - case '5': - if (hascolor) - m_color((long)gateorange); - break; - - case '6': - if (hascolor) - m_color((long)gateblack); - break; - - case '7': - if (hascolor) - m_color((long)gatewhite); - break; - - case 'v': - case 'C': - case 'e': - case 'E': - case 'r': - drawvector2(&k->vector[i], - (long)(x + WITH1->x1 * rxx + WITH1->y1 * ryx), - (long)(y + WITH1->x1 * rxy + WITH1->y1 * ryy), - (long)(x + WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx), - (long)(y + WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy)); - break; - - case 'c': - case 'F': - drawvector4(&k->vector[i], - (long)(x + WITH1->x1 * rxx + WITH1->y1 * ryx), - (long)(y + WITH1->x1 * rxy + WITH1->y1 * ryy), - (long)(x + WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx), - (long)(y + WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy), - (long)(x + WITH1->UU.U99.x3 * rxx + WITH1->UU.U99.y3 * ryx), - (long)(y + WITH1->UU.U99.x3 * rxy + WITH1->UU.U99.y3 * ryy), - (long)(x + WITH1->UU.U99.x4 * rxx + WITH1->UU.U99.y4 * ryx), - (long)(y + WITH1->UU.U99.x4 * rxy + WITH1->UU.U99.y4 * ryy)); - break; - - case 't': - drawtext(&k->vector[i], (long)log_scale0, (long)z, - (long)(x + WITH1->x1 * rxx + WITH1->y1 * ryx), - (long)(y + WITH1->x1 * rxy + WITH1->y1 * ryy)); - break; - } - } - } - hidecursor(); -} - - -static void udrawgatec(short x, short y, short g, short c) -{ - short i, z, rxx, rxy, ryx, ryy; - log_krec *k; - int hascolor; - short FORLIM; - log_vectorrec *WITH1; - - if (g == 0) - { - hidecursor(); - m_color((long)c); - m_drawpoint((long)x, (long)y); - hidecursor(); - return; - } - k = kind[(g & (log_kindoffset - 1)) - 1]; - if (k->bbmax <= maxsafescale) - { - plaindrawgatec(x, y, g, c); - return; - } - hascolor = (c != gg.color.backgr); - z = log_scale0 * k->bbmax + 2; - if (x < -z || x > across + z || y < -z || y > down + z) - return; - z = g / log_kindoffset; - rxx = log_rotxx[z] * maxsafescale; - rxy = log_rotxy[z] * maxsafescale; - ryx = log_rotyx[z] * maxsafescale; - ryy = log_rotyy[z] * maxsafescale; - hidecursor(); - m_color((long)c); - FORLIM = k->numvects; - for (i = 0; i < FORLIM; i++) - { - WITH1 = &k->vector[i]; - switch (WITH1->vkind) - { - - case '1': - if (hascolor) - m_color((long)c); - break; - - case '2': - if (hascolor) - m_color((long)gategreen); - break; - - case '3': - if (hascolor) - m_color((long)gateyellow); - break; - - case '4': - if (hascolor) - m_color((long)gatered); - break; - - case '5': - if (hascolor) - m_color((long)gateorange); - break; - - case '6': - if (hascolor) - m_color((long)gateblack); - break; - - case '7': - if (hascolor) - m_color((long)gatewhite); - break; - - case 'v': - case 'C': - case 'e': - case 'E': - case 'r': - drawvector2(&k->vector[i], - (long)(x + (WITH1->x1 * rxx + WITH1->y1 * ryx) / k->bbmax), - (long)(y + (WITH1->x1 * rxy + WITH1->y1 * ryy) / k->bbmax), - (long)(x + (WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx) / k->bbmax), - (long)(y + (WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy) / k->bbmax)); - break; - - case 'c': - case 'F': - drawvector4(&k->vector[i], (long)(x + (WITH1->x1 * rxx + - WITH1->y1 * ryx) / k->bbmax), (long) - (y + (WITH1->x1 * rxy + WITH1->y1 * ryy) / k->bbmax), (long) - (x + (WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx) / k->bbmax), - (long) - (y + (WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy) / k->bbmax), - (long) - (x + (WITH1->UU.U99.x3 * rxx + WITH1->UU.U99.y3 * ryx) / k->bbmax), - (long) - (y + (WITH1->UU.U99.x3 * rxy + WITH1->UU.U99.y3 * ryy) / k->bbmax), - (long) - (x + (WITH1->UU.U99.x4 * rxx + WITH1->UU.U99.y4 * ryx) / k->bbmax), - (long) - (y + (WITH1->UU.U99.x4 * rxy + WITH1->UU.U99.y4 * ryy) / k->bbmax)); - break; - } - } - hidecursor(); -} - - -/*================= DRAWGATEC ==================*/ -/*= =*/ -/*= Draw a gate of specified color at a =*/ -/*= certain position (grid coordinates). =*/ -/*= =*/ -/*================================================*/ - -static void drawgatedotsc(short x, short y, short g, short c) -{ - short i, z, rxx, rxy, ryx, ryy; - log_krec *WITH; - short FORLIM; - - if (g == 0 || vlsi) - return; - m_color((long)c); - z = g / log_kindoffset; - if (z != 0) - { - rxx = log_rotxx[z]; - rxy = log_rotxy[z]; - ryx = log_rotyx[z]; - ryy = log_rotyy[z]; - WITH = kind[(g & (log_kindoffset - 1)) - 1]; - FORLIM = WITH->numpins; - for (i = 0; i < FORLIM; i++) - point(x + WITH->pin[i].x * rxx + WITH->pin[i].y * ryx, - y + WITH->pin[i].x * rxy + WITH->pin[i].y * ryy); - return; - } - WITH = kind[(g & (log_kindoffset - 1)) - 1]; - FORLIM = WITH->numpins; - for (i = 0; i < FORLIM; i++) - point(x + WITH->pin[i].x, y + WITH->pin[i].y); -} - - -static void drawgatec(short x, short y, short g, short c) -{ - short i, xx, yy, z, rxx, rxy, ryx, ryy; - long savecol; - int hascolor; - log_krec *WITH; - short FORLIM; - log_vectorrec *WITH1; - - if (zoom == 0) - { - plaindrawgatec((int)(x * gg.scale - gg.xoff), - (int)(y * gg.scale - gg.yoff), g, c); - } - else - { - z = g / log_kindoffset; - rxx = log_rotxx[z] * gg.scale; - rxy = log_rotxy[z] * gg.scale; - ryx = log_rotyx[z] * gg.scale; - ryy = log_rotyy[z] * gg.scale; - xx = x * gg.scale - gg.xoff; - yy = y * gg.scale - gg.yoff; - hidecursor(); - m_color((long)c); - hascolor = (c != gg.color.backgr && c != gg.color.conflict); - WITH = kind[(g & (log_kindoffset - 1)) - 1]; - FORLIM = WITH->numvects; - for (i = 0; i < FORLIM; i++) - { - WITH1 = &WITH->vector[i]; - switch (WITH1->vkind) - { - - case '1': - if (hascolor) - m_color((long)c); - break; - - case '2': - if (hascolor) - m_color((long)gategreen); - break; - - case '3': - if (hascolor) - m_color((long)gateyellow); - break; - - case '4': - if (hascolor) - m_color((long)gatered); - break; - - case '5': - if (hascolor) - m_color((long)gateorange); - break; - - case '6': - if (hascolor) - m_color((long)gateblack); - break; - - case '7': - if (hascolor) - m_color((long)gatewhite); - break; - - case 'v': - case 'r': - drawvector2( - &WITH->vector[i], - (long)(xx + (WITH1->x1 * rxx + WITH1->y1 * ryx) / log_scale0), - (long)(yy + (WITH1->x1 * rxy + WITH1->y1 * ryy) / log_scale0), - (long) - (xx + (WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx) / log_scale0), - (long) - (yy + - (WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy) / log_scale0)); - break; - - case 'C': - m_circle(xx + ((WITH1->x1 + WITH1->UU.U99.x2) * rxx + (WITH1->y1 + - WITH1->UU.U99.y2) * ryx) / (log_scale0 * 2L), - yy + ((WITH1->x1 + WITH1->UU.U99.x2) * rxy + (WITH1->y1 + WITH1-> - UU.U99.y2) * ryy) / (log_scale0 * 2L), - P_imax2((long)abs((WITH1->x1 - WITH1->UU.U99.x2) * rxx + - (WITH1->y1 - WITH1->UU.U99.y2) * ryx), - (long)abs((WITH1->x1 - WITH1->UU.U99.x2) * ryx + - (WITH1->y1 - WITH1->UU.U99.y2) * ryy)) / - (log_scale0 * 2)); - break; - - case 'e': - savecol = m_curcolor(); - m_color(m_trans); - m_ellipse( - xx + ((WITH1->x1 + WITH1->UU.U99.x2) * rxx + - (WITH1->y1 + WITH1->UU.U99.y2) * ryx) / (log_scale0 * 2L), - yy + ((WITH1->x1 + WITH1->UU.U99.x2) * rxy + - (WITH1->y1 + WITH1->UU.U99.y2) * ryy) / (log_scale0 * 2L), - ((WITH1->x1 - WITH1->UU.U99.x2) * rxx + - (WITH1->y1 - WITH1->UU.U99.y2) * ryx) / (log_scale0 * 2L), - ((WITH1->x1 - WITH1->UU.U99.x2) * ryx + - (WITH1->y1 - WITH1->UU.U99.y2) * ryy) / (log_scale0 * 2L), - savecol); - m_color(savecol); - break; - - case 'E': - m_ellipse( - xx + ((WITH1->x1 + WITH1->UU.U99.x2) * rxx + - (WITH1->y1 + WITH1->UU.U99.y2) * ryx) / (log_scale0 * 2L), - yy + ((WITH1->x1 + WITH1->UU.U99.x2) * rxy + - (WITH1->y1 + WITH1->UU.U99.y2) * ryy) / (log_scale0 * 2L), - ((WITH1->x1 - WITH1->UU.U99.x2) * rxx + - (WITH1->y1 - WITH1->UU.U99.y2) * ryx) / (log_scale0 * 2L), - ((WITH1->x1 - WITH1->UU.U99.x2) * ryx + - (WITH1->y1 - WITH1->UU.U99.y2) * ryy) / (log_scale0 * 2L), - m_curcolor()); - break; - - case 'c': - case 'F': - drawvector4(&WITH->vector[i], (long)(xx + (WITH1->x1 * rxx + - WITH1->y1 * ryx) / log_scale0), (long)(yy + - (WITH1->x1 * rxy + WITH1->y1 * ryy) / log_scale0), (long)(xx + - (WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx) / log_scale0), - (long)(yy + - (WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy) / log_scale0), - (long)(xx + - (WITH1->UU.U99.x3 * rxx + WITH1->UU.U99.y3 * ryx) / log_scale0), - (long)(yy + - (WITH1->UU.U99.x3 * rxy + WITH1->UU.U99.y3 * ryy) / log_scale0), - (long)(xx + - (WITH1->UU.U99.x4 * rxx + WITH1->UU.U99.y4 * ryx) / log_scale0), - (long)(yy + (WITH1->UU.U99.x4 * rxy + WITH1->UU.U99.y4 * ryy) / - log_scale0)); - break; - - case 't': - drawtext(&WITH->vector[i], (long)gg.scale, (long)z, - (long)(xx + (WITH1->x1 * rxx + WITH1->y1 * ryx) / log_scale0), - (long)(yy + (WITH1->x1 * rxy + WITH1->y1 * ryy) / log_scale0)); - break; - } - } - hidecursor(); - } - if ((c == gg.color.gate || c == gg.color.dimgate) && !suppressdots) - drawgatedotsc(x, y, g, gg.color.gatepin); -} - - -static void signallabel(short x, short y, short gtype, short sig, short c) -{ - log_krec *k; - char STR1[256]; - - k = kind[(gtype & (log_kindoffset - 1)) - 1]; - if (!(sig != 0 && k->flag.U3.named)) - return; - remcursor(); - m_color((long)c); - if (k->flag.U3.nright != (gtype / log_kindoffset == 0)) - drawstr2((int)(x - m_strwidth(NULL, - strrtrim(strcpy(STR1, gg.signaltab[sig - 1].name))) + NAMEGAP), - y - 3, gg.signaltab[sig - 1].name); - else - drawstr2(x - NAMEGAP, y - 3, gg.signaltab[sig - 1].name); -} - - -static void gsignallabel(short x, short y, log_grec *g, short c) -{ - signallabel((int)(x * gg.scale - gg.xoff), (int)(y * gg.scale - gg.yoff), - g->g, g->sig, c); -} - - -typedef enum {inside,north,east,south,west} placement; - -static void drawpnums(log_grec *g, short c) -{ - short rxx, rxy, ryx, ryy, i, j, k; - char s[7]; - log_krec *WITH; - short FORLIM, FORLIM1; - int tx,ty,ex,ey; - int minx,miny,maxx,maxy; - placement p = inside; - long hw; - - if (zoom <= 0 || gg.textinvisible || gg.pnuminvisible) - return; - m_color((long)c); - rxx = log_rotxx[g->rot]; - rxy = log_rotxy[g->rot]; - ryx = log_rotyx[g->rot]; - ryy = log_rotyy[g->rot]; - WITH = g->kind; - - /* use grab rectangle to determine which edge this pin is attached to. */ - minx = ( WITH->x1 * rxx + WITH->y1 * ryx); - miny = ( WITH->x1 * rxy + WITH->y1 * ryy); - maxx = ( WITH->x2 * rxx + WITH->y2 * ryx); - maxy = ( WITH->x2 * rxy + WITH->y2 * ryy); - - FORLIM = WITH->numpnums; - for (i = 0; i < FORLIM; i++) - { - sprintf(s, "%d", WITH->pnum[i].num); - hw = strlen(s) * 5 / 2; - ex = (WITH->pnum[i].x * rxx + WITH->pnum[i].y * ryx); - ey = (WITH->pnum[i].x * rxy + WITH->pnum[i].y * ryy); - if (ex < minx) - { - p = west; - } - else if (ex > maxx) - { - p = east; - } - else if (ey < miny) - { - p = north; - } - else if (ey > maxy) - { - p = south; - } - tx = g->x * gg.scale + ex * gg.scale / log_scale0 - gg.xoff; - ty = g->y * gg.scale + ey * gg.scale / log_scale0 - gg.yoff; - switch (p) - { - case west: - tx -= 5; - break; - case east: - tx += 5; - break; - case north: - tx -= hw; - ty -= 9; - break; - case south: - tx -= hw; - ty += 5; - break; - - default: - break; - } - - if (p == west) - m_rightstr(tx,ty,NULL,s); - else - m_drawstr(tx,ty,NULL,s); - } -} - -#undef fromtab -#undef totab - - -static void setscale (short s); - - -static void kdrawgatec(short i, short c) -{ - short x, y; - short ozoom = zoom; - - x = (i - 1) * kindgroupspacing + kindgroupstart; - y = (down + baseline) / 2; - udrawgatec(x, y, kindgroup[i - 1], c); - setscale(0); - if (kindgroup[i - 1] != 0) - signallabel(x, y, kindgroup[i - 1], kindsig[i - 1], c); - setscale(ozoom); -} - - -/*================= DRAWGATEX ==================*/ -/*= =*/ -/*= Draw a gate. If it is a TO or FROM gate, =*/ -/*= draw its name as well. =*/ -/*= =*/ -/*================================================*/ - -static void drawgatexc(log_grec *g, short c) -{ - if (g->dimcolor && c == gg.color.gate) - c = gg.color.dimgate; - drawgatec(g->x, g->y, g->g, c); - if (!gg.textinvisible) - gsignallabel(g->x, g->y, g, gg.color.signal); - if (g->kind->numpnums > 0) - drawpnums(g, gg.color.pinnum); -} - - -static void drawgatex(log_grec *g) -{ - drawgatexc(g, gg.color.gate); -} - - -static void setdimgate(log_grec *g, int dim) -{ - log_grec *g1; - - if (g->dimcolor == dim) - return; - g->dimcolor = dim; - if (gg.showpage <= 0) - return; - g1 = gg.gbase[gg.showpage - 1]; - while (g1 != NULL && g1 != g) - g1 = g1->next; - if (g1 != g) - return; - m_saveclip(); - clipon(); - drawgatex(g); - m_unclip(); -} - - -#define rtn "ERAGATE" - - -/*================== ERAGATE ===================*/ -/*= =*/ -/*= Erase a gate (including LED's and other =*/ -/*= "magic" stuff) using grid coordinates. =*/ -/*= =*/ -/*================================================*/ - -static void eragate(log_grec *g) -{ - log_grec *g1, *g2; + rabstate = 0; + } else + rabstate = i; + } else + rabstate = 0; + } + } + else + { + rabstate = 0; + } - if (g->conflict || g->oconflict) + if (gg.probemode) { - g1 = gateconflictbase; - g2 = NULL; - while (g1 != NULL && g1 != g) + if (cursx != gg.t.x || cursy != gg.t.y) { - g2 = g1; - g1 = g1->confnext; + if (gg.probesimtype != NULL) + checkprobe((int)gg.t.x, (int)gg.t.y); + probeflag = false; + drawcursor((int)gg.t.x, (int)gg.t.y); } - - if (g1 == NULL) - report(10, rtn); - else if (g2 == NULL) - gateconflictbase = g->confnext; else - g2->confnext = g->confnext; - g->conflict = false; - g->conflict1 = false; - g->conflict2 = false; - g->oconflict = false; - } - drawgatec(g->x, g->y, g->g, gg.color.backgr); - gsignallabel(g->x, g->y, g, gg.color.backgr); - if (g->kind->numpnums > 0) - drawpnums(g, gg.color.backgr); - drawgatedotsc(g->x, g->y, g->g, gg.color.backgr); - calltoolgate(g, act_erasegate); -} - -#undef rtn - - -/*================ DRAWSOLDERC =================*/ -/*= =*/ -/*= Draw a solder point at a certain position =*/ -/*= (grid coordinates). =*/ -/*= =*/ -/*================================================*/ + { + if (!cursorflag) + drawcursor((int)gg.t.x, (int)gg.t.y); + if (!probeflag) + { + testprobe((int)gg.t.x, (int)gg.t.y); + probeflag = true; + } + } -static void drawsolderc(short x, short y, short c) -{ - if (!showsolder) - return; - if (vlsi) + if (!gg.t.near_ && briefprobe) + { + remcursor(); + gg.probemode = false; + } + } + else { - if (c == gg.color.conflict || c == gg.color.backgr) - m_color((long)c); + briefprobe = false; + if (gg.probesimtype != NULL) + unprobe(); + if (gg.t.near_) + drawcursor((int)gg.t.x, (int)gg.t.y); else - m_color((long)gg.color.vlsicut); - x = x * gg.scale - gg.xoff; - y = y * gg.scale - gg.yoff; - m_drawline(x - 3L, y - 3L, x + 3L, y + 3L); - m_drawline(x - 3L, y + 3L, x + 3L, y - 3L); - m_drawline(x - 2L, y - 3L, x + 4L, y + 3L); - m_drawline(x - 2L, y + 3L, x + 4L, y - 3L); - return; + remcursor(); + } + cred = gg.color.conflict; + if (anyconflicts && (cred == log_cred || cred == log_cred8) && + (rcolormap[cred] == 255 || gcolormap[cred] == 255 || + bcolormap[cred] == 255)) + { + x = timers_sysclock() * 6 % 137 + 119; + rval = (char)(x * rcolormap[cred] / 255); + gval = (char)(x * gcolormap[cred] / 255); + bval = (char)(x * bcolormap[cred] / 255); + m_vsetcolors((long)cred, 1L, (unsigned char *) &rval, + (unsigned char *) &gval, (unsigned char *) &bval); } - m_color((long)c); - x = x * gg.scale - gg.xoff; - y = y * gg.scale - gg.yoff; - m_drawline(x - 1L, y - 2L, x + 1L, y - 2L); - m_drawline(x - 2L, y - 1L, x + 2L, y - 1L); - m_drawline(x - 2L, (long)y, x + 2L, (long)y); - m_drawline(x - 2L, y + 1L, x + 2L, y + 1L); - m_drawline(x - 1L, y + 2L, x + 1L, y + 2L); -} - - -/*================= DRAWTRANSC =================*/ -/*= =*/ -/*= Draw a VLSI transistor at a certain =*/ -/*= position (grid coordinates). =*/ -/*= =*/ -/*================================================*/ - -static void drawtransc(short x, short y, short c) -{ - if (!vlsi) - return; - if (c == gg.color.solder) - m_color((long)gg.color.vlsicut); - else - m_color((long)c); - x = x * gg.scale - gg.xoff; - y = y * gg.scale - gg.yoff; - m_circle((long)x, (long)y, 4L); -} - - -/*================== ERALABEL ==================*/ -/*= =*/ -/*= Erase a text label from the screen. =*/ -/*= =*/ -/*================================================*/ - -static void eralabel(log_lrec *l) -{ - m_color((long)gg.color.backgr); - m_drawstr(l->x * gg.scale - gg.xoff, l->y * gg.scale - gg.yoff + 2, - logfont_lfont, l->name); -} - - -/*================== XORLABEL ==================*/ -/*= =*/ -/*= XOR a text label onto the screen. =*/ -/*= =*/ -/*================================================*/ -static void xorlabel(short x, short y, log_lrec *l) -{ - m_colormode((long)m_xor); - m_color((long)gg.color.labeltext); - m_drawstr(x * gg.scale - gg.xoff, y * gg.scale - gg.yoff + 2, logfont_lfont, - l->name); - m_colormode((long)m_normal); + if (gg.t.moving) + { + gg.fastspeed = gg.fastmin; + fastsavetime = timers_sysclock(); + } + else if (gg.fastspeed < gg.fastmax && + timers_sysclock() > fastsavetime + gg.fastrate) + { + gg.fastspeed++; + fastsavetime = timers_sysclock(); + } + gg.gridx = (gg.t.x + gg.hscale + gg.xoff) / gg.scale; + gg.gridy = (gg.t.y + gg.hscale + gg.yoff) / gg.scale; } -/*================== DRAWBOXC ==================*/ +/*================= JUSTTAP ====================*/ /*= =*/ -/*= Draw a dashed box on the screen. =*/ +/*= Return TRUE if pen was tapped. Return =*/ +/*= FALSE if pen was held and/or moved. =*/ /*= =*/ /*================================================*/ -static void drawboxc0(short x1, short y1, short x2, short y2, short c) +static int justtap() { - m_color((long)c); - m_linestyle(1L); - rect(x1, y1, x2, y2); - m_linestyle(0L); -} - + long t0; + short tx, ty; -static void drawboxc(log_brec *b, short c) -{ - drawboxc0(b->x1, b->y1, b->x2, b->y2, c); + t0 = timers_sysclock() + tapdelay; + tx = gg.t.x; + ty = gg.t.y; + do + { + pen(); + } while (gg.t.depressed && labs(gg.t.x - tx) <= taptolerance && + labs(gg.t.y - ty) <= taptolerance && timers_sysclock() <= t0); + return (!gg.t.depressed); } -/*================ DRAWMARKERSC ================*/ +/*================== TESTKEY2 ==================*/ /*= =*/ -/*= Draw the printing markers on the screen. =*/ +/*= Return the most recently pressed key. =*/ /*= =*/ /*================================================*/ -static void drawmarkersc(short c) +static char testkey2() { - clipon(); - m_color((long)c); - hline(gg.markerx1, gg.markerx1 + 2, gg.markery1); - vline(gg.markerx1, gg.markery1, gg.markery1 + 2); - hline(gg.markerx2 - 2, gg.markerx2, gg.markery2); - vline(gg.markerx2, gg.markery2 - 2, gg.markery2); - clipoff(); + if (pushedbackkey != '\0') + return pushedbackkey; + else if (pollkbd2()) + return (nk_testkey(0)); + else + return ' '; } -/*================= DRAWNODEC ==================*/ +/*================== INKEY2 ====================*/ /*= =*/ -/*= Draw all wires and solder points in a =*/ -/*= particular node, in color C. =*/ +/*= Return a keystroke. Key is removed from =*/ +/*= the buffer. =*/ /*= =*/ /*================================================*/ -static void drawnodec(log_nrec *n, short c) +static char inkey2() { - log_hwrec *hw; - log_vwrec *vw; - log_srec *s; - - if (gg.invisible || (gg.showconflicts == true && n->conflict == false)) - return; + char ch; - hidecursor(); - if ((unsigned)c > 15) + do { - if (gg.glowmode && gg.showpage > 0) - c = glowcol(n, (long)gg.color.wire[0]); - else - c = gg.color.wire[0]; - } - if (vlsi && c == gg.color.wire[0]) + } while (!pollkbd2()); + if (pushedbackkey != '\0') { - hw = gg.hwbase[gg.curpage - 1]; - while (hw != NULL) - { - if (hw->node == n && hw != gg.movinghw) - { - m_color((long)gg.color.wire[hw->wcolr - log_wcol_normal]); - hline(hw->x1, hw->x2, hw->y); - } - hw = hw->next; - } - vw = gg.vwbase[gg.curpage - 1]; - while (vw != NULL) - { - if (vw->node == n && vw != gg.movingvw) - { - m_color((long)gg.color.wire[vw->wcolr - log_wcol_normal]); - vline(vw->x, vw->y1, vw->y2); - } - vw = vw->next; - } + realkey = pushedbackkey; + pushedbackkey = '\0'; } else { - m_color((long)c); - hw = gg.hwbase[gg.curpage - 1]; - while (hw != NULL) { - if (hw->node == n && hw != gg.movinghw) - hline(hw->x1, hw->x2, hw->y); - hw = hw->next; - } - vw = gg.vwbase[gg.curpage - 1]; - while (vw != NULL) - { - if (vw->node == n && vw != gg.movingvw) - vline(vw->x, vw->y1, vw->y2); - vw = vw->next; - } + realkey = nk_getkey(); } - if (showsolder) + ch = realkey; + if ((ch & 255) >= 168 && (ch & 255) <= 239 && nk_capslock) { - s = gg.sbase[gg.curpage - 1]; - while (s != NULL) + if ((ch & 255) <= 193) { - if ((s->hwire != NULL && s->hwire->node == n) || - (s->vwire != NULL && s->vwire->node == n)) - drawsolderc(s->x, s->y, c); - s = s->next; + ch += 46; + } else if ((ch & 255) >= 214) + { + ch -= 46; } } - hidecursor(); -} - - -/*================= DRAWNODE ===================*/ -/*= =*/ -/*= Draw all wires and solder points in a =*/ -/*= particular node. =*/ -/*= =*/ -/*================================================*/ - -static void drawnode(log_nrec *n) -{ - drawnodec(n, -1); -} - - -/*================ REFRPAGEDISP ================*/ -/*= =*/ -/*= Refresh the page-number display. =*/ -/*= =*/ -/*================================================*/ - -static int pageempty (int pg); - - -static void refrpagedisp() -{ - short num; - - m_color((long)gg.color.page1); - drawstr2(across - 49, 2, "PAGE"); - m_color((long)gg.color.page2); - drawnum2(across - 14, 2, (int)gg.curpage); - m_color((long)gg.color.page3); - drawstr2(across - 35, 14, "OF"); - m_color((long)gg.color.page4); - num = gg.numpages; - while (num > gg.curpage && pageempty(num)) - num--; - drawnum2(across - 14, 14, num); + gg.fastspeed = gg.fastmin; + return ch; } -/*================ REFREDITMODE ================*/ -/*= =*/ -/*= Refresh the editing mode in the menus. =*/ -/*= =*/ -/*================================================*/ - -static void refreditmode() +static void inkey3(char *ch) { - hidecursor(); - m_color((long)gg.color.backgr); - m_fillrect(across + menux4 - 1L, line2 - 2L, across + menux4 + 30L, - line2 + 9L); - switch (cureditmode) - { - - case 1: - m_color((long)gg.color.menuword); - drawstr2(across + menux4, line2, "ROT"); - break; - - case 2: - m_color((long)gg.color.menuword); - drawstr2(across + menux4, line2, "MIR-"); - break; - - case 3: - m_color((long)gg.color.menuword); - drawstr2(across + menux4, line2, "MIR|"); - break; - - case 4: - m_color((long)gg.color.selword); - drawstr2(across + menux4, line2, "CNFG"); - break; - } - hidecursor(); + *ch = inkey2(); } -/*=============== REFRBASELINE =================*/ -/*= =*/ -/*= Refresh the baseline to the correct color. =*/ -/*= =*/ -/*================================================*/ - -static void refrbaseline(int always) +static char inkey4() { - short c; + /* undo CAPSLOCK key */ + char ch; - if (anyconflicts) - c = gg.color.conflict; - else - c = gg.baselinecolor; - if (!(c != gg.color.curbaseline || always)) - return; - clipoff(); - gg.color.curbaseline = c; - hidecursor(); - m_color((long)c); - m_fillrect(0L, (long)baseline, (long)kindgroupleft, baseline + 1L); - m_fillrect((long)kindgroupright, (long)baseline, (long)across, - baseline + 1L); - hidecursor(); + ch = inkey2(); + if (!nk_capslock) + return ch; + if (isupper(ch)) + ch += 32; + else if (islower(ch)) + ch -= 32; + return ch; } -#define rtn "REFRESH" +static void ungetkey2(char ch) +{ + pushedbackkey = ch; +} -/*=================== REFRESH ==================*/ +/*=============== WAITFORKEY ===================*/ /*= =*/ -/*= Refresh the screen (does not clear, so may =*/ -/*= be used to "clean up" existing screen). =*/ +/*= Wait until a key is pressed (but ignore it) =*/ /*= =*/ /*================================================*/ -static void refresh() +static void waitforkey() { - long x1, y1, x2, y2; - log_grec *g; - log_hwrec *hw; - log_vwrec *vw; - log_nrec *n; - log_srec *s; - log_lrec *l; - log_brec *b; - - stamp(&gg.refrstamp); - gg.showpage = gg.curpage; - showsolder = (zoom > -1 && (vlsi || !gg.glowmode || glowsolder)); - x1 = (gg.xoff - 30) / gg.scale; - y1 = (gg.yoff - 30) / gg.scale; - x2 = (gg.xoff + across + 30) / gg.scale; - y2 = (gg.yoff + down + 30) / gg.scale; - refrtimer = -1; - remcursor(); - clipon(); - refrpagedisp(); - if (!gg.invisible && !gg.showconflicts) - { - working(); - suppressdots = gg.dotsvisible; - g = gg.gbase[gg.curpage - 1]; - while (g != NULL) - { - if (P_ibetweenm(x1, (long)g->x, x2, (long)g->kind->bbmax) && - P_ibetweenm(y1, (long)g->y, y2, (long)g->kind->bbmax)) - drawgatex(g); - g = g->next; - } - suppressdots = false; - working(); - if (gg.glowmode) - { - hw = gg.hwbase[gg.curpage - 1]; - while (hw != NULL) - { - if (hw->y > y1 && hw->y < y2 && hw != gg.movinghw) - { - m_color(glowcol(hw->node, - (long)gg.color.wire[hw->wcolr - log_wcol_normal])); - hline(hw->x1, hw->x2, hw->y); - } - hw = hw->next; - } - working(); - vw = gg.vwbase[gg.curpage - 1]; - while (vw != NULL) - { - if (vw->x > x1 && vw->x < x2 && vw != gg.movingvw) - { - m_color(glowcol(vw->node, - (long)gg.color.wire[vw->wcolr - log_wcol_normal])); - vline(vw->x, vw->y1, vw->y2); - } - vw = vw->next; - } - working(); - if (showsolder) - { - s = gg.sbase[gg.curpage - 1]; - while (s != NULL) - { - if (s->hwire != NULL) - n = s->hwire->node; - else - n = s->vwire->node; - drawsolderc(s->x, s->y, (int)glowcol(n, (long)gg.color.solder)); - s = s->next; - } - } - } - else - { - m_color((long)gg.color.wire[0]); - hw = gg.hwbase[gg.curpage - 1]; - while (hw != NULL) - { - if (hw->y > y1 && hw->y < y2 && hw != gg.movinghw) - { - if (vlsi) - m_color((long)gg.color.wire[hw->wcolr - log_wcol_normal]); - hline(hw->x1, hw->x2, hw->y); - } - hw = hw->next; - } - working(); - vw = gg.vwbase[gg.curpage - 1]; - while (vw != NULL) - { - if (vw->x > x1 && vw->x < x2 && vw != gg.movingvw) - { - if (vlsi) - m_color((long)gg.color.wire[vw->wcolr - log_wcol_normal]); - vline(vw->x, vw->y1, vw->y2); - } - vw = vw->next; - } - working(); - if (showsolder) - { - s = gg.sbase[gg.curpage - 1]; - while (s != NULL) - { - if (s->hwire != NULL) - n = s->hwire->node; - else - n = s->vwire->node; - drawsolderc(s->x, s->y, gg.color.solder); - s = s->next; - } - } - } + char ch; - if (gg.dotsvisible) - { - g = gg.gbase[gg.curpage - 1]; - while (g != NULL) - { - if (g->x > x1 && g->x < x2 && g->y > y1 && g->y < y2) - drawgatedotsc(g->x, g->y, g->g, gg.color.gatepin); - g = g->next; - } - } - } - else - { - working(); - g = gg.gbase[gg.curpage - 1]; - while (g != NULL) - { - if (g->kind->flag.U3.visible) - drawgatex(g); - g = g->next; - } - } - working(); - if (!gg.textinvisible) + while (pollkbd2()) + ch = inkey2(); + do { - b = gg.bbase[gg.curpage - 1]; - while (b != NULL) - { - drawboxc(b, gg.color.dashbox); - b = b->next; - } - working(); - l = gg.lbase[gg.curpage - 1]; - m_color((long)gg.color.labeltext); - while (l != NULL) - { - if (l->y > y1 && l->y < y2) - { - m_drawstr(l->x * gg.scale - gg.xoff, l->y * gg.scale - gg.yoff + 2, - logfont_lfont, l->name); - } - l = l->next; - } - } - working(); - if (gg.markers) - drawmarkersc(gg.color.marker); - if (memavail() < memtolerance) - message("Low on memory!"); - clipoff(); - restorecursor(); + pen(); + } while (!(pollkbd2() || (gg.t.dn && gg.t.off))); + if (pollkbd2()) + ch = inkey2(); } -#undef rtn - -/*================= REFRESHSOON ================*/ +/*=================== INBOX ====================*/ /*= =*/ -/*= Screen is messed up, so refresh it as soon =*/ -/*= as the user stops moving around. =*/ +/*= Return TRUE if cursor is inside a certain =*/ +/*= rectangular area (screen coordinates). =*/ /*= =*/ /*================================================*/ -static void refreshsoon() +static int inbox(short x, short y, short x1, short y1) { - refrtimer0 = refrdelay; - refrtimer = refrdelay; - gg.refrflag = true; + return (gg.t.x >= x && gg.t.y >= y && gg.t.x <= x + x1 && gg.t.y <= y + y1); } @@ -4683,79 +1793,6 @@ static void closedumpfiles() } -/*================== REFRMENU ==================*/ -/*= =*/ -/*= Clear and redraw menu area of screen. =*/ -/*= =*/ -/*================================================*/ - -static void refrmenu() -{ - short i, FORLIM; - - working(); - remcursor(); - uerase(0, baseline + 2, across, down); - clipoff(); - refrbaseline(true); - m_color((long)gg.color.backgr); - m_fillrect(kindgroupleft + 1L, (long)baseline, kindgroupright - 1L, - baseline + 1L); - m_color((long)gg.color.menuword); - drawstr2(menux1, line1, "Frills"); - drawstr2(menux2, line1, "Editing"); - drawstr2(menux1, line2, "HELP"); - drawstr2(menux2, line2, "CAT"); - drawstr2(across + menux3, line1, "Cursor"); - drawstr2(across + menux4, line1, "Misc"); - refreditmode(); - if (modeflag) - log_setmode(modename); - else - log_setmode(""); - FORLIM = kindgroupsize; - for (i = 1; i <= FORLIM; i++) - kdrawgatec(i, gg.color.kindgate); -} - - -static void beginbottom() -{ - remcursor(); - clipoff(); - bottomcount++; - if (m_autoraise) - { - clearshowalpha(); - } - else - { - clearalpha(); - } - nk_gotoxy(0, txdown - 1); -} - - -static void endbottom() -{ - remcursor(); - bottomcount--; - if (m_autoraise) - { - if (bottomcount < 1) /* fix from WES */ - { - bottomcount =0; - m_graphics_on(); - } - } - else - { - m_graphics_on(); /* switch back to the graphics window */ - } - clearalpha(); -} - - /*================= BEGINERROR =================*/ /*= =*/ /*= Clear the menu area for an error message. =*/ @@ -4766,130 +1803,22 @@ static void beginerror() { beginbottom(); strlist_empty(&thingstodo); - warning(); -} - - -/*================== ENDERROR ==================*/ -/*= =*/ -/*= Clean up after displaying an error message. =*/ -/*= =*/ -/*================================================*/ - -static void enderror() -{ - printf(" Press any key to continue."); - m_alpha_on(); - waitforkey(); - endbottom(); -} - - -/*================ REFRSCREEN1 =================*/ -/*= =*/ -/*= Clear and redraw working area of screen. =*/ -/*= =*/ -/*================================================*/ - -static void refrscreen1() -{ - m_colormode((long)m_normal); - m_noclip(); - remcursor(); - uerase(0, 0, across, baseline - 1); - resetmessages(); - refresh(); - gg.refrflag = true; -} - - -/*================= REFRSCREEN =================*/ -/*= =*/ -/*= Clear and redraw entire screen. =*/ -/*= =*/ -/*================================================*/ - -static void refrscreen() -{ - gg.showpage = gg.curpage; - bottomcount = 0; - m_colormode((long)m_normal); - m_noclip(); - fixcolormap(); - clearalpha(); - refrmenu(); - refrscreen1(); - m_graphics_on(); -} - - -static void resize_screen() -{ - initscreen2(); - refrscreen(); -} - -static void chpage(short pg) -{ - log_regrec *r; - - stamp(&gg.pagestamp[pg - 1]); - gg.pagechanged[pg - 1] = true; - r = gg.pageregions[pg - 1]; - while (r != NULL) { - stamp(&r->regstamp); - r = r->next; - } -} - - -static void chpageplace(short pg, short x1, short y1, short x2, short y2) -{ - log_regrec *r; - - stamp(&gg.pagestamp[pg - 1]); - gg.pagechanged[pg - 1] = true; - r = gg.pageregions[pg - 1]; - if (r == NULL) - return; - sortshints(&x1, &x2); - sortshints(&y1, &y2); - while (r != NULL) - { - if (r->x1 <= x2 && x1 <= r->x2 && r->y1 <= y2 && y1 <= r->y2) - stamp(&r->regstamp); - r = r->next; - } -} - - -static int pageempty(int pg) -{ - return (gg.gbase[pg - 1] == NULL && gg.hwbase[pg - 1] == NULL && - gg.vwbase[pg - 1] == NULL && gg.bbase[pg - 1] == NULL && - gg.lbase[pg - 1] == NULL); -} - - -static int pagenull(short pg) -{ - return (pageempty(pg) && gg.pageregions[pg - 1] == NULL); + warning(); } -static int pagechanged(short pg) -{ - return (gg.pagechanged[pg - 1] && !pageempty(pg)); -} +/*================== ENDERROR ==================*/ +/*= =*/ +/*= Clean up after displaying an error message. =*/ +/*= =*/ +/*================================================*/ -static int anychanged() +static void enderror() { - short i; - - i = 1; - while (i <= gg.numpages && !pagechanged(i)) - i++; - return (i <= gg.numpages); + printf(" Press any key to continue."); + m_alpha_on(); + waitforkey(); + endbottom(); } @@ -5512,192 +2441,15 @@ static void clearconflicts(log_tool *tool) static short getsignal (int d, char *n); -/*=================== NEWHW ====================*/ -/*= =*/ -/*= Create a Horizontal Wire. =*/ -/*= =*/ -/*================================================*/ - -static void newhw(log_hwrec **hw) -{ - *hw = (log_hwrec *)Malloc(sizeof(log_hwrec)); - (*hw)->next = gg.hwbase[gg.curpage - 1]; - gg.hwbase[gg.curpage - 1] = *hw; - (*hw)->temp = (na_long)0; -} - - -#define rtn "DISPHW" - - -/*================== DISPHW ====================*/ -/*= =*/ -/*= Dispose of a Horizontal Wire. =*/ -/*= =*/ -/*================================================*/ - -static void disphw(log_hwrec **hw) -{ - log_hwrec *hw1; - - if (gg.traceflag) - fprintf(tracefile, "Dispose hwire %ld\n", (long)(*hw)); - if (*hw == NULL) - return; - hw1 = gg.hwbase[gg.curpage - 1]; - if (*hw == hw1) - { - gg.hwbase[gg.curpage - 1] = (*hw)->next; - } - else - { - while (hw1 != NULL && hw1->next != *hw) - hw1 = hw1->next; - if (hw1 == NULL) - report(10, rtn); - else - hw1->next = (*hw)->next; - } - chpageplace((int)gg.curpage, (*hw)->x1, (*hw)->y, (*hw)->x2, (*hw)->y); - Free(*hw); -} - -#undef rtn - - -/*=================== NEWVW ====================*/ -/*= =*/ -/*= Create a Vertical Wire. =*/ -/*= =*/ -/*================================================*/ - -static void newvw(log_vwrec **vw) -{ - *vw = (log_vwrec *)Malloc(sizeof(log_vwrec)); - (*vw)->next = gg.vwbase[gg.curpage - 1]; - gg.vwbase[gg.curpage - 1] = *vw; - (*vw)->temp = (na_long)0; -} - - -#define rtn "DISW" - - -/*================== DISW ====================*/ -/*= =*/ -/*= Dispose of a Vertical Wire. =*/ -/*= =*/ -/*================================================*/ - -static void dispvw(log_vwrec **vw) -{ - log_vwrec *vw1; - - if (gg.traceflag) - fprintf(tracefile, "Dispose vwire %ld\n", (long)(*vw)); - if (*vw == NULL) - return; - vw1 = gg.vwbase[gg.curpage - 1]; - if (*vw == vw1) - { - gg.vwbase[gg.curpage - 1] = (*vw)->next; - } - else - { - while (vw1 != NULL && vw1->next != *vw) - vw1 = vw1->next; - if (vw1 == NULL) - report(10, rtn); - else - vw1->next = (*vw)->next; - } - chpageplace((int)gg.curpage, (*vw)->x, (*vw)->y1, (*vw)->x, (*vw)->y2); - Free(*vw); -} - -#undef rtn - - -/*================== NEWSOLDER =================*/ -/*= =*/ -/*= Create a solder point. =*/ -/*= =*/ -/*================================================*/ - -static void newsolder(log_srec **s) -{ - *s = (log_srec *)Malloc(sizeof(log_srec)); - (*s)->next = gg.sbase[gg.curpage - 1]; - gg.sbase[gg.curpage - 1] = *s; - (*s)->hwire = NULL; - (*s)->hwire2 = NULL; - (*s)->vwire = NULL; - (*s)->vwire2 = NULL; - (*s)->temp = (na_long)0; -} - - -#define rtn "DISPSOLDER" - - -/*================ DISPSOLDER ==================*/ -/*= =*/ -/*= Dispose of a solder point. =*/ -/*= =*/ -/*================================================*/ - -static void dispsolder(log_srec **s) -{ - log_srec *s1; - - if (gg.traceflag) - fprintf(tracefile, "Dispose solder %ld\n", (long)(*s)); - if (*s == NULL) - return; - s1 = gg.sbase[gg.curpage - 1]; - if (*s == s1) - { - gg.sbase[gg.curpage - 1] = (*s)->next; - } - else - { - while (s1 != NULL && s1->next != *s) - s1 = s1->next; - if (s1 == NULL) - report(10, rtn); - else - s1->next = (*s)->next; - } - chpageplace((int)gg.curpage, (*s)->x, (*s)->y, (*s)->x, (*s)->y); - Free(*s); -} - -#undef rtn - - -/*================== LINKGATE ==================*/ -/*= =*/ -/*= Add a gate to the gate list. =*/ -/*= =*/ -/*================================================*/ - -static void linkgate(log_grec **g) -{ - (*g)->next = gg.gbase[gg.curpage - 1]; - gg.gbase[gg.curpage - 1] = *g; - chpageplace((int)gg.curpage, (*g)->x - (*g)->kind->bbmax, - (*g)->y - (*g)->kind->bbmax, (*g)->x + (*g)->kind->bbmax, - (*g)->y + (*g)->kind->bbmax); -} - - static void newattrs(log_gattrrec **gattr, short numattrs, log_kattrrec *kattr) { short i; *gattr = (log_gattrrec *)Malloc(numattrs * gattrrecsize); - for (i = 0; i < numattrs; i++) { - switch (kattr[i].dtype) { + for (i = 0; i < numattrs; i++) + { + switch (kattr[i].dtype) + { case 'R': case 'U': @@ -5727,284 +2479,56 @@ static void newattrs(log_gattrrec **gattr, short numattrs, log_kattrrec *kattr) (*gattr)[i].UU.nv = kattr[i].UU.U86.dv; break; } - (*gattr)[i].blnk = kattr[i].blnk; - (*gattr)[i].changed = false; - } -} - - -static void disposeattrs(log_gattrrec **gattr, short numattrs, log_kattrrec *kattr) -{ - short i; - - for (i = 0; i < numattrs; i++) - { - switch (kattr[i].dtype) - { - - case 'C': - Free((*gattr)[i].UU.c); - break; - - case 'A': - strdispose(&(*gattr)[i].UU.sp); - break; - } - } - Free(*gattr); -} - - -static void copyattrs(log_gattrrec **gattr, log_gattrrec *oldattr, short numattrs, log_kattrrec *kattr) -{ - short i; - - *gattr = (log_gattrrec *)Malloc(numattrs * gattrrecsize); - for (i = 0; i < numattrs; i++) - { - (*gattr)[i] = oldattr[i]; - switch (kattr[i].dtype) - { - - case 'C': - (*gattr)[i].UU.c = (char *)Malloc(kattr[i].prec + 1L); - strcpy((*gattr)[i].UU.c, oldattr[i].UU.c); - break; - - case 'A': - (*gattr)[i].UU.sp = strdup(oldattr[i].UU.sp); - break; - } - } -} - - -/*=================== NEWGATE ==================*/ -/*= =*/ -/*= Create a gate. =*/ -/*= =*/ -/*================================================*/ - -static void newgptr(log_grec **g) -{ - if (freegate == NULL) - { - *g = (log_grec *)Malloc(sizeof(log_grec)); - } - else - { - *g = freegate; - freegate = freegate->next; - } -} - - -static void newgate2(log_grec **g, short gt, short sig, log_gattrrec *attrs) -{ - short i; - char name[256]; - - newgptr(g); - (*g)->g = gt; - (*g)->rot = gt / log_kindoffset; - (*g)->kind = kind[(gt & (log_kindoffset - 1)) - 1]; - (*g)->vars = (na_long)0; - (*g)->conflict = false; - (*g)->conflict1 = false; - (*g)->conflict2 = false; - (*g)->oconflict = false; - (*g)->dimcolor = false; - (*g)->pin = (log_nrec **)Malloc((*g)->kind->numpins * sizeof(log_nrec *)); - (*g)->pinpos = (log_pinposrec *) - Malloc((*g)->kind->numpins * sizeof(log_pinposrec)); - if (attrs != NULL) - copyattrs(&(*g)->attr, attrs, (*g)->kind->numattrs, (*g)->kind->attr); - else - newattrs(&(*g)->attr, (*g)->kind->numattrs, (*g)->kind->attr); - - if (sig != 0) - { - (*g)->sig = sig; - } - else if ((*g)->kind->simtype == simtype_common) - { - *name = '\0'; - i = 1; - while ((*g)->kind->proc[i - 1] != '\0') - { - sprintf(name + strlen(name), "%c", (*g)->kind->proc[i - 1]); - i++; - } - (*g)->sig = getsignal(0, name); - } - else - { - (*g)->sig = 0; - } - (*g)->info = (na_long)0; - (*g)->temp = (na_long)0; - gg.actflag = (attrs != NULL); - calltoolgate(*g, act_newgate); -} - - -static void newgate(log_grec **g, short gt) -{ - newgate2(g, gt, 0, NULL); -} - - -/*================ COPYGATE ====================*/ -/*= =*/ -/*= Make a copy of a gate (unlinked). =*/ -/*= =*/ -/*================================================*/ - -static void copygate(log_grec *old, log_grec **g) -{ - long i, FORLIM; - - newgptr(g); - **g = *old; - if ((*g)->conflict || (*g)->oconflict) - { - (*g)->confnext = gateconflictbase; - gateconflictbase = *g; - } - (*g)->pin = (log_nrec **)Malloc((*g)->kind->numpins * sizeof(log_nrec *)); - FORLIM = (*g)->kind->numpins; - for (i = 0; i < FORLIM; i++) - (*g)->pin[i] = old->pin[i]; - (*g)->pinpos = (log_pinposrec *) - Malloc((*g)->kind->numpins * sizeof(log_pinposrec)); - FORLIM = (*g)->kind->numpins; - for (i = 0; i < FORLIM; i++) - (*g)->pinpos[i] = old->pinpos[i]; - copyattrs(&(*g)->attr, old->attr, (*g)->kind->numattrs, (*g)->kind->attr); - (*g)->info = (na_long)0; - gg.actgate2 = old; - calltoolgate(*g, act_copygate); -} - - -/*================== UNLKGATE ==================*/ -/*= =*/ -/*= Remove a gate from gate list. =*/ -/*= =*/ -/*================================================*/ - -static void unlkgate(log_grec **g) -{ - log_grec *g1; - - g1 = gg.gbase[gg.curpage - 1]; - while (g1 != NULL && g1->next != *g) - g1 = g1->next; - if (g1 == NULL) - gg.gbase[gg.curpage - 1] = (*g)->next; - else - g1->next = (*g)->next; - chpageplace((int)gg.curpage, (*g)->x - (*g)->kind->bbmax, - (*g)->y - (*g)->kind->bbmax, (*g)->x + (*g)->kind->bbmax, - (*g)->y + (*g)->kind->bbmax); -} - - -/*=============== DISPOSEGATE ==================*/ -/*= =*/ -/*= Dispose of a gate. =*/ -/*= =*/ -/*================================================*/ - -static void disposegptr(log_grec **g) -{ - (*g)->next = freegate; - freegate = *g; -} - - -#define rtn "DISPOSEGATE" - -static void disposegate(log_grec **g) -{ - log_grec *g1, *g2; - - if ((*g)->conflict || (*g)->oconflict) - { - g1 = gateconflictbase; - g2 = NULL; - while (g1 != NULL && g1 != *g) - { - g2 = g1; - g1 = g1->confnext; - } - if (g1 == NULL) - report(10, rtn); - else if (g2 == NULL) - gateconflictbase = (*g)->confnext; - else - g2->confnext = (*g)->confnext; + (*gattr)[i].blnk = kattr[i].blnk; + (*gattr)[i].changed = false; } - if (*g == gg.probegate) - gg.probegate = NULL; - calltoolgate(*g, act_disposegate); - disposeattrs(&(*g)->attr, (*g)->kind->numattrs, (*g)->kind->attr); - Free((*g)->pin); - Free((*g)->pinpos); - disposegptr(g); } -#undef rtn - -/*================== NEWLABEL ==================*/ -/*= =*/ -/*= Create a Label. =*/ -/*= =*/ -/*================================================*/ -static void linklabel(log_lrec *l) +static void disposeattrs(log_gattrrec **gattr, short numattrs, log_kattrrec *kattr) { - l->next = gg.lbase[gg.curpage - 1]; - gg.lbase[gg.curpage - 1] = l; - stamp(&gg.labelstamp); -} + short i; + for (i = 0; i < numattrs; i++) + { + switch (kattr[i].dtype) + { -static void newlabel(log_lrec **l) -{ - *l = (log_lrec *)Malloc(sizeof(log_lrec)); - (*l)->temp = (na_long)0; - linklabel(*l); -} + case 'C': + Free((*gattr)[i].UU.c); + break; + case 'A': + strdispose(&(*gattr)[i].UU.sp); + break; + } + } + Free(*gattr); +} -/*================ DISPLABEL ===================*/ -/*= =*/ -/*= Dispose of a text label. =*/ -/*= =*/ -/*================================================*/ -static void unlinklabel(log_lrec *l) +static void copyattrs(log_gattrrec **gattr, log_gattrrec *oldattr, short numattrs, log_kattrrec *kattr) { - log_lrec *l1; + short i; - l1 = gg.lbase[gg.curpage - 1]; - while (l1 != NULL && l1->next != l) - l1 = l1->next; - if (l1 == NULL) - gg.lbase[gg.curpage - 1] = l->next; - else - l1->next = l->next; - chpageplace((int)gg.curpage, l->x, l->y, l->x + l->w, l->y + 2); - stamp(&gg.labelstamp); -} + *gattr = (log_gattrrec *)Malloc(numattrs * gattrrecsize); + for (i = 0; i < numattrs; i++) + { + (*gattr)[i] = oldattr[i]; + switch (kattr[i].dtype) + { + case 'C': + (*gattr)[i].UU.c = (char *)Malloc(kattr[i].prec + 1L); + strcpy((*gattr)[i].UU.c, oldattr[i].UU.c); + break; -static void displabel(log_lrec **l) -{ - unlinklabel(*l); - Free(*l); + case 'A': + (*gattr)[i].UU.sp = strdup(oldattr[i].UU.sp); + break; + } + } } @@ -6583,50 +3107,6 @@ static void setscale(short s) } -/*================== NEWPAGE ===================*/ -/*= =*/ -/*= Switch to a new page. =*/ -/*= =*/ -/*================================================*/ - -static void newpage(short p) -{ - short i; - - garbagecoll(); - for (i = gg.numpages; i < p; i++) - { - xoffp[i] = (origin + across / 2) * gg.scale / log_scale0 - across / 2; - yoffp[i] = (origin + baseline / 2) * gg.scale / log_scale0 - baseline / 2; - gatecount[i] = 0; - gg.gbase[i] = NULL; - gg.sbase[i] = NULL; - gg.hwbase[i] = NULL; - gg.vwbase[i] = NULL; - gg.lbase[i] = NULL; - gg.bbase[i] = NULL; - gg.pagechanged[i] = false; - stamp(&gg.pagestamp[i]); - gg.pageregions[i] = NULL; - curfilename[i] = NULL; - vlsimode[i] = vlsi; - } - if (p != gg.curpage) - { - xoffp[gg.curpage - 1] = gg.xoff; - yoffp[gg.curpage - 1] = gg.yoff; - gg.xoff = xoffp[p - 1]; - gg.yoff = yoffp[p - 1]; - vlsi = vlsimode[p - 1]; - curwcolor = log_wcol_normal; - gg.numpages = P_imax2((long)p, gg.numpages); - gg.curpage = p; - realcurpage = p; - } - while (gg.numpages > gg.curpage && pagenull((int)gg.numpages)) - gg.numpages--; -} - static void setupregion(log_regrec **r, short pagenum) { log_regrec *r2; @@ -7529,442 +4009,28 @@ static void trykbd() if (moving) ch = inkey2(); } while (moving && labs(yoff0) <= baseline - 10); - refrfunc(); - break; - - default: - mp = macrobase; - while (mp != NULL && mp->key != ch) - mp = mp->next; - if (mp != NULL) - assertfunc(mp->name); - break; - } -} - - -static void trykbdscroll() -{ - immedscroll = true; - trykbd(); - immedscroll = false; - scroll(); -} - - -/*================ CLOSERGATE ==================*/ -/*= =*/ -/*= Find which gate (if any) is under cursor. =*/ -/*= Also checks for textual labels. =*/ -/*= =*/ -/*================================================*/ - -static void closergate(short x, short y) -{ - if (gg.textinvisible) - gg.nearlabel = NULL; - else { - gg.nearlabel = gg.lbase[gg.curpage - 1]; - while (gg.nearlabel != NULL && - (x < gg.nearlabel->x || - x > gg.nearlabel->x + m_strwidth(logfont_lfont, - gg.nearlabel->name) / gg.scale || - y < gg.nearlabel->y || y > gg.nearlabel->y + 2)) { - gg.nearlabel = gg.nearlabel->next; - } - } - if (gg.nearlabel != NULL) { - gg.nearbox = NULL; - gg.neargate = NULL; - return; - } - if (!gg.textinvisible) { - gg.nearbox = gg.bbase[gg.curpage - 1]; - while (gg.nearbox != NULL && - ((x != gg.nearbox->x1 && x != gg.nearbox->x2 && - y != gg.nearbox->y1 && - y != gg.nearbox->y2) || x < gg.nearbox->x1 || - x > gg.nearbox->x2 || y < gg.nearbox->y1 || y > gg.nearbox->y2)) - gg.nearbox = gg.nearbox->next; - } else - gg.nearbox = NULL; - if (gg.nearbox != NULL) - { - gg.neargate = NULL; - return; - } - gg.neargate = gg.gbase[gg.curpage - 1]; - while (gg.neargate != NULL && !insidegate(gg.neargate, x, y)) - gg.neargate = gg.neargate->next; -} - -/*================ CLOSERWIRE ==================*/ -/*= =*/ -/*= Find which wire(s) are under the cursor, =*/ -/*= if any. =*/ -/*= =*/ -/*================================================*/ - -static void closerwire(short x, short y) -{ - if (gg.invisible || gg.showconflicts) - { - gg.nearhw = NULL; - gg.nearvw = NULL; - return; - } - gg.nearhw = gg.hwbase[gg.curpage - 1]; - while (gg.nearhw != NULL && - (gg.nearhw->y != y || gg.nearhw->x1 > x || gg.nearhw->x2 < x)) - gg.nearhw = gg.nearhw->next; - gg.nearvw = gg.vwbase[gg.curpage - 1]; - while (gg.nearvw != NULL && - (gg.nearvw->x != x || gg.nearvw->y1 > y || gg.nearvw->y2 < y)) - gg.nearvw = gg.nearvw->next; -} - -/*assumes hw <> nil if hw2 <> nil*/ - -#define rtn "ADDSOLDER" - - -/*================= ADDSOLDER ==================*/ -/*= =*/ -/*= Add a solder point between two wires. =*/ -/*= =*/ -/*================================================*/ - -static void addsolder(short x, short y, log_hwrec *hw, log_hwrec *hw2, log_vwrec *vw, log_vwrec *vw2) -{ - log_srec *s; - log_nrec *n; - - s = gg.sbase[gg.curpage - 1]; - while (s != NULL && (s->x != x || s->y != y)) - s = s->next; - if (s == NULL) { - newsolder(&s); - s->x = x; - s->y = y; - chpageplace((int)gg.curpage, x, y, x, y); - s->hwire = NULL; - s->hwire2 = NULL; - s->vwire = NULL; - s->vwire2 = NULL; - n = NULL; - if (hw != NULL) - n = hw->node; - if (vw != NULL && n == NULL) - n = vw->node; - hidecursor(); - if (gg.glowmode && n != NULL) - drawsolderc(x, y, (int)glowcol(n, (long)gg.color.solder)); - else - drawsolderc(x, y, gg.color.solder); - hidecursor(); - } - if (hw != NULL && hw != s->hwire && hw != s->hwire2) - { - if (s->hwire == NULL) - s->hwire = hw; - else if (s->hwire2 == NULL) - s->hwire2 = hw2; - else - report(1, rtn); - } - if (hw2 != NULL && hw2 != s->hwire && hw2 != s->hwire2) - { - if (s->hwire2 == NULL) - s->hwire2 = hw2; - else - report(2, rtn); - } - if (vw != NULL && vw != s->vwire && vw != s->vwire2) - { - if (s->vwire == NULL) - s->vwire = vw; - else if (s->vwire2 == NULL) - s->vwire2 = vw; - else - report(3, rtn); - } - if (vw2 != NULL && vw2 != s->vwire && vw2 != s->vwire2) - { - if (s->vwire2 == NULL) - s->vwire2 = vw2; - else - report(4, rtn); - } - if (gg.traceflag) - fprintf(tracefile, "Add solder %ld\n", (long)s); -} - -#undef rtn - - -/*================= FINDSOLDER =================*/ -/*= =*/ -/*= Find a solder point at specified position. =*/ -/*= =*/ -/*================================================*/ - -static log_srec *findsolder(short x, short y) -{ - log_srec *s; - - s = gg.sbase[gg.curpage - 1]; - while (s != NULL && (s->x != x || s->y != y)) - s = s->next; - return s; -} - - -/*================= ADDSOLDERT =================*/ -/*= =*/ -/*= Add a solder point at a T-intersection of =*/ -/*= two wires. =*/ -/*= =*/ -/*================================================*/ - -static void addsoldert(log_hwrec *hw, log_vwrec *vw) -{ - if (hw->x1 == vw->x && hw->y != vw->y1 && hw->y != vw->y2) - { - addsolder(hw->x1, hw->y, hw, NULL, vw, NULL); - return; - } - if (hw->x2 == vw->x && hw->y != vw->y1 && hw->y != vw->y2) - { - addsolder(hw->x2, hw->y, hw, NULL, vw, NULL); - return; - } - if (hw->y == vw->y1 && hw->x1 != vw->x && hw->x2 != vw->x) - addsolder(vw->x, vw->y1, hw, NULL, vw, NULL); - else if (hw->y == vw->y2 && hw->x1 != vw->x && hw->x2 != vw->x) - addsolder(vw->x, vw->y2, hw, NULL, vw, NULL); -} - - -/*================== CHGHW/VW ==================*/ -/*= =*/ -/*= Used for deleting wires (see DELHWIRE). =*/ -/*= =*/ -/*================================================*/ - -static void chggate (log_grec *g, int i, log_nrec *oldnode, log_nrec *n); - -static void chgvw (log_vwrec *vw, log_nrec *oldnode, log_nrec *n); - - -#define rtn "CHGHW" - - -static void chghw(log_hwrec *hw, log_nrec *oldnode, log_nrec *n) -{ - log_vwrec *vw; - log_hwrec *hw1; - log_grec *g; - log_srec *s; - short i, px, FORLIM; - - if (gg.traceflag) - fprintf(tracefile, "Change hwire %ld to node %ld\n", (long)hw, (long)n); - switchnode(&hw->node, n); - g = gg.gbase[gg.curpage - 1]; - while (g != NULL) - { - if (abs(g->y - hw->y) <= g->kind->bbmax && - P_ibetweenm((long)hw->x1, (long)g->x, (long)hw->x2, - (long)g->kind->bbmax)) - { - FORLIM = g->kind->numpins; - for (i = 1; i <= FORLIM; i++) - { - px = g->pinpos[i - 1].x; - if (hw->x1 <= px && px <= hw->x2 && g->pinpos[i - 1].y == hw->y && - g->pin[i - 1] == oldnode) - chggate(g, i, oldnode, n); - } - } - g = g->next; - } - vw = gg.vwbase[gg.curpage - 1]; - while (vw != NULL) - { - if (hw->x1 <= vw->x && vw->x <= hw->x2 && vw->y1 <= hw->y && - hw->y <= vw->y2 && vw->node == oldnode) - { - if ((hw->x1 == vw->x || hw->x2 == vw->x || vw->y1 == hw->y || - vw->y2 == hw->y) && - (hw->wcolr == vw->wcolr || hw->wcolr == log_wcol_blue || - vw->wcolr == log_wcol_blue)) - chgvw(vw, oldnode, n); - else - { /*vlsi only*/ - s = gg.sbase[gg.curpage - 1]; - while (s != NULL && (s->x != vw->x || s->y != hw->y)) - s = s->next; - if (s != NULL) - chgvw(vw, oldnode, n); - } - } - vw = vw->next; - } - hw1 = gg.hwbase[gg.curpage - 1]; - while (hw1 != NULL && vlsi) - { - if (hw->y == hw1->y && (hw->x1 == hw1->x2 || hw->x2 == hw1->x1) && - (hw->wcolr == log_wcol_blue || hw1->wcolr == log_wcol_blue) && - hw1->node == oldnode) - chghw(hw1, oldnode, n); - hw1 = hw1->next; - } -} - -#undef rtn - - -#define rtn "CHGVW" - - -static void chgvw(log_vwrec *vw, log_nrec *oldnode, log_nrec *n) -{ - log_hwrec *hw; - log_vwrec *vw1; - log_grec *g; - log_srec *s; - short i, py, FORLIM; - - if (gg.traceflag) - fprintf(tracefile, "Change vwire %ld to node %ld\n", (long)vw, (long)n); - switchnode(&vw->node, n); - g = gg.gbase[gg.curpage - 1]; - while (g != NULL) - { - if (abs(g->x - vw->x) <= g->kind->bbmax && - P_ibetweenm((long)vw->y1, (long)g->y, (long)vw->y2, - (long)g->kind->bbmax)) - { - FORLIM = g->kind->numpins; - for (i = 1; i <= FORLIM; i++) - { - py = g->pinpos[i - 1].y; - if (vw->y1 <= py && py <= vw->y2 && g->pinpos[i - 1].x == vw->x && - g->pin[i - 1] == oldnode) - chggate(g, i, oldnode, n); - } - } - g = g->next; - } - hw = gg.hwbase[gg.curpage - 1]; - while (hw != NULL) - { - if (hw->x1 <= vw->x && vw->x <= hw->x2 && vw->y1 <= hw->y && - hw->y <= vw->y2 && hw->node == oldnode) { - if (hw->x1 == vw->x || hw->x2 == vw->x || vw->y1 == hw->y || - vw->y2 == hw->y) - chghw(hw, oldnode, n); - else - { - s = gg.sbase[gg.curpage - 1]; - while (s != NULL && (s->x != vw->x || s->y != hw->y)) - s = s->next; - if (s != NULL) - chghw(hw, oldnode, n); - } - } - hw = hw->next; - } - vw1 = gg.vwbase[gg.curpage - 1]; - while (vw1 != NULL && vlsi) - { - if (vw->x == vw1->x && (vw->y1 == vw1->y2 || vw->y2 == vw1->y1) && - (vw->wcolr == log_wcol_blue || vw1->wcolr == log_wcol_blue) && - vw1->node == oldnode) - chgvw(vw1, oldnode, n); - vw1 = vw1->next; + refrfunc(); + break; + + default: + mp = macrobase; + while (mp != NULL && mp->key != ch) + mp = mp->next; + if (mp != NULL) + assertfunc(mp->name); + break; } } -#undef rtn - -#define rtn "CHGGATE" - -static void chggate(log_grec *g, int i, log_nrec *oldnode, log_nrec *n) +static void trykbdscroll() { - log_hwrec *hw; - log_vwrec *vw; - log_grec *g1; - short j, k, savepg, pg, x, y, FORLIM; - - if (gg.traceflag) - fprintf(tracefile, "Change gate %ld pin %d to node %ld\n", - (long)g, i, (long)n); - j = i; - do - { - if (g->pin[j - 1] == oldnode) - { - switchnode(&g->pin[j - 1], n); - /* if (j <> i) then */ - /*unsafe optimization*/ - x = g->pinpos[j - 1].x; - y = g->pinpos[j - 1].y; - hw = gg.hwbase[gg.curpage - 1]; - while (hw != NULL) - { - if (hw->x1 <= x && x <= hw->x2 && hw->y == y && hw->node == oldnode) - chghw(hw, oldnode, n); - hw = hw->next; - } - vw = gg.vwbase[gg.curpage - 1]; - while (vw != NULL) - { - if (vw->y1 <= y && y <= vw->y2 && vw->x == x && vw->node == oldnode) - chgvw(vw, oldnode, n); - vw = vw->next; - } - g1 = gg.gbase[gg.curpage - 1]; - while (g1 != NULL) - { - if (g1 != g && P_imax2((long)abs(g1->x - x), (long)abs(g1->y - y)) <= - g1->kind->bbmax) { - FORLIM = g1->kind->numpins; - for (k = 1; k <= FORLIM; k++) { - if (x == g1->pinpos[k - 1].x && y == g1->pinpos[k - 1].y && - g1->pin[k - 1] == oldnode) - chggate(g1, k, oldnode, n); - } - } - g1 = g1->next; - } - } - j = g->kind->pin[j - 1].c; - } while (j != i && j != 0); - if (i != 1 || g->kind->simtype != simtype_common || g->sig == 0 || - gg.signaltab[g->sig - 1].np != oldnode) - return; - switchnode(&gg.signaltab[g->sig - 1].np, n); - savepg = gg.curpage; - FORLIM = gg.numpages; - for (pg = 1; pg <= FORLIM; pg++) - { - gg.curpage = pg; - g1 = gg.gbase[gg.curpage - 1]; - while (g1 != NULL) - { - if (g1->kind->simtype == simtype_common && g1->sig == g->sig && - g1->pin[0] == oldnode) - chggate(g1, 1, oldnode, n); - g1 = g1->next; - } - } - gg.curpage = savepg; + immedscroll = true; + trykbd(); + immedscroll = false; + scroll(); } -#undef rtn - /* Local variables for wantsolder: */ struct LOC_wantsolder { @@ -7998,33 +4064,6 @@ static void markcolor(hw, LINK) } - - -/*================= DELHWIRE ===================*/ -/*================= DELVWIRE ===================*/ -/*= =*/ -/*= Delete a horizontal or vertical wire. =*/ -/*= =*/ -/*================================================*/ - -static int wantsolder(s) - log_srec *s; -{ - struct LOC_wantsolder V; - - V.hasred = false; - V.hasgreen = false; - V.hasyellow = false; - V.hasblue = false; - markcolor(&s->hwire, &V); - markcolor(&s->hwire2, &V); - markcolor((log_hwrec **)(&s->vwire), &V); - markcolor((log_hwrec **)(&s->vwire2), &V); - return (V.hasblue && (V.hasgreen || V.hasyellow || V.hasred)); -} - - - static void delgetnode(save, old, n) log_nrec **save, **old, **n; { @@ -8039,276 +4078,6 @@ else } -static void delhwire(hw) - log_hwrec *hw; -{ - log_vwrec *vw; - log_hwrec *hw1; - log_srec *s, *s1; - log_nrec *oldnode, *n, *savenode; - log_grec *g; - short i, x, y, FORLIM; - - if (gg.traceflag) - fprintf(tracefile, "Delete hwire %ld\n", (long)hw); - working(); - clipon(); - m_color((long)gg.color.backgr); - hline(hw->x1, hw->x2, hw->y); - oldnode = hw->node; - stamp(&oldnode->simtype->netstamp); - switchnode(&hw->node, NULL); - savenode = oldnode; - s = gg.sbase[gg.curpage - 1]; - while (s != NULL) { - s1 = s->next; - if (s->hwire == hw || s->hwire2 == hw) { - if (s->hwire == hw) - s->hwire = s->hwire2; - s->hwire2 = NULL; - if (!wantsolder(s)) { - drawsolderc(s->x, s->y, gg.color.backgr); - dispsolder(&s); - } else { - if (gg.traceflag) - fprintf(tracefile, "DELHW keeping solder %ld\n", (long)s); - } - } - s = s1; - } - vw = gg.vwbase[gg.curpage - 1]; - while (vw != NULL) { - if (hw->x1 <= vw->x && vw->x <= hw->x2 && vw->y1 <= hw->y && - hw->y <= vw->y2 && vw->node == oldnode) { - delgetnode(&savenode, &oldnode, &n); - if (n != oldnode) - chgvw(vw, oldnode, n); - } - vw = vw->next; - } - hw1 = gg.hwbase[gg.curpage - 1]; - while (hw1 != NULL && vlsi) { - if (hw->y == hw1->y && (hw1->x1 == hw->x2 || hw1->x2 == hw->x1) && - hw1->node == oldnode) { - delgetnode(&savenode, &oldnode, &n); - if (n != oldnode) - chghw(hw1, oldnode, n); - } - hw1 = hw1->next; - } - g = gg.gbase[gg.curpage - 1]; - while (g != NULL) { - if (abs(g->y - hw->y) <= g->kind->bbmax && - P_ibetweenm((long)hw->x1, (long)g->x, (long)hw->x2, - (long)g->kind->bbmax)) { - FORLIM = g->kind->numpins; - for (i = 1; i <= FORLIM; i++) { - if (g->pin[i - 1] == oldnode) { - x = g->pinpos[i - 1].x; - y = g->pinpos[i - 1].y; - if (hw->x1 <= x && x <= hw->x2 && y == hw->y) { - delgetnode(&savenode, &oldnode, &n); - if (n != oldnode) - chggate(g, i, oldnode, n); - } - } - } - } - g = g->next; - } - disphw(&hw); - clipoff(); -} - - -static void delvwire(vw) - log_vwrec *vw; -{ - log_hwrec *hw; - log_vwrec *vw1; - log_srec *s, *s1; - log_nrec *oldnode, *n, *savenode; - log_grec *g; - short i, x, y, FORLIM; - - if (gg.traceflag) - fprintf(tracefile, "Delete vwire %ld\n", (long)vw); - working(); - clipon(); - m_color((long)gg.color.backgr); - vline(vw->x, vw->y1, vw->y2); - oldnode = vw->node; - stamp(&oldnode->simtype->netstamp); - switchnode(&vw->node, NULL); - savenode = oldnode; - s = gg.sbase[gg.curpage - 1]; - while (s != NULL) { - s1 = s->next; - if (s->vwire == vw || s->vwire2 == vw) { - if (s->vwire == vw) - s->vwire = s->vwire2; - s->vwire2 = NULL; - if (!wantsolder(s)) { - drawsolderc(s->x, s->y, gg.color.backgr); - dispsolder(&s); - } else { - if (gg.traceflag) - fprintf(tracefile, "DELVW keeping solder %ld\n", (long)s); - } - } - s = s1; - } - hw = gg.hwbase[gg.curpage - 1]; - while (hw != NULL) { - if (hw->x1 <= vw->x && vw->x <= hw->x2 && vw->y1 <= hw->y && - hw->y <= vw->y2 && hw->node == oldnode) { - delgetnode(&savenode, &oldnode, &n); - if (n != oldnode) - chghw(hw, oldnode, n); - } - hw = hw->next; - } - vw1 = gg.vwbase[gg.curpage - 1]; - while (vw1 != NULL && vlsi) { - if (vw->x == vw1->x && (vw1->y1 == vw->y2 || vw1->y2 == vw->y1) && - vw1->node == oldnode) { - delgetnode(&savenode, &oldnode, &n); - if (n != oldnode) - chgvw(vw1, oldnode, n); - } - vw1 = vw1->next; - } - g = gg.gbase[gg.curpage - 1]; - while (g != NULL) { - if (abs(g->x - vw->x) <= g->kind->bbmax && - P_ibetweenm((long)vw->y1, (long)g->y, (long)vw->y2, - (long)g->kind->bbmax)) { - FORLIM = g->kind->numpins; - for (i = 1; i <= FORLIM; i++) { - if (g->pin[i - 1] == oldnode) { - x = g->pinpos[i - 1].x; - y = g->pinpos[i - 1].y; - if (vw->y1 <= y && y <= vw->y2 && x == vw->x) { - delgetnode(&savenode, &oldnode, &n); - if (n != oldnode) - chggate(g, i, oldnode, n); - } - } - } - } - g = g->next; - } - vw1 = vw; - dispvw(&vw); - clipoff(); -} - - -static void chggatepin(g, i, oldnode, savenode) - log_grec *g; - short i; - log_nrec **oldnode, **savenode; -{ - log_nrec *n; - log_hwrec *hw; - log_vwrec *vw; - log_grec *g1; - short j, x, y, FORLIM; - - if (gg.traceflag) - fprintf(tracefile, "Change gate %ld pin %d from node %ld\n", - (long)g, i, (long)(*oldnode)); - x = g->pinpos[i - 1].x; - y = g->pinpos[i - 1].y; - hw = gg.hwbase[gg.curpage - 1]; - while (hw != NULL) { - if (hw->x1 <= x && x <= hw->x2 && hw->y == y && hw->node == *oldnode) { - delgetnode(savenode, oldnode, &n); - if (n != *oldnode) - chghw(hw, *oldnode, n); - } - hw = hw->next; - } - vw = gg.vwbase[gg.curpage - 1]; - while (vw != NULL) { - if (vw->y1 <= y && y <= vw->y2 && vw->x == x && vw->node == *oldnode) { - delgetnode(savenode, oldnode, &n); - if (n != *oldnode) - chgvw(vw, *oldnode, n); - } - vw = vw->next; - } - g1 = gg.gbase[gg.curpage - 1]; - while (g1 != NULL) { - if (g1 != g && - P_imax2((long)abs(g1->x - x), (long)abs(g1->y - y)) <= g1->kind->bbmax) { - FORLIM = g1->kind->numpins; - for (j = 1; j <= FORLIM; j++) { - if (x == g1->pinpos[j - 1].x && y == g1->pinpos[j - 1].y && - g1->pin[j - 1] == *oldnode) { - delgetnode(savenode, oldnode, &n); - if (n != *oldnode) - chggate(g1, j, *oldnode, n); - } - } - } - g1 = g1->next; - } -} - - -static void disconnectgate(g) - log_grec *g; -{ - log_nrec *savenode; - short i, j; - log_nrec **oldnode; - long done[log_maxpins / 32 + 2]; - short FORLIM; - long SET[9]; - - if (gg.traceflag) - fprintf(tracefile, "Disconnect gate %ld\n", (long)g); - stamp(&g->kind->simtype->netstamp); - calltoolgate(g, act_disconnectgate); - oldnode = (log_nrec **)Malloc(g->kind->numpins * sizeof(log_nrec *)); - FORLIM = g->kind->numpins; - for (i = 0; i < FORLIM; i++) { - oldnode[i] = g->pin[i]; - stamp(&oldnode[i]->simtype->netstamp); - switchnode(&g->pin[i], NULL); - } - P_expset(done, 0L); - FORLIM = g->kind->numpins; - for (i = 1; i <= FORLIM; i++) { - if (!P_inset(i, done)) { - j = i; - if (i == 1 && g->kind->simtype == simtype_common && g->sig != 0) - savenode = NULL; - else - savenode = oldnode[i - 1]; - do { - chggatepin(g, j, &oldnode[i - 1], &savenode); - P_addset(done, j); - j = g->kind->pin[j - 1].c; - } while (j != i && j != 0); - } - } - unlkgate(&g); -} - - -static void delgate(g) - log_grec *g; -{ - clipon(); - eragate(g); - disconnectgate(g); - disposegate(&g); - clipoff(); -} - - static void confirmsimtype(n) log_nrec *n; { @@ -8626,9 +4395,6 @@ static int trycombinenodes(n1, n2) } - - - static void fryhwire(hw) log_hwrec *hw; { @@ -8769,7 +4535,6 @@ static void dispblobs(blbase) #define rtn "ADDHWIRE" -/*================== ADDHWIRE ==================*/ /*================== ADDVWIRE ==================*/ /*= =*/ /*= ADDHWIRE: =*/ @@ -9815,9 +5580,6 @@ static void yardstickcommand() } - - - /*================= ADDGATE1 ===================*/ /*= =*/ /*= Add a gate to the circuit. Initialize all =*/ @@ -9867,7 +5629,6 @@ static void addgate2(x, y, gtype, sig, attrs) } - static void addgate1(x, y, gtype) short x, y, gtype; { @@ -9875,7 +5636,6 @@ static void addgate1(x, y, gtype) } - static void uaddgate(x, y, gtype) short x, y, gtype; { @@ -9906,9 +5666,6 @@ static void uaddgate(x, y, gtype) - - - /*================== ADDGATE ===================*/ /*= =*/ /*= Move a gate into position, then add to =*/ @@ -11695,9 +7452,6 @@ static void closevert() } - - - static void centercommand() { log_grec *g; @@ -11758,55 +7512,6 @@ static void centercommand() } -/*================= SHOWCATALOG ================*/ -/*= =*/ -/*= Switch screen to catalog (TRUE) or circuit =*/ -/*= (FALSE). =*/ -/*= =*/ -/*================================================*/ - -static void showcatalog() -{ - short i; - catboxrec *cb; - short x1, y1, x2, y2, FORLIM; - - clearscreen(); - gg.showpage = log_page_cat; - FORLIM = maxkinds; - for (i = 1; i <= FORLIM; i++) { - if (kind[i - 1] != NULL) { - /* p2c: log.text, line 11731: - * Note: Using % for possibly-negative arguments [317] */ - udrawgatec((int)(((i - 1) % catwidth * 2 + 1) * gridcen), - (int)(((i - 1) / catwidth * 2 + 1) * gridcen), i, - gg.color.catgate); - } - } - cb = catboxes; - while (cb != NULL) { - x1 = (cb->pos - 1) % catwidth * gridcen * 2; - /* p2c: log.text, line 11738: - * Note: Using % for possibly-negative arguments [317] */ - y1 = (cb->pos - 1) / catwidth * gridcen * 2; - x2 = ((cb->pos + cb->count - 2) % catwidth + 1) * gridcen * 2; - /* p2c: log.text, line 11740: - * Note: Using % for possibly-negative arguments [317] */ - y2 = ((cb->pos + cb->count - 2) / catwidth + 1) * gridcen * 2; - m_color((long)catboxcolor); - m_linestyle(2L); - m_drawline((long)x1, (long)y1, (long)x2, (long)y1); - m_linestyle(2L); - m_drawline((long)x1, (long)y2, (long)x2, (long)y2); - m_linestyle(2L); - m_drawline((long)x1, (long)y1, (long)x1, (long)y2); - m_linestyle(2L); - m_drawline((long)x2, (long)y1, (long)x2, (long)y2); - m_linestyle(0L); - cb = cb->next; - } -} - /*================ COMPARESTR ==================*/ /*= =*/ /*= Compare string S with template string T. =*/ @@ -12755,12 +8460,6 @@ static void gatedefinitioncommand() } - - - - - - /*================ LISTLIBRARY =================*/ /*= =*/ /*= List the gates available in the library. =*/ @@ -14575,15 +10274,6 @@ const fliparr flips = { }; - - - - - - - - - static short doflip(rot, mode) short rot, mode; { @@ -14591,8 +10281,6 @@ static short doflip(rot, mode) } - - /*================== FLIPGATE ==================*/ /*= =*/ /*= Flip a gate in the circuit. =*/ @@ -21115,10 +16803,6 @@ static void readcnf(char *fn_, struct LOC_initialize *LINK) /*obsolete*/ } - - - - /*================== INITIALIZE ================*/ /*= =*/ /*= Initialize all variables. Read basic gates =*/ @@ -21757,8 +17441,6 @@ static void shownews() } - - /*================ MAIN PROGRAM ================*/ /*= =*/ /*= Initialize. =*/ diff --git a/log/src/page.c b/log/src/page.c new file mode 100644 index 0000000000000000000000000000000000000000..0a93e3f2b43bba379c8e28f1cccd86050ed85b2c --- /dev/null +++ b/log/src/page.c @@ -0,0 +1,110 @@ + +#include <p2c/p2c.h> + +static void chpage(short pg) +{ + log_regrec *r; + + stamp(&gg.pagestamp[pg - 1]); + gg.pagechanged[pg - 1] = true; + r = gg.pageregions[pg - 1]; + while (r != NULL) { + stamp(&r->regstamp); + r = r->next; + } +} + + +static void chpageplace(short pg, short x1, short y1, short x2, short y2) +{ + log_regrec *r; + + stamp(&gg.pagestamp[pg - 1]); + gg.pagechanged[pg - 1] = true; + r = gg.pageregions[pg - 1]; + if (r == NULL) + return; + sortshints(&x1, &x2); + sortshints(&y1, &y2); + while (r != NULL) + { + if (r->x1 <= x2 && x1 <= r->x2 && r->y1 <= y2 && y1 <= r->y2) + stamp(&r->regstamp); + r = r->next; + } +} + + +static int pageempty(int pg) +{ + return (gg.gbase[pg - 1] == NULL && gg.hwbase[pg - 1] == NULL && + gg.vwbase[pg - 1] == NULL && gg.bbase[pg - 1] == NULL && + gg.lbase[pg - 1] == NULL); +} + + +static int pagenull(short pg) +{ + return (pageempty(pg) && gg.pageregions[pg - 1] == NULL); +} + +static int pagechanged(short pg) +{ + return (gg.pagechanged[pg - 1] && !pageempty(pg)); +} + + +static int anychanged() +{ + short i; + + i = 1; + while (i <= gg.numpages && !pagechanged(i)) + i++; + return (i <= gg.numpages); +} + +/*================== NEWPAGE ===================*/ +/*= =*/ +/*= Switch to a new page. =*/ +/*= =*/ +/*================================================*/ + +static void newpage(short p) +{ + short i; + + garbagecoll(); + for (i = gg.numpages; i < p; i++) + { + xoffp[i] = (origin + across / 2) * gg.scale / log_scale0 - across / 2; + yoffp[i] = (origin + baseline / 2) * gg.scale / log_scale0 - baseline / 2; + gatecount[i] = 0; + gg.gbase[i] = NULL; + gg.sbase[i] = NULL; + gg.hwbase[i] = NULL; + gg.vwbase[i] = NULL; + gg.lbase[i] = NULL; + gg.bbase[i] = NULL; + gg.pagechanged[i] = false; + stamp(&gg.pagestamp[i]); + gg.pageregions[i] = NULL; + curfilename[i] = NULL; + vlsimode[i] = vlsi; + } + if (p != gg.curpage) + { + xoffp[gg.curpage - 1] = gg.xoff; + yoffp[gg.curpage - 1] = gg.yoff; + gg.xoff = xoffp[p - 1]; + gg.yoff = yoffp[p - 1]; + vlsi = vlsimode[p - 1]; + curwcolor = log_wcol_normal; + gg.numpages = P_imax2((long)p, gg.numpages); + gg.curpage = p; + realcurpage = p; + } + while (gg.numpages > gg.curpage && pagenull((int)gg.numpages)) + gg.numpages--; +} + diff --git a/log/src/screen.c b/log/src/screen.c new file mode 100644 index 0000000000000000000000000000000000000000..177e83866d28014e0cec1b8a49d5257c387c0aab --- /dev/null +++ b/log/src/screen.c @@ -0,0 +1,2426 @@ +/* "LOG", the circuit editing and simulation system, + "DigLOG", the digital simulator for LOG. + Copyright (C) 1985, 1990 David Gillespie. + Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125. + + "AnaLOG", the analog simulator for LOG. + Copyright (C) 1985, 1990 John Lazzaro. + Author's address: lazzaro@csvax.caltech.edu; 256-80 Caltech. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation (any version). + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + Logic Simulator Version 4.1 + For HP 9836C + + Copyright (c) 1985 + + David Gillespie + */ + +#include <p2c/p2c.h> + + +/*================= INITSCREEN =================*/ +/*= =*/ +/*= Initialize color graphics, graphics tablet, =*/ +/*= low-level flags & variables =*/ +/*= =*/ +/*================================================*/ + +static void initcolormap() +{ + m_setcolor((long)log_gray, 4L, 4L, 4L); + m_setcolor((long)log_red, 15L, 0L, 0L); + m_setcolor((long)log_green, 0L, 15L, 0L); + m_setcolor((long)log_yellow, 15L, 15L, 0L); + if (eightcolors) { + m_setcolor((long)log_cred8, 15L, 0L, 0L); + m_setcolor((long)log_black8, 0L, 0L, 0L); + } else { + m_setcolor((long)log_mred, 11L, 0L, 0L); + m_setcolor((long)log_orange, 15L, 9L, 0L); + } + m_setcolor((long)log_cyan, 0L, 15L, 15L); + m_setcolor((long)log_white, 15L, 15L, 15L); + m_setcolor((long)log_black, 0L, 0L, 0L); + m_setcolor((long)log_pink, 15L, 9L, 9L); + m_setcolor((long)log_dyellow, 12L, 12L, 0L); + m_setcolor((long)log_xgreen, 0L, 13L, 0L); + m_setcolor((long)log_dcyan, 0L, 10L, 10L); + m_setcolor((long)log_dred, 8L, 0L, 0L); + m_setcolor((long)log_lgray, 10L, 10L, 10L); + m_setcolor((long)log_cred, 15L, 0L, 0L); + m_vseecolors(0L, 16L, rcolormap, gcolormap, bcolormap); +} + + +static void fixcolormap() +{ + m_vsetcolors(0L, 16L, rcolormap, gcolormap, bcolormap); + recolor_log_cursors(gg.color.cursor, true); +} + + + +static void initscreen() +{ + m_init_screen(); + m_upside_down(); + m_setlinestyle(1L, 0xf0f0L); + m_setlinestyle(2L, 0xaaaaL); + m_setfont(logfont_lfont); + init_X_screen(); + onescreen = nc_alphashared(); + eightcolors = (m_maxcolor <= 7); + + txacross = nc_curWindow->width - 1; + txdown = nc_curWindow->height - 1; + across = m_across; + down = m_down; + baseline = down - 53; /* Position of baseline on screen */ + line1 = down - 43; /* Position of first text line in menu */ + line2 = down - 23; /* Position of second text line in menu */ + histdown = down - 26; + histdivsacross = (double)(across - histleft) / histdivision; + histvalrange = (double)histdown / histdivision * 5; + kindgroupsize = (across - 160) / kindgroupspacing; + kindgroupleft = (across - kindgroupsize * kindgroupspacing) / 2; + kindgroupright = kindgroupleft + kindgroupsize * kindgroupspacing; + kindgroupstart = kindgroupleft + kindgroupspacing / 2; + kindgroupbase = (baseline + down) / 2; + + printf("\200\210"); + SETRUNLIGHT(' '); + + cursorflag = false; + gg.stillnear = true; +} + + +static void initscreen2() +{ + initscreen(); + m_clear(); + m_graphics_on(); +} + +/*================== NOBLINK ===================*/ +/*= =*/ +/*= Turn off the stupid blinking Alpha cursor. =*/ +/*= =*/ +/*================================================*/ + +static void noblink() +{ + nc_cursXY(-1, -1); + /* oldx := xpos; +oldy := ypos; +xpos := -1; +ypos := -1; +call(updatecursorhook); +xpos := oldx; +ypos := oldy; */ +} + + +static void clearalpha() +{ + if (!onescreen) + { + printf("\f"); + noblink(); + m_alpha_off(); + } + nk_gotoxy(0, 0); +} + + +static void showalpha() +{ + m_graphics_off(); + m_alpha_on(); +} + +/*=================== LINE =====================*/ +/*= =*/ +/*= Draw a line in grid coordinates. =*/ +/*= =*/ +/*================================================*/ + +static void line(short x1, short y1, short x2, short y2) +{ + m_drawline(x1 * gg.scale - gg.xoff, y1 * gg.scale - gg.yoff, + x2 * gg.scale - gg.xoff, y2 * gg.scale - gg.yoff); +} + + +/*=================== HLINE ====================*/ +/*= =*/ +/*= Draw a horizontal line in grid coordinates. =*/ +/*= =*/ +/*= =*/ +/*================================================*/ + +static void hline(short x1, short x2, short y) +{ + short yy; + + yy = y * gg.scale - gg.yoff; + m_drawline(x1 * gg.scale - gg.xoff, (long)yy, x2 * gg.scale - gg.xoff, (long)yy); +} + + +/*=================== VLINE ====================*/ +/*= =*/ +/*= Draw a vertical line in grid coordinates. =*/ +/*= =*/ +/*= =*/ +/*================================================*/ + +static void vline(short x, short y1, short y2) +{ + short xx; + + xx = x * gg.scale - gg.xoff; + m_drawline((long)xx, y1 * gg.scale - gg.yoff, (long)xx, + y2 * gg.scale - gg.yoff); +} + + +/*=================== POINT ====================*/ +/*= =*/ +/*= Draw a point in grid coordinates. =*/ +/*= =*/ +/*================================================*/ + +static void point(short x, short y) +{ + m_drawpoint(x * gg.scale - gg.xoff, y * gg.scale - gg.yoff); +} + + +/*=================== RECT =====================*/ +/*= =*/ +/*= Draw a rectangle in grid coordinates. =*/ +/*= =*/ +/*================================================*/ + +static void rect(short x1, short y1, short x2, short y2) +{ + m_drawrect(x1 * gg.scale - gg.xoff, y1 * gg.scale - gg.yoff, + x2 * gg.scale - gg.xoff, y2 * gg.scale - gg.yoff); +} + +/*==================== BOX =====================*/ +/*= =*/ +/*= Draw a filled rectangle in grid coords. =*/ +/*= =*/ +/*================================================*/ + +static void box(short x1, short y1, short x2, short y2) +{ + m_fillrect(x1 * gg.scale - gg.xoff, y1 * gg.scale - gg.yoff, + x2 * gg.scale - gg.xoff, y2 * gg.scale - gg.yoff); +} + +/*================= DRAWSTR2 ===================*/ +/*= =*/ +/*= Draw a text string. =*/ +/*= =*/ +/*================================================*/ + +static void drawstr2(short x, short y, char *s) +{ + long save; + + if (m_curcolor() < 16) + { + save = m_curcolor(); + m_color((long)gg.color.backgr); + m_fillrect(x - 1L, y - 2L, x + m_strwidth(logfont_lfont, s), y + 9L); + m_color(save); + } + m_move((long)x, (long)y); + m_displaytext(s); +} + + +static void rightstr2(short x, short y, char *s) +{ + long save; + + if (m_curcolor() < 16) + { + save = m_curcolor(); + m_color((long)gg.color.backgr); + m_fillrect(x + m_strwidth(logfont_lfont, s) - 1, y - 2L, x + 1L, y + 9L); + m_color(save); + } + m_rightstr((long)x, (long)y, logfont_lfont, s); +} + + +static void centerstr2(short x, short y, char *s) +{ + short w; + long save; + + if (m_curcolor() < 16) + { + save = m_curcolor(); + m_color((long)gg.color.backgr); + w = m_strwidth(logfont_lfont, s) / 2 + 2; + m_fillrect((long)(x - w), y - 2L, (long)(x + w), y + 9L); + m_color(save); + } + m_centerstr((long)x, (long)y, logfont_lfont, s); +} + + +/*================= DRAWNUM1 ===================*/ +/*= =*/ +/*= Draw a single digit at the specified =*/ +/*= position (screen coordinates). =*/ +/*= =*/ +/*================================================*/ + +static void drawnum1(short x, short y, short n) +{ + char s[2]; + + m_move((long)x, (long)y); + strcpy(s, " "); + s[0] = n + '0'; + m_displaytext(s); +} + + +/*================= DRAWNUM2 ===================*/ +/*= =*/ +/*= Draw a two-digit number at the specified =*/ +/*= position (screen coordinates). =*/ +/*= =*/ +/*================================================*/ + +static void drawnum2(short x, short y, short n) +{ + char s[3]; + + m_move((long)x, (long)y); + strcpy(s, " "); + if (n >= 10) + s[0] = n / 10 + '0'; + s[1] = n % 10 + '0'; + m_displaytext(s); +} + + +static void xformcoords(log_grec *g, short *x, short *y) +{ + short xx, yy; + + if (g == NULL) + { + *x = *x * gg.scale - gg.xoff; + *y = *y * gg.scale - gg.yoff; + return; + } + xx = *x * gg.scale; + yy = *y * gg.scale; + *x = g->x * gg.scale - gg.xoff + + (log_rotxx[g->rot] * xx + log_rotyx[g->rot] * yy) / log_scale0; + *y = g->y * gg.scale - gg.yoff + + (log_rotxy[g->rot] * xx + log_rotyy[g->rot] * yy) / log_scale0; +} + + +static void plainxformcoords(log_grec *g, short *x, short *y) +{ + short xx; + + if (g == NULL) + { + *x *= log_scale0; + *y *= log_scale0; + return; + } + xx = *x; + *x = g->x * log_scale0 + log_rotxx[g->rot] * xx + log_rotyx[g->rot] * *y; + *y = g->y * log_scale0 + log_rotxy[g->rot] * xx + log_rotyy[g->rot] * *y; +} + + +/*================== CLIPON ====================*/ +/*= =*/ +/*= Allow drawing only in the working area. =*/ +/*= =*/ +/*================================================*/ + +static void clipon() +{ + m_clip(0L, 0L, (long)across, baseline - 1L); +} + + +/*================== CLIPOFF ===================*/ +/*= =*/ +/*= Allow drawing in working area and menus. =*/ +/*= =*/ +/*================================================*/ + +static void clipoff() +{ + m_noclip(); +} + +/*================== UERASE ====================*/ +/*= =*/ +/*= Erase a rectangular area of the screen =*/ +/*= using screen coordinates. =*/ +/*= =*/ +/*================================================*/ + +static void uerase(short x1, short y1, short x2, short y2) +{ + m_color((long)gg.color.backgr); + m_fillrect((long)x1, (long)y1, (long)x2, (long)y2); +} + + +/*=================== ERASE ====================*/ +/*= =*/ +/*= Erase a rectangular area of the screen =*/ +/*= using grid coordinates. =*/ +/*= =*/ +/*================================================*/ + +static void erase(short x1, short y1, short x2, short y2) +{ + m_color((long)gg.color.backgr); + box(x1, y1, x2, y2); +} + + +/*================ NORABBITS ===================*/ +/*= =*/ +/*= Make sure there are no rabbits on the =*/ +/*= screen. =*/ +/*= =*/ +/*================================================*/ + +static void norabbits() +{ + short i; + + clipoff(); + for (i = 0; i < rabtabsize; i++) + { + if (rabtable[i].next == 1) + { + m_bunny((long)rabtable[i].x, (long)rabtable[i].y); + rabtable[i].next = 0; + } + } + rabflag = false; +} + + +/*================ ADDRABBIT ===================*/ +/*= =*/ +/*= Draw a rabbit on the screen. =*/ +/*= =*/ +/*================================================*/ + +static void addrabbit() +{ + short i, j, rx, ry; + int nogood; + rablistrec *WITH; + + clipoff(); + j = -1; + for (i = 1; i <= rabtabsize; i++) + { + if (rabtable[i - 1].next == 0) + j = i; + } + if (j == -1) + { + j = P_rand(&gg.rndseed, (long)rabtabsize) + 1; + m_bunny((long)rabtable[j - 1].x, (long)rabtable[j - 1].y); + rabtable[j - 1].next = 0; + } + do + { + rx = P_rand(&gg.rndseed, across - 24L); + ry = P_rand(&gg.rndseed, baseline - 40L) + down - baseline + 30; + nogood = false; + for (i = 0; i < rabtabsize; i++) + { + WITH = &rabtable[i]; + if (WITH->next == 1) + { + if (WITH->x + 24 >= rx && WITH->x <= rx + 24 && WITH->y + 26 >= ry && + WITH->y <= ry + 26) + nogood = true; + } + } + } while (nogood); + rabtable[j - 1].next = 1; + rabtable[j - 1].x = rx; + rabtable[j - 1].y = ry; + m_bunny((long)rx, (long)ry); + rabflag = true; + rabtime = timers_sysclock(); +} + + +/*================== HVLINE ====================*/ +/*= =*/ +/*= Attempt to force a line to be horizontal =*/ +/*= or vertical. If possible, second pair =*/ +/*= of coordinates is changed appropriately. =*/ +/*= =*/ +/*= Returns true if possible, false if not. =*/ +/*= =*/ +/*================================================*/ + +static int hvline(short x1, short y1, short *x2, short *y2) +{ + int Result; + + Result = true; + if (x1 == *x2 && y1 == *y2) + return false; + if (abs(*x2 - x1) > abs(*y2 - y1) && abs(*y2 - y1) < abs(*x2 - x1) / 3 + 20) + { /*7/14/88*/ + *y2 = y1; + return Result; + } + if (abs(*y2 - y1) <= abs(*x2 - x1) || + abs(*x2 - x1) >= abs(*y2 - y1) / 3 + 20) + /*7/14/88*/ + return false; + *x2 = x1; + return Result; +} + + +/*=================== FIXXY ====================*/ +/*= =*/ +/*= Adjust screen coordinates so that they are =*/ +/*= aligned to the nearest grid point. =*/ +/*= =*/ +/*================================================*/ + +static void fixxy(short *x, short *y) +{ + *x = (*x + gg.xoff + gg.hscale) / gg.scale * gg.scale - gg.xoff; + *y = (*y + gg.yoff + gg.hscale) / gg.scale * gg.scale - gg.yoff; +} + +/*================ NOCROSSHAIR =================*/ +/*= =*/ +/*= Turn off crosshair (no effect until next =*/ +/*= call of CURSOR). =*/ +/*= =*/ +/*================================================*/ + +static void nocrosshair() +{ + chairflag2 = false; +} + + +/*================= CROSSHAIR ==================*/ +/*= =*/ +/*= Move the crosshair to a particular position =*/ +/*= in grid coordinates. =*/ +/*= =*/ +/*================================================*/ + +static void crosshair(short x, short y) +{ + chairx = x * gg.scale - gg.xoff; + chairy = y * gg.scale - gg.yoff; + chairflag2 = true; +} + +/*================= XORCURSOR ==================*/ +/*= =*/ +/*= Draw the cursor on the screen. =*/ +/*= The exact shape drawn depends upon the =*/ +/*= current mode. =*/ +/*= If the cursor is already on the screen, it =*/ +/*= is removed. =*/ +/*= =*/ +/*= Possible cursors: =*/ +/*= Arrow (normal). =*/ +/*= Probe (if Logic Probe mode). =*/ +/*= Big crosshair (if "Grid" mode on). =*/ +/*= Long arrow (if Copy command). =*/ +/*= Scissors (if Delete command). =*/ +/*= Rectangle (if Paste command). =*/ +/*= Green line (if drawing a wire). =*/ +/*= Rabbit (if Rabbit mode). =*/ +/*= =*/ +/*================================================*/ + +static void xorcursor() +{ + long curcm; + short cx0, cy0; + + gg.cx_min = 0; + gg.cx_max = across; + gg.cy_min = 0; + gg.cy_max = baseline - 1; + curcm = m_curcolormode(); + m_colormode((long)m_xor); + m_color((long)gg.color.cursor); + if (!chairflag || cursortype == grid) + { + if (cursortype != normal && cursy < baseline) + { + switch (cursortype) + { + + case grid: + choose_log_cursor(0); + if (chairflag) { + m_drawline(cursx1 - 3L, cursy1 - 5L, cursx1 + 3L, cursy1 + 5L); + m_drawline(cursx1 - 3L, cursy1 + 5L, cursx1 + 3L, cursy1 - 5L); + } + cx0 = (cursx + gg.xoff) / gg.scale * gg.scale - gg.xoff; + cy0 = (cursy + gg.yoff) / gg.scale * gg.scale - gg.yoff; + m_drawline(0L, (long)cy0, (long)across, (long)cy0); + m_drawline((long)cx0, 0L, (long)cx0, baseline - 1L); + break; + + case delete__: + choose_log_cursor(2); + break; + + case copy_: + choose_log_cursor(1); + break; + + case boxcursor: + choose_log_cursor(4); + break; + + case paste: + choose_log_cursor(0); + cx0 = (cursx + gg.xoff + 2) / gg.scale; + cy0 = (cursy + gg.yoff + 2) / gg.scale; + m_saveclip(); + m_clip(0L, 0L, (long)across, baseline - 1L); + gg.cx_min = cx0; + gg.cx_max = cx0 + copybuf.dxcopy; + gg.cy_min = cy0; + gg.cy_max = cy0 + copybuf.dycopy; + rect(gg.cx_min, gg.cy_min, gg.cx_max, gg.cy_max); + m_unclip(); + break; + + default: + break; + } + } + else + { + if (rabbits && !avoidrabbits && cursy < baseline) + { + choose_log_cursor(0); + if (cursx < 45) + m_bunny(0L, cursy - 17L); + else + m_bunny(cursx - 45L, cursy - 17L); + } + else if (gg.probemode) + { + choose_log_cursor(3); + } + else + { + choose_log_cursor(0); + } + } + } + if (chairflag) + { + if (rbandflag) + { + choose_log_cursor(0); + if (vlsi) + m_color((long)gg.color.wire[curwcolor - log_wcol_normal]); + else + m_color((long)gg.color.xwire); + m_drawline((long)cursx1, (long)cursy1, (long)cursx2, (long)cursy2); + } + else + { + choose_log_cursor(0); + } + } + oldcursortype = cursortype; + m_colormode(curcm); + + /*and (cursy < baseline)*/ +} + + +/*================= HIDECURSOR =================*/ +/*= =*/ +/*= Used to remove cursor from screen while =*/ +/*= drawing graphics. =*/ +/*= =*/ +/*================================================*/ + +static void hidecursor() +{ + if (cursorflag) + xorcursor(); +} + + +static void hidecursor_hook() +{ + if (!cursorhide) + hidecursor(); + cursorhide = true; +} + + +static void unhidecursor_hook() +{ + if (cursorhide) + hidecursor(); + cursorhide = false; +} + + +static void hidecursorrect_hook(long x1, long y1, long x2, long y2) +{ + if (!cursorhide && x1 <= gg.cx_max && x2 >= gg.cx_min && y1 <= gg.cy_max && + y2 >= gg.cy_min) + hidecursor_hook(); +} + + +/*================ DRAWCURSOR ==================*/ +/*= =*/ +/*= Position the cursor to a particular point =*/ +/*= (screen coordinates). =*/ +/*= =*/ +/*================================================*/ + +static void drawcursor(short x, short y) +{ + if (x != cursx || y != cursy || !cursorflag || cursortype != oldcursortype) + { + if (cursorflag && !cursorhide) + xorcursor(); + cursx = x; + cursy = y; + cursx1 = chairx; + cursy1 = chairy; + cursx2 = x; + cursy2 = y; + chairflag = chairflag2; + if (chairflag) + { + chairflag = true; + fixxy(&cursx2, &cursy2); + rbandflag = (abs(cursx1 - cursx2) + abs(cursy1 - cursy2) >= gg.scale && + hvline(cursx1, cursy1, &cursx2, &cursy2)); + } + xorcursor(); + } + else + { + if (!cursorflag && !cursorhide) + xorcursor(); + } + cursorflag = true; + cursorhide = false; +} + +/*================= REMCURSOR ==================*/ +/*= =*/ +/*= Take the cursor off the screen. =*/ +/*= =*/ +/*================================================*/ + +static void remcursor() +{ + prevcursorflag = cursorflag; + if (cursorflag) + xorcursor(); + cursorflag = false; + cursorhide = false; +} + + +/*================ RESTORECURSOR ===============*/ +/*= =*/ +/*= Restore the cursor to its previous on/off =*/ +/*= status. =*/ +/*= =*/ +/*================================================*/ + +static void restorecursor() +{ + if (prevcursorflag != cursorflag) + xorcursor(); + cursorflag = prevcursorflag; +} + +/*================ CLEARSCREEN =================*/ +/*= =*/ +/*= Clear the screen. =*/ +/*= =*/ +/*================================================*/ + +static void clearscreen() +{ + remcursor(); + m_noclip(); + m_vsetcolors((long)gg.color.backgr, 1L, &rcolormap[gg.color.backgr], + &gcolormap[gg.color.backgr], &bcolormap[gg.color.backgr]); + m_color((long)gg.color.backgr); + m_fillrect(0L, 0L, (long)across, (long)down); + fixcolormap(); + resetmessages(); + bottomcount = 0; + gg.showpage = 0; +} + + +static void clearshowalpha() +{ + if (onescreen) + clearscreen(); + printf("\f"); + nk_gotoxy(0, 0); + noblink(); + showalpha(); +} + +/*================ UDRAWGATEC ==================*/ +/*= =*/ +/*= Draw a gate of specified color at a =*/ +/*= certain position (screen coordinates). =*/ +/*= =*/ +/*================================================*/ + +static void drawvector2(log_vectorrec *v, long x1, long y1, long x2, long y2) +{ + long diam, savecol, coord; + + switch (v->vkind) + { + + case 'v': + m_drawline(x1, y1, x2, y2); + break; + + case 'C': + diam = P_imax2(labs(x1 - x2), labs(y1 - y2)); + switch (diam) + { + + case 3: + if (x1 == x2) + { + coord = P_imin2(y1, y2); + m_move2(x1, coord); + m_draw(x1 + 2, coord + 1); + m_draw(x1 + 2, coord + 2); + m_draw(x1, coord + 3); + m_draw(x1 - 2, coord + 2); + m_draw(x1 - 2, coord + 1); + m_draw(x1, coord); + } + else if (y1 == y2) + { + coord = P_imin2(x1, x2); + m_move2(coord, y1); + m_draw(coord + 1, y1 + 2); + m_draw(coord + 2, y1 + 2); + m_draw(coord + 3, y1); + m_draw(coord + 2, y1 - 2); + m_draw(coord + 1, y1 - 2); + m_draw(coord, y1); + } + else + { + m_circle((x1 + x2) / 2, (y1 + y2) / 2, 1L); + } + break; + + case 5: + if (x1 == x2) + { + coord = P_imin2(y1, y2); + m_move2(x1, coord); + m_draw(x1 + 3, coord + 1); + m_draw(x1 + 3, coord + 4); + m_draw(x1, coord + 5); + m_draw(x1 - 3, coord + 4); + m_draw(x1 - 3, coord + 1); + m_draw(x1, coord); + } + else if (y1 == y2) + { + coord = P_imin2(x1, x2); + m_move2(coord, y1); + m_draw(coord + 1, y1 + 3); + m_draw(coord + 4, y1 + 3); + m_draw(coord + 5, y1); + m_draw(coord + 4, y1 - 3); + m_draw(coord + 1, y1 - 3); + m_draw(coord, y1); + } + else + { + m_circle((x1 + x2) / 2, (y1 + y2) / 2, 2L); + } + break; + + default: + m_circle((x1 + x2) / 2, (y1 + y2) / 2, diam / 2); + break; + } + break; + + case 'e': + savecol = m_curcolor(); + m_color(m_trans); + m_ellipse((x1 + x2) / 2, (y1 + y2) / 2, (x1 - x2) / 2, (y1 - y2) / 2, + savecol); + m_color(savecol); + break; + + case 'E': + m_ellipse((x1 + x2) / 2, (y1 + y2) / 2, (x1 - x2) / 2, (y1 - y2) / 2, + m_curcolor()); + break; + + case 'r': /*should do a true roundrect*/ + m_drawrect(x1, y1, x2, y2); + break; + } +} + + +static void drawvector4(log_vectorrec *v, long x1, long y1, long x2, long y2, long x3, long y3, long x4, long y4) +{ + long xarr[4], yarr[4]; + + switch (v->vkind) + { + + case 'c': + m_bezier(x1, y1, x2, y2, x3, y3, x4, y4); + break; + + case 'F': + xarr[0] = x1; + yarr[0] = y1; + xarr[1] = x2; + yarr[1] = y2; + xarr[2] = x3; + yarr[2] = y3; + xarr[3] = x4; + yarr[3] = y4; + m_fillpoly(4L, (int *) xarr, (int *) yarr); + break; + } +} + + +#define big1 "0.,+123-456*789/\0()^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " +#define big2 "0.,\000123-456\000789 " + + +static void drawtext(log_vectorrec *v, long scale, long rot, long xx, long yy) +{ + long sc, i, j, tx, ty; + char mode; + char buf[256]; + long FORLIM; + + sc = v->UU.U116.tsize * scale; + if (sc >= log_scale0 * 70) + { + tx = (v->UU.U116.torg % 3 - 1) * log_rotxx[rot] + + (v->UU.U116.torg / 3 - 1) * log_rotyx[rot]; + ty = (v->UU.U116.torg % 3 - 1) * log_rotxy[rot] + + (v->UU.U116.torg / 3 - 1) * log_rotyy[rot]; + i = strposc(v->UU.U116.sp, '$', 1L); + if (i > 0 && i < strlen(v->UU.U116.sp)) + { + strcpy(buf, v->UU.U116.sp); + mode = 'X'; + while (i <= strlen(buf)) { + if (buf[i - 1] == '$' && i < strlen(buf)) + { + switch (toupper(buf[i])) + { + + case '$': + strcpy_overlap(buf + i - 1, buf + i); + i++; + break; + + case 'P': + case 'B': + case 'O': + case 'X': + mode = toupper(buf[i]); /*close enough*/ + strcpy_overlap(buf + i - 1, buf + i + 1); + break; + + default: + i++; + break; + } + continue; + } + switch (mode) + { + + case 'P': + j = strposc("0.,+123-456*789/E()^", buf[i - 1], 1L); + if (j > 0) + buf[i - 1] = (char)(j + 147); + break; + + case 'B': + j = strposc("0.,+123-456*789/\0()^ABCDEFGHIJKLMNOPQRSTUVWXYZ", + toupper(buf[i - 1]), 1L); + if (j > 20) + buf[i - 1] = (char)(j + 147); + else if (j > 0) + buf[i - 1] = (char)(j + 127); + break; + + case 'O': + j = strposc("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", + toupper(buf[i - 1]), 1L); + if (j > 0) + buf[i - 1] = (char)(j + 213); + break; + } + i++; + } + switch (tx) + { + + case -1: + m_drawstr(xx, yy - (ty + 1) * 3, NULL, buf); + break; + + case 0: + m_centerstr(xx, yy - (ty + 1) * 3, NULL, buf); + break; + + case 1: + m_rightstr(xx, yy - (ty + 1) * 3, NULL, buf); + break; + } + return; + } + switch (tx) + { + + case -1: + m_drawstr(xx, yy - (ty + 1) * 3, NULL, v->UU.U116.sp); + break; + + case 0: + m_centerstr(xx, yy - (ty + 1) * 3, NULL, v->UU.U116.sp); + break; + + case 1: + m_rightstr(xx, yy - (ty + 1) * 3, NULL, v->UU.U116.sp); + break; + } + return; + } + if (sc < log_scale0 * 40) + return; + if (sc >= log_scale0 * 50) { + if (!strsubset(v->UU.U116.sp, big1)) + return; + buf[strlen(v->UU.U116.sp)] = '\0'; + FORLIM = strlen(v->UU.U116.sp); + for (i = 0; i < FORLIM; i++) { + j = strposc(big1, v->UU.U116.sp[i], 1L); + if (j <= 20) + buf[i] = (char)(j + 127); + else if (j <= 46) + buf[i] = (char)(j + 147); + else if (j <= 72) + buf[i] = (char)(j + 121); + else + buf[i] = ' '; + } + tx = (v->UU.U116.torg % 3 - 1) * log_rotxx[rot] + + (v->UU.U116.torg / 3 - 1) * log_rotyx[rot]; + ty = (v->UU.U116.torg % 3 - 1) * log_rotxy[rot] + + (v->UU.U116.torg / 3 - 1) * log_rotyy[rot]; + switch (tx) + { + + case -1: + m_drawstr(xx, yy - (ty + 2) * 2, NULL, buf); + break; + + case 0: + m_centerstr(xx, yy - (ty + 2) * 2, NULL, buf); + break; + + case 1: + m_rightstr(xx, yy - (ty + 2) * 2, NULL, buf); + break; + } + return; + } + if (!strsubset(v->UU.U116.sp, big2)) + return; + buf[strlen(v->UU.U116.sp)] = '\0'; + FORLIM = strlen(v->UU.U116.sp); + for (i = 0; i < FORLIM; i++) + { + j = strposc(big2, v->UU.U116.sp[i], 1L); + if (j <= 15) + buf[i] = (char)(j + 193); + else + buf[i] = ' '; + } + tx = (v->UU.U116.torg % 3 - 1) * log_rotxx[rot] + + (v->UU.U116.torg / 3 - 1) * log_rotyx[rot]; + ty = (v->UU.U116.torg % 3 - 1) * log_rotxy[rot] + + (v->UU.U116.torg / 3 - 1) * log_rotyy[rot]; + switch (tx) + { + + case -1: + m_drawstr(xx, yy - (ty + 1) * 2 - 3, NULL, buf); + break; + + case 0: + m_centerstr(xx, yy - (ty + 1) * 2 - 3, NULL, buf); + break; + + case 1: + m_rightstr(xx, yy - (ty + 1) * 2 - 3, NULL, buf); + break; + } +} + +#undef big1 +#undef big2 + + +static void plaindrawgatec(short x, short y, short g, short c) +{ + short i, z, rxx, rxy, ryx, ryy; + log_krec *k; + int hascolor; + short FORLIM; + log_vectorrec *WITH1; + + k = kind[(g & (log_kindoffset - 1)) - 1]; + z = log_scale0 * k->bbmax + 2; + if (x < -z || x > across + z || y < -z || y > down + z) + return; + hidecursor(); + hascolor = (c != gg.color.backgr && c != gg.color.conflict); + m_color((long)c); + if (g < log_kindoffset) + { + FORLIM = k->numvects; + for (i = 0; i < FORLIM; i++) + { + WITH1 = &k->vector[i]; + switch (WITH1->vkind) + { + + case '1': + if (hascolor) + m_color((long)c); + break; + + case '2': + if (hascolor) + m_color((long)gategreen); + break; + + case '3': + if (hascolor) + m_color((long)gateyellow); + break; + + case '4': + if (hascolor) + m_color((long)gatered); + break; + + case '5': + if (hascolor) + m_color((long)gateorange); + break; + + case '6': + if (hascolor) + m_color((long)gateblack); + break; + + case '7': + if (hascolor) + m_color((long)gatewhite); + break; + + case 'v': + case 'C': + case 'e': + case 'E': + case 'r': + drawvector2(&k->vector[i], (long)(x + WITH1->x1), + (long)(y + WITH1->y1), (long)(x + WITH1->UU.U99.x2), + (long)(y + WITH1->UU.U99.y2)); + break; + + case 'c': + case 'F': + drawvector4(&k->vector[i], (long)(x + WITH1->x1), + (long)(y + WITH1->y1), (long)(x + WITH1->UU.U99.x2), + (long)(y + WITH1->UU.U99.y2), (long)(x + WITH1->UU.U99.x3), + (long)(y + WITH1->UU.U99.y3), (long)(x + WITH1->UU.U99.x4), + (long)(y + WITH1->UU.U99.y4)); + break; + + case 't': + drawtext(&k->vector[i], (long)log_scale0, 0L, (long)(x + WITH1->x1), + (long)(y + WITH1->y1)); + break; + } + } + } + else + { + z = g / log_kindoffset; + rxx = log_rotxx[z]; + rxy = log_rotxy[z]; + ryx = log_rotyx[z]; + ryy = log_rotyy[z]; + FORLIM = k->numvects; + for (i = 0; i < FORLIM; i++) + { + WITH1 = &k->vector[i]; + switch (WITH1->vkind) + { + + case '1': + if (hascolor) + m_color((long)c); + break; + + case '2': + if (hascolor) + m_color((long)gategreen); + break; + + case '3': + if (hascolor) + m_color((long)gateyellow); + break; + + case '4': + if (hascolor) + m_color((long)gatered); + break; + + case '5': + if (hascolor) + m_color((long)gateorange); + break; + + case '6': + if (hascolor) + m_color((long)gateblack); + break; + + case '7': + if (hascolor) + m_color((long)gatewhite); + break; + + case 'v': + case 'C': + case 'e': + case 'E': + case 'r': + drawvector2(&k->vector[i], + (long)(x + WITH1->x1 * rxx + WITH1->y1 * ryx), + (long)(y + WITH1->x1 * rxy + WITH1->y1 * ryy), + (long)(x + WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx), + (long)(y + WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy)); + break; + + case 'c': + case 'F': + drawvector4(&k->vector[i], + (long)(x + WITH1->x1 * rxx + WITH1->y1 * ryx), + (long)(y + WITH1->x1 * rxy + WITH1->y1 * ryy), + (long)(x + WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx), + (long)(y + WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy), + (long)(x + WITH1->UU.U99.x3 * rxx + WITH1->UU.U99.y3 * ryx), + (long)(y + WITH1->UU.U99.x3 * rxy + WITH1->UU.U99.y3 * ryy), + (long)(x + WITH1->UU.U99.x4 * rxx + WITH1->UU.U99.y4 * ryx), + (long)(y + WITH1->UU.U99.x4 * rxy + WITH1->UU.U99.y4 * ryy)); + break; + + case 't': + drawtext(&k->vector[i], (long)log_scale0, (long)z, + (long)(x + WITH1->x1 * rxx + WITH1->y1 * ryx), + (long)(y + WITH1->x1 * rxy + WITH1->y1 * ryy)); + break; + } + } + } + hidecursor(); +} + + +static void udrawgatec(short x, short y, short g, short c) +{ + short i, z, rxx, rxy, ryx, ryy; + log_krec *k; + int hascolor; + short FORLIM; + log_vectorrec *WITH1; + + if (g == 0) + { + hidecursor(); + m_color((long)c); + m_drawpoint((long)x, (long)y); + hidecursor(); + return; + } + k = kind[(g & (log_kindoffset - 1)) - 1]; + if (k->bbmax <= maxsafescale) + { + plaindrawgatec(x, y, g, c); + return; + } + hascolor = (c != gg.color.backgr); + z = log_scale0 * k->bbmax + 2; + if (x < -z || x > across + z || y < -z || y > down + z) + return; + z = g / log_kindoffset; + rxx = log_rotxx[z] * maxsafescale; + rxy = log_rotxy[z] * maxsafescale; + ryx = log_rotyx[z] * maxsafescale; + ryy = log_rotyy[z] * maxsafescale; + hidecursor(); + m_color((long)c); + FORLIM = k->numvects; + for (i = 0; i < FORLIM; i++) + { + WITH1 = &k->vector[i]; + switch (WITH1->vkind) + { + + case '1': + if (hascolor) + m_color((long)c); + break; + + case '2': + if (hascolor) + m_color((long)gategreen); + break; + + case '3': + if (hascolor) + m_color((long)gateyellow); + break; + + case '4': + if (hascolor) + m_color((long)gatered); + break; + + case '5': + if (hascolor) + m_color((long)gateorange); + break; + + case '6': + if (hascolor) + m_color((long)gateblack); + break; + + case '7': + if (hascolor) + m_color((long)gatewhite); + break; + + case 'v': + case 'C': + case 'e': + case 'E': + case 'r': + drawvector2(&k->vector[i], + (long)(x + (WITH1->x1 * rxx + WITH1->y1 * ryx) / k->bbmax), + (long)(y + (WITH1->x1 * rxy + WITH1->y1 * ryy) / k->bbmax), + (long)(x + (WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx) / k->bbmax), + (long)(y + (WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy) / k->bbmax)); + break; + + case 'c': + case 'F': + drawvector4(&k->vector[i], (long)(x + (WITH1->x1 * rxx + + WITH1->y1 * ryx) / k->bbmax), (long) + (y + (WITH1->x1 * rxy + WITH1->y1 * ryy) / k->bbmax), (long) + (x + (WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx) / k->bbmax), + (long) + (y + (WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy) / k->bbmax), + (long) + (x + (WITH1->UU.U99.x3 * rxx + WITH1->UU.U99.y3 * ryx) / k->bbmax), + (long) + (y + (WITH1->UU.U99.x3 * rxy + WITH1->UU.U99.y3 * ryy) / k->bbmax), + (long) + (x + (WITH1->UU.U99.x4 * rxx + WITH1->UU.U99.y4 * ryx) / k->bbmax), + (long) + (y + (WITH1->UU.U99.x4 * rxy + WITH1->UU.U99.y4 * ryy) / k->bbmax)); + break; + } + } + hidecursor(); +} + + +/*================= DRAWGATEC ==================*/ +/*= =*/ +/*= Draw a gate of specified color at a =*/ +/*= certain position (grid coordinates). =*/ +/*= =*/ +/*================================================*/ + +static void drawgatedotsc(short x, short y, short g, short c) +{ + short i, z, rxx, rxy, ryx, ryy; + log_krec *WITH; + short FORLIM; + + if (g == 0 || vlsi) + return; + m_color((long)c); + z = g / log_kindoffset; + if (z != 0) + { + rxx = log_rotxx[z]; + rxy = log_rotxy[z]; + ryx = log_rotyx[z]; + ryy = log_rotyy[z]; + WITH = kind[(g & (log_kindoffset - 1)) - 1]; + FORLIM = WITH->numpins; + for (i = 0; i < FORLIM; i++) + point(x + WITH->pin[i].x * rxx + WITH->pin[i].y * ryx, + y + WITH->pin[i].x * rxy + WITH->pin[i].y * ryy); + return; + } + WITH = kind[(g & (log_kindoffset - 1)) - 1]; + FORLIM = WITH->numpins; + for (i = 0; i < FORLIM; i++) + point(x + WITH->pin[i].x, y + WITH->pin[i].y); +} + + +static void drawgatec(short x, short y, short g, short c) +{ + short i, xx, yy, z, rxx, rxy, ryx, ryy; + long savecol; + int hascolor; + log_krec *WITH; + short FORLIM; + log_vectorrec *WITH1; + + if (zoom == 0) + { + plaindrawgatec((int)(x * gg.scale - gg.xoff), + (int)(y * gg.scale - gg.yoff), g, c); + } + else + { + z = g / log_kindoffset; + rxx = log_rotxx[z] * gg.scale; + rxy = log_rotxy[z] * gg.scale; + ryx = log_rotyx[z] * gg.scale; + ryy = log_rotyy[z] * gg.scale; + xx = x * gg.scale - gg.xoff; + yy = y * gg.scale - gg.yoff; + hidecursor(); + m_color((long)c); + hascolor = (c != gg.color.backgr && c != gg.color.conflict); + WITH = kind[(g & (log_kindoffset - 1)) - 1]; + FORLIM = WITH->numvects; + for (i = 0; i < FORLIM; i++) + { + WITH1 = &WITH->vector[i]; + switch (WITH1->vkind) + { + + case '1': + if (hascolor) + m_color((long)c); + break; + + case '2': + if (hascolor) + m_color((long)gategreen); + break; + + case '3': + if (hascolor) + m_color((long)gateyellow); + break; + + case '4': + if (hascolor) + m_color((long)gatered); + break; + + case '5': + if (hascolor) + m_color((long)gateorange); + break; + + case '6': + if (hascolor) + m_color((long)gateblack); + break; + + case '7': + if (hascolor) + m_color((long)gatewhite); + break; + + case 'v': + case 'r': + drawvector2( + &WITH->vector[i], + (long)(xx + (WITH1->x1 * rxx + WITH1->y1 * ryx) / log_scale0), + (long)(yy + (WITH1->x1 * rxy + WITH1->y1 * ryy) / log_scale0), + (long) + (xx + (WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx) / log_scale0), + (long) + (yy + + (WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy) / log_scale0)); + break; + + case 'C': + m_circle(xx + ((WITH1->x1 + WITH1->UU.U99.x2) * rxx + (WITH1->y1 + + WITH1->UU.U99.y2) * ryx) / (log_scale0 * 2L), + yy + ((WITH1->x1 + WITH1->UU.U99.x2) * rxy + (WITH1->y1 + WITH1-> + UU.U99.y2) * ryy) / (log_scale0 * 2L), + P_imax2((long)abs((WITH1->x1 - WITH1->UU.U99.x2) * rxx + + (WITH1->y1 - WITH1->UU.U99.y2) * ryx), + (long)abs((WITH1->x1 - WITH1->UU.U99.x2) * ryx + + (WITH1->y1 - WITH1->UU.U99.y2) * ryy)) / + (log_scale0 * 2)); + break; + + case 'e': + savecol = m_curcolor(); + m_color(m_trans); + m_ellipse( + xx + ((WITH1->x1 + WITH1->UU.U99.x2) * rxx + + (WITH1->y1 + WITH1->UU.U99.y2) * ryx) / (log_scale0 * 2L), + yy + ((WITH1->x1 + WITH1->UU.U99.x2) * rxy + + (WITH1->y1 + WITH1->UU.U99.y2) * ryy) / (log_scale0 * 2L), + ((WITH1->x1 - WITH1->UU.U99.x2) * rxx + + (WITH1->y1 - WITH1->UU.U99.y2) * ryx) / (log_scale0 * 2L), + ((WITH1->x1 - WITH1->UU.U99.x2) * ryx + + (WITH1->y1 - WITH1->UU.U99.y2) * ryy) / (log_scale0 * 2L), + savecol); + m_color(savecol); + break; + + case 'E': + m_ellipse( + xx + ((WITH1->x1 + WITH1->UU.U99.x2) * rxx + + (WITH1->y1 + WITH1->UU.U99.y2) * ryx) / (log_scale0 * 2L), + yy + ((WITH1->x1 + WITH1->UU.U99.x2) * rxy + + (WITH1->y1 + WITH1->UU.U99.y2) * ryy) / (log_scale0 * 2L), + ((WITH1->x1 - WITH1->UU.U99.x2) * rxx + + (WITH1->y1 - WITH1->UU.U99.y2) * ryx) / (log_scale0 * 2L), + ((WITH1->x1 - WITH1->UU.U99.x2) * ryx + + (WITH1->y1 - WITH1->UU.U99.y2) * ryy) / (log_scale0 * 2L), + m_curcolor()); + break; + + case 'c': + case 'F': + drawvector4(&WITH->vector[i], (long)(xx + (WITH1->x1 * rxx + + WITH1->y1 * ryx) / log_scale0), (long)(yy + + (WITH1->x1 * rxy + WITH1->y1 * ryy) / log_scale0), (long)(xx + + (WITH1->UU.U99.x2 * rxx + WITH1->UU.U99.y2 * ryx) / log_scale0), + (long)(yy + + (WITH1->UU.U99.x2 * rxy + WITH1->UU.U99.y2 * ryy) / log_scale0), + (long)(xx + + (WITH1->UU.U99.x3 * rxx + WITH1->UU.U99.y3 * ryx) / log_scale0), + (long)(yy + + (WITH1->UU.U99.x3 * rxy + WITH1->UU.U99.y3 * ryy) / log_scale0), + (long)(xx + + (WITH1->UU.U99.x4 * rxx + WITH1->UU.U99.y4 * ryx) / log_scale0), + (long)(yy + (WITH1->UU.U99.x4 * rxy + WITH1->UU.U99.y4 * ryy) / + log_scale0)); + break; + + case 't': + drawtext(&WITH->vector[i], (long)gg.scale, (long)z, + (long)(xx + (WITH1->x1 * rxx + WITH1->y1 * ryx) / log_scale0), + (long)(yy + (WITH1->x1 * rxy + WITH1->y1 * ryy) / log_scale0)); + break; + } + } + hidecursor(); + } + if ((c == gg.color.gate || c == gg.color.dimgate) && !suppressdots) + drawgatedotsc(x, y, g, gg.color.gatepin); +} + + +static void signallabel(short x, short y, short gtype, short sig, short c) +{ + log_krec *k; + char STR1[256]; + + k = kind[(gtype & (log_kindoffset - 1)) - 1]; + if (!(sig != 0 && k->flag.U3.named)) + return; + remcursor(); + m_color((long)c); + if (k->flag.U3.nright != (gtype / log_kindoffset == 0)) + drawstr2((int)(x - m_strwidth(NULL, + strrtrim(strcpy(STR1, gg.signaltab[sig - 1].name))) + NAMEGAP), + y - 3, gg.signaltab[sig - 1].name); + else + drawstr2(x - NAMEGAP, y - 3, gg.signaltab[sig - 1].name); +} + + +static void gsignallabel(short x, short y, log_grec *g, short c) +{ + signallabel((int)(x * gg.scale - gg.xoff), (int)(y * gg.scale - gg.yoff), + g->g, g->sig, c); +} + + +typedef enum {inside,north,east,south,west} placement; + +static void drawpnums(log_grec *g, short c) +{ + short rxx, rxy, ryx, ryy, i, j, k; + char s[7]; + log_krec *WITH; + short FORLIM, FORLIM1; + int tx,ty,ex,ey; + int minx,miny,maxx,maxy; + placement p = inside; + long hw; + + if (zoom <= 0 || gg.textinvisible || gg.pnuminvisible) + return; + m_color((long)c); + rxx = log_rotxx[g->rot]; + rxy = log_rotxy[g->rot]; + ryx = log_rotyx[g->rot]; + ryy = log_rotyy[g->rot]; + WITH = g->kind; + + /* use grab rectangle to determine which edge this pin is attached to. */ + minx = ( WITH->x1 * rxx + WITH->y1 * ryx); + miny = ( WITH->x1 * rxy + WITH->y1 * ryy); + maxx = ( WITH->x2 * rxx + WITH->y2 * ryx); + maxy = ( WITH->x2 * rxy + WITH->y2 * ryy); + + FORLIM = WITH->numpnums; + for (i = 0; i < FORLIM; i++) + { + sprintf(s, "%d", WITH->pnum[i].num); + hw = strlen(s) * 5 / 2; + ex = (WITH->pnum[i].x * rxx + WITH->pnum[i].y * ryx); + ey = (WITH->pnum[i].x * rxy + WITH->pnum[i].y * ryy); + if (ex < minx) + { + p = west; + } + else if (ex > maxx) + { + p = east; + } + else if (ey < miny) + { + p = north; + } + else if (ey > maxy) + { + p = south; + } + tx = g->x * gg.scale + ex * gg.scale / log_scale0 - gg.xoff; + ty = g->y * gg.scale + ey * gg.scale / log_scale0 - gg.yoff; + switch (p) + { + case west: + tx -= 5; + break; + case east: + tx += 5; + break; + case north: + tx -= hw; + ty -= 9; + break; + case south: + tx -= hw; + ty += 5; + break; + + default: + break; + } + + if (p == west) + m_rightstr(tx,ty,NULL,s); + else + m_drawstr(tx,ty,NULL,s); + } +} + +#undef fromtab +#undef totab + + +static void setscale (short s); + + +static void kdrawgatec(short i, short c) +{ + short x, y; + short ozoom = zoom; + + x = (i - 1) * kindgroupspacing + kindgroupstart; + y = (down + baseline) / 2; + udrawgatec(x, y, kindgroup[i - 1], c); + setscale(0); + if (kindgroup[i - 1] != 0) + signallabel(x, y, kindgroup[i - 1], kindsig[i - 1], c); + setscale(ozoom); +} + + +/*================= DRAWGATEX ==================*/ +/*= =*/ +/*= Draw a gate. If it is a TO or FROM gate, =*/ +/*= draw its name as well. =*/ +/*= =*/ +/*================================================*/ + +static void drawgatexc(log_grec *g, short c) +{ + if (g->dimcolor && c == gg.color.gate) + c = gg.color.dimgate; + drawgatec(g->x, g->y, g->g, c); + if (!gg.textinvisible) + gsignallabel(g->x, g->y, g, gg.color.signal); + if (g->kind->numpnums > 0) + drawpnums(g, gg.color.pinnum); +} + + +static void drawgatex(log_grec *g) +{ + drawgatexc(g, gg.color.gate); +} + + +static void setdimgate(log_grec *g, int dim) +{ + log_grec *g1; + + if (g->dimcolor == dim) + return; + g->dimcolor = dim; + if (gg.showpage <= 0) + return; + g1 = gg.gbase[gg.showpage - 1]; + while (g1 != NULL && g1 != g) + g1 = g1->next; + if (g1 != g) + return; + m_saveclip(); + clipon(); + drawgatex(g); + m_unclip(); +} + +/*================ DRAWSOLDERC =================*/ +/*= =*/ +/*= Draw a solder point at a certain position =*/ +/*= (grid coordinates). =*/ +/*= =*/ +/*================================================*/ + +static void drawsolderc(short x, short y, short c) +{ + if (!showsolder) + return; + if (vlsi) + { + if (c == gg.color.conflict || c == gg.color.backgr) + m_color((long)c); + else + m_color((long)gg.color.vlsicut); + x = x * gg.scale - gg.xoff; + y = y * gg.scale - gg.yoff; + m_drawline(x - 3L, y - 3L, x + 3L, y + 3L); + m_drawline(x - 3L, y + 3L, x + 3L, y - 3L); + m_drawline(x - 2L, y - 3L, x + 4L, y + 3L); + m_drawline(x - 2L, y + 3L, x + 4L, y - 3L); + return; + } + m_color((long)c); + x = x * gg.scale - gg.xoff; + y = y * gg.scale - gg.yoff; + m_drawline(x - 1L, y - 2L, x + 1L, y - 2L); + m_drawline(x - 2L, y - 1L, x + 2L, y - 1L); + m_drawline(x - 2L, (long)y, x + 2L, (long)y); + m_drawline(x - 2L, y + 1L, x + 2L, y + 1L); + m_drawline(x - 1L, y + 2L, x + 1L, y + 2L); +} + + +/*================= DRAWTRANSC =================*/ +/*= =*/ +/*= Draw a VLSI transistor at a certain =*/ +/*= position (grid coordinates). =*/ +/*= =*/ +/*================================================*/ + +static void drawtransc(short x, short y, short c) +{ + if (!vlsi) + return; + if (c == gg.color.solder) + m_color((long)gg.color.vlsicut); + else + m_color((long)c); + x = x * gg.scale - gg.xoff; + y = y * gg.scale - gg.yoff; + m_circle((long)x, (long)y, 4L); +} + +/*================== DRAWBOXC ==================*/ +/*= =*/ +/*= Draw a dashed box on the screen. =*/ +/*= =*/ +/*================================================*/ + +static void drawboxc0(short x1, short y1, short x2, short y2, short c) +{ + m_color((long)c); + m_linestyle(1L); + rect(x1, y1, x2, y2); + m_linestyle(0L); +} + + +static void drawboxc(log_brec *b, short c) +{ + drawboxc0(b->x1, b->y1, b->x2, b->y2, c); +} + + +/*================ DRAWMARKERSC ================*/ +/*= =*/ +/*= Draw the printing markers on the screen. =*/ +/*= =*/ +/*================================================*/ + +static void drawmarkersc(short c) +{ + clipon(); + m_color((long)c); + hline(gg.markerx1, gg.markerx1 + 2, gg.markery1); + vline(gg.markerx1, gg.markery1, gg.markery1 + 2); + hline(gg.markerx2 - 2, gg.markerx2, gg.markery2); + vline(gg.markerx2, gg.markery2 - 2, gg.markery2); + clipoff(); +} + + +/*================= DRAWNODEC ==================*/ +/*= =*/ +/*= Draw all wires and solder points in a =*/ +/*= particular node, in color C. =*/ +/*= =*/ +/*================================================*/ + +static void drawnodec(log_nrec *n, short c) +{ + log_hwrec *hw; + log_vwrec *vw; + log_srec *s; + + if (gg.invisible || (gg.showconflicts == true && n->conflict == false)) + return; + + hidecursor(); + if ((unsigned)c > 15) + { + if (gg.glowmode && gg.showpage > 0) + c = glowcol(n, (long)gg.color.wire[0]); + else + c = gg.color.wire[0]; + } + if (vlsi && c == gg.color.wire[0]) + { + hw = gg.hwbase[gg.curpage - 1]; + while (hw != NULL) + { + if (hw->node == n && hw != gg.movinghw) + { + m_color((long)gg.color.wire[hw->wcolr - log_wcol_normal]); + hline(hw->x1, hw->x2, hw->y); + } + hw = hw->next; + } + vw = gg.vwbase[gg.curpage - 1]; + while (vw != NULL) + { + if (vw->node == n && vw != gg.movingvw) + { + m_color((long)gg.color.wire[vw->wcolr - log_wcol_normal]); + vline(vw->x, vw->y1, vw->y2); + } + vw = vw->next; + } + } + else + { + m_color((long)c); + hw = gg.hwbase[gg.curpage - 1]; + while (hw != NULL) { + if (hw->node == n && hw != gg.movinghw) + hline(hw->x1, hw->x2, hw->y); + hw = hw->next; + } + vw = gg.vwbase[gg.curpage - 1]; + while (vw != NULL) + { + if (vw->node == n && vw != gg.movingvw) + vline(vw->x, vw->y1, vw->y2); + vw = vw->next; + } + } + if (showsolder) + { + s = gg.sbase[gg.curpage - 1]; + while (s != NULL) + { + if ((s->hwire != NULL && s->hwire->node == n) || + (s->vwire != NULL && s->vwire->node == n)) + drawsolderc(s->x, s->y, c); + s = s->next; + } + } + hidecursor(); +} + + +/*================= DRAWNODE ===================*/ +/*= =*/ +/*= Draw all wires and solder points in a =*/ +/*= particular node. =*/ +/*= =*/ +/*================================================*/ + +static void drawnode(log_nrec *n) +{ + drawnodec(n, -1); +} + +/*================ REFRPAGEDISP ================*/ +/*= =*/ +/*= Refresh the page-number display. =*/ +/*= =*/ +/*================================================*/ + +static int pageempty (int pg); + + +static void refrpagedisp() +{ + short num; + + m_color((long)gg.color.page1); + drawstr2(across - 49, 2, "PAGE"); + m_color((long)gg.color.page2); + drawnum2(across - 14, 2, (int)gg.curpage); + m_color((long)gg.color.page3); + drawstr2(across - 35, 14, "OF"); + m_color((long)gg.color.page4); + num = gg.numpages; + while (num > gg.curpage && pageempty(num)) + num--; + drawnum2(across - 14, 14, num); +} + + +/*================ REFREDITMODE ================*/ +/*= =*/ +/*= Refresh the editing mode in the menus. =*/ +/*= =*/ +/*================================================*/ + +static void refreditmode() +{ + hidecursor(); + m_color((long)gg.color.backgr); + m_fillrect(across + menux4 - 1L, line2 - 2L, across + menux4 + 30L, + line2 + 9L); + switch (cureditmode) + { + + case 1: + m_color((long)gg.color.menuword); + drawstr2(across + menux4, line2, "ROT"); + break; + + case 2: + m_color((long)gg.color.menuword); + drawstr2(across + menux4, line2, "MIR-"); + break; + + case 3: + m_color((long)gg.color.menuword); + drawstr2(across + menux4, line2, "MIR|"); + break; + + case 4: + m_color((long)gg.color.selword); + drawstr2(across + menux4, line2, "CNFG"); + break; + } + hidecursor(); +} + + +/*=============== REFRBASELINE =================*/ +/*= =*/ +/*= Refresh the baseline to the correct color. =*/ +/*= =*/ +/*================================================*/ + +static void refrbaseline(int always) +{ + short c; + + if (anyconflicts) + c = gg.color.conflict; + else + c = gg.baselinecolor; + if (!(c != gg.color.curbaseline || always)) + return; + clipoff(); + gg.color.curbaseline = c; + hidecursor(); + m_color((long)c); + m_fillrect(0L, (long)baseline, (long)kindgroupleft, baseline + 1L); + m_fillrect((long)kindgroupright, (long)baseline, (long)across, + baseline + 1L); + hidecursor(); +} + + +#define rtn "REFRESH" + + +/*=================== REFRESH ==================*/ +/*= =*/ +/*= Refresh the screen (does not clear, so may =*/ +/*= be used to "clean up" existing screen). =*/ +/*= =*/ +/*================================================*/ + +static void refresh() +{ + long x1, y1, x2, y2; + log_grec *g; + log_hwrec *hw; + log_vwrec *vw; + log_nrec *n; + log_srec *s; + log_lrec *l; + log_brec *b; + + stamp(&gg.refrstamp); + gg.showpage = gg.curpage; + showsolder = (zoom > -1 && (vlsi || !gg.glowmode || glowsolder)); + x1 = (gg.xoff - 30) / gg.scale; + y1 = (gg.yoff - 30) / gg.scale; + x2 = (gg.xoff + across + 30) / gg.scale; + y2 = (gg.yoff + down + 30) / gg.scale; + refrtimer = -1; + remcursor(); + clipon(); + refrpagedisp(); + if (!gg.invisible && !gg.showconflicts) + { + working(); + suppressdots = gg.dotsvisible; + g = gg.gbase[gg.curpage - 1]; + while (g != NULL) + { + if (P_ibetweenm(x1, (long)g->x, x2, (long)g->kind->bbmax) && + P_ibetweenm(y1, (long)g->y, y2, (long)g->kind->bbmax)) + drawgatex(g); + g = g->next; + } + suppressdots = false; + working(); + if (gg.glowmode) + { + hw = gg.hwbase[gg.curpage - 1]; + while (hw != NULL) + { + if (hw->y > y1 && hw->y < y2 && hw != gg.movinghw) + { + m_color(glowcol(hw->node, + (long)gg.color.wire[hw->wcolr - log_wcol_normal])); + hline(hw->x1, hw->x2, hw->y); + } + hw = hw->next; + } + working(); + vw = gg.vwbase[gg.curpage - 1]; + while (vw != NULL) + { + if (vw->x > x1 && vw->x < x2 && vw != gg.movingvw) + { + m_color(glowcol(vw->node, + (long)gg.color.wire[vw->wcolr - log_wcol_normal])); + vline(vw->x, vw->y1, vw->y2); + } + vw = vw->next; + } + working(); + if (showsolder) + { + s = gg.sbase[gg.curpage - 1]; + while (s != NULL) + { + if (s->hwire != NULL) + n = s->hwire->node; + else + n = s->vwire->node; + drawsolderc(s->x, s->y, (int)glowcol(n, (long)gg.color.solder)); + s = s->next; + } + } + } + else + { + m_color((long)gg.color.wire[0]); + hw = gg.hwbase[gg.curpage - 1]; + while (hw != NULL) + { + if (hw->y > y1 && hw->y < y2 && hw != gg.movinghw) + { + if (vlsi) + m_color((long)gg.color.wire[hw->wcolr - log_wcol_normal]); + hline(hw->x1, hw->x2, hw->y); + } + hw = hw->next; + } + working(); + vw = gg.vwbase[gg.curpage - 1]; + while (vw != NULL) + { + if (vw->x > x1 && vw->x < x2 && vw != gg.movingvw) + { + if (vlsi) + m_color((long)gg.color.wire[vw->wcolr - log_wcol_normal]); + vline(vw->x, vw->y1, vw->y2); + } + vw = vw->next; + } + working(); + if (showsolder) + { + s = gg.sbase[gg.curpage - 1]; + while (s != NULL) + { + if (s->hwire != NULL) + n = s->hwire->node; + else + n = s->vwire->node; + drawsolderc(s->x, s->y, gg.color.solder); + s = s->next; + } + } + } + + if (gg.dotsvisible) + { + g = gg.gbase[gg.curpage - 1]; + while (g != NULL) + { + if (g->x > x1 && g->x < x2 && g->y > y1 && g->y < y2) + drawgatedotsc(g->x, g->y, g->g, gg.color.gatepin); + g = g->next; + } + } + } + else + { + working(); + g = gg.gbase[gg.curpage - 1]; + while (g != NULL) + { + if (g->kind->flag.U3.visible) + drawgatex(g); + g = g->next; + } + } + working(); + if (!gg.textinvisible) + { + b = gg.bbase[gg.curpage - 1]; + while (b != NULL) + { + drawboxc(b, gg.color.dashbox); + b = b->next; + } + working(); + l = gg.lbase[gg.curpage - 1]; + m_color((long)gg.color.labeltext); + while (l != NULL) + { + if (l->y > y1 && l->y < y2) + { + m_drawstr(l->x * gg.scale - gg.xoff, l->y * gg.scale - gg.yoff + 2, + logfont_lfont, l->name); + } + l = l->next; + } + } + working(); + if (gg.markers) + drawmarkersc(gg.color.marker); + if (memavail() < memtolerance) + message("Low on memory!"); + clipoff(); + restorecursor(); +} + +#undef rtn + + +/*================= REFRESHSOON ================*/ +/*= =*/ +/*= Screen is messed up, so refresh it as soon =*/ +/*= as the user stops moving around. =*/ +/*= =*/ +/*================================================*/ + +static void refreshsoon() +{ + refrtimer0 = refrdelay; + refrtimer = refrdelay; + gg.refrflag = true; +} + +/*================== REFRMENU ==================*/ +/*= =*/ +/*= Clear and redraw menu area of screen. =*/ +/*= =*/ +/*================================================*/ + +static void refrmenu() +{ + short i, FORLIM; + + working(); + remcursor(); + uerase(0, baseline + 2, across, down); + clipoff(); + refrbaseline(true); + m_color((long)gg.color.backgr); + m_fillrect(kindgroupleft + 1L, (long)baseline, kindgroupright - 1L, + baseline + 1L); + m_color((long)gg.color.menuword); + drawstr2(menux1, line1, "Frills"); + drawstr2(menux2, line1, "Editing"); + drawstr2(menux1, line2, "HELP"); + drawstr2(menux2, line2, "CAT"); + drawstr2(across + menux3, line1, "Cursor"); + drawstr2(across + menux4, line1, "Misc"); + refreditmode(); + if (modeflag) + log_setmode(modename); + else + log_setmode(""); + FORLIM = kindgroupsize; + for (i = 1; i <= FORLIM; i++) + kdrawgatec(i, gg.color.kindgate); +} + + +static void beginbottom() +{ + remcursor(); + clipoff(); + bottomcount++; + if (m_autoraise) + { + clearshowalpha(); + } + else + { + clearalpha(); + } + nk_gotoxy(0, txdown - 1); +} + + +static void endbottom() +{ + remcursor(); + bottomcount--; + if (m_autoraise) + { + if (bottomcount < 1) /* fix from WES */ + { + bottomcount =0; + m_graphics_on(); + } + } + else + { + m_graphics_on(); /* switch back to the graphics window */ + } + clearalpha(); +} + +/*================ REFRSCREEN1 =================*/ +/*= =*/ +/*= Clear and redraw working area of screen. =*/ +/*= =*/ +/*================================================*/ + +static void refrscreen1() +{ + m_colormode((long)m_normal); + m_noclip(); + remcursor(); + uerase(0, 0, across, baseline - 1); + resetmessages(); + refresh(); + gg.refrflag = true; +} + + +/*================= REFRSCREEN =================*/ +/*= =*/ +/*= Clear and redraw entire screen. =*/ +/*= =*/ +/*================================================*/ + +static void refrscreen() +{ + gg.showpage = gg.curpage; + bottomcount = 0; + m_colormode((long)m_normal); + m_noclip(); + fixcolormap(); + clearalpha(); + refrmenu(); + refrscreen1(); + m_graphics_on(); +} + +static void resize_screen() +{ + initscreen2(); + initscreen(); +} + +/*================= SHOWCATALOG ================*/ +/*= =*/ +/*= Switch screen to catalog (TRUE) or circuit =*/ +/*= (FALSE). =*/ +/*= =*/ +/*================================================*/ + +static void showcatalog() +{ + short i; + catboxrec *cb; + short x1, y1, x2, y2, FORLIM; + + clearscreen(); + gg.showpage = log_page_cat; + FORLIM = maxkinds; + for (i = 1; i <= FORLIM; i++) + { + if (kind[i - 1] != NULL) + { + udrawgatec((int)(((i - 1) % catwidth * 2 + 1) * gridcen), + (int)(((i - 1) / catwidth * 2 + 1) * gridcen), i, + gg.color.catgate); + } + } + cb = catboxes; + while (cb != NULL) + { + x1 = (cb->pos - 1) % catwidth * gridcen * 2; + y1 = (cb->pos - 1) / catwidth * gridcen * 2; + x2 = ((cb->pos + cb->count - 2) % catwidth + 1) * gridcen * 2; + y2 = ((cb->pos + cb->count - 2) / catwidth + 1) * gridcen * 2; + m_color((long)catboxcolor); + m_linestyle(2L); + m_drawline((long)x1, (long)y1, (long)x2, (long)y1); + m_linestyle(2L); + m_drawline((long)x1, (long)y2, (long)x2, (long)y2); + m_linestyle(2L); + m_drawline((long)x1, (long)y1, (long)x1, (long)y2); + m_linestyle(2L); + m_drawline((long)x2, (long)y1, (long)x2, (long)y2); + m_linestyle(0L); + cb = cb->next; + } +} + + diff --git a/log/src/tool.c b/log/src/tool.c new file mode 100644 index 0000000000000000000000000000000000000000..017c6c1af1409494fb37d9bc3e1fe7af4600e0e0 --- /dev/null +++ b/log/src/tool.c @@ -0,0 +1,200 @@ + +#include <log/log.h> + +static void newtool(log_tool **t, char *name) +{ + log_tool *t2; + + *t = (log_tool *)Malloc(sizeof(log_tool)); + strcpy((*t)->name, name); + (*t)->ready = false; + (*t)->simulator = false; + (*t)->keep = false; + (*t)->nostatus = false; + (*t)->fname = NULL; + (*t)->comment = (char *)Malloc(256); + *(*t)->comment = '\0'; + (*t)->info = (na_long)0; + (*t)->nlbl = NULL; + (*t)->hlbl = NULL; + (*t)->shortname = (char *)Malloc(33); + strcpy((*t)->shortname, name); + stamp(&(*t)->netstamp); + (*t)->deltatime = 0.0; + t2 = gg.toolbase; + while (t2 != NULL && t2->next != NULL) + t2 = t2->next; + if (t2 == NULL) + gg.toolbase = *t; + else + t2->next = *t; + (*t)->next = NULL; +} + + +static log_tool *findtool(char *name_) +{ + log_tool *Result; + char name[17]; + log_tool *lp; + char savefunc[17]; + char saveargs[256]; + char suffix[51]; + void (*proc) (log_action_t *act); + int ready; + cnfrec *cnfp; + + strcpy(name, name_); + strcpy(savefunc, gg.func); + strcpy(saveargs, gg.funcarg); + lp = gg.toolbase; + while (lp != NULL && strcmp(lp->name, name)) + lp = lp->next; + if (lp == NULL) + newtool(&lp, name); + if (!lp->ready) + { + sprintf(suffix, "LOG_%s_PROC", name); + ready = newci_findprocedure2(suffix, (void(**) ())(&proc)); + if (gg.traceflag) + fprintf(tracefile, "Findtool to load: %s - %s.\n", suffix, lp->fname); + + if (!ready && lp->fname != NULL) + { + TRY(try2); + newci_fixfname(lp->fname, "code", ""); + if (gg.traceflag) + fprintf(tracefile, "Findtool, loading %s\n", lp->fname); + newci_loadprogram(lp->fname); + RECOVER(try2); + if (P_escapecode == -20) + _Escape(P_escapecode); + ENDTRY(try2); + ready = newci_findprocedure2(suffix, (void(**) ())(&proc)); + if (gg.traceflag) + fprintf(tracefile, "Findtool, ready=%s\n", ready ? " TRUE" : "FALSE"); + } + + if (ready) + { + lp->proc = proc; + gg.action = act_init; + gg.acttool = lp; + (*proc)(&gg); + if (lp->ready) + { + cnfp = cnfbase; + while (cnfp != NULL) + { + if (!strcmp(cnfp->tool, name)) + { + doingcnffunction = true; + gg.action = act_cnf; + strcpy(gg.funcarg, cnfp->s); + getword(gg.funcarg, gg.func); + (*proc)(&gg); + doingcnffunction = false; + } + cnfp = cnfp->next; + } + gg.action = act_color; + (*proc)(&gg); + gg.action = act_endinit; + (*proc)(&gg); + lp->nexttstep = 0.0; + lp->nnumattrs = 0; + lp->nattr = NULL; + if (lp->nlbl != NULL) + parselabel(&lp->nlbl, &lp->nnumattrs, &lp->nattr); + lp->hnumattrs = 0; + lp->hattr = NULL; + if (lp->hlbl != NULL) + parselabel(&lp->hlbl, &lp->hnumattrs, &lp->hattr); + } + } + } + Result = lp; + strcpy(gg.func, savefunc); + strcpy(gg.funcarg, saveargs); + return Result; +} + + +static void calltool(log_tool *t, log_actionkinds act) +{ + log_tool *savetool; + + savetool = gg.acttool; + gg.action = act; + gg.acttool = t; + (*t->proc)(&gg); + gg.acttool = savetool; +} + + +static void calltoolgate(log_grec *g, log_actionkinds act) +{ + gg.actgate = g; + calltool(g->kind->simtype, act); +} + + +static void calltoolnode(log_nrec *n, log_actionkinds act) +{ + gg.actnode = n; + calltool(n->simtype, act); +} + +static void calltoolkind(log_krec *k, log_actionkinds act) +{ + gg.actkind = k; + calltool(k->simtype, act); +} + +static void calltools(log_actionkinds act) +{ + log_tool *tp; + + tp = gg.toolbase; + while (tp != NULL) + { + if (tp->ready) + calltool(tp, act); + tp = tp->next; + } +} + + +static void callsimtools(log_actionkinds act) +{ + log_tool *tp; + + tp = gg.toolbase; + while (tp != NULL) + { + if (tp->ready && tp->simulator) + calltool(tp, act); + tp = tp->next; + } +} + +static void closetool(log_tool *tp) +{ + if (tp->ready) + calltool(tp, act_exit); + tp->ready = false; +} + + +static void closetools() +{ + log_tool *tp; + + tp = gg.toolbase; + while (tp != NULL) + { + closetool(tp); + tp = tp->next; + } +} + diff --git a/log/src/wire.c b/log/src/wire.c new file mode 100644 index 0000000000000000000000000000000000000000..fc378abdbf4f4940606e14255c2deb8ce4116a38 --- /dev/null +++ b/log/src/wire.c @@ -0,0 +1,663 @@ + +#include <p2c/p2c.h> + +/*=================== NEWHW ====================*/ +/*= =*/ +/*= Create a Horizontal Wire. =*/ +/*= =*/ +/*================================================*/ + +static void newhw(log_hwrec **hw) +{ + *hw = (log_hwrec *)Malloc(sizeof(log_hwrec)); + (*hw)->next = gg.hwbase[gg.curpage - 1]; + gg.hwbase[gg.curpage - 1] = *hw; + (*hw)->temp = (na_long)0; +} + + +#define rtn "DISPHW" + + +/*================== DISPHW ====================*/ +/*= =*/ +/*= Dispose of a Horizontal Wire. =*/ +/*= =*/ +/*================================================*/ + +static void disphw(log_hwrec **hw) +{ + log_hwrec *hw1; + + if (gg.traceflag) + fprintf(tracefile, "Dispose hwire %ld\n", (long)(*hw)); + if (*hw == NULL) + return; + hw1 = gg.hwbase[gg.curpage - 1]; + if (*hw == hw1) + { + gg.hwbase[gg.curpage - 1] = (*hw)->next; + } + else + { + while (hw1 != NULL && hw1->next != *hw) + hw1 = hw1->next; + if (hw1 == NULL) + report(10, rtn); + else + hw1->next = (*hw)->next; + } + chpageplace((int)gg.curpage, (*hw)->x1, (*hw)->y, (*hw)->x2, (*hw)->y); + Free(*hw); +} + +#undef rtn + + +/*=================== NEWVW ====================*/ +/*= =*/ +/*= Create a Vertical Wire. =*/ +/*= =*/ +/*================================================*/ + +static void newvw(log_vwrec **vw) +{ + *vw = (log_vwrec *)Malloc(sizeof(log_vwrec)); + (*vw)->next = gg.vwbase[gg.curpage - 1]; + gg.vwbase[gg.curpage - 1] = *vw; + (*vw)->temp = (na_long)0; +} + + +#define rtn "DISW" + + +/*================== DISW ====================*/ +/*= =*/ +/*= Dispose of a Vertical Wire. =*/ +/*= =*/ +/*================================================*/ + +static void dispvw(log_vwrec **vw) +{ + log_vwrec *vw1; + + if (gg.traceflag) + fprintf(tracefile, "Dispose vwire %ld\n", (long)(*vw)); + if (*vw == NULL) + return; + vw1 = gg.vwbase[gg.curpage - 1]; + if (*vw == vw1) + { + gg.vwbase[gg.curpage - 1] = (*vw)->next; + } + else + { + while (vw1 != NULL && vw1->next != *vw) + vw1 = vw1->next; + if (vw1 == NULL) + report(10, rtn); + else + vw1->next = (*vw)->next; + } + chpageplace((int)gg.curpage, (*vw)->x, (*vw)->y1, (*vw)->x, (*vw)->y2); + Free(*vw); +} + +#undef rtn + +/*================== NEWSOLDER =================*/ +/*= =*/ +/*= Create a solder point. =*/ +/*= =*/ +/*================================================*/ + +static void newsolder(log_srec **s) +{ + *s = (log_srec *)Malloc(sizeof(log_srec)); + (*s)->next = gg.sbase[gg.curpage - 1]; + gg.sbase[gg.curpage - 1] = *s; + (*s)->hwire = NULL; + (*s)->hwire2 = NULL; + (*s)->vwire = NULL; + (*s)->vwire2 = NULL; + (*s)->temp = (na_long)0; +} + + +#define rtn "DISPSOLDER" + + +/*================ DISPSOLDER ==================*/ +/*= =*/ +/*= Dispose of a solder point. =*/ +/*= =*/ +/*================================================*/ + +static void dispsolder(log_srec **s) +{ + log_srec *s1; + + if (gg.traceflag) + fprintf(tracefile, "Dispose solder %ld\n", (long)(*s)); + if (*s == NULL) + return; + s1 = gg.sbase[gg.curpage - 1]; + if (*s == s1) + { + gg.sbase[gg.curpage - 1] = (*s)->next; + } + else + { + while (s1 != NULL && s1->next != *s) + s1 = s1->next; + if (s1 == NULL) + report(10, rtn); + else + s1->next = (*s)->next; + } + chpageplace((int)gg.curpage, (*s)->x, (*s)->y, (*s)->x, (*s)->y); + Free(*s); +} + +#undef rtn + +/*================ CLOSERWIRE ==================*/ +/*= =*/ +/*= Find which wire(s) are under the cursor, =*/ +/*= if any. =*/ +/*= =*/ +/*================================================*/ + +static void closerwire(short x, short y) +{ + if (gg.invisible || gg.showconflicts) + { + gg.nearhw = NULL; + gg.nearvw = NULL; + return; + } + gg.nearhw = gg.hwbase[gg.curpage - 1]; + while (gg.nearhw != NULL && + (gg.nearhw->y != y || gg.nearhw->x1 > x || gg.nearhw->x2 < x)) + gg.nearhw = gg.nearhw->next; + gg.nearvw = gg.vwbase[gg.curpage - 1]; + while (gg.nearvw != NULL && + (gg.nearvw->x != x || gg.nearvw->y1 > y || gg.nearvw->y2 < y)) + gg.nearvw = gg.nearvw->next; +} + +/*assumes hw <> nil if hw2 <> nil*/ + +#define rtn "ADDSOLDER" + + +/*================= ADDSOLDER ==================*/ +/*= =*/ +/*= Add a solder point between two wires. =*/ +/*= =*/ +/*================================================*/ + +static void addsolder(short x, short y, log_hwrec *hw, log_hwrec *hw2, log_vwrec *vw, log_vwrec *vw2) +{ + log_srec *s; + log_nrec *n; + + s = gg.sbase[gg.curpage - 1]; + while (s != NULL && (s->x != x || s->y != y)) + s = s->next; + if (s == NULL) { + newsolder(&s); + s->x = x; + s->y = y; + chpageplace((int)gg.curpage, x, y, x, y); + s->hwire = NULL; + s->hwire2 = NULL; + s->vwire = NULL; + s->vwire2 = NULL; + n = NULL; + if (hw != NULL) + n = hw->node; + if (vw != NULL && n == NULL) + n = vw->node; + hidecursor(); + if (gg.glowmode && n != NULL) + drawsolderc(x, y, (int)glowcol(n, (long)gg.color.solder)); + else + drawsolderc(x, y, gg.color.solder); + hidecursor(); + } + if (hw != NULL && hw != s->hwire && hw != s->hwire2) + { + if (s->hwire == NULL) + s->hwire = hw; + else if (s->hwire2 == NULL) + s->hwire2 = hw2; + else + report(1, rtn); + } + if (hw2 != NULL && hw2 != s->hwire && hw2 != s->hwire2) + { + if (s->hwire2 == NULL) + s->hwire2 = hw2; + else + report(2, rtn); + } + if (vw != NULL && vw != s->vwire && vw != s->vwire2) + { + if (s->vwire == NULL) + s->vwire = vw; + else if (s->vwire2 == NULL) + s->vwire2 = vw; + else + report(3, rtn); + } + if (vw2 != NULL && vw2 != s->vwire && vw2 != s->vwire2) + { + if (s->vwire2 == NULL) + s->vwire2 = vw2; + else + report(4, rtn); + } + if (gg.traceflag) + fprintf(tracefile, "Add solder %ld\n", (long)s); +} + +#undef rtn + + +/*================= FINDSOLDER =================*/ +/*= =*/ +/*= Find a solder point at specified position. =*/ +/*= =*/ +/*================================================*/ + +static log_srec *findsolder(short x, short y) +{ + log_srec *s; + + s = gg.sbase[gg.curpage - 1]; + while (s != NULL && (s->x != x || s->y != y)) + s = s->next; + return s; +} + + +/*================= ADDSOLDERT =================*/ +/*= =*/ +/*= Add a solder point at a T-intersection of =*/ +/*= two wires. =*/ +/*= =*/ +/*================================================*/ + +static void addsoldert(log_hwrec *hw, log_vwrec *vw) +{ + if (hw->x1 == vw->x && hw->y != vw->y1 && hw->y != vw->y2) + { + addsolder(hw->x1, hw->y, hw, NULL, vw, NULL); + return; + } + if (hw->x2 == vw->x && hw->y != vw->y1 && hw->y != vw->y2) + { + addsolder(hw->x2, hw->y, hw, NULL, vw, NULL); + return; + } + if (hw->y == vw->y1 && hw->x1 != vw->x && hw->x2 != vw->x) + addsolder(vw->x, vw->y1, hw, NULL, vw, NULL); + else if (hw->y == vw->y2 && hw->x1 != vw->x && hw->x2 != vw->x) + addsolder(vw->x, vw->y2, hw, NULL, vw, NULL); +} + + +/*================== CHGHW/VW ==================*/ +/*= =*/ +/*= Used for deleting wires (see DELHWIRE). =*/ +/*= =*/ +/*================================================*/ + +static void chggate (log_grec *g, int i, log_nrec *oldnode, log_nrec *n); + +static void chgvw (log_vwrec *vw, log_nrec *oldnode, log_nrec *n); + + +#define rtn "CHGHW" + + +static void chghw(log_hwrec *hw, log_nrec *oldnode, log_nrec *n) +{ + log_vwrec *vw; + log_hwrec *hw1; + log_grec *g; + log_srec *s; + short i, px, FORLIM; + + if (gg.traceflag) + fprintf(tracefile, "Change hwire %ld to node %ld\n", (long)hw, (long)n); + switchnode(&hw->node, n); + g = gg.gbase[gg.curpage - 1]; + while (g != NULL) + { + if (abs(g->y - hw->y) <= g->kind->bbmax && + P_ibetweenm((long)hw->x1, (long)g->x, (long)hw->x2, + (long)g->kind->bbmax)) + { + FORLIM = g->kind->numpins; + for (i = 1; i <= FORLIM; i++) + { + px = g->pinpos[i - 1].x; + if (hw->x1 <= px && px <= hw->x2 && g->pinpos[i - 1].y == hw->y && + g->pin[i - 1] == oldnode) + chggate(g, i, oldnode, n); + } + } + g = g->next; + } + vw = gg.vwbase[gg.curpage - 1]; + while (vw != NULL) + { + if (hw->x1 <= vw->x && vw->x <= hw->x2 && vw->y1 <= hw->y && + hw->y <= vw->y2 && vw->node == oldnode) + { + if ((hw->x1 == vw->x || hw->x2 == vw->x || vw->y1 == hw->y || + vw->y2 == hw->y) && + (hw->wcolr == vw->wcolr || hw->wcolr == log_wcol_blue || + vw->wcolr == log_wcol_blue)) + chgvw(vw, oldnode, n); + else + { /*vlsi only*/ + s = gg.sbase[gg.curpage - 1]; + while (s != NULL && (s->x != vw->x || s->y != hw->y)) + s = s->next; + if (s != NULL) + chgvw(vw, oldnode, n); + } + } + vw = vw->next; + } + hw1 = gg.hwbase[gg.curpage - 1]; + while (hw1 != NULL && vlsi) + { + if (hw->y == hw1->y && (hw->x1 == hw1->x2 || hw->x2 == hw1->x1) && + (hw->wcolr == log_wcol_blue || hw1->wcolr == log_wcol_blue) && + hw1->node == oldnode) + chghw(hw1, oldnode, n); + hw1 = hw1->next; + } +} + +#undef rtn + + +#define rtn "CHGVW" + + +static void chgvw(log_vwrec *vw, log_nrec *oldnode, log_nrec *n) +{ + log_hwrec *hw; + log_vwrec *vw1; + log_grec *g; + log_srec *s; + short i, py, FORLIM; + + if (gg.traceflag) + fprintf(tracefile, "Change vwire %ld to node %ld\n", (long)vw, (long)n); + switchnode(&vw->node, n); + g = gg.gbase[gg.curpage - 1]; + while (g != NULL) + { + if (abs(g->x - vw->x) <= g->kind->bbmax && + P_ibetweenm((long)vw->y1, (long)g->y, (long)vw->y2, + (long)g->kind->bbmax)) + { + FORLIM = g->kind->numpins; + for (i = 1; i <= FORLIM; i++) + { + py = g->pinpos[i - 1].y; + if (vw->y1 <= py && py <= vw->y2 && g->pinpos[i - 1].x == vw->x && + g->pin[i - 1] == oldnode) + chggate(g, i, oldnode, n); + } + } + g = g->next; + } + hw = gg.hwbase[gg.curpage - 1]; + while (hw != NULL) + { + if (hw->x1 <= vw->x && vw->x <= hw->x2 && vw->y1 <= hw->y && + hw->y <= vw->y2 && hw->node == oldnode) { + if (hw->x1 == vw->x || hw->x2 == vw->x || vw->y1 == hw->y || + vw->y2 == hw->y) + chghw(hw, oldnode, n); + else + { + s = gg.sbase[gg.curpage - 1]; + while (s != NULL && (s->x != vw->x || s->y != hw->y)) + s = s->next; + if (s != NULL) + chghw(hw, oldnode, n); + } + } + hw = hw->next; + } + vw1 = gg.vwbase[gg.curpage - 1]; + while (vw1 != NULL && vlsi) + { + if (vw->x == vw1->x && (vw->y1 == vw1->y2 || vw->y2 == vw1->y1) && + (vw->wcolr == log_wcol_blue || vw1->wcolr == log_wcol_blue) && + vw1->node == oldnode) + chgvw(vw1, oldnode, n); + vw1 = vw1->next; + } +} + +#undef rtn + +/*================= DELVWIRE ===================*/ +/*= =*/ +/*= Delete a horizontal or vertical wire. =*/ +/*= =*/ +/*================================================*/ + +static int wantsolder(log_srec *s) +{ + struct LOC_wantsolder V; + + V.hasred = false; + V.hasgreen = false; + V.hasyellow = false; + V.hasblue = false; + markcolor(&s->hwire, &V); + markcolor(&s->hwire2, &V); + markcolor((log_hwrec **)(&s->vwire), &V); + markcolor((log_hwrec **)(&s->vwire2), &V); + return (V.hasblue && (V.hasgreen || V.hasyellow || V.hasred)); +} + +static void delhwire(log_hwrec *hw) +{ + log_vwrec *vw; + log_hwrec *hw1; + log_srec *s, *s1; + log_nrec *oldnode, *n, *savenode; + log_grec *g; + short i, x, y, FORLIM; + + if (gg.traceflag) + fprintf(tracefile, "Delete hwire %ld\n", (long)hw); + working(); + clipon(); + m_color((long)gg.color.backgr); + hline(hw->x1, hw->x2, hw->y); + oldnode = hw->node; + stamp(&oldnode->simtype->netstamp); + switchnode(&hw->node, NULL); + savenode = oldnode; + s = gg.sbase[gg.curpage - 1]; + while (s != NULL) + { + s1 = s->next; + if (s->hwire == hw || s->hwire2 == hw) + { + if (s->hwire == hw) + s->hwire = s->hwire2; + s->hwire2 = NULL; + if (!wantsolder(s)) + { + drawsolderc(s->x, s->y, gg.color.backgr); + dispsolder(&s); + } + else + { + if (gg.traceflag) + fprintf(tracefile, "DELHW keeping solder %ld\n", (long)s); + } + } + s = s1; + } + vw = gg.vwbase[gg.curpage - 1]; + while (vw != NULL) + { + if (hw->x1 <= vw->x && vw->x <= hw->x2 && vw->y1 <= hw->y && + hw->y <= vw->y2 && vw->node == oldnode) + { + delgetnode(&savenode, &oldnode, &n); + if (n != oldnode) + chgvw(vw, oldnode, n); + } + vw = vw->next; + } + hw1 = gg.hwbase[gg.curpage - 1]; + while (hw1 != NULL && vlsi) + { + if (hw->y == hw1->y && (hw1->x1 == hw->x2 || hw1->x2 == hw->x1) && + hw1->node == oldnode) { + delgetnode(&savenode, &oldnode, &n); + if (n != oldnode) + chghw(hw1, oldnode, n); + } + hw1 = hw1->next; + } + g = gg.gbase[gg.curpage - 1]; + while (g != NULL) + { + if (abs(g->y - hw->y) <= g->kind->bbmax && + P_ibetweenm((long)hw->x1, (long)g->x, (long)hw->x2, + (long)g->kind->bbmax)) + { + FORLIM = g->kind->numpins; + for (i = 1; i <= FORLIM; i++) + { + if (g->pin[i - 1] == oldnode) + { + x = g->pinpos[i - 1].x; + y = g->pinpos[i - 1].y; + if (hw->x1 <= x && x <= hw->x2 && y == hw->y) + { + delgetnode(&savenode, &oldnode, &n); + if (n != oldnode) + chggate(g, i, oldnode, n); + } + } + } + } + g = g->next; + } + disphw(&hw); + clipoff(); +} + + +static void delvwire(log_vwrec *vw) +{ + log_hwrec *hw; + log_vwrec *vw1; + log_srec *s, *s1; + log_nrec *oldnode, *n, *savenode; + log_grec *g; + short i, x, y, FORLIM; + + if (gg.traceflag) + fprintf(tracefile, "Delete vwire %ld\n", (long)vw); + working(); + clipon(); + m_color((long)gg.color.backgr); + vline(vw->x, vw->y1, vw->y2); + oldnode = vw->node; + stamp(&oldnode->simtype->netstamp); + switchnode(&vw->node, NULL); + savenode = oldnode; + s = gg.sbase[gg.curpage - 1]; + while (s != NULL) + { + s1 = s->next; + if (s->vwire == vw || s->vwire2 == vw) + { + if (s->vwire == vw) + s->vwire = s->vwire2; + s->vwire2 = NULL; + if (!wantsolder(s)) { + drawsolderc(s->x, s->y, gg.color.backgr); + dispsolder(&s); + } + else + { + if (gg.traceflag) + fprintf(tracefile, "DELVW keeping solder %ld\n", (long)s); + } + } + s = s1; + } + hw = gg.hwbase[gg.curpage - 1]; + while (hw != NULL) + { + if (hw->x1 <= vw->x && vw->x <= hw->x2 && vw->y1 <= hw->y && + hw->y <= vw->y2 && hw->node == oldnode) + { + delgetnode(&savenode, &oldnode, &n); + if (n != oldnode) + chghw(hw, oldnode, n); + } + hw = hw->next; + } + vw1 = gg.vwbase[gg.curpage - 1]; + while (vw1 != NULL && vlsi) + { + if (vw->x == vw1->x && (vw1->y1 == vw->y2 || vw1->y2 == vw->y1) && + vw1->node == oldnode) + { + delgetnode(&savenode, &oldnode, &n); + if (n != oldnode) + chgvw(vw1, oldnode, n); + } + vw1 = vw1->next; + } + g = gg.gbase[gg.curpage - 1]; + while (g != NULL) + { + if (abs(g->x - vw->x) <= g->kind->bbmax && + P_ibetweenm((long)vw->y1, (long)g->y, (long)vw->y2, + (long)g->kind->bbmax)) + { + FORLIM = g->kind->numpins; + for (i = 1; i <= FORLIM; i++) + { + if (g->pin[i - 1] == oldnode) + { + x = g->pinpos[i - 1].x; + y = g->pinpos[i - 1].y; + if (vw->y1 <= y && y <= vw->y2 && x == vw->x) + { + delgetnode(&savenode, &oldnode, &n); + if (n != oldnode) + chggate(g, i, oldnode, n); + } + } + } + } + g = g->next; + } + vw1 = vw; + dispvw(&vw); + clipoff(); +} +