|
|
1.1.1.2 ! root 1: /* 1.1 root 2: * UAE - The Un*x Amiga Emulator 1.1.1.2 ! root 3: * 1.1 root 4: * AutoConfig devices 5: * 6: * (c) 1995 Bernd Schmidt 7: */ 8: 1.1.1.2 ! root 9: #include "sysconfig.h" ! 10: #include "sysdeps.h" 1.1 root 11: 12: #include "config.h" 13: #include "options.h" 14: #include "events.h" 15: #include "memory.h" 16: #include "custom.h" 17: #include "newcpu.h" 18: #include "disk.h" 19: #include "xwin.h" 20: #include "autoconf.h" 21: #include "hardfile.h" 22: 23: static int opencount = 0; 24: static int uaedevfd; 25: static int numtracks = 512; 26: 1.1.1.2 ! root 27: static ULONG dosname, uaedevname; 1.1 root 28: 29: static ULONG hardfile_init(void) 30: { 1.1.1.2 ! root 31: ULONG tmp1, tmp2, tmp3,configdev; ! 32: int have36 = 1; 1.1 root 33: ULONG retval = regs.d[0]; 34: 35: if (!automount_uaedev) 36: return retval; 37: 38: regs.d[0] = 88; regs.d[1] = 1; /* MEMF_PUBLIC */ 39: tmp1 = CallLib (regs.a[6], -198); /* AllocMem() */ 40: if (tmp1 == 0) { 41: fprintf(stderr, "Not enough memory for uae.device!\n"); 42: return 0; 43: } 44: /* Open expansion.lib */ 45: regs.d[0] = 36; /* Let's try this... */ 46: regs.a[1] = explibname; 47: regs.a[4] = CallLib (regs.a[6], -552); /* OpenLibrary() */ 48: if (regs.a[4]) 1.1.1.2 ! root 49: have36 = 1; 1.1 root 50: else { 51: regs.d[0] = 0; 52: regs.a[1] = explibname; 53: regs.a[4] = CallLib (regs.a[6], -552); /* OpenLibrary() */ 54: } 55: put_long (tmp1, dosname); 1.1.1.2 ! root 56: put_long (tmp1+4, uaedevname); 1.1 root 57: put_long (tmp1+8, 0); /* Unit no. */ 58: put_long (tmp1+12, 0); /* Device flags */ 59: put_long (tmp1+16, 16); /* Env. size */ 60: put_long (tmp1+20, 128); /* 512 bytes/block */ 61: put_long (tmp1+24, 0); /* unused */ 62: put_long (tmp1+28, 1); /* heads */ 63: put_long (tmp1+32, 1); /* unused */ 64: put_long (tmp1+36, 32); /* secs per track */ 65: put_long (tmp1+40, 1); /* reserved blocks */ 66: put_long (tmp1+44, 0); /* unused */ 67: put_long (tmp1+48, 0); /* interleave */ 68: put_long (tmp1+52, 0); /* lowCyl */ 1.1.1.2 ! root 69: #ifndef __DOS__ 1.1 root 70: put_long (tmp1+56, 511); /* upperCyl */ 1.1.1.2 ! root 71: #else ! 72: put_long (tmp1+56, numtracks-1); /* upperCyl */ ! 73: #endif 1.1 root 74: put_long (tmp1+60, 0); /* Number of buffers */ 75: put_long (tmp1+64, 0); /* Buffer mem type */ 76: put_long (tmp1+68, 0x7FFFFFFF); /* largest transfer */ 77: put_long (tmp1+72, ~1); /* addMask (?) */ 78: put_long (tmp1+76, (ULONG)-1); /* bootPri */ 79: if (have36) 80: put_long (tmp1+80, 0x444f5301); /* DOS\1 */ 81: else 82: put_long (tmp1+80, 0x444f5300); /* DOS\0 */ 1.1.1.2 ! root 83: ! 84: 1.1 root 85: put_long (tmp1+84, 0); /* pad */ 86: regs.a[0] = tmp1; 87: tmp2 = CallLib (regs.a[4], -144); /* MakeDosNode() */ 1.1.1.2 ! root 88: ! 89: configdev = CallLib(regs.a[4], -48); /* AllocConfigDev() */ ! 90: ! 91: /* hier init der Configdev */ ! 92: 1.1 root 93: regs.a[0] = tmp2; 94: regs.d[0] = (ULONG)-1; 1.1.1.2 ! root 95: regs.a[1] = configdev; 1.1 root 96: regs.d[1] = 0; 97: #if 0 1.1.1.2 ! root 98: CallLib (regs.a[4], -150); /* AddDosNode() */ ! 99: #endif ! 100: ! 101: ! 102: #if 1 ! 103: #if 1 1.1 root 104: if (have36) 1.1.1.2 ! root 105: CallLib (regs.a[4], /*-150*/ -36); /* AddDosNode() */ 1.1 root 106: else { 107: #endif 108: /* We could also try to call AddBootNode() here - but we don't have 109: * a ConfigDev. */ 110: regs.d[0] = 20; 111: regs.d[1] = 0; 112: tmp3 = CallLib (regs.a[6], -198); 113: if (tmp3 == 0) { 114: fprintf(stderr, "Not enough memory for uae.device bootnode!\n"); 115: return 0; 116: } 117: put_word (tmp3 + 14, 0); 118: put_long (tmp3 + 16, tmp2); 119: put_word (tmp3 + 8, 0x1005); 120: put_long (tmp3 + 10, 0); 121: put_long (tmp3 + 0, 0); 122: put_long (tmp3 + 4, 0); 123: regs.a[0] = regs.a[4] + 74; /* MountList */ 124: regs.a[1] = tmp3; 125: CallLib (regs.a[6], -270); /* Enqueue() */ 1.1.1.2 ! root 126: #if 1 1.1 root 127: } 128: #endif 129: #endif 1.1.1.2 ! root 130: 1.1 root 131: regs.a[1] = tmp1; 132: regs.d[0] = 88; 133: CallLib (regs.a[6], -210); /* FreeMem() */ 1.1.1.2 ! root 134: 1.1 root 135: regs.a[1] = regs.a[4]; 136: CallLib (regs.a[6], -414); /* CloseLibrary() */ 1.1.1.2 ! root 137: 1.1 root 138: return retval; 139: } 1.1.1.2 ! root 140: 1.1 root 141: static ULONG hardfile_open(void) 142: { 143: CPTR tmp1 = regs.a[1]; /* IOReq */ 1.1.1.2 ! root 144: 1.1 root 145: /* Check unit number */ 1.1.1.2 ! root 146: if (regs.d[0] == 0) { 1.1 root 147: opencount++; 148: put_word (regs.a[6]+32, get_word (regs.a[6]+32) + 1); 149: put_long (tmp1+24, 0); /* io_Unit */ 150: put_byte (tmp1+31, 0); /* io_Error */ 151: put_byte (tmp1+8, 7); /* ln_type = NT_REPLYMSG */ 152: return 0; 153: } 154: 155: put_long (tmp1+20, (ULONG)-1); 156: put_byte (tmp1+31, (UBYTE)-1); 157: return (ULONG)-1; 158: } 159: 160: static ULONG hardfile_close(void) 161: { 162: opencount--; 163: put_word (regs.a[6]+32, get_word (regs.a[6]+32) - 1); 164: 165: return regs.d[0]; 166: } 1.1.1.2 ! root 167: 1.1 root 168: static ULONG hardfile_expunge(void) 169: { 170: return 0; /* Simply ignore this one... */ 171: } 1.1.1.2 ! root 172: 1.1 root 173: static ULONG hardfile_beginio(void) 174: { 175: ULONG tmp1, tmp2, dataptr, offset; 176: ULONG retval = regs.d[0]; 177: 178: tmp1 = regs.a[1]; 179: put_byte (tmp1+8, 5); /* set ln_type to NT_MESSAGE */ 180: put_byte (tmp1+31, 0); /* no error yet */ 181: tmp2 = get_word (tmp1+28); /* io_Command */ 182: switch (tmp2) { 183: case 2: /* Read */ 184: dataptr = get_long (tmp1 + 40); 185: if (dataptr & 1) 186: goto bad_command; 187: offset = get_long (tmp1 + 44); 188: if (offset & 511) 189: goto bad_command; 190: tmp2 = get_long (tmp1 + 36); /* io_Length */ 191: if (tmp2 & 511) 192: goto bad_command; 193: if (tmp2 + offset > (ULONG)numtracks * 32 * 512) 194: goto bad_command; 1.1.1.2 ! root 195: 1.1 root 196: put_long (tmp1 + 32, tmp2); /* set io_Actual */ 197: lseek (uaedevfd, offset, SEEK_SET); 198: while (tmp2) { 199: int i; 200: char buffer[512]; 201: read (uaedevfd, buffer, 512); 202: for (i = 0; i < 512; i++, dataptr++) 203: put_byte(dataptr, buffer[i]); 204: tmp2 -= 512; 205: } 206: break; 1.1.1.2 ! root 207: 1.1 root 208: case 3: /* Write */ 209: case 11: /* Format */ 210: dataptr = get_long (tmp1 + 40); 211: if (dataptr & 1) 212: goto bad_command; 213: offset = get_long (tmp1 + 44); 214: if (offset & 511) 215: goto bad_command; 216: tmp2 = get_long (tmp1 + 36); /* io_Length */ 217: if (tmp2 & 511) 218: goto bad_command; 219: if (tmp2 + offset > (ULONG)numtracks * 32 * 512) 220: goto bad_command; 1.1.1.2 ! root 221: 1.1 root 222: put_long (tmp1 + 32, tmp2); /* set io_Actual */ 223: lseek (uaedevfd, offset, SEEK_SET); 224: while (tmp2) { 225: char buffer[512]; 226: int i; 227: for (i=0; i < 512; i++, dataptr++) 228: buffer[i] = get_byte(dataptr); 229: write (uaedevfd, buffer, 512); 230: tmp2 -= 512; 231: } 232: break; 1.1.1.2 ! root 233: 1.1 root 234: bad_command: 235: break; 1.1.1.2 ! root 236: 1.1 root 237: case 18: /* GetDriveType */ 238: put_long (tmp1 + 32, 1); /* not exactly a 3.5" drive, but... */ 239: break; 1.1.1.2 ! root 240: 1.1 root 241: case 19: /* GetNumTracks */ 1.1.1.2 ! root 242: put_long (tmp1 + 32, numtracks); 1.1 root 243: break; 1.1.1.2 ! root 244: 1.1 root 245: /* Some commands that just do nothing and return zero */ 246: case 4: /* Update */ 247: case 5: /* Clear */ 248: case 9: /* Motor */ 249: case 10: /* Seek */ 250: case 12: /* Remove */ 251: case 13: /* ChangeNum */ 252: case 14: /* ChangeStatus */ 253: case 15: /* ProtStatus */ 254: case 20: /* AddChangeInt */ 255: case 21: /* RemChangeInt */ 256: put_long (tmp1+32, 0); /* io_Actual */ 257: retval = 0; 258: break; 1.1.1.2 ! root 259: 1.1 root 260: default: 261: /* Command not understood. */ 262: put_byte (tmp1+31, (UBYTE)-3); /* io_Error */ 263: retval = 0; 264: break; 265: } 266: if ((get_byte (tmp1+30) & 1) == 0) { 267: /* Not IOF_QUICK -- need to ReplyMsg */ 268: regs.a[1] = tmp1; 269: CallLib (get_long(4), -378); 270: } 271: return retval; 272: } 1.1.1.2 ! root 273: 1.1 root 274: static ULONG hardfile_abortio(void) 275: { 276: return (ULONG)-3; 277: } 278: 279: void hardfile_install(void) 280: { 281: ULONG devid, functable, datatable, inittable, begin, end; 282: ULONG initroutine, openfunc, closefunc, expungefunc; 283: ULONG nullfunc, beginiofunc, abortiofunc; 284: 1.1.1.2 ! root 285: uaedevfd = open ("hardfile", O_RDWR | O_BINARY); ! 286: 1.1 root 287: if (uaedevfd < 0) 1.1.1.2 ! root 288: return; ! 289: ! 290: #ifdef __DOS__ ! 291: numtracks = filelength(uaedevfd) / 16384; ! 292: #endif ! 293: ! 294: uaedevname = ds("uae.device"); 1.1 root 295: devid = ds("uae 0.4"); /* ID */ 296: dosname = ds("UAEHF"); /* This is the DOS name */ 297: 298: begin = here(); 299: dw(0x4AFC); /* RTC_MATCHWORD */ 300: dl(begin); /* our start address */ 301: dl(0); /* Continue scan here */ 302: dw(0x8101); /* RTF_AUTOINIT|RTF_COLDSTART; Version 1 */ 303: dw(0x0305); /* NT_DEVICE; pri 5 */ 1.1.1.2 ! root 304: dl(uaedevname); /* name */ 1.1 root 305: dl(devid); /* ID */ 306: dl(here() + 4); /* Init area: directly after this */ 307: /* Init area starts here */ 308: dw(0x0000); /* Not really sure what to put here */ 309: dw(0x0100); 310: inittable = here(); 311: dl(0); dl(0); dl(0); /* skip 3 longs */ 312: 313: /* InitRoutine */ 314: initroutine = here(); 315: calltrap(deftrap(hardfile_init)); dw(RTS); 316: 317: /* Open */ 318: openfunc = here(); 319: calltrap(deftrap(hardfile_open)); dw(RTS); 320: 321: /* Close */ 322: closefunc = here(); 323: calltrap(deftrap(hardfile_close)); dw(RTS); 324: 325: /* Expunge */ 326: expungefunc = here(); 327: calltrap(deftrap(hardfile_expunge)); dw(RTS); 1.1.1.2 ! root 328: 1.1 root 329: /* Null */ 330: nullfunc = here(); 331: dw(0x7000); /* return 0; */ 332: dw(RTS); 333: 334: /* BeginIO */ 335: beginiofunc = here(); 336: calltrap(deftrap(hardfile_beginio)); dw(RTS); 337: 338: /* AbortIO */ 339: abortiofunc = here(); 340: calltrap(deftrap(hardfile_abortio)); dw(RTS); 1.1.1.2 ! root 341: 1.1 root 342: /* FuncTable */ 343: functable = here(); 344: dl(openfunc); /* Open */ 345: dl(closefunc); /* Close */ 346: dl(expungefunc); /* Expunge */ 347: dl(nullfunc); /* Null */ 348: dl(beginiofunc); /* BeginIO */ 349: dl(abortiofunc); /* AbortIO */ 350: dl(0xFFFFFFFF); /* end of table */ 351: 352: /* DataTable */ 353: datatable = here(); 354: dw(0xE000); /* INITBYTE */ 355: dw(0x0008); /* LN_TYPE */ 356: dw(0x0300); /* NT_DEVICE */ 357: dw(0xC000); /* INITLONG */ 358: dw(0x000A); /* LN_NAME */ 1.1.1.2 ! root 359: dl(uaedevname); 1.1 root 360: dw(0xE000); /* INITBYTE */ 361: dw(0x000E); /* LIB_FLAGS */ 362: dw(0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */ 363: dw(0xD000); /* INITWORD */ 364: dw(0x0014); /* LIB_VERSION */ 365: dw(0x0004); /* 0.4 */ 366: dw(0xD000); 367: dw(0x0016); /* LIB_REVISION */ 368: dw(0x0000); 369: dw(0xC000); 370: dw(0x0018); /* LIB_IDSTRING */ 371: dl(devid); 372: dw(0x0000); /* end of table */ 373: 374: end = here(); 375: 376: org(inittable); 377: dl(functable); 378: dl(datatable); 379: dl(initroutine); 380: 381: org(begin + 6); 382: dl(end); 383: 384: org(end); 385: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.