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