Annotation of uae/src/od-amiga/ami-disk.c, revision 1.1

1.1     ! root        1:  /* 
        !             2:   * UAE - The Un*x Amiga Emulator
        !             3:   * 
        !             4:   * ami-disk.c: Creates pseudo dev: handler. Copy tracks to rawfile 
        !             5:   * (used in zfile.c).
        !             6:   * 
        !             7:   * 08/06/97: Modified to avoid a spilled registers error message
        !             8:   *           when used with the new fd2inline convention.
        !             9:   * 
        !            10:   * Copyright 1996 Samuel Devulder.
        !            11:   */
        !            12: 
        !            13: /****************************************************************************/
        !            14: 
        !            15: #include <exec/execbase.h>
        !            16: #include <exec/memory.h>
        !            17: #include <exec/devices.h>
        !            18: #include <exec/io.h>
        !            19: 
        !            20: #include <dos/dos.h>
        !            21: 
        !            22: #include <devices/trackdisk.h>
        !            23: 
        !            24: /* This should cure the spilled-register problem. An other solution is to */
        !            25: /* compile with -O2 instead of -O3 */
        !            26: #define NO_INLINE_STDARGS
        !            27: #define __NOINLINES__
        !            28: 
        !            29: #include <proto/exec.h>
        !            30: #ifndef __SASC
        !            31: #include <proto/alib.h>
        !            32: #endif
        !            33: #include <proto/dos.h>
        !            34: 
        !            35: /****************************************************************************/
        !            36: 
        !            37: #include "sysconfig.h"
        !            38: #include "sysdeps.h"
        !            39: 
        !            40: #include <ctype.h>
        !            41: #include <signal.h>
        !            42: 
        !            43: #include "config.h"
        !            44: #include "options.h"
        !            45: #include "memory.h"
        !            46: #include "custom.h"
        !            47: #include "keyboard.h"
        !            48: #include "keybuf.h"
        !            49: #include "disk.h"
        !            50: #include "debug.h"
        !            51: #include "gui.h"
        !            52: 
        !            53: /****************************************************************************/
        !            54: 
        !            55: char *amiga_dev_path  = "DEV:";
        !            56: char *ixemul_dev_path = "/dev/";
        !            57: 
        !            58: int readdevice(char *name, char *dst);
        !            59: void initpseudodevices(void);
        !            60: void closepseudodevices(void);
        !            61: char *to_unix_path(char *s);
        !            62: char *from_unix_path(char *s);
        !            63: void split_dir_file(char *src, char **dir, char **file);
        !            64: static void myDoIO(struct IOStdReq *ioreq, LONG CMD, LONG FLAGS, LONG OFFSET, 
        !            65:                    LONG LENGTH, LONG DATA);
        !            66: 
        !            67: /****************************************************************************/
        !            68: 
        !            69: static char *pseudo_dev_path = "T:DEV";
        !            70: 
        !            71: static char pseudo_dev_created  = 0;
        !            72: static char pseudo_dev_assigned = 0;
        !            73: static char dfx_done[4];
        !            74: 
        !            75: static int device_exists(char *device_name, int device_unit);
        !            76: static int dev_inhibit(char *dev,int on);
        !            77: static void set_req(int ok);
        !            78: 
        !            79: /****************************************************************************/
        !            80: /* support routines to handle unix filename convention 
        !            81:  */
        !            82: char *to_unix_path(char *s)
        !            83: {
        !            84:     char *t,*r,*u;
        !            85:     int l;
        !            86: 
        !            87: #ifndef __GNUC
        !            88:     return my_strdup(s);
        !            89: #endif
        !            90: 
        !            91:     for(u=s,l=0;*u;++u,++l) if(*u=='/' || *u==':') l+=2;
        !            92: 
        !            93:     r = t = malloc(1+l);
        !            94:     if(!r) return NULL;
        !            95: 
        !            96:     for(u=s;*u && *u!=':';++u);
        !            97:     if(*u) {
        !            98:         *t++='/';
        !            99:         while(*s!=':') *t++=*s++;
        !           100:         *t++='/';++s;
        !           101:     }
        !           102:     while(*s=='/') {*t++='.';*t++='.';*t++=*s++;}
        !           103:     while(*s) {
        !           104:         if(s[0]=='/' && s[1]=='/') {*t++=*s++;*t++='.';*t++='.';*t++=*s++;}
        !           105:         else *t++=*s++;
        !           106:     }
        !           107:     *t='\0';
        !           108:     return r;
        !           109: }
        !           110: 
        !           111: /****************************************************************************/
        !           112: 
        !           113: char *from_unix_path(char *s)
        !           114: {
        !           115:     char *t,*r;
        !           116: 
        !           117:     r = t = malloc(strlen(s)+1);
        !           118:     if(!r) return NULL;
        !           119: #ifndef __GNUC__
        !           120:     strcpy(r,s);
        !           121:     return r;
        !           122: #endif
        !           123: 
        !           124:     if(*s=='/') {
        !           125:         ++s;
        !           126:         while(*s && *s!='/') *t++=*s++;
        !           127:         if(*s=='/') {*t++=':';++s;}
        !           128:     }
        !           129: 
        !           130:     while(*s) {
        !           131:         if(s[0]=='.' && s[1]=='.') s+=2;
        !           132:         else *t++=*s++;
        !           133:     }
        !           134: 
        !           135:     *t='\0';
        !           136: 
        !           137:     return r;
        !           138: }
        !           139: 
        !           140: /****************************************************************************/
        !           141: 
        !           142: void split_dir_file(char *src, char **dir, char **file)
        !           143: {   /* note: src is freed() */
        !           144:     char *s=src;
        !           145: 
        !           146:     while(*s) ++s;
        !           147:     while(s>src && (*s!=':' && *s!='/')) --s;
        !           148:     if(*s==':' || *s=='/') {
        !           149:         *file = my_strdup(s+1);
        !           150:         s[1]  = '\0';
        !           151:         *dir  = my_strdup(src);
        !           152:         free(src);
        !           153:     } else {
        !           154:         *file = src;
        !           155:         *dir  = my_strdup("");
        !           156:     }
        !           157: }
        !           158: 
        !           159: /****************************************************************************/
        !           160: /*
        !           161:  * Creates peudo DEV:DFx files.
        !           162:  */
        !           163: void initpseudodevices(void)
        !           164: {
        !           165:     ULONG lock;
        !           166:     int i;
        !           167: 
        !           168:     pseudo_dev_created  = 0;
        !           169:     pseudo_dev_assigned = 0;
        !           170:     for(i=0;i<4;++i) dfx_done[i]=0;
        !           171: 
        !           172:     /* check if dev: already exists */
        !           173:     set_req(0);lock = Lock(amiga_dev_path,SHARED_LOCK);set_req(1);
        !           174:     if(!lock) {
        !           175:         char name[80];
        !           176:         set_req(0);lock = Lock(pseudo_dev_path,SHARED_LOCK);set_req(1);
        !           177:         if(!lock) {
        !           178:             /* create it */
        !           179:             lock = CreateDir(pseudo_dev_path);
        !           180:             if(!lock) goto fail;
        !           181:             UnLock(lock);lock = Lock(pseudo_dev_path,SHARED_LOCK);
        !           182:             pseudo_dev_created = 1;
        !           183:         }
        !           184:         strcpy(name,amiga_dev_path);
        !           185:         if(*name && name[strlen(name)-1]==':') name[strlen(name)-1]='\0';
        !           186:         if(!AssignLock(name,lock)) {UnLock(lock);goto fail;}
        !           187:         /* the lock is the assign now */
        !           188:         pseudo_dev_assigned = 1;
        !           189:     } else UnLock(lock);
        !           190: 
        !           191:     /* Create the dev:DFi entry */
        !           192:     for(i=0;i<4;++i) if(device_exists("trackdisk.device",i)) {
        !           193:         ULONG fd;
        !           194:         char name[80];
        !           195: 
        !           196:         sprintf(name,"%sDF%d",amiga_dev_path,i);
        !           197:         fd = Open(name,MODE_NEWFILE);
        !           198:         if(fd) {Close(fd);dfx_done[i]=1;}
        !           199:     }
        !           200: 
        !           201:     return;
        !           202:  fail:
        !           203:     fprintf(stderr,"Failed to create pseudo dev: entry!\n");
        !           204: }
        !           205: 
        !           206: /****************************************************************************/
        !           207: /*
        !           208:  * Cleanup pseudo DEV:DFx
        !           209:  */
        !           210: void closepseudodevices(void)
        !           211: {
        !           212:     int i;
        !           213:     for(i=0;i<4;++i) if(dfx_done[i]) {
        !           214:         char name[80];
        !           215:         sprintf(name,"%sDF%d",amiga_dev_path,i);
        !           216:         DeleteFile(name);
        !           217:         dfx_done[i] = 0;
        !           218:     }
        !           219: 
        !           220:     if(pseudo_dev_assigned) {
        !           221:         char name[80];
        !           222:         strcpy(name,amiga_dev_path);
        !           223:         if(*name && name[strlen(name)-1]==':') name[strlen(name)-1]='\0';
        !           224:         AssignLock(name,NULL);
        !           225:         pseudo_dev_assigned = 0;
        !           226:     }
        !           227: 
        !           228:     if(pseudo_dev_created) {
        !           229:         DeleteFile(pseudo_dev_path);
        !           230:         pseudo_dev_created = 0;
        !           231:     }
        !           232: }
        !           233: 
        !           234: /****************************************************************************/
        !           235: /*
        !           236:  * Enable/Disable system requester
        !           237:  */
        !           238: static void set_req(int ok)
        !           239: {
        !           240:     static ULONG wd = 0;
        !           241:     struct Process *pr;
        !           242:     
        !           243:     pr = (void*)FindTask(NULL);
        !           244:     
        !           245:     if(pr->pr_Task.tc_Node.ln_Type != NT_PROCESS) return;
        !           246:     
        !           247:     if(ok)  {
        !           248:         pr->pr_WindowPtr = (APTR)wd;
        !           249:     }
        !           250:     else    {
        !           251:         wd = (ULONG)pr->pr_WindowPtr;
        !           252:         pr->pr_WindowPtr = (APTR)-1;
        !           253:     }
        !           254: }
        !           255: 
        !           256: /****************************************************************************/
        !           257: /*
        !           258:  * checks if a device exists
        !           259:  */
        !           260: static int device_exists(char *device_name, int device_unit)
        !           261: {
        !           262:     struct IOStdReq *ioreq  = NULL;
        !           263:     struct MsgPort  *port   = NULL;
        !           264:     int ret = 0;
        !           265: 
        !           266:     port = CreatePort(0, 0);
        !           267:     if(port) {
        !           268:         ioreq = CreateStdIO(port);        
        !           269:         if(ioreq) {
        !           270:             if(!OpenDevice(device_name,device_unit,(void*)ioreq,0)) {
        !           271:                 CloseDevice((void*)ioreq);
        !           272:                 ret = 1;
        !           273:             }
        !           274:             DeleteStdIO(ioreq);    
        !           275:         }
        !           276:         DeletePort(port);
        !           277:     }
        !           278:     return ret;
        !           279: }
        !           280: 
        !           281: /****************************************************************************/
        !           282: /*
        !           283:  * extract the device and unit form a filename.
        !           284:  */
        !           285: static void extract_dev_unit(char *name, char **dev_name, int *dev_unit)
        !           286: {
        !           287:     char *s;
        !           288:     if(tolower(name[0])=='d' && tolower(name[1])=='f' &&
        !           289:        name[2]>='0' && name[2]<='3' && name[3]=='\0') { 
        !           290:         /* DF0 */
        !           291:         *dev_unit = name[2]-'0';
        !           292:         *dev_name = strdup("trackdisk.device");
        !           293:     } else if((s = strrchr(name,'/'))) { 
        !           294:         /* trackdisk[.device]/0 */
        !           295:         *dev_unit = atoi(s+1);
        !           296:         *dev_name = malloc(1 + s-name);
        !           297:         if(*dev_name) {
        !           298:             strncpy(*dev_name, name, 1 + s-name);
        !           299:             (*dev_name)[s-name]='\0';
        !           300:         }
        !           301:     } else { 
        !           302:         /* ?? STRANGEDISK0: ?? */
        !           303:         *dev_unit = 0;
        !           304:         *dev_name = strdup(name);
        !           305:     }
        !           306:     if(*dev_name) {
        !           307:         char *s;
        !           308:         if(!(s = strrchr(*dev_name,'.'))) { 
        !           309:             /* .device is missing */
        !           310:             s = malloc(8+strlen(*dev_name));
        !           311:             if(s) {
        !           312:                 sprintf(s,"%s.device",*dev_name);
        !           313:                 free(*dev_name);
        !           314:                 *dev_name = s;
        !           315:             }
        !           316:         }
        !           317:     }
        !           318: }
        !           319: 
        !           320: /****************************************************************************/
        !           321: /*
        !           322:  * copy a device to a FILE*.
        !           323:  */
        !           324: static int raw_copy(char *dev_name, int dev_unit, FILE *dst)
        !           325: {
        !           326:     struct MsgPort  *port   = NULL;
        !           327:     struct IOStdReq *ioreq  = NULL;
        !           328:     int tracklen            = 512*11;
        !           329:     int retstatus           = 1;
        !           330:     int inhibited           = 0;
        !           331:     char *buffer            = NULL;
        !           332:     static char name[]      = {'D','F','0','\0'};
        !           333: 
        !           334:     if(!strcmp(dev_name, "trackdisk.device")) {
        !           335:         inhibited = 1;
        !           336:         name[2] = '0'+dev_unit;
        !           337:     }
        !           338: 
        !           339:     /* allocate system stuff */
        !           340:     if((port   = CreatePort(0, 0)))            {
        !           341:     if((ioreq  = CreateStdIO(port)))           {
        !           342:     if((buffer = AllocMem(tracklen, MEMF_CHIP))) {
        !           343: 
        !           344:     /* gain access to the device */
        !           345:     if(!OpenDevice(dev_name, dev_unit, (struct IORequest*)ioreq, 0)) {
        !           346: 
        !           347:     /* check if a disk is present */
        !           348:     myDoIO(ioreq, TD_CHANGESTATE, 0, -1, -1, -1);
        !           349:     if(!ioreq->io_Error && ioreq->io_Actual) {
        !           350:         fprintf(stderr,"No disk in %s unit %d !\n", dev_name, dev_unit);
        !           351:         retstatus = 0;
        !           352:     } else {
        !           353:         int tr = 0;
        !           354:         int write_protected = 0;
        !           355:         /* check if disk is write-protected:
        !           356:         myDoIO(ioreq, TD_PROTSTATUS, 0, -1, -1, -1);
        !           357:         if(!ioreq->io_Error && ioreq->io_Actual) write_protected = 1;
        !           358:         */
        !           359: 
        !           360:         /* inhibit device */
        !           361:         if(inhibited) inhibited = dev_inhibit(name,1);
        !           362: 
        !           363:         /* read tracks */
        !           364:         for(tr = 0; tr < 160; ++tr) {
        !           365:             printf("Reading track %2d side %d of %s unit %d  \r",
        !           366:                    tr/2, tr%2, dev_name, dev_unit);
        !           367:             fflush(stdout);
        !           368:             myDoIO(ioreq, CMD_READ, -1, tracklen*tr, tracklen, (LONG)buffer);
        !           369:             if(ioreq->io_Error) printf("Err. on\n");
        !           370:             if(fwrite(buffer, 1, tracklen, dst) != (unsigned int)tracklen) {
        !           371:                retstatus = 0; 
        !           372:                break;
        !           373:             }
        !           374:         }
        !           375: 
        !           376:         /* ok everything done! */
        !           377:         printf("                                                                        \r");
        !           378:         fflush(stdout);
        !           379: 
        !           380:         /* stop motor */
        !           381:         myDoIO(ioreq, TD_MOTOR, 0, -1, 0, -1);
        !           382: 
        !           383:         /* uninhibit */
        !           384:         if(inhibited) dev_inhibit(name,0);
        !           385:     }
        !           386:     CloseDevice((struct IORequest*)ioreq);   } else retstatus = 0;
        !           387:     FreeMem(buffer,tracklen);                } else retstatus = 0;
        !           388:     DeleteStdIO(ioreq);                      } else retstatus = 0;
        !           389:     DeletePort(port);                        } else retstatus = 0;
        !           390:     return retstatus;
        !           391: }
        !           392: 
        !           393: /****************************************************************************/
        !           394: /*
        !           395:  * Copy one raw disk to a file.
        !           396:  */
        !           397: int readdevice(char *name, char *dst) 
        !           398: {   /* erhm, I must admit this code is long and ugly! */
        !           399:     FILE *f = NULL;
        !           400:     char *device_name;
        !           401:     int   device_unit;
        !           402:     int   retstatus = 0;
        !           403: #ifdef HAVE_SIGACTION
        !           404:     struct sigaction oldsa;
        !           405:     int oldsa_valid;
        !           406: 
        !           407:     /* disable break */
        !           408:     oldsa_valid = (0==sigaction(SIGINT, NULL, &oldsa));
        !           409:     signal(SIGINT, SIG_IGN); /* <--- gcc complains about something */
        !           410:                              /* in there but I don't know why. */
        !           411: #endif
        !           412: 
        !           413:     /* get device name & unit */
        !           414:     extract_dev_unit(name, &device_name, &device_unit);
        !           415:     if(device_name) {
        !           416:         /* if no destination then just check if the device exists */
        !           417:         if(dst == NULL) 
        !           418:            retstatus = device_exists(device_name, device_unit);
        !           419:         else {
        !           420:             /* open dest file */
        !           421:             if((f = fopen(dst,"wb"))) {
        !           422:                 retstatus = raw_copy(device_name, device_unit, f);
        !           423:                 fclose(f);
        !           424:             }
        !           425:         }
        !           426:         free(device_name);           
        !           427:     }
        !           428: 
        !           429: #ifdef HAVE_SIGACTION
        !           430:     /* enable break */
        !           431:     if(oldsa_valid) sigaction(SIGINT, &oldsa, NULL);
        !           432: #endif
        !           433: 
        !           434:     return retstatus;
        !           435: }
        !           436: 
        !           437: /****************************************************************************/
        !           438: 
        !           439: static void myDoIO(struct IOStdReq *ioreq, LONG CMD, LONG FLAGS, LONG OFFSET, 
        !           440:                    LONG LENGTH, LONG DATA)
        !           441: {
        !           442:     if(CMD>=0)    ioreq->io_Command = CMD;
        !           443:     if(FLAGS>=0)  ioreq->io_Flags   = FLAGS;
        !           444:     if(OFFSET>=0) ioreq->io_Offset  = OFFSET;
        !           445:     if(LENGTH>=0) ioreq->io_Length  = LENGTH;
        !           446:     if(DATA>=0)   ioreq->io_Data    = (void*)DATA;
        !           447:     DoIO((struct IORequest*)ioreq);
        !           448: }
        !           449: 
        !           450: /****************************************************************************/
        !           451: /*
        !           452:  * Prevents DOS to access a DFx device.
        !           453:  */
        !           454: static int dev_inhibit(char *dev,int on)
        !           455: {
        !           456:     char buff[10],*s;
        !           457:     struct MsgPort *DevPort;
        !           458: 
        !           459:     if(!*dev) return 0;
        !           460:     s=dev;while(*s++);
        !           461:     if(s[-2]==':') strcpy(buff,dev); else sprintf(buff,"%s:",dev);
        !           462:     if((DevPort = (struct MsgPort*)DeviceProc((STRPTR)buff))) {
        !           463:         if(on) {
        !           464:            DoPkt(DevPort,ACTION_INHIBIT,DOSTRUE,NULL,NULL,NULL,NULL);
        !           465:            return 1;
        !           466:         }
        !           467:         else   DoPkt(DevPort,ACTION_INHIBIT,DOSFALSE,NULL,NULL,NULL,NULL);
        !           468:     }
        !           469:     return 0;
        !           470: }
        !           471: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.