home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
datafiles
/
hardware
/
eprommer
/
source.lha
/
src
/
eprommer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-14
|
41KB
|
1,825 lines
/*
* An adaption of EPROMmer.bas
* By Udi Finkelstein (C) 1990
*
* Changes by Carsten Rose in November 1992 - June 1993:
* - changed to compile with DICE 2.07.54R
* - GUI now generated with GadToolsBox V2.0c
* - WB 2.0 Look
* - Use default Screen Font (done by GTB)
* - Notice Font Size (done by GTB)
* - Ability to Load and Save Files in 'intelhex' Format
* (Pseudo Standard Object Code Format)
* - req.library no longer used (use ASL FileRequest and EasyRequest)
* if you don't like it use any of the 'ASL to REQ' Patches
* - Integer Gadgets changed to String Gadgets , to allow input of HEX-Numbers
* - Settings will be saved temporaly in ENV:Eprommer.Prefs or in ENVARC:Eprommer.Prefs
* - Test of VPP more 'Eprom friendly' ;-)
* - some little hacks more
*/
#include "defs.h"
#include "eprommer.h"
#include "gad_eprommer.h"
#include "intelhex.h"
#include "eprommer_protos.h"
/*#define DEBUG_PROG*/
#define CIA_MINUSEC 5 /* Minimum CIA access time (in micro seconds) */
#define DELAY {volatile u_char c;int i;for(i=0;i<waitcnt;i++) c=*ParPort;}
char *vers = "\0$VER: Eprommer 3.2d (November,14,1993)";
#define OE 0x01
#define PGM 0x02
#define VOLTS12 (223 - 128)
#define VOLTS21 (223 - 64)
#define VOLTS25 (223 - 192)
/* PA2 = SEL */
#define Clock0 0
#define Clock1 4
#define MAXDATABUFFER 0x10000 /* 64kB */
struct Window *window_locked=NULL; /* If program stops, check fisrt if any Window is locked, release them */
struct IntuiText IT_counting; /* IntuiText struct which shows counting */
BOOL pp_flag=FALSE;ppb_flag=FALSE;
u_char *PEmemBase;
char *EmemTop,*RamBot;
extern __far struct CIA ciaa,ciab;
volatile u_char *ParPort = &ciaa.ciaprb; /*(volatile u_char *)0xbfe101;*/
volatile u_char *ParDDR = &ciaa.ciaddrb; /*(volatile u_char *)0xbfe301;*/
volatile u_char *CtrlPort = &ciab.ciapra; /*(volatile u_char *)0xbfd000;*/
volatile u_char *CtrlDDR = &ciab.ciaddra; /*(volatile u_char *)0xbfd200;*/
u_char volt_tbl[] = { VOLTS25, VOLTS25, VOLTS21, VOLTS21,
VOLTS12, VOLTS12, VOLTS12, VOLTS12, VOLTS12, VOLTS12 };
/* PA0 = /OE, PA1 = /PGM */
u_char rp_tbl[] = { 0, 0, 0, PGM, PGM, PGM, 0, 0, 0, 0 ,0};
u_char wp_tbl[] = { OE+PGM, OE, OE, OE, OE, OE, OE, OE, OE, OE, OE };
u_char lp_tbl[] = { OE+PGM, OE+PGM, OE+PGM, OE+PGM, OE+PGM,
OE+PGM, OE+PGM, OE+PGM, OE+PGM, OE+PGM, OE+PGM };
u_char ip_tbl[] = { OE, OE+PGM, OE+PGM, OE+PGM, OE+PGM, OE+PGM,
OE+PGM, OE+PGM, OE+PGM , OE+PGM, OE+PGM };
/* 1==EProm, 0==Static RAM (used to check only EProm's if any bits in the eprom are already 0) */
u_char e_flag[] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 };
u_short ad_tbl[] = { 0, 0, 0, 0, 0, 0, 0, 0,0, 0x2000, 0 };
/* Table of default program Alorythm */
short ag_tbl[] = {AG_50MS,AG_50MS,AG_50MS,AG_INTE,AG_INTE,AG_INTE,AG_INTE,AG_INTE,AG_NDEL,AG_NDEL,AG_NDEL};
/* Table of 'Programing' Functions Adresses */
short (*wa_tbl2[])(u_char) = { Wr50ms, WrIntel, WrEprommer, WrFast };
short (*WriteAlg)(u_char);
/* Table of Eprom default sizes */
long size_tbl[] = { 2048, 4096, 4096, 8192, 8192, 16384, 32768, 65536, 2048, 8192, 32768 };
/* Global Variables to do Eprom Handling */
u_char VoltVal, ReadParam, WriteParam, LeaveParam, InhibitParam;
u_char Addr0, /* Prepare Clock for High Byte of Address */
Addr1, /* Clock for High Byte of Address */
Addr2, /* Prepare Clock for Low Byte of Address */
Addr3; /* Clock for Low Byte of Address */
u_char Write1, Write2, Write3, Write4, Write5;
u_char Read0, Read1;
long LastAddr; /* Contains always the latest switched address */
u_short AdParam; /* Eprommer Hardware Offset. All Eprom Addresses will */
/* be added with this value. */
/* These are all Mirrors of the appropriate String Gadget */
u_char RAMValInt=0; /* RAM Buffer Value */
LONG RAMLowInt=0, /* Logical RAM Buffer Start Address */
EPROMLowInt=0, /* logical Eprom Start Address */
LengthInt=0; /* Eprom Length */
#ifdef _DCC
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
#else
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
#endif
struct Library *MiscBase=NULL;
struct MsgPort *tp;
struct timerequest *tr;
long Size;
ULONG waitcnt=20; /* Delay Counter for CIA Access. Depends of your Amiga 500/600/... */
short EPType = -1; /* Eprom Type EP_xxxx / See Eprommer.h */
char LDir[DSIZE + 1], LFile[FCHARS + 1], LFullPath[DSIZE+FCHARS+2];
char SDir[DSIZE + 1], SFile[FCHARS + 1], SFullPath[DSIZE+FCHARS+2];
u_char testvpp=VOLTS12;
struct Config conf,newconf; /* contains User settings */
BOOL epromout = FALSE; /* Eprom in Socket ? */
BOOL newepromout = FALSE; /* Eprom in Socket ? */
BOOL abort_flag=FALSE; /* set, if User abort Operation */
APTR aslreq;
struct Requester *plockreq=NULL;
/* Static Data for Busy Pointer */
__chip UWORD waitpointer[] = {
0x0000, 0x0000,
0x0400, 0x07C0,
0x0000, 0x07C0,
0x0100, 0x0380,
0x0000, 0x07E0,
0x07C0, 0x1FF8,
0x1FF0, 0x3FEC,
0x3FF8, 0x7FDE,
0x3FF8, 0x7FBE,
0x7FFC, 0xFF7F,
0x7EFC, 0xFFFF,
0x7FFC, 0xFFFF,
0x3FF8, 0x7FFE,
0x3FF8, 0x7FFE,
0x1FF0, 0x3FFC,
0x07C0, 0x1FF8,
0x0000, 0x07E0,
0x0000, 0x0000}; /* reserved, must be NULL */
static long speedtest(struct timerequest *tr,long cnt)
{
int i;
u_char c;
long sec1,sec2,micro1,micro2;
tr->tr_node.io_Command = TR_GETSYSTIME;
DoIO((struct IORequest *)tr);
sec1=tr->tr_time.tv_secs;
micro1=tr->tr_time.tv_micro;
for(i=0;i<cnt;i++)
c = *ParPort;
DoIO((struct IORequest *)tr);
sec2=tr->tr_time.tv_secs;
micro2=tr->tr_time.tv_micro;
micro1 = (sec2 - sec1)*1000000 + micro2-micro1;
return(micro1);
}
static void checkspeed(void)
{
long cnt=10000,tm=0;
while(tm<100000)
{
cnt*=5;
tm=speedtest(tr,cnt);
}
waitcnt=cnt/(tm/CIA_MINUSEC);
}
static void lockwindow(struct Window *wnd,int flag)
{
/* Locks a window for User input and changes MousePointer for this Window
* like the Workbench BusyPointer.
* If flag is
* TRUE: Opens an unvisible Requester.
* FALSE: Close this Requester.
*/
#ifdef DEBUG_PROG
puts("lockwindow");
#endif
if(flag)
{
SetPointer(wnd,waitpointer,16,16,0,0);
window_locked = wnd;
if(!Request(plockreq,wnd))
DisplayBeep(NULL); /* Just if request can't open/lock the Window*/
}
else
{
EndRequest(plockreq,wnd);
window_locked = NULL;
ClearPointer(wnd);
}
}
static void simplerequest(char *ctl, ...)
{
/* Call this routine like printf().
* Simply open a requester with your message.
*/
va_list va;
struct EasyStruct easy = {
sizeof (struct EasyStruct),
0,
"Message",
NULL, /* ctl */
"OK"
};
easy.es_TextFormat = ctl;
va_start(va,ctl);
EasyRequestArgs(EprommerWnd,&easy,NULL,va);
va_end(va);
}
static int twogadrequest(char *buttons,char *ctl, ...)
{
/* Call this routine like printf(), but a special string 'buttons'.
* This string must contain the text for the 2 Buttons (mostly "OK|CANCEL").
* The 2 Buttons must be seperated with '|'.
* Simply open a requester with your message.
*
* RC: 1 if the left Button is pushed
* 0 if the right Button is pushed
*/
va_list va;
int rc;
struct EasyStruct easy = {
sizeof (struct EasyStruct),
0,
"Message",
NULL, /*ctl,*/
NULL
};
easy.es_TextFormat = ctl;
easy.es_GadgetFormat = buttons;
va_start(va,ctl);
rc = EasyRequestArgs(EprommerWnd,&easy,NULL,va);
va_end(va);
return(rc);
}
static void updatevalgad(int gadnr,int value)
{
/* Update (Display) 'value' in 'gadnr' String Gadget */
char tmp[256];
switch(conf.numericalbase)
{
case CY_DEC: sprintf(tmp, "%d", value);
break;
case CY_DECHEX:
case CY_HEX: sprintf(tmp, "0x%x", value);
break;
default: simplerequest("Error numerical Base, Type:%d. File:%s Line:%d",conf.numericalbase,__FILE__,__LINE__);
}
GT_SetGadgetAttrs(EprommerGadgets[gadnr],EprommerWnd,NULL,GTST_String,tmp,TAG_DONE);
}
static void updateallvalgad(void)
{
/* Updae all String Gadgets */
updatevalgad(GD_RamAddress,RAMLowInt);
updatevalgad(GD_EpromAddress,EPROMLowInt);
updatevalgad(GD_Length,LengthInt);
updatevalgad(GD_RamVal,(int)RAMValInt);
}
/*
* Timer initialization done here
*/
static int OpenTimer(void)
{
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;
return(NULL);
}
/*
* Timer freed done here
*/
static void CloseTimer(struct timerequest *tr)
{
if (tp)
{
DeletePort(tp);
tp = NULL;
}
if (tr)
{
CloseDevice((struct IORequest *)tr);
DeleteExtIO((struct IORequest *)tr);
tr = NULL;
}
}
/*
* A MicroSeconds precision delay routine
*/
static void uDelay(ULONG delay)
{
tr->tr_node.io_Command = TR_ADDREQUEST;
tr->tr_time.tv_secs = 0;
tr->tr_time.tv_micro = delay;
DoIO((struct IORequest *)tr);
}
static void SetAddr(long Address)
{
LastAddr = Address;
*ParDDR = 255; /* Parallel Port Direction Output */
*ParPort = 253; /* Prepare selection of High Byte Address Latch */
DELAY
*CtrlPort = Addr0; /* Select High Byte Address Latch and inactivate Address Latch Clock */
DELAY
*ParPort = Address >> 8; /* Write High Byte Address */
DELAY
*CtrlPort = Addr1; /* Clock High Byte Address into Latch*/
DELAY
*ParPort = 254; /* Prepare selection of Low Byte Address Latch */
DELAY
*CtrlPort = Addr2; /* Select Low Byte Address Latch and inactivate Address Latch Clock */
DELAY
*ParPort = Address & 0xff; /* Write Low Byte Address */
DELAY
*CtrlPort = Addr3; /* Clock Low Byte Address into Latch */
}
static void InitPorts(void)
{
/* Prepare VPP DataBits and Lo/Hi Address Latch to take Data */
*CtrlDDR = Clock1 + OE + PGM; /* Set to OutPut: 0000 0111 */
*CtrlPort = Clock0 + OE + PGM; /* Write : 0000 0011 */
DELAY
testvppoff();
SetAddr(0);
}
static void testvppon(u_char volt)
{
*ParDDR = 255;
*ParPort = volt;
*CtrlPort = Clock0;
DELAY
*CtrlPort = Clock1;
}
static void testvppoff(void)
{
*CtrlPort = LeaveParam + Clock0;
DELAY
*ParDDR = 255;
*ParPort = 255;
DELAY
*CtrlPort = LeaveParam + Clock1;
}
static void ThatsIt(void)
{
/* Set Eprom Adress to 0, Init CIA */
SetAddr(0);
testvppoff();
*CtrlDDR = 0;
*ParDDR = 0;
}
static u_char ReadByte(void)
{
u_char DataIn;
/* If A15 is used for /WR, make sure it's high now - used for 62256,6264 */
if( (EPType==EP_6216) || (EPType==EP_6264)|| (EPType==EP_62256) )
SetAddr(LastAddr | 0x8000);
/* port is now input */
*ParDDR = 0;
*CtrlPort = Read0;
DELAY
DataIn = *ParPort;
*CtrlPort = Read1;
return DataIn;
}
static void WriteByte(u_char DataOut, u_long delay)
{
/* If A15 is used for /WR, make sure it's low now - used for 62256,6264 */
if( (EPType==EP_6216) || (EPType==EP_6264) || (EPType==EP_62256) )
SetAddr(LastAddr & ~0x8000);
*ParDDR = 255;
*ParPort = VoltVal;
DELAY
*CtrlPort = Write1;
DELAY
*ParPort = DataOut;
DELAY
*CtrlPort = Write2;
uDelay(delay);
*CtrlPort = Write3;
DELAY
*ParPort = 255;
DELAY
*CtrlPort = Write4;
DELAY
*CtrlPort = Write5;
}
static void SetCycleParams(void )
{
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
*/
static short WriteCycle(u_char DataOut)
{
u_char c;
#ifdef DEBUG_PROG
puts("WriteCycle");
#endif
/* Any bit set in DataOut which is already reset in the EPROM? */
c = ReadByte();
if (e_flag[EPType] && (~c & DataOut)) /* e_flag==0 -> EProm is a static RAM, NO check */
return 1;
/* Is data already identical? */
if (DataOut == c) return 0;
#ifdef DEBUG_PROG
printf("call WriteAlg: %x\n",WriteAlg);
#endif
return (*WriteAlg)(DataOut);
}
/*
* The Eprommer algorythm - a variation on the intel algorythm.
*/
static short WrEprommer(u_char DataOut)
{
short n;
u_long l;
#ifdef DEBUG_PROG
puts("WriteEprommer");
#endif
/* 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.
*/
static short WrIntel(u_char DataOut)
{
short n;
#ifdef DEBUG_PROG
puts("WriteIntel");
#endif
/* 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!
*/
static short WrFast(u_char DataOut)
{
/* No loop! */
#ifdef DEBUG_PROG
puts("WriteFast");
#endif
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).
*/
static short Wr50ms(u_char DataOut)
{
/* No loop! */
#ifdef DEBUG_PROG
puts("Wr50ms");
#endif
WriteByte(DataOut, 50000);
if (ReadByte() == DataOut) return 0;
/* RAM failure */
return 2;
}
static void LoadFile(void)
{
/* Load the file 'LFullPath' in buffer pointed by 'PEmemBase+RAMLowInt'.
* Notice the 'conf.dataformat' and 'conf.clearbuffer'.
*/
FILE *fin;
char *perror; /* Pointer to Error Message */
int loadmode;
if ((fin = fopen(LFullPath, "r")) == NULL) {
simplerequest("Could not open input file '%s'!", LFullPath);
return;
}
if(conf.clearbuffer)
setmem(PEmemBase,MAXDATABUFFER,0xFF);
lockwindow(EprommerWnd,TRUE);
if(conf.dataformat==INTELHEX)
{
loadmode = conf.bufferfragmented?FRAGMENTED:CONTINOUS;
if(perror=readintelhex(fin,PEmemBase+RAMLowInt,MAXDATABUFFER-RAMLowInt,&LengthInt,loadmode,&EPROMLowInt))
{
simplerequest(perror);
LengthInt=0;
}
}
else
{
LengthInt=fread(PEmemBase+RAMLowInt,1,MAXDATABUFFER-RAMLowInt,fin);
}
fclose(fin);
if( (LengthInt+EPROMLowInt) >size_tbl[EPType])
{
if(EPROMLowInt>size_tbl[EPType])
{
simplerequest("Start Address:%ls bigger than Eprom size:%ld",EPROMLowInt,size_tbl[EPType]);
LengthInt=0;
EPROMLowInt=0;
}
else
{
simplerequest("That's too much data.\nRead %ld Bytes, Start's at: %ld\nEprom Size: %ld Bytes",LengthInt,EPROMLowInt,size_tbl[EPType]);
LengthInt=size_tbl[EPType]-EPROMLowInt;
}
}
else if(conf.inforeq)
simplerequest("Read %ld Bytes",LengthInt);
updatevalgad(GD_Length,LengthInt);
updatevalgad(GD_EpromAddress,EPROMLowInt);
lockwindow(EprommerWnd,FALSE);
}
static void SaveFile(void)
{
FILE *fin;
LONG len;
char *perror; /* Pointer to Error Message */
/* check if File exists */
if (fin=fopen(SFullPath, "r"))
{
fclose(fin);
if(!twogadrequest("OK|CANCEL","Do you want overwrite\n '%s'",SFullPath))
return;
}
if ((fin = fopen(SFullPath, "w")) == NULL) {
simplerequest("Could not open output file '%s'!",SFullPath);
return;
}
lockwindow(EprommerWnd,TRUE);
if(conf.dataformat==INTELHEX)
{
if(perror=writeintelhex(fin,PEmemBase + RAMLowInt,RAMLowInt,LengthInt))
{
simplerequest(perror);
return;
}
len = LengthInt;
}
else
len = fwrite(PEmemBase + RAMLowInt, 1, LengthInt, fin);
fclose(fin);
updatevalgad(GD_Length,LengthInt);
lockwindow(EprommerWnd,FALSE);
if (len != LengthInt)
simplerequest("We wrote only %ld bytes Instead of %ld bytes",len,LengthInt);
else
if(conf.inforeq)
simplerequest("Write %ld Bytes",LengthInt);
}
static char *stoh(u_short value,char *pbuf)
{
/* Convert 'value' to 4-digit ASCII Hex Notation.
*
* Write ASCII Hex Code (4 Chars) at '*pbuf'.
*
* RC: pbuf+4 (points to next free char )
*/
u_char nibble; /* 4 Bits of 'value' */
nibble = 0x000F & value;
pbuf[3]= (nibble<=9) ? nibble+'0' : (nibble-0x0A)+'A';
value >>=4;
nibble = 0x000F & value;
pbuf[2]= (nibble<=9) ? nibble+'0' : (nibble-0x0A)+'A';
value >>=4;
nibble = 0x000F & value;
pbuf[1]= (nibble<=9) ? nibble+'0' : (nibble-0x0A)+'A';
value >>=4;
nibble = 0x000F & value;
pbuf[0]= (nibble<=9) ? nibble+'0' : (nibble-0x0A)+'A';
return(&pbuf[4]);
}
static void startamigaguide(UWORD code)
{
if(code==95) /* Key: Help */
system("run SYS:Utilities/AmigaGuide Eprommer.guide");
}
int EprommerRawKey( void )
{
/* routine for "IDCMP_RAWKEY". */
startamigaguide(EprommerMsg.Code);
return(TRUE);
}
int OptionsRawKey( void )
{
/* routine for "IDCMP_RAWKEY". */
startamigaguide(OptionsMsg.Code);
return(TRUE);
}
int BusyRawKey( void )
{
/* routine for "IDCMP_RAWKEY". */
startamigaguide(BusyMsg.Code);
return(TRUE);
}
int TestRawKey( void )
{
/* routine for "IDCMP_RAWKEY". */
startamigaguide(TestMsg.Code);
return(TRUE);
}
int abortClicked(void)
{
abort_flag = TRUE;
return(TRUE);
}
static void showaddr_checkabort(long addr,BOOL flag)
{
int rc;
struct IntuiMessage *m;
int (*func)(void);
if(!BusyWnd) /* Busy Window already opened ? */
{
#ifdef DEBUG_PROG
puts("OpenBusyWindow");
#endif
if(rc=OpenBusyWindow())
cleanup("Error Open Busy Window");
}
if(conf.counting && (flag || !(addr&0xFF)))
{
stoh((u_short)addr,&IT_counting.IText[2]);
PrintIText( BusyWnd->RPort, &IT_counting, 0,0 );
}
/* check if 'abort' is pushed (through IDCMP_Class GadgetUp*/
while( m = GT_GetIMsg( BusyWnd->UserPort ))
{
CopyMem(( char * )m, ( char * )&BusyMsg, (long)sizeof( struct IntuiMessage ));
GT_ReplyIMsg( m );
switch ( BusyMsg.Class )
{
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh( BusyWnd );
BusyRender();
GT_EndRefresh( BusyWnd, TRUE );
break;
case IDCMP_GADGETUP:
func = (int (*)(void)) (( struct Gadget * )BusyMsg.IAddress )->UserData;
func();
break;
}
}
}
/*
* Read the EPROM
*/
static void ReadEPROM(void)
{
long addr,s_addr, len;
u_char *c;
len = LengthInt;
s_addr = EPROMLowInt;
addr = EPROMLowInt + AdParam;
c = PEmemBase+RAMLowInt;
#ifdef DEBUG_PROG
printf("ReadEprom len:%x addr:%x c:%x 1000:%d\n",len,addr,c,1000);
#endif
while (len--)
{
showaddr_checkabort(s_addr++,FALSE);
SetAddr(addr++);
*c++ = ReadByte();
if(abort_flag)
{
CloseBusyWindow();
abort_flag = FALSE;
return;
}
}
CloseBusyWindow();
if(conf.inforeq)
simplerequest("We read %ld bytes", LengthInt);
}
/*
* Compare the EPROM with the RAM buffer
*/
static void CompareEPROM(void)
{
long addr,s_addr, len;
u_char *c, ce, cr;
int flag_failed=FALSE;
len = LengthInt;
s_addr = EPROMLowInt;
addr = EPROMLowInt + AdParam;
c = PEmemBase+(RAMLowInt);
while (len--) {
showaddr_checkabort(s_addr++,FALSE);
SetAddr(addr++);
if ((cr = *c++) != (ce = ReadByte()))
{
flag_failed = TRUE;
if (!twogadrequest("CONTINUE|CANCEL","Offset %ld, EPROM:%02lx RAM:%02lx",
addr - EPROMLowInt - 1, ce, cr) )
abort_flag = TRUE;
}
if(abort_flag)
{
CloseBusyWindow();
abort_flag = FALSE;
return;
}
}
CloseBusyWindow();
if(flag_failed)
simplerequest("Compare failed");
else
simplerequest("Compare successfull");
}
/*
* Make sure EPROM is empty
*/
static void CheckEPROM(void)
{
long addr,s_addr,end;
s_addr = EPROMLowInt;
addr = EPROMLowInt + AdParam;
end = addr + LengthInt;
for (; addr < end;) {
showaddr_checkabort(s_addr++,FALSE);
SetAddr((u_short)(addr++));
if (ReadByte() != 0xff)
{
simplerequest("EPROM contains data at %ld!", s_addr - 1);
abort_flag = TRUE;
}
if(abort_flag)
{
CloseBusyWindow();
abort_flag = FALSE;
return;
}
}
CloseBusyWindow();
simplerequest("EPROM is empty");
}
/*
* Program the EPROM
*/
static void ProgramEPROM(void)
{
long addr,s_addr, len;
u_char *c;
#ifdef DEBUG_PROG
puts("ProgramEPROM");
#endif
len = LengthInt;
s_addr = EPROMLowInt;
addr = EPROMLowInt+AdParam;
c = PEmemBase+RAMLowInt;
abort_flag = FALSE;
while (len-- && !abort_flag)
{
showaddr_checkabort(s_addr++,FALSE);
SetAddr(addr++);
switch (WriteCycle(*c++))
{
case 2:
simplerequest("Verify error at EPROM address %ld", s_addr - 1);
abort_flag = TRUE;
break;
case 1:
simplerequest("EPROM already has data at address %ld", s_addr - 1);
abort_flag = TRUE;
break;
}
}
CloseBusyWindow();
abort_flag = FALSE;
if(conf.inforeq)
simplerequest("We programmed %ld bytes", LengthInt);
}
static void getstringgads(void)
{
char *dummy;
int base;
#ifdef DEBUG_PROG
puts("getstringgads");
#endif
switch(conf.numericalbase)
{
case CY_DEC: base=10;
break;
case CY_DECHEX: base=0;
break;
case CY_HEX: base=16;
break;
default: simplerequest("Error numerical Base, Type:%d. File:%s Line:%d",conf.numericalbase,__FILE__,__LINE__);
}
RAMValInt = (u_char)strtol(((struct StringInfo *)EprommerGadgets[GD_RamVal]->SpecialInfo)->Buffer,&dummy,base);
RAMLowInt = strtol(((struct StringInfo *)EprommerGadgets[GD_RamAddress]->SpecialInfo)->Buffer,&dummy,base);
EPROMLowInt = strtol(((struct StringInfo *)EprommerGadgets[GD_EpromAddress]->SpecialInfo)->Buffer,&dummy,base);
LengthInt = strtol(((struct StringInfo *)EprommerGadgets[GD_Length]->SpecialInfo)->Buffer,&dummy,base);
}
static void dividepath(char *path,char *dir,char *file)
{
/* divide 'path' in Name of Directory and Name of File */
char *pfile;
if(!(pfile=strrchr(path,'/')))
{
if(!(pfile=strrchr(path,':')))
{
strcpy(file,path);
*dir='\0';
return;
}
}
strncpy(dir,path,pfile-path+1);
dir[pfile-path+1]='\0';
strcpy(file,pfile+1);
}
static void setepromtype(int eptype)
{
/* set EPROM parameters */
EPType = eptype;
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();
WriteAlg = wa_tbl2[ag_tbl[EPType]];
/* set dafault Program Algorythm for this Eprom */
GT_SetGadgetAttrs(EprommerGadgets[GD_ProgAlgo],EprommerWnd,NULL,GTMX_Active,ag_tbl[EPType],TAG_DONE);
/* check if 'Eprom Default Size' is set */
if(conf.defepsize)
{
/* yes, set default size */
LengthInt = size_tbl[EPType];
updatevalgad(GD_Length,LengthInt);
}
}
static void optionsvalid(void)
{
/* Copy new configuration to old one.
* Update the String Gadgets.
* Erase the Vpp if they set.
*/
int change;
/* numericale Base changed ? */
change = (conf.numericalbase==newconf.numericalbase)?FALSE:TRUE;
conf = newconf; /* copy complete structure */
/* Take latest used Directories */
strcpy(conf.loaddir,LDir);
strcpy(conf.savedir,SDir);
if(change) /* perhaps the base has been changed (Decimal or Hexadecimal) */
updateallvalgad();
waitcnt = conf.waitcnt;
}
int DataFormatClicked( void )
{
/* routine when gadget "Data Format" is clicked. */
conf.dataformat = EprommerMsg.Code;
return(TRUE);
}
int ProgAlgoClicked( void )
{
/* routine when gadget "" is clicked. */
WriteAlg = wa_tbl2[EprommerMsg.Code];
return(TRUE);
}
int RamAddressClicked( void )
{
/* routine when gadget "Buffer" is clicked. */
getstringgads();
updatevalgad(GD_RamAddress,RAMLowInt);
return(TRUE);
}
int EpromAddressClicked( void )
{
/* routine when gadget "Eprom" is clicked. */
int max;
getstringgads();
EPROMLowInt=MIN(EPROMLowInt,size_tbl[EPType]); /* Adjust Length */
max=size_tbl[EPType]-EPROMLowInt;
LengthInt=MIN(max,size_tbl[EPType]); /* Adjust Length */
updatevalgad(GD_EpromAddress,EPROMLowInt);
updatevalgad(GD_Length,LengthInt);
return(TRUE);
}
int LengthClicked( void )
{
/* routine when gadget "Length" is clicked. */
int max;
getstringgads();
max=size_tbl[EPType]-EPROMLowInt;
LengthInt=MIN(max,size_tbl[EPType]); /* Adjust Length */
updatevalgad(GD_Length,LengthInt);
return(TRUE);
}
int EpromTypeClicked( void )
{
if(conf.inforeq)
simplerequest("Check for correct Personality Module");
setepromtype(EprommerMsg.Code);
conf.epromtype = (int)EPType;
return(TRUE);
}
int RamValClicked( void )
{
/* routine when gadget "RAM Value" is clicked. */
getstringgads();
updatevalgad(GD_RamVal,(int)RAMValInt);
return(TRUE);
}
int ReadByteClicked( void )
{
/* routine when gadget "Read Byte" is clicked. */
getstringgads();
RAMValInt = (u_char)(*(PEmemBase+RAMLowInt));
updatevalgad(GD_RamVal,(int)RAMValInt);
return(TRUE);
}
int WriteByteClicked( void )
{
/* routine when gadget "Write Byte" is clicked. */
getstringgads();
*(PEmemBase+RAMLowInt) = RAMValInt;
updatevalgad(GD_RamVal,(int)RAMValInt);
return(TRUE);
}
int ReadEpromClicked( void )
{
/* routine when gadget "Read" is clicked. */
#ifdef DEBUG_PROG
puts("ReadEpromClicked");
#endif
lockwindow (EprommerWnd,TRUE);
getstringgads();
ReadEPROM();
lockwindow(EprommerWnd,FALSE);
return(TRUE);
}
int BlankTestClicked( void )
{
/* routine when gadget "Check" is clicked. */
lockwindow(EprommerWnd,TRUE);
getstringgads();
CheckEPROM();
lockwindow(EprommerWnd,FALSE);
return(TRUE);
}
int CompareEpromClicked( void )
{
/* routine when gadget "Compare" is clicked. */
lockwindow(EprommerWnd,TRUE);
getstringgads();
CompareEPROM();
lockwindow(EprommerWnd,FALSE);
return(TRUE);
}
int ProgramEpromClicked( void )
{
#ifdef DEBUG_PROG
puts("ProgramEpromClicked");
#endif
/* routine when gadget "Program" is clicked. */
lockwindow(EprommerWnd,TRUE);
getstringgads();
ProgramEPROM();
lockwindow(EprommerWnd,FALSE);
return(TRUE);
}
int LoadFileReqClicked( void )
{
char *pos;
struct StringInfo *pstrinfo;
int len;
if(!LFullPath[0] && SFullPath[0])
{
/* no entry -> fill with 'savepath' */
strcpy(LFullPath,SFullPath);
strcpy(LFile,SFile);
strcpy(LDir,SDir);
}
pos= (conf.dataformat==INTELHEX)?"Load IntelHex":"Load Binary";
if(AslRequestTags(aslreq,ASL_Hail, pos,ASL_Window,EprommerWnd,ASL_File,LFile,
ASL_Dir,LDir,ASL_Height,(ULONG)EprommerWnd->Height,TAG_DONE))
{
strcpy(LFile,((struct FileRequester *)aslreq)->rf_File);
strcpy(LDir,((struct FileRequester *)aslreq)->rf_Dir);
strcpy(LFullPath,LDir);
if(len=strlen(LFullPath))
{
if((LFullPath[len-1]!=':')&&(LFullPath[len-1]!='/'))
strcat(LFullPath,"/");
}
strcat(LFullPath,LFile);
/* fill LoadFile StringGadget */
pstrinfo = (struct StringInfo *)(EprommerGadgets[GD_LoadFile]->SpecialInfo);
pos = pstrinfo->Buffer;
strcpy(pos,LFullPath);
pstrinfo->NumChars = strlen(pos);
pstrinfo->BufferPos = 0;
RefreshGList(EprommerGadgets[GD_LoadFile], EprommerWnd, NULL, 1);
getstringgads();
LoadFile();
}
return(TRUE);
}
int LoadBtClicked( void )
{
/* routine when gadget "LOAD" is clicked. */
getstringgads();
if(!LFullPath[0])
LoadFileReqClicked();
else
LoadFile();
return(TRUE);
}
int SaveBtClicked( void )
{
/* routine when gadget "SAVE" is clicked. */
getstringgads();
if(!SFullPath[0])
SaveFileReqClicked();
else
SaveFile();
return(TRUE);
}
int SaveFileReqClicked( void )
{
/* routine when gadget "" is clicked. */
char *pos;
struct StringInfo *pstrinfo;
int len;
if(!SFullPath[0] && LFullPath[0])
{
/* no entry -> fill with 'loadpath' */
strcpy(SFullPath,LFullPath);
strcpy(SFile,LFile);
strcpy(SDir,LDir);
}
pos= (conf.dataformat==INTELHEX)?"Save IntelHex":"Save Binary";
if(AslRequestTags(aslreq,ASL_Hail, pos,ASL_Window,EprommerWnd,ASL_File,SFile,
ASL_Dir,SDir,ASL_Height,(ULONG)EprommerWnd->Height,TAG_DONE))
{
strcpy(SFile,((struct FileRequester *)aslreq)->rf_File);
strcpy(SDir,((struct FileRequester *)aslreq)->rf_Dir);
strcpy(SFullPath,SDir);
if(len=strlen(SFullPath))
{
if((SFullPath[len-1]!=':')&&(SFullPath[len-1]!='/'))
strcat(SFullPath,"/");
}
strcat(SFullPath,SFile);
/* fill SaveFile StringGadget */
pstrinfo = (struct StringInfo *)(EprommerGadgets[GD_SaveFile]->SpecialInfo);
pos = pstrinfo->Buffer;
strcpy(pos,SFullPath);
pstrinfo->NumChars = strlen(pos);
pstrinfo->BufferPos = 0;
RefreshGList(EprommerGadgets[GD_SaveFile], EprommerWnd, NULL, 1);
getstringgads();
SaveFile();
}
return(TRUE);
}
int LoadFileClicked( void )
{
/* routine when gadget "Load" is clicked. */
struct StringInfo *pstrinfo;
char *pos;
pstrinfo = (struct StringInfo *)(EprommerGadgets[GD_LoadFile]->SpecialInfo);
pos = pstrinfo->Buffer;
/* check if StringGadget isn't empty */
if(strlen(pos))
{
strcpy(LFullPath,pos);
dividepath(LFullPath,LDir,LFile);
getstringgads();
LoadFile();
}
return(TRUE);
}
int SaveFileClicked( void )
{
/* routine when gadget "Save" is clicked. */
struct StringInfo *pstrinfo;
char *pos;
pstrinfo = (struct StringInfo *)(EprommerGadgets[GD_SaveFile]->SpecialInfo);
pos = pstrinfo->Buffer;
/* check if StringGadget isn't empty */
if(strlen(pos))
{
strcpy(SFullPath,pos);
dividepath(SFullPath,SDir,SFile);
getstringgads();
SaveFile();
}
return(TRUE);
}
int EprommerCloseWindow( void )
{
/* routine for "IDCMP_CLOSEWINDOW". */
simplerequest("Please remove the EPROM now");
return(FALSE);
}
int DoOptionsClicked( void )
{
/* routine when gadget "Options" is clicked. */
/* - Lock 'EprommerWindow'
* - Mark/Unmark CheckBox Gadgets :
* - GD_NumericalBase
* - GD_SetClearBuffer
* - GD_SetBufferFrag
*/
int rc;
/* Lock the Eprommer Window */
lockwindow(EprommerWnd,TRUE);
if(rc=OpenOptionsWindow())
cleanup("Error Open Options Window");
newconf = conf; /* copy complete structure */
GT_SetGadgetAttrs(OptionsGadgets[GD_NumericalBase],OptionsWnd,NULL,GTCY_Active,conf.numericalbase,TAG_DONE);
GT_SetGadgetAttrs(OptionsGadgets[GD_SetBufferFrag],OptionsWnd,NULL,GTCB_Checked,conf.bufferfragmented,TAG_DONE);
GT_SetGadgetAttrs(OptionsGadgets[GD_SetClearBuffer],OptionsWnd,NULL,GTCB_Checked,conf.clearbuffer,TAG_DONE);
GT_SetGadgetAttrs(OptionsGadgets[GD_SetInfoReq],OptionsWnd,NULL,GTCB_Checked,conf.inforeq,TAG_DONE);
GT_SetGadgetAttrs(OptionsGadgets[GD_count],OptionsWnd,NULL,GTCB_Checked,conf.counting,TAG_DONE);
GT_SetGadgetAttrs(OptionsGadgets[GD_setepsize],OptionsWnd,NULL,GTCB_Checked,conf.defepsize,TAG_DONE);
GT_SetGadgetAttrs(OptionsGadgets[GD_CIADelay],OptionsWnd,NULL,GTIN_Number,conf.waitcnt,TAG_DONE);
rc=TRUE;
while( rc )
{
WaitPort( OptionsWnd->UserPort );
rc=HandleOptionsIDCMP();
}
CloseOptionsWindow();
lockwindow(EprommerWnd,FALSE);
return(TRUE);
}
int NumericalBaseClicked( void )
{
/* routine when gadget "Input String Gadget" is clicked. */
newconf.numericalbase=OptionsMsg.Code;
return(TRUE);
}
int SetClearBufferClicked( void )
{
/* routine when gadget "Clear Buffer (0xFF)" is clicked. */
newconf.clearbuffer=OptionsGadgets[GD_SetClearBuffer]->Flags&SELECTED;
return(TRUE);
}
int SetBufferFragClicked( void )
{
/* routine when gadget "Buffer fragmented" is clicked. */
newconf.bufferfragmented=OptionsGadgets[GD_SetBufferFrag]->Flags&SELECTED;
return(TRUE);
}
int SavePrefsClicked( void )
{
/* routine when gadget "SAVE" is clicked. */
FILE *fpconfig=NULL;
optionsvalid();
if( (!(fpconfig=fopen(CONFIG_ENVARC,"w"))) ||
(fwrite(&conf,sizeof(struct Config),1,fpconfig) != 1))
simplerequest("Error. Can't write Settings to '%s'",CONFIG_ENVARC);
if(fpconfig)
fclose(fpconfig);
return(TRUE);
}
int SetInfoReqClicked( void )
{
/* routine when gadget "Info Requester" is clicked. */
newconf.inforeq = OptionsGadgets[GD_SetInfoReq]->Flags&SELECTED;
return(TRUE);
}
int countClicked( void )
{
/* routine when gadget "Counting" is clicked. */
newconf.counting = OptionsGadgets[GD_count]->Flags&SELECTED;
return(TRUE);
}
int setepsizeClicked( void )
{
/* routine when gadget "EProm default size" is clicked. */
newconf.defepsize = OptionsGadgets[GD_setepsize]->Flags&SELECTED;
return(TRUE);
}
int CIADelayClicked( void )
{
/* routine when gadget "CIA Delay" is clicked. */
newconf.waitcnt = ((struct StringInfo *)(OptionsGadgets[GD_CIADelay]->SpecialInfo))->LongInt;
return(TRUE);
}
int OptionsOkClicked( void )
{
/* routine when gadget "OK" is clicked. */
optionsvalid();
return(FALSE);
}
int OptionsCancelClicked( void )
{
/* routine when gadget "CANCEL" is clicked. */
return(FALSE);
}
int OptionsCloseWindow( void )
{
/* routine for "IDCMP_CLOSEWINDOW". */
return(OptionsCancelClicked());
}
/***************** Routines to check Hardware ************************/
int TestHardwareClicked( void )
{
/* routine when gadget "Test" is clicked. */
int rc;
char title[64];
lockwindow (EprommerWnd,TRUE);
epromout = FALSE; /* Safer to think there is an Eprom plugged in */
if(rc=OpenTestWindow())
cleanup("Error Open Test Window");
SetAddr((TestMsg.Code==0)?0x5555:0xAAAA); /* Switch Eprom Address */
sprintf(title,"%s",TestWnd->Title);
SetWindowTitles(TestWnd,title,NULL);
rc = TRUE;
while( rc )
{
WaitPort( TestWnd->UserPort );
rc=HandleTestIDCMP();
}
testvppoff();
testvpp=VOLTS12;
CloseTestWindow();
lockwindow (EprommerWnd,FALSE);
epromout = FALSE; /* Safer to think there is an Eprom plugged in */
return(TRUE);
}
int NoEpromClicked( void )
{
/* routine when gadget "Eprom removed" is clicked. */
GT_SetGadgetAttrs(TestGadgets[GD_SetVpp],TestWnd,NULL,GA_Disabled,epromout,TAG_DONE);
epromout=TestGadgets[GD_NoEprom]->Flags&SELECTED;
testvppoff();
if(epromout)
testvppon(testvpp);
return(TRUE);
}
int SetVppClicked( void )
{
/* routine when gadget "" is clicked. */
switch(TestMsg.Code)
{
case CY_VPP12: testvppoff();
testvppon(VOLTS12);
testvpp=VOLTS12;
break;
case CY_VPP21: testvppoff();
testvppon(VOLTS21);
testvpp=VOLTS21;
break;
case CY_VPP25: testvppoff();
testvppon(VOLTS25);
testvpp=VOLTS25;
break;
default: simplerequest("Error VPP Cycle Gadget. File:%s Line:%d",__FILE__,__LINE__);
}
return(TRUE);
}
int T_CyAddressClicked( void )
{
/* routine when gadget "Address" is clicked. */
SetAddr((TestMsg.Code==0)?0x5555:0xAAAA); /* Switch Eprom Address */
return(TRUE);
}
int T_CyDataClicked( void )
{
/* routine when gadget "Data" is clicked. */
*ParPort = (TestMsg.Code==0)?0x55:0xAA;
return(TRUE);
}
int TestCloseWindow( void )
{
/* routine for "IDCMP_CLOSEWINDOW". */
return(FALSE);
}
/*
* free every resource we might have allocated
*/
static void cleanup(char *s)
{
ThatsIt();
if (window_locked) lockwindow(window_locked,FALSE);
if (s) puts(s);
if (pp_flag) FreeMiscResource(MR_PARALLELPORT);
if (ppb_flag) FreeMiscResource(MR_PARALLELBITS);
if (tp) CloseTimer(tr);
CloseEprommerWindow();
CloseOptionsWindow();
CloseBusyWindow();
CloseTestWindow();
CloseDownScreen();
#ifndef _DCC
if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
if (GfxBase) CloseLibrary((struct Library *)GfxBase);
#endif
if (aslreq) FreeAslRequest(aslreq);
if (PEmemBase) FreeMem(PEmemBase,MAXDATABUFFER);
if (plockreq) FreeMem(plockreq,sizeof(struct Requester));
if(s)
exit(RETURN_ERROR);
else
exit(RETURN_OK);
}
static void handlesigint(int sig)
{
cleanup("Ctrl-C detected");
return;
}
int wbmain(void)
{
int rc;
rc=main(0,NULL);
return(rc);
}
int main(int argc, char **argv)
{
int rc,def_flag;
FILE *fpconfig=NULL;
char *owner;
char title[64],*pos;
signal(SIGINT,handlesigint);
/*
* Open all libraries, as well as the program's window
*/
#ifndef _DCC
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");
#endif
if(rc=SetupScreen())
cleanup("Error Setting Screen");
if(rc=OpenEprommerWindow())
cleanup("Error Open Eprommer Window");
strcpy(title,&vers[7]);
strcat(title," © Bob,Udi,Carsten");
SetWindowTitles(EprommerWnd,title,(char *)-1);
if(!(PEmemBase = AllocMem(MAXDATABUFFER,MEMF_ANY+MEMF_CLEAR)))
cleanup("No Memory!\n");
#ifdef DEBUG_PROG
printf("RAM:%lx\n",PEmemBase);
#endif
/* Initialization for FileRequester */
if(!(aslreq=AllocAslRequestTags(ASL_FileRequest,ASL_Hail,"FileRequester",TAG_DONE)))
cleanup("Allocate ASL Requester failed");
/* Initialization for Lock Requester */
if(!(plockreq=AllocMem(sizeof(struct Requester),MEMF_ANY+MEMF_CLEAR)))
{
cleanup("Can't alocate memory for 'Lock Requester'");
return;
}
plockreq->LeftEdge=-1;
plockreq->TopEdge=-1;
plockreq->Width=0;
plockreq->Height=0;
/* Initialization for timer */
if (OpenTimer())
cleanup("No timer!");
/* Clear Load,Save Paths */
SFullPath[0] = LFullPath[0] = '\0';
/* Load/Set default Configuration */
def_flag = TRUE;
if(fpconfig=fopen(CONFIG_ENV,"r"))
{
if(fread(&conf,sizeof(struct Config),1,fpconfig) != 1)
{
simplerequest("Error reading '%s'",CONFIG_ENV);
perror(CONFIG_ENV);
}
else
{
/* Take latest used Directories */
strcpy(LDir,conf.loaddir);
pos = ((struct StringInfo *)(EprommerGadgets[GD_LoadFile]->SpecialInfo))->Buffer;
strcpy(pos,LDir);
strcpy(SDir,conf.savedir);
pos = ((struct StringInfo *)(EprommerGadgets[GD_SaveFile]->SpecialInfo))->Buffer;
strcpy(pos,SDir);
RefreshGList(EprommerGadgets[GD_LoadFile], EprommerWnd, NULL, 1);
RefreshGList(EprommerGadgets[GD_SaveFile], EprommerWnd, NULL, 1);
waitcnt = conf.waitcnt;
def_flag=FALSE;
}
fclose(fpconfig);
fpconfig=NULL;
}
/* determine CIA delay. Is there any commandline Option ? */
if(argc>=2)
waitcnt=MAX(1,atoi(argv[1]));
else
{
if(def_flag)
checkspeed(); /* No, so calculate the CIA-delay */
}
/* Defaults, if reading Prefs-File failed */
if(def_flag)
{
conf.epromtype = EP_2716; /* 2716 */
conf.dataformat = BINARY; /* set DataFormat to BINARY */
conf.bufferfragmented = FALSE; /* Buffer Fragmentation allowed */
conf.clearbuffer = FALSE; /* clear buffer first before load */
conf.numericalbase = CY_DECHEX; /* Set Default Input to Decimal and Hexadecimal */
conf.inforeq = TRUE; /* Requester appears for default */
conf.counting = TRUE; /* Show address counting for default */
conf.defepsize = TRUE; /* Set default Eprom Size */
conf.loaddir[0] = '\0'; /* Delete Load directory */
conf.savedir[0] = '\0'; /* Delete Save directory */
conf.waitcnt = waitcnt; /* CIA Delay */
}
setepromtype(conf.epromtype);
/* Initialize hardware */
InitPorts();
GT_SetGadgetAttrs(EprommerGadgets[GD_EpromType],EprommerWnd,NULL,GTMX_Active,EPType,TAG_DONE);
GT_SetGadgetAttrs(EprommerGadgets[GD_DataFormat],EprommerWnd,NULL,GTCY_Active,conf.dataformat,TAG_DONE);
/* Prepare Address counting (Busy/Abort Window) */
IT_counting = BusyIText[1]; /* Copy original IntuiText structure */
/* X,Y-Position depends on Font Size. */
/* OffX,OffY,Font,FontX,FontY are calculated in gad_eprommer.c during SetupScreen() */
IT_counting.ITextFont = Font;
IT_counting.LeftEdge = OffX + ((( FontX * IT_counting.LeftEdge ) + 4 ) / 8 ) - ( IntuiTextLength( &IT_counting ) >> 1 );
IT_counting.TopEdge = OffY + ((( FontY * IT_counting.TopEdge ) + 4 ) / 8 ) - ( Font->ta_YSize >> 1 );
/* At Program End: MiscBase don't have to be closed - there's no 'CloseResource()' */
if (!(MiscBase = (struct Library *)OpenResource(MISCNAME)))
cleanup("Can't open 'misc.resource' !\n");
if(owner = AllocMiscResource(MR_PARALLELPORT,"Eprommer"))
{
if(!(twogadrequest("OK|CANCEL","Parallel Port already allocated by:%s\nDo you want continue ?",owner)))
cleanup("PAR: busy");
}
else
pp_flag = TRUE;
if(pp_flag)
{
if(owner = AllocMiscResource(MR_PARALLELBITS,"Eprommer"))
{
if(!(twogadrequest("OK|CANCEL","Parallel Port Bits already allocated by:%s\nDo you want continue ?",owner)))
cleanup("PAR: busy");
}
else
ppb_flag = TRUE;
}
/*
* Event loop
*/
rc = TRUE;
while( rc )
{
WaitPort( EprommerWnd->UserPort );
rc=HandleEprommerIDCMP();
}
/* Take latest used Directories */
strcpy(conf.loaddir,LDir);
strcpy(conf.savedir,SDir);
if( (!(fpconfig=fopen("ENV:Eprommer.prefs","w"))) ||
(fwrite(&conf,sizeof(struct Config),1,fpconfig) != 1))
simplerequest("Error. Can't write Settings to 'ENV:Eprommer.prefs'");
if(fpconfig)
fclose(fpconfig);
cleanup(NULL);
return(0);
}