Annotation of uae/hardfile.c, revision 1.1.1.2

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: }

unix.superglobalmegacorp.com

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