Annotation of uae/src/od-amiga/ami-disk.c, revision 1.1.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.