Annotation of uae/hardfile.c, revision 1.1

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

unix.superglobalmegacorp.com

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