home *** CD-ROM | disk | FTP | other *** search
-
- /*
- ======
- ROMS.C
- ======
-
- This file manages loading of binary data in ROMs or cartridges.
- For cartridge lists, etc., see moduledb.c.
- */
-
- #include "OSLib.h"
-
- #include "v9t9_common.h"
- #include "memory.h"
- #include "roms.h"
- #include "fiad.h"
-
- #define _L LOG_ROMS | LOG_INFO
-
- /*
- Find the location for a binary image and return size.
- */
- int
- findbinary(char *path, char *syspath, char *filename, OSSpec *spec)
- {
- OSRef ref;
- OSSize size;
- OSError err;
-
- if (!filename)
- return 0;
-
- if (OS_GetFileNamePtr(filename) != filename &&
- (err = OS_MakeFileSpec(filename, spec)) == OS_NOERR &&
- OS_Status(spec) == OS_NOERR) {
- // found it
- } else if ((err = OS_FindFileInPath(filename, path, spec)) != OS_NOERR &&
- (err = OS_FindFileInPath(filename, syspath, spec)) != OS_NOERR) {
- return 0;
- }
-
-
- if ((err = OS_Open(spec, OSReadOnly, &ref)) != OS_NOERR) {
- OSerror(err, "\n");
- return 0;
- }
-
- OS_GetSize(ref, &size);
-
- OS_Close(ref);
-
- return size;
- }
-
- /*
- Load a binary image, return # bytes read.
- */
- int
- loadbinary(char *path, char *syspath, char *filename, char *type,
- u8 * loadat, int swap, int fileoffs, int imagesize,
- int maxsize)
- {
- OSRef ref;
- OSSize size;
- OSError err;
- OSSpec spec;
-
- size = findbinary(path, syspath, filename, &spec);
-
- if (!size) {
- if (*filename) {
- logger(_L |LOG_USER|LOG_ERROR, "Cannot find '%s' in paths:\n%s or\n%s", filename,
- path, syspath);
- }
- return 0;
- }
- logger(_L|L_0, "Loading %s image %s... ", type, OS_SpecToString1(&spec));
-
- if (imagesize)
- size = imagesize;
- else if (size - fileoffs > maxsize) {
- logger(_L | LOG_WARN | LOG_USER, "%s too long, only %d bytes of %d read... ",
- OS_SpecToString1(&spec), maxsize, size);
- size = maxsize - fileoffs;
- }
-
- if ((err = OS_Open(&spec, OSReadOnly, &ref)) != OS_NOERR) {
- OSerror(err, "\n");
- return 0;
- }
-
- // size -= offset;
- // loadat += offset;
-
- if ((err = OS_Seek(ref, OSSeekAbs, fileoffs)) != OS_NOERR ||
- (err = OS_Read(ref, loadat, &size)) != OS_NOERR) {
- OSerror(err, "could not read\n");
- return 0;
- }
-
- if (swap) {
- logger(_L, "swapping bytes... ");
- swab((const void *) loadat, (void *) loadat, size);
- }
-
- logger(_L| L_0, "done\n");
-
- OS_Close(ref);
- return size;
- }
-
- /*
- Save a binary image, return # bytes written.
- */
- #if BEWORKS_FS
- OSFileType osBinaryType = { 0666, "x/v9t9-memory-image" };
- #elif POSIX_FS
- OSFileType osBinaryType = { 0666 };
- #elif WIN32_FS
- OSFileType osBinaryType = 0;
- #elif MAC_FS
- OSFileType osBinaryType = 'BIN ';
- #endif
-
- /*
- * Save data to an image found somewhere in 'path' or 'syspath'
- * (if not existing, placed in first entry of 'path').
- * Existing file is not overwritten.
- *
- * path / syspath: search paths
- * type: string emitted in error, i.e., "RAM image"
- * filename: name of image
- * fileoffs: offset into file to write
- * saveat: start of memory to write
- * swap: if true, byteswap word data to TI format
- * memsize: size of memory to write
- */
- int
- savebinary(char *path, char *syspath, char *type,
- char *filename, int fileoffs,
- u8 * saveat, int swap, int memsize)
- {
- OSRef ref;
- OSSize size;
- OSError err;
- OSSpec spec;
-
- if ((size = findbinary(path, syspath, filename, &spec)) == 0) {
- if ((err = OS_CreateFileInPath(filename,
- *path ? path : syspath,
- &spec,
- &osBinaryType)) != OS_NOERR) {
- OSerror(err, "Couldn't create %s image %s anywhere in path: %s\n",
- type, filename, path);
- return 0;
- }
- }
-
- logger(_L |L_0, "Writing %s image %s... ", type, OS_SpecToString1(&spec));
-
- if ((err = OS_Open(&spec, OSReadWrite, &ref)) != OS_NOERR) {
- OSerror(err, "\n");
- return 0;
- }
-
- //size = memsize - offset;
- //saveat += offset;
-
- if (swap) {
- logger(_L, "swapping bytes to save... ");
- swab((const void *) saveat, (void *) saveat, size);
- }
-
- if ((err = OS_Seek(ref, OSSeekAbs, fileoffs)) != OS_NOERR ||
- (err = OS_Write(ref, saveat, &size)) != OS_NOERR) {
- OSerror(err, "could not write\n");
- return 0;
- }
-
- if (swap) {
- logger(_L, "swapping bytes back... ");
- swab((const void *) saveat, (void *) saveat, size);
- }
-
- logger(_L|L_0, "done\n");
-
- OS_Close(ref);
- return size;
- }
-
- /*
- Return 1 if loaded.
- */
- int
- loaddsr(char *path, char *syspath, char *filename, char *name, void *mem)
- {
- return loadbinary(path, syspath, filename, name, mem, 1, 0, 8192, 8192);
- }
-
- /*
- Return 1 if loaded.
- */
- /*
- int
- loadspeech(char *path, char *syspath, char *filename, void *mem)
- {
- return loadbinary(path, syspath, filename, "Speech ROM", mem, 0,
- 0, 32768, 32768);
- }
- */
-
- /*
-
- Each GRAM Kracker stores an 8K ROM or GROM bank. The first six bytes
- are an extension of the memory image program standard. Here is what the
- bytes mean:
-
- Byte 0: "More to load" flag, values:
- >FF = There's another file to load
- >80 = There's a "UTIL" file to load (I don't think this is ever used).
- >00 = This is the last file
-
- Byte 1: Bank of GRAM/RAM to load file into, values:
- >01 = GROM/GRAM bank 0 (>0000)
- >02 = GROM/GRAM bank 1 (>2000)
- >03 = GROM/GRAM bank 2 (>4000)
- >04 = GROM/GRAM bank 3 (>6000)
- >05 = GROM/GRAM bank 4 (>8000)
- >06 = GROM/GRAM bank 5 (>A000)
- >07 = GROM/GRAM bank 6 (>C000)
- >08 = GROM/GRAM bank 7 (>E000)
- >09 = ROM bank 1 (>6000)
- >0A = ROM bank 2 (second >6000)
- >00 or >FF = Assembly language program, not a cartridge file
-
- Bytes 2 and 3: Number of bytes to load (normally 8192)
- Bytes 4 and 5: Actual address to start loading at (e.g. >6000)
-
- As an example, Extended BASIC gets saved as files "XB" to "XB5", which
- have headers as follows:
- XB FF0A 2000 6000 (ROM bank 2)
- XB1 FF09 2000 6000 (ROM bank 1)
- XB2 FF07 2000 C000 (GRAM bank 6)
- XB3 FF06 2000 A000 (GRAM bank 5)
- XB4 FF05 2000 8000 (GRAM bank 4)
- XB5 0004 2000 6000
-
- Even though TI GROMS only use 6K of each 8K bank, all 8K is stored so people
- can add their own GPL code as extensions to modules. Extended BASIC has
- a number of enhancements available.
- */
-
- /*
- * Search paths for a file matching 'filename'.
- * If found, and it is a valid GRAM-Kracker file,
- * set 'spec' to point to it, and return its header info in 'header'
- *
- */
- int roms_find_gram_kracker(char *path, char *systempath, char *filename,
- OSSpec *spec, gram_kracker_header *header)
- {
- int size;
- fiad_logger_func old;
- int old_unknownfileistext;
- fiad_tifile tf;
- OSError err;
- OSRef ref;
- bool is_v9t9_file;
-
- memset(header, 0, sizeof(gram_kracker_header));
-
- /* Can we find the file? */
- size = findbinary(path, systempath, filename, spec);
- if (!size)
- return 0;
-
- /* See if it's a V9t9/TIFILES file or perhaps a plain binary */
- old = fiad_set_logger(0L);
- old_unknownfileistext = unknownfileistext;
- unknownfileistext = 0;
-
- if (fiad_tifile_setup_spec_with_spec(&tf, spec) != OS_NOERR) {
- goto error_exit;
- }
-
- /* Is it a V9t9 file? */
- if (fiad_tifile_get_info(&tf)) {
- if (!(tf.fdr.flags & ff_program)) {
- logger(_L|LOG_ERROR|LOG_USER, "GRAM Kracker segment '%s' is not a PROGRAM file (it's %s)\n",
- OS_SpecToString1(spec), fiad_catalog_get_file_type_string(&tf.fdr));
- goto error_exit;
- }
- // allow enough space for the data, header, and extra sector
- if (FDR_FILESIZE(&tf.fdr) > 8198+256) {
- logger(_L|LOG_ERROR|LOG_USER, "GRAM Kracker segment '%s' is too long\n"
- "to be a segment (%d bytes > 8192+6 bytes)\n",
- OS_SpecToString1(spec), FDR_FILESIZE(&tf.fdr));
- goto error_exit;
- }
- is_v9t9_file = true;
- } else {
- is_v9t9_file = false;
- }
-
- /* Read header from first sector */
- if (is_v9t9_file) {
- u16 headersize = 6;
- if (fiad_tifile_open_file(&tf, newfileformat,
- false /*create*/,
- false /*always*/,
- true /*readonly*/) != OS_NOERR
- ||
- fiad_tifile_read_binary_image(&tf,
- (u8 *)header,
- headersize,
- &headersize) != 0
- ||
- headersize < 6)
- {
- logger(_L|LOG_ERROR|LOG_USER, "Could not read signature for GRAM Kracker segment in V9t9 file '%s' (%s)\n",
- OS_SpecToString1(spec), OS_GetErrText(tf.error));
- goto error_exit;
- }
- header->absolute_image_file_offset = sizeof(v9t9_fdr) + 6;
- } else {
- OSSize headersize = 6;
-
- if ((err = OS_Open(spec, OSReadOnly, &ref)) != OS_NOERR ||
- (err = OS_Read(ref, (void *)header, &headersize)) != OS_NOERR ||
- (err = OS_Close(ref)) != OS_NOERR)
- {
- logger(_L|LOG_ERROR|LOG_USER, "Could not read signature for GRAM Kracker segment in binary file '%s' (%s)\n",
- OS_SpecToString1(spec), OS_GetErrText(err));
- goto error_exit;
- }
- header->absolute_image_file_offset = 6;
- }
-
- /* Make header suitable for v9t9 */
- header->address = TI2HOST(header->address);
- header->length = TI2HOST(header->length);
-
- if (header->more_to_load == 0x80)
- {
- logger(_L|LOG_ERROR|LOG_USER, "GRAM Kracker segment '%s' is a 'UTIL' segment (not supported)\n",
- OS_SpecToString1(spec));
- goto error_exit;
- }
-
- if (header->gk_type == 0x00 ||
- header->gk_type == 0xff ||
- header->gk_type > GK_TYPE_ROM_2)
- {
- logger(_L|LOG_ERROR|LOG_USER, "GRAM Kracker segment '%s' is not a ROM file (got >%02X)\n",
- OS_SpecToString1(spec), header->gk_type);
- goto error_exit;
- }
-
- return size;
-
- error_exit:
- fiad_set_logger(old);
- unknownfileistext = old_unknownfileistext;
- return 0;
- }
-