home *** CD-ROM | disk | FTP | other *** search
- ;/*
- sc DisAsm=ram:1541.s 1541.c ProgramName=1541 ObjectName=ram: Ignore=73+306 GST=include:all.gst GSTImm NoIcon NoStackCheck UnsignedChar Parm=Register Opt OptSched OptInLocal OptDep=100 OptRDep=100 CommentNest Link
- quit
- */
-
- /*
- 1541 disk-to-file convertor for A1020
- Copyright © 1994 by Dan Babcock
-
- Compiled with SAS/C V6.51
- */
-
- typedef short bool; /* enum bool { FALSE, TRUE }; */
-
- /* Buffers */
- #define RAWBUFSIZE 9000
- #define MAXBITPTR RAWBUFSIZE*8-400*8
-
- #define DISKSIZE 683*256
- static __chip char RawBuffer[RAWBUFSIZE];
- static __far char DecodedBuffer[DISKSIZE];
-
- /* Command line parsing */
- enum cmdargs { DRIVE, FILENAME, RETRY, TOP, OFFSET, NUMARGS };
- static struct RDArgs *rdargs;
- static LONG args[NUMARGS];
-
- /* Device access */
- static struct MsgPort *port;
- static struct IOStdReq *io;
- static bool DevOpen;
-
- /* Misc */
- static char ver[]="$VER: 1541 1.01 (17.6.94)\n";
- long __OSlibversion = 37;
- struct Library *DiskBase;
- static unsigned RetryCount=10;
-
- /* Finish disk I/O */
- static void FinishIO(void)
- {
- io->io_Command = TD_MOTOR;
- io->io_Length = 0;
- DoIO((struct IORequest *)io);
- }
-
- /* Autotermination routine */
- void _STDautoterm(void)
- {
- /* Free misc */
- if (DevOpen) {
- FinishIO();
- CloseDevice((struct IORequest *)io);
- }
- if (io) DeleteIORequest(io);
- if (port) DeleteMsgPort(port);
- if (rdargs) FreeArgs(rdargs);
- }
-
- /* Read a raw track */
- /* Unfortunately we can't use TD_RAWREAD, since we need to set 4us/bit mode */
- static void RawRead(unsigned track)
- {
- static struct DiscResourceUnit diskunit; /* initialized to zero because of static */
- // volatile struct CIA *ciaa=(void*)0xbfe001;
- volatile struct CIA *ciab=(void*)0xbfd000;
- volatile struct Custom *custom=(void*)0xdff000;
-
- /* TD motor on */
- io->io_Command = TD_MOTOR;
- io->io_Length = 1;
- DoIO((struct IORequest *)io);
-
- /* Seek to the proper track */
- io->io_Command = TD_SEEK;
- io->io_Offset = track*5632;
- if (args[OFFSET])
- io->io_Offset += (*(int*)args[OFFSET])*11264;
- if (io->io_Offset > 11264*39)
- io->io_Offset = 0;
- DoIO((struct IORequest *)io);
-
- /* Take over the disk hardware and read the track "by hand" */
- /* (which is a pain even when taking some shortcuts) */
- /* Here goes...*/
-
- /* get the resource */
- diskunit.dru_Message.mn_ReplyPort=port;
- diskunit.dru_Message.mn_Node.ln_Name="1541 disk reader";
- while (!GetUnit((struct DiskResourceUnit*)&diskunit)) {
- WaitPort(port);
- GetMsg(port); /* important! remove message */
- }
-
- /* set up CIA bits, turn on motor, wait for motor */
- ciab->ciaprb |= CIAF_DSKSEL0|CIAF_DSKSEL1|CIAF_DSKSEL2|CIAF_DSKSEL3;
- ciab->ciaprb &= ~CIAF_DSKMOTOR;
- ciab->ciaprb &= ~(1<<(*(int *)args[DRIVE]+3));
- if (track & 1)
- ciab->ciaprb &= ~CIAF_DSKSIDE;
- else
- ciab->ciaprb |= CIAF_DSKSIDE;
- // while (ciaa->ciapra & CIAF_DSKRDY)
- // ;
-
- /* set up disk hardware */
- custom->adkcon = ADKF_WORDSYNC|ADKF_MSBSYNC|ADKF_FAST;
- custom->intreq = INTF_DSKBLK;
- custom->dskpt = RawBuffer;
-
- /* now for the main event...drum roll please */
- custom->dsklen = (RAWBUFSIZE/2)|(1<<15);
- custom->dsklen = (RAWBUFSIZE/2)|(1<<15);
- while (!(custom->intreqr & INTF_DSKBLK))
- ;
-
- /* done! */
- custom->intreq = INTF_DSKBLK;
- custom->dsklen = DSKDMAOFF;
- GiveUnit();
- }
-
-
- static unsigned bitptr; /* Bit pointer to raw data (offset from RawBuffer) */
-
- /* Grab 10 bits of GCR from RawBuffer+bitptr and return a byte of decoded data */
- /* Note: No checking for "end of buffer" condition! */
-
- static __inline UBYTE GetByte(void)
- {
- static UBYTE GCRTable[] = {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x80,0x81,0x00,0x8C,0x84,0x85,
- 0x00,0x00,0x82,0x83,0x00,0x8F,0x86,0x87,0x00,0x89,0x8A,0x8B,0x00,0x8D,0x8E,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x01,0x00,0x0C,0x04,0x05,
- 0x00,0x00,0x02,0x03,0x00,0x0F,0x06,0x07,0x00,0x09,0x0A,0x0B,0x00,0x0D,0x0E,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x10,0x11,0x00,0x1C,0x14,0x15,
- 0x00,0x00,0x12,0x13,0x00,0x1F,0x16,0x17,0x00,0x19,0x1A,0x1B,0x00,0x1D,0x1E,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC8,0xC0,0xC1,0x00,0xCC,0xC4,0xC5,
- 0x00,0x00,0xC2,0xC3,0x00,0xCF,0xC6,0xC7,0x00,0xC9,0xCA,0xCB,0x00,0xCD,0xCE,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x40,0x41,0x00,0x4C,0x44,0x45,
- 0x00,0x00,0x42,0x43,0x00,0x4F,0x46,0x47,0x00,0x49,0x4A,0x4B,0x00,0x4D,0x4E,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x50,0x51,0x00,0x5C,0x54,0x55,
- 0x00,0x00,0x52,0x53,0x00,0x5F,0x56,0x57,0x00,0x59,0x5A,0x5B,0x00,0x5D,0x5E,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x20,0x21,0x00,0x2C,0x24,0x25,
- 0x00,0x00,0x22,0x23,0x00,0x2F,0x26,0x27,0x00,0x29,0x2A,0x2B,0x00,0x2D,0x2E,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x30,0x31,0x00,0x3C,0x34,0x35,
- 0x00,0x00,0x32,0x33,0x00,0x3F,0x36,0x37,0x00,0x39,0x3A,0x3B,0x00,0x3D,0x3E,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF0,0xF1,0x00,0xFC,0xF4,0xF5,
- 0x00,0x00,0xF2,0xF3,0x00,0xFF,0xF6,0xF7,0x00,0xF9,0xFA,0xFB,0x00,0xFD,0xFE,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x60,0x61,0x00,0x6C,0x64,0x65,
- 0x00,0x00,0x62,0x63,0x00,0x6F,0x66,0x67,0x00,0x69,0x6A,0x6B,0x00,0x6D,0x6E,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x70,0x71,0x00,0x7C,0x74,0x75,
- 0x00,0x00,0x72,0x73,0x00,0x7F,0x76,0x77,0x00,0x79,0x7A,0x7B,0x00,0x7D,0x7E,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x90,0x91,0x00,0x9C,0x94,0x95,
- 0x00,0x00,0x92,0x93,0x00,0x9F,0x96,0x97,0x00,0x99,0x9A,0x9B,0x00,0x9D,0x9E,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xA0,0xA1,0x00,0xAC,0xA4,0xA5,
- 0x00,0x00,0xA2,0xA3,0x00,0xAF,0xA6,0xA7,0x00,0xA9,0xAA,0xAB,0x00,0xAD,0xAE,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB8,0xB0,0xB1,0x00,0xBC,0xB4,0xB5,
- 0x00,0x00,0xB2,0xB3,0x00,0xBF,0xB6,0xB7,0x00,0xB9,0xBA,0xBB,0x00,0xBD,0xBE,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0xD0,0xD1,0x00,0xDC,0xD4,0xD5,
- 0x00,0x00,0xD2,0xD3,0x00,0xDF,0xD6,0xD7,0x00,0xD9,0xDA,0xDB,0x00,0xDD,0xDE,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,0xE0,0xE1,0x00,0xEC,0xE4,0xE5,
- 0x00,0x00,0xE2,0xE3,0x00,0xEF,0xE6,0xE7,0x00,0xE9,0xEA,0xEB,0x00,0xED,0xEE,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- };
-
- ULONG data;
-
- /* Fetch a longword at a word address using bitptr */
- data=*(ULONG*)(RawBuffer+(bitptr>>3 & ~1));
-
- /* Right-adjust and mask */
- data >>= 22-(bitptr & 15);
- data &= 1023;
-
- bitptr += 10;
- return GCRTable[data];
- }
-
- /* Scan for sync mark from bitptr. Returns TRUE if sync found.
- We look for 9 1-bits (minimum to distinguish from normal data) starting on a byte
- alignment. Consequently there must be at least 16 1-bits physically on the disk.
- */
- static bool ScanSync(void)
- {
- UBYTE *ptr;
- unsigned offset;
-
- ptr=RawBuffer+(bitptr>>3);
- if (bitptr&7) ptr++;
- if (ptr >= RawBuffer+RAWBUFSIZE) return FALSE;
-
- while (1) {
- while (*ptr != 0xFF) {
- ++ptr;
- if (ptr >= RawBuffer+RAWBUFSIZE) return FALSE;
- }
- ++ptr;
- if (ptr >= RawBuffer+RAWBUFSIZE) return FALSE;
- if (*ptr & 0x80) break;
- }
- while (*ptr == 0xFF) {
- ++ptr;
- if (ptr >= RawBuffer+RAWBUFSIZE) return FALSE;
- }
-
- if (*ptr == 0xFE) offset=7;
- else if ((*ptr&0xFC)==0xFC) offset=6;
- else if ((*ptr&0xF8)==0xF8) offset=5;
- else if ((*ptr&0xF0)==0xF0) offset=4;
- else if ((*ptr&0xE0)==0xE0) offset=3;
- else if ((*ptr&0xC0)==0xC0) offset=2;
- else if ((*ptr&0x80)==0x80) offset=1;
- else offset=0;
-
- bitptr=(ptr-RawBuffer)*8 + offset;
- return TRUE;
- }
-
- static void ReadAndDecodeTrack(unsigned track, char *DecodedBuffer)
- {
- unsigned NeedMap, ReadMap;
- unsigned drivetrack; /* 1541 track# */
- unsigned SectorsPerTrack;
- int retry;
- UBYTE *secptr;
-
- unsigned sec;
- ULONG *longsecptr;
-
- drivetrack=track/2 + 1;
- /* Set bufbase, SectorsPerTrack, and DecodedBuffer */
- if (drivetrack < 18) { /* zone 1 */
- SectorsPerTrack=21; DecodedBuffer+=(drivetrack-1)*21*256; NeedMap=(1<<21)-1;
- }
- else if (drivetrack < 25) { /* zone 2 */
- SectorsPerTrack=19; DecodedBuffer+=357*256+(drivetrack-18)*19*256; NeedMap=(1<<19)-1;
- }
- else if (drivetrack < 31) { /* zone 3 */
- SectorsPerTrack=18; DecodedBuffer+=490*256+(drivetrack-25)*18*256; NeedMap=(1<<18)-1;
- }
- else { /* zone 4 */
- SectorsPerTrack=17; DecodedBuffer+=598*256+(drivetrack-31)*17*256; NeedMap=(1<<17)-1;
- }
-
- ReadMap=0;
- for (retry=RetryCount; (ReadMap != NeedMap) && (retry>=0); retry--) {
- bitptr=0;
- RawRead(track);
- while (ReadMap != NeedMap) {
- /* decode sector */
- UBYTE checksum, sectornum, tracknum, id1, id2;
- unsigned i;
-
- if (!ScanSync()) break;
- if (bitptr > MAXBITPTR) break;
- if (GetByte() != 0x08) continue; /* if not header, restart */
- checksum=GetByte(); sectornum=GetByte(); tracknum=GetByte(); id1=GetByte(); id2=GetByte();
- if (checksum^tracknum^sectornum^id1^id2) continue;
- if (sectornum >= SectorsPerTrack) {
- printf("Sector number out of range on track %d\n",drivetrack);
- continue;
- }
- if (tracknum != drivetrack) {
- printf("Wrong track number (%d) on track %d\n",(int)tracknum,drivetrack);
- continue;
- }
- if (ReadMap & (1<<sectornum)) continue; /* already read 'em */
-
- /* Header looks good. Onto the data block. */
- if (!ScanSync()) break;
- if (bitptr > MAXBITPTR) break;
- if (GetByte() != 0x07) continue; /* if not data block, restart */
- secptr=DecodedBuffer+(sectornum*256);
- checksum=0;
- for (i=0; i <= 255; i++) {
- *secptr=GetByte(); checksum ^= *secptr; secptr++;
- }
- if (GetByte() == checksum) {
- ReadMap |= 1<<sectornum;
- }
- }
- if (ReadMap != NeedMap) {
- printf("Trouble reading track %d\n",drivetrack);
- }
- }
- if (ReadMap == NeedMap) {
- // printf("Track %d read successfully\n",drivetrack);
- return;
- }
-
- /* We couldn't read one or more sectors on this track. Print out some info and
- mark the bad sectors with a special identifier */
- printf("Bad sectors on track %d: ",drivetrack);
- for (sec=0; sec < SectorsPerTrack; sec++) {
- unsigned i;
- if (!(ReadMap & 1<<sec)) {
- printf("%d, ",sec);
- secptr=DecodedBuffer+(sec*256);
- longsecptr=(ULONG*)secptr;
- for (i=0; i <= 63; i++) {
- longsecptr[i]=0;
- }
- secptr[1]=0xFF;
- strcpy(secptr+2,"LAZARUS");
- }
- }
- printf("\b\b \n");
- }
-
-
- /* Returns TRUE if successful */
- static bool WriteFile(char *filename, char *buffer, unsigned size)
- {
- BPTR file;
- LONG actual;
-
- file=Open(filename,MODE_NEWFILE); if (!file) return FALSE;
- actual=Write(file,buffer,size);
- Close(file);
- if (actual != size) return FALSE;
- return TRUE;
- }
-
- void main(void)
- {
- unsigned track;
-
- printf("1541 - Copyright © 1994 by Dan Babcock\n");
-
- /* Handle command-line arguments */
- rdargs=ReadArgs("DRIVE/N/A,FILENAME/A,RETRY/K/N,TOP/S,OFFSET/K/N",args,0);
- if (rdargs == 0) {
- printf("Invalid parameters\n");
- return;
- }
- if (args[RETRY]) RetryCount=*(unsigned*)args[RETRY];
-
- /* Set up for trackdisk I/O */
- DiskBase=OpenResource("disk.resource");
- if ((port = CreateMsgPort())==0) {
- printf("Could not create message port (out of memory)\n");
- return;
- }
- if ((io = CreateIORequest(port,sizeof(struct IOStdReq)))==0) {
- printf("Could not create IORequest (out of memory)\n");
- return;
- }
- if (OpenDevice("trackdisk.device", *(int *)args[DRIVE], (struct IORequest *)io, TDF_ALLOW_NON_3_5)) {
- printf("Could not open trackdisk unit %d\n",*(int *)args[DRIVE]);
- return;
- }
- DevOpen = TRUE;
-
- /* Read and decode */
- if (!args[TOP])
- for (track=0; track <= 68; track+=2)
- ReadAndDecodeTrack(track, DecodedBuffer);
- else
- for (track=1; track <= 69; track+=2)
- ReadAndDecodeTrack(track, DecodedBuffer);
-
- /* Write image to file */
- if (!WriteFile((char *)args[FILENAME],DecodedBuffer,DISKSIZE)) {
- printf("Error writing image file\n");
- }
- }
-