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

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

unix.superglobalmegacorp.com

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