home *** CD-ROM | disk | FTP | other *** search
- /*
- * An adaption of EPROMmer.bas
- * By Udi Finkelstein (C) 1990
- */
-
- #include <stdio.h>
- #include <stdarg.h>
- #include "req/reqbase.h"
- #include "req/req_protos.h"
- #include "req/req.h"
-
- /*
- * So PowerWindows doesn't add a 'chip' keyword?? so what ...
- */
- #define USHORTTMP USHORT
- #undef USHORT
- #define USHORT USHORTTMP chip
- #include "EPROMmer.h"
- #undef USHORT
- #define USHORT USHORTTMP
-
- /*
- * Since I have blown PA0 on my machine, I have used one of the RS232
- * signals instead, and used a 1489 receiver on the circuit instead of
- * using PA0.
- */
- #ifdef USE_RS232
- #define OE 0x41
- #else
- #define OE 0x01
- #endif
-
- #define PGM 0x02
-
- #define VOLTS12 (223 - 128)
- #define VOLTS21 (223 - 64)
- #define VOLTS25 (223 - 192)
-
- /* PA2 = SEL */
- #define Clock0 0
- #define Clock1 4
-
- unsigned char far EmemBase[0x10000];
- char *EmemTop,*RamBot;
- volatile unsigned char *ParPort = (volatile unsigned char *)0xbfe101;
- volatile unsigned char *ParDDR = (volatile unsigned char *)0xbfe301;
- volatile unsigned char *CtrlPort = (volatile unsigned char *)0xbfd000;
- volatile unsigned char *CtrlDDR = (volatile unsigned char *)0xbfd200;
- char *EpromType;
-
- unsigned char volt_tbl[] = { VOLTS25, VOLTS25, VOLTS21, VOLTS21,
- VOLTS12, VOLTS12, VOLTS12, VOLTS12, VOLTS12 };
-
- /* PA0 = /OE, PA1 = /PGM */
- unsigned char rp_tbl[] = { 0, 0, 0, PGM, PGM, PGM, 0, 0, 0 };
- unsigned char wp_tbl[] = { OE+PGM, OE, OE, OE, OE, OE, OE, OE, OE };
- unsigned char lp_tbl[] = { OE+PGM, OE+PGM, OE+PGM, OE+PGM, OE+PGM,
- OE+PGM, OE+PGM, OE+PGM, OE+PGM };
- unsigned char ip_tbl[] = { OE, OE+PGM, OE+PGM, OE+PGM, OE+PGM, OE+PGM,
- OE+PGM, OE+PGM, OE+PGM };
- unsigned char e_flag[] = { 1, 1, 1, 1, 1, 1, 1, 1, 0 };
-
- unsigned short ad_tbl[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0x8000 };
-
- short Wr50ms(unsigned char), WrIntel(unsigned char), WrFast(unsigned char),
- WrEprommer(unsigned char);
-
- struct Gadget *ag_tbl[] = { &FiftyMSGad, &FiftyMSGad, &FiftyMSGad,
- &IntelGad, &IntelGad, &IntelGad, &IntelGad, &IntelGad, &FastGad };
- short (*wa_tbl2[])(unsigned char) = { Wr50ms, WrIntel, WrEprommer, WrFast };
-
- short (*WriteAlg)(unsigned char);
-
- long size_tbl[] = { 2048, 4096, 4096, 8192, 8192, 16384, 32768, 65536, 32768 };
-
- unsigned char VoltVal, ReadParam, WriteParam, LeaveParam, InhibitParam;
-
- unsigned char Addr0, Addr1, Addr2, Addr3;
- unsigned char Write1, Write2, Write3, Write4, Write5;
- unsigned char Read0, Read1;
-
- unsigned short LastAddr, AdParam;
-
- LONG *RAMValInt, *RAMLowInt, *EPROMLowInt, *LengthInt;
-
- struct Window *win;
- struct RastPort *rp;
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct Library *ReqBase;
- struct Gadget *ia, *old_type_gad, *old_alg_gad;
- struct IntuiMessage *m;
- struct MsgPort *tp;
- struct timerequest *tr;
- ULONG mc;
- long Size;
- short EPType = -1;
-
- char Dir[DSIZE + 1], File[FCHARS + 1], FullPath[DSIZE+FCHARS+2];
- struct ReqFileRequester frq ;
-
- void UpdateLongInt(g)
- struct Gadget *g;
- {
- SHORT pos;
- struct StringInfo *si;
-
- si = (struct StringInfo *)(g->SpecialInfo);
- pos = RemoveGList(win, g, 1);
- sprintf(si->Buffer, "%lu", si->LongInt);
- si->NumChars = strlen(si->Buffer);
- AddGList(win, g, pos, 1, NULL);
- RefreshGList(g, win, NULL, 1);
- }
-
- /*
- * Turn off the previously selected gadget, if there was one.
- */
- void GadExclude(gad)
- struct Gadget *gad;
- {
- if (gad) {
- /* Turn off previous gadget */
- gad->Flags ^= SELECTED;
- SetAPen(rp, 0);
- SetDrMd(rp, JAM1);
- RectFill(rp, gad->LeftEdge, gad->TopEdge,
- gad->LeftEdge + gad->Width, gad->TopEdge + gad->Height);
- RefreshGList(gad, win, NULL, 1);
- }
- }
-
- /*
- * A general one gadget requester using req.library
- */
- void SimpleRequest(char *str,...)
- {
- va_list ap;
- struct TRStructure trs;
-
- va_start(ap,str);
-
- trs.Text = str;
- trs.Controls = ap;
- trs.Window = 0;
- trs.MiddleText = 0;
- trs.PositiveText = 0;
- trs.NegativeText = "Resume";
- trs.Title = "Ahem...";
- trs.KeyMask = 0xFFFF;
- trs.textcolor = 1;
- trs.detailcolor = 2;
- trs.blockcolor = 3;
- trs.versionnumber = REQVERSION;
- trs.Timeout = 0;
- trs.AbortMask = 0;
- trs.rfu1 = 0;
-
- TextRequest(&trs);
- va_end(ap);
- }
-
- /*
- * A general two gadget requester using req.library
- */
- short TwoGadRequest(char *str,...)
- {
- va_list ap;
- struct TRStructure trs;
- short res;
-
- va_start(ap,str);
-
- trs.Text = str;
- trs.Controls = ap;
- trs.Window = 0;
- trs.MiddleText = 0;
- trs.PositiveText = " OK ";
- trs.NegativeText = "CANCEL";
- trs.Title = "Ahem...";
- trs.KeyMask = 0xFFFF;
- trs.textcolor = 1;
- trs.detailcolor = 2;
- trs.blockcolor = 3;
- trs.versionnumber = REQVERSION;
- trs.Timeout = 0;
- trs.AbortMask = 0;
- trs.rfu1 = 0;
-
- res = TextRequest(&trs);
- va_end(ap);
- return(res);
- }
-
- /*
- * Timer initialization done here
- */
- short OpenTimer()
- {
-
- if ((tp = CreatePort(0, 0)) == 0) return 1;
- if ((tr = (struct timerequest *)CreateExtIO(tp, sizeof(struct timerequest)))
- == NULL) return 1;
-
- if (OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)tr, 0))
- return 1;
- }
-
- /*
- * Timer cleanup done here
- */
- void CloseTimer(tr)
- struct timerequest *tr;
- {
-
- if (tp) DeletePort(tp);
- if (tr) {
- CloseDevice((struct IORequest *)tr);
- DeleteExtIO((struct IORequest *)tr);
- }
- }
-
- /*
- * A MicroHz precision delay routine
- */
- void uDelay(delay)
- unsigned long delay;
- {
-
- tr->tr_node.io_Command = TR_ADDREQUEST;
- tr->tr_time.tv_secs = 0;
- tr->tr_time.tv_micro = delay;
- DoIO((struct IORequest *)tr);
- }
-
- void SetAddr(Address)
- unsigned short Address;
- {
-
- LastAddr = Address;
- *ParDDR = 255;
- *ParPort = 253;
- *CtrlPort = Addr0;
- *ParPort = Address >> 8;
- *CtrlPort = Addr1;
- *ParPort = 254;
- *CtrlPort = Addr2;
- *ParPort = Address & 255;
- *CtrlPort = Addr3;
- }
-
- void InitPorts()
- {
-
- *CtrlDDR = Clock1 + OE + PGM;
- *CtrlPort = Clock0 + OE + PGM;
- *ParDDR = 255;
- *ParPort = 255;
- *CtrlPort = Clock1 + OE + PGM;
- *CtrlPort = Clock0 + OE + PGM;;
-
- SetAddr(0);
- }
-
- void VPP_on()
- {
- *ParDDR = 255;
- *ParPort = VoltVal;
- *CtrlPort = Clock1;
- }
-
- void VPP_off()
- {
- *ParPort = 255;
- *CtrlPort = LeaveParam + Clock0;
- *CtrlPort = LeaveParam + Clock1;
- *CtrlPort = LeaveParam + Clock0;
- }
-
- void ThatsIt()
- {
- SetAddr(0);
- *CtrlDDR = 0;
- *ParDDR = 0;
- }
-
- unsigned char ReadByte()
- {
- unsigned char DataIn;
-
- /* If A15 is used for /WR, make sure it's high now - used for 62256 */
- if (AdParam & 0x8000 & ~LastAddr) SetAddr(LastAddr | 0x8000);
- /* port is now input */
- *ParDDR = 0;
- *CtrlPort = Read0;
- DataIn = *ParPort;
- *CtrlPort = Read1;
- return DataIn;
- }
-
- void WriteByte(DataOut, delay)
- unsigned char DataOut;
- unsigned long delay;
- {
- /* If A15 is used for /WR, make sure it's low now - used for 62256 */
- if (AdParam & 0x8000 & LastAddr) SetAddr(LastAddr & 0x7fff);
- *ParDDR = 255;
- *ParPort = VoltVal;
- *CtrlPort = Write1;
- *ParPort = DataOut;
- *CtrlPort = Write2;
- uDelay(delay);
- *CtrlPort = Write3;
- *ParPort = 255;
- *CtrlPort = Write4;
- *CtrlPort = Write5;
- }
-
- void SetCycleParams()
- {
- Write1 = InhibitParam + Clock1;
- Write2 = WriteParam + Clock1;
- Write3 = InhibitParam + Clock0;
- Write4 = InhibitParam + Clock1;
- Write5 = LeaveParam + Clock0;
- Read0 = ReadParam + Clock0;
- Read1 = LeaveParam + Clock0;
- Addr0 = LeaveParam + Clock1;
- Addr1 = LeaveParam + Clock0;
- Addr2 = LeaveParam + Clock1;
- Addr3 = LeaveParam + Clock0;
- }
-
- /*
- * Write a single byte
- */
- short WriteCycle(DataOut)
- unsigned char DataOut;
- {
- unsigned char c;
-
- /* Any bit set in DataOut which is already reset in the EPROM? */
- c = ReadByte();
- if (e_flag[EPType] && (~c & DataOut)) return 1;
-
- /* Is data already identical? */
- if (DataOut == c) return 0;
-
- return (*WriteAlg)(DataOut);
- }
-
- /*
- * The Eprommer algorythm - a variation on the intel algorythm.
- */
- short WrEprommer(DataOut)
- unsigned char DataOut;
- {
- short n;
- unsigned long l;
-
- /* Programming loop */
- n = 0;
- while(++n < 20) {
- WriteByte(DataOut, 1000);
- if (ReadByte() == DataOut) {
- /* Overprogramming section */
- l = n * 5000;
- if (l > 20000) l = 20000;
- WriteByte(DataOut, l);
- return 0;
- }
- }
- /* Too many retries, must be EPROM failure */
- return 2;
- }
-
- /*
- * The IntEligent programming algorythm algorythm.
- */
- short WrIntel(DataOut)
- unsigned char DataOut;
- {
- short n;
-
- /* Programming loop */
- n = 0;
- while(++n < 15) {
- WriteByte(DataOut, 1000);
- if (ReadByte() == DataOut) {
- /* Overprogramming section */
- WriteByte(DataOut, n * 4000);
- return 0;
- }
- }
- /* Too many retries, must be EPROM failure */
- return 2;
- }
-
- /*
- * The fastest algorythm - use for RAMs only!
- */
- short WrFast(DataOut)
- unsigned char DataOut;
- {
- /* No loop! */
- WriteByte(DataOut, 10);
- if (ReadByte() == DataOut) return 0;
-
- /* RAM failure */
- return 2;
- }
-
- /*
- * The basic 50ms pulse algorythm.
- * Use for 2716, 2732 and 2732A chips which requires it. not all
- * brands of chips require this slow algorythm (Intel does, TI don't).
- */
- short Wr50ms(DataOut)
- unsigned char DataOut;
- {
- /* No loop! */
- WriteByte(DataOut, 50000);
- if (ReadByte() == DataOut) return 0;
-
- /* RAM failure */
- return 2;
- }
-
- /*
- * Read a file into the buffer
- */
- void LoadFile()
- {
- FILE *fin;
-
- frq.VersionNumber = REQVERSION;
- frq.Dir = Dir;
- frq.File = File;
- frq.PathName = FullPath;
- frq.Title = "Buffer Load";
- frq.Flags = FRQCACHINGM|FRQLOADINGM|FRQHIDEWILDSM;
-
- if (!FileRequester(&frq)) return;
-
- if ((fin = fopen(FullPath, "r")) == NULL) {
- SimpleRequest("Could not open input file (%s)!", FullPath);
- return;
- }
- *LengthInt = fread(EmemBase + *RAMLowInt, 1, 0x10000 - *RAMLowInt, fin);
- SimpleRequest("We read %ld bytes", *LengthInt);
- UpdateLongInt(&Length);
- fclose(fin);
- }
-
- /*
- * Save a part of the buffer to disk
- */
- void SaveFile()
- {
- FILE *fin;
- LONG len;
-
- frq.VersionNumber = REQVERSION;
- frq.Dir = Dir;
- frq.File = File;
- frq.PathName = FullPath;
- frq.Title = "Buffer Save";
- frq.Flags = FRQCACHINGM|FRQLOADINGM|FRQHIDEWILDSM;
-
- if (!FileRequester(&frq)) return;
-
- if ((fin = fopen(FullPath, "w")) == NULL) {
- SimpleRequest("Could not open output file!");
- return;
- }
- len = fwrite(EmemBase + *RAMLowInt, 1, *LengthInt, fin);
- if (len == *LengthInt)
- SimpleRequest("We wrote %ld bytes", len);
- else
- SimpleRequest("We wrote only %ld bytes Instead of %ld bytes",
- len, *LengthInt);
- fclose(fin);
- }
-
- /*
- * Read the EPROM
- */
- void ReadEPROM()
- {
- unsigned short addr, len;
- unsigned char *c;
-
- if (EPType == -1) {
- SimpleRequest("You must select an EPROM type first!");
- return;
- }
- len = *LengthInt;
- addr = *EPROMLowInt;
- c = &EmemBase[*RAMLowInt];
- while (len--) {
- SetAddr(addr++);
- *c++ = ReadByte();
- }
- SimpleRequest("We read %ld bytes", *LengthInt);
- }
-
- /*
- * Compare the EPROM with the RAM buffer
- */
- void CompareEPROM()
- {
- unsigned short addr, len;
- unsigned char *c, ce, cr;
-
- if (EPType == -1) {
- SimpleRequest("You must select an EPROM type first!");
- return;
- }
- len = *LengthInt;
- addr = *EPROMLowInt;
- c = &EmemBase[*RAMLowInt];
- while (len--) {
- SetAddr(addr++);
- if ((cr = *c++) != (ce = ReadByte()))
- if (!TwoGadRequest("Offset %ld, EPROM:%02lx RAM:%02lx",
- addr - *EPROMLowInt - 1, ce, cr)) return;
- }
- SimpleRequest("We compared %ld bytes", *LengthInt);
- }
-
- /*
- * Make sure EPROM is empty
- */
- void CheckEPROM()
- {
- unsigned long addr;
-
- if (EPType == -1) {
- SimpleRequest("You must select an EPROM type first!");
- return;
- }
- for (addr = 0; addr < Size;) {
- SetAddr((unsigned short)(addr++));
- if (ReadByte() != 255) {
- SimpleRequest("EPROM contains data at %ld!", addr - 1);
- return;
- }
- }
- SimpleRequest("EPROM is empty");
- }
-
- /*
- * Program the EPROM
- */
- void ProgramEPROM()
- {
- unsigned short addr, len;
- unsigned char *c;
-
- if (EPType == -1) {
- SimpleRequest("You must select an EPROM type first!");
- return;
- }
- len = *LengthInt;
- addr = *EPROMLowInt;
- c = &EmemBase[*RAMLowInt];
- while (len--) {
- SetAddr(addr++);
- switch (WriteCycle(*c++)) {
- case 2:
- SimpleRequest("Verify error at EPROM address %d", addr - 1);
- return;
-
- case 1:
- SimpleRequest("EPROM already has data at address %d", addr - 1);
- return;
- }
- }
- SimpleRequest("We programmed %ld bytes", *LengthInt);
- }
-
- /*
- * free every resource we might have allocated
- */
- void cleanup(s)
- char *s;
- {
- ThatsIt();
- PurgeFiles(&frq);
- if (s) Write(Output(), s, strlen(s));
- if (tp) CloseTimer(tr);
- if (win) CloseWindow(win);
- if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
- if (GfxBase) CloseLibrary((struct Library *)GfxBase);
- if (ReqBase) CloseLibrary(ReqBase);
- exit(0);
- }
-
- main()
- {
-
- /*
- * Open all libraries, as well as the program's window
- */
- if (!(IntuitionBase = (struct IntuitionBase *)
- OpenLibrary("intuition.library", 33L)))
- cleanup("No intuition.library!\n");
-
- if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 33L)))
- cleanup("No graphics.library!\n");
-
- if (!(ReqBase = OpenLibrary("req.library", 0L)))
- cleanup("No req.library!\n");
-
- if (!(win = OpenWindow(&NewWindowStructure1)))
- cleanup("No window!\n");
-
- rp = win->RPort;
-
- /* Initialization for timer */
- if (OpenTimer()) cleanup("No timer!");
-
- /*
- * Warning! due to a Lattice bug, we can't initialize these variables while
- * they're defined, even though it's value is known at the time. They get
- * initialized, but with the wrong values. Instead, we initialize them at
- * run time.
- */
- RAMLowInt = &(((struct StringInfo *)(RAMLow.SpecialInfo))->LongInt);
- RAMValInt = &(((struct StringInfo *)(RAMVal.SpecialInfo))->LongInt);
- EPROMLowInt = &(((struct StringInfo *)(EPROMLow.SpecialInfo))->LongInt);
- LengthInt = &(((struct StringInfo *)(Length.SpecialInfo))->LongInt);
-
- /* Update display */
- UpdateLongInt(&RAMLow);
- UpdateLongInt(&Length);
- UpdateLongInt(&EPROMLow);
-
- /* Initialize hardware */
- InitPorts();
-
- /*
- * Event loop
- */
- while (1) {
- Wait(1L << (win->UserPort->mp_SigBit));
- while (m = (struct IntuiMessage *)GetMsg(win->UserPort)) {
- ia = (struct Gadget *)m->IAddress;
- mc = m->Class;
- ReplyMsg((struct Message *)m);
- if (mc == CLOSEWINDOW) {
- SimpleRequest("Please remove the EPROM now");
- cleanup(NULL);
- } else if (mc == GADGETUP) {
- if (ia == &LoadGad) LoadFile();
- else if (ia == &SaveGad) SaveFile();
- else if (ia == &ReadGad) ReadEPROM();
- else if (ia == &CheckGad) CheckEPROM();
- else if (ia == &ProgramGad) ProgramEPROM();
- else if (ia == &CompareGad) CompareEPROM();
- else if (ia == &VPPGad) {
- VPP_on();
- SimpleRequest("VPP on now, press OK to turn it off");
- VPP_off();
- } else if (ia == &ReadByteGad) {
- *RAMValInt = EmemBase[*RAMLowInt];
- UpdateLongInt(&RAMVal);
- } else if (ia == &WriteByteGad) {
- EmemBase[*RAMLowInt] = (*RAMValInt &= 255);
- UpdateLongInt(&RAMVal);
- }
- } else if (mc == GADGETDOWN) {
- if ((LONG)(ia->UserData) & 0x200) {
- /* get EPROM type */
- EPType = (unsigned char)(ia->UserData);
- /* set EPROM parameters */
- Size = size_tbl[EPType];
- VoltVal = volt_tbl[EPType];
- ReadParam = rp_tbl[EPType];
- WriteParam = wp_tbl[EPType];
- InhibitParam = ip_tbl[EPType];
- AdParam = ad_tbl[EPType];
- *CtrlPort = LeaveParam = lp_tbl[EPType];
- SetCycleParams();
- /* turn off old gad */
- GadExclude(old_type_gad);
- old_type_gad = ia;
- /* inform user */
- SimpleRequest("Check for correct Personality Module");
- /* fake a gadget event to set the defalut algorythm for the new type */
- ia = ag_tbl[EPType];
- /* Use GadExclude to turn the new gadget ON! */
- GadExclude(ia);
- /* Fall into the algorythm gadget's code to turn old gad off */
- }
- if ((LONG)(ia->UserData) & 0x100) {
- WriteAlg = wa_tbl2[(unsigned char)(ia->UserData)];
- GadExclude(old_alg_gad);
- old_alg_gad = ia;
- }
- }
- }
- }
- }
-