home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Emulatoren / UAE061.LZH / uae-0.6.1 / hardfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  9.0 KB  |  385 lines

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