home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <libraries/dos.h>
- #include <hardware/custom.h>
- #include <hardware/dmabits.h>
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/execbase.h>
- #include <functions.h>
- #include <exec/lists.h>
- #include <graphics/gfxmacros.h>
-
-
- #define PREFERENCES_OFFSET 0x2 /* offset to an index to PREFS */
- #define EMULATOR_ENTRY_POINT 0x298 /* actual start of the emulator */
- #define DOSSIZE_OFFSET 0x3b /* offset into ATPREFS for dossize */
- #define PRIVHNDLRSIZE 0x38
- #define DATASIZE 0xa3ce
-
- #define HUNK_CODE 0x3e9L
-
- char *em = 0; /* pointer to loaded emulator code */
- struct Segment *em_seg = 0; /* pointer to loaded emulator segment */
- char *text = 0; /* pointer to emulator text */
- char *data = 0; /* pointer to emulator data */
- char *dos = 0; /* pointer to area for dos */
- char *total_chip = 0; /* pointer to a temp area for sizing */
-
- long tsize; /* amount of memory for emulator text */
- long dsize = DATASIZE; /* amount of memory for emulator data */
- long dossize; /* amount of memory allocated to dos */
- long totalsize; /* total text+data */
-
- long fsize; /* amount of available fast memory */
- long csize; /* amount of available chip memory */
- long size; /* larger of free chip or fast mem */
-
- long tattributes; /* AllocMem attributes for emulator text */
- long dattributes; /* AllocMem attributes for user DOS space */
-
- long preferences_offset; /* offset to data area for ATPREFS */
- long dossize_offset; /* offset to ATPREFS requested dos size */
- int preferences_loaded; /* flag to indicate that we read ATPREFS */
-
- struct FileHandle *handle = 0; /* file handle, general use */
- char pref_buf[200]; /* buffer to hold preferences data */
-
- extern struct ExecBase *SysBase;
-
- main()
- {
- /* The declaration for PrivHndlr should really be a
- * function returning void, but we declare it this way because
- * we are copying the routine into a new place in RAM.
- */
- extern char PrivHndlr[];
- extern int startup_text();
-
- char s[10]; /* input buffer for testing for abort */
-
- /* The first thing we have to do is to ensure that the emulator
- * loads into chip ram. This *could* have been done by
- * running "FixHunk" on the AT1 file, but since some people
- * don't have that, we achieve the same result by writing 0x40 at
- * an offset of 0x14 bytes from the start of the file. This sets
- * bit 30 of the hunk size longword.
- *
- * See page 283 of the Bantam AmigaDOS reference manual for more
- * details.
- */
- handle = Open("AT1",(long)MODE_OLDFILE);
- if (!handle)
- errexit("Can't find AT1");
-
- if (Seek(handle,(long)0x14,(long)OFFSET_BEGINNING) == -1)
- errexit("File Seek error: AT1");
-
- /* we use the preferences buffer to hold the value to insert */
- pref_buf[0] = (char)0x40;
- if (Write(handle, &pref_buf[0], (long)1) == -1)
- errexit("File Write error: AT1");
-
- /* Now seek to the size of the text segment. */
- if (Seek(handle,(long)0x1c,(long)OFFSET_BEGINNING) == -1)
- errexit("File Seek error: AT1");
-
- /* See how big the text segment is. Use tsize as a 4 byte buffer,
- * and read 4 bytes. This is the size of the segment in long
- * words. Adjust for a byte count, and add 8 bytes
- * fudge factor for the segment overhead. (Size and
- * pointer to next)
- */
- if (Read(handle,&tsize,(long)sizeof(long)) == -1)
- errexit("File Read error: AT1");
- Close(handle);
- handle = 0;
-
- tsize = (tsize << 2) + 8; /* 8 bytes for segment overhead */
-
-
- /* Read the default Transformer preferences from ATPREFS */
- handle = Open("ATPREFS",(long)MODE_OLDFILE);
- if (!handle) {
- printf("Can't find ATPREFS. Using Default values.\n");
- dossize = 640 * 1024;
- preferences_loaded = 0;
- }
- else {
- Read(handle,pref_buf,200L);
- Close(handle);
- handle = 0;
- preferences_loaded = 1;
-
- /* see how much DOS space the user has requested */
- dossize = 1024 * (((pref_buf[DOSSIZE_OFFSET] & 0xff) << 8) +
- (pref_buf[DOSSIZE_OFFSET+1] & 0xff)) + 62;
- }
-
- /* We don't allow interruptions from now on from other tasks */
- Forbid();
-
- /* make an unreasonably large memory allocation request to
- * flush any libraries out which are no longer in use.
- */
- (void)AllocMem(0x1000000L, (long)MEMF_CHIP);
- (void)AllocMem(0x1000000L, (long)MEMF_FAST);
-
-
- /* We have to determine how much free memory we will
- * have available for DOS. We need dsize + tsize bytes in
- * CHIP ram. Once that's obtained, we attempt to allocate the
- * amount of memory requested in ATPREFS for DOS. This can be
- * in either CHIP or FAST ram, depending on which we have more of.
- */
-
- tsize = (tsize + 7) & ~7; /* round up to 8 byte boundary */
- dsize = (dsize + 7) & ~7; /* round up to 8 byte boundary */
-
- totalsize = tsize+dsize;
-
- /* allocate all we would need for both chip and text areas */
- total_chip = AllocMem(totalsize, (long)(MEMF_CHIP|MEMF_PUBLIC));
-
- /* we now need to see how much we have available for DOS */
- fsize = AvailMem((long)(MEMF_FAST|MEMF_LARGEST)) & ~07;
- csize = AvailMem((long)(MEMF_CHIP|MEMF_LARGEST)) & ~07;
-
- /* have to leave some chip ram for display use */
- csize -= 2048;
-
- /* If we have more FAST memory than we asked for for DOS use,
- * or if we have more free FAST memory than CHIP, use FAST
- * for DOS. Otherwise use CHIP.
- */
- if ((fsize >= dossize) || (fsize >= csize)) {
- dattributes = MEMF_FAST|MEMF_PUBLIC;
- size = fsize;
- }
- else {
- dattributes = MEMF_CHIP|MEMF_PUBLIC;
- size = csize;
- }
-
- /* Free up the chunk we allocated above. We only allocated
- * it to determine how much ram we would have left after
- * allocation of space for emulator text and data.
- */
- FreeMem(total_chip, totalsize);
- total_chip = NULL;
-
- /* Load the emulator segment */
- em_seg = LoadSeg("AT1");
- if (!em_seg)
- errexit("Can't load Emulator");
-
- /* Convert the BPTR to the loaded segment to a pointer,
- * then increment it past the pointer to the "next" segment.
- */
- em = (char *)BADDR(em_seg) + 4;
-
-
- /* If we were able to read ATPREFS, copy the preferences into
- * the appropriate place in the text area.
- */
- if (preferences_loaded) {
- preferences_offset = *((long *)(&em[PREFERENCES_OFFSET]));
- movmem(pref_buf,&em[preferences_offset],(long)200);
- }
-
- /* We install a modified version of Scott Turner's DeciGel
- * program, which allows us to use a 68010 or 68020 processor.
- */
- movmem(&PrivHndlr[0],
- &em[EMULATOR_ENTRY_POINT-PRIVHNDLRSIZE], (long)PRIVHNDLRSIZE);
-
- /* 'text' needs to point to the start of the emulator.
- */
- text = &em[EMULATOR_ENTRY_POINT];
-
- /* now get some space for the emulator data */
- data = AllocMem(dsize, (long)MEMF_CHIP|MEMF_PUBLIC);
- if (!data)
- errexit("Can't get RAM for Emulator data\n");
-
- /* We'll only get the lesser of 'dossize' or 'size' ramspace
- * for DOS.
- */
- dossize = (dossize < size) ? dossize : size;
- dos = AllocMem(dossize,dattributes);
-
- /* Show us where we've allocated memory and how much of it there
- * is. Also, a little ego boosting here.
- */
- printf("\nPSTransformer, Copyright (c) 1987 by Phil Staub\n\n");
- printf("Startup module for AmigaTransformer to provide support ");
- printf("for extended memory,\n");
- printf("68010/68020, and multiple operating system versions.\n\n");
- printf("\nAmigaTransformer Memory allocations\n");
- printf("Emulator code : %10ld bytes at %08lx\n", tsize, text);
- printf("Emulator data : %10ld bytes at %08lx\n", dsize, data);
- printf("DOS User Space: %10ld bytes at %08lx\n\n", dossize, dos);
-
- /* now offer the chance to bail out */
-
- printf("Continue? [y/n] ");
- gets(&s[0]);
- if (s[0] == 'n' || s[0] == 'N')
- errexit("AmigaTransformer exiting\n");
-
- OFF_SPRITE; /* don't need the mouse pointer */
- OFF_DISPLAY; /* turn off the display dma */
-
- /* now branch off to an assembly language routine which
- * installs the Privileged instruction handler, sets up the
- * registers the way the emulator wants them, then starts the
- * emulator.
- */
- startup_text();
- }
-
- errexit(s)
- char *s;
- {
- printf("%s\n",s);
- if (em_seg)
- (void)UnLoadSeg((struct Segment *)em_seg);
- if (total_chip)
- FreeMem(total_chip, totalsize);
- if (data)
- FreeMem(data, dsize);
- if (dos)
- FreeMem(dos, dossize);
- if (handle)
- Close(handle);
- Permit();
- exit(1);
- }
-