#include #include #include #include #include #include "bin.out.h" #define KICK_SIG 0x4b49434b struct MsgPort *mp; struct IOStdReq *iob; char *diskbuf; extern struct MsgPort *CreatePort(); extern struct IOStdReq *CreateStdIO(); extern long OpenDevice(); extern void *AllocMem(); extern int Enable_Abort; main(argc,argv) int argc; char *argv[]; { int fd; struct bin uh; unsigned long startaddr; unsigned long endaddr; unsigned long size; int offset,bytestoread; long sector; int rc = 20; if(argc!=2) { printf("Syntax: %s filename\n",argv[0]); exit(99); } fd = open(argv[1],O_RDONLY); if(fd==-1) { printf("Unable to open '%s'.\n",argv[1]); exit(20); } if(read(fd,&uh,sizeof(struct bin)) != sizeof(struct bin)) { printf("Unable to read binary file header.\n"); close(fd); exit(20); } if(uh.b_magic != BMAGIC) { printf("Not an unhunk output file.\n"); close(fd); exit(20); } if(uh.b_data || uh.b_bss) { printf("Fatal: File contains data or bss segments.\n"); close(fd); exit(20); } size = uh.b_text; startaddr = uh.b_txorg; endaddr = startaddr + size - 1; printf("%s: start $%lx, length $%lx, end $%lx.\n", argv[1],startaddr, size, endaddr); if(startaddr < 0xfc0000 || endaddr > 0xffffff) { printf("Fatal: Text segment not in kickstart memory.\n"); close(fd); exit(20); } if(!size) { printf("Fatal: Text segment is empty.\n"); close(fd); exit(20); } Enable_Abort = 0; mp = CreatePort(0L,0L); if(!mp) exit(99); iob = CreateStdIO(mp); if(!iob) { DeletePort(mp); exit(99); } if(OpenDevice("trackdisk.device",0L,iob,0L)) { printf("Unable to open device driver.\n"); DeleteStdIO(iob); DeletePort(mp); exit(99); } diskbuf = AllocMem(512L,MEMF_PUBLIC|MEMF_CHIP); if(!diskbuf) { CloseDevice(iob); DeleteStdIO(iob); DeletePort(mp); close(fd); exit(99); } iob->io_Command = CMD_READ; iob->io_Data = (APTR) diskbuf; iob->io_Length = 512; iob->io_Offset = 0; DoIO(iob); if(iob->io_Error) { printf("Fatal: Unable to read block zero from floppy.\n"); goto bomb; } if(*((long *)diskbuf) != KICK_SIG) { printf("Fatal: Floppy is not a kickstart disk.\n"); goto bomb; } sector = 1 + ((startaddr - 0xfc0000) >> 9); offset = startaddr & 0x1ff; do { if(offset || (size<512)) { iob->io_Command = CMD_READ; iob->io_Data = (APTR) diskbuf; iob->io_Length = 512; iob->io_Offset = sector << 9; DoIO(iob); if(iob->io_Error) { printf("Fatal: Unable to read sector %ld from kickstart disk.\n",sector); goto bomb; } } bytestoread = 512 - offset; if(sizeio_Command = CMD_WRITE; iob->io_Data = (APTR) diskbuf; iob->io_Length = 512; iob->io_Offset = sector << 9; DoIO(iob); if(iob->io_Error) { if(iob->io_Error == TDERR_WriteProt) printf("Fatal: Kickstart disk is write-protected.\n"); else printf("Fatal: Unable to write sector %ld to kickstart disk.\n",sector); goto bomb; } size -= bytestoread; sector += 1; offset = 0; } while(size); iob->io_Command = CMD_UPDATE; DoIO(iob); if(iob->io_Error) { if(iob->io_Error == TDERR_WriteProt) printf("Fatal: Kickstart disk is write-protected.\n"); else printf("Fatal: Disk update failed.\n"); goto bomb; } printf("Disk update successful.\n"); rc = 0; bomb: iob->io_Command = TD_MOTOR; iob->io_Length = 0; DoIO(iob); FreeMem(diskbuf,512L); CloseDevice(iob); DeleteStdIO(iob); DeletePort(mp); close(fd); exit(rc); }