divert(-1)
   liblog.m4                    Elementary logic gates

* Circuit_macros Version 5.86, copyright (c) 2006 J. D. Aplevich, under    *
* the LaTeX Project Public License. The files of this distribution may be *
* redistributed or modified, provided that this copyright notice is       *
* included, and provided that modifications are clearly marked to         *
* distinguish them from this distribution.  There is no warranty          *
* whatsoever for these files.                                             *

                                Installation directory.  You can set this to
                                the null string if you use an environment
                                variable to tell m4 where to search:
ifdef(`HOMELIB_',,
 `define(`HOMELIB_',`./circuit/')')
#`define(`HOMELIB_',`C:\Dwight\lib\')')

                                Default pic processor: gpic. To make dpic -p
                                the default, change gpic to pstricks here:
ifdef(`m4picprocessor',,`include(HOMELIB_`'gpic.m4)divert(-1)')

`Notes: ==================================================================
  Gates other than BUFFER and NOT have an optional integer argument N
  that sets the number of input locations, which then have labels In1
  to InN.

  BUFFER and NOT gates have In1 only.  If there is a first argument, it
  is a line specification and the gate is drawn along the line as for a
  two-terminal element.

  NEGATED inputs are obtained if the second argument is N (uppercase n).
 ========================================================================='

define(`L_unit',`linewid/10')  `Grid mesh size'
                               `Dimensions in L_units, also for external use:'
define(`G_hht',3)              `gate half-height'
define(`AND_ht',`2*G_hht')     `gate heights and widths ...'
define(`AND_wd',7)
define(`BUF_ht',4)
define(`BUF_wd',3.5)
define(`OR_rad',7)             `OR input radius'
define(`XOR_off',1)            `XOR and NXOR parameter'
define(`N_diam',3/2)           `not-circle diameter'
define(`N_rad',N_diam/2)       `not-circle radius'
define(`NOT_rad',N_rad*L_unit) `scaled not-circle radius eg line chop NOT_rad'
define(`H_ht',2)               `Hysteresis symbol dimen'
define(`Mx_pins',6)            `max number of gate input pins without extensions
                                Possibly 4 is better for negated inputs'
define(`FF_wid',12)            `Bistable'
define(`FF_ht',18)
define(`Mux_wid',8)            `Multiplexer'
define(`Mux_ht',18)
define(`lg_plen',4)            `Logic pin'
define(`lg_pintxt',ifxfig(`"$1"',`"sp_{\scriptsize `$1'}sp_"'))
define(`lg_bartxt',ifxfig(`$1',`$\overline{\hbox{`$1'}}$'))

                               `Scale grid coordinates to world coordinates'
define(`grid_',`(vscal_(L_unit,`$1',`$2'))')
                               `Scale and rotate grid coords to world coords'
define(`svec_',`vec_(vscal_(L_unit,`$1',`$2'))')
                               `Relative svec_'
define(`rsvec_',`Here+svec_(`$1',`$2')')

                                `NOT_circle
                                 convenience for drawing NOT circles'
define(`NOT_circle',`circle diam N_diam*L_unit')

                                `LH_symbol(U|D|L|R|degrees)
                                 logical hysteresis symbol'
define(`LH_symbol',`[ m4tmp_ang = rp_ang; direction_(`$1')
  line from svec_(-H_ht*0.7,-H_ht/2) to svec_(H_ht*0.35,-H_ht/2) \
    then to svec_(H_ht*0.35,H_ht/2)
  line from svec_(H_ht*0.7,H_ht/2) to svec_(-H_ht*0.35,H_ht/2) \
    then to svec_(-H_ht*0.35,-H_ht/2)
  point_(m4tmp_ang) ] ')

                                `LT_symbol(U|D|L|R|degrees)
                                 triangle_symbol'
define(`LT_symbol', `[ m4tmp_ang = rp_ang; direction_(`$1')
  line to svec_(0,H_ht*5/8) then to svec_(H_ht,0) \
    then to svec_(0,-H_ht*5/8) then to Here
  point_(m4tmp_ang) ] ')

                                `BOX_gate(inputs,output,swid,sht,label)
                                 drawn in the current direction
                                 inputs=[P|N]* output=P|N'
define(`BOX_gate',`dnl
define(`m4m',`ifelse(`$1',,2,len(`$1'))')define(`m4a',`$1')dnl
define(`m4h',`ifelse(`$3',,AND_wd,`$3')')dnl
define(`m4v',`ifelse(`$4',,AND_wd,`$4')')dnl
[ {[line to svec_(0,m4v/2) then to svec_(m4h,m4v/2) then to svec_(m4h,-m4v/2) \
    then to svec_(0,-m4v/2) then to (0,0)]}
  ifelse(`$5',,,`{ move to last [].n+(0,-5pt__)
    m4lstring($5,"{\scriptsize$ $5 $}") }')
  IOdefs(from svec_(0,m4v/2) to svec_(0,-m4v/2),In,`$1',R)
  Out: svec_(m4h,0) ifelse(`$2',N,`+svec_(N_diam,0)
    N_Out: NOT_circle at Out-svec_(N_rad,0)') ]')

                                `AND_gate(n,[N][B],wid,ht)
                                 drawn in the current direction
                                 0 <= n <= 16; N=negated inputs, B=box shape'
define(`AND_gate',`ifelse(index(`$2',B),-1,
`AND_gen(ifelse(`$1',,2,`$1'),ifelse(`$2',N,N)IBAONESEC,`$3',`$4')',
`m4_m4t(`$1',`$2') BOX_gate(m4t,P,`$3',`$4',\&)')')

define(`m4_m4t',`define(`m4_t',`ifelse(index(`$2',N),-1,P,N)')define(`m4t',)dnl
for_(1,ifelse(`$1',,2,`$1'),1,`define(`m4t',m4t`'m4_t)dnl')')

                                `NAND_gate(n,[N][B],wid,ht)
                                 0 <= n <= 16; N=negated inputs, B=box shape'
define(`NAND_gate',`ifelse(index(`$2',B),-1,
`AND_gen(ifelse(`$1',,2,`$1'),ifelse(`$2',N,N)IBANONESEC,`$3',`$4')',
`m4_m4t(`$1',`$2') BOX_gate(m4t,N,`$3',`$4',\&)')')

                                `AND_gen(n,chars,[wid,[ht]])
                                 0 <= n <= 16;
                                 B=base and straight sides; A=Arc;
                                 [N]NE,[N]SE,[N]I,[N]N,[N]S=inputs or circles;
                                 [N]O=output; C=center location '
define(`AND_gen',
 `define(`m4h',`ifelse(`$3',,AND_wd,`($3)/(L_unit)')')dnl
  define(`m4v',`ifelse(`$4',,ifelse(`$3',,AND_ht,AND_ht/(AND_wd)*m4h),
   `($4)/(L_unit)')')define(`dna_',`$2')dnl
 [ sc_draw(`dna_',B,dnl
   `line from svec_(m4h-m4v/2,-m4v/2) to svec_(0,-m4v/2) then to svec_(0,m4v/2)\
     then to svec_(m4h-m4v/2,m4v/2)')
  sc_draw(`dna_',A, `Arc: arc cw rad m4v/2 to rsvec_(0,-m4v) \
     with .c at rsvec_(0,-m4v/2)')
  sc_draw(`dna_',NNE,
   `NNE: svec_(m4h-m4v/2,0)+svec_(Rect_(m4v/2+N_diam,45))
    N_NNE: NOT_circle at svec_(m4h-m4v/2,0)+svec_(Rect_(m4v/2+N_rad,45))')
  sc_draw(`dna_',NSE,
   `NSE: svec_(m4h-m4v/2,0)+svec_(Rect_(m4v/2+N_diam,-45))
    N_NSE: NOT_circle at svec_(m4h-m4v/2,0)+svec_(Rect_(m4v/2+N_rad,-45))')
  sc_draw(`dna_',NE, `NE: svec_(m4h-m4v/2,0)+svec_(Rect_(m4v/2,45))')
  sc_draw(`dna_',NI, `m4A_defs(ifelse(`$1',,2,`$1'),N)')
  sc_draw(`dna_',SE, `SE: svec_(m4h-m4v/2,0)+svec_(Rect_(m4v/2,-45))')
  sc_draw(`dna_',NN, `N_NN: NOT_circle at svec_((m4h-m4v/2)/2,m4v/2+N_rad)
                      NN: svec_((m4h-m4v/2)/2,m4v/2+N_diam)')
  sc_draw(`dna_',NS, `N_NS: NOT_circle at svec_((m4h-m4v/2)/2,-m4v/2-N_rad)
                      NS: NOT_circle at svec_((m4h-m4v/2)/2,-m4v/2-N_diam)')
  sc_draw(`dna_',NO, `N_Out: NOT_circle at svec_(m4h+N_rad,0)
                      Out: svec_(m4h+N_diam,0)')
  sc_draw(`dna_',O, `Out: svec_(m4h,0)')
  sc_draw(`dna_',N, `N: svec_(0,m4v/2)')
  sc_draw(`dna_',I, `m4A_defs(ifelse(`$1',,2,`$1'))')
  sc_draw(`dna_',S, `S: svec_(0,-m4v/2)')
  sc_draw(`dna_',C, `C: svec_(m4h/2,0)')
 ]')

                                `m4A_defs(n,[N]) Input locations, flat face'
define(`m4A_defs',
 `define(`m4m',`m4v/2/min(`$1',Mx_pins-1)*min(`$1',3*(Mx_pins-1))')dnl
  ifelse(eval(`$1'>Mx_pins),1,
   `line from svec_(0, m4m) to svec_(0,m4v/2)
    line from svec_(0,-m4m) to svec_(0,-m4v/2)')
  for_(1,`$1',1,`ifelse(`$2',N,
   `N_In`'m4x: NOT_circle at \
      svec_(-N_rad,m4v/min(`$1',Mx_pins-1)*((`$1'+1)/2-m4x))
    In`'m4x: svec_(-N_diam,m4v/min(`$1',Mx_pins-1)*((`$1'+1)/2-m4x)) ',
   `In`'m4x: svec_(0,m4v/min(`$1',Mx_pins-1)*((`$1'+1)/2-m4x))') ') ')

                                `OR_gate(n,[N][B],wid,ht)
                                 drawn in the current direction
                                 0 <= n <= 16; N=negated inputs, B=box shape'
define(`OR_gate',`ifelse(index(`$2',B),-1,
`OR_gen(ifelse(`$1',,2,`$1'),ifelse(`$2',N,N)IBAONESEC,`$3',`$4')',
`m4_m4t(`$1',`$2') BOX_gate(m4t,P,`$3',`$4',\geq 1)')')

                                `NOR_gate(n,[N|B],wid,ht)
                                 0 <= n <= 16; N=negated inputs, B=box shape'
define(`NOR_gate',`ifelse(index(`$2',B),-1,
`OR_gen(ifelse(`$1',,2,`$1'),ifelse(`$2',N,N)IBANONESEC,`$3',`$4')',
`m4_m4t(`$1',`$2') BOX_gate(m4t,P,`$3',`$4',\geq 1)')')

                                `XOR_gate(n,[N|B],wid,ht)
                                 0 <= n <= 16; N=negated inputs, B=box shape'
define(`XOR_gate',`ifelse(index(`$2',B),-1,
`OR_gen(ifelse(`$1',,2,`$1'),P`'ifelse(`$2',N,N)IBAONESEC,`$3',`$4')',
`m4_m4t(`$1',`$2') BOX_gate(m4t,P,`$3',`$4',=)')')

                                `NXOR_gate(n,[N|B],wid,ht)
                                 0 <= n <= 16; N=negated inputs, B=box shape'
define(`NXOR_gate',`ifelse(index(`$2',B),-1,
`OR_gen(ifelse(`$1',,2,`$1'),P`'ifelse(`$2',N,N)IBANONESEC,`$3',`$4')',
`m4_m4t(`$1',`$2') BOX_gate(m4t,P,`$3',`$4',\geq 1)')')

                                `OR_gen(n,chars,[wid,[ht]])
                                 0 <= n <= 16;
                                 B=base and straight sides; A=Arcs;
                                 [N]NE,[N]SE,[N]I,[N]N,[N]S=inputs or circles;
                                 [N]P=XOR arc; [N]O=output; C=center '
define(`OR_gen',
 `define(`m4h',`ifelse(`$3',,AND_wd,`($3)/(L_unit)')')define(`m4o',0)dnl
  define(`m4v',`ifelse(`$4',,ifelse(`$3',,AND_ht,AND_ht/(AND_wd)*m4h),
   `($4)/(L_unit)')')define(`dna_',`$2')dnl
 [sc_draw(`dna_',P,`define(`m4o',XOR_off*m4v/(AND_ht))dnl
    arc cw from svec_(0,m4v/2) to svec_(0,-m4v/2) \
      with .c at svec_(-sqrt((OR_rad*m4v/(AND_ht))^2-(m4v/2)^2),0)')
  sc_draw(`dna_',B,dnl
   `line from svec_(m4o+m4h/3,m4v/2) to svec_(m4o,m4v/2)
    arc cw to svec_(m4o,-m4v/2) \
      with .c at svec_(m4o-sqrt((OR_rad*m4v/(AND_ht))^2-(m4v/2)^2),0)
    line to svec_(m4o+m4h/3,-m4v/2)')
  sc_draw(`dna_',A,`define(`m4m',`((m4h*2/3)^2-(m4v/2)^2)/(m4v)')dnl
   ArcN: arc  cw from svec_(m4o+m4h/3, m4v/2) to svec_(m4o+m4h,0) \
     with .c at svec_(m4o+m4h/3,-m4m)
   ArcS: arc ccw from svec_(m4o+m4h/3,-m4v/2) to svec_(m4o+m4h,0) \
     with .c at svec_(m4o+m4h/3,m4m)')
  sc_draw(`dna_',NNE,
   `N_NNE: NOT_circle at svec_(m4o+m4h/3,-m4m)+svec_(Rect_(m4v/2+m4m+N_rad,60))
    NNE: svec_(m4o+m4h/3,-m4m)+svec_(Rect_(m4v/2+m4m+N_diam,60))')
  sc_draw(`dna_',NSE,
   `N_NSE: NOT_circle at svec(m4o+m4h/3,m4m)+svec_(Rect_(m4v/2+m4m+N_rad,-60))
    NSE: svec(m4o+m4h/3,m4m)+svec_(Rect_(m4v/2+m4m+N_diam,-60))')
  sc_draw(`dna_',NE, `NE: svec_(m4o+m4h/3,-m4m)+svec_(Rect_(m4v/2+m4m,60))')
  sc_draw(`dna_',SE, `SE: svec_(m4o+m4h/3,m4m)+svec_(Rect_(m4v/2+m4m,-60))')
  sc_draw(`dna_',NI, `m4O_defs(ifelse(`$1',,2,`$1'),N)')
  sc_draw(`dna_',NN, `N_NN: NOT_circle at svec_(m4o+m4h/6,m4v/2+N_rad)
                      NN: svec_(m4o+m4h/6,m4v/2+N_diam)')
  sc_draw(`dna_',NS, `N_NS: NOT_circle at svec_(m4o+m4h/6,-m4v/2-N_rad)
                      NS: svec_(m4o+m4h/6,-m4v/2-N_diam)')
  sc_draw(`dna_',NO, `N_Out: NOT_circle at svec_(m4o+m4h+N_rad,0)
                      Out: svec_(m4o+m4h+N_diam,0)')
  sc_draw(`dna_',O, `Out: svec_(m4o+m4h,0)')
  sc_draw(`dna_',N, `N: svec_(m4o+m4h/6,m4v/2)')
  sc_draw(`dna_',I, `m4O_defs(ifelse(`$1',,2,`$1'))')
  sc_draw(`dna_',S, `S: svec_(m4o+m4h/6,-m4v/2)')
  sc_draw(`dna_',C, `C: svec_(m4o+m4h/2,0)')
 ]')

                                `m4O_defs(n,[N]) Input locations, curved face'
define(`m4O_defs',
 `define(`m4om',`m4v/2/min(`$1',Mx_pins-1)*min(`$1',3*(Mx_pins-1))')dnl
  ifelse(eval(`$1'>Mx_pins),1,
   `arc ccw from svec_(0,m4v/2) to svec_(0,m4v) + OR_apos(m4om-m4v) \
      with .c at svec_(-OR_dst,m4v)
    arc cw from svec_(0,-m4v/2) to svec_(0,-m4v) +OR_apos(-(m4om-m4v))\
      with .c at svec_(-OR_dst,-m4v) ')
  define(`m4on',`eval((`$1'-Mx_pins+1)/2)')
  for_(1,`$1',1,
   `define(`m4oq',`m4v/2/min(`$1',Mx_pins-1)*(`$1'+1-2*m4x)')
    In`'m4x: ifelse(eval(m4x<=m4on),1,`svec_(0, m4v)+OR_apos(m4oq-m4v)',
      eval(m4x>(`$1'-m4on)),1,        `svec_(0,-m4v)+OR_apos(m4oq+m4v)',
      `OR_apos(m4oq)')
    ifelse(`$2',N,
     `N_In`'m4x: NOT_circle at In`'m4x+svec_(-N_rad,0)
      In`'m4x: In`'m4x+svec_(-N_diam,0)')
    ')
  ')
define(`OR_dst',`sqrt((OR_rad*m4v/(AND_ht))^2-(m4v/2)^2)')
define(`OR_apos',`svec_(-OR_dst+sqrt((OR_rad*m4v/(AND_ht))^2-(`$1')^2),`$1')')

                                `IOdefs(linespec,label,[P|N]*,L|R)
                                 Distribute named locations with optional NOT
                                 circles along a line
                                 eg IOdefs(up 1,Z,PNN,R) defines Z1 at 1/6
                                 along the line, NOT circles N_Z2 and N_Z3 to
                                 the right at 1/2 and 5/6 along the line with
                                 Z2 and Z3 labeled at their right edges'
define(`IOdefs',`define(`m4dm',`ifelse(`$3',,1,len(`$3'))')m4IOtmp = rp_ang
eleminit_(`$1')define(`m4da',`$3')define(`m4dv',`ifelse(`$2',,In,`$2')')
  for_(1,m4dm,1,
   `m4dv`'m4x: last line.start+vec_((m4x-1/2)*rp_len/m4dm,0)dnl
    ifelse(substr(m4da,0,1),N,`+svec_(0,ifelse(`$4',R,-)N_diam)
      {N_`'m4dv`'m4x: NOT_circle at m4dv`'m4x+svec_(0,ifelse(`$4',R,,-)N_rad)}')
    define(`m4da',substr(m4da,1))')  rp_ang = m4IOtmp')

                                `BUFFER_gate(linespec,[N|B],wid,ht)
                                 When linespec is blank then the element is
                                 composite and In1, Out, C, NE, and SE are
                                 defined; otherwise the element is drawn as
                                 two-terminal'
define(`BUFFER_gate',`ifelse(index(`$2',B),-1,
 `ifelse(`$1',,
   `BUFFER_gen(ifelse(`$2',N,N)ITOCNESE,`$3',`$4')',
   `eleminit_(`$1')
    { BUFFER_gen(ifelse(`$2',N,N)ITOC,`$3',`$4') with .C at last line.c }
    { line to last [].In1; line from last [].Out to 2nd last line.end }
    line to rvec_(rp_len,0) invis')',
 `BOX_gate(ifelse(index(`$2',N),-1,P,N),P,`$3',`$4',1)')')

                                `NOT_gate(linespec,[N|B],wid,ht)
                                 When linespec is blank then the element is
                                 composite and In1, Out, C, NE, and SE are
                                 defined; otherwise the element is drawn as
                                 two-terminal'
define(`NOT_gate',`ifelse(index(`$2',B),-1,
 `ifelse(`$1',,
   `BUFFER_gen(ifelse(`$2',N,N)ITNOCNESE,`$3',`$4')',
   `eleminit_(`$1')
    { BUFFER_gen(ifelse(`$2',N,N)ITNOC,`$3',`$4') with .C at last line.c }
    { line to last [].In1; line from last [].Out to 2nd last line.end }
    line to rvec_(rp_len,0) invis')',
 `BOX_gate(ifelse(index(`$2',N),-1,P,N),N,`$3',`$4',1)')')

                                `BUFFER_gen(chars,wd,ht,[N|P]*,[N|P]*,[N|P]*)
                                 chars: T=triangle, [N]O=output location Out
                                 (NO draws circle N_Out);
                                 [N]I,[N]N,[N]S,[N]NE,[N]SE input locations
                                 C=centre location.  Args 4-6 define In, NE,
                                 and SE argument sequences'
define(`BUFFER_gen',
 `define(`m4h',`ifelse(`$2',,BUF_wd,`($2)/(L_unit)')')define(`m4y',m4h)dnl
  define(`m4v',`ifelse(`$3',,BUF_ht,`($3)/(L_unit)')')dnl
  define(`dna_',`$1')define(`m4z',`N_rad/vlength(m4h,m4v/2)')dnl
 [sc_draw(`dna_',T,
   `line from svec_(m4h,0) to svec_(0,-m4v/2) then to svec_(0,m4v/2) \
     then to svec_(m4h,0)')
  sc_draw(`dna_',NNE,
   `N_NNE: NOT_circle at svec_(m4h/2,m4v/4)+svec_(m4v/2*m4z,m4h*m4z)
    NNE: svec_(m4h/2,m4v/4)+svec_(m4v*m4z,m4h*2*m4z)')
  sc_draw(`dna_',NSE,
   `N_NSE: NOT_circle at svec_(m4h/2,-m4v/4)-svec_(-m4v/2*m4z,m4h*m4z)
    NSE: svec_(m4h/2,-m4v/4)-svec_(-m4v*m4z,m4h*2*m4z)')
  sc_draw(`dna_',NI,`define(`m4y',m4y+N_diam) In1: svec_(-N_diam,0)
    N_In1: NOT_circle at svec_(-N_rad,0)')
  sc_draw(`dna_',NE, `NE: svec_(m4h/2,m4v/4)')
  sc_draw(`dna_',SE, `SE: svec_(m4h/2,-m4v/4)')
  sc_draw(`dna_',NN, `N_NN: NOT_circle at svec_(0,m4v/2+N_rad)
                      NN: svec_(0,m4v/2+N_diam)')
  sc_draw(`dna_',NS, `N_NS: NOT_circle at svec_(0,-m4v/2-N_rad)
                      NS: svec_(0,-m4v/2-N_diam)')
  sc_draw(`dna_',NO,`define(`m4y',m4y+N_diam) Out: svec_(m4h+N_diam,0)
    N_Out: NOT_circle at svec_(m4h+N_rad,0)')
  sc_draw(`dna_',N, `N: svec_(0,m4v/2)')
  sc_draw(`dna_',S, `S: svec_(0,-m4v/2)')
  sc_draw(`dna_',O, `Out: svec_(m4h,0)')
  sc_draw(`dna_',I, `In1: (0,0)')
  sc_draw(`dna_',C, `C: svec_(m4h/2,0)')
  ifelse(`$4',,,`IOdefs(from svec_(0,m4v/2) to svec_(0,-m4v/2),In,`$4',R)')
  ifelse(`$5',,,`IOdefs(from svec_(0,m4v/2) to svec_(m4h,0),NE,`$5')')
  ifelse(`$6',,,`IOdefs(from svec_(0,-m4v/2) to svec_(m4h,0),SE,`$6',R)')]')

                                `The comprehensive logic pin:
   lg_pin(location, logicalname, Pinlabel, n|e|s|w[N|L|M][E], pinno, optlen)
     n|e|s|w=orientation;
     N=negated; L=active low out; M=active low in; E=edge trigger'
define(`lg_pin',`ifelse(`$1',,,`move to $1')
  define(`dna_',`substr(`$4',1)')define(`m4lE',)define(`m4lN',)dnl
  define(`m4ld',`ifelse(`$4',,e,`substr(`$4',0,1)')')dnl
  define(`m4lph',`ifelse(m4ld,n,0,m4ld,w,-1,m4ld,s,0,1)')dnl
  define(`m4lpv',`ifelse(m4ld,n,1,m4ld,w,0,m4ld,s,-1,0)')dnl
  define(`m4lpl',`ifelse(`$6',,`lg_plen',`$6')')dnl
  sc_draw(`dna_',E,`define(`m4lE',1)dnl
    { line from rsvec_(lp_xy(0,N_rad)) \
      to rsvec_(lp_xy(-N_diam*sqrt(3)/2,0)) then to rsvec_(lp_xy(0,-N_rad)) }')
  ifelse(`$2',,,
   `{ lg_pintxt(`$2') ifelse(m4ld,w,`ljust_', m4ld,n,`below_',
      m4ld,s,`above_',`rjust_') at Here dnl
      ifxfig(`+(lp_xy(-0.72bp__,0))') dnl
      ifelse(m4lE,1,`+svec_(lp_xy(-N_diam*sqrt(3)/2,0))') }')
  sc_draw(`dna_',N,`define(`m4lN',N)
    { NOT_circle at rsvec_(lp_xy(N_rad,0)) }')
  sc_draw(`dna_',L,`define(`m4lN',M)
    {line from rsvec_(lp_xy(0,
      ifelse(m4ld,w,-,m4ld,s,-)N_rad*3/2)) to rsvec_(lp_xy(N_rad*2.5,0)) }')
  sc_draw(`dna_',M,`define(`m4lN',M)
    { line to rsvec_(lp_xy(N_rad*2.5,
      ifelse(m4ld,w,-,m4ld,s,-)N_rad*3/2)) then to rsvec_(lp_xy(N_rad*2.5,0))}')
  {ifelse(`$3',,,`$3':) line to rsvec_(lp_xy(m4lpl,0))dnl
   ifelse(m4lN,N,`chop N_diam*L_unit chop 0')
   ifelse(`$5',,,`lg_pintxt(`$5') dnl
     at rsvec_(lp_xy(vscal_(1/(L_unit),2pt__,0))) dnl
     ifgpic(
      `ifelse(m4ld,n,`+svec_(lp_xy(4pt__/(L_unit),0)) rjust_ below_',
              m4ld,w,`+svec_(lp_xy(vscal_(1/(L_unit),1pt__,3pt__))) \
                      ljust_ above_',
              m4ld,s,`+svec_(lp_xy(2pt__/(L_unit),0)) rjust_ above_',
                     `+svec_(lp_xy(0,-3pt__/(L_unit))) rjust_ above_') ',
      `ifelse(m4ld,n,`rjust_ below_', m4ld,w,`ljust_ above_',
                     `rjust_ above_')')') dnl
   } ')
define(`lp_xy',`vrot_(`$1',`$2',m4lph,m4lpv)')

                                `Mux(inputs, label, [L][T])
                                 Binary multiplexer: L reverses pin numbering,
                                 T puts Sel at the top'
define(`Mux',`[
Chip: [line from svec_(-Mux_wid/2, 0) to svec_(-Mux_wid/2, Mux_ht/2) \
       then to svec_(Mux_wid/2, (Mux_ht/2)-2) \
       then to svec_(Mux_wid/2, -(Mux_ht/2)+2) \
       then to svec_(-Mux_wid/2, -Mux_ht/2) then to svec_(-Mux_wid/2, 0) ]
  ifelse(`$2',,,`"\scriptsize $2" at Chip.c')
  lg_pin(Chip.e_,,Out,e)
  ifelse(index(`$3',T),-1,
    `lg_pin(Chip.s_+svec_(0,1),$\;$Sel,Sel,s)',
    `lg_pin(Chip.n_+svec_(0,-1),$\;$Sel,Sel,n)')
  for_(1,ifelse(`$1',,2,`$1'),1,
   `lg_pin(Chip.w_+svec_(0,
     ifelse(index(`$3',L),-1,,-)Mux_ht*(0.5+(0.5-m4x)/ifelse(`$1',,2,`$1'))),
     decr(m4x),In`'decr(m4x),w)')
  ]')

                                `FlipFlop( D|T|RS|JK, label, boxspec )'
define(`FlipFlop',
  `ifelse(`$1',D,`FlipFlop6(`$2',DCKQNQ,`$3')',
  `$1',T,`FlipFlop6(`$2',TCKQNQ,`$3')',
  `$1',RS,`FlipFlop6(`$2',RSQNQ,`$3')',
  `$1',JK,`FlipFlopJK(`$2',JnCKKnCLRnPRQNQ,`$3')',
  `FlipFlop6(`$2',.QNQ,`$3')')dnl
  ')
                                `FlipFlop6( label, spec, boxspec )
                                 Customizable 6-pin flipflop:
                                 The spec string contains NQ, Q, CK, S, PR,
                                 CLR to include these pins.  Preceding any of
                                 these with n negates the pin.  Any other
                                 substring applies to the top left pin, with
                                 . equating to a blank'
define(`FlipFlop6',`[ dnl
 Chip: box ifelse(`$3',,`wid_ FF_wid*L_unit ht_ FF_ht*L_unit',`$3')
   ifelse(`$1',,,`"\scriptsize $1" at Chip.c')
   define(`M4_spec',`ifelse(`$2',,.QnNQ,$2)')dnl
   M4_ffs(`M4_spec',NQ)ifelse(m4h,-1,,
    `lg_pin(Chip.se_+svec_(0,int(FF_ht/4)),lg_bartxt(Q),PinNQ,e`'m4N)')
   M4_ffs(`M4_spec',Q)ifelse(m4h,-1,,
    `lg_pin(Chip.ne_-svec_(0,int(FF_ht/4)),Q,PinQ,e`'m4N)')
   M4_ffs(`M4_spec',CK)ifelse(m4h,-1,,
    `lg_pin(Chip.sw_+svec_(0,int(FF_ht/4)),CK,PinCK,wE`'m4N)')
   M4_ffs(`M4_spec',S)ifelse(m4h,-1,,
    `lg_pin(Chip.sw_+svec_(0,int(FF_ht/4)),S,PinS,w`'m4N)')
   M4_ffs(`M4_spec',PR)ifelse(m4h,-1,, dnl thanks to Louis Dupont
    `lg_pin(Chip.s_,PR,PinPR,s`'m4N)')
   M4_ffs(`M4_spec',CLR)ifelse(m4h,-1,,
    `lg_pin(Chip.n_,CLR,PinCLR,n`'m4N)')
   ifelse(M4_spec,,,
    `define(`m4N',ifelse(substr(M4_spec,0,1),n,
      `define(`M4_spec',substr(M4_spec,1))'N,))dnl
     ifelse(M4_spec,.,`define(`M4_spec',)')dnl
     lg_pin(Chip.nw_-svec_(0,int(FF_ht/4)),M4_spec,Pin`'M4_spec,w`'m4N) ')
  ]')

                                `FlipFlopJK( label, spec, boxspec )
                                 Customizable JK flipflop (see FlipFlop6)
                                 with pins NQ, Q, CK, PR, CLR, K, top-left'
define(`FlipFlopJK',`[ define(`m4u',int(FF_ht/4))dnl
 Chip: box ifelse(`$3',,`wid_ FF_wid*L_unit ht_ FF_ht*L_unit',`$3')
   ifelse(`$1',,,`"\scriptsize $1" at Chip.c')
   define(`M4_spec',`ifelse(`$2',,JnCKKnCLRnPRQNQ,$2)')dnl
   M4_ffs(`M4_spec',NQ)ifelse(m4h,-1,,
    `lg_pin(Chip.se_+svec_(0,m4u),lg_bartxt(Q),PinNQ,e`'m4N)')
   M4_ffs(`M4_spec',Q)ifelse(m4h,-1,,
    `lg_pin(Chip.ne_-svec_(0,m4u),Q,PinQ,e`'m4N)')
   M4_ffs(`M4_spec',CK)ifelse(m4h,-1,,`lg_pin(Chip.w_,CK,PinCK,wE`'m4N)')
   M4_ffs(`M4_spec',PR)ifelse(m4h,-1,,`lg_pin(Chip.s_,PR,PinPR,s`'m4N)')
   M4_ffs(`M4_spec',CLR)ifelse(m4h,-1,,`lg_pin(Chip.n_,CLR,PinCLR,n`'m4N)')
   M4_ffs(`M4_spec',K)ifelse(m4h,-1,,
    `lg_pin(Chip.sw_+svec_(0,m4u),K,PinK,w`'m4N)')
   ifelse(M4_spec,,,
    `define(`m4N',ifelse(substr(M4_spec,0,1),n,
      `define(`M4_spec',substr(M4_spec,1))'n,))dnl
     ifelse(M4_spec,.,`define(`M4_spec',)')dnl
     lg_pin(Chip.nw_-svec_(0,int(FF_ht/4)),M4_spec,Pin`'M4_spec,w`'m4N) ')
  ]')
define(`M4_ffs',`define(`m4h',index($1,`$2'))dnl
  ifelse(m4h,-1,,`define(`m4v',eval(m4h+len($2)))dnl
  define(`m4N',ifelse(substr($1,decr(m4h),1),n,`define(`m4h',decr(m4h))'N,))dnl
  define(`$1',substr($1,0,m4h)`'substr($1,m4v)) ')')

define(`log_init',`gen_init')
divert(0)dnl