%%HP: T(3)A(D)F(.);
@ by Tony Duell
DIR
  DEMO { { "CLK" 5 5 M }
         { "CLK" 10 10 N }
         { "CLK" 20 20 P }
         { "FADD" M N P S C } }
  FADD { { A B CIN SUM COUT }
         { { "HADD" A B S1 C1 } { "HADD" CIN S1 SUM C2 } { "OR" C1 C2 COUT } } }
  HADD { { A B SUM CARRY } { { "XOR" A B SUM } { "AND" A B CARRY } } }
  SIM
    \<< INIT TITLE 1 SWAP
      FOR j NXTSTATE 1 OUT.L SIZE
        FOR i OUT.L i GET NAME.L SWAP POS STATE SWAP GET -4 * 6 + i 1 - 8 *
          + R\->B j 29 + R\->B SWAP 2 \->LIST PIXON
        NEXT
      NEXT 7 FREEZE 0 WAIT DROP TEXT
    \>>
  ALL
    \<< NAME.L NODES
    \>>
  NODES
    \<< 'OUT.L' STO
    \>>
  COMPILE
    \<< NEWC RCL DUP SIZE \-> cir siz
      \<< 1 siz
        FOR i cir i GET COMGATE
        NEXT
      \>>
    \>>
  MUX4 { { A B C D SA SB Y }
         { { "MUX" SA A B YA } { "MUX" SA C D YB } { "MUX" SB YA YB Y } } }
  MUX { { SEL A B Y }
        { { "NOT" SEL NS }
          { "AND" A NS YA }
          { "AND" B SEL YB }
          { "OR" YA YB Y } } }
  MACCNT 3
  TITLE
    \<< ERASE { # 1Eh # 0h } { # 1Eh # 3Fh } LINE OUT.L SIZE 8 MIN 1 SWAP
      FOR i OUT.L i GET \->STR DUP SIZE 1 - 2 SWAP SUB DUP SIZE 5 MIN 1 SWAP
        SUB 2 \->GROB i 1 - 8 * R\->B # 0h SWAP 2 \->LIST SWAP PICT 3
        ROLLD GOR
      NEXT { # 0h # 0h } PVIEW
    \>>
  PPAR { (-6.5,-3.1) (6.5,3.2) X 0 (0,0) FUNCTION Y }
  OUT.L { M N P S C }
  NXTSTATE
    \<< 1 CIRCUIT.L SIZE
      FOR i CIRCUIT.L i GET DUP 1 GET "D" SWAP + OBJ\->
      NEXT 'STATE.CNT' INCR DROP STATE.NEW 'STATE' STO
    \>>
  TMP { { "CLK" 5 5 R } { "CLK" 10 10 Q } { "CLK" 20 20 P } { "MUX" P Q R S } }
  STATE { 1 1 0 0 1 0 0 1 }
  DCLK
    \<< DUP DUP 2 GET SWAP 3 GET \-> n m
      \<< STATE.CNT n m + MOD n \>= SWAP 4 GET SWAP STATE.NEW 3 ROLLD PUT
        'STATE.NEW' STO
      \>>
    \>>
  DLO
    \<< 2 GET 'STATE.NEW' SWAP 0 PUT
    \>>
  DHI
    \<< 2 GET 'STATE.NEW' SWAP 1 PUT
    \>>
  DXOR
    \<< DUP 2 GET STATE SWAP GET OVER 3 GET STATE SWAP GET XOR SWAP 4 GET
      STATE.NEW 3 ROLLD SWAP PUT 'STATE.NEW' STO
    \>>
  DOR
    \<< DUP 2 GET STATE SWAP GET OVER 3 GET STATE SWAP GET OR SWAP 4 GET
      STATE.NEW 3 ROLLD SWAP PUT 'STATE.NEW' STO
    \>>
  DAND
    \<< DUP 2 GET STATE SWAP GET OVER 3 GET STATE SWAP GET AND SWAP 4 GET
      STATE.NEW 3 ROLLD SWAP PUT 'STATE.NEW' STO
    \>>
  DNOT
    \<< DUP 2 GET STATE SWAP GET NOT SWAP 3 GET STATE.NEW 3 ROLLD SWAP PUT
      'STATE.NEW' STO
    \>>
  DBUF
    \<< DUP 2 GET STATE SWAP GET SWAP 3 GET STATE.NEW 3 ROLLD SWAP PUT
      'STATE.NEW' STO
    \>>
  STATE.CNT 100
  STATE.NEW { 1 1 0 0 1 0 0 1 }
  INIT
    \<< NAME.L SIZE CLIST DUP 'STATE' STO 'STATE.NEW' STO 0 'STATE.CNT' STO
    \>>
  COMGATE
    \<< DUP SIZE OVER 1 GET PRIM OVER POS
      IF 0 ==
      THEN MACRO
      ELSE 1 \->LIST SWAP 2 SWAP
        FOR i OVER i GET DUP TYPE
          IF 6 ==
          THEN ADDNAME
          END 1 \->LIST +
        NEXT SWAP DROP 1 \->LIST CIRCUIT.L SWAP + 'CIRCUIT.L' STO
      END
    \>>
  ADDNAME
    \<< NAME.L OVER POS DUP
      IF 0 ==
      THEN DROP NAME.L SWAP + DUP 'NAME.L' STO SIZE
      ELSE SWAP DROP
      END
    \>>
  NEWC
    \<< { } DUP 'CIRCUIT.L' STO 'NAME.L' STO 0 'MACCNT' STO
    \>>
  CIRCUIT.L { { "CLK" 5 5 1 } { "CLK" 10 10 2 } { "CLK" 20 20 3 }
    { "XOR" 1 2 4 } { "AND" 1 2 5 } { "XOR" 3 4 6 } { "AND" 3 4 7 }
    { "OR" 5 7 8 } }
  NAME.L { M N P S1.1 C1.1 S C2.1 C }
  MACRO
    \<< DROP DROP OBJ\-> 1 - \->LIST 'MACCNT' INCR \-> arglist locmac
      \<< OBJ\-> OBJ\-> DROP \-> extrn circ
        \<< 1 circ SIZE
          FOR i circ i GET 2 OVER SIZE
            FOR j DUP j GET DUP TYPE
              IF 6 ==
              THEN extrn OVER POS IF 0 == THEN \->STR 1 OVER SIZE 1 - SUB "." +
                locmac \->STR + "'" + OBJ\-> j SWAP PUT ELSE extrn SWAP POS
                arglist SWAP GET j SWAP PUT END
              END
            NEXT COMGATE
          NEXT
        \>>
      \>>
    \>>
  PRIM { "AND" "OR" "XOR" "NOT" "BUF" "HI" "LO" "CLK" }
  CLIST
    \<< { } SWAP 1 SWAP
      START { 0 } +
      NEXT
    \>>
END
