home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / emulator / transuti.lzh / PSTransformer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-27  |  7.9 KB  |  257 lines

  1. #include    <stdio.h>
  2. #include    <libraries/dos.h>
  3. #include    <hardware/custom.h>
  4. #include    <hardware/dmabits.h>
  5. #include    <exec/types.h>
  6. #include    <exec/memory.h>
  7. #include    <exec/execbase.h>
  8. #include    <functions.h>
  9. #include    <exec/lists.h>
  10. #include    <graphics/gfxmacros.h>
  11.  
  12.  
  13. #define PREFERENCES_OFFSET    0x2   /* offset to an index to PREFS */
  14. #define EMULATOR_ENTRY_POINT    0x298 /* actual start of the emulator */
  15. #define DOSSIZE_OFFSET        0x3b  /* offset into ATPREFS for dossize */
  16. #define PRIVHNDLRSIZE        0x38
  17. #define DATASIZE        0xa3ce
  18.  
  19. #define HUNK_CODE        0x3e9L
  20.  
  21. char    *em = 0;        /* pointer to loaded emulator code */
  22. struct Segment    *em_seg = 0;    /* pointer to loaded emulator segment */
  23. char    *text = 0;        /* pointer to emulator text */
  24. char    *data = 0;        /* pointer to emulator data */
  25. char    *dos = 0;        /* pointer to area for dos */
  26. char    *total_chip = 0;    /* pointer to a temp area for sizing */
  27.  
  28. long    tsize;            /* amount of memory for emulator text */
  29. long    dsize = DATASIZE;    /* amount of memory for emulator data */
  30. long    dossize;        /* amount of memory allocated to dos */ 
  31. long    totalsize;        /* total text+data */
  32.  
  33. long    fsize;            /* amount of available fast memory */
  34. long    csize;            /* amount of available chip memory */
  35. long    size;            /* larger of free chip or fast mem */
  36.  
  37. long    tattributes;        /* AllocMem attributes for emulator text */
  38. long    dattributes;        /* AllocMem attributes for user DOS space */
  39.  
  40. long    preferences_offset;    /* offset to data area for ATPREFS */
  41. long    dossize_offset;        /* offset to ATPREFS requested dos size */
  42. int    preferences_loaded;    /* flag to indicate that we read ATPREFS */
  43.  
  44. struct FileHandle *handle = 0;    /* file handle, general use */
  45. char    pref_buf[200];        /* buffer to hold preferences data */
  46.  
  47. extern struct ExecBase    *SysBase;
  48.  
  49. main()
  50. {
  51. /* The declaration for PrivHndlr should really be a
  52.  * function returning void, but we declare it this way because
  53.  * we are copying the routine into a new place in RAM.
  54.  */
  55.     extern char    PrivHndlr[];    
  56.     extern int    startup_text();
  57.  
  58.     char    s[10];    /* input buffer for testing for abort */
  59.  
  60.     /* The first thing we have to do is to ensure that the emulator
  61.      * loads into chip ram. This *could* have been done by 
  62.      * running "FixHunk" on the AT1 file, but since some people
  63.      * don't have that, we achieve the same result by writing 0x40 at 
  64.      * an offset of 0x14 bytes from the start of the file. This sets 
  65.      * bit 30 of the hunk size longword. 
  66.      *
  67.      * See page 283 of the Bantam AmigaDOS reference manual for more 
  68.      * details.
  69.      */
  70.     handle = Open("AT1",(long)MODE_OLDFILE);
  71.     if (!handle)
  72.         errexit("Can't find AT1");
  73.  
  74.     if (Seek(handle,(long)0x14,(long)OFFSET_BEGINNING) == -1)
  75.         errexit("File Seek error: AT1");
  76.  
  77.     /* we use the preferences buffer to hold the value to insert */
  78.     pref_buf[0] = (char)0x40;
  79.     if (Write(handle, &pref_buf[0], (long)1) == -1)
  80.         errexit("File Write error: AT1");
  81.  
  82.     /* Now seek to the size of the text segment. */
  83.     if (Seek(handle,(long)0x1c,(long)OFFSET_BEGINNING) == -1)
  84.         errexit("File Seek error: AT1");
  85.  
  86.     /* See how big the text segment is. Use tsize as a 4 byte buffer,
  87.      * and read 4 bytes. This is the size of the segment in long 
  88.      * words. Adjust for a byte count, and add 8 bytes
  89.      * fudge factor for the segment overhead. (Size and 
  90.      * pointer to next)
  91.      */
  92.     if (Read(handle,&tsize,(long)sizeof(long)) == -1)
  93.         errexit("File Read error: AT1");
  94.     Close(handle);
  95.     handle = 0;
  96.  
  97.     tsize = (tsize << 2) + 8;    /* 8 bytes for segment overhead */
  98.  
  99.  
  100.     /* Read the default Transformer preferences from ATPREFS */
  101.     handle = Open("ATPREFS",(long)MODE_OLDFILE);
  102.     if (!handle) {
  103.         printf("Can't find ATPREFS. Using Default values.\n");
  104.         dossize = 640 * 1024;
  105.         preferences_loaded = 0;
  106.     }
  107.     else {
  108.         Read(handle,pref_buf,200L);
  109.         Close(handle);
  110.         handle = 0;
  111.         preferences_loaded = 1;
  112.  
  113.         /* see how much DOS space the user has requested */
  114.         dossize = 1024 * (((pref_buf[DOSSIZE_OFFSET] & 0xff) << 8) +
  115.                    (pref_buf[DOSSIZE_OFFSET+1] & 0xff)) + 62;
  116.     }
  117.  
  118.     /* We don't allow interruptions from now on from other tasks */
  119.     Forbid();
  120.  
  121.     /* make an unreasonably large memory allocation request to 
  122.      * flush any libraries out which are no longer in use.
  123.      */
  124.     (void)AllocMem(0x1000000L, (long)MEMF_CHIP);
  125.     (void)AllocMem(0x1000000L, (long)MEMF_FAST);
  126.  
  127.  
  128.     /* We have to determine how much free memory we will
  129.      * have available for DOS. We need dsize + tsize bytes in 
  130.      * CHIP ram. Once that's obtained, we attempt to allocate the 
  131.      * amount of memory requested in ATPREFS for DOS. This can be 
  132.      * in either CHIP or FAST ram, depending on which we have more of.
  133.      */ 
  134.  
  135.     tsize = (tsize + 7) & ~7;    /* round up to 8 byte boundary */
  136.     dsize = (dsize + 7) & ~7;    /* round up to 8 byte boundary */
  137.  
  138.     totalsize = tsize+dsize;
  139.  
  140.     /* allocate all we would need for both chip and text areas */
  141.     total_chip = AllocMem(totalsize, (long)(MEMF_CHIP|MEMF_PUBLIC));
  142.  
  143.     /* we now need to see how much we have available for DOS */
  144.     fsize = AvailMem((long)(MEMF_FAST|MEMF_LARGEST)) & ~07;
  145.     csize = AvailMem((long)(MEMF_CHIP|MEMF_LARGEST)) & ~07;
  146.  
  147.     /* have to leave some chip ram for display use */
  148.     csize -= 2048;
  149.  
  150.     /* If we have more FAST memory than we asked for for DOS use,
  151.      * or if we have more free FAST memory than CHIP, use FAST
  152.      * for DOS. Otherwise use CHIP.
  153.      */
  154.     if ((fsize >= dossize) || (fsize >= csize)) {
  155.         dattributes = MEMF_FAST|MEMF_PUBLIC;
  156.         size = fsize;
  157.     }
  158.     else {
  159.         dattributes = MEMF_CHIP|MEMF_PUBLIC;
  160.         size = csize;
  161.     }
  162.  
  163.     /* Free up the chunk we allocated above. We only allocated
  164.      * it to determine how much ram we would have left after
  165.      * allocation of space for emulator text and data.
  166.      */
  167.     FreeMem(total_chip, totalsize);
  168.     total_chip = NULL;
  169.  
  170.     /* Load the emulator segment */
  171.     em_seg = LoadSeg("AT1");
  172.     if (!em_seg)
  173.         errexit("Can't load Emulator");
  174.  
  175.     /* Convert the BPTR to the loaded segment to a pointer,
  176.      * then increment it past the pointer to the "next" segment.
  177.      */
  178.     em = (char *)BADDR(em_seg) + 4;
  179.  
  180.  
  181.     /* If we were able to read ATPREFS, copy the preferences into 
  182.      * the appropriate place in the text area.
  183.      */
  184.     if (preferences_loaded) {
  185.         preferences_offset = *((long *)(&em[PREFERENCES_OFFSET]));
  186.         movmem(pref_buf,&em[preferences_offset],(long)200);
  187.     }
  188.  
  189.     /* We install a modified version of Scott Turner's DeciGel 
  190.      * program, which allows us to use a 68010 or 68020 processor.
  191.      */
  192.     movmem(&PrivHndlr[0], 
  193.            &em[EMULATOR_ENTRY_POINT-PRIVHNDLRSIZE], (long)PRIVHNDLRSIZE);
  194.  
  195.     /* 'text' needs to point to the start of the emulator.
  196.      */
  197.     text = &em[EMULATOR_ENTRY_POINT];
  198.  
  199.     /* now get some space for the emulator data */
  200.     data = AllocMem(dsize, (long)MEMF_CHIP|MEMF_PUBLIC);
  201.     if (!data)
  202.         errexit("Can't get RAM for Emulator data\n");
  203.  
  204.     /* We'll only get the lesser of 'dossize' or 'size' ramspace
  205.      * for DOS.
  206.      */
  207.     dossize = (dossize < size) ? dossize : size;
  208.     dos = AllocMem(dossize,dattributes);
  209.  
  210.     /* Show us where we've allocated memory and how much of it there
  211.      * is. Also, a little ego boosting here.
  212.      */
  213.     printf("\nPSTransformer, Copyright (c) 1987 by Phil Staub\n\n");
  214.     printf("Startup module for AmigaTransformer to provide support ");
  215.     printf("for extended memory,\n");
  216.     printf("68010/68020, and multiple operating system versions.\n\n");
  217.     printf("\nAmigaTransformer Memory allocations\n");
  218.     printf("Emulator code : %10ld bytes at %08lx\n", tsize, text);
  219.     printf("Emulator data : %10ld bytes at %08lx\n", dsize, data);
  220.     printf("DOS User Space: %10ld bytes at %08lx\n\n", dossize, dos);
  221.  
  222.     /* now offer the chance to bail out */
  223.  
  224.     printf("Continue? [y/n] ");
  225.     gets(&s[0]);
  226.     if (s[0] == 'n' || s[0] == 'N')
  227.         errexit("AmigaTransformer exiting\n");
  228.  
  229.     OFF_SPRITE;            /* don't need the mouse pointer */
  230.     OFF_DISPLAY;             /* turn off the display dma */
  231.  
  232.     /* now branch off to an assembly language routine which
  233.      * installs the Privileged instruction  handler, sets up the 
  234.      * registers the way the emulator wants them, then starts the 
  235.      * emulator.
  236.      */
  237.     startup_text();
  238. }
  239.  
  240. errexit(s)
  241. char    *s;
  242. {
  243.     printf("%s\n",s);
  244.     if (em_seg)
  245.         (void)UnLoadSeg((struct Segment *)em_seg);
  246.     if (total_chip)
  247.         FreeMem(total_chip, totalsize);
  248.     if (data)
  249.         FreeMem(data, dsize);
  250.     if (dos)
  251.         FreeMem(dos, dossize);
  252.     if (handle)
  253.         Close(handle);
  254.     Permit();
  255.     exit(1);
  256. }
  257.