my old Parallel EEproms programmer :)

(MPLAB PM3, PICSTART Plus, PICkit 2, PICkit 3) Topics covered in this conference relate to all programmers manufactured and distributed by Microchip.

my old Parallel EEproms programmer :)

Postby DarioG » Sat May 27, 2017 11:14 pm

It was based upon an ISA board (8bits) that I developed as a prototype back in 1991. It was used for some 5 years, maybe more, but I only created 2 of them. I should still have the schematics in Orcad 3 format :)

Am posting the code here, for some fun (MSDOS, C):
Code: Select all
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <io.h>
#include <dos.h>
#include <fcntl.h>
#include <time.h>

#define HIBYTE(x) ((x >> 8) & 0xff)
#define LOBYTE(x) (x & 0xff)

#define LOW_ADDRESS (Porta+0)
#define HIGH_ADDRESS (Porta+1)
#define DATA_PORT (Porta+2)            // Autoincremento dopo inp
#define CONTROL_PORT1 (Porta+4)
#define CONTROL_PORT2 (Porta+3)

#pragma intrinsic( _enable, _disable )

void (_interrupt _far *oldtimer)( void );
void _interrupt _far newtimer( );
unsigned int Porta=0x300;
unsigned int BinaryFile=0;
unsigned int StartAddress=0;
unsigned int EndAddress;
long FileOffset=0l;
int DebugMode=0;
int TipoEprom=0;
int LongTime=0;
int Verify=0,PreTestBlank=0;
int Quiet=0;
int OptimizeFF=1;
unsigned int EraseTime=60;             // 1 ora
void (_interrupt _far *OldCtrl_C)();
int RetVal=0;
int fExit;
unsigned int TickCheck;
unsigned long TickCount;

char *Eproms[]={
   "2708",
   "2716",
   "2532",
   "2732",
   "2764",
   "27128",
   "27256",
   "27512",
   ""
   };

// bit 7 = program pulse
// bit 6 = Vpp ON
// bit 5 = pin 23
// bit 4 = pin 22
// bit 3 = pin 1
// bit 2 = pin 27
// bit 1 = +5 al pin 26
// bit 0 = lampada UV

// bit 15 = lampada UV
// bit 14 = Vpp 12/24
// bit 13 = +5 on/off
// bit 12 =
// bit 11 =
// bit 10 =
// bit 9  =
// bit 8  = Output Enable
// bit 7  = LED & program pulse
// bit 6  = pin 20
// bit 5  = pin 1
// bit 4  = pin 22
// bit 3  = pin 23
// bit 2  = pin 27 e 20
// bit 1  = +5 al pin 26
// bit 0  = pin 22

unsigned int ReadWord[]={
   2+64+8192+256,
   2+64+8192+256,
   2+8192+256,
   2+64+8192+256,
   4+64+8192+256,
   4+64+8192+256,
   4+64+8192+256,
   64+8192+256
   };

unsigned int ProgramWord[]={
   2+16+8+64+8192,
   2+16+8+64+8192,
   2+16+8+8192,
   2+1+4+8192,
   4+32+64+8192+16384,
   4+32+64+8192/*+16384*/,
   4+32+64+8192/*+16384*/,
   8192+16384
   };

unsigned int ProgramPulseWord[]={
   128+2+16+8+4+8192,
   128+2+16+8+4+8192,
   128+2+8+8192,
   128+64+1+2+4+8192,
   128+64+32+8192+16384,
   128+64+32+8192/*+16384*/,
   64+32+8192/*+16384*/,
   128+8192+16384
   };

unsigned int StandByWord=   4+64+8192;

unsigned char KBytes[]={
   1,
   2,
   4,
   4,
   8,
   16,
   32,
   64
   };

int check(unsigned int begin, unsigned int end) {
   register int i;            // long per le 27512
   register int ch;
   long t;

   i=StartAddress;
   outp(CONTROL_PORT1, HIBYTE(ReadWord[TipoEprom]));
   outp(CONTROL_PORT2, LOBYTE(ReadWord[TipoEprom]));
   outp(LOW_ADDRESS,i % 256);
   outp(HIGH_ADDRESS,i / 256);

   do  {
      if(LongTime) {
         t=TickCount/100;
         while(t--);
         }
      ch=inp(DATA_PORT);
      if((!Quiet) || !(i & 0xff))
         printf("Indirizzo: %04XH, byte: %02XH\r",i,(unsigned char)ch);
      if(ch != 0xff) {
         RetVal=3;
         printf("Indirizzo: %04XH, byte: %02XH\r",i,(unsigned char)ch);
         break;
         }
      i++;
      } while(i<=EndAddress && !fExit && i);
      
   outp(CONTROL_PORT1, HIBYTE(StandByWord));
   outp(CONTROL_PORT2, LOBYTE(StandByWord));
   return RetVal;
   }

int dump(unsigned int begin, unsigned int end) {
   register int i,ch;
   char chcount[20];
   unsigned int count;
   long t;

   outp(CONTROL_PORT1, HIBYTE(ReadWord[TipoEprom]));
   outp(CONTROL_PORT2, LOBYTE(ReadWord[TipoEprom]));
   begin-=begin & 16;
   outp(LOW_ADDRESS,begin & 255);
   outp(HIGH_ADDRESS,begin >> 8);
   count=begin;

   if(BinaryFile) {
      setmode(fileno(stdout),O_BINARY);
      do  {
         if(LongTime) {
            t=TickCount/100;
            while(t--);
            }
         ch=inp(DATA_PORT);
         putc(ch, stdout);
         count++;
         } while((count <= end) && !fExit && count);
      }
   else do {
      printf("\n%04X:  ",count);
      for(i=0; i<16; chcount[++i]=0) {
         if(LongTime) {
            t=TickCount/100;
            while(t--);
            }
         ch=inp(DATA_PORT);
         count++;
            
         printf("%02X%c",ch,i==7 ? '-' : ' ');
         chcount[i]=isprint(ch) ? ch : '.';
         }
      printf("   %s",chcount);
      } while((count <= end) && !fExit && count);

   outp(CONTROL_PORT1, HIBYTE(StandByWord));
   outp(CONTROL_PORT2, LOBYTE(StandByWord));
   return 0;
   }


//***************************************************************************

int program(unsigned int begin, unsigned int end, FILE *f, long offset, int mode) {
   register int i,j;
   int ch,ch1,bVuota=1;
//  int RetVal=0;
   long t;

   if(BinaryFile) {
      setmode(fileno(stdin),O_BINARY);
      if(offset) {
         fseek(f,offset,SEEK_SET);
         fprintf(stderr, "Offset dall'inizio del file: %lXH\n", offset);
         }
      }

   if(!mode) {
      outp(CONTROL_PORT1, HIBYTE(ProgramWord[TipoEprom]));
      outp(CONTROL_PORT2, LOBYTE(ProgramWord[TipoEprom]));
      t=clock()+1000l;
      while(clock() <= t);    // importante affinchŠ +25VPP carichi il condensatore
      }
  else {
      outp(CONTROL_PORT1, HIBYTE(ReadWord[TipoEprom]));
      outp(CONTROL_PORT2, LOBYTE(ReadWord[TipoEprom]));
      }
      
   outp(LOW_ADDRESS,begin & 255);
   outp(HIGH_ADDRESS,begin >> 8);
   
   t=TickCount/10;
   while(t--);
   
   for(i=begin; i<=end; i++) {

      if(!mode) {
         outp(LOW_ADDRESS,LOBYTE(i));
         outp(HIGH_ADDRESS,HIBYTE(i));
         }

      if(BinaryFile) {
         j=ch=getc(f);
         }
      else {
         j=fscanf(f,"%x",&ch);
         }
      if(j == EOF) {
         puts("Attenzione: sono stati forniti meno dati della lunghezza della Eprom");
         break;
         }
      if(fExit) {
         break;
         }
      if(!mode) {
         if((!Quiet) || !(i & 0xff))
            printf("Indirizzo: %04XH, byte: %02XH%c",i,(unsigned char)ch,
               1 ? '\r' : '\n');
         if((!OptimizeFF) || (ch != 0xff)) {
            outp(DATA_PORT,ch);
   //      t=clock();
   //      while(clock() == t);
            outp(CONTROL_PORT1, HIBYTE(ProgramPulseWord[TipoEprom]));
            outp(CONTROL_PORT2, LOBYTE(ProgramPulseWord[TipoEprom]));
            t=TickCount;
            while(t--);
            outp(CONTROL_PORT1, HIBYTE(ProgramWord[TipoEprom]));
            outp(CONTROL_PORT2, LOBYTE(ProgramWord[TipoEprom]));
            t=TickCount/2;
            while(t--);
            }
         }
      else {
         if(LongTime) {
            t=TickCount/20;
            while(t--);
            }
         ch1=inp(DATA_PORT);
         if((!Quiet) || (ch != ch1))
            printf("Indirizzo: %04XH, byte letto: %02XH, byte da confrontare %02XH%c",
               i,ch1,(unsigned char)ch, (ch==ch1) ? '\r' : '\n');
         if(ch != ch1) {
            RetVal=3;
            }
         if(ch1 != 0xff) {
            bVuota=0;
            }
         }
      }
   
   if(mode && bVuota)
     puts("Attenzione: la EPROM non contiene dati.");
   putchar('\n');

   outp(CONTROL_PORT1, HIBYTE(StandByWord));
   outp(CONTROL_PORT2, LOBYTE(StandByWord));
   return RetVal;
   }

int ErrorExit(int modo) {
   char buffer[64];

   switch(modo) {
      case 1:
         strcpy(buffer,"funzione inesistente");
         break;

      case 2:
         strcpy(buffer,"switch sconosciuto");
         break;

      case 3:
         strcpy(buffer,"");
         break;

      case 4:
         strcpy(buffer,"interruzione dell'utente");
         break;

      }
   if(modo && (modo != 3))
      fprintf(stderr,"\nErrore: %s\n\n",buffer);
   _dos_setvect(0x23,OldCtrl_C);
   exit(modo);
   }

#pragma check_stack(off)
void _interrupt _far Ctrl_C() {

_asm {

   mov   word ptr RetVal,4
   mov   word ptr fExit,1
//  pop   bp
//  iret
   }
   }
#pragma check_stack(on)

int main(int argc, char *argv[]) {
   char Args[20][40];
   register i,j;
   char opts[40];
   char *t;
   int k;
   long l;
   long m;

   fprintf(stderr,"\nProgrammatore di Eprom v1.60 - (C) G.Dar 1991-2000\n");
   fprintf(stderr,"                               (C) ADPM Synthesis 1992-2000\n");
   if((argc<2) || (*argv[1]=='?')) {
      puts("\nSintassi: EPROM <funzione> [/switch]");
      puts("Funzione:     1 ... controlla contenuto Eprom cancellata");
      puts("              2 ... dump della Eprom");
      puts("              3 ... programma la Eprom");
      puts("              4 ... verifica la Eprom");
      puts("              5 ... cancella la Eprom");
      puts("Switch:       /p<numero hex> ... indirizzo base I/O");
      puts("              /t<sigla Eprom> ... imposta tipo Eprom");
      puts("              /s<offset hex> ... indirizzo iniziale");
      puts("              /e<offset hex> ... indirizzo finale");
      puts("              /o<offset hex> ... offset nel file");
      puts("              /b ... specifica dati binari durante programmazione");
      puts("              /q ... sopprime contatore indirizzi");
      puts("              /a ... controlla canc. prima della programmazione");
      puts("              /v ... verifica dopo la programmazione");
      puts("              /f ... disabilita ottimizzazione FF");
      puts("              /l ... allunga impulsi PRG, per memorie lente");
      puts("              /c ... specifica tempo di cancellazione in minuti");
      puts("Errorlevel:   0=OK, 1=Errore esecuzione, 2=Errore comandi,");
      puts("              3=Errore svolgimento, 4=Interruzione.");
      exit(99);
      }

   OldCtrl_C=_dos_getvect(0x23);
   _dos_setvect(0x23,Ctrl_C);
   fExit=0;

   // Estrae opzioni della command line: /s o -s
   for(i=1; i<argc; i++)
      strcpy(Args[i],argv[i]);
   *opts=0;
   for(i=1; i<argc; i++) {
      if(*Args[i]=='/' || *Args[i]=='-') {
         strcat(opts,((char *)(Args[i]))+1);
         strcat(opts,"~");
         for(j=i; j<argc; j++)
            strcpy(Args[j],Args[j+1]);
         *Args[j-1]=0;
         i--;
         argc--;
         }
      }
   strupr(opts);

   if(t=strchr(opts,'C')) {
      sscanf(t+1,"%u",&EraseTime);
      }

   if(t=strchr(opts,'D')) {
      DebugMode=1;
      }

   if(t=strchr(opts,'P')) {
      sscanf(t+1,"%x",&Porta);
      }

   if(t=strchr(opts,'Q')) {
      Quiet=1;
      }

   if(t=strchr(opts,'F')) {
      OptimizeFF=0;
      }

   if(t=strchr(opts,'B')) {
      BinaryFile=1;
      }

   if(t=strchr(opts,'V')) {
      Verify=1;
      }
   if(t=strchr(opts,'A')) {
      PreTestBlank=1;
      }

   if(t=strchr(opts,'L')) {
      sscanf(t+1,"%d",&LongTime);
      if(LongTime>10)
        LongTime=10;
      }

   if(t=strchr(opts,'T')) {
      TipoEprom=-1;
      for(i=0; *Eproms[i]; i++) {
         if(*(t+1) == '?') {
            puts(Eproms[i]);
            }
         else {
            if(!strncmp(t+1,Eproms[i],strlen(Eproms[i]))) {
               TipoEprom=i;
               break;
               }
            }
         }
      if(TipoEprom < 0)
         ErrorExit(2);
      }

   if(t=strchr(opts,'O')) {
      sscanf(t+1,"%lx",&FileOffset);
      }

   if(t=strchr(opts,'S')) {
      sscanf(t+1,"%x",&StartAddress);
      }

   if(t=strchr(opts,'E')) {
      sscanf(t+1,"%x",&EndAddress);
      }

   if(!EndAddress) {
      EndAddress=KBytes[TipoEprom] * 1024-1;
      }

   fprintf(stderr,"\nEprom scelta: %s\n",Eproms[TipoEprom]);
   fprintf(stderr,"Range di indirizzi di lavoro %04XH - %04XH\n",
      StartAddress,EndAddress);
   fprintf(stderr,"Base I/O: %X (hex)\n\n",Porta);
   outp(CONTROL_PORT1, HIBYTE(StandByWord));
   outp(CONTROL_PORT2, LOBYTE(StandByWord));
   RetVal=0;

// Misura clock di sistema
   oldtimer = _dos_getvect( 8);
   _dos_setvect( 8, newtimer );

_asm {
   push  si
   push  di
   mov   word ptr TickCheck,0
   xor   di,di
   xor   si,si
aspetta:
   cmp   TickCheck,1
   jne   aspetta
aspetta_:
   cmp   TickCheck,2
   je    fine
   inc   di
   jne   aspetta_
   inc   si
   jne   aspetta_
fine:
   mov   word ptr m,di
   mov   word ptr m+2,si
   pop   di
   pop   si
   }

   _dos_setvect( 8, oldtimer );

   if(LongTime) {
      m/=4;
      TickCount=m*LongTime;
      }
   else
      TickCount=m/10;            // era /8, 19-11-93

   if(DebugMode) {
      fprintf(stderr,"Conteggi in un tick (%u millisecondi): %lu\n",10000/182,m);
      fprintf(stderr,"Program pulse=%3.1f mSec\n",((double)TickCount)*10000.0/182.0/((double)m));
      }


   switch(*Args[1]) {
      case '1':
         check(StartAddress,EndAddress);
         if(!RetVal || (RetVal==3))
            printf("\nLa Eprom %s correttamente cancellata.\n", RetVal ? "non Š\a" : "Š");
         break;

      case '2':
         dump(StartAddress,EndAddress);
         break;

      case '3':
         if(PreTestBlank)
            if(check(StartAddress,EndAddress)) {
               printf("\nLa Eprom non Š correttamente cancellata.\n");
               goto no_program;
               }
   
         program(StartAddress, EndAddress, stdin, FileOffset, 0);
         if(!RetVal || (RetVal==3))
            printf("\nProgrammazione %s.\n", RetVal ? "fallita\a" : "OK");
         if(Verify) {
           RetVal=0;
           fseek(stdin,0,SEEK_SET);
            t=clock()+500l;
            while(clock() <= t);
           goto verify;
           }
no_program:
         break;

      case '4':
verify:
      program(StartAddress, EndAddress, stdin, FileOffset, 1);
         if(!RetVal || (RetVal==3))
            printf("\nLa verifica %s OK.\n", RetVal ? "non Š\a" : "Š");
         break;

      case '5':
         outp(CONTROL_PORT1, 128);
         outp(CONTROL_PORT2, 0);
         l=clock()+EraseTime*60000l;
         while((clock() <= l) && !fExit) {
            if(!Quiet)
               printf("Cancellazione Eprom, ancora %u minuti...\r",
                  ((unsigned int)((l-clock())/60000L)));
            }
         break;

      default:
         RetVal=1;
         break;
      }

   outp(CONTROL_PORT1, HIBYTE(StandByWord));
   outp(CONTROL_PORT2, LOBYTE(StandByWord));
   ErrorExit(RetVal);
   }

void _interrupt _far newtimer() {


   TickCheck++;

   _chain_intr( oldtimer );
   }

All we are praying / is an earthquake in Chandler
User avatar
DarioG
Verified identity
 
Posts: 34
Joined: Thu May 29, 2014 8:42 am
PIC experience: Professional 5+ years with MCHP products

Re: my old Parallel EEproms programmer :)

Postby Ian.M » Sat May 27, 2017 11:59 pm

Can you render the schematics to some hi-res loss-free image format or PDF?. PDF would probably be best for most of us, but a zippped folder of PNGs or GIFs would also do.
Ian.M
Verified identity
 
Posts: 94
Joined: Wed May 28, 2014 12:47 am
PIC experience: Professional 1+ years with MCHP products

Re: my old Parallel EEproms programmer :)

Postby DarioG » Mon Nov 13, 2017 6:54 pm

Hi Ian, sorry but I got no notifications...

So, here they go! (paper format, for some reason, is wrong and I could not adjust it but... zooming is okay!)
All we are praying / is an earthquake in Chandler
User avatar
DarioG
Verified identity
 
Posts: 34
Joined: Thu May 29, 2014 8:42 am
PIC experience: Professional 5+ years with MCHP products

Re: my old Parallel EEproms programmer :)

Postby DarioG » Mon Nov 13, 2017 6:55 pm

schematics
Attachments
EPROMP.DSN - EPROMP_3.pdf
(11.66 KiB) Downloaded 47 times
EPROMP.DSN - EPROMP_2.pdf
(15.58 KiB) Downloaded 63 times
EPROMP.DSN - EPROMP_1.pdf
(24.97 KiB) Downloaded 43 times
EPROMP.DSN - EPROMP.pdf
(10.45 KiB) Downloaded 49 times
All we are praying / is an earthquake in Chandler
User avatar
DarioG
Verified identity
 
Posts: 34
Joined: Thu May 29, 2014 8:42 am
PIC experience: Professional 5+ years with MCHP products


Return to Programmers

Who is online

Users browsing this forum: No registered users and 1 guest

cron