diff options
Diffstat (limited to 'src/mess/tools/imgtool/modules/psion.c')
-rw-r--r-- | src/mess/tools/imgtool/modules/psion.c | 683 |
1 files changed, 0 insertions, 683 deletions
diff --git a/src/mess/tools/imgtool/modules/psion.c b/src/mess/tools/imgtool/modules/psion.c deleted file mode 100644 index d343dde5c6a..00000000000 --- a/src/mess/tools/imgtool/modules/psion.c +++ /dev/null @@ -1,683 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Sandro Ronco -/*************************************************************************** - - Psion Organiser II Datapack - - 08/18/2010 Sandro Ronco - - Known file types: - 0x00 invalid record - 0x01 - 0x7e deleted record - 0x7f invalid deleted record - 0x80 long record - 0x81 file name - 0x82 diary - 0x83 OPL/OB3 procedure - 0x84 RS232 setup - 0x85 - 0x8f reserved - 0x90 MAIN Record - 0x91 - 0xfe data records from files - 0xff invalid record - -****************************************************************************/ - -#include "imgtool.h" - -#define MAXFILES 256 - -struct psion_file -{ - char filename[9]; - UINT8 type; - UINT8 id; - - UINT16 name_rec; - UINT16 data_rec; -}; - -struct psion_pack -{ - imgtool_stream *stream; - - UINT16 eop; - struct psion_file pack_index[MAXFILES]; -}; - -struct psion_iter -{ - UINT16 index; -}; - -UINT16 head_checksum(UINT8* data) -{ - UINT16 checksum = 0; - - for (int i=0; i<6; i+=2) - checksum += (data[i]<<8 | data[i+1]); - - return checksum; -} - -UINT16 get_long_rec_size(imgtool_stream *stream) -{ - UINT8 size_h, size_l; - - stream_read(stream, &size_h, 1); - stream_read(stream, &size_l, 1); - - return (size_h<<8) | size_l; -} - -UINT32 update_pack_index(psion_pack *pack) -{ - UINT8 data, type; - UINT16 size; - UINT16 index = 0; - - memset(pack->pack_index, 0, sizeof(psion_file) * MAXFILES); - - // start at the first record - stream_seek(pack->stream, 0x10, SEEK_SET); - - do - { - stream_read(pack->stream, &data, 1); - - if(data == 0xff) - { - pack->eop = stream_tell(pack->stream) - 1; - return TRUE; - } - else if (data == 0x02) - { - // long record without name are ignored - stream_read(pack->stream, &data, 1); - size = get_long_rec_size(pack->stream); - stream_seek(pack->stream, size, SEEK_CUR); - } - else - { - stream_read(pack->stream, &type, 1); - - // deleted record are not listed - if (type < 0x90 && (type & 0x80)) - { - pack->pack_index[index].type = type; - stream_read(pack->stream, &pack->pack_index[index].filename, 8); - stream_read(pack->stream, &pack->pack_index[index].id, 1); - pack->pack_index[index].name_rec = stream_tell(pack->stream) - 11; - - //check for data record - stream_read(pack->stream, &data, 1); - if (data == 0x02) - pack->pack_index[index].data_rec = stream_tell(pack->stream) - 1; - - stream_seek(pack->stream, -1, SEEK_CUR); - - index++; - } - else - stream_seek(pack->stream, data, SEEK_CUR); - } - - } while (stream_size(pack->stream) > stream_tell(pack->stream)); - - // corrupted image - return FALSE; -} - -int seek_next_record(imgtool_stream *stream, UINT8 id) -{ - UINT8 data, rec_id; - UINT16 size; - - do - { - stream_read(stream, &data, 1); - - if(data == 0xff) - break; - - if (data == 2) - { - stream_read(stream, &rec_id, 1); - size = get_long_rec_size(stream); - - } - else - { - stream_read(stream, &rec_id, 1); - if (id == rec_id) - { - stream_seek(stream, -2, SEEK_CUR); - return TRUE; - } - size = data; - } - - // next record - stream_seek(stream, size, SEEK_CUR); - - } while (stream_size(stream) > stream_tell(stream)); - - return FALSE; -} - -// if there are multiple files with the same name, only the first is found -int seek_file_name(psion_pack *pack, const char *filename) -{ - UINT16 index = 0; - - while (pack->pack_index[index].name_rec) - { - if (!strncmp(filename, pack->pack_index[index].filename, strlen(filename))) - return index; - index++; - } - - // filename not found - return -1; -} - -UINT8 get_free_file_id(psion_pack *pack) -{ - for (UINT8 file_id=0x91; file_id<0xff; file_id++) - { - int index = 0; - - while (pack->pack_index[index].id != file_id) - if (pack->pack_index[index++].name_rec == 0) - return file_id; - } - - return 0xff; -} - -void put_name_record(imgtool_stream *stream, const char* filename, UINT8 record_type, UINT8 record_id) -{ - char data[0x10]; - int i = 0; - - data[i++] = 0x09; - data[i++] = record_type; - - // filename is 8 char long space filled - for (int j=0; j<8; j++) - if (j < strlen(filename)) - data[i++] = filename[j]; - else - data[i++] = 0x20; - - data[i++] = record_id; - - stream_write(stream, data, i); -} - -void update_opk_head(imgtool_stream *stream) -{ - UINT16 size = stream_size(stream) - 6; - - stream_seek(stream, 4, SEEK_SET); - stream_putc(stream, (size>>8) & 0xff); - stream_putc(stream, size & 0xff); -} - -char *stream_getline(imgtool_stream *source, UINT16 max_len) -{ - UINT16 pos = 0; - char data; - char *line = (char*)malloc(max_len); - memset(line, 0, max_len); - - while (pos < max_len && stream_size(source) > stream_tell(source)) - { - stream_read(source, &data, 1); - - switch(data) - { - case '\r': - stream_read(source, &data, 1); - if (data != '\n') - stream_seek(source, -1, SEEK_CUR); - case '\n': - return line; - default: - line[pos++] = data; - break; - } - } - - if (pos) - return line; - - free(line); - return NULL; -} - -UINT16 put_odb(imgtool_stream *instream, imgtool_stream *outstream, UINT8 file_id) -{ - char *line; - UINT16 out_size = 0; - - // reset stream - stream_seek(instream, 0, SEEK_SET); - - while ((line = stream_getline(instream, 256))) - { - UINT16 len = strlen(line); - - stream_putc(outstream, (UINT8)len); - stream_putc(outstream, file_id); - stream_write(outstream, line, len); - - out_size += (len + 1); - - free(line); - } - - // end of pack - stream_fill(outstream, 0xff, 2); - - return out_size + 4; -} - -UINT16 put_ob3(imgtool_stream *instream, imgtool_stream *outstream) -{ - UINT16 size = stream_size(instream) - 6; - dynamic_buffer buffer(size); - - stream_seek(instream, 6, SEEK_SET); - stream_read(instream, &buffer[0], size); - - stream_write(outstream, &buffer[0], size); - - // end of pack - stream_fill(outstream, 0xff, 2); - - return size; -} - -UINT16 put_opl(imgtool_stream *instream, imgtool_stream *outstream) -{ - UINT16 out_size = 0; - UINT32 rec_start = stream_tell(outstream); - char *line; - - // reset stream - stream_seek(instream, 0, SEEK_SET); - - stream_fill(outstream, 0x00, 4); - - // replace all eol with 0x00 - while ((line = stream_getline(instream, 256))) - { - // replace tab with space - for (int i=0; i<strlen(line); i++) - if (line[i] == '\t') line[i] = ' '; - - stream_write(outstream, line, strlen(line)); - stream_putc(outstream, 0x00); - out_size += strlen(line) + 1; - free(line); - } - - // end of pack - stream_fill(outstream, 0xff, 2); - - // update the size in the head - stream_seek(outstream, rec_start + 2, SEEK_SET); - stream_putc(outstream, (out_size>>8) & 0xff); - stream_putc(outstream, out_size & 0xff); - - return out_size + 4; -} - -UINT16 get_odb(imgtool_stream *instream, imgtool_stream *outstream, UINT8 type, UINT8 file_id) -{ - UINT8 data, *buffer; - UINT16 out_size = 0; - - if (file_id >= 0x90) - while (seek_next_record(instream, file_id)) - { - stream_read(instream, &data, 1); - stream_seek(instream, 1, SEEK_CUR); - buffer = (UINT8*)malloc(data); - stream_read(instream, buffer, data); - stream_write(outstream, buffer, data); - stream_putc(outstream, '\r'); - stream_putc(outstream, '\n'); - free (buffer); - out_size += data; - } - - return out_size; -} - -UINT16 get_ob3(imgtool_stream *instream, imgtool_stream *outstream, UINT8 type, UINT8 file_id) -{ - UINT8 data, *buffer = NULL; - UINT16 size = 0; - static const char ob3_magic[3] = {'O', 'R', 'G'}; - - stream_read(instream, &data, 1); - - if (data == 0x02) - { - stream_seek(instream, 1, SEEK_CUR); - size = get_long_rec_size(instream); - buffer = (UINT8*)malloc(size); - stream_read(instream, buffer, size); - } - - stream_write(outstream, ob3_magic, 3); - stream_putc(outstream, (size>>8) & 0xff); - stream_putc(outstream, size & 0xff); - stream_putc(outstream, type | 0x80); - - if (buffer) - { - stream_write(outstream, buffer, size); - free (buffer); - } - - return size; -} - -static imgtoolerr_t datapack_open( imgtool_image *image, imgtool_stream *stream) -{ - psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); - char opk_magic[4]; - - stream_read(stream, opk_magic, 4); - - if(strcmp(opk_magic, "OPK\0")) - return IMGTOOLERR_UNEXPECTED; - - pack->stream = stream; - - if (update_pack_index(pack)) - return IMGTOOLERR_SUCCESS; - else - return IMGTOOLERR_CORRUPTIMAGE; -} - -static imgtoolerr_t datapack_create( imgtool_image *image, imgtool_stream *stream, option_resolution *opts) -{ - psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); - static const UINT8 opk_magic[4] = {'O', 'P', 'K', 0x00}; - UINT8 pack_head[8] = {0x40, 0x00, 0x59, 0x01, 0x01, 0x01, 0x00, 0x00}; - UINT16 checksum; - - pack_head[0] |= (option_resolution_lookup_int(opts, 'R')) ? 0x00 : 0x02; - pack_head[0] |= (option_resolution_lookup_int(opts, 'P')) ? 0x04 : 0x00; - pack_head[0] |= (option_resolution_lookup_int(opts, 'W')) ? 0x00 : 0x08; - pack_head[0] |= (option_resolution_lookup_int(opts, 'B')) ? 0x00 : 0x10; - pack_head[0] |= (option_resolution_lookup_int(opts, 'C')) ? 0x20 : 0x00; - pack_head[1] = option_resolution_lookup_int(opts, 'S'); - - checksum = head_checksum(pack_head); - - stream_write(stream, opk_magic, 4); - stream_fill(stream, 0x00, 2); - stream_write(stream, pack_head, 8); - - stream_putc(stream, (checksum>>8) & 0xff); - stream_putc(stream, checksum & 0xff); - - put_name_record(stream, "MAIN", 0x81, 0x90); - - stream_fill(stream, 0xff, 2); - - update_opk_head(stream); - - pack->stream = stream; - - if (update_pack_index(pack)) - return IMGTOOLERR_SUCCESS; - else - return IMGTOOLERR_CORRUPTIMAGE; -} - -static void datapack_close( imgtool_image *image) -{ - psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); - - stream_close( pack->stream ); -} - -static imgtoolerr_t datapack_begin_enum(imgtool_directory *enumeration, const char *path) -{ - psion_iter *iter = (psion_iter*)imgtool_directory_extrabytes(enumeration); - iter->index = 0; - - return IMGTOOLERR_SUCCESS; -} - -static imgtoolerr_t datapack_next_enum(imgtool_directory *enumeration, imgtool_dirent *ent) -{ - imgtool_image *image = imgtool_directory_image(enumeration); - psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); - psion_iter *iter = (psion_iter*)imgtool_directory_extrabytes(enumeration); - UINT8 data = 0; - - if (!pack->pack_index[iter->index].name_rec) - { - ent->eof = 1; - return IMGTOOLERR_SUCCESS; - } - memcpy(ent->filename, pack->pack_index[iter->index].filename, 8); - sprintf(ent->attr, "Type: %02x ID: %02x", pack->pack_index[iter->index].type, pack->pack_index[iter->index].id); - - if (pack->pack_index[iter->index].data_rec) - { - stream_seek(pack->stream, pack->pack_index[iter->index].data_rec + 2, SEEK_SET); - ent->filesize = get_long_rec_size(pack->stream); - } - - // seek all file's records - if (pack->pack_index[iter->index].id >= 0x90) - { - stream_seek(pack->stream, 0x10, SEEK_SET); - while (seek_next_record(pack->stream, pack->pack_index[iter->index].id)) - { - stream_read(pack->stream, &data, 1); - stream_seek(pack->stream, data + 1, SEEK_CUR); - ent->filesize +=data; - } - } - - iter->index++; - return IMGTOOLERR_SUCCESS; -} - -static void datapack_close_enum( imgtool_directory *enumeration) -{ -} - -static imgtoolerr_t datapack_free_space( imgtool_partition *partition, UINT64 *size) -{ - imgtool_image *image = imgtool_partition_image( partition); - psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); - UINT32 pack_size = 0; - - stream_seek(pack->stream, 0x07, SEEK_SET); - stream_read(pack->stream, &pack_size, 1); - - if (size) - *size = (pack_size * 0x2000) - pack->eop; - - return IMGTOOLERR_SUCCESS; -} - -static imgtoolerr_t datapack_read_file(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *destf) -{ - imgtool_image *image = imgtool_partition_image(partition); - psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); - int index = seek_file_name(pack, filename); - - if (index >= 0) - { - if ((pack->pack_index[index].type & 0x7f) == 0x01) - { - // ODB files - stream_seek(pack->stream, 0x10, SEEK_SET); - get_odb(pack->stream, destf, pack->pack_index[index].type, pack->pack_index[index].id); - } - else if ((pack->pack_index[index].type & 0x7f) == 0x03) - { - // OB3/OPL files - stream_seek(pack->stream, pack->pack_index[index].data_rec, SEEK_SET); - get_ob3(pack->stream, destf, pack->pack_index[index].type, pack->pack_index[index].id); - } - else - { - // Other files - return IMGTOOLERR_UNIMPLEMENTED; - } - - return IMGTOOLERR_SUCCESS; - } - else - return IMGTOOLERR_FILENOTFOUND; -} - -static imgtoolerr_t datapack_write_file( imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *sourcef, option_resolution *opts) -{ - imgtool_image *image = imgtool_partition_image(partition); - psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); - static const UINT8 data_head[4] = {0x02, 0x80, 0x00, 0x00}; - UINT8 head[3]; - UINT16 size = 0; - UINT8 type = option_resolution_lookup_int(opts, 'T'); - UINT8 file_id = option_resolution_lookup_int(opts, 'I'); - - if (!pack->eop) - return IMGTOOLERR_CORRUPTIMAGE; - - // if not file_id is specified get the first free (for ODB only) - if (file_id == 0 && type == 3) - { - file_id = get_free_file_id(pack); - - if (file_id == 0xff) - return IMGTOOLERR_NOSPACE; - } - - stream_read(sourcef, head, 3); - stream_seek(pack->stream, pack->eop, SEEK_SET); - - if (type == 0) - type = (!strncmp((char*)head, "ORG", 3)) ? 1 : 2; - - switch (type) - { - case 1: //OB3 file - put_name_record(pack->stream, filename, 0x83, file_id); - stream_write(pack->stream, data_head, 4); - size = put_ob3(sourcef, pack->stream); - break; - case 2: //OPL file - put_name_record(pack->stream, filename, 0x83, file_id); - stream_write(pack->stream, data_head, 4); - size = put_opl(sourcef, pack->stream); - break; - case 3: //ODB file - put_name_record(pack->stream, filename, 0x81, file_id); - size = put_odb(sourcef, pack->stream, file_id); - break; - } - - if (type != 3) - { - // update the OB3/OPL long record size - stream_seek(pack->stream, pack->eop + 13, SEEK_SET); - stream_putc(pack->stream, (size>>8) & 0xff); - stream_putc(pack->stream, size & 0xff); - } - - update_opk_head(pack->stream); - - if (update_pack_index(pack)) - return IMGTOOLERR_SUCCESS; - else - return IMGTOOLERR_CORRUPTIMAGE; -} - -static imgtoolerr_t datapack_delete_file( imgtool_partition *partition, const char *filename) -{ - imgtool_image *image = imgtool_partition_image(partition); - psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image); - int index = seek_file_name(pack, filename); - - if (index >= 0) - { - // clear the bit 7 of the file type to mark the file as deleted - stream_seek(pack->stream, pack->pack_index[index].name_rec + 1, SEEK_SET); - stream_putc(pack->stream, pack->pack_index[index].type & 0x7f); - - if (update_pack_index(pack)) - return IMGTOOLERR_SUCCESS; - else - return IMGTOOLERR_CORRUPTIMAGE; - } - else - return IMGTOOLERR_FILENOTFOUND; -} - -static OPTION_GUIDE_START( psion_create_optguide ) - OPTION_ENUM_START( 'S', "size", "datapack size" ) - OPTION_ENUM( 1, "8k", "8 kbyte" ) - OPTION_ENUM( 2, "16k", "16 kbyts" ) - OPTION_ENUM( 4, "32k", "32 kbyte" ) - OPTION_ENUM( 8, "64k", "64 kbyte" ) - OPTION_ENUM( 16, "128k", "128 kbyte" ) // only paged datapacks can have this size - OPTION_ENUM_END - OPTION_INT('R', "ram", "EPROM/RAM datapack" ) - OPTION_INT('P', "paged", "linear/paged datapack" ) - OPTION_INT('W', "protect", "write-protected datapack" ) - OPTION_INT('B', "boot", "bootable datapack" ) - OPTION_INT('C', "copy", "copyable datapack" ) -OPTION_GUIDE_END - -static OPTION_GUIDE_START( psion_write_optguide ) - OPTION_ENUM_START( 'T', "type", "file type" ) - OPTION_ENUM( 1, "OB3", "OB3 files" ) - OPTION_ENUM( 2, "OPL", "OPL files" ) - OPTION_ENUM( 3, "ODB", "ODB or text files" ) - OPTION_ENUM_END - OPTION_INT( 'I', "id", "File ID" ) -OPTION_GUIDE_END - -void psion_get_info( const imgtool_class *imgclass, UINT32 state, union imgtoolinfo *info) -{ - switch (state) - { - // --- the following bits of info are returned as 64-bit signed integers --- - case IMGTOOLINFO_INT_IMAGE_EXTRA_BYTES : info->i = sizeof(psion_pack); break; - case IMGTOOLINFO_INT_DIRECTORY_EXTRA_BYTES : info->i = sizeof(psion_iter); break; - - // --- the following bits of info are returned as pointers to data or functions --- - case IMGTOOLINFO_PTR_OPEN : info->open = datapack_open; break; - case IMGTOOLINFO_PTR_CREATE : info->create = datapack_create; break; - case IMGTOOLINFO_PTR_CLOSE : info->close = datapack_close; break; - case IMGTOOLINFO_PTR_BEGIN_ENUM : info->begin_enum = datapack_begin_enum; break; - case IMGTOOLINFO_PTR_NEXT_ENUM : info->next_enum = datapack_next_enum; break; - case IMGTOOLINFO_PTR_CLOSE_ENUM : info->close_enum = datapack_close_enum; break; - case IMGTOOLINFO_PTR_FREE_SPACE : info->free_space = datapack_free_space; break; - case IMGTOOLINFO_PTR_READ_FILE : info->read_file = datapack_read_file; break; - case IMGTOOLINFO_PTR_WRITE_FILE : info->write_file = datapack_write_file; break; - case IMGTOOLINFO_PTR_DELETE_FILE : info->delete_file = datapack_delete_file; break; - case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE : info->createimage_optguide = psion_create_optguide; break; - case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE : info->createimage_optguide = psion_write_optguide; break; - - // --- the following bits of info are returned as NULL-terminated strings --- - case IMGTOOLINFO_STR_NAME : strcpy( info->s = imgtool_temp_str(), "psionpack"); break; - case IMGTOOLINFO_STR_DESCRIPTION : strcpy( info->s = imgtool_temp_str(), "Psion Organiser II Datapack"); break; - case IMGTOOLINFO_STR_FILE : strcpy( info->s = imgtool_temp_str(), __FILE__); break; - case IMGTOOLINFO_STR_FILE_EXTENSIONS : strcpy( info->s = imgtool_temp_str(), "opk"); break; - case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC : strcpy( info->s = imgtool_temp_str(), "S1/2/[4]/8/16;R[0]/1;P[0]/1;W0/[1];B[0]/1;C0/[1]"); break; - case IMGTOOLINFO_STR_WRITEFILE_OPTSPEC : strcpy( info->s = imgtool_temp_str(), "T[1]/2/3;I[0]/145-255"); break; - } -} |