home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD1.img
/
d1xx
/
d157
/
bootback
/
bootback.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-10-02
|
10KB
|
253 lines
==========
amiga/programs #367, from talin, 9715 chars, Sun Feb 7 07:56:54 1988
Comment to 366.
----------
/***********************************************************************
* bootback.c - copies boot blocks to file, or files to boot blocks *
* By Talin, otherwise known as David Joiner *
* Note comments are only mostly serious *
***********************************************************************/
/* compiled like this:
cc +l bootback
ln bootback.o -lc32
*/
#include "exec/types.h"
#include "exec/memory.h"
#include "libraries/dosextens.h" /* my DOS is bigger than your DOS */
#include "libraries/filehandler.h"
#include "devices/trackdisk.h" /* But does it make a good frisbee? */
#include "arp/arpbase.h"
#include "arp/arpfunctions.h"
#define SCAT goto exit_pgm
#define MAX_FILENAME 32
struct ArpBase *ArpBase; /* Mama! */
void *OpenLibrary(), /* Daddy! */
*AllocMem(); /* Cheetah! */
/* This is the stuff mother never told you about */
struct DevEnviron {
ULONG TableSize, SizeBlock, SecOrg, NumHeads,
SecsPerBlock, BlocksPerTrack, ReservedBlocks, Preface,
Interleave, LowCylinder, UpperCylinder, NumBuffers,
MemBufType;
} *environ;
ULONG blocksize;
struct MsgPort *diskport, *CreatePort();
struct IOExtTD *diskreq, *CreateExtIO();
#define ADDR(a) (void *)( (int)a << 2) /* I don't like the standard macro */
/* This is a rather EVIL way to do this, but I can think of nothing
else that will work in a reasonable fashion.
Essentially what this does is take a name of a device or volume
and returns the DeviceNode entry for that device, buy brute force
searching through the AmigaDOS device list. For a volume, the
search has to be done twice, and is rather kludgey.
Works like a charm. I wish it worked like software instead.
Once this is done, the caller can easily determine the device
driver name for exec-level IO. (see main below).
*/
struct DeviceNode *get_device(name) char *name;
{ struct DeviceNode *dlist = NULL;
char device_name[MAX_FILENAME+2];
short length;
while (dlist = (struct DeviceNode *)GetDevInfo(dlist))
{ length = BtoCStr(device_name,dlist->dn_Name,33);
device_name[length++] = ':'; /* Appendix a Colon on the end */
device_name[length] = '\0'; /* and that other thing */
/* try to find a match with name */
if (Strcmp(name,device_name)==0)
{ if (dlist->dn_Type == DLT_DEVICE) return dlist;
if (dlist->dn_Type == DLT_VOLUME)
{ struct Task *dev_task;
char *task_name, *colon_name;
struct MsgPort *proc; /* actually a Process, but those */
/* makes no sense anyway */
proc = (struct MsgPort *)dlist->dn_Task;
/* Oooh, I remembered 'mp_SigTask' without looking it
up...that's Scary. */
dev_task = proc->mp_SigTask; /* not very kosher */
colon_name = device_name; /* copy device name to here */
task_name = dev_task->tc_Node.ln_Name; /* BAD Talin! BAD! */
while (*task_name) *colon_name++ = *task_name++; /* copy */
*colon_name++ = ':'; /* put a colon on it, bud. */
*colon_name++ = '\0'; /* and stop it from bleeding */
return get_device(device_name); /* recursive but only once */
}
return NULL; /* return NULL for assigns: */
}
}
return NULL; /* Negative, Will Robinson */
}
extern struct WBStartup *WBenchMsg;
wb_parse(); /* stub */
main(argc, argv) LONG argc; UBYTE **argv;
{ char driver_name[MAX_FILENAME+2];
ULONG error, /* open device error */
arg_device, /* which arg was the device */
arg_file; /* and which was the file? */
struct FileSysStartupMsg *fssm; /* filesys startup message */
struct DeviceNode *d1, /* Device node entries for */
*d2, /* arg1, arg2 and */
*dvc; /* whichever one we open */
struct FILE *save_file=NULL, *Open();
APTR buff=NULL; /* buffer for loaded blocks */
UBYTE device_open=0; /* flag is device was open */
diskport = NULL; diskreq = NULL;
if (WBenchMsg) exit(0); /* HELL NO, WE WON'T GO! */
if (!(ArpBase = OpenLibrary("arp.library",0))) /* open up there, arp! */
{ Write(Output(),"Can't find arp.library\n",23); /* You Varmit! */
exit(20);
}
if (argc != 3) /* check to make sure correct # of arguments */
{ Printf("BootBack - Saves and restores custom boot blocks\n");
Printf("Usage:\n\n");
Printf("To save boot block: BootBack <device> <file>\n");
Printf("To restore boot block: BootBack <file> <device>\n");
SCAT; /* Take a powder */
}
d1 = get_device(argv[1]);
d2 = get_device(argv[2]);
if (d1 && d2) { Printf("They can't BOTH be devices!\n"); SCAT; }
if (!d1 && !d2) { Printf("Neither of those is a device, silly!\n"); SCAT; }
if (d1) { dvc = d1; arg_device = 1; arg_file = 2; }
if (d2) { dvc = d2; arg_device = 2; arg_file = 1; }
fssm = ADDR(dvc->dn_Startup);
if (!fssm)
{ Printf("Can't find device driver for <%s>.\n",argv[arg_device]); SCAT; }
BtoCStr(driver_name,fssm->fssm_Device,33);
environ = ADDR(fssm->fssm_Environ);
blocksize = environ->SizeBlock * sizeof (LONG); /* BCPL foolishness */
if (arg_file == 1) save_file = Open(argv[arg_file],MODE_OLDFILE);
else save_file = Open(argv[arg_file],MODE_NEWFILE);
if (!save_file)
{ Printf("Can't open save file <%s>.\n",argv[arg_file]); SCAT; }
/* Ah pity the foo don't have enough memory to run this program! */
buff = AllocMem(2 * blocksize,MEMF_CHIP);
if (!buff) { Printf("Not enough memory.\n"); SCAT; } /* TILT! */
if (!(diskport = CreatePort(0,0)) ||
!(diskreq = CreateExtIO(diskport,sizeof (struct IOExtTD))) ||
(error = OpenDevice(driver_name,fssm->fssm_Unit,
diskreq,fssm->fssm_Flags)) )
{ Printf("Problems opening disk device...!\n");
if (error) Printf("Error = %d.\n",error);
SCAT; /* get outta here, ya nut! */
}
device_open = TRUE;
Printf("%s opened.\n",driver_name); /* chatty but educational */
if (arg_file == 2) /* if filename was 2nd arg */
{ if (load_track_range(0,2,buff)) /* 2 lumps please */
{ Printf("Problem reading device...\n"); SCAT; } /* TOAST */
Write(save_file,"BOOTBLOC",8); /* id check for safety's sake */
Write(save_file,buff,2*blocksize); /* Doit Toit */
}
else
{ char file_id[9]; /* id string */
Read(save_file,file_id,8); /* read id */
file_id[8] = 0; /* null terminate */
if (Strcmp(file_id,"BOOTBLOC"))
{ Printf("This file is NOT a saved boot block!\n"); SCAT; }
Read(save_file,buff,2 * blocksize);
if (save_track_range(0,2,buff)) /* Thou art Healed! A Miracle! */
{ Printf("Problem writing device...\n"); SCAT; } /* Well, Almost */
}
Printf("Done!\n");
exit_pgm:
if (device_open) { motor_off(); CloseDevice(diskreq); }
if (diskreq) DeleteExtIO(diskreq,sizeof (struct IOExtTD));
if (diskport) DeletePort(diskport);
if (buff) FreeMem(buff,2 * blocksize);
if (save_file) Close(save_file);
if (ArpBase) CloseLibrary(ArpBase);
}
save_track_range(first_block,block_count,buffer)
short first_block, block_count; char *buffer;
{ diskreq->iotd_Req.io_Length = (block_count * blocksize);
diskreq->iotd_Req.io_Data = (APTR)buffer;
diskreq->iotd_Req.io_Command = CMD_WRITE;
diskreq->iotd_Req.io_Offset = (first_block * blocksize);
DoIO(diskreq);
return diskreq->iotd_Req.io_Error;
}
load_track_range(first_block,block_count,buffer)
short first_block, block_count; char *buffer;
{ diskreq->iotd_Req.io_Length = (block_count * blocksize);
diskreq->iotd_Req.io_Data = (APTR)buffer;
diskreq->iotd_Req.io_Command = CMD_READ;
diskreq->iotd_Req.io_Offset = (first_block * blocksize);
DoIO(diskreq);
return diskreq->iotd_Req.io_Error;
}
motor_off()
{ diskreq->iotd_Req.io_Length = 0;
diskreq->iotd_Req.io_Command = TD_MOTOR;
DoIO(diskreq);
}
#asm
cseg
include "arp/arpbase.i"
public _ArpBase
public _Printf
_Printf move.l 4(sp),a0
lea 8(sp),a1
move.l _ArpBase,a6
jmp _LVOPrintf(a6)
public _Strcmp
_Strcmp move.l 4(sp),a0
move.l 8(sp),a1
move.l _ArpBase,a6
jmp _LVOStrcmp(a6)
public _GetDevInfo
_GetDevInfo move.l 4(sp),a2
move.l _ArpBase,a6
jmp _LVOGetDevInfo(a6)
public _BtoCStr
_BtoCStr move.l 4(sp),a0
move.l 8(sp),d0
move.l 12(sp),d1
move.l _ArpBase,a6
jmp _LVOBtoCStr(a6)
#endasm
/* That's all, folks! */