Annotation of uae/hardfile.c, revision 1.1.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.