/** Program to convert logic equations
 * of 16 inputs and 8 outputs
 * to a 64-kilobyte truth table.
 * @author Marko Mäkelä (msmakela@nic.funet.fi)
 * @date 9th July 2003, based on a version from 2nd July 2002
 * The equations in this program have been translated from the
 * files in 8296/82s100.tar.gz compiled by André Fachat in 21th November 1998
 * and verified against the 64-kilobyte dumps supplied by Jens Schönfeld.
 *
 * Compilation:
 *	cc -o pla 324744-1.c
 * Example usage:
 *	./pla | diff - pla-dump.bin
 * or
 *	./pla > pla-dump.bin
 */

#include <stdio.h>

/** Extract an input bit
 * @param b	the bit to be extracted
 * @return	nonzero if the input bit b is set
 */
#define I(b) (!!((i) & (1 << b)))

/** @name The input signals.
 * This mapping corresponds to the 82S100 to 27512 adapter made by
 * Jens Schönfeld (jens@ami.ga).  Note also the permutation of outputs
 * in the main loop.
 */
/*@{*/
#define NOROM	I(1)
#define RAMON	I(2)
#define RAMSEL9	I(3)
#define RAMSELA	I(4)
#define NOIO	I(5)
#define NOSCR	I(6)
#define BR_W	I(7)
#define Phi2	I(12)
#define BA8	I(14)
#define BA9	I(13)
#define BA10	I(8)
#define BA11	I(9)
#define BA12	I(11)
#define BA13	I(15)
#define BA14	I(10)
#define BA15	I(0)
/*@}*/

/** @name The output signals. */
/*@{*/
/* CSWFF, write to $ffxx, active high */
#define F0 BA8 && BA9 && BA10 && BA11 && BA12 && BA13 && BA14 && BA15 && !BR_W
/* CS9 selects the $9*** ROM socket - no write protection, active low */
#define F1 !(BA12 && !BA13 && !BA14 && BA15 && NOROM && RAMON && RAMSEL9)
/* CSA selects the $a*** ROM socket - no write protection, active low */
#define F2 !(!BA12 && BA13 && !BA14 && BA15 && NOROM && RAMON && RAMSELA)
/* CSI/O selects the I/O area at $e8xx, active low */
#define F3 !((!BA8 && !BA9 && !BA10 && BA11 && !BA12 && BA13 && BA14 && BA15) \
	     && (NOIO || NOROM && (RAMON || RAMSELA)))
/* CSK+B selects the combined Kernel+Basic ROM, active low */
#define F5 !((NOROM && RAMON && BR_W && !BA13 && BA14 && BA15) ||	 \
	     (NOROM && RAMON && BR_W && BA12 && BA13 && BA15) ||	 \
	     (NOROM && RAMSELA && BR_W && BA12 && BA13 && BA14 && BA15))
/* FA12 is the highest address bit of the combined BASIC/KERNEL ROM */
#define F6 !(BR_W && NOROM && RAMON &&			\
	     ((!BA12 && !BA13 && BA14 && BA15) ||	\
	      (BA12 && BA13 && !BA14 && BA15)))

/* CSE selects the editor ROM, active low */
#define F4 !((NOROM && BR_W && !BA11 && !BA12 && BA13 && BA14 && BA15 && \
	      (RAMON || (RAMSEL9 && RAMSELA))) ||			 \
	     (NOROM && RAMON && BR_W &&					 \
	      BA8 && !BA12 && BA13 && BA14 && BA15) ||			 \
	     (!NOROM && NOIO && BR_W &&					 \
	      BA8 && BA11 && !BA12 && BA13 && BA14 && BA15) ||		 \
	     (NOROM && RAMON && BR_W &&					 \
	      BA9 && !BA12 && BA13 && BA14 && BA15) ||			 \
	     (!NOROM && NOIO && BR_W &&					 \
	      BA9 && BA11 && !BA12 && BA13 && BA14 && BA15) ||		 \
	     (NOROM && RAMON && BR_W &&					 \
	      BA10 && !BA12 && BA13 && BA14 && BA15) ||			 \
	     (!NOROM && NOIO && BR_W &&					 \
	      BA10 && BA11 && !BA12 && BA13 && BA14 && BA15) ||		 \
	     (NOROM && RAMSEL9 && RAMSELA && BR_W &&			 \
	      BA8 && !BA12 && BA13 && BA14 && BA15) ||			 \
	     (NOROM && RAMSEL9 && RAMSELA && BR_W &&			 \
	      BA9 && !BA12 && BA13 && BA14 && BA15) ||			 \
	     (NOROM && RAMSEL9 && RAMSELA && BR_W &&			 \
	      BA10 && !BA12 && BA13 && BA14 && BA15))
/* CASENAI is the select signal for "normal" RAM, active low */
#define F7 !(Phi2 &&						\
	     (!BA15 ||						\
	      (!NOSCR && !BA12 && !BA13 && !BA14) ||		\
	      (NOROM &&						\
	       ((!BA12 && !BA13 && !BA14) ||			\
		(!RAMSEL9 && !BA13 && !BA14) ||			\
		(!RAMSELA && !BA12 && !BA14) ||			\
		(!RAMON && !BA14) ||				\
		(!BR_W && !BA14) ||				\
		(!RAMON && !BA13) ||				\
		(!BR_W && !BA13) ||				\
		(!BR_W && !BA11) ||				\
		(!RAMON && !RAMSEL9 && !BA11 && !BA12) ||	\
		(!RAMON && !RAMSELA && !BA11) ||		\
		(!RAMON && !RAMSELA && !NOIO) ||		\
		(!BR_W && BA8) ||				\
		(!RAMON && !RAMSEL9 && BA8 && !BA12) ||		\
		(!RAMON && !RAMSELA && BA8) ||			\
		(!BR_W && BA9) ||				\
		(!RAMON && !RAMSEL9 && BA9 && !BA12) ||		\
		(!RAMON && !RAMSELA && BA9) ||			\
		(!BR_W && BA10) ||				\
		(!RAMON && !RAMSEL9 && BA10 && !BA12) ||	\
		(!RAMON && !RAMSELA && BA10) ||			\
		(!BR_W && BA12) ||				\
		(!RAMON && !RAMSELA && BA12)))))
/*@}*/

/** The main program
 * @param argc	command line argument count
 * @param argv	command line argument vector
 * @return	zero on successful termination
 */
int
main (int argc, char** argv)
{
  /** The input combination, at least 16 bits */
  register unsigned int i = 0;
  do {
    /** The output combination, 8 bits */
    register unsigned char o = 0;
    /* The outputs are permuted so that they correspond to the adapter
     * made by Jens Schönfeld.
     */
    if (F0) o |= 1 << 6;
    if (F1) o |= 1 << 5;
    if (F2) o |= 1 << 4;
    if (F3) o |= 1 << 3;
    if (F4) o |= 1 << 2;
    if (F5) o |= 1 << 1;
    if (F6) o |= 1 << 0;
    if (F7) o |= 1 << 7;
    putchar (o);
  }
  while (++i & 0xffff);
  return 0;
}
