|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.