/*
 *
 * Copyright © 1996 Norlinvest Ltd. All rights reserved.
 * EDComX, EDSpice, EDWin, EE Designer, CompCAD, CAD 1000,
 * CAD ABC and Visionics are trade marks of Norlinvest Ltd.
 * Copyright © 1983 - 2002.
 *
 */

////////////////////////////////////////////////////////////////////////////
// Logic simulation definitions

#include "Prim.h"
#include "LogPrim.h"

#define LSTATE 3   // logic state mask
#define LOW    0   // states
#define XSTAT1 1
#define XSTAT2 2
#define HIGH   3

#define LPOWER 0xc // logic power mask
#define ZIMP   0x0 // power values
#define XPWR1  0x4
#define XPWR2  0x8
#define DRV    0xc

#define OUT_L DRV   + LOW
#define OUT_D XPWR1 + XSTAT1
#define OUT_X DRV   + XSTAT1
#define OUT_Z ZIMP  + XSTAT1
#define OUT_U XPWR1 + XSTAT2
#define OUT_H DRV   + HIGH

#define CHANGE (LSTATE << 8 | LSTATE)
#define RISE   (LOW    << 8 | HIGH)
#define FALL   (HIGH   << 8 | LOW)

#define NOT(st)  (st ^ LSTATE)
#define NOT2(st) (st ^ CHANGE)

///////////////////////////////////////////////////////////////////////////
// DLL Interface

typedef DWORD (CALLBACK* PEEKPROC)(WORD addr);
typedef void  (CALLBACK* POKEPROC)(WORD addr, DWORD state, float risedelay,
                                  float falldelay);

PEEKPROC lpPeek;
POKEPROC lpPoke;

//  Macros for all cases of use callback functions PEEK, POKE, SETUP:
//  parameters:
//    i - input/output start number [0-127]
//    n - number of inputs/outputs for word functions [1-16]
//    s - logic state bit or word of up to 16 logic state bits
//    p - logic power
//    dr, df - rise, fall delay values (float)
//

#define LADDR(i, n, cmd) (i) | (n) << 7 | (cmd) << 12

#define PEEK(i)        (WORD)(*lpPeek)(LADDR(i, 0, 0))
#define PEEK_CHANGE(i) (WORD)(*lpPeek)(LADDR(i, 0, 1))
#define PEEK_EDGE(i)   (WORD)(*lpPeek)(LADDR(i, 0, 2))

#define PEEK_AND(i, n)        (WORD)(*lpPeek)(LADDR(i, n, 4))
#define PEEK_AND_CHANGE(i, n) (WORD)(*lpPeek)(LADDR(i, n, 5))
#define PEEK_AND_EDGE(i, n)   (WORD)(*lpPeek)(LADDR(i, n, 6))

#define PEEK_OR(i, n)        (WORD)(*lpPeek)(LADDR(i, n, 8))
#define PEEK_OR_CHANGE(i, n) (WORD)(*lpPeek)(LADDR(i, n, 9))
#define PEEK_OR_EDGE(i, n)   (WORD)(*lpPeek)(LADDR(i, n, 10))

#define PEEK_WORD(i, n)        (WORD)(*lpPeek)(LADDR(i, n, 12))
#define PEEK_DWORD(i, n)       (*lpPeek)(LADDR(i, n, 12))
#define PEEK_WORD_CHANGE(i, n) (WORD)(*lpPeek)(LADDR(i, n, 13))

#define POKE_ZIMP(i, dr, df)    (*lpPoke)(LADDR(i, 1, 0), 0, dr, df)
#define POKE_OC(i, s, dr, df)   (*lpPoke)(LADDR(i, 1, 1), s, dr, df)
#define POKE_DRV(i, s, dr, df)  (*lpPoke)(LADDR(i, 1, 2), s, dr, df)
#define POKE_XPWR(i, s, dr, df) (*lpPoke)(LADDR(i, 1, 3), s, dr, df)

#define POKE_WORD_ZIMP(i, n, dr, df)    (*lpPoke)(LADDR(i, n, 0), 0, dr, df)
#define POKE_WORD_OC(i, n, s, dr, df)   (*lpPoke)(LADDR(i, n, 1), s, dr, df)
#define POKE_WORD_DRV(i, n, s, dr, df)  (*lpPoke)(LADDR(i, n, 2), s, dr, df)
#define POKE_WORD_XPWR(i, n, s, dr, df) (*lpPoke)(LADDR(i, n, 3), s, dr, df)

#define POKE_ALARM(d) (*lpPoke)(0xFFFF, 1, d, d)
#define KILL_ALARM()  (*lpPoke)(0xFFFF, 0, 0, 0)

#define SETUP_DRV(i, s)         POKE_DRV(i, s, 0, 0)
#define SETUP_OC(i, s)          POKE_OC(i, s, 0, 0)
#define SETUP_ZIMP(i)           POKE_ZIMP(i, 0, 0)
#define SETUP_WORD_DRV(i, n, s) POKE_WORD_DRV(i, n, s, 0, 0)
#define SETUP_WORD_OC(i, n, s)  POKE_WORD_OC(i, n, s, 0, 0)
#define SETUP_WORD_ZIMP(i, n)   POKE_WORD_ZIMP(i, n, 0, 0)

// use in DIGIN & DIGOUT only:
#define PEEK_DIGOUT()  (*lpPeek)(0)
#define POKE_DIGIN(s)  (*lpPoke)(0, s, 0, 0)

// use to XOR n bits of x, the result will be in y  *ved
#define XOR_BITS(x, y, n) { int i, l, k;                  \
							 	    k = 1;                        \
							 	    l = x & 1;                    \
    						 	    for(i = 1; i < n ; ++i)       \
     					     	    l ^= x & (k = k << 1) ? 1 : 0;\
     					     	    y = l & 1 ? HIGH : LOW; }
     					     	
// use to get the max value *ved
#define GET_MAX2(b, c)       (b > c ? b : c)
#define GET_MAX3(b, c, d)    (b > c && b > d ? b : c > d ? c : d)
#define GET_MAX4(b, c, d, e) (b > c && b > d && b > e ? b: c > d && c > e ? \
                                                            c: d > e ? d : e)

