Update to v082r28 release.

byuu says:

Was mostly working on BML. Still working on the spec.
Added NES-BNROM, NES-GNROM/NES-MHROM boards. I don't even know why. The
latter games do not work very well without Zapper support.
This commit is contained in:
Tim Allen 2011-10-02 21:05:45 +11:00
parent ba2e6b5789
commit b629a46779
36 changed files with 398 additions and 192 deletions

View File

@ -29,7 +29,7 @@ endif
# platform
ifeq ($(platform),x)
# tree vectorization causes code generation errors with GCC 4.6.1
# tree vectorization causes code generation errors with Linux/GCC 4.6.1
flags += -fno-tree-vectorize
link += -s -ldl -lX11 -lXext
else ifeq ($(platform),osx)

View File

@ -53,21 +53,14 @@ namespace nall {
operator[](buffersize) = data;
}
void append(const T data[], unsigned length) {
for(unsigned n = 0; n < length; n++) operator[](buffersize) = data[n];
}
void remove() {
if(size > 0) resize(size - 1); //remove last element only
}
template<typename U> void insert(unsigned index, const U list) {
unsigned listsize = container_size(list);
resize(buffersize + listsize);
memmove(pool + index + listsize, pool + index, (buffersize - index) * sizeof(T));
for(auto &item : list) pool[index++] = item;
}
void insert(unsigned index, const T item) {
insert(index, array<T>{ item });
}
void remove(unsigned index, unsigned count = 1) {
for(unsigned i = index; count + i < buffersize; i++) {
pool[i] = pool[count + i];

View File

@ -28,6 +28,7 @@
#include <nall/string/cast.hpp>
#include <nall/string/compare.hpp>
#include <nall/string/convert.hpp>
#include <nall/string/cstring.hpp>
#include <nall/string/filename.hpp>
#include <nall/string/math.hpp>
#include <nall/string/platform.hpp>

View File

@ -1,11 +1,26 @@
#ifndef NALL_STRING_BASE_HPP
#define NALL_STRING_BASE_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {
struct cstring;
struct string;
struct lstring;
template<typename T> inline const char* to_string(T);
struct cstring {
inline operator const char*() const;
inline unsigned length() const;
inline bool operator==(const char*) const;
inline bool operator!=(const char*) const;
inline optional<unsigned> position(const char *key) const;
inline optional<unsigned> iposition(const char *key) const;
inline cstring& operator=(const char *data);
inline cstring(const char *data);
inline cstring();
protected:
const char *data;
};
struct string {
inline void reserve(unsigned);

View File

@ -1,124 +1,175 @@
#ifdef NALL_STRING_INTERNAL_HPP
//BML parser
//version 0.02
//BML v1.0 parser
//revision 0.03
namespace nall {
namespace BML {
struct Node : linear_vector<Node> {
Node *parent;
const char *cname;
const char *cvalue;
inline static string encode(const char *s) {
array<char> output;
while(*s) {
char c = *s++;
(c == '\n') ? output.append("{lf}", 4) :
(c == '{') ? output.append("{lb}", 4) :
(c == '}') ? output.append("{rb}", 4) :
output.append(c);
}
output.append(0);
return output.get();
}
inline string name() { return cname; }
inline string value() { return cvalue; }
struct Node {
cstring name;
cstring value;
signed depth;
private:
linear_vector<Node> children;
inline bool valid(char p) const {
if(p >= 'A' && p <= 'Z') return true;
if(p >= 'a' && p <= 'z') return true;
if(p >= '0' && p <= '9') return true;
if(p == '+' || p == '-') return true;
if(p == '.' || p == '_') return true;
if(p == ':') return true;
if(p == '-' || p == '.') return true;
return false;
}
inline bool space(char p) const {
return p == ' ' || p == '\t';
}
inline unsigned parseDepth(char *p) {
unsigned depth = 0;
while(space(*p)) depth++, p++;
while(*p == '\t') depth++, p++;
return depth;
}
inline void parseNode(char *&p) {
inline void parseName(char *&p) {
if(valid(*p)) {
cname = p;
name = p;
while(valid(*p)) p++;
if(*p != '=') return;
*p++ = 0;
}
if(*p == '\n') throw "Missing node value";
}
if(valid(*p)) {
cvalue = p;
while(valid(*p)) p++;
} else {
char terminal = *p++;
cvalue = p;
while(*p && *p != terminal) p++;
if(*p == 0) throw "Unclosed terminal";
*p++ = 0;
inline void parseValue(char *&p) {
*p++ = 0; //'{'
value = p;
char *w = p;
while(*p) {
if(*p == '\n') throw "Unclosed node value";
if(*p == '}') break;
if(*p == '{') {
if(*(p + 1) == 'l' && *(p + 2) == 'b' && *(p + 3) == '}') *w++ = '{', p += 4;
else if(*(p + 1) == 'r' && *(p + 2) == 'b' && *(p + 3) == '}') *w++ = '}', p += 4;
else if(*(p + 1) == 'l' && *(p + 2) == 'f' && *(p + 3) == '}') *w++ = '\n', p += 4;
else throw "Unrecognized escape sequence";
continue;
}
*w++ = *p++;
}
if(*p != '}') throw "Unclosed node value";
*w = *p++ = 0; //'}'
}
inline void parseLine(char *&p) {
unsigned depth = parseDepth(p);
while(space(*p)) p++;
parseNode(p);
depth = parseDepth(p);
while(*p == '\t') p++;
while(space(*p)) {
parseName(p);
bool multiLine = false;
if(*p == ':') {
multiLine = true;
*p++ = 0;
Node node(this);
node.parseNode(p);
append(node);
} else if(*p == '{') {
parseValue(p);
if(*p != ' ' && *p != '\n') throw "Invalid character after first node value";
}
if(*p == '\n') *p++ = 0;
while(*p == ' ') {
*p++ = 0;
Node node;
node.parseName(p);
if(*p == '{') node.parseValue(p);
if(*p != ' ' && *p != '\n') throw "Invalid character after node";
children.append(node);
}
while(parseDepth(p) > depth) {
Node node(this);
node.parseLine(p);
append(node);
if(*p == 0) throw "Missing line feed";
while(*p == '\n') *p++ = 0;
if(multiLine == false) {
while(parseDepth(p) > depth) {
Node node;
node.parseLine(p);
children.append(node);
}
} else {
value = p;
char *w = p;
while(parseDepth(p) > depth) {
p += depth + 1;
while(*p && *p != '\n') *w++ = *p++;
if(*p != '\n') throw "Multi-line value missing line feed";
*w++ = *p++;
}
*(w - 1) = 0;
if(value == p) value = p - 1; //no text data copied, point it back at null data
*(p - 1) = 0;
}
}
inline void parse(char *&p, unsigned parentDepth = 0) {
inline void parse(char *&p) {
while(*p) {
while(*p == '\n') *p++ = 0;
Node node(this);
Node node;
node.parseLine(p);
append(node);
children.append(node);
}
}
public:
inline Node& operator[](const string &name) {
for(auto &node : *this) {
if(!strcmp(node.cname, name)) return node;
inline Node& operator[](const char *name) {
for(auto &node : children) {
if(node.name == name) return node;
}
static Node node;
node.name = nullptr;
return node;
}
inline bool exists() {
return parent != nullptr;
inline bool exists() const {
return name;
}
inline string content(const string &separator = "\n") const {
string result;
for(auto &node : *this) result.append(node.cvalue, separator);
result.rtrim<1>(separator);
return result;
}
inline Node(const string &document) : parent(nullptr), cname(nullptr), cvalue(nullptr) {
inline bool load(const char *document) {
if(document == nullptr) return false;
char *p = strdup(document);
cvalue = p;
name = nullptr;
value = p;
try {
parse(p);
} catch(const char *error) {
reset();
free((void*)(const char*)value);
children.reset();
return false;
}
depth = -1;
return true;
}
inline Node(Node *parent) : parent(parent), cname(""), cvalue("") {}
inline Node() : parent(nullptr), cname(""), cvalue("") {}
inline ~Node() { if(cname == nullptr && cvalue) free((void*)cvalue); }
inline void constructor() {
depth = 0;
name = "";
value = "";
}
unsigned size() const { return children.size(); }
Node* begin() { return children.begin(); }
Node* end() { return children.end(); }
const Node* begin() const { return children.begin(); }
const Node* end() const { return children.end(); }
inline Node() { constructor(); }
inline Node(const char *document) { constructor(); load(document); }
inline ~Node() { if(depth == -1) free((void*)(const char*)value); }
};
}

View File

@ -1,7 +1,7 @@
#ifdef NALL_STRING_INTERNAL_HPP
//BSV parser
//version 0.02
//BSV v1.0 parser
//revision 0.02
namespace nall {

View File

@ -1,19 +1,20 @@
#ifndef NALL_STRING_CAST_HPP
#define NALL_STRING_CAST_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {
//this is needed, as C++0x does not support explicit template specialization inside classes
template<> inline const char* to_string<bool> (bool v) { return v ? "true" : "false"; }
template<> inline const char* to_string<signed int> (signed int v) { static char temp[256]; snprintf(temp, 255, "%+d", v); return temp; }
template<> inline const char* to_string<unsigned int> (unsigned int v) { static char temp[256]; snprintf(temp, 255, "%u", v); return temp; }
template<> inline const char* to_string<intmax_t> (intmax_t v) { static char temp[256]; snprintf(temp, 255, "%+lld", (long long)v); return temp; }
template<> inline const char* to_string<uintmax_t> (uintmax_t v) { static char temp[256]; snprintf(temp, 255, "%llu", (unsigned long long)v); return temp; }
template<> inline const char* to_string<double> (double v) { static char temp[256]; snprintf(temp, 255, "%f", v); return temp; }
template<> inline const char* to_string<char*> (char *v) { return v; }
template<> inline const char* to_string<const char*> (const char *v) { return v; }
template<> inline const char* to_string<string> (string v) { return v; }
template<> inline const char* to_string<const string&>(const string &v) { return v; }
template<> inline const char* to_string<bool> (bool v) { return v ? "true" : "false"; }
template<> inline const char* to_string<signed int> (signed int v) { static char temp[256]; snprintf(temp, 255, "%+d", v); return temp; }
template<> inline const char* to_string<unsigned int> (unsigned int v) { static char temp[256]; snprintf(temp, 255, "%u", v); return temp; }
template<> inline const char* to_string<intmax_t> (intmax_t v) { static char temp[256]; snprintf(temp, 255, "%+lld", (long long)v); return temp; }
template<> inline const char* to_string<uintmax_t> (uintmax_t v) { static char temp[256]; snprintf(temp, 255, "%llu", (unsigned long long)v); return temp; }
template<> inline const char* to_string<double> (double v) { static char temp[256]; snprintf(temp, 255, "%f", v); return temp; }
template<> inline const char* to_string<char*> (char *v) { return v; }
template<> inline const char* to_string<const char*> (const char *v) { return v; }
template<> inline const char* to_string<string> (string v) { return v; }
template<> inline const char* to_string<const string&> (const string &v) { return v; }
template<> inline const char* to_string<cstring> (cstring v) { return v; }
template<> inline const char* to_string<const cstring&>(const cstring &v) { return v; }
template<typename T> lstring& lstring::operator<<(T value) {
operator[](size()).assign(to_string<T>(value));

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_COMPARE_HPP
#define NALL_STRING_COMPARE_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_CONVERT_HPP
#define NALL_STRING_CONVERT_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_CORE_HPP
#define NALL_STRING_CORE_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

21
bsnes/nall/string/cstring.hpp Executable file
View File

@ -0,0 +1,21 @@
#ifdef NALL_STRING_INTERNAL_HPP
//const string:
//bind a const char* pointer to an object that has various testing functionality;
//yet lacks the memory allocation and modification functionality of the string class
namespace nall {
cstring::operator const char*() const { return data; }
unsigned cstring::length() const { return strlen(data); }
bool cstring::operator==(const char *s) const { return !strcmp(data, s); }
bool cstring::operator!=(const char *s) const { return strcmp(data, s); }
optional<unsigned> cstring::position (const char *key) const { return strpos(data, key); }
optional<unsigned> cstring::iposition(const char *key) const { return istrpos(data, key); }
cstring& cstring::operator=(const char *data) { this->data = data; return *this; }
cstring::cstring(const char *data) : data(data) {}
cstring::cstring() : data("") {}
}
#endif

View File

@ -1,5 +1,4 @@
#ifndef NALL_FILENAME_HPP
#define NALL_FILENAME_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_MATH_HPP
#define NALL_STRING_MATH_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_PLATFORM_HPP
#define NALL_STRING_PLATFORM_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_REPLACE_HPP
#define NALL_STRING_REPLACE_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_SPLIT_HPP
#define NALL_STRING_SPLIT_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_STRL_HPP
#define NALL_STRING_STRL_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_STRPOS_HPP
#define NALL_STRING_STRPOS_HPP
#ifdef NALL_STRING_INTERNAL_HPP
//usage example:
//if(auto position = strpos(str, key)) print(position(), "\n");

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_TRIM_HPP
#define NALL_STRING_TRIM_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_UTILITY_HPP
#define NALL_STRING_UTILITY_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_VARIADIC_HPP
#define NALL_STRING_VARIADIC_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,5 +1,4 @@
#ifndef NALL_STRING_WRAPPER_HPP
#define NALL_STRING_WRAPPER_HPP
#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {

View File

@ -1,8 +1,7 @@
#ifndef NALL_STRING_XML_HPP
#define NALL_STRING_XML_HPP
#ifdef NALL_STRING_INTERNAL_HPP
//XML subset parser
//version 0.05
//XML v1.0 subset parser
//revision 0.05
namespace nall {

View File

@ -1,11 +1,13 @@
#include "axrom.cpp"
#include "cnrom.cpp"
#include "nrom.cpp"
#include "sxrom.cpp"
#include "txrom.cpp"
#include "uxrom.cpp"
#include "bandai-fcg.cpp"
#include "konami-vrc6.cpp"
#include "nes-axrom.cpp"
#include "nes-bnrom.cpp"
#include "nes-cnrom.cpp"
#include "nes-gxrom.cpp"
#include "nes-nrom.cpp"
#include "nes-sxrom.cpp"
#include "nes-txrom.cpp"
#include "nes-uxrom.cpp"
unsigned Board::mirror(unsigned addr, unsigned size) const {
unsigned base = 0;
@ -75,13 +77,13 @@ void Board::serialize(serializer &s) {
}
Board::Board(BML::Node &board, const uint8_t *data, unsigned size) {
information.type = board["type"].value();
information.battery = board["prg"]["battery"].value();
information.type = board["type"].value;
information.battery = board["prg"]["battery"].value;
prgrom.size = decimal(board["prg"]["rom"].value());
prgram.size = decimal(board["prg"]["ram"].value());
chrrom.size = decimal(board["chr"]["rom"].value());
chrram.size = decimal(board["chr"]["ram"].value());
prgrom.size = decimal(board["prg"]["rom"].value);
prgram.size = decimal(board["prg"]["ram"].value);
chrrom.size = decimal(board["chr"]["rom"].value);
chrram.size = decimal(board["chr"]["ram"].value);
if(prgrom.size) prgrom.data = new uint8[prgrom.size]();
if(prgram.size) prgram.data = new uint8[prgram.size]();
@ -102,23 +104,34 @@ Board::~Board() {
Board* Board::load(const string &markup, const uint8_t *data, unsigned size) {
BML::Node document(markup);
auto &board = document["cartridge"]["board"];
string type = board["type"].value();
if(type == "NES-AMROM" ) return new AxROM(board, data, size);
if(type == "NES-ANROM" ) return new AxROM(board, data, size);
if(type == "NES-AN1ROM" ) return new AxROM(board, data, size);
if(type == "NES-AOROM" ) return new AxROM(board, data, size);
if(type == "NES-CNROM" ) return new CNROM(board, data, size);
if(type == "NES-NROM-256") return new NROM (board, data, size);
if(type == "NES-UNROM" ) return new UxROM(board, data, size);
if(type == "NES-SNROM" ) return new SxROM(board, data, size);
if(type == "NES-SXROM" ) return new SxROM(board, data, size);
if(type == "NES-TLROM" ) return new TxROM(board, data, size);
if(type == "NES-UOROM" ) return new UxROM(board, data, size);
string type = board["type"].value;
if(type == "BANDAI-FCG") return new BandaiFCG(board, data, size);
if(type == "KONAMI-VRC-6") return new KonamiVRC6(board, data, size);
if(type == "NES-AMROM" ) return new NES_AxROM(board, data, size);
if(type == "NES-ANROM" ) return new NES_AxROM(board, data, size);
if(type == "NES-AN1ROM" ) return new NES_AxROM(board, data, size);
if(type == "NES-AOROM" ) return new NES_AxROM(board, data, size);
if(type == "NES-BNROM" ) return new NES_BNROM(board, data, size);
if(type == "NES-CNROM" ) return new NES_CNROM(board, data, size);
if(type == "NES-GNROM" ) return new NES_GxROM(board, data, size);
if(type == "NES-MHROM" ) return new NES_GxROM(board, data, size);
if(type == "NES-NROM-128") return new NES_NROM(board, data, size);
if(type == "NES-NROM-256") return new NES_NROM(board, data, size);
if(type == "NES-SNROM" ) return new NES_SxROM(board, data, size);
if(type == "NES-SXROM" ) return new NES_SxROM(board, data, size);
if(type == "NES-TLROM" ) return new NES_TxROM(board, data, size);
if(type == "NES-UNROM" ) return new NES_UxROM(board, data, size);
if(type == "NES-UOROM" ) return new NES_UxROM(board, data, size);
return nullptr;
}

View File

@ -3,7 +3,7 @@
//NES-AN1ROM
//NES-AOROM
struct AxROM : Board {
struct NES_AxROM : Board {
uint4 prg_bank;
bool mirror_select;
@ -46,7 +46,7 @@ void serialize(serializer &s) {
s.integer(mirror_select);
}
AxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) {
NES_AxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) {
}
};

View File

@ -0,0 +1,53 @@
//NES-BN-ROM-01
struct NES_BNROM : Board {
struct Settings {
bool mirror; //0 = horizontal, 1 = vertical
} settings;
uint2 prg_bank;
uint8 prg_read(unsigned addr) {
if(addr & 0x8000) return Board::prg_read((prg_bank << 15) | (addr & 0x7fff));
return cpu.mdr();
}
void prg_write(unsigned addr, uint8 data) {
if(addr & 0x8000) prg_bank = data & 0x03;
}
uint8 chr_read(unsigned addr) {
if(addr & 0x2000) {
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
return ppu.ciram_read(addr);
}
return Board::chr_read(addr);
}
void chr_write(unsigned addr, uint8 data) {
if(addr & 0x2000) {
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
return ppu.ciram_write(addr, data);
}
return Board::chr_write(addr, data);
}
void power() {
reset();
}
void reset() {
prg_bank = 0;
}
void serialize(serializer &s) {
Board::serialize(s);
s.integer(prg_bank);
}
NES_BNROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) {
settings.mirror = board["mirror"].value == "vertical" ? 1 : 0;
}
};

View File

@ -1,6 +1,6 @@
//NES-CNROM
struct CNROM : Board {
struct NES_CNROM : Board {
struct Settings {
bool mirror; //0 = horizontal, 1 = vertical
@ -49,8 +49,8 @@ void serialize(serializer &s) {
s.integer(chr_bank);
}
CNROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) {
settings.mirror = board["mirror"].value() == "vertical" ? 1 : 0;
NES_CNROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) {
settings.mirror = board["mirror"].value == "vertical" ? 1 : 0;
}
};

View File

@ -0,0 +1,62 @@
//NES-GNROM
//NES-MHROM
struct NES_GxROM : Board {
struct Settings {
bool mirror; //0 = horizontal, 1 = vertical
} settings;
uint2 prg_bank;
uint2 chr_bank;
uint8 prg_read(unsigned addr) {
if(addr & 0x8000) return Board::prg_read((prg_bank << 15) | (addr & 0x7fff));
return cpu.mdr();
}
void prg_write(unsigned addr, uint8 data) {
if(addr & 0x8000) {
prg_bank = (data & 0x30) >> 4;
chr_bank = (data & 0x03) >> 0;
}
}
uint8 chr_read(unsigned addr) {
if(addr & 0x2000) {
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
return ppu.ciram_read(addr & 0x07ff);
}
addr = (chr_bank * 0x2000) + (addr & 0x1fff);
return Board::chr_read(addr);
}
void chr_write(unsigned addr, uint8 data) {
if(addr & 0x2000) {
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
return ppu.ciram_write(addr & 0x07ff, data);
}
addr = (chr_bank * 0x2000) + (addr & 0x1fff);
Board::chr_write(addr, data);
}
void power() {
reset();
}
void reset() {
prg_bank = 0;
chr_bank = 0;
}
void serialize(serializer &s) {
Board::serialize(s);
s.integer(prg_bank);
s.integer(chr_bank);
}
NES_GxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) {
settings.mirror = board["mirror"].value == "vertical" ? 1 : 0;
}
};

View File

@ -1,7 +1,7 @@
//NES-NROM-128
//NES-NROM-256
struct NROM : Board {
struct NES_NROM : Board {
struct Settings {
bool mirror; //0 = horizontal, 1 = vertical
@ -35,8 +35,8 @@ void serialize(serializer &s) {
Board::serialize(s);
}
NROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) {
settings.mirror = board["mirror"].value() == "vertical" ? 1 : 0;
NES_NROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) {
settings.mirror = board["mirror"].value == "vertical" ? 1 : 0;
}
};

View File

@ -1,4 +1,4 @@
struct SxROM : Board {
struct NES_SxROM : Board {
enum class Revision : unsigned {
SAROM,
@ -138,7 +138,7 @@ void serialize(serializer &s) {
s.integer(shiftdata);
}
SxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), mmc1(*this) {
NES_SxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), mmc1(*this) {
revision = Revision::SXROM;
shiftaddr = 0;

View File

@ -1,4 +1,4 @@
struct TxROM : Board {
struct NES_TxROM : Board {
enum class Revision : unsigned {
TBROM,
@ -110,7 +110,7 @@ void serialize(serializer &s) {
mmc3.serialize(s);
}
TxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), mmc3(*this) {
NES_TxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), mmc3(*this) {
revision = Revision::TLROM;
}

View File

@ -1,7 +1,7 @@
//NES-UNROM
//NES-UOROM
struct UxROM : Board {
struct NES_UxROM : Board {
struct Settings {
bool mirror; //0 = horizontal, 1 = vertical
@ -49,8 +49,8 @@ void serialize(serializer &s) {
s.integer(prg_bank);
}
UxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) {
settings.mirror = board["mirror"].value() == "vertical" ? 1 : 0;
NES_UxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) {
settings.mirror = board["mirror"].value == "vertical" ? 1 : 0;
}
};

View File

@ -23,6 +23,7 @@ void Cartridge::load(const string &markup, const uint8_t *data, unsigned size) {
sha256 = nall::sha256(data + 16, size - 16);
board = Board::load(markup != "" ? markup : iNES(data, size), data + 16, size - 16);
}
if(board == nullptr) return;
system.load();
loaded = true;

View File

@ -20,55 +20,65 @@ static string iNES(const uint8_t *data, unsigned size) {
switch(mapper) {
default:
output.append(" board type=NES-NROM-256\n");
output.append(" mirror=", mirror == 0 ? "horizontal" : "vertical", "\n");
output.append("\tboard type{NES-NROM-256}\n");
output.append("\t\tmirror{", mirror == 0 ? "horizontal" : "vertical", "}\n");
break;
case 1:
output.append(" board type=NES-SXROM\n");
output.append(" chip type=MMC1B2\n");
output.append("\tboard type{NES-SXROM}\n");
output.append("\t\tchip type{MMC1B2}\n");
prgram = 8192;
break;
case 2:
output.append(" board type=NES-UOROM\n");
output.append(" mirror=", mirror == 0 ? "horizontal" : "vertical", "\n");
output.append("\tboard type{NES-UOROM}\n");
output.append("\t\tmirror{", mirror == 0 ? "horizontal" : "vertical", "}\n");
break;
case 3:
output.append(" board type=NES-CNROM\n");
output.append(" mirror=", mirror == 0 ? "horizontal" : "vertical", "\n");
output.append("\tboard type{NES-CNROM}\n");
output.append("\t\tmirror{", mirror == 0 ? "horizontal" : "vertical", "}\n");
break;
case 4:
output.append(" board type=NES-TLROM\n");
output.append(" chip type=MMC3B\n");
output.append("\tboard type{NES-TLROM}\n");
output.append("\t\tchip type{MMC3B}\n");
prgram = 8192;
break;
case 7:
output.append(" board type=NES-AOROM\n");
output.append("\tboard type{NES-AOROM}\n");
break;
case 16:
output.append(" board type=BANDAI-FCG\n");
output.append(" chip type=LZ93D50 manufacturer=Sharp\n");
output.append("\tboard type{BANDAI-FCG}\n");
output.append("\t\tchip type{LZ93D50}\n");
break;
case 24:
output.append(" board type=KONAMI-VRC-6\n");
output.append(" chip type=VRC6\n");
case 24:
output.append("\tboard type{KONAMI-VRC-6}\n");
output.append("\t\tchip type{VRC6}\n");
break;
case 26:
output.append(" board type=KONAMI-VRC-6\n");
output.append(" chip type=VRC6\n");
case 26:
output.append("\tboard type{KONAMI-VRC-6}\n");
output.append("\t\tchip type{VRC6}\n");
prgram = 8192;
break;
case 34:
output.append("\tboard type{NES-BNROM}\n");
output.append("\t\tmirror{", mirror == 0 ? "horizontal" : "vertical", "}\n");
break;
case 66:
output.append("\tboard type{NES-GNROM}\n");
output.append("\t\tmirror{", mirror == 0 ? "horizontal" : "vertical", "}\n");
break;
}
output.append(" prg rom=", prgrom, " ram=", prgram, "\n");
output.append(" chr rom=", chrrom, " ram=", chrram, "\n");
output.append("\t\tprg rom{", prgrom, "} ram{", prgram, "}\n");
output.append("\t\tchr rom{", chrrom, "} ram{", chrram, "}\n");
print(output, "\n");

View File

@ -49,7 +49,7 @@ Application::Application(int argc, char **argv) {
inputManager = new InputManager;
utility = new Utility;
title = "bsnes v082.27";
title = "bsnes v082.28";
string fontFamily = Intrinsics::platform() == Intrinsics::Platform::Windows ? "Tahoma, " : "Sans, ";
normalFont = { fontFamily, "8" };

View File

@ -131,10 +131,10 @@ bool CheatEditor::load(const string &filename) {
unsigned n = 0;
BML::Node document(data);
for(auto &cheat : document["cartridge"]) {
if(cheat.name() != "cheat") continue;
if(cheat.name != "cheat") continue;
cheatList.setChecked(n, cheat["enable"].exists());
cheatText[n][Code] = cheat["code"].value();
cheatText[n][Desc] = cheat["description"].value();
cheatText[n][Code] = cheat["code"].value;
cheatText[n][Desc] = cheat["description"].value;
if(++n >= 128) break;
}
@ -161,11 +161,11 @@ bool CheatEditor::save(const string &filename) {
file fp;
if(fp.open(filename, file::mode::write) == false) return false;
fp.print("cartridge sha256=`", interface->sha256(), "`\n");
fp.print("cartridge sha256{", interface->sha256(), "}\n");
for(unsigned n = 0; n <= lastSave; n++) {
fp.print(" cheat", cheatList.checked(n) ? " enable" : "", "\n");
fp.print(" description=`", string{cheatText[n][Desc]}.transform("`", "'"), "`\n");
fp.print(" code=`", string{cheatText[n][Code]}.transform("`", "'"), "`\n");
fp.print("\tcheat", cheatList.checked(n) ? " enable" : "", "\n");
fp.print("\t\tdescription{", BML::encode(cheatText[n][Desc]), "}\n");
fp.print("\t\tcode{", BML::encode(cheatText[n][Code]), "}\n");
}
fp.close();