mirror of
https://github.com/GerbilSoft/rom-properties.git
synced 2025-06-18 11:35:38 -04:00
[libromdata] Intellivision: Initial Intellivision ROM image parser.
There's a bit of weirdness with Intellivision due to its unusual word size. The General Instrument CP1610 is a 16-bit CPU, but uses 10-bit opcodes. Because of this, Mattel used 10-bit ROMs. Some of the fields in the ROM header use 16-bit addresses, split up into two 10-bit words. The ROM file uses 16-bit big-endian for words, so in order to decode these addresses, we have to take two 16-bit big-endian values, read the low 8 bits of each, and combine it into a 16-bit value. NOTE: ROM images must have a .int or .itv file extension, since the Intellivision ROM header doesn't have a magic number.
This commit is contained in:
parent
77c7f7fada
commit
13a95183eb
4
NEWS.md
4
NEWS.md
@ -46,6 +46,10 @@
|
||||
D67, and (mostly supports) G64 and G71 images, plus GEOS file icons.
|
||||
* ColecoVision: ColecoVision ROM images. Supports reading the title screen
|
||||
message and copyright/release year from .col images, among other things.
|
||||
Requires a .col file extension due to lack of magic number.
|
||||
* Intellivision: Intellivision ROM images. Supports reading the game title
|
||||
and copyright year (if present), and some flags. Requires a .int or .itv
|
||||
file extension due to lack of magic number.
|
||||
|
||||
* New parser features:
|
||||
* DMG: MMM01 and MBC1M multicarts are now detected, and the internal ROM
|
||||
|
@ -47,6 +47,9 @@ Major changes in v2.3 include:
|
||||
* ColecoVision ROM images are now supported, including the text displayed
|
||||
on the ColecoVision logo screen.
|
||||
|
||||
* Intellivision ROM images are now supported, including the game title
|
||||
and copyright year.
|
||||
|
||||
* New translations: Romanian and Italian
|
||||
|
||||
Translators wanted; if you can translate rom-properties from English to another
|
||||
@ -128,6 +131,7 @@ button.
|
||||
|:-------------------------:|:--------------:|:--------:|:---------------:|:---------------:|
|
||||
| ColecoVision | Yes | Yes | N/A | No |
|
||||
| Commodore 64/128 .CRT | Yes | Yes | N/A | Title |
|
||||
| Intellivision | Yes | Yes | N/A | No |
|
||||
| iQue Player ticket files | Yes | Yes | Icon, Banner | No |
|
||||
| Microsoft Xbox (XBE) | Yes | Yes | Icon | No |
|
||||
| Microsoft Xbox 360 (XEX) | Yes | Yes | Icon | No |
|
||||
|
@ -19,6 +19,7 @@ SET(${PROJECT_NAME}_SRCS
|
||||
Console/GameCubeBNR.cpp
|
||||
Console/GameCubeSave.cpp
|
||||
Console/GameCubeRegions.cpp
|
||||
Console/Intellivision.cpp
|
||||
Console/iQuePlayer.cpp
|
||||
Console/MegaDrive.cpp
|
||||
Console/MegaDriveRegions.cpp
|
||||
@ -149,6 +150,7 @@ SET(${PROJECT_NAME}_H
|
||||
Console/GameCubeBNR.hpp
|
||||
Console/GameCubeSave.hpp
|
||||
Console/GameCubeRegions.hpp
|
||||
Console/Intellivision.hpp
|
||||
Console/iQuePlayer.hpp
|
||||
Console/MegaDrive.hpp
|
||||
Console/MegaDriveRegions.hpp
|
||||
@ -180,6 +182,7 @@ SET(${PROJECT_NAME}_H
|
||||
Console/gcn_structs.h
|
||||
Console/gcn_banner.h
|
||||
Console/gcn_card.h
|
||||
Console/intv_structs.h
|
||||
Console/ique_player_structs.h
|
||||
Console/md_structs.h
|
||||
Console/n64_structs.h
|
||||
|
351
src/libromdata/Console/Intellivision.cpp
Normal file
351
src/libromdata/Console/Intellivision.cpp
Normal file
@ -0,0 +1,351 @@
|
||||
/***************************************************************************
|
||||
* ROM Properties Page shell extension. (libromdata) *
|
||||
* Intellivision.cpp: Intellivision ROM reader. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Intellivision.hpp"
|
||||
#include "intv_structs.h"
|
||||
|
||||
#include "ctypex.h"
|
||||
|
||||
// Other rom-properties libraries
|
||||
using namespace LibRpBase;
|
||||
using namespace LibRpFile;
|
||||
using namespace LibRpText;
|
||||
|
||||
// C++ STL classes
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
namespace LibRomData {
|
||||
|
||||
class IntellivisionPrivate final : public RomDataPrivate
|
||||
{
|
||||
public:
|
||||
IntellivisionPrivate(const IRpFilePtr &file);
|
||||
|
||||
private:
|
||||
typedef RomDataPrivate super;
|
||||
RP_DISABLE_COPY(IntellivisionPrivate)
|
||||
|
||||
public:
|
||||
/** RomDataInfo **/
|
||||
static const char *const exts[];
|
||||
static const char *const mimeTypes[];
|
||||
static const RomDataInfo romDataInfo;
|
||||
|
||||
public:
|
||||
// ROM header
|
||||
Intellivision_ROMHeader romHeader;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Get the title from the ROM header.
|
||||
* @param pOutYear [out,opt] Release year, if set; otherwise, -1.
|
||||
* @return Title screen lines, or empty string on error.
|
||||
*/
|
||||
string getTitle(int *pOutYear = nullptr) const;
|
||||
};
|
||||
|
||||
ROMDATA_IMPL(Intellivision)
|
||||
|
||||
/** IntellivisionPrivate **/
|
||||
|
||||
/* RomDataInfo */
|
||||
const char *const IntellivisionPrivate::exts[] = {
|
||||
".int", ".itv",
|
||||
|
||||
//".bin", // NOTE: Too generic...
|
||||
|
||||
nullptr
|
||||
};
|
||||
const char *const IntellivisionPrivate::mimeTypes[] = {
|
||||
// Unofficial MIME types.
|
||||
// TODO: Get these upstreamed on FreeDesktop.org.
|
||||
"application/x-intellivision-rom",
|
||||
|
||||
nullptr
|
||||
};
|
||||
const RomDataInfo IntellivisionPrivate::romDataInfo = {
|
||||
"Intellivision", exts, mimeTypes
|
||||
};
|
||||
|
||||
IntellivisionPrivate::IntellivisionPrivate(const IRpFilePtr &file)
|
||||
: super(file, &romDataInfo)
|
||||
{
|
||||
// Clear the ROM header struct.
|
||||
memset(&romHeader, 0, sizeof(romHeader));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title from the ROM header.
|
||||
* @param pOutYear [out,opt] Release year, if set; otherwise, -1.
|
||||
* @return Title screen lines, or empty string on error.
|
||||
*/
|
||||
string IntellivisionPrivate::getTitle(int *pOutYear) const
|
||||
{
|
||||
// NOTE: The cartridge ROM is mapped to 0x5000.
|
||||
|
||||
// Title/date address must be between 0x5010 and 0x50FF.
|
||||
uint16_t title_addr = romHeader.title_date.get_real_value();
|
||||
if (title_addr < 0x5010 || title_addr >= (0x5000 + ARRAY_SIZE(romHeader.u16))) {
|
||||
// Out of range.
|
||||
return {};
|
||||
}
|
||||
// Convert to an absolute address.
|
||||
title_addr -= 0x5000;
|
||||
|
||||
// First word has the year, minus 1900.
|
||||
// NOTE: ROMs that don't have a valid title/date field may have 0 (1900) here.
|
||||
// Some homebrew titles have weird values, e.g. 2 (1902) or 4 (1904), so
|
||||
// we'll allow any year as long as it's not 0 (1900).
|
||||
if (pOutYear) {
|
||||
unsigned int year_raw = be16_to_cpu(romHeader.u16[title_addr]);
|
||||
if (year_raw != 0) {
|
||||
*pOutYear = year_raw + 1900;
|
||||
}
|
||||
}
|
||||
|
||||
// Title is a NULL-terminated ASCII string, but it's 16-bit words.
|
||||
// Convert it to 8-bit ASCII.
|
||||
// NOTE: Removing the high bit to ensure UTF-8 compatibility.
|
||||
// TODO: Verify the whole EXEC character set.
|
||||
string title;
|
||||
title.reserve(32);
|
||||
const uint16_t *const p_end = &romHeader.u16[ARRAY_SIZE(romHeader.u16)];
|
||||
for (const uint16_t *p = &romHeader.u16[title_addr+1]; p < p_end; p++) {
|
||||
const uint16_t chr = *p;
|
||||
if (chr == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
title += static_cast<char>(static_cast<uint8_t>(be16_to_cpu(chr)));
|
||||
}
|
||||
|
||||
// Trim the title.
|
||||
// NOTE: Games that don't use EXEC don't necessarily have a valid title.
|
||||
// The title field is usually single space in that case, and we should
|
||||
// ignore it. (date is 0 aka 1900; maybe we should skip if that's the case?)
|
||||
while (!title.empty() && ISSPACE(title[title.size()-1])) {
|
||||
title.resize(title.size()-1);
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
/** Intellivision **/
|
||||
|
||||
/**
|
||||
* Read a Intellivision ROM image.
|
||||
*
|
||||
* A ROM image must be opened by the caller. The file handle
|
||||
* will be ref()'d and must be kept open in order to load
|
||||
* data from the ROM image.
|
||||
*
|
||||
* To close the file, either delete this object or call close().
|
||||
*
|
||||
* NOTE: Check isValid() to determine if this is a valid ROM.
|
||||
*
|
||||
* @param file Open ROM image.
|
||||
*/
|
||||
Intellivision::Intellivision(const IRpFilePtr &file)
|
||||
: super(new IntellivisionPrivate(file))
|
||||
{
|
||||
RP_D(Intellivision);
|
||||
|
||||
if (!d->file) {
|
||||
// Could not ref() the file handle.
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the ROM header.
|
||||
d->file->rewind();
|
||||
size_t size = d->file->read(&d->romHeader, sizeof(d->romHeader));
|
||||
if (size != sizeof(d->romHeader)) {
|
||||
// Seek and/or read error.
|
||||
d->file.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this ROM image is supported.
|
||||
const char *const filename = file->filename();
|
||||
const DetectInfo info = {
|
||||
{0, sizeof(d->romHeader), reinterpret_cast<const uint8_t*>(&d->romHeader)},
|
||||
FileSystem::file_ext(filename), // ext
|
||||
0 // szFile (not needed for Intellivision)
|
||||
};
|
||||
d->isValid = (isRomSupported_static(&info) >= 0);
|
||||
|
||||
if (!d->isValid) {
|
||||
d->file.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a ROM image supported by this class?
|
||||
* @param info DetectInfo containing ROM detection information.
|
||||
* @return Class-specific system ID (>= 0) if supported; -1 if not.
|
||||
*/
|
||||
int Intellivision::isRomSupported_static(const DetectInfo *info)
|
||||
{
|
||||
assert(info != nullptr);
|
||||
assert(info->ext != nullptr);
|
||||
if (!info || !info->ext) {
|
||||
// Needs the file extension...
|
||||
return -1;
|
||||
}
|
||||
|
||||
// File extension is required.
|
||||
if (info->ext[0] == '\0') {
|
||||
// Empty file extension...
|
||||
return -1;
|
||||
}
|
||||
|
||||
// The Intellivision ROM header doesn't have enough magic
|
||||
// to conclusively determine if it's a Intellivision ROM,
|
||||
// so check the file extension.
|
||||
for (const char *const *ext = IntellivisionPrivate::exts;
|
||||
*ext != nullptr; ext++)
|
||||
{
|
||||
if (!strcasecmp(info->ext, *ext)) {
|
||||
// File extension is supported.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Not supported.
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the system the loaded ROM is designed for.
|
||||
* @param type System name type. (See the SystemName enum.)
|
||||
* @return System name, or nullptr if type is invalid.
|
||||
*/
|
||||
const char *Intellivision::systemName(unsigned int type) const
|
||||
{
|
||||
RP_D(const Intellivision);
|
||||
if (!d->isValid || !isSystemNameTypeValid(type))
|
||||
return nullptr;
|
||||
|
||||
// Intellivision has the same name worldwide, so we can
|
||||
// ignore the region selection.
|
||||
static_assert(SYSNAME_TYPE_MASK == 3,
|
||||
"N64::systemName() array index optimization needs to be updated.");
|
||||
|
||||
// Bits 0-1: Type. (long, short, abbreviation)
|
||||
static const char *const sysNames[4] = {
|
||||
"Intellivision", "Intellivision", "INTV", nullptr
|
||||
};
|
||||
|
||||
return sysNames[type & SYSNAME_TYPE_MASK];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load field data.
|
||||
* Called by RomData::fields() if the field data hasn't been loaded yet.
|
||||
* @return Number of fields read on success; negative POSIX error code on error.
|
||||
*/
|
||||
int Intellivision::loadFieldData(void)
|
||||
{
|
||||
RP_D(Intellivision);
|
||||
if (!d->fields.empty()) {
|
||||
// Field data *has* been loaded...
|
||||
return 0;
|
||||
} else if (!d->file) {
|
||||
// File isn't open.
|
||||
return -EBADF;
|
||||
} else if (!d->isValid) {
|
||||
// Unknown ROM image type.
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
const Intellivision_ROMHeader *const romHeader = &d->romHeader;
|
||||
d->fields.reserve(3); // Maximum of 3 fields.
|
||||
|
||||
// Title
|
||||
int year = -1;
|
||||
const string title = d->getTitle(&year);
|
||||
if (!title.empty()) {
|
||||
d->fields.addField_string(C_("RomData", "Title"), title);
|
||||
}
|
||||
|
||||
// Copyright year
|
||||
if (year >= 0) {
|
||||
d->fields.addField_string_numeric(C_("Intellivision", "Copyright Year"), year);
|
||||
}
|
||||
|
||||
// Flags
|
||||
unsigned int flags = be16_to_cpu(romHeader->flags);
|
||||
|
||||
// If both "Skip ECS" bits aren't set, clear both to prevent issues.
|
||||
if ((flags & INTV_SKIP_ECS) != INTV_SKIP_ECS) {
|
||||
flags &= ~INTV_SKIP_ECS;
|
||||
}
|
||||
|
||||
static const char *const flags_bitfield_names[] = {
|
||||
// Bits 0-5: Keyclick bits (TODO)
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
|
||||
// Bits 6-8
|
||||
NOP_C_("Intellivision|Flags", "Intellivision 2"),
|
||||
NOP_C_("Intellivision|Flags", "Run code after title string"),
|
||||
NOP_C_("Intellivision|Flags", "Skip ECS title screen"),
|
||||
};
|
||||
vector<string> *const v_flags_bitfield_names = RomFields::strArrayToVector_i18n(
|
||||
"Region", flags_bitfield_names, ARRAY_SIZE(flags_bitfield_names));
|
||||
d->fields.addField_bitfield(C_("Intellivision", "Flags"),
|
||||
v_flags_bitfield_names, 2, flags);
|
||||
|
||||
// TODO: Entry point (differs if EXEC is used or not)
|
||||
|
||||
// Finished reading the field data.
|
||||
return static_cast<int>(d->fields.count());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load metadata properties.
|
||||
* Called by RomData::metaData() if the metadata hasn't been loaded yet.
|
||||
* @return Number of metadata properties read on success; negative POSIX error code on error.
|
||||
*/
|
||||
int Intellivision::loadMetaData(void)
|
||||
{
|
||||
RP_D(Intellivision);
|
||||
if (d->metaData != nullptr) {
|
||||
// Metadata *has* been loaded...
|
||||
return 0;
|
||||
} else if (!d->file) {
|
||||
// File isn't open.
|
||||
return -EBADF;
|
||||
} else if (!d->isValid) {
|
||||
// Unknown ROM image type.
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
// Create the metadata object.
|
||||
d->metaData = new RomMetaData();
|
||||
d->metaData->reserve(2); // Maximum of 2 metadata properties.
|
||||
|
||||
//const Intellivision_ROMHeader *const romHeader = &d->romHeader;
|
||||
|
||||
// Title
|
||||
int year = -1;
|
||||
const string title = d->getTitle(&year);
|
||||
if (!title.empty()) {
|
||||
d->metaData->addMetaData_string(Property::Title, title);
|
||||
}
|
||||
|
||||
// Release year (actually copyright year)
|
||||
if (year >= 0) {
|
||||
d->metaData->addMetaData_uint(Property::ReleaseYear, static_cast<unsigned int>(year));
|
||||
}
|
||||
|
||||
// Finished reading the metadata.
|
||||
return (d->metaData ? static_cast<int>(d->metaData->count()) : -ENOENT);
|
||||
}
|
||||
|
||||
}
|
19
src/libromdata/Console/Intellivision.hpp
Normal file
19
src/libromdata/Console/Intellivision.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
/***************************************************************************
|
||||
* ROM Properties Page shell extension. (libromdata) *
|
||||
* Intellivision.hpp: Intellivision ROM reader. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "librpbase/RomData.hpp"
|
||||
|
||||
namespace LibRomData {
|
||||
|
||||
ROMDATA_DECL_BEGIN(Intellivision)
|
||||
ROMDATA_DECL_METADATA()
|
||||
ROMDATA_DECL_END()
|
||||
|
||||
}
|
86
src/libromdata/Console/intv_structs.h
Normal file
86
src/libromdata/Console/intv_structs.h
Normal file
@ -0,0 +1,86 @@
|
||||
/***************************************************************************
|
||||
* ROM Properties Page shell extension. (libromdata) *
|
||||
* intv_structs.h: Intellivision ROM image data structures. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Intellivision: BIDECLE type
|
||||
* This type stores a low byte and high byte from a 16-bit word
|
||||
* in two consecutive 10-bit words.
|
||||
*
|
||||
* All fields are in 16-bit big-endian, but the byte ordering
|
||||
* within the fields is (low, high).
|
||||
*/
|
||||
typedef union _Intv_BIDECLE {
|
||||
struct {
|
||||
uint8_t unused_lo;
|
||||
uint8_t lo;
|
||||
uint8_t unused_hi;
|
||||
uint8_t hi;
|
||||
};
|
||||
uint16_t u16[2];
|
||||
|
||||
#ifdef __cplusplus
|
||||
uint16_t get_real_value(void) const {
|
||||
return (hi << 8) | lo;
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
} Intv_BIDECLE;
|
||||
ASSERT_STRUCT(Intv_BIDECLE, 2*sizeof(uint16_t));
|
||||
|
||||
/**
|
||||
* Intellivision ROM image file header.
|
||||
* Reference: https://wiki.intellivision.us/index.php/Hello_World_Tutorial
|
||||
*
|
||||
* All fields are in 16-bit big-endian.
|
||||
*
|
||||
* NOTE: Intellivision used 10-bit ROMs. ROM images use
|
||||
* 16-bit words for convenience, plus homebrew games
|
||||
* sometimes use 16-bit ROMs.
|
||||
*/
|
||||
typedef union _Intellivision_ROMHeader {
|
||||
struct {
|
||||
// Pointers (NOTE: Addresses are in 16-bit word units.)
|
||||
Intv_BIDECLE mob_picture_base; // [0x000] MOB picture base
|
||||
Intv_BIDECLE process_table; // [0x004] Process table
|
||||
Intv_BIDECLE program_start_address; // [0x008] Entry point (only used if EXEC is in use)
|
||||
Intv_BIDECLE bkgnd_picture_base; // [0x00C] Background picture base
|
||||
Intv_BIDECLE gram_pictures; // [0x010] GRAM pictures
|
||||
Intv_BIDECLE title_date; // [0x014] Title and date (date is year minus 1900)
|
||||
|
||||
uint16_t flags; // [0x018] Flags (see Intellivision_Flags_e)
|
||||
uint16_t screen_border_ctrl; // [0x01A] Screen border control
|
||||
uint16_t color_stack_mode; // [0x01C] Color stack and framebuffer mode
|
||||
|
||||
uint16_t color_stack[4]; // [0x01E] Initial color stack
|
||||
uint16_t border_color; // [0x026] Initial border color
|
||||
};
|
||||
uint16_t u16[256]; // Direct access for e.g. title/date
|
||||
} Intellivision_ROMHeader;
|
||||
ASSERT_STRUCT(Intellivision_ROMHeader, 512);
|
||||
|
||||
/**
|
||||
* Intelliviison flags
|
||||
*/
|
||||
typedef enum {
|
||||
INTV_SKIP_ECS = (1U << 9) | (1U << 8), // Skip ECS title screen (both bits must be set)
|
||||
INTV_RUN_CODE_AFTER_TITLE = (1U << 7), // Run code that appears after the title string
|
||||
INTV_SUPPORT_INTV2 = (1U << 6), // Must be set to allow use on Intellivision 2
|
||||
INTV_KEYCLICK_MASK = 0x001F, // Keyclick mask (requires EXEC)
|
||||
} Intellivision_Flags_e;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -40,6 +40,7 @@ using std::vector;
|
||||
#include "Console/GameCube.hpp"
|
||||
#include "Console/GameCubeBNR.hpp"
|
||||
#include "Console/GameCubeSave.hpp"
|
||||
#include "Console/Intellivision.hpp"
|
||||
#include "Console/iQuePlayer.hpp"
|
||||
#include "Console/MegaDrive.hpp"
|
||||
#include "Console/N64.hpp"
|
||||
@ -378,6 +379,7 @@ const RomDataFactoryPrivate::RomDataFns RomDataFactoryPrivate::romDataFns_header
|
||||
GetRomDataFns(GameCube, ATTR_HAS_THUMBNAIL | ATTR_HAS_METADATA | ATTR_SUPPORTS_DEVICES),
|
||||
GetRomDataFns(GameCubeBNR, ATTR_HAS_THUMBNAIL | ATTR_HAS_METADATA),
|
||||
GetRomDataFns(GameCubeSave, ATTR_HAS_THUMBNAIL | ATTR_HAS_METADATA),
|
||||
GetRomDataFns(Intellivision, ATTR_HAS_METADATA),
|
||||
GetRomDataFns(iQuePlayer, ATTR_HAS_THUMBNAIL | ATTR_HAS_METADATA),
|
||||
// MegaDrive: ATTR_SUPPORTS_DEVICES for Sega CD
|
||||
GetRomDataFns(MegaDrive, ATTR_HAS_THUMBNAIL | ATTR_HAS_METADATA | ATTR_SUPPORTS_DEVICES),
|
||||
|
@ -30,6 +30,7 @@ application/x-colecovision-rom # ColecoVision
|
||||
application/x-n64-rom # N64
|
||||
application/x-nes-rom # NES
|
||||
application/x-fds-disk # NES
|
||||
application/x-intellivision-rom # IntelliVision
|
||||
application/x-ps1-executable # PlayStationEXE
|
||||
application/x-sms-rom # Sega8Bit
|
||||
application/x-gamegear-rom # Sega8Bit
|
||||
|
@ -365,6 +365,15 @@
|
||||
</magic>
|
||||
</mime-type>
|
||||
|
||||
<!-- Intellivision -->
|
||||
<mime-type type="application/x-intellivision-rom">
|
||||
<comment>Intellivision ROM image</comment>
|
||||
<sub-class-of type="application/x-executable"/>
|
||||
<generic-icon name="application-x-executable"/>
|
||||
<glob pattern="*.int"/>
|
||||
<glob pattern="*.itv"/>
|
||||
</mime-type>
|
||||
|
||||
<!-- iQuePlayer -->
|
||||
<!-- TODO: Distinguish between CMD (10,668 bytes) and DAT (11,084 bytes). -->
|
||||
<mime-type type="application/x-ique-cmd">
|
||||
|
Loading…
Reference in New Issue
Block a user