home *** CD-ROM | disk | FTP | other *** search
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/ports.h>
- #include <exec/io.h>
- #include <devices/trackdisk.h>
- #include <dos/rdargs.h>
- #include <dos/doshunks.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
-
- #include <stdio.h>
- #include <stdlib.h>
-
- const STRPTR PROG_Name = "BBInstall";
- const STRPTR PROG_Ver = "1";
- const STRPTR PROG_Rev = "7";
- const STRPTR PROG_Date = "1st September 1997";
-
- /* Information for C:Version */
- const STRPTR VerStr = "$VER: BBInstall 1.7 (1st September 1997)";
-
-
- const STRPTR BA_Template = "DRIVE/A,LOAD/K,SAVE/K,DOSTYPE/N,CODE/S,MOVESYS/S";
-
- struct BBIArgs {
- STRPTR DRIVE;
- STRPTR LOAD;
- STRPTR SAVE;
- ULONG *DOSTYPE;
- ULONG CODE;
- ULONG MOVESYS;
- };
-
- struct RDArgs *rdargs;
- struct MsgPort *diskport;
- struct IOExtTD *diskreq;
- BYTE td_open;
- ULONG *bb_buffer;
- FILE *bbfile;
-
-
- /* Initialize global data */
- void clear_globals(void)
- {
- rdargs = NULL;
- diskport = NULL;
- diskreq = NULL;
- td_open = NULL;
- bb_buffer = NULL;
- bbfile = NULL;
- }
-
- /* Exit cleanly */
- void clean_exit(ULONG rc)
- {
- /* Close BootBlock FILE */
- if (bbfile) fclose(bbfile);
-
- /* Free Allocated Memory */
- if (bb_buffer) FreeMem(bb_buffer,1024);
-
- /* Close TrackDisk Unit */
- if (td_open)
- {
- /* Flush any buffers */
- diskreq->iotd_Req.io_Command = CMD_UPDATE;
- DoIO((struct IORequest *)diskreq);
-
- /* Turn off the motor */
- diskreq->iotd_Req.io_Command = TD_MOTOR;
- diskreq->iotd_Req.io_Length = 0;
- DoIO((struct IORequest *)diskreq);
-
- /* Close trackdisk.device */
- CloseDevice((struct IORequest *)diskreq);
- }
-
- /* Delete IO Request */
- if (diskreq) DeleteIORequest(diskreq);
-
- /* Delete Message Port */
- if (diskport) DeleteMsgPort(diskport);
-
- /* Free arguments */
- if (rdargs) FreeArgs(rdargs);
-
- exit(rc);
- }
-
-
- void LoadCode(ULONG *buf, FILE *infile, STRPTR infilename, ULONG moveSysBase)
- {
- ULONG read_value;
- ULONG code_size;
- int i;
-
- /* Find a HUNK_CODE within input file */
- do {
- fread(&read_value,4,1,infile);
- } while ((read_value != HUNK_CODE) && (!feof(infile)));
-
- if (read_value != HUNK_CODE)
- {
- fprintf(stderr,"%s has no code hunk.\n",infilename);
- clean_exit(10);
- }
-
- /* Get size of code */
- fread(&code_size,4,1,infile);
- if (moveSysBase)
- {
- fread(&read_value,4,1,infile);
-
- if (read_value == 0x2C780004)
- code_size--;
- else
- fseek(infile,-4,SEEK_CUR);
- }
- if (code_size > 253)
- {
- fprintf(stderr,"%s is too large to fit into a boot block.\n",infilename);
- clean_exit(10);
- }
-
- /* read code into bootblock array and clear leftover space */
- fread(buf+3,4,code_size,infile);
- for (i=code_size+3; i<256; i++)
- buf[i] = 0;
- }
-
- void LoadData(ULONG *buf, FILE *infile)
- {
- int i;
- ULONG read_value;
-
- /* Clear buffer */
- for (i=0; i<256; i++)
- buf[i] = 0;
-
- fread(&read_value,4,1,infile);
-
- if ((read_value & 0xFFFFFF00) == 0x444F5300)
- {
- buf[0] = read_value;
- fread(buf+1,4,255,infile);
- }
- else
- {
- buf[3] = read_value;
- fread(buf+4,4,252,infile);
- }
- }
-
- void SaveCode(ULONG *buf, FILE *outfile, ULONG moveSysBase)
- {
- ULONG exe_head[8] = {HUNK_HEADER,0,1,0,0,253,
- HUNK_CODE,253};
- ULONG exe_foot[1] = {HUNK_END};
- ULONG exe_sysbase[1] = {0x2C780004}; /* MOVEA.L 4.W,A6 */
-
- if (moveSysBase)
- {
- exe_head[5]++;
- exe_head[7]++;
- }
-
- fwrite(exe_head,4,8,outfile);
-
- if (moveSysBase)
- fwrite(exe_sysbase,4,1,outfile);
-
- fwrite(buf+3,4,253,outfile);
- fwrite(exe_foot,4,1,outfile);
- }
-
- void SaveData(ULONG *buf, FILE *outfile)
- {
- fwrite(buf,4,256,outfile);
- }
-
- ULONG calcsum(ULONG *buf)
- {
- ULONG sum,prevsum;
- int i;
-
- sum = buf[0];
- prevsum = 0;
- if (sum < 0)
- sum++;
-
- for (i=2; i<256; i++)
- {
- prevsum = sum;
- sum += buf[i];
- if (prevsum > sum)
- sum++;
- }
-
- return -(sum+1);
- }
-
- void OutputBanner(void)
- {
- printf("\033[1m%s v%s.%s © %s Karl J. Ots\033[0m\n\n",PROG_Name,
- PROG_Ver,
- PROG_Rev,
- PROG_Date);
- }
-
- void OutputUsage(void)
- {
- fprintf(stderr,"Usage: BBInstall %s\n",BA_Template);
- clean_exit(5);
- }
-
- int main(int argc, char *argv[])
- {
- struct BBIArgs BBIArgs = {NULL, NULL, NULL, NULL, FALSE, FALSE};
- int unit;
- ULONG old_dostype;
-
- clear_globals();
- OutputBanner();
-
- /* Collect and analyse arguments */
- rdargs = ReadArgs(BA_Template,(ULONG *)&BBIArgs,NULL);
- if (!rdargs)
- OutputUsage();
-
- if ((BBIArgs.LOAD && BBIArgs.SAVE) ||
- (!BBIArgs.LOAD && !BBIArgs.SAVE))
- OutputUsage();
-
-
- /* Determine if DRIVE is valid */
- if (((BBIArgs.DRIVE[0] != 'D') && (BBIArgs.DRIVE[0] != 'd')) ||
- ((BBIArgs.DRIVE[1] != 'F') && (BBIArgs.DRIVE[1] != 'f')) ||
- (BBIArgs.DRIVE[2] >= '4') ||
- (BBIArgs.DRIVE[3] != ':'))
- {
- fprintf(stderr,"Invalid Drive %s\n",BBIArgs.DRIVE);
- clean_exit(5);
- }
- unit = BBIArgs.DRIVE[2] - '0';
-
-
- /* Open TrackDisk Unit */
- diskport = CreateMsgPort();
- if (!diskport)
- {
- fputs("Error: Couldn't create a Message Port (Out of Memory?)\n",stderr);
- clean_exit(20);
- }
-
- diskreq = (struct IOExtTD *)
- CreateIORequest(diskport,sizeof(struct IOExtTD));
- if (!diskreq)
- {
- fputs("Error: Couldn't create an IO request (Out of Memory?)\n",stderr);
- clean_exit(20);
- }
-
- td_open = !OpenDevice(TD_NAME,unit,(struct IORequest *)diskreq,NULL);
- if (!td_open)
- {
- fprintf(stderr,"Can't open trackdisk.device unit %d (DF%d:)!\n",unit,
- unit);
- clean_exit(20);
- }
-
-
- /* Allocate some memory */
- bb_buffer = (ULONG *)AllocMem(1024,MEMF_CLEAR|MEMF_CHIP);
- if (!bb_buffer)
- {
- fputs("Error: Out of memory.\n",stderr);
- clean_exit(10);
- }
-
- /* Read TrackDisk Unit */
- diskreq->iotd_Req.io_Length = 1024;
- diskreq->iotd_Req.io_Data = bb_buffer;
- diskreq->iotd_Req.io_Command = CMD_READ;
- diskreq->iotd_Req.io_Offset = 0;
- if (DoIO((struct IORequest *)diskreq))
- {
- fputs("An error occured\n",stderr);
- clean_exit(20);
- }
-
- old_dostype = bb_buffer[0];
-
- if (BBIArgs.LOAD)
- {
- bbfile = fopen(BBIArgs.LOAD,"rb");
- if (!bbfile)
- {
- fprintf(stderr,"Couldn't open \"%s\" for reading\n",BBIArgs.LOAD);
- clean_exit(10);
- }
- printf("Loading \"%s\" as %s to DF%d: ... \n",BBIArgs.LOAD,
- (BBIArgs.CODE ? "code" : "data"),
- unit);
-
- /* Setup bootblock header (without checksum) */
- /* bb_buffer[0] = bb_buffer[0] */ /* Obviously... */
- bb_buffer[1] = 0;
- bb_buffer[2] = 0x00000370;
-
- if (BBIArgs.CODE)
- LoadCode(bb_buffer,bbfile,BBIArgs.LOAD,BBIArgs.MOVESYS);
- else
- LoadData(bb_buffer,bbfile);
-
- if (BBIArgs.DOSTYPE)
- bb_buffer[0] = (bb_buffer[0] & 0xFFFFFF00) |
- (BBIArgs.DOSTYPE[0] & 0xFF);
- printf(" Dostype = 0x%02X ... ",(bb_buffer[0] & 0xFF));
- fflush(stdout);
-
- /* Calculate checksum and insert it into bootblock */
- bb_buffer[1] = calcsum(bb_buffer);
- printf("Checksum = 0x%08X ... ",bb_buffer[1]);
- fflush(stdout);
-
- /* bb_buffer in now ready to be inserted into bootblock */
- /* Write TD Unit */
- diskreq->iotd_Req.io_Length = 1024;
- diskreq->iotd_Req.io_Data = bb_buffer;
- diskreq->iotd_Req.io_Command = CMD_WRITE;
- diskreq->iotd_Req.io_Offset = 0;
- if (DoIO((struct IORequest *)diskreq))
- {
- fputs("Another error occured\n",stderr);
- clean_exit(20);
- }
-
- puts("Done.\n");
- }
- else /* if (BBIArgs.SAVE) */ /* <-- We know this is set if LOAD isn't */
- {
- bbfile = fopen(BBIArgs.SAVE,"wb");
- if (!bbfile)
- {
- fprintf(stderr,"Couldn't open \"%s\" for writing.\n",BBIArgs.SAVE);
- clean_exit(10);
- }
- printf("Saving old BootBlock from DF%d: to \"%s\" as %s ... ",unit,
- BBIArgs.SAVE,
- (BBIArgs.CODE ? "code" : "data"));
- fflush(stdout);
-
- if (BBIArgs.CODE)
- SaveCode(bb_buffer,bbfile,BBIArgs.MOVESYS);
- else
- SaveData(bb_buffer,bbfile);
-
- puts("Done.\n");
- }
-
- clean_exit(0);
-
- return 0; /* Keep compiler happy */
- }
-