/* ----------------------------------------------------------------P. S. O---
 *  FIRST UPDATE : 2. 20. 91.  all ok!
 *  LIB Ver      : 1.00
 * --------------------------------------------------------------------------
 * Fuse_su		      : 6504 44
 * Internal Security Fuse     : 1
/* ------------------------------------------------------------------------ */
declaration
  dataunit : bit
  ;
  functions
    Program
    Read
    Verify
    Blank_Check
    Security
    Erase
    Auto
  ;
  Manufacturers
    AMD
  ;
  Devices
    dMACH110
  ;
  
		/*  ΥΝΝΝΝΈΥΝΝΝΝΈ          */
  chips =MCLK,  /* [³ 1     28 ³] VCC     */
	  VPP,  /* [³ 2     27 ³] NC      */
          MD0,  /* [³ 3     26 ³] D19     */
	  MD1,  /* [³ 4     25 ³] D18     */
	  MD2,  /* [³ 5     24 ³] D17     */
       I0: D5,  /* [³ 6     23 ³] D16     */
       I1: D6,  /* [³ 7     22 ³] D15     */
       I2: D7,  /* [³ 8     21 ³] D14     */
       I3: D8,  /* [³ 9     20 ³] D4      */
       I4: D9,  /* [³ 10    19 ³] D3      */
       I5:D10,  /* [³ 11    18 ³] D2      */
	   D0,  /* [³ 12    17 ³] P2 :D13 */
	   D1,  /* [³ 13    16 ³] P1 :D12 */
	  GND,  /* [³ 14    15 ³] P0 :D11 */	  
		/*  ΤΝΝΝΝΝΝΝΝΝΝΎ          */
  P0:D11, P1:D12, P2:D13, D2, D3, D4, D14, D15, D16, D17, D18, D19, NC, VCC;

  $v2 = VPP;
  $v3 = VCC;
endd

int pt_no[140] =
  { 3,11,19,27,31,35,39,47,55,63,73,81,89,97,101,105,109,117,125,133,   /* 0 */
    4,12,20,28,32,36,40,48,56,64,74,82,90,98,102,106,110,118,126,134,   /* 1 */
    5,13,21,29,33,37,41,49,57,65,75,83,91,99,103,107,111,119,127,135,   /* 2 */
    6,14,22,30,34,38,42,50,58,66,76,84,92,100,104,108,112,120,128,136,  /* 3 */
    0, 7,15,23,43,51,59,67,70,77,85,93,113,121,129,137,		        /* 4 */
    1, 8,16,24,44,52,60,68,71,78,86,94,114,122,130,138,		        /* 5 */
    2, 9,17,25,45,53,61,69,72,79,87,95,115,123,131,139,		        /* 6 */
   10,18,26,46,54,62,80,88,96,116,124,132};			        /* 7 */
int pt_io[140] =
  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,    
    0, 1, 2, 3, 6, 7, 8, 9,10,11,12,13,16,17,18,19,    
    0, 1, 2, 3, 6, 7, 8, 9,10,11,12,13,16,17,18,19,    
    0, 1, 2, 3, 6, 7, 8, 9,10,11,12,13,16,17,18,19,    
    1, 2, 3, 6, 7, 8,11,12,13,16,17,18};
int end[8] =
 { 20, 20, 20, 20, 16, 16, 16, 12};
int end_d[8] =
 { 0, 20, 40, 60, 80, 96, 112, 128};

int arch_no0[88] =
 {6160,6176,6192,6208,6216,6224,6232,6248,6264,6280,6288,6304,6320,6336,6344,6352,6360,6376,6392,6408,  /* 0 */
  6161,6177,6193,6209,6217,6225,6233,6249,6265,6281,6289,6305,6321,6337,6345,6353,6361,6377,6393,6409,  /* 1 */
  6416,6438,6460,6482,		/* 2 */
  6418,6440,6462,6484,   	/* 3 */
  6420,6168,6184,6200,6240,6256,6272,6442,6486,6296,6312,6328,6368,6384,6400,6464,    /* 4 */
  6422,6169,6185,6201,6241,6257,6273,6444,6488,6297,6313,6329,6369,6385,6401,6466,    /* 5 */
  6424,6446,6468,6490,    	/* 6 */
  6426,6448,6470,6492};    	/* 7 */
int arch_io[88] =
 {0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
  0,   9,   19,  10,
  0,   9,   19,  10,
  0,   1,   2,   3,   6,   7,   8,   9,   10,  11,  12,  13,  16,  17,  18,  19,
  0,   1,   2,   3,   6,   7,   8,   9,   10,  11,  12,  13,  16,  17,  18,  19,
  0,   9,   19,  10,
  0,   9,   19,  10};

int arch_no1[88] =		/* 61 */
 {6162,6178,6194,6210,6218,6226,6234,6250,6266,6282,6290,6306,6322,6338,6346,6354,6362,6378,6394,6410,  /* 0 */
  6163,6179,6195,6211,6219,6227,6235,6251,6267,6283,6291,6307,6323,6339,6347,6355,6363,6379,6395,6411,  /* 1 */
  6417,6439,6461,6483,		/* 2 */
  6419,6441,6463,6485,    	/* 3 */
  6421,6170,6186,6202,6242,6258,6274,6443,6487,6298,6314,6330,6370,6386,6402,6465,    /* 4 */
  6423,6171,6187,6203,6243,6259,6275,6445,6489,6299,6315,6331,6371,6387,6403,6467,    /* 5 */
  6425,6447,6469,6491,    	/* 6 */
  6427,6449,6471,6493};    	/* 7 */

int arch_no2[88] =		/* 62 */
 {6164,6180,6196,6212,6220,6228,6236,6252,6268,6284,6292,6308,6324,6340,6348,6356,6364,6380,6396,6412,  /* 0 */
  6165,6181,6197,6213,6221,6229,6237,6253,6269,6285,6293,6309,6325,6341,6349,6357,6365,6381,6397,6413,  /* 1 */
  6428,6450,6472,6494,		/* 2 */
  6430,6452,6474,6496,    	/* 3 */
  6432,6172,6188,6204,6244,6260,6276,6454,6498,6300,6316,6332,6372,6388,6404,6476,    /* 4 */
  6434,6173,6189,6205,6245,6261,6277,6456,6500,6301,6317,6333,6373,6389,6405,6478,    /* 5 */
  6436,6458,6480,6502};    	/* 6 */

int arch_no3[88] =		/* 63 */
 {6166,6182,6198,6214,6222,6230,6238,6254,6270,6286,6294,6310,6326,6342,6350,6358,6366,6382,6398,6414,  /* 0 */
  6167,6183,6199,6215,6223,6231,6239,6255,6271,6287,6295,6311,6327,6343,6351,6359,6367,6383,6399,6415,  /* 1 */
  6429,6451,6473,6495,		/* 2 */
  6431,6453,6475,6497,    	/* 3 */
  6433,6174,6190,6206,6246,6262,6278,6455,6499,6302,6318,6334,6374,6390,6406,6477,    /* 4 */
  6435,6175,6191,6207,6247,6263,6279,6457,6501,6303,6319,6335,6375,6391,6407,6479,    /* 5 */
  6437,6459,6481,6503};    	/* 6 */

int arch_end[8] =
 { 20, 20,  4,  4, 16, 16,  4,  4};
int arch_end_d[8] =
 {  0, 20, 40, 44, 48, 64, 80, 84};
    
int index, disp_flag;
int pgm_d0, pgm_d1, read_d0, read_d1;
/* -----------------------------------------------------------------------
 * Display processing
 * ----------------------------------------------------------------------- */
int disp(option, p)
int option, p;
{
  if(disp_flag == 1) return(p);
  if(p == 0) {
    if     (option == 'p') @Display 26, index, "Programming ...";    
    else if(option == 'r') @Display 26, index, "Reading ...";      
    else if(option == 'b') @Display 26, index, "Blank checking ...";
    else if(option == 'v') @Display 26, index, "Verifying ...   ";
    else if(option == 's') @Display 26, index, "Securing ...";
    else if(option == 'e') @Display 26, index, "Eraseing ...";
  }
  else {
    if     (option == 'p') @Display 26, index, "Program OK!    ";
    else if(option == 'r') @Display 26, index, "Read OK!   ";
    else if(option == 'b') @Display 26, index, "Blank check OK!   ";
    else if(option == 'v') @Display 26, index, "Verification OK!";
    else if(option == 's') @Display 26, index, "Security OK!";
    else if(option == 'e') @Display 26, index, "Erase OK!   ";
    index ++;
  }
}
/* -----------------------------------------------------------------------
 * init() ---> inital processing
 * ----------------------------------------------------------------------- */
int init()
{
  @Vout 1, 	5.00;
  @Vout 2,	5.00;
  @Vout 3,	5.00;				/* Vcc 5.0 V */
  @Delay 10, @Ms;

  @Out GND,	@G;

  @Out MCLK,     @W;
  @Out VPP,      @W;
  @Out MD[0..2], @W;  
  @Out I[0..5],  @W;
  @Out D[0..15], @W;
  @Out D[16..19],@W;  
  @Out P[0..2],  @W;
  @Out NC,	 @W;
  @Out VCC,	 @W;
  
  @Out VCC,      @L;
  @Out MCLK,     @L;
  @Out VPP,      @L;
  @Out MD[0..2], @L;  
  @Out I[0..5],  @L;
  @Out D[0..15], @L;
  @Out D[16..19],@L;
  @Out P[0..2],  @L;
  @Out NC,	 @L;

  @Out VCC,	 @O;
  @Delay 200, @us;
  @Raising VPP, 2.0, 9.25, 300;
  @Delay 200, @us;
}
int exit()
{
  @Delay 200, @Us;              
  @Falling VPP, 9.25, 2.0, 300;
  @Out VPP,   @F;
  @Delay 200, @Us;                
  @Out VCC,   @F;
}              
int clock()
{
  @Out MCLK, @H;
  @Out MCLK, @L;
}
/* -----------------------------------------------------------------------
 * verify process
 * ----------------------------------------------------------------------- */
int verifyf(address, shift, option)
int address, shift, option;
{
  int data, tmp;

  
  if(shift < 16) data = read_d0 >> shift;
  else           data = read_d1 >> (shift-16);
  data = data & 1; 
  
  if     (option == 'r') @Load data;		/* Read data	   */
  else if(option == 'b') {			/* Blank check     */
    if(data != 1)        @Exit;
  }
  else if(option == 'v') {			/* Verify check    */
    @Store tmp;
    if(tmp&1 != data)    @Exit;
  }
}
/* -----------------------------------------------------------------------
 * put process
 * ----------------------------------------------------------------------- */
int put_data(address, shift)
int address, shift;
{
  int tmp;
  
  tmp = 0;

  @Store tmp;
  
  if(shift < 16) pgm_d0 |= tmp << shift;
  else           pgm_d1 |= tmp << (shift-16);
}
/* ----------------------------------------------------------------------- 
 * convert sub process
 * ----------------------------------------------------------------------- */
int convert_sub(address, shift, option)
int address, shift, option;
{
  @Display  67, 9, address, @d;
  @Set 0, address;  
  
  if(option == 'p') put_data(address, shift);
  else              verifyf(address, shift, option);    
}
/* ----------------------------------------------------------------------- 
 * convert process
 * ----------------------------------------------------------------------- */
int convert(i, j, arr_type, option)
int i, j, arr_type, option;
{
  int k, address, shift;
  
  pgm_d0 = pgm_d1 = 0;

  if(arr_type == 0) {  
    for(k=0; k<end[i]; k++) 
      convert_sub(pt_no[end_d[i]+k]*44+j, pt_io[end_d[i]+k], option);
  }
  else {
    for(k=0; k<arch_end[i]; k++) {
      if(j >= 62 && i == 7) continue;
      
      if(j == 60) {
        address = arch_no0[arch_end_d[i]+k];
      }
      else if(j == 61) {
        address = arch_no1[arch_end_d[i]+k];
      }
      else if(j == 62) {
        address = arch_no2[arch_end_d[i]+k];
      }
      else if(j == 63) {
        address = arch_no3[arch_end_d[i]+k];
      }
      convert_sub(address, arch_io[arch_end_d[i]+k], option);    
    }
  }
}
/* -----------------------------------------------------------------------
 * SUB
 * ----------------------------------------------------------------------- */
int sub(j, arr_type, option)
int j, arr_type, option;
{
  int i;
  
  for(i=0; i<8; i++) {
    @Out MD[0..2],  7;				/* Addressing mode*/
    @Out I[0..5],   @W;
    @Out P[0..2],   @W;
    @Out I[0..5],   j;				/* Input line addressing */  
    @Out P[0..2],   i;				/* Product line addressing */  
    clock();
    if(option == 'p') {
      convert(i, j, arr_type, option);
      @Out MD[0..2],  3;			/* Data in mode */
      @Out D[0..15],  @W;
      @Out D[16..19], @W;
      @Out D[0..15],  pgm_d0;
      @Out D[16..19], pgm_d1;
      clock();
    }
    else {      
      @Out MD[0..2],  1;			/* Verify mode */
      @Out MCLK,      @H;			/* Read data */
      @Out D[0..15],  @Z;
      @Out D[16..19], @Z;
      @In D[0..15],   read_d0;
      @In D[16..19],  read_d1;
      @Out MCLK,      @L;
      convert(i, j, arr_type, option);
    }
  }

  if(option == 'p') {
    @Out MD[0..2],  2;				/* Program mode */
    @Out MCLK,      @H;
    @Delay 50, @Ms;
    @Out MCLK,      @L;
  }
}
/* -----------------------------------------------------------------------
 * Read data from device
 * Blank check
 * Verify
 * ----------------------------------------------------------------------- */
int top(option)
int option;
{
  int j;

  disp(option, 0);
  init();
  
  for(j=0; j<44; j++) 				/* AND array */
    sub(j, 0, option);
    
  for(j=60; j<64; j++)
    sub(j, 1, option);
   
  exit();
  disp(option, 1);
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  int i;
             
  disp('s', 0);      
  init();

  @Out MD[0..2],  4;				/* Security mode*/  
  @Out MCLK, @H;
  @Delay 100, @Ms;
  @Out MCLK, @L;
  
  disp_flag = 1;
  top('b');
  disp_flag = 0;
  disp('s', 1);
}
/* -----------------------------------------------------------------------
 * erase device
 * ----------------------------------------------------------------------- */
int erase_device()
{
  int i;
  
  disp('e', 0);
  init();

  @Out MD[0..2],  5;				/* Erase mode */  
  @Out MCLK, @H;
  @Delay 100, @Ms;
  @Out MCLK, @L;
    
  exit();
  disp_flag = 1;
  top('b');
  disp_flag = 0;
  disp('e', 1);
}
/* -----------------------------------------------------------------------
 * MAIN Porgram
 * ----------------------------------------------------------------------- */
int main()
{
  index = 6;
  disp_flag = 0;

  if     (FUNCTION == Program) {
    erase_device();
    top('p');					/* Program device     */
    top('v');					/* Verify device      */
  }
  else if(FUNCTION == Security) {
    security_device();				/* Security device    */
  }
  else if(FUNCTION == Read) {   		/* Read device        */
    top('r');
    @CheckSumOn;
  }
  else if(FUNCTION == Blank_Check) top('b');	/* Blank check device */
  else if(FUNCTION == Verify)      top('v');	/* Verify device      */
  else if(FUNCTION == Auto) {
    erase_device();				/* Erase device	      */
    top('p');					/* Program device     */
    top('v');					/* Verify device      */
    security_device();	                        /* Security device    */
  }
  else if(FUNCTION == Erase) {
    erase_device();				/* Erase device       */
  }
}
/* ------------------------------- End of program ------------------------ */

  
 