summaryrefslogtreecommitdiffstatshomepage
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/castool.cpp5
-rw-r--r--src/tools/floptool.cpp12
-rw-r--r--src/tools/imgtool/imgtool.cpp79
-rw-r--r--src/tools/imgtool/library.cpp120
-rw-r--r--src/tools/imgtool/library.h71
-rw-r--r--src/tools/imgtool/main.cpp8
-rw-r--r--src/tools/imgtool/modules/amiga.cpp31
-rw-r--r--src/tools/imgtool/modules/cybiko.cpp16
-rw-r--r--src/tools/imgtool/modules/cybikoxt.cpp17
-rw-r--r--src/tools/imgtool/modules/fat.cpp36
-rw-r--r--src/tools/imgtool/modules/mac.cpp4
-rw-r--r--src/tools/imgtool/modules/macbin.cpp4
-rw-r--r--src/tools/imgtool/modules/macutil.cpp40
-rw-r--r--src/tools/imgtool/modules/macutil.h3
-rw-r--r--src/tools/imgtool/modules/prodos.cpp35
-rw-r--r--src/tools/imgtool/modules/thomson.cpp24
-rw-r--r--src/tools/unidasm.cpp1667
17 files changed, 1487 insertions, 685 deletions
diff --git a/src/tools/castool.cpp b/src/tools/castool.cpp
index 8fc9d3bd911..bba809cd88d 100644
--- a/src/tools/castool.cpp
+++ b/src/tools/castool.cpp
@@ -23,6 +23,7 @@
#include "formats/ace_tap.h"
#include "formats/adam_cas.h"
#include "formats/apf_apt.h"
+#include "formats/atom_tap.h"
#include "formats/cbm_tap.h"
#include "formats/cgen_cas.h"
#include "formats/coco_cas.h"
@@ -69,6 +70,7 @@ struct SupportedCassetteFormats
const struct SupportedCassetteFormats formats[] = {
{"a26", a26_cassette_formats ,"Atari 2600 SuperCharger"},
{"apf", apf_cassette_formats ,"APF Imagination Machine"},
+ {"atom", atom_cassette_formats ,"Acorn Atom"},
{"bbc", bbc_cassette_formats ,"Acorn BBC & Electron"},
{"cbm", cbm_cassette_formats ,"Commodore 8-bit series"},
{"cdt", cdt_cassette_formats ,"Amstrad CPC"},
@@ -110,7 +112,6 @@ const struct SupportedCassetteFormats formats[] = {
{"trs80l2", trs80l2_cassette_formats ,"TRS-80 Level 2"},
{"tvc64", tvc64_cassette_formats ,"Videoton TVC 64"},
{"tzx", tzx_cassette_formats ,"Sinclair ZX Spectrum"},
- {"uef", uef_cassette_formats ,"Acorn Electron"},
{"vg5k", vg5k_cassette_formats ,"Philips VG 5000"},
{"vtech1", vtech1_cassette_formats ,"Video Technology Laser 110-310"},
{"vtech2", vtech2_cassette_formats ,"Video Technology Laser 350-700"},
@@ -205,7 +206,7 @@ int CLIB_DECL main(int argc, char *argv[])
}
/* Usage */
- fprintf(stderr, "castool - Generic cassette manipulation tool for use with MESS\n\n");
+ fprintf(stderr, "castool - Generic cassette manipulation tool for use with MAME\n\n");
display_usage();
fprintf(stderr, "\n");
display_formats();
diff --git a/src/tools/floptool.cpp b/src/tools/floptool.cpp
index 6e7ee709e5f..aea7dd9576a 100644
--- a/src/tools/floptool.cpp
+++ b/src/tools/floptool.cpp
@@ -42,6 +42,9 @@
#include "formats/ap_dsk35.h"
#include "formats/ap2_dsk.h"
+#include "formats/atom_dsk.h"
+#include "formats/acorn_dsk.h"
+
#include "formats/oric_dsk.h"
#include "formats/applix_dsk.h"
@@ -74,6 +77,13 @@ static floppy_format_type floppy_formats[] = {
FLOPPY_RWTS18_FORMAT,
FLOPPY_EDD_FORMAT,
+ FLOPPY_ATOM_FORMAT,
+ FLOPPY_ACORN_SSD_FORMAT,
+ FLOPPY_ACORN_DSD_FORMAT,
+ FLOPPY_ACORN_DOS_FORMAT,
+ FLOPPY_ACORN_ADFS_OLD_FORMAT,
+ FLOPPY_ACORN_ADFS_NEW_FORMAT,
+
FLOPPY_ORIC_DSK_FORMAT,
FLOPPY_APPLIX_FORMAT,
@@ -143,7 +153,7 @@ static void display_formats()
static void display_full_usage()
{
/* Usage */
- fprintf(stderr, "floptool - Generic floppy image manipulation tool for use with MESS\n\n");
+ fprintf(stderr, "floptool - Generic floppy image manipulation tool for use with MAME\n\n");
display_usage();
fprintf(stderr, "\n");
display_formats();
diff --git a/src/tools/imgtool/imgtool.cpp b/src/tools/imgtool/imgtool.cpp
index 52d4b23c759..67283ce8fa3 100644
--- a/src/tools/imgtool/imgtool.cpp
+++ b/src/tools/imgtool/imgtool.cpp
@@ -753,6 +753,77 @@ void imgtool::partition::get_attribute_name(uint32_t attribute, const imgtool_at
//-------------------------------------------------
+// test_imgtool_datetime - unit test for imgtool::datetime
+//-------------------------------------------------
+
+static bool test_imgtool_datetime(int second, int minute, int hour, int day_of_month, int month, int year)
+{
+ bool error = false;
+
+ util::arbitrary_datetime t;
+ t.second = second;
+ t.minute = minute;
+ t.hour = hour;
+ t.day_of_month = day_of_month;
+ t.month = month;
+ t.year = year;
+
+ imgtool::datetime dt(imgtool::datetime::datetime_type::GMT, t);
+ std::tm t2 = dt.gmtime();
+
+ if (t2.tm_sec != second)
+ {
+ util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_sec to be %d, instead got %d\n", second, t2.tm_sec);
+ error = true;
+ }
+ if (t2.tm_min != minute)
+ {
+ util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_min to be %d, instead got %d\n", minute, t2.tm_min);
+ error = true;
+ }
+ if (t2.tm_hour != hour)
+ {
+ util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_hour to be %d, instead got %d\n", hour, t2.tm_hour);
+ error = true;
+ }
+ if (t2.tm_mday != day_of_month)
+ {
+ util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_mday to be %d, instead got %d\n", day_of_month, t2.tm_mday);
+ error = true;
+ }
+ if (t2.tm_mon != month - 1)
+ {
+ util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_mon to be %d, instead got %d\n", month - 1, t2.tm_mon);
+ error = true;
+ }
+ if (t2.tm_year != year - 1900)
+ {
+ util::stream_format(std::wcerr, L"test_imgtool_datetime(): Expected t2.tm_mon to be %d, instead got %d\n", year - 1900, t2.tm_year);
+ error = true;
+ }
+ return error;
+}
+
+
+//-------------------------------------------------
+// test_imgtool_datetime - unit tests for imgtool::datetime
+//-------------------------------------------------
+
+static bool test_imgtool_datetime()
+{
+ bool error = false;
+
+ // various test cases for imgtool::datetime
+ if (test_imgtool_datetime(34, 23, 12, 18, 3, 1993)) // March 18th, 1993 12:23:34
+ error = true;
+ if (test_imgtool_datetime(0, 20, 16, 25, 12, 1976)) // December 25th, 1976 16:20:00
+ error = true;
+
+ return error;
+}
+
+
+//-------------------------------------------------
// imgtool_validitychecks - checks the validity
// of the imgtool modules
//-------------------------------------------------
@@ -764,6 +835,10 @@ bool imgtool_validitychecks(void)
imgtool_module_features features;
int created_library = false;
+ // various test cases for imgtool::datetime
+ if (test_imgtool_datetime())
+ error = true;
+
if (!global_imgtool_library)
{
imgtool_init(false, nullptr);
@@ -2290,12 +2365,12 @@ imgtoolerr_t imgtool::directory::get_next(imgtool_dirent &ent)
}
// don't trust the module!
- if (!m_partition.m_supports_creation_time && (ent.creation_time != 0))
+ if (!m_partition.m_supports_creation_time && (ent.creation_time.type() != imgtool::datetime::datetime_type::NONE))
{
internal_error(nullptr, "next_enum() specified creation_time, which is marked as unsupported by this module");
return IMGTOOLERR_UNEXPECTED;
}
- if (!m_partition.m_supports_lastmodified_time && (ent.lastmodified_time != 0))
+ if (!m_partition.m_supports_lastmodified_time && (ent.lastmodified_time.type() != imgtool::datetime::datetime_type::NONE))
{
internal_error(nullptr, "next_enum() specified lastmodified_time, which is marked as unsupported by this module");
return IMGTOOLERR_UNEXPECTED;
diff --git a/src/tools/imgtool/library.cpp b/src/tools/imgtool/library.cpp
index 9b04eecb03a..785054575b0 100644
--- a/src/tools/imgtool/library.cpp
+++ b/src/tools/imgtool/library.cpp
@@ -18,6 +18,126 @@
namespace imgtool {
+datetime::imgtool_clock::duration datetime::s_gmt_offset = datetime::calculate_gmt_offset();
+
+//-------------------------------------------------
+// datetime ctor
+//-------------------------------------------------
+
+datetime::datetime(datetime_type type, std::chrono::time_point<std::chrono::system_clock> tp)
+ : m_type(type)
+ , m_time_point(imgtool_clock::from_system_clock(tp))
+{
+}
+
+
+//-------------------------------------------------
+// datetime ctor
+//-------------------------------------------------
+
+datetime::datetime(datetime_type type, time_t t)
+ : datetime(type, std::chrono::system_clock::from_time_t(t))
+{
+}
+
+
+//-------------------------------------------------
+// datetime ctor
+//-------------------------------------------------
+
+datetime::datetime(datetime_type type, const util::arbitrary_datetime &dt, bool clamp)
+ : m_type(type)
+ , m_time_point(imgtool_clock::from_arbitrary_datetime(dt, clamp))
+{
+}
+
+
+//-------------------------------------------------
+// datetime::now
+//-------------------------------------------------
+
+datetime datetime::now(datetime_type type)
+{
+ return imgtool::datetime(
+ type,
+ std::chrono::system_clock::now());
+}
+
+
+//-------------------------------------------------
+// datetime::localtime
+//-------------------------------------------------
+
+std::tm datetime::localtime() const
+{
+ imgtool_clock::time_point tp;
+
+ switch (type())
+ {
+ case datetime_type::LOCAL:
+ tp = time_point();
+ break;
+ case datetime_type::GMT:
+ tp = time_point() + s_gmt_offset;
+ break;
+ default:
+ tp = imgtool_clock::time_point();
+ break;
+ }
+ return imgtool_clock::to_tm(tp);
+}
+
+
+//-------------------------------------------------
+// datetime::gmtime
+//-------------------------------------------------
+
+std::tm datetime::gmtime() const
+{
+ imgtool_clock::time_point tp;
+
+ switch (type())
+ {
+ case datetime_type::GMT:
+ tp = time_point();
+ break;
+ case datetime_type::LOCAL:
+ tp = time_point() - s_gmt_offset;
+ break;
+ default:
+ tp = imgtool_clock::time_point();
+ break;
+ }
+ return imgtool_clock::to_tm(tp);
+}
+
+
+//-------------------------------------------------
+// datetime::calculate_gmt_offset
+//-------------------------------------------------
+
+datetime::imgtool_clock::duration datetime::calculate_gmt_offset()
+{
+ time_t t = time(nullptr);
+ std::tm utc_tm = *std::gmtime(&t);
+ time_t utc = mktime(&utc_tm);
+ std::tm local_tm = *std::localtime(&t);
+ time_t local = mktime(&local_tm);
+ double d = difftime(local, utc) * imgtool_clock::period::den / imgtool_clock::period::num;
+ return imgtool_clock::duration((std::int64_t) d);
+}
+
+
+//-------------------------------------------------
+// datetime::to_time_t
+//-------------------------------------------------
+
+time_t datetime::to_time_t() const
+{
+ auto system_clock_tp = imgtool_clock::to_system_clock(time_point());
+ return std::chrono::system_clock::to_time_t(system_clock_tp);
+}
+
//-------------------------------------------------
// ctor
diff --git a/src/tools/imgtool/library.h b/src/tools/imgtool/library.h
index ec508bcbd0e..c709a70201b 100644
--- a/src/tools/imgtool/library.h
+++ b/src/tools/imgtool/library.h
@@ -19,6 +19,7 @@
#include <time.h>
#include <list>
+#include <chrono>
#include "corestr.h"
#include "opresolv.h"
@@ -26,6 +27,7 @@
#include "unicode.h"
#include "charconv.h"
#include "pool.h"
+#include "timeconv.h"
namespace imgtool
{
@@ -55,15 +57,78 @@ union filterinfo
typedef void (*filter_getinfoproc)(uint32_t state, union filterinfo *info);
+namespace imgtool
+{
+ class datetime
+ {
+ public:
+ typedef util::arbitrary_clock<std::int64_t, 1600, 1, 1, 0, 0, 0, std::ratio<1, 10000000> > imgtool_clock;
+
+ enum datetime_type
+ {
+ NONE,
+ LOCAL,
+ GMT
+ };
+
+ datetime()
+ : m_type(datetime_type::NONE)
+ {
+ }
+
+
+ template<typename Rep, int Y, int M, int D, int H, int N, int S, typename Ratio>
+ datetime(datetime_type type, std::chrono::time_point<util::arbitrary_clock<Rep, Y, M, D, H, N, S, Ratio> > tp)
+ : m_type(type)
+ , m_time_point(imgtool_clock::from_arbitrary_time_point(tp))
+ {
+ }
+
+ datetime(datetime_type type, std::chrono::time_point<std::chrono::system_clock> tp);
+ datetime(datetime_type type, time_t t);
+ datetime(datetime_type type, const util::arbitrary_datetime &dt, bool clamp = true);
+ datetime(const datetime &that) = default;
+ datetime(datetime &&that) = default;
+
+ // accessors
+ datetime_type type() const { return m_type; }
+ bool empty() const { return type() == datetime_type::NONE; }
+ std::chrono::time_point<imgtool_clock> time_point() const { return m_time_point; }
+
+ // operators
+ datetime &operator =(const datetime &that)
+ {
+ m_type = that.m_type;
+ m_time_point = that.m_time_point;
+ return *this;
+ }
+
+ // returns the current time
+ static datetime now(datetime_type type);
+
+ // returns time structures
+ std::tm localtime() const;
+ std::tm gmtime() const;
+ time_t to_time_t() const;
+
+ private:
+ static imgtool_clock::duration s_gmt_offset;
+ datetime_type m_type;
+ std::chrono::time_point<imgtool_clock> m_time_point;
+
+ static imgtool_clock::duration calculate_gmt_offset();
+ };
+};
+
struct imgtool_dirent
{
char filename[1024];
char attr[64];
uint64_t filesize;
- time_t creation_time;
- time_t lastmodified_time;
- time_t lastaccess_time;
+ imgtool::datetime creation_time;
+ imgtool::datetime lastmodified_time;
+ imgtool::datetime lastaccess_time;
char softlink[1024];
char comment[256];
diff --git a/src/tools/imgtool/main.cpp b/src/tools/imgtool/main.cpp
index ee3f603dc6f..50c65845ddb 100644
--- a/src/tools/imgtool/main.cpp
+++ b/src/tools/imgtool/main.cpp
@@ -234,9 +234,11 @@ static int cmd_dir(const struct command *c, int argc, char *argv[])
? "<DIR>"
: string_format("%u", (unsigned int) ent.filesize);
- if (ent.lastmodified_time != 0)
- strftime(last_modified, sizeof(last_modified), "%d-%b-%y %H:%M:%S",
- localtime(&ent.lastmodified_time));
+ if (!ent.lastmodified_time.empty())
+ {
+ std::tm t = ent.lastmodified_time.localtime();
+ strftime(last_modified, sizeof(last_modified), "%d-%b-%y %H:%M:%S", &t);
+ }
if (ent.hardlink)
strcat(ent.filename, " <hl>");
diff --git a/src/tools/imgtool/modules/amiga.cpp b/src/tools/imgtool/modules/amiga.cpp
index 7a7a3572320..c1c5563012e 100644
--- a/src/tools/imgtool/modules/amiga.cpp
+++ b/src/tools/imgtool/modules/amiga.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Dirk Best
/****************************************************************************
- amiga.c
+ amiga.cpp
Amiga floppies
@@ -290,15 +290,11 @@ static int is_leap(int year)
/* Convert amiga time to standard time */
-static time_t amiga_crack_time(amiga_date *date)
+static imgtool::datetime amiga_crack_time(amiga_date *date)
{
int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int year = 1978, month = 1, year_days = 365; /* base date */
int day = date->days;
- struct tm t;
-
- /* initialize struct */
- memset(&t, 0, sizeof(t));
/* first calculate the year */
while (day >= year_days)
@@ -316,15 +312,16 @@ static time_t amiga_crack_time(amiga_date *date)
month++;
}
- /* fill the struct with our calculated values */
- t.tm_year = year - 1900;
- t.tm_mon = month - 1;
- t.tm_mday = day + 1;
- t.tm_hour = date->mins / 60;
- t.tm_min = date->mins % 60;
- t.tm_sec = date->ticks / 50;
+ // fill the struct with our calculated values
+ util::arbitrary_datetime dt;
+ dt.year = year;
+ dt.month = month;
+ dt.day_of_month = day;
+ dt.hour = date->mins / 60;
+ dt.minute = date->mins % 60;
+ dt.second = date->ticks / 50;
- return mktime(&t);
+ return imgtool::datetime(imgtool::datetime::datetime_type::LOCAL, dt);
}
@@ -1785,9 +1782,9 @@ static void amiga_image_info(imgtool::image &img, std::ostream &stream)
ret = read_root_block(img, &root);
if (ret) return;
- t_c = amiga_crack_time(&root.c);
- t_v = amiga_crack_time(&root.v);
- t_r = amiga_crack_time(&root.r);
+ t_c = amiga_crack_time(&root.c).to_time_t();
+ t_v = amiga_crack_time(&root.v).to_time_t();
+ t_r = amiga_crack_time(&root.r).to_time_t();
strftime(c, sizeof(c), "%d-%b-%y %H:%M:%S", localtime(&t_c));
strftime(v, sizeof(v), "%d-%b-%y %H:%M:%S", localtime(&t_v));
diff --git a/src/tools/imgtool/modules/cybiko.cpp b/src/tools/imgtool/modules/cybiko.cpp
index 81184533291..4ba278ddd2b 100644
--- a/src/tools/imgtool/modules/cybiko.cpp
+++ b/src/tools/imgtool/modules/cybiko.cpp
@@ -64,15 +64,19 @@ static cybiko_file_system *get_cfs(imgtool::image &image)
}
// 2208988800 is the number of seconds between 1900/01/01 and 1970/01/01
+typedef util::arbitrary_clock<std::uint32_t, 1900, 1, 1, 0, 0, 0, std::ratio<1, 1> > cybiko_clock;
-static time_t time_crack( uint32_t cfs_time)
+imgtool::datetime cybiko_time_crack(uint32_t cfs_time)
{
- return (time_t)(cfs_time - 2208988800UL);
+ cybiko_clock::duration d(cfs_time);
+ std::chrono::time_point<cybiko_clock> tp(d);
+ return imgtool::datetime(imgtool::datetime::datetime_type::LOCAL, tp);
}
-static uint32_t time_setup( time_t ansi_time)
+uint32_t cybiko_time_setup(const imgtool::datetime &t)
{
- return (uint32_t)(ansi_time + 2208988800UL);
+ auto cybiko_time_point = cybiko_clock::from_arbitrary_time_point(t.time_point());
+ return cybiko_time_point.time_since_epoch().count();
}
static uint32_t buffer_read_32_be( uint8_t *buffer)
@@ -412,7 +416,7 @@ static imgtoolerr_t cybiko_image_next_enum(imgtool::directory &enumeration, imgt
{
strcpy(ent.filename, file.name);
ent.filesize = file.size;
- ent.lastmodified_time = time_crack(file.date);
+ ent.lastmodified_time = cybiko_time_crack(file.date);
ent.filesize = file.size;
}
else
@@ -501,7 +505,7 @@ static imgtoolerr_t cybiko_image_write_file(imgtool::partition &partition, const
{
buffer[6] = 0;
strcpy(BLOCK_FILENAME(buffer), filename);
- buffer_write_32_be( buffer + 6 + FILE_HEADER_SIZE - 4, time_setup( time( NULL)));
+ buffer_write_32_be(buffer + 6 + FILE_HEADER_SIZE - 4, cybiko_time_setup(imgtool::datetime::now(imgtool::datetime::datetime_type::LOCAL)));
sourcef.read(buffer + 6 + FILE_HEADER_SIZE, buffer[1]);
}
else
diff --git a/src/tools/imgtool/modules/cybikoxt.cpp b/src/tools/imgtool/modules/cybikoxt.cpp
index a649dbe8909..8c2980de449 100644
--- a/src/tools/imgtool/modules/cybikoxt.cpp
+++ b/src/tools/imgtool/modules/cybikoxt.cpp
@@ -55,17 +55,8 @@ static cybiko_file_system *get_cfs(imgtool::image &image)
return (cybiko_file_system*)image.extra_bytes();
}
-// 2208988800 is the number of seconds between 1900/01/01 and 1970/01/01
-
-static time_t time_crack( uint32_t cfs_time)
-{
- return (time_t)(cfs_time - 2208988800UL);
-}
-
-static uint32_t time_setup( time_t ansi_time)
-{
- return (uint32_t)(ansi_time + 2208988800UL);
-}
+extern imgtool::datetime cybiko_time_crack(uint32_t cfs_time);
+extern uint32_t cybiko_time_setup(const imgtool::datetime &t);
static uint32_t buffer_read_32_be( uint8_t *buffer)
{
@@ -382,7 +373,7 @@ static imgtoolerr_t cybiko_image_next_enum(imgtool::directory &enumeration, imgt
{
strcpy(ent.filename, file.name);
ent.filesize = file.size;
- ent.lastmodified_time = time_crack(file.date);
+ ent.lastmodified_time = cybiko_time_crack(file.date);
ent.filesize = file.size;
}
else
@@ -475,7 +466,7 @@ static imgtoolerr_t cybiko_image_write_file(imgtool::partition &partition, const
{
buffer[6] = 0x20;
strcpy(BLOCK_FILENAME(buffer), filename);
- buffer_write_32_be( buffer + 6 + FILE_HEADER_SIZE - 4, time_setup( time( NULL)));
+ buffer_write_32_be( buffer + 6 + FILE_HEADER_SIZE - 4, cybiko_time_setup(imgtool::datetime::now(imgtool::datetime::datetime_type::LOCAL)));
sourcef.read(buffer + 6 + FILE_HEADER_SIZE, buffer[1]);
}
else
diff --git a/src/tools/imgtool/modules/fat.cpp b/src/tools/imgtool/modules/fat.cpp
index aa15a4783f6..e1b3a914c2b 100644
--- a/src/tools/imgtool/modules/fat.cpp
+++ b/src/tools/imgtool/modules/fat.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Raphael Nabet
/****************************************************************************
- fat.c
+ fat.cpp
PC FAT disk images
@@ -184,8 +184,8 @@ struct fat_dirent
uint32_t first_cluster;
uint32_t dirent_sector_index;
uint32_t dirent_sector_offset;
- time_t creation_time;
- time_t lastmodified_time;
+ imgtool::datetime creation_time;
+ imgtool::datetime lastmodified_time;
};
struct fat_freeentry_info
@@ -1241,33 +1241,25 @@ static void fat_cannonicalize_sfn(char *sfn, const uint8_t *sfn_bytes)
-static time_t fat_crack_time(uint32_t fat_time)
+static imgtool::datetime fat_crack_time(uint32_t fat_time)
{
- struct tm t;
- time_t now;
-
- time(&now);
- t = *localtime(&now);
-
- t.tm_sec = ((fat_time >> 0) & 0x001F) * 2;
- t.tm_min = ((fat_time >> 5) & 0x003F);
- t.tm_hour = ((fat_time >> 11) & 0x001F);
- t.tm_mday = ((fat_time >> 16) & 0x001F);
- t.tm_mon = ((fat_time >> 21) & 0x000F);
- t.tm_year = ((fat_time >> 25) & 0x007F) + 1980 - 1900;
-
- return mktime(&t);
+ util::arbitrary_datetime dt;
+ dt.second = ((fat_time >> 0) & 0x001F) * 2;
+ dt.minute = ((fat_time >> 5) & 0x003F);
+ dt.hour = ((fat_time >> 11) & 0x001F);
+ dt.day_of_month = ((fat_time >> 16) & 0x001F);
+ dt.month = ((fat_time >> 21) & 0x000F);
+ dt.year = ((fat_time >> 25) & 0x007F) + 1980;
+ return imgtool::datetime(imgtool::datetime::LOCAL, dt);
}
static uint32_t fat_setup_time(time_t ansi_time)
{
- struct tm t;
- uint32_t result = 0;
-
- t = *localtime(&ansi_time);
+ std::tm t = *localtime(&ansi_time);
+ uint32_t result = 0;
result |= (((uint32_t) (t.tm_sec / 2)) & 0x001F) << 0;
result |= (((uint32_t) t.tm_min) & 0x003F) << 5;
result |= (((uint32_t) t.tm_hour) & 0x001F) << 11;
diff --git a/src/tools/imgtool/modules/mac.cpp b/src/tools/imgtool/modules/mac.cpp
index 546a153a7e8..f606451c6e1 100644
--- a/src/tools/imgtool/modules/mac.cpp
+++ b/src/tools/imgtool/modules/mac.cpp
@@ -5827,10 +5827,10 @@ static imgtoolerr_t mac_image_getattrs(imgtool::partition &partition, const char
break;
case IMGTOOLATTR_TIME_CREATED:
- values[i].t = mac_crack_time(cat_info.createDate);
+ values[i].t = mac_crack_time(cat_info.createDate).to_time_t();
break;
case IMGTOOLATTR_TIME_LASTMODIFIED:
- values[i].t = mac_crack_time(cat_info.modifyDate);
+ values[i].t = mac_crack_time(cat_info.modifyDate).to_time_t();
break;
}
}
diff --git a/src/tools/imgtool/modules/macbin.cpp b/src/tools/imgtool/modules/macbin.cpp
index c937ff22163..30400dffdbb 100644
--- a/src/tools/imgtool/modules/macbin.cpp
+++ b/src/tools/imgtool/modules/macbin.cpp
@@ -323,8 +323,8 @@ static imgtoolerr_t macbinary_writefile(imgtool::partition &partition, const cha
return err;
/* set up attributes */
- attr_values[0].t = mac_crack_time(creation_time);
- attr_values[1].t = mac_crack_time(lastmodified_time);
+ attr_values[0].t = mac_crack_time(creation_time).to_time_t();
+ attr_values[1].t = mac_crack_time(lastmodified_time).to_time_t();
attr_values[2].i = type_code;
attr_values[3].i = creator_code;
attr_values[4].i = finder_flags;
diff --git a/src/tools/imgtool/modules/macutil.cpp b/src/tools/imgtool/modules/macutil.cpp
index 1bab14487cd..08c8b84989f 100644
--- a/src/tools/imgtool/modules/macutil.cpp
+++ b/src/tools/imgtool/modules/macutil.cpp
@@ -15,32 +15,54 @@
typedef util::arbitrary_clock<std::uint32_t, 1904, 1, 1, 0, 0, 0, std::ratio<1, 1> > classic_mac_clock;
-time_t mac_crack_time(uint32_t t)
+//-------------------------------------------------
+// mac_crack_time
+//-------------------------------------------------
+
+imgtool::datetime mac_crack_time(uint32_t t)
{
classic_mac_clock::duration d(t);
- std::chrono::time_point<std::chrono::system_clock> tp = classic_mac_clock::to_system_clock(std::chrono::time_point<classic_mac_clock>(d));
- return std::chrono::system_clock::to_time_t(tp);
+ std::chrono::time_point<classic_mac_clock> tp(d);
+ return imgtool::datetime(imgtool::datetime::datetime_type::LOCAL, tp);
}
+//-------------------------------------------------
+// mac_setup_time
+//-------------------------------------------------
-uint32_t mac_setup_time(time_t t)
+uint32_t mac_setup_time(const imgtool::datetime &t)
{
- auto system_time_point = std::chrono::system_clock::from_time_t(t);
- auto mac_time_point = classic_mac_clock::from_system_clock(system_time_point);
+ auto mac_time_point = classic_mac_clock::from_arbitrary_time_point(t.time_point());
return mac_time_point.time_since_epoch().count();
}
+//-------------------------------------------------
+// mac_setup_time
+//-------------------------------------------------
+
+uint32_t mac_setup_time(time_t t)
+{
+ imgtool::datetime dt(imgtool::datetime::datetime_type::LOCAL, t);
+ return mac_setup_time(dt);
+}
+
+
+//-------------------------------------------------
+// mac_time_now
+//-------------------------------------------------
uint32_t mac_time_now(void)
{
- time_t now;
- time(&now);
- return mac_setup_time(now);
+ imgtool::datetime dt = imgtool::datetime::now(imgtool::datetime::datetime_type::LOCAL);
+ return mac_setup_time(dt);
}
+//-------------------------------------------------
+// mac_identify_fork
+//-------------------------------------------------
imgtoolerr_t mac_identify_fork(const char *fork_string, mac_fork_t *fork_num)
{
diff --git a/src/tools/imgtool/modules/macutil.h b/src/tools/imgtool/modules/macutil.h
index fcec0728c95..0ab3315874b 100644
--- a/src/tools/imgtool/modules/macutil.h
+++ b/src/tools/imgtool/modules/macutil.h
@@ -29,7 +29,8 @@ enum mac_filecategory_t
/* converting Classic Mac OS time <==> Imgtool time */
-time_t mac_crack_time(uint32_t t);
+imgtool::datetime mac_crack_time(uint32_t t);
+uint32_t mac_setup_time(const imgtool::datetime &t);
uint32_t mac_setup_time(time_t t);
uint32_t mac_time_now(void);
diff --git a/src/tools/imgtool/modules/prodos.cpp b/src/tools/imgtool/modules/prodos.cpp
index 4c01612283f..6db41ae529b 100644
--- a/src/tools/imgtool/modules/prodos.cpp
+++ b/src/tools/imgtool/modules/prodos.cpp
@@ -186,24 +186,19 @@ enum creation_policy_t
-static time_t prodos_crack_time(uint32_t prodos_time)
-{
- struct tm t;
- time_t now;
-
- time(&now);
- t = *localtime(&now);
-
- t.tm_sec = 0;
- t.tm_min = (prodos_time >> 16) & 0x3F;
- t.tm_hour = (prodos_time >> 24) & 0x1F;
- t.tm_mday = (prodos_time >> 0) & 0x1F;
- t.tm_mon = (prodos_time >> 5) & 0x0F;
- t.tm_year = (prodos_time >> 9) & 0x7F;
-
- if (t.tm_year <= 49)
- t.tm_year += 100;
- return mktime(&t);
+static imgtool::datetime prodos_crack_time(uint32_t prodos_time)
+{
+ util::arbitrary_datetime dt;
+ dt.second = 0;
+ dt.minute = ((prodos_time >> 16) & 0x3F);
+ dt.hour = ((prodos_time >> 24) & 0x1F);
+ dt.day_of_month = ((prodos_time >> 0) & 0x1F);
+ dt.month = ((prodos_time >> 5) & 0x0F) + 1;
+ dt.year = ((prodos_time >> 9) & 0x7F) + 1900;
+ if (dt.year <= 1949)
+ dt.year += 100;
+
+ return imgtool::datetime(imgtool::datetime::datetime_type::LOCAL, dt);
}
@@ -2039,10 +2034,10 @@ static imgtoolerr_t prodos_diskimage_getattrs(imgtool::partition &partition, con
break;
case IMGTOOLATTR_TIME_CREATED:
- values[i].t = prodos_crack_time(ent.creation_time);
+ values[i].t = prodos_crack_time(ent.creation_time).to_time_t();
break;
case IMGTOOLATTR_TIME_LASTMODIFIED:
- values[i].t = prodos_crack_time(ent.lastmodified_time);
+ values[i].t = prodos_crack_time(ent.lastmodified_time).to_time_t();
break;
}
}
diff --git a/src/tools/imgtool/modules/thomson.cpp b/src/tools/imgtool/modules/thomson.cpp
index d7adce9dbb9..d2848a00cde 100644
--- a/src/tools/imgtool/modules/thomson.cpp
+++ b/src/tools/imgtool/modules/thomson.cpp
@@ -485,24 +485,20 @@ static void thom_conv_filename(const char* s, char name[9], char ext[4])
}
}
-static time_t thom_crack_time(thom_dirent* d)
+static imgtool::datetime thom_crack_time(thom_dirent* d)
{
- struct tm t;
- time_t now;
-
/* check */
- if ( d->day < 1 || d->day > 31 || d->month < 1 || d->month > 12 ) return 0;
+ if ( d->day < 1 || d->day > 31 || d->month < 1 || d->month > 12 ) return imgtool::datetime();
/* converts */
- time( &now );
- t = *localtime( &now );
- t.tm_sec = 0;
- t.tm_min = 0;
- t.tm_hour = 0;
- t.tm_mday = d->day;
- t.tm_mon = d->month - 1;
- t.tm_year = (d->year < 65 ) ? d->year + 100 : d->year;
- return mktime(&t);
+ util::arbitrary_datetime dt;
+ dt.second = 0;
+ dt.minute = 0;
+ dt.hour = 0;
+ dt.day_of_month = d->day;
+ dt.month = d->month;
+ dt.year = d->year + (d->year < 65 ? 2000 : 1900);
+ return imgtool::datetime(imgtool::datetime::datetime_type::LOCAL, dt);
}
static void thom_make_time(thom_dirent* d, time_t time)
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index eafca32f14f..744d65282a3 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -9,41 +9,246 @@
****************************************************************************/
#include "emu.h"
-#include "cpu/sparc/sparcdasm.h"
#include <algorithm>
#include <cstring>
#include <ctype.h>
+#include "cpu/8x300/8x300dasm.h"
+#include "cpu/adsp2100/2100dasm.h"
+#include "cpu/alph8201/8201dasm.h"
+#include "cpu/alto2/alto2dsm.h"
+#include "cpu/am29000/am29dasm.h"
+#include "cpu/amis2000/amis2000d.h"
+#include "cpu/apexc/apexcdsm.h"
+#include "cpu/arc/arcdasm.h"
+#include "cpu/arcompact/arcompactdasm.h"
+#include "cpu/arm/armdasm.h"
+#include "cpu/arm7/arm7dasm.h"
+#include "cpu/asap/asapdasm.h"
+#include "cpu/avr8/avr8dasm.h"
+#include "cpu/capricorn/capricorn_dasm.h"
+#include "cpu/ccpu/ccpudasm.h"
+#include "cpu/clipper/clipperd.h"
+#include "cpu/cop400/cop410ds.h"
+#include "cpu/cop400/cop420ds.h"
+#include "cpu/cop400/cop424ds.h"
+#include "cpu/cop400/cop444ds.h"
+#include "cpu/cosmac/cosdasm.h"
+#include "cpu/cp1610/1610dasm.h"
+#include "cpu/cubeqcpu/cubedasm.h"
+#include "cpu/dsp16/dsp16dis.h"
+#include "cpu/dsp32/dsp32dis.h"
+#include "cpu/dsp56k/dsp56dsm.h"
+#include "cpu/e0c6200/e0c6200d.h"
+#include "cpu/e132xs/32xsdasm.h"
+#include "cpu/es5510/es5510d.h"
+#include "cpu/esrip/esripdsm.h"
+#include "cpu/f8/f8dasm.h"
+#include "cpu/g65816/g65816ds.h"
+#include "cpu/h6280/6280dasm.h"
+#include "cpu/h8/h8d.h"
+#include "cpu/h8/h8hd.h"
+#include "cpu/h8/h8s2000d.h"
+#include "cpu/h8/h8s2600d.h"
+#include "cpu/hcd62121/hcd62121d.h"
+#include "cpu/hd61700/hd61700d.h"
+#include "cpu/hmcs40/hmcs40d.h"
+#include "cpu/hphybrid/hphybrid_dasm.h"
+#include "cpu/i386/i386dasm.h"
+#include "cpu/i8008/8008dasm.h"
+#include "cpu/i8085/8085dasm.h"
+#include "cpu/i8089/i8089_dasm.h"
+#include "cpu/i860/i860dis.h"
+#include "cpu/i960/i960dis.h"
+#include "cpu/ie15/ie15dasm.h"
+#include "cpu/jaguar/jagdasm.h"
+#include "cpu/lc8670/lc8670dsm.h"
+#include "cpu/lh5801/5801dasm.h"
+#include "cpu/lr35902/lr35902d.h"
+#include "cpu/m37710/m7700ds.h"
+#include "cpu/m6502/m4510d.h"
+#include "cpu/m6502/m6502d.h"
+#include "cpu/m6502/m6509d.h"
+#include "cpu/m6502/m6510d.h"
+#include "cpu/m6502/m65c02d.h"
+#include "cpu/m6502/m65ce02d.h"
+#include "cpu/m6502/m740d.h"
+#include "cpu/m6800/6800dasm.h"
+#include "cpu/m68000/m68kdasm.h"
+#include "cpu/m6805/6805dasm.h"
+#include "cpu/m6809/6x09dasm.h"
+#include "cpu/mb86233/mb86233d.h"
+#include "cpu/mb86235/mb86235d.h"
+#include "cpu/mb88xx/mb88dasm.h"
+#include "cpu/mc68hc11/hc11dasm.h"
+#include "cpu/mcs40/mcs40dasm.h"
+#include "cpu/mcs48/mcs48dsm.h"
+#include "cpu/mcs51/mcs51dasm.h"
+#include "cpu/mcs96/i8x9xd.h"
+#include "cpu/mcs96/i8xc196d.h"
+#include "cpu/melps4/melps4d.h"
+#include "cpu/minx/minxd.h"
+#include "cpu/mips/mips3dsm.h"
+#include "cpu/mips/r3kdasm.h"
+#include "cpu/mn10200/mn102dis.h"
+#include "cpu/nanoprocessor/nanoprocessor_dasm.h"
+#include "cpu/nec/necdasm.h"
+#include "cpu/patinhofeio/patinho_feio_dasm.h"
+#include "cpu/pdp1/pdp1dasm.h"
+#include "cpu/pdp1/tx0dasm.h"
+#include "cpu/pdp8/pdp8dasm.h"
+#include "cpu/pic16c5x/16c5xdsm.h"
+#include "cpu/pic16c62x/16c62xdsm.h"
+#include "cpu/powerpc/ppc_dasm.h"
+#include "cpu/pps4/pps4dasm.h"
+#include "cpu/psx/psxdasm.h"
+#include "cpu/rsp/rsp_dasm.h"
+#include "cpu/s2650/2650dasm.h"
+#include "cpu/saturn/saturnds.h"
+#include "cpu/sc61860/scdasm.h"
+#include "cpu/scmp/scmpdasm.h"
+#include "cpu/score/scoredsm.h"
+#include "cpu/scudsp/scudspdasm.h"
+#include "cpu/se3208/se3208dis.h"
+#include "cpu/sh/sh_dasm.h"
+#include "cpu/sharc/sharcdsm.h"
+#include "cpu/sm510/sm510d.h"
+#include "cpu/sm8500/sm8500d.h"
+#include "cpu/sparc/sparcdasm.h"
+#include "cpu/spc700/spc700ds.h"
+#include "cpu/ssem/ssemdasm.h"
+#include "cpu/ssp1601/ssp1601d.h"
+#include "cpu/superfx/sfx_dasm.h"
+#include "cpu/t11/t11dasm.h"
+#include "cpu/tlcs870/tlcs870d.h"
+#include "cpu/tlcs90/tlcs90d.h"
+#include "cpu/tlcs900/dasm900.h"
+#include "cpu/tms1000/tms1k_dasm.h"
+#include "cpu/tms32010/32010dsm.h"
+#include "cpu/tms32025/32025dsm.h"
+#include "cpu/tms32031/dis32031.h"
+#include "cpu/tms32051/dis32051.h"
+#include "cpu/tms32082/dis_mp.h"
+#include "cpu/tms32082/dis_pp.h"
+#include "cpu/tms34010/34010dsm.h"
+#include "cpu/tms57002/57002dsm.h"
+#include "cpu/tms7000/7000dasm.h"
+#include "cpu/tms9900/9900dasm.h"
+#include "cpu/tms9900/tms99com.h"
+#include "cpu/ucom4/ucom4d.h"
+#include "cpu/unsp/unspdasm.h"
+#include "cpu/upd7725/dasm7725.h"
+#include "cpu/upd7810/upd7810_dasm.h"
+#include "cpu/v60/v60d.h"
+#include "cpu/v810/v810dasm.h"
+#include "cpu/z180/z180dasm.h"
+#include "cpu/z8/z8dasm.h"
+#include "cpu/z80/z80dasm.h"
+#include "cpu/z8000/8000dasm.h"
+
+// Configuration classes
-enum display_type
+// Selected through dasm name
+struct arm7_unidasm_t : public arm7_disassembler::config
{
- _8bit,
- _8bitx,
- _16be,
- _16le,
- _24be,
- _24le,
- _32be,
- _32le,
- _40be,
- _40le,
- _48be,
- _48le,
- _56be,
- _56le,
- _64be,
- _64le
-};
+ bool t_flag;
+ arm7_unidasm_t() { t_flag = false; }
+ virtual ~arm7_unidasm_t() override = default;
+ virtual bool get_t_flag() const override { return t_flag; }
+} arm7_unidasm;
+
+// Configuration missing
+struct g65816_unidasm_t : g65816_disassembler::config
+{
+ bool m_flag;
+ bool x_flag;
+
+ g65816_unidasm_t() { m_flag = false; x_flag = false; }
+ virtual ~g65816_unidasm_t() override = default;
+ virtual bool get_m_flag() const override { return m_flag; }
+ virtual bool get_x_flag() const override { return x_flag; }
+} g65816_unidasm;
+
+// Configuration missing
+struct m740_unidasm_t : m740_disassembler::config
+{
+ u32 inst_state_base;
+ m740_unidasm_t() { inst_state_base = 0; }
+ virtual ~m740_unidasm_t() override = default;
+ virtual u32 get_state_base() const override { return inst_state_base; }
+} m740_unidasm;
+
+// Configuration missing
+struct m7700_unidasm_t : m7700_disassembler::config
+{
+ bool m_flag;
+ bool x_flag;
+
+ m7700_unidasm_t() { m_flag = false; x_flag = false; }
+ virtual ~m7700_unidasm_t() override = default;
+ virtual bool get_m_flag() const override { return m_flag; }
+ virtual bool get_x_flag() const override { return x_flag; }
+} m7700_unidasm;
+
+
+// Configuration missing
+struct s2650_unidasm_t : s2650_disassembler::config
+{
+ bool z80_mnemonics;
+ s2650_unidasm_t() { z80_mnemonics = false; }
+ virtual ~s2650_unidasm_t() override = default;
+ virtual bool get_z80_mnemonics_mode() const override { return z80_mnemonics; }
+} s2650_unidasm;
+
+// Configuration missing
+struct saturn_unidasm_t : saturn_disassembler::config
+{
+ bool nonstandard_mnemonics;
+ saturn_unidasm_t() { nonstandard_mnemonics = false; }
+ virtual ~saturn_unidasm_t() override = default;
+ virtual bool get_nonstandard_mnemonics_mode() const override { return nonstandard_mnemonics; }
+} saturn_unidasm;
+// Configuration missing
+struct superfx_unidasm_t : superfx_disassembler::config
+{
+ u16 sfr;
+ superfx_unidasm_t() { sfr = superfx_disassembler::SUPERFX_SFR_ALT0; }
+ virtual ~superfx_unidasm_t() override = default;
+ virtual u16 get_alt() const override { return sfr; }
+} superfx_unidasm;
+
+// Selected through dasm name
+struct i386_unidasm_t : i386_disassembler::config
+{
+ int mode;
+ i386_unidasm_t() { mode = 32; }
+ virtual ~i386_unidasm_t() override = default;
+ virtual int get_mode() const override { return mode; }
+} i386_unidasm;
+
+// Configuration missing
+struct z8000_unidasm_t : z8000_disassembler::config
+{
+ bool segmented_mode;
+ z8000_unidasm_t() { segmented_mode = false; }
+ virtual ~z8000_unidasm_t() override = default;
+ virtual bool get_segmented_mode() const override { return segmented_mode; }
+} z8000_unidasm;
+
+
+
+
+enum endianness { le, be };
struct dasm_table_entry
{
const char * name;
- display_type display;
- int8_t pcshift;
- cpu_disassemble_func func;
+ endianness endian;
+ int8_t pcshift;
+ std::function<util::disasm_interface *()> alloc;
};
@@ -51,363 +256,574 @@ struct options
{
const char * filename;
offs_t basepc;
- uint8_t norawbytes;
- uint8_t lower;
- uint8_t upper;
- uint8_t flipped;
+ uint8_t norawbytes;
+ uint8_t lower;
+ uint8_t upper;
+ uint8_t flipped;
int mode;
const dasm_table_entry *dasm;
- uint32_t skip;
- uint32_t count;
+ uint32_t skip;
+ uint32_t count;
};
+static const dasm_table_entry dasm_table[] =
+{
+ { "8x300", be, 0, []() -> util::disasm_interface * { return new n8x300_disassembler; } },
+ { "adsp21xx", le, -2, []() -> util::disasm_interface * { return new adsp21xx_disassembler; } },
+ { "alpha8201", le, 0, []() -> util::disasm_interface * { return new alpha8201_disassembler; } },
+ { "alto2", be, -2, []() -> util::disasm_interface * { return new alto2_disassembler; } },
+ { "am29000", be, 0, []() -> util::disasm_interface * { return new am29000_disassembler; } },
+ { "amis2000", le, 0, []() -> util::disasm_interface * { return new amis2000_disassembler; } },
+ { "apexc", be, 0, []() -> util::disasm_interface * { return new apexc_disassembler; } },
+ { "arc", be, 0, []() -> util::disasm_interface * { return new arc_disassembler; } },
+ { "arcompact", le, 0, []() -> util::disasm_interface * { return new arcompact_disassembler; } },
+ { "arm", le, 0, []() -> util::disasm_interface * { return new arm_disassembler; } },
+ { "arm_be", be, 0, []() -> util::disasm_interface * { return new arm_disassembler; } },
+ { "arm7", le, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = false; return new arm7_disassembler(&arm7_unidasm); } },
+ { "arm7_be", be, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = false; return new arm7_disassembler(&arm7_unidasm); } },
+ { "arm7thumb", le, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = true; return new arm7_disassembler(&arm7_unidasm); } },
+ { "arm7thumbb", be, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = true; return new arm7_disassembler(&arm7_unidasm); } },
+ { "asap", le, 0, []() -> util::disasm_interface * { return new asap_disassembler; } },
+ { "avr8", le, 0, []() -> util::disasm_interface * { return new avr8_disassembler; } },
+ { "capricorn", le, 0, []() -> util::disasm_interface * { return new capricorn_disassembler; } },
+ { "ccpu", le, 0, []() -> util::disasm_interface * { return new ccpu_disassembler; } },
+ { "cdp1801", le, 0, []() -> util::disasm_interface * { return new cosmac_disassembler(cosmac_disassembler::TYPE_1801); } },
+ { "cdp1802", le, 0, []() -> util::disasm_interface * { return new cosmac_disassembler(cosmac_disassembler::TYPE_1802); } },
+ { "clipper", le, 0, []() -> util::disasm_interface * { return new clipper_disassembler; } },
+ { "coldfire", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_COLDFIRE); } },
+ { "cop410", le, 0, []() -> util::disasm_interface * { return new cop410_disassembler; } },
+ { "cop420", le, 0, []() -> util::disasm_interface * { return new cop420_disassembler; } },
+ { "cop444", le, 0, []() -> util::disasm_interface * { return new cop444_disassembler; } },
+ { "cop424", le, 0, []() -> util::disasm_interface * { return new cop424_disassembler; } },
+ { "cp1610", be, -1, []() -> util::disasm_interface * { return new cp1610_disassembler; } },
+ { "cquestlin", be, -3, []() -> util::disasm_interface * { return new cquestlin_disassembler; } },
+ { "cquestrot", be, -3, []() -> util::disasm_interface * { return new cquestrot_disassembler; } },
+ { "cquestsnd", be, -3, []() -> util::disasm_interface * { return new cquestsnd_disassembler; } },
+ { "ds5002fp", le, 0, []() -> util::disasm_interface * { return new ds5002fp_disassembler; } },
+ { "dsp16a", le, -1, []() -> util::disasm_interface * { return new dsp16a_disassembler; } },
+ { "dsp32c", le, 0, []() -> util::disasm_interface * { return new dsp32c_disassembler; } },
+ { "dsp56k", le, -1, []() -> util::disasm_interface * { return new dsp56k_disassembler; } },
+ { "e0c6200", be, -1, []() -> util::disasm_interface * { return new e0c6200_disassembler; } },
+// { "es5510", be, 0, []() -> util::disasm_interface * { return new es5510_disassembler; } }, // Currently does nothing
+ { "esrip", be, 0, []() -> util::disasm_interface * { return new esrip_disassembler; } },
+ { "f8", le, 0, []() -> util::disasm_interface * { return new f8_disassembler; } },
+ { "g65816", le, 0, []() -> util::disasm_interface * { return new g65816_disassembler(&g65816_unidasm); } },
+ { "h6280", le, 0, []() -> util::disasm_interface * { return new h6280_disassembler; } },
+ { "h8", be, 0, []() -> util::disasm_interface * { return new h8_disassembler; } },
+ { "h8h", be, 0, []() -> util::disasm_interface * { return new h8h_disassembler; } },
+ { "h8s2000", be, 0, []() -> util::disasm_interface * { return new h8s2000_disassembler; } },
+ { "h8s2600", be, 0, []() -> util::disasm_interface * { return new h8s2600_disassembler; } },
+ { "hc11", le, 0, []() -> util::disasm_interface * { return new hc11_disassembler; } },
+ { "hcd62121", le, 0, []() -> util::disasm_interface * { return new hcd62121_disassembler; } },
+ { "hd61700", le, 0, []() -> util::disasm_interface * { return new hd61700_disassembler; } },
+ { "hd6301", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6301); } },
+ { "hd6309", le, 0, []() -> util::disasm_interface * { return new hd6309_disassembler; } },
+ { "hd63701", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(63701); } },
+ { "hmcs40", le, -1, []() -> util::disasm_interface * { return new hmcs40_disassembler; } },
+ { "hp_hybrid", be, -1, []() -> util::disasm_interface * { return new hp_hybrid_disassembler; } },
+ { "hp_5061_3001", be, -1, []() -> util::disasm_interface * { return new hp_5061_3001_disassembler; } },
+ { "hyperstone", be, 0, []() -> util::disasm_interface * { return new hyperstone_disassembler; } },
+ { "i4004", le, 0, []() -> util::disasm_interface * { return new i4004_disassembler; } },
+ { "i4040", le, 0, []() -> util::disasm_interface * { return new i4040_disassembler; } },
+ { "i8008", le, 0, []() -> util::disasm_interface * { return new i8008_disassembler; } },
+ { "i8051", le, 0, []() -> util::disasm_interface * { return new i8051_disassembler; } },
+ { "i8052", le, 0, []() -> util::disasm_interface * { return new i8052_disassembler; } },
+ { "i8085", le, 0, []() -> util::disasm_interface * { return new i8085_disassembler; } },
+ { "i8089", le, 0, []() -> util::disasm_interface * { return new i8089_disassembler; } },
+ { "i80c51", le, 0, []() -> util::disasm_interface * { return new i80c51_disassembler; } },
+ { "i80c52", le, 0, []() -> util::disasm_interface * { return new i80c52_disassembler; } },
+ { "i860", le, 0, []() -> util::disasm_interface * { return new i860_disassembler; } },
+ { "i8x9x", le, 0, []() -> util::disasm_interface * { return new i8x9x_disassembler; } },
+ { "i8xc196", le, 0, []() -> util::disasm_interface * { return new i8xc196_disassembler; } },
+ { "i960", le, 0, []() -> util::disasm_interface * { return new i960_disassembler; } },
+ { "ie15", le, 0, []() -> util::disasm_interface * { return new ie15_disassembler; } },
+ { "jaguardsp", be, 0, []() -> util::disasm_interface * { return new jaguar_disassembler(jaguar_disassembler::JAGUAR_VARIANT_DSP); } },
+ { "jaguargpu", be, 0, []() -> util::disasm_interface * { return new jaguar_disassembler(jaguar_disassembler::JAGUAR_VARIANT_GPU); } },
+ { "konami", le, 0, []() -> util::disasm_interface * { return new konami_disassembler; } },
+ { "lc8670", be, 0, []() -> util::disasm_interface * { return new lc8670_disassembler; } },
+ { "lh5801", le, 0, []() -> util::disasm_interface * { return new lh5801_disassembler; } },
+ { "lr35902", le, 0, []() -> util::disasm_interface * { return new lr35902_disassembler; } },
+ { "m146805", le, 0, []() -> util::disasm_interface * { return new m146805_disassembler; } },
+ { "m37710", le, 0, []() -> util::disasm_interface * { return new m7700_disassembler(&m7700_unidasm); } },
+ { "m4510", le, 0, []() -> util::disasm_interface * { return new m4510_disassembler; } },
+ { "m58846", le, -1, []() -> util::disasm_interface * { return new melps4_disassembler; } },
+ { "m6502", le, 0, []() -> util::disasm_interface * { return new m6502_disassembler; } },
+ { "m6509", le, 0, []() -> util::disasm_interface * { return new m6509_disassembler; } },
+ { "m6510", le, 0, []() -> util::disasm_interface * { return new m6510_disassembler; } },
+ { "m65c02", le, 0, []() -> util::disasm_interface * { return new m65c02_disassembler; } },
+ { "m65ce02", le, 0, []() -> util::disasm_interface * { return new m65ce02_disassembler; } },
+ { "m6800", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6800); } },
+ { "m68000", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68000); } },
+ { "m68008", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68008); } },
+ { "m6801", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6801); } },
+ { "m68010", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68010); } },
+ { "m6802", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6802); } },
+ { "m68020", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68020); } },
+ { "m6803", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6803); } },
+ { "m68030", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68030); } },
+ { "m68040", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68040); } },
+ { "m6805", le, 0, []() -> util::disasm_interface * { return new m6805_disassembler; } },
+ { "m6808", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6808); } },
+ { "m6809", le, 0, []() -> util::disasm_interface * { return new m6809_disassembler; } },
+ { "m68340", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68340); } },
+ { "m68hc05", le, 0, []() -> util::disasm_interface * { return new m68hc05_disassembler; } },
+ { "m740", le, 0, []() -> util::disasm_interface * { return new m740_disassembler(&m740_unidasm); } },
+ { "mb86233", le, -2, []() -> util::disasm_interface * { return new mb86233_disassembler; } },
+ { "mb86235", le, -3, []() -> util::disasm_interface * { return new mb86235_disassembler; } },
+ { "mb88", le, 0, []() -> util::disasm_interface * { return new mb88_disassembler; } },
+ { "mcs48", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(false); } },
+ { "minx", le, 0, []() -> util::disasm_interface * { return new minx_disassembler; } },
+ { "mips3be", be, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } },
+ { "mips3le", le, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } },
+ { "mn10200", le, 0, []() -> util::disasm_interface * { return new mn10200_disassembler; } },
+ { "nanoprocessor", le, 0, []() -> util::disasm_interface * { return new hp_nanoprocessor_disassembler; } },
+ { "nec", le, 0, []() -> util::disasm_interface * { return new nec_disassembler; } },
+ { "nsc8105", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(8105); } },
+ { "patinho_feio", le, 0, []() -> util::disasm_interface * { return new patinho_feio_disassembler; } },
+ { "pdp1", be, 0, []() -> util::disasm_interface * { return new pdp1_disassembler; } },
+ { "pdp8", be, 0, []() -> util::disasm_interface * { return new pdp8_disassembler; } },
+ { "pic16c5x", le, -1, []() -> util::disasm_interface * { return new pic16c5x_disassembler; } },
+ { "pic16c62x", le, -1, []() -> util::disasm_interface * { return new pic16c62x_disassembler; } },
+ { "powerpc", be, 0, []() -> util::disasm_interface * { return new powerpc_disassembler; } },
+ { "pps4", le, 0, []() -> util::disasm_interface * { return new pps4_disassembler; } },
+ { "psxcpu", le, 0, []() -> util::disasm_interface * { return new psxcpu_disassembler; } },
+ { "r3000be", be, 0, []() -> util::disasm_interface * { return new r3000_disassembler; } },
+ { "r3000le", le, 0, []() -> util::disasm_interface * { return new r3000_disassembler; } },
+ { "rsp", le, 0, []() -> util::disasm_interface * { return new rsp_disassembler; } },
+ { "s2650", le, 0, []() -> util::disasm_interface * { return new s2650_disassembler(&s2650_unidasm); } },
+ { "saturn", le, 0, []() -> util::disasm_interface * { return new saturn_disassembler(&saturn_unidasm); } },
+ { "sc61860", le, 0, []() -> util::disasm_interface * { return new sc61860_disassembler; } },
+ { "scmp", le, 0, []() -> util::disasm_interface * { return new scmp_disassembler; } },
+ { "scudsp", be, 0, []() -> util::disasm_interface * { return new scudsp_disassembler; } },
+ { "se3208", le, 0, []() -> util::disasm_interface * { return new se3208_disassembler; } },
+ { "sh2", be, 0, []() -> util::disasm_interface * { return new sh_disassembler(false); } },
+ { "sh4", le, 0, []() -> util::disasm_interface * { return new sh_disassembler(true); } },
+ { "sh4be", be, 0, []() -> util::disasm_interface * { return new sh_disassembler(true); } },
+ { "sharc", le, -2, []() -> util::disasm_interface * { return new sharc_disassembler; } },
+ { "sm500", le, 0, []() -> util::disasm_interface * { return new sm500_disassembler; } },
+ { "sm510", le, 0, []() -> util::disasm_interface * { return new sm510_disassembler; } },
+ { "sm511", le, 0, []() -> util::disasm_interface * { return new sm511_disassembler; } },
+ { "sm590", le, 0, []() -> util::disasm_interface * { return new sm590_disassembler; } },
+ { "sm5a", le, 0, []() -> util::disasm_interface * { return new sm5a_disassembler; } },
+ { "sm8500", le, 0, []() -> util::disasm_interface * { return new sm8500_disassembler; } },
+ { "sparcv7", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 7); } },
+ { "sparcv8", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 8); } },
+ { "sparcv9", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9); } },
+ { "sparcv9vis1", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_1); } },
+ { "sparcv9vis2", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_2); } },
+ { "sparcv9vis2p", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_2p); } },
+ { "sparcv9vis3", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_3); } },
+ { "sparcv9vis3b", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_3b); } },
+ { "spc700", le, 0, []() -> util::disasm_interface * { return new spc700_disassembler; } },
+ { "ssem", le, 0, []() -> util::disasm_interface * { return new ssem_disassembler; } },
+ { "ssp1601", be, -1, []() -> util::disasm_interface * { return new ssp1601_disassembler; } },
+ { "superfx", le, 0, []() -> util::disasm_interface * { return new superfx_disassembler(&superfx_unidasm); } },
+ { "t11", le, 0, []() -> util::disasm_interface * { return new t11_disassembler; } },
+ { "tlcs870", le, 0, []() -> util::disasm_interface * { return new tlcs870_disassembler; } },
+ { "tlcs90", le, 0, []() -> util::disasm_interface * { return new tlcs90_disassembler; } },
+ { "tlcs900", le, 0, []() -> util::disasm_interface * { return new tlcs900_disassembler; } },
+ { "tms0980", be, 0, []() -> util::disasm_interface * { return new tms0980_disassembler; } },
+ { "tms1000", le, 0, []() -> util::disasm_interface * { return new tms1000_disassembler; } },
+ { "tms1100", le, 0, []() -> util::disasm_interface * { return new tms1100_disassembler; } },
+ { "tms32010", be, -1, []() -> util::disasm_interface * { return new tms32010_disassembler; } },
+ { "tms32025", be, -1, []() -> util::disasm_interface * { return new tms32025_disassembler; } },
+ { "tms32031", le, -2, []() -> util::disasm_interface * { return new tms32031_disassembler; } },
+ { "tms32051", le, -1, []() -> util::disasm_interface * { return new tms32051_disassembler; } },
+ { "tms32082_mp", be, 0, []() -> util::disasm_interface * { return new tms32082_mp_disassembler; } },
+ { "tms32082_pp", be, 0, []() -> util::disasm_interface * { return new tms32082_pp_disassembler; } },
+ { "tms34010", le, 3, []() -> util::disasm_interface * { return new tms34010_disassembler(false); } },
+ { "tms34020", le, 3, []() -> util::disasm_interface * { return new tms34010_disassembler(true); } },
+ { "tms57002", le, -2, []() -> util::disasm_interface * { return new tms57002_disassembler; } },
+ { "tms7000", le, 0, []() -> util::disasm_interface * { return new tms7000_disassembler; } },
+ { "tms9900", be, 0, []() -> util::disasm_interface * { return new tms9900_disassembler(TMS9900_ID); } },
+ { "tms9980", le, 0, []() -> util::disasm_interface * { return new tms9900_disassembler(TMS9980_ID); } },
+ { "tms9995", le, 0, []() -> util::disasm_interface * { return new tms9900_disassembler(TMS9995_ID); } },
+ { "tp0320", be, 0, []() -> util::disasm_interface * { return new tp0320_disassembler; } },
+ { "tx0_64kw", be, -2, []() -> util::disasm_interface * { return new tx0_64kw_disassembler; } },
+ { "tx0_8kw", be, -2, []() -> util::disasm_interface * { return new tx0_8kw_disassembler; } },
+ { "ucom4", le, 0, []() -> util::disasm_interface * { return new ucom4_disassembler; } },
+ { "unsp", be, 0, []() -> util::disasm_interface * { return new unsp_disassembler; } },
+ { "upd7725", be, 0, []() -> util::disasm_interface * { return new necdsp_disassembler; } },
+ { "upd7801", le, 0, []() -> util::disasm_interface * { return new upd7801_disassembler; } },
+ { "upd7807", le, 0, []() -> util::disasm_interface * { return new upd7807_disassembler; } },
+ { "upd7810", le, 0, []() -> util::disasm_interface * { return new upd7810_disassembler; } },
+ { "upd78c05", le, 0, []() -> util::disasm_interface * { return new upd78c05_disassembler; } },
+ { "upi41", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(true); } },
+ { "v60", le, 0, []() -> util::disasm_interface * { return new v60_disassembler; } },
+ { "v810", le, 0, []() -> util::disasm_interface * { return new v810_disassembler; } },
+ { "x86_16", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 16; return new i386_disassembler(&i386_unidasm); } },
+ { "x86_32", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 32; return new i386_disassembler(&i386_unidasm); } },
+ { "x86_64", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 64; return new i386_disassembler(&i386_unidasm); } },
+ { "z180", le, 0, []() -> util::disasm_interface * { return new z180_disassembler; } },
+ { "z8", le, 0, []() -> util::disasm_interface * { return new z8_disassembler; } },
+ { "z80", le, 0, []() -> util::disasm_interface * { return new z80_disassembler; } },
+ { "z8000", be, 0, []() -> util::disasm_interface * { return new z8000_disassembler(&z8000_unidasm); } },
+};
+
+class unidasm_data_buffer : public util::disasm_interface::data_buffer
+{
+public:
+ std::vector<u8> data;
+ offs_t base_pc;
+ u32 size;
-CPU_DISASSEMBLE( adsp21xx );
-CPU_DISASSEMBLE( alpha8201 );
-CPU_DISASSEMBLE( am29000 );
-CPU_DISASSEMBLE( amis2000 );
-CPU_DISASSEMBLE( apexc );
-CPU_DISASSEMBLE( arcompact );
-CPU_DISASSEMBLE( arm );
-CPU_DISASSEMBLE( arm_be );
-CPU_DISASSEMBLE( arm7arm );
-CPU_DISASSEMBLE( arm7arm_be );
-CPU_DISASSEMBLE( arm7thumb );
-CPU_DISASSEMBLE( arm7thumb_be );
-CPU_DISASSEMBLE( asap );
-CPU_DISASSEMBLE( avr8 );
-CPU_DISASSEMBLE( capricorn );
-CPU_DISASSEMBLE( ccpu );
-CPU_DISASSEMBLE( cdp1801 );
-CPU_DISASSEMBLE( cdp1802 );
-CPU_DISASSEMBLE( clipper );
-CPU_DISASSEMBLE( coldfire );
-CPU_DISASSEMBLE( cop410 );
-CPU_DISASSEMBLE( cop420 );
-CPU_DISASSEMBLE( cop444 );
-CPU_DISASSEMBLE( cop424 );
-CPU_DISASSEMBLE( cp1610 );
-CPU_DISASSEMBLE( cquestlin );
-CPU_DISASSEMBLE( cquestrot );
-CPU_DISASSEMBLE( cquestsnd );
-CPU_DISASSEMBLE( ds5002fp );
-CPU_DISASSEMBLE( dsp16a );
-CPU_DISASSEMBLE( dsp32c );
-CPU_DISASSEMBLE( dsp56k );
-CPU_DISASSEMBLE( e0c6200 );
-CPU_DISASSEMBLE( esrip );
-CPU_DISASSEMBLE( f8 );
-CPU_DISASSEMBLE( g65816_generic );
-CPU_DISASSEMBLE( h6280 );
-CPU_DISASSEMBLE( hc11 );
-CPU_DISASSEMBLE( hcd62121 );
-CPU_DISASSEMBLE( hd61700 );
-CPU_DISASSEMBLE( hd6301 );
-CPU_DISASSEMBLE( hd6309 );
-CPU_DISASSEMBLE( hd63701 );
-CPU_DISASSEMBLE( hmcs40 );
-CPU_DISASSEMBLE( hp_hybrid );
-CPU_DISASSEMBLE( hp_5061_3001 );
-CPU_DISASSEMBLE( hp_nanoprocessor );
-CPU_DISASSEMBLE( hyperstone_generic );
-CPU_DISASSEMBLE( i4004 );
-CPU_DISASSEMBLE( i4040 );
-CPU_DISASSEMBLE( i8008 );
-CPU_DISASSEMBLE( i8051 );
-CPU_DISASSEMBLE( i8052 );
-CPU_DISASSEMBLE( i8085 );
-CPU_DISASSEMBLE( i8089 );
-CPU_DISASSEMBLE( i80c51 );
-CPU_DISASSEMBLE( i80c52 );
-CPU_DISASSEMBLE( i860 );
-CPU_DISASSEMBLE( i960 );
-CPU_DISASSEMBLE( ie15 );
-CPU_DISASSEMBLE( jaguardsp );
-CPU_DISASSEMBLE( jaguargpu );
-CPU_DISASSEMBLE( konami );
-CPU_DISASSEMBLE( lh5801 );
-CPU_DISASSEMBLE( lr35902 );
-CPU_DISASSEMBLE( m58846 );
-CPU_DISASSEMBLE( m37710_generic );
-CPU_DISASSEMBLE( m6800 );
-CPU_DISASSEMBLE( m68000 );
-CPU_DISASSEMBLE( m68008 );
-CPU_DISASSEMBLE( m6801 );
-CPU_DISASSEMBLE( m68010 );
-CPU_DISASSEMBLE( m6802 );
-CPU_DISASSEMBLE( m68020 );
-CPU_DISASSEMBLE( m6803 );
-CPU_DISASSEMBLE( m68030 );
-CPU_DISASSEMBLE( m68040 );
-CPU_DISASSEMBLE( m6805 );
-CPU_DISASSEMBLE( m146805 );
-CPU_DISASSEMBLE( m68hc05 );
-CPU_DISASSEMBLE( m6808 );
-CPU_DISASSEMBLE( m6809 );
-CPU_DISASSEMBLE( m68340 );
-CPU_DISASSEMBLE( mb86233 );
-CPU_DISASSEMBLE( mb88 );
-CPU_DISASSEMBLE( mcs48 );
-CPU_DISASSEMBLE( minx );
-CPU_DISASSEMBLE( mips3be );
-CPU_DISASSEMBLE( mips3le );
-CPU_DISASSEMBLE( mn10200 );
-CPU_DISASSEMBLE( n8x300 );
-CPU_DISASSEMBLE( nec );
-CPU_DISASSEMBLE( nsc8105 );
-CPU_DISASSEMBLE( pdp1 );
-CPU_DISASSEMBLE( pdp8 );
-CPU_DISASSEMBLE( pic16c5x );
-CPU_DISASSEMBLE( pic16c62x );
-CPU_DISASSEMBLE( powerpc );
-CPU_DISASSEMBLE( pps4 );
-CPU_DISASSEMBLE( psxcpu_generic );
-CPU_DISASSEMBLE( r3000be );
-CPU_DISASSEMBLE( r3000le );
-CPU_DISASSEMBLE( rsp );
-CPU_DISASSEMBLE( s2650 );
-CPU_DISASSEMBLE( saturn );
-CPU_DISASSEMBLE( sc61860 );
-CPU_DISASSEMBLE( scmp );
-CPU_DISASSEMBLE( scudsp );
-CPU_DISASSEMBLE( se3208 );
-CPU_DISASSEMBLE( sh2 );
-CPU_DISASSEMBLE( sh4 );
-CPU_DISASSEMBLE( sh4be );
-CPU_DISASSEMBLE( sharc );
-CPU_DISASSEMBLE( sm500 );
-CPU_DISASSEMBLE( sm510 );
-CPU_DISASSEMBLE( sm511 );
-CPU_DISASSEMBLE( sm5a );
-CPU_DISASSEMBLE( sm8500 );
-CPU_DISASSEMBLE( spc700 );
-CPU_DISASSEMBLE( ssem );
-CPU_DISASSEMBLE( ssp1601 );
-CPU_DISASSEMBLE( superfx );
-CPU_DISASSEMBLE( t11 );
-CPU_DISASSEMBLE( t90 );
-CPU_DISASSEMBLE( tlcs900 );
-CPU_DISASSEMBLE( tms0980 );
-CPU_DISASSEMBLE( tms1000 );
-CPU_DISASSEMBLE( tms1100 );
-CPU_DISASSEMBLE( tms32010 );
-CPU_DISASSEMBLE( tms32025 );
-CPU_DISASSEMBLE( tms3203x );
-CPU_DISASSEMBLE( tms32051 );
-CPU_DISASSEMBLE( tms34010 );
-CPU_DISASSEMBLE( tms34020 );
-CPU_DISASSEMBLE( tms57002 );
-CPU_DISASSEMBLE( tms7000 );
-CPU_DISASSEMBLE( tms9900 );
-CPU_DISASSEMBLE( tms9980 );
-CPU_DISASSEMBLE( tms9995 );
-CPU_DISASSEMBLE( tp0320 );
-CPU_DISASSEMBLE( tx0_64kw );
-CPU_DISASSEMBLE( tx0_8kw );
-CPU_DISASSEMBLE( ucom4 );
-CPU_DISASSEMBLE( unsp );
-CPU_DISASSEMBLE( upd7725 );
-CPU_DISASSEMBLE( upd7801 );
-CPU_DISASSEMBLE( upd7807 );
-CPU_DISASSEMBLE( upd7810 );
-CPU_DISASSEMBLE( upd78c05 );
-CPU_DISASSEMBLE( upi41 );
-CPU_DISASSEMBLE( v60 );
-CPU_DISASSEMBLE( v70 );
-CPU_DISASSEMBLE( v810 );
-CPU_DISASSEMBLE( x86_16 );
-CPU_DISASSEMBLE( x86_32 );
-CPU_DISASSEMBLE( x86_64 );
-CPU_DISASSEMBLE( z180 );
-CPU_DISASSEMBLE( z8 );
-CPU_DISASSEMBLE( z80 );
-CPU_DISASSEMBLE( z8000 );
-
-CPU_DISASSEMBLE( sparcv7 ) { static sparc_disassembler dasm(nullptr, 7); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv8 ) { static sparc_disassembler dasm(nullptr, 8); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9 ) { static sparc_disassembler dasm(nullptr, 9); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9vis1 ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_1); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9vis2 ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_2); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9vis2p ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_2p); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9vis3 ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_3); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
-CPU_DISASSEMBLE( sparcv9vis3b ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_3b); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); }
+ unidasm_data_buffer(util::disasm_interface *disasm, const dasm_table_entry *entry);
+ virtual ~unidasm_data_buffer() = default;
+ void decrypt(const unidasm_data_buffer &buffer, bool opcode);
-static const dasm_table_entry dasm_table[] =
+ virtual u8 r8 (offs_t pc) const override { return lr8 (pc); }
+ virtual u16 r16(offs_t pc) const override { return lr16(pc); }
+ virtual u32 r32(offs_t pc) const override { return lr32(pc); }
+ virtual u64 r64(offs_t pc) const override { return lr64(pc); }
+
+private:
+ std::function<u8 (offs_t pc)> lr8;
+ std::function<u16 (offs_t pc)> lr16;
+ std::function<u32 (offs_t pc)> lr32;
+ std::function<u64 (offs_t pc)> lr64;
+
+ util::disasm_interface *disasm;
+ const dasm_table_entry *entry;
+
+ template<typename T> const T *get_ptr(offs_t pc) const {
+ if(pc < base_pc)
+ return nullptr;
+ offs_t delta = (pc - base_pc) * sizeof(T);
+ if(delta >= size)
+ return nullptr;
+ return reinterpret_cast<const T *>(&data[delta]);
+ }
+
+ template<typename T> T get(offs_t pc) const {
+ auto p = get_ptr<T>(pc);
+ return p ? *p : 0;
+ }
+};
+
+struct dasm_line
{
- { "8x300", _16be, 0, CPU_DISASSEMBLE_NAME(n8x300) },
- { "adsp21xx", _24le, -2, CPU_DISASSEMBLE_NAME(adsp21xx) },
- { "alpha8201", _8bit, 0, CPU_DISASSEMBLE_NAME(alpha8201) },
- { "am29000", _32be, 0, CPU_DISASSEMBLE_NAME(am29000) },
- { "amis2000", _8bit, 0, CPU_DISASSEMBLE_NAME(amis2000) },
- { "apexc", _32be, 0, CPU_DISASSEMBLE_NAME(apexc) },
- { "arcompact", _16le, 0, CPU_DISASSEMBLE_NAME(arcompact) },
- { "arm", _32le, 0, CPU_DISASSEMBLE_NAME(arm) },
- { "arm_be", _32be, 0, CPU_DISASSEMBLE_NAME(arm_be) },
- { "arm7", _32le, 0, CPU_DISASSEMBLE_NAME(arm7arm) },
- { "arm7_be", _32be, 0, CPU_DISASSEMBLE_NAME(arm7arm_be) },
- { "arm7thumb", _16le, 0, CPU_DISASSEMBLE_NAME(arm7thumb) },
- { "arm7thumbb", _16be, 0, CPU_DISASSEMBLE_NAME(arm7thumb_be) },
- { "asap", _32le, 0, CPU_DISASSEMBLE_NAME(asap) },
- { "avr8", _16le, 0, CPU_DISASSEMBLE_NAME(avr8) },
- { "capricorn", _8bit, 0, CPU_DISASSEMBLE_NAME(capricorn) },
- { "ccpu", _8bit, 0, CPU_DISASSEMBLE_NAME(ccpu) },
- { "cdp1801", _8bit, 0, CPU_DISASSEMBLE_NAME(cdp1801) },
- { "cdp1802", _8bit, 0, CPU_DISASSEMBLE_NAME(cdp1802) },
- { "clipper", _16le, 0, CPU_DISASSEMBLE_NAME(clipper) },
- { "coldfire", _16be, 0, CPU_DISASSEMBLE_NAME(coldfire) },
- { "cop410", _8bit, 0, CPU_DISASSEMBLE_NAME(cop410) },
- { "cop420", _8bit, 0, CPU_DISASSEMBLE_NAME(cop420) },
- { "cop444", _8bit, 0, CPU_DISASSEMBLE_NAME(cop444) },
- { "cop424", _8bit, 0, CPU_DISASSEMBLE_NAME(cop424) },
- { "cp1610", _16be, -1, CPU_DISASSEMBLE_NAME(cp1610) },
- { "cquestlin", _64be, -3, CPU_DISASSEMBLE_NAME(cquestlin) },
- { "cquestrot", _64be, -3, CPU_DISASSEMBLE_NAME(cquestrot) },
- { "cquestsnd", _64be, -3, CPU_DISASSEMBLE_NAME(cquestsnd) },
- { "ds5002fp", _8bit, 0, CPU_DISASSEMBLE_NAME(ds5002fp) },
- { "dsp16a", _16le, -1, CPU_DISASSEMBLE_NAME(dsp16a) },
- { "dsp32c", _32le, 0, CPU_DISASSEMBLE_NAME(dsp32c) },
- { "dsp56k", _16le, -1, CPU_DISASSEMBLE_NAME(dsp56k) },
- { "e0c6200", _16be, -1, CPU_DISASSEMBLE_NAME(e0c6200) },
- { "esrip", _64be, 0, CPU_DISASSEMBLE_NAME(esrip) },
- { "f8", _8bit, 0, CPU_DISASSEMBLE_NAME(f8) },
- { "g65816", _8bit, 0, CPU_DISASSEMBLE_NAME(g65816_generic) },
- { "h6280", _8bit, 0, CPU_DISASSEMBLE_NAME(h6280) },
-// { "h8", _16be, 0, CPU_DISASSEMBLE_NAME(h8) },
-// { "h8_24", _16be, 0, CPU_DISASSEMBLE_NAME(h8_24) },
-// { "h8_32", _16be, 0, CPU_DISASSEMBLE_NAME(h8_32) },
- { "hc11", _8bit, 0, CPU_DISASSEMBLE_NAME(hc11) },
- { "hcd62121", _8bit, 0, CPU_DISASSEMBLE_NAME(hcd62121) },
- { "hd61700", _8bit, 0, CPU_DISASSEMBLE_NAME(hd61700) },
- { "hd6301", _8bit, 0, CPU_DISASSEMBLE_NAME(hd6301) },
- { "hd6309", _8bit, 0, CPU_DISASSEMBLE_NAME(hd6309) },
- { "hd63701", _8bit, 0, CPU_DISASSEMBLE_NAME(hd63701) },
- { "hmcs40", _16le, -1, CPU_DISASSEMBLE_NAME(hmcs40) },
- { "hp_hybrid", _16be, -1, CPU_DISASSEMBLE_NAME(hp_hybrid) },
- { "hp_5061_3001",_16be, -1, CPU_DISASSEMBLE_NAME(hp_5061_3001) },
- { "hyperstone", _16be, 0, CPU_DISASSEMBLE_NAME(hyperstone_generic) },
- { "i4004", _8bit, 0, CPU_DISASSEMBLE_NAME(i4004) },
- { "i4040", _8bit, 0, CPU_DISASSEMBLE_NAME(i4040) },
- { "i8008", _8bit, 0, CPU_DISASSEMBLE_NAME(i8008) },
- { "i8051", _8bit, 0, CPU_DISASSEMBLE_NAME(i8051) },
- { "i8052", _8bit, 0, CPU_DISASSEMBLE_NAME(i8052) },
- { "i8085", _8bit, 0, CPU_DISASSEMBLE_NAME(i8085) },
- { "i8089", _8bit, 0, CPU_DISASSEMBLE_NAME(i8089) },
- { "i80c51", _8bit, 0, CPU_DISASSEMBLE_NAME(i80c51) },
- { "i80c52", _8bit, 0, CPU_DISASSEMBLE_NAME(i80c52) },
- { "i860", _64le, 0, CPU_DISASSEMBLE_NAME(i860) },
- { "i960", _32le, 0, CPU_DISASSEMBLE_NAME(i960) },
- { "ie15", _8bit, 0, CPU_DISASSEMBLE_NAME(ie15) },
- { "jaguardsp", _16be, 0, CPU_DISASSEMBLE_NAME(jaguardsp) },
- { "jaguargpu", _16be, 0, CPU_DISASSEMBLE_NAME(jaguargpu) },
- { "konami", _8bit, 0, CPU_DISASSEMBLE_NAME(konami) },
- { "lh5801", _8bit, 0, CPU_DISASSEMBLE_NAME(lh5801) },
- { "lr35902", _8bit, 0, CPU_DISASSEMBLE_NAME(lr35902) },
- { "m58846", _16le, -1, CPU_DISASSEMBLE_NAME(m58846) },
- { "m37710", _8bit, 0, CPU_DISASSEMBLE_NAME(m37710_generic) },
- { "m6800", _8bit, 0, CPU_DISASSEMBLE_NAME(m6800) },
- { "m68000", _16be, 0, CPU_DISASSEMBLE_NAME(m68000) },
- { "m68008", _16be, 0, CPU_DISASSEMBLE_NAME(m68008) },
- { "m6801", _8bit, 0, CPU_DISASSEMBLE_NAME(m6801) },
- { "m68010", _16be, 0, CPU_DISASSEMBLE_NAME(m68010) },
- { "m6802", _8bit, 0, CPU_DISASSEMBLE_NAME(m6802) },
- { "m68020", _16be, 0, CPU_DISASSEMBLE_NAME(m68020) },
- { "m6803", _8bit, 0, CPU_DISASSEMBLE_NAME(m6803) },
- { "m68030", _16be, 0, CPU_DISASSEMBLE_NAME(m68030) },
- { "m68040", _16be, 0, CPU_DISASSEMBLE_NAME(m68040) },
- { "m6805", _8bit, 0, CPU_DISASSEMBLE_NAME(m6805) },
- { "m146805", _8bit, 0, CPU_DISASSEMBLE_NAME(m146805) },
- { "m68hc05", _8bit, 0, CPU_DISASSEMBLE_NAME(m68hc05) },
- { "m6808", _8bit, 0, CPU_DISASSEMBLE_NAME(m6808) },
- { "m6809", _8bit, 0, CPU_DISASSEMBLE_NAME(m6809) },
- { "m68340", _16be, 0, CPU_DISASSEMBLE_NAME(m68340) },
- { "mb86233", _32le, -2, CPU_DISASSEMBLE_NAME(mb86233) },
- { "mb88", _8bit, 0, CPU_DISASSEMBLE_NAME(mb88) },
- { "mcs48", _8bit, 0, CPU_DISASSEMBLE_NAME(mcs48) },
- { "minx", _8bit, 0, CPU_DISASSEMBLE_NAME(minx) },
- { "mips3be", _32be, 0, CPU_DISASSEMBLE_NAME(mips3be) },
- { "mips3le", _32le, 0, CPU_DISASSEMBLE_NAME(mips3le) },
- { "mn10200", _16le, 0, CPU_DISASSEMBLE_NAME(mn10200) },
- { "nanoprocessor",_8bit, 0, CPU_DISASSEMBLE_NAME(hp_nanoprocessor) },
- { "nec", _8bit, 0, CPU_DISASSEMBLE_NAME(nec) },
- { "nsc8105", _8bit, 0, CPU_DISASSEMBLE_NAME(nsc8105) },
- { "pdp1", _32be, 0, CPU_DISASSEMBLE_NAME(pdp1) },
- { "pdp8", _16be, 0, CPU_DISASSEMBLE_NAME(pdp8) },
- { "pic16c5x", _16le, -1, CPU_DISASSEMBLE_NAME(pic16c5x) },
- { "pic16c62x", _16le, -1, CPU_DISASSEMBLE_NAME(pic16c62x) },
- { "powerpc", _32be, 0, CPU_DISASSEMBLE_NAME(powerpc) },
- { "pps4", _8bit, 0, CPU_DISASSEMBLE_NAME(pps4) },
- { "psxcpu", _32le, 0, CPU_DISASSEMBLE_NAME(psxcpu_generic) },
- { "r3000be", _32be, 0, CPU_DISASSEMBLE_NAME(r3000be) },
- { "r3000le", _32le, 0, CPU_DISASSEMBLE_NAME(r3000le) },
- { "rsp", _32le, 0, CPU_DISASSEMBLE_NAME(rsp) },
- { "s2650", _8bit, 0, CPU_DISASSEMBLE_NAME(s2650) },
- { "saturn", _8bit, 0, CPU_DISASSEMBLE_NAME(saturn) },
- { "sc61860", _8bit, 0, CPU_DISASSEMBLE_NAME(sc61860) },
- { "scmp", _8bit, 0, CPU_DISASSEMBLE_NAME(scmp) },
- { "scudsp", _32be, 0, CPU_DISASSEMBLE_NAME(scudsp) },
- { "se3208", _16le, 0, CPU_DISASSEMBLE_NAME(se3208) },
- { "sh2", _16be, 0, CPU_DISASSEMBLE_NAME(sh2) },
- { "sh4", _16le, 0, CPU_DISASSEMBLE_NAME(sh4) },
- { "sh4be", _16be, 0, CPU_DISASSEMBLE_NAME(sh4be) },
- { "sharc", _48le, -2, CPU_DISASSEMBLE_NAME(sharc) },
- { "sm500", _8bit, 0, CPU_DISASSEMBLE_NAME(sm500) },
- { "sm510", _8bit, 0, CPU_DISASSEMBLE_NAME(sm510) },
- { "sm511", _8bit, 0, CPU_DISASSEMBLE_NAME(sm511) },
- { "sm5a", _8bit, 0, CPU_DISASSEMBLE_NAME(sm5a) },
- { "sm8500", _8bit, 0, CPU_DISASSEMBLE_NAME(sm8500) },
- { "sparcv7", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv7) },
- { "sparcv8", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv8) },
- { "sparcv9", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9) },
- { "sparcv9vis1", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis1) },
- { "sparcv9vis2", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis2) },
- { "sparcv9vis2p",_32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis2p) },
- { "sparcv9vis3", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis3) },
- { "sparcv9vis3b",_32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis3b) },
- { "spc700", _8bit, 0, CPU_DISASSEMBLE_NAME(spc700) },
- { "ssem", _32le, 0, CPU_DISASSEMBLE_NAME(ssem) },
- { "ssp1601", _16be, -1, CPU_DISASSEMBLE_NAME(ssp1601) },
-// { "superfx", _8bit, 0, CPU_DISASSEMBLE_NAME(superfx) },
- { "t11", _16le, 0, CPU_DISASSEMBLE_NAME(t11) },
-// { "t90", _8bit, 0, CPU_DISASSEMBLE_NAME(t90) },
- { "tlcs900", _8bit, 0, CPU_DISASSEMBLE_NAME(tlcs900) },
- { "tms0980", _16be, 0, CPU_DISASSEMBLE_NAME(tms0980) },
- { "tms1000", _8bit, 0, CPU_DISASSEMBLE_NAME(tms1000) },
- { "tms1100", _8bit, 0, CPU_DISASSEMBLE_NAME(tms1100) },
- { "tms32010", _16be, -1, CPU_DISASSEMBLE_NAME(tms32010) },
- { "tms32025", _16be, -1, CPU_DISASSEMBLE_NAME(tms32025) },
- { "tms3203x", _32le, -2, CPU_DISASSEMBLE_NAME(tms3203x) },
- { "tms32051", _16le, -1, CPU_DISASSEMBLE_NAME(tms32051) },
- { "tms34010", _8bit, 3, CPU_DISASSEMBLE_NAME(tms34010) },
- { "tms34020", _8bit, 3, CPU_DISASSEMBLE_NAME(tms34020) },
- { "tms57002", _32le, -2, CPU_DISASSEMBLE_NAME(tms57002) },
- { "tms7000", _8bit, 0, CPU_DISASSEMBLE_NAME(tms7000) },
- { "tms9900", _16be, 0, CPU_DISASSEMBLE_NAME(tms9900) },
- { "tms9980", _8bit, 0, CPU_DISASSEMBLE_NAME(tms9980) },
- { "tms9995", _8bit, 0, CPU_DISASSEMBLE_NAME(tms9995) },
- { "tp0320", _16be, 0, CPU_DISASSEMBLE_NAME(tp0320) },
- { "tx0_64kw", _32be, -2, CPU_DISASSEMBLE_NAME(tx0_64kw) },
- { "tx0_8kw", _32be, -2, CPU_DISASSEMBLE_NAME(tx0_8kw) },
- { "ucom4", _8bit, 0, CPU_DISASSEMBLE_NAME(ucom4) },
- { "unsp", _16be, 0, CPU_DISASSEMBLE_NAME(unsp) },
- { "upd7725", _32be, 0, CPU_DISASSEMBLE_NAME(upd7725) },
- { "upd7801", _8bit, 0, CPU_DISASSEMBLE_NAME(upd7801) },
- { "upd7807", _8bit, 0, CPU_DISASSEMBLE_NAME(upd7807) },
- { "upd7810", _8bit, 0, CPU_DISASSEMBLE_NAME(upd7810) },
- { "upd78c05", _8bit, 0, CPU_DISASSEMBLE_NAME(upd78c05) },
- { "upi41", _8bit, 0, CPU_DISASSEMBLE_NAME(upi41) },
- { "v60", _8bit, 0, CPU_DISASSEMBLE_NAME(v60) },
- { "v70", _8bit, 0, CPU_DISASSEMBLE_NAME(v70) },
- { "v810", _16le, 0, CPU_DISASSEMBLE_NAME(v810) },
- { "x86_16", _8bit, 0, CPU_DISASSEMBLE_NAME(x86_16) },
- { "x86_32", _8bit, 0, CPU_DISASSEMBLE_NAME(x86_32) },
- { "x86_64", _8bit, 0, CPU_DISASSEMBLE_NAME(x86_64) },
- { "z180", _8bit, 0, CPU_DISASSEMBLE_NAME(z180) },
- { "z8", _8bit, 0, CPU_DISASSEMBLE_NAME(z8) },
- { "z80", _8bit, 0, CPU_DISASSEMBLE_NAME(z80) },
-// { "z8000", _16be, 0, CPU_DISASSEMBLE_NAME(z8000) },
+ offs_t pc;
+ offs_t size;
+ std::string dasm;
};
+unidasm_data_buffer::unidasm_data_buffer(util::disasm_interface *_disasm, const dasm_table_entry *_entry) : disasm(_disasm), entry(_entry)
+{
+ u32 flags = disasm->interface_flags();
+ u32 page_mask = flags & util::disasm_interface::PAGED ? (1 << disasm->page_address_bits()) - 1 : 0;
+
+ if(flags & util::disasm_interface::NONLINEAR_PC) {
+ switch(entry->pcshift) {
+ case -1:
+ lr8 = [](offs_t pc) -> u8 { throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer: r8 access on 16-bits granularity bus\n"); };
+ lr16 = [this](offs_t pc) -> u16 {
+ const u16 *src = get_ptr<u16>(pc);
+ return src[0];
+ };
+
+ switch(entry->endian) {
+ case le:
+ lr32 = [this, page_mask](offs_t pc) -> u32 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u32 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u16>(disasm->pc_linear_to_real(lpc)) << (j*16);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr64 = [this, page_mask](offs_t pc) -> u64 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u64 r = 0;
+ for(int j=0; j != 4; j++) {
+ r |= u64(get<u16>(disasm->pc_linear_to_real(lpc))) << (j*16);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ break;
+
+ case be:
+ lr32 = [this, page_mask](offs_t pc) -> u32 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u32 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u16>(disasm->pc_linear_to_real(lpc)) << ((1-j)*16);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr64 = [this, page_mask](offs_t pc) -> u64 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u64 r = 0;
+ for(int j=0; j != 4; j++) {
+ r |= u64(get<u16>(disasm->pc_linear_to_real(lpc))) << ((3-j)*16);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ break;
+ }
+ break;
+
+ case 0:
+ lr8 = [this](offs_t pc) -> u8 {
+ const u8 *src = get_ptr<u8>(pc);
+ return src[0];
+ };
+
+ switch(entry->endian) {
+ case le:
+ lr16 = [this, page_mask](offs_t pc) -> u16 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u16 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u8>(disasm->pc_linear_to_real(lpc)) << (j*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr32 = [this, page_mask](offs_t pc) -> u32 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u32 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u8>(disasm->pc_linear_to_real(lpc)) << (j*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr64 = [this, page_mask](offs_t pc) -> u64 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u64 r = 0;
+ for(int j=0; j != 8; j++) {
+ r |= u64(get<u8>(disasm->pc_linear_to_real(lpc))) << (j*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ break;
+
+ case be:
+ lr16 = [this, page_mask](offs_t pc) -> u16 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u16 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u8>(disasm->pc_linear_to_real(lpc)) << ((1-j)*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr32 = [this, page_mask](offs_t pc) -> u32 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u32 r = 0;
+ for(int j=0; j != 2; j++) {
+ r |= get<u8>(disasm->pc_linear_to_real(lpc)) << ((3-j)*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ lr64 = [this, page_mask](offs_t pc) -> u64 {
+ offs_t lpc = disasm->pc_real_to_linear(pc);
+ u64 r = 0;
+ for(int j=0; j != 8; j++) {
+ r |= u64(get<u8>(disasm->pc_linear_to_real(lpc))) << ((7-j)*8);
+ lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask);
+ }
+ return r;
+ };
+ break;
+ }
+ break;
+ }
+ } else {
+ switch(entry->pcshift) {
+ case 0:
+ lr8 = [this](offs_t pc) -> u8 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ p[0]
+ : 0x00;
+ };
+ switch(entry->endian) {
+ case le:
+ lr16 = [this](offs_t pc) -> u16 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ p[0] |
+ (p[1] << 8)
+ : 0x0000;
+ };
+ lr32 = [this](offs_t pc) -> u32 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ p[0] |
+ (p[1] << 8) |
+ (p[2] << 16) |
+ (p[3] << 24)
+ : 0x00000000;
+ };
+ lr64 = [this](offs_t pc) -> u64 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ p[0] |
+ (p[1] << 8) |
+ (p[2] << 16) |
+ (p[3] << 24) |
+ (u64(p[4]) << 32) |
+ (u64(p[5]) << 40) |
+ (u64(p[6]) << 48) |
+ (u64(p[7]) << 56)
+ : 0x0000000000000000; };
+ break;
+ case be:
+ lr16 = [this](offs_t pc) -> u16 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ (p[0] << 8) |
+ p[1]
+ : 0x0000;
+ };
+ lr32 = [this](offs_t pc) -> u32 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ (p[0] << 24) |
+ (p[1] << 16) |
+ (p[2] << 8) |
+ p[3]
+ : 0x00000000;
+ };
+ lr64 = [this](offs_t pc) -> u64 {
+ const u8 *p = get_ptr<u8>(pc);
+ return p ?
+ (u64(p[0]) << 56) |
+ (u64(p[1]) << 48) |
+ (u64(p[2]) << 40) |
+ (u64(p[3]) << 32) |
+ (p[4] << 24) |
+ (p[5] << 16) |
+ (p[6] << 8) |
+ p[7]
+ : 0x0000000000000000; };
+ break;
+ }
+ break;
+
+ case -1:
+ lr8 = [](offs_t pc) -> u8 { abort(); };
+ lr16 = [this](offs_t pc) -> u16 {
+ const u16 *p = get_ptr<u16>(pc);
+ return p ?
+ p[0]
+ : 0x0000;
+ };
+ switch(entry->endian) {
+ case le:
+ lr32 = [this](offs_t pc) -> u32 {
+ const u16 *p = get_ptr<u16>(pc);
+ return p ?
+ p[0] |
+ (p[1] << 16)
+ : 0x00000000;
+ };
+ lr64 = [this](offs_t pc) -> u64 {
+ const u16 *p = get_ptr<u16>(pc);
+ return p ?
+ p[0] |
+ (p[1] << 16) |
+ (u64(p[2]) << 32) |
+ (u64(p[3]) << 48)
+ : 0x0000000000000000;
+ };
+ break;
+ case be:
+ lr32 = [this](offs_t pc) -> u32 {
+ const u16 *p = get_ptr<u16>(pc);
+ return p ?
+ (p[0] << 16)|
+ p[1]
+ : 0x00000000;
+ };
+ lr64 = [this](offs_t pc) -> u64 {
+ const u16 *p = get_ptr<u16>(pc);
+ return p ?
+ (u64(p[0]) << 48) |
+ (u64(p[1]) << 32) |
+ (p[2] << 16) |
+ p[3]
+ : 0x0000000000000000;
+ };
+ break;
+ }
+ break;
+
+ case -2:
+ lr8 = [](offs_t pc) -> u8 { abort(); };
+ lr16 = [](offs_t pc) -> u16 { abort(); };
+ lr32 = [this](offs_t pc) -> u16 {
+ const u32 *p = get_ptr<u32>(pc);
+ return p ?
+ p[0]
+ : 0x00000000;
+ };
+ switch(entry->endian) {
+ case le:
+ lr64 = [this](offs_t pc) -> u64 {
+ const u32 *p = get_ptr<u32>(pc);
+ return p ?
+ p[0] |
+ (u64(p[1]) << 32)
+ : 0x0000000000000000;
+ };
+ break;
+ case be:
+ lr64 = [this](offs_t pc) -> u64 {
+ const u32 *p = get_ptr<u32>(pc);
+ return p ?
+ (u64(p[0]) << 32) |
+ p[1]
+ : 0x0000000000000000;
+ };
+ break;
+ }
+ break;
+
+ case -3:
+ lr8 = [](offs_t pc) -> u8 { abort(); };
+ lr16 = [](offs_t pc) -> u16 { abort(); };
+ lr32 = [](offs_t pc) -> u32 { abort(); };
+ lr64 = [this](offs_t pc) -> u64 {
+ const u64 *p = get_ptr<u64>(pc);
+ return p ?
+ p[0]
+ : 0x0000000000000000;
+ };
+ break;
+
+ case 3:
+ lr8 = [](offs_t pc) -> u8 { abort(); };
+ lr32 = [](offs_t pc) -> u32 { abort(); };
+ lr64 = [](offs_t pc) -> u64 { abort(); };
+ lr16 = [this](offs_t pc) -> u16 {
+ if(pc < base_pc)
+ return 0x0000;
+ offs_t delta = (pc - base_pc) >> 3;
+ if(delta >= size)
+ return 0x0000;
+ return reinterpret_cast<const u16 *>(&data[delta])[0];
+ };
+ break;
+
+ default:
+ abort();
+ }
+ }
+}
+
+void unidasm_data_buffer::decrypt(const unidasm_data_buffer &buffer, bool opcode)
+{
+ abort();
+}
static int parse_options(int argc, char *argv[], options *opts)
{
@@ -420,92 +836,87 @@ static int parse_options(int argc, char *argv[], options *opts)
memset(opts, 0, sizeof(*opts));
// loop through arguments
- for (unsigned arg = 1; arg < argc; arg++)
- {
+ for(unsigned arg = 1; arg < argc; arg++) {
char *curarg = argv[arg];
// is it a switch?
- if (curarg[0] == '-')
- {
- if (pending_base || pending_arch || pending_mode || pending_skip || pending_count)
+ if(curarg[0] == '-') {
+ if(pending_base || pending_arch || pending_mode || pending_skip || pending_count)
goto usage;
- if (tolower((uint8_t)curarg[1]) == 'a')
+ if(tolower((uint8_t)curarg[1]) == 'a')
pending_arch = true;
- else if (tolower((uint8_t)curarg[1]) == 'b')
+ else if(tolower((uint8_t)curarg[1]) == 'b')
pending_base = true;
- else if (tolower((uint8_t)curarg[1]) == 'f')
+ else if(tolower((uint8_t)curarg[1]) == 'f')
opts->flipped = true;
- else if (tolower((uint8_t)curarg[1]) == 'l')
+ else if(tolower((uint8_t)curarg[1]) == 'l')
opts->lower = true;
- else if (tolower((uint8_t)curarg[1]) == 'm')
+ else if(tolower((uint8_t)curarg[1]) == 'm')
pending_mode = true;
- else if (tolower((uint8_t)curarg[1]) == 's')
+ else if(tolower((uint8_t)curarg[1]) == 's')
pending_skip = true;
- else if (tolower((uint8_t)curarg[1]) == 'c')
+ else if(tolower((uint8_t)curarg[1]) == 'c')
pending_count = true;
- else if (tolower((uint8_t)curarg[1]) == 'n')
+ else if(tolower((uint8_t)curarg[1]) == 'n')
opts->norawbytes = true;
- else if (tolower((uint8_t)curarg[1]) == 'u')
+ else if(tolower((uint8_t)curarg[1]) == 'u')
opts->upper = true;
else
goto usage;
}
// base PC
- else if (pending_base)
+ else if(pending_base)
{
int result;
- if (curarg[0] == '0' && curarg[1] == 'x')
+ if(curarg[0] == '0' && curarg[1] == 'x')
result = sscanf(&curarg[2], "%x", &opts->basepc);
- else if (curarg[0] == '$')
+ else if(curarg[0] == '$')
result = sscanf(&curarg[1], "%x", &opts->basepc);
else
result = sscanf(&curarg[0], "%x", &opts->basepc);
- if (result != 1)
+ if(result != 1)
goto usage;
pending_base = false;
}
// mode
- else if (pending_mode)
+ else if(pending_mode)
{
- if (sscanf(curarg, "%d", &opts->mode) != 1)
+ if(sscanf(curarg, "%d", &opts->mode) != 1)
goto usage;
pending_mode = false;
}
// architecture
- else if (pending_arch)
- {
+ else if(pending_arch) {
int curarch;
- for (curarch = 0; curarch < ARRAY_LENGTH(dasm_table); curarch++)
- if (core_stricmp(curarg, dasm_table[curarch].name) == 0)
+ for(curarch = 0; curarch < ARRAY_LENGTH(dasm_table); curarch++)
+ if(core_stricmp(curarg, dasm_table[curarch].name) == 0)
break;
- if (curarch == ARRAY_LENGTH(dasm_table))
+ if(curarch == ARRAY_LENGTH(dasm_table))
goto usage;
opts->dasm = &dasm_table[curarch];
pending_arch = false;
}
// skip bytes
- else if (pending_skip)
- {
- if (sscanf(curarg, "%d", &opts->skip) != 1)
+ else if(pending_skip) {
+ if(sscanf(curarg, "%d", &opts->skip) != 1)
goto usage;
pending_skip = false;
}
// size
- else if (pending_count)
- {
- if (sscanf(curarg, "%d", &opts->count) != 1)
+ else if(pending_count) {
+ if(sscanf(curarg, "%d", &opts->count) != 1)
goto usage;
pending_count = false;
}
// filename
- else if (opts->filename == nullptr)
+ else if(opts->filename == nullptr)
opts->filename = curarg;
// fail
@@ -514,11 +925,11 @@ static int parse_options(int argc, char *argv[], options *opts)
}
// if we have a dangling option, error
- if (pending_base || pending_arch || pending_mode || pending_skip || pending_count)
+ if(pending_base || pending_arch || pending_mode || pending_skip || pending_count)
goto usage;
// if no file or no architecture, fail
- if (opts->filename == nullptr || opts->dasm == nullptr)
+ if(opts->filename == nullptr || opts->dasm == nullptr)
goto usage;
return 0;
@@ -531,12 +942,12 @@ usage:
const int colwidth = 1 + std::strlen(std::max_element(std::begin(dasm_table), std::end(dasm_table), [](const dasm_table_entry &a, const dasm_table_entry &b) { return std::strlen(a.name) < std::strlen(b.name); })->name);
const int columns = std::max(1, 80 / colwidth);
const int numrows = (ARRAY_LENGTH(dasm_table) + columns - 1) / columns;
- for (unsigned curarch = 0; curarch < numrows * columns; curarch++)
+ for(unsigned curarch = 0; curarch < numrows * columns; curarch++)
{
const int row = curarch / columns;
const int col = curarch % columns;
const int index = col * numrows + row;
- if (col == 0)
+ if(col == 0)
printf("\n ");
printf("%-*s", colwidth, (index < ARRAY_LENGTH(dasm_table)) ? dasm_table[index].name : "");
}
@@ -547,191 +958,311 @@ usage:
int main(int argc, char *argv[])
{
- osd_file::error filerr;
- int displayendian;
- int displaychunk;
- uint32_t curbyte;
- uint32_t length;
- int maxchunks;
- uint32_t curpc;
+ // Parse options first
options opts;
- int numbytes;
- void *data;
- int result = 0;
-
- // parse options first
- if (parse_options(argc, argv, &opts))
+ if(parse_options(argc, argv, &opts))
return 1;
- // load the file
- filerr = util::core_file::load(opts.filename, &data, length);
- if (filerr != osd_file::error::NONE)
+ // Load the file
+ void *data;
+ uint32_t length;
+ osd_file::error filerr = util::core_file::load(opts.filename, &data, length);
+ if(filerr != osd_file::error::NONE)
{
fprintf(stderr, "Error opening file '%s'\n", opts.filename);
return 1;
}
- // precompute parameters
- displaychunk = (opts.dasm->display / 2) + 1;
- displayendian = opts.dasm->display % 2;
- switch (displaychunk)
- {
- case 1: maxchunks = 6; break;
- case 2: maxchunks = 3; break;
- default: maxchunks = 1; break;
+ // Build the disasm object
+ std::unique_ptr<util::disasm_interface> disasm(opts.dasm->alloc());
+ u32 flags = disasm->interface_flags();
+
+ // Compute the granularity in bytes (1-8)
+ offs_t granularity = opts.dasm->pcshift < 0 ? disasm->opcode_alignment() << -opts.dasm->pcshift : disasm->opcode_alignment() >> opts.dasm->pcshift;
+
+ // Build the base buffer and fill it (with a margin)
+ unidasm_data_buffer base_buffer(disasm.get(), opts.dasm);
+ u32 rounded_size = (((length - opts.skip) | (granularity - 1)) & ~(granularity - 1));
+ base_buffer.data.resize(rounded_size + 8, 0x00);
+ base_buffer.size = length;
+ base_buffer.base_pc = opts.basepc;
+ memcpy(&base_buffer.data[0], (const u8 *)data + opts.skip, length - opts.skip);
+
+ // Build the decryption buffers if needed
+ unidasm_data_buffer opcodes_buffer(disasm.get(), opts.dasm), params_buffer(disasm.get(), opts.dasm);
+ if(flags & util::disasm_interface::INTERNAL_DECRYPTION) {
+ opcodes_buffer.decrypt(base_buffer, true);
+ if((flags & util::disasm_interface::SPLIT_DECRYPTION) == util::disasm_interface::SPLIT_DECRYPTION)
+ params_buffer.decrypt(base_buffer, false);
}
- // run it
- try
- {
- if (length > opts.skip)
- length = length - opts.skip;
- if ((length > opts.count) && (opts.count != 0))
- length = opts.count;
- curpc = opts.basepc;
-
- std::stringstream stream;
- for (curbyte = 0; curbyte < length; curbyte += numbytes)
- {
- uint8_t *oprom = (uint8_t *)data + opts.skip + curbyte;
- uint32_t pcdelta;
- int numchunks;
+ // Select the buffers to actually use
+ unidasm_data_buffer *popcodes = opcodes_buffer.data.empty() ? &base_buffer : &opcodes_buffer;
+ unidasm_data_buffer *pparams = params_buffer.data.empty() ? popcodes : &params_buffer;
- // disassemble
- stream.str("");
- pcdelta = (*opts.dasm->func)(nullptr, stream, curpc, oprom, oprom, opts.mode) & DASMFLAG_LENGTHMASK;
- std::string buffer = stream.str();
+ // Compute the pc warparound
+ offs_t pclength = opts.dasm->pcshift < 0 ? rounded_size >> -opts.dasm->pcshift : rounded_size << opts.dasm->pcshift;
+ offs_t limit = opts.basepc + pclength;
+ offs_t pc_mask;
+ if(!limit)
+ pc_mask = 0xffffffff;
+ else {
+ for(pc_mask = 2; pc_mask && pc_mask < limit; pc_mask *= 2);
+ pc_mask--;
+ }
- if (opts.dasm->pcshift < 0)
- numbytes = pcdelta << -opts.dasm->pcshift;
- else
- numbytes = pcdelta >> opts.dasm->pcshift;
-
- // force upper or lower
- if (opts.lower)
- {
- std::transform(
- std::begin(buffer),
- std::end(buffer),
- std::begin(buffer),
- [](char c) { return tolower(c); });
- }
- else if (opts.upper)
- {
- std::transform(
- std::begin(buffer),
- std::end(buffer),
- std::begin(buffer),
- [](char c) { return toupper(c); });
- }
+ // Compute the page warparound
+ offs_t page_mask = flags & util::disasm_interface::PAGED ? (1 << disasm->page_address_bits()) - 1 : 0;
- // round to the nearest display chunk
- numbytes = ((numbytes + displaychunk - 1) / displaychunk) * displaychunk;
- if (numbytes == 0)
- numbytes = displaychunk;
- numchunks = numbytes / displaychunk;
-
- // non-flipped case
- if (!opts.flipped)
- {
- // output the address
- printf("%08X: ", curpc);
-
- // output the raw bytes
- if (!opts.norawbytes)
- {
- int firstchunks = (numchunks < maxchunks) ? numchunks : maxchunks;
- int chunknum, bytenum;
- for (chunknum = 0; chunknum < firstchunks; chunknum++)
- {
- for (bytenum = 0; bytenum < displaychunk; bytenum++)
- printf("%02X", oprom[displayendian ? (displaychunk - 1 - bytenum) : bytenum]);
- printf(" ");
- oprom += displaychunk;
- }
- for ( ; chunknum < maxchunks; chunknum++)
- printf("%*s ", displaychunk * 2, "");
- printf(" ");
- }
-
- // output the disassembly
- printf("%s\n", buffer.c_str());
-
- // output additional raw bytes
- if (!opts.norawbytes && numchunks > maxchunks)
- {
- for (numchunks -= maxchunks; numchunks > 0; numchunks -= maxchunks)
- {
- int firstchunks = (numchunks < maxchunks) ? numchunks : maxchunks;
- int chunknum, bytenum;
- printf(" ");
- for (chunknum = 0; chunknum < firstchunks; chunknum++)
- {
- for (bytenum = 0; bytenum < displaychunk; bytenum++)
- printf("%02X", oprom[displayendian ? (displaychunk - 1 - bytenum) : bytenum]);
- printf(" ");
- oprom += displaychunk;
- }
- printf("\n");
- }
- }
- }
+ // Next pc computation lambdas
+ std::function<offs_t (offs_t, offs_t)> next_pc;
+ std::function<offs_t (offs_t, offs_t)> next_pc_wrap;
+ if(flags & util::disasm_interface::NONLINEAR_PC) {
+ // lfsr pc is always paged
+ next_pc = [pc_mask, page_mask, dis = disasm.get()](offs_t pc, offs_t size) {
+ offs_t lpc = dis->pc_real_to_linear(pc);
+ offs_t lpce = lpc + size;
+ if((lpc ^ lpce) & ~page_mask)
+ lpce = (lpc | page_mask) + 1;
+ lpce &= pc_mask;
+ return dis->pc_linear_to_real(lpce);
+ };
+ next_pc_wrap = [page_mask, dis = disasm.get()](offs_t pc, offs_t size) {
+ offs_t lpc = dis->pc_real_to_linear(pc);
+ offs_t lpce = (lpc & ~page_mask) | ((lpc + size) & page_mask);
+ return dis->pc_linear_to_real(lpce);
+ };
- // flipped case
- else
- {
- // output the disassembly and address
- printf("\t%-40s ; %08X", buffer.c_str(), curpc);
-
- // output the raw bytes
- if (!opts.norawbytes)
- {
- int chunknum, bytenum;
- printf(": ");
- for (chunknum = 0; chunknum < numchunks; chunknum++)
- {
- for (bytenum = 0; bytenum < displaychunk; bytenum++)
- printf("%02X", oprom[displayendian ? (displaychunk - 1 - bytenum) : bytenum]);
- printf(" ");
- oprom += displaychunk;
- }
- }
- printf("\n");
- }
+ } else if(flags & util::disasm_interface::PAGED) {
+ next_pc = [pc_mask, page_mask](offs_t pc, offs_t size) {
+ offs_t pce = pc + size;
+ if((pc ^ pce) & ~page_mask)
+ pce = (pc | page_mask) + 1;
+ pce &= pc_mask;
+ return pce;
+ };
+ next_pc_wrap = [page_mask](offs_t pc, offs_t size) {
+ offs_t pce = (pc & ~page_mask) | ((pc + size) & page_mask);
+ return pce;
+ };
- // advance
- curpc += pcdelta;
- }
+ } else {
+ next_pc = [pc_mask](offs_t pc, offs_t size) {
+ return (pc + size) & pc_mask;
+ };
+ next_pc_wrap = [pc_mask](offs_t pc, offs_t size) {
+ return (pc + size) & pc_mask;
+ };
}
- catch (emu_fatalerror &fatal)
- {
- fprintf(stderr, "%s\n", fatal.string());
- result = 1;
- if (fatal.exitcode() != 0)
- result = fatal.exitcode();
+
+ // Compute the shift amount from pc delta to granularity-sized elements
+ u32 granularity_shift = 31 - count_leading_zeros(disasm->opcode_alignment());
+
+ // Number of pc steps to disassemble
+ u32 count = pclength;
+
+ if((count > opts.count) && (opts.count != 0))
+ count = opts.count;
+
+ // pc to string conversion
+ std::function<std::string (offs_t pc)> pc_to_string;
+ int aw = 32 - count_leading_zeros(pc_mask);
+ bool is_octal = false; // Parameter? Per-cpu config?
+ if((flags & util::disasm_interface::PAGED2LEVEL) == util::disasm_interface::PAGED2LEVEL) {
+ int bits1 = disasm->page_address_bits();
+ int bits2 = disasm->page2_address_bits();
+ int bits3 = aw - bits1 - bits2;
+ offs_t sm1 = (1 << bits1) - 1;
+ int sh2 = bits1;
+ offs_t sm2 = (1 << bits2) - 1;
+ int sh3 = bits1+bits2;
+
+ if(is_octal) {
+ int nc1 = (bits1+2)/3;
+ int nc2 = (bits2+2)/3;
+ int nc3 = (bits3+2)/3;
+ pc_to_string = [nc1, nc2, nc3, sm1, sm2, sh2, sh3](offs_t pc) -> std::string {
+ return util::string_format("%0*o:%0*o:%0*o",
+ nc3, pc >> sh3,
+ nc2, (pc >> sh2) & sm2,
+ nc1, pc & sm1);
+ };
+ } else {
+ int nc1 = (bits1+3)/4;
+ int nc2 = (bits2+3)/4;
+ int nc3 = (bits3+3)/4;
+ pc_to_string = [nc1, nc2, nc3, sm1, sm2, sh2, sh3](offs_t pc) -> std::string {
+ return util::string_format("%0*x:%0*x:%0*x",
+ nc3, pc >> sh3,
+ nc2, (pc >> sh2) & sm2,
+ nc1, pc & sm1);
+ };
+ }
+
+ } else if(flags & util::disasm_interface::PAGED) {
+ int bits1 = disasm->page_address_bits();
+ int bits2 = aw - bits1;
+ offs_t sm1 = (1 << bits1) - 1;
+ int sh2 = bits1;
+
+ if(is_octal) {
+ int nc1 = (bits1+2)/3;
+ int nc2 = (bits2+2)/3;
+ pc_to_string = [nc1, nc2, sm1, sh2](offs_t pc) -> std::string {
+ return util::string_format("%0*o:%0*o",
+ nc2, pc >> sh2,
+ nc1, pc & sm1);
+ };
+ } else {
+ int nc1 = (bits1+3)/4;
+ int nc2 = (bits2+3)/4;
+ pc_to_string = [nc1, nc2, sm1, sh2](offs_t pc) -> std::string {
+ return util::string_format("%0*x:%0*x",
+ nc2, pc >> sh2,
+ nc1, pc & sm1);
+ };
+ }
+
+ } else {
+ int bits1 = aw;
+
+ if(is_octal) {
+ int nc1 = (bits1+2)/3;
+ pc_to_string = [nc1](offs_t pc) -> std::string {
+ return util::string_format("%0*o",
+ nc1, pc);
+ };
+ } else {
+ int nc1 = (bits1+3)/4;
+ pc_to_string = [nc1](offs_t pc) -> std::string {
+ return util::string_format("%0*x",
+ nc1, pc);
+ };
+ }
}
- catch (emu_exception &)
- {
- fprintf(stderr, "Caught unhandled emulator exception\n");
- result = 1;
+
+ // Lower/upper optional transform
+ std::function<std::string (const std::string &)> tf;
+ if(opts.lower)
+ tf = [](const std::string &str) -> std::string {
+ std::string result = str;
+ std::transform(result.begin(), result.end(), result.begin(), [](char c) { return tolower(c); });
+ return result;
+ };
+ else if(opts.upper)
+ tf = [](const std::string &str) -> std::string {
+ std::string result = str;
+ std::transform(result.begin(), result.end(), result.begin(), [](char c) { return toupper(c); });
+ return result;
+ };
+ else
+ tf = [](const std::string &str) -> std::string {
+ return str;
+ };
+
+
+ // Do the disassembly
+ std::vector<dasm_line> dasm_lines;
+ offs_t curpc = opts.basepc;
+ for(u32 i=0; i < count;) {
+ std::ostringstream stream;
+ offs_t result = disasm->disassemble(stream, curpc, *popcodes, *pparams);
+ offs_t len = result & util::disasm_interface::LENGTHMASK;
+ dasm_lines.emplace_back(dasm_line{ curpc, len, stream.str() });
+ curpc = next_pc(curpc, len);
+ i += len;
}
- catch (tag_add_exception &aex)
- {
- fprintf(stderr, "Tag '%s' already exists in tagged map\n", aex.tag());
- result = 1;
+
+ // Compute the extrema
+ offs_t max_len = 0;
+ size_t max_text = 0;
+ for(const auto &l : dasm_lines) {
+ if(max_len < l.size)
+ max_len = l.size;
+ size_t s = l.dasm.size();
+ if(max_text < s)
+ max_text = s;
}
- catch (std::exception &ex)
- {
- fprintf(stderr, "Caught unhandled %s exception: %s\n", typeid(ex).name(), ex.what());
- result = 1;
+
+ // Build the raw bytes generator and compute the field size
+ max_len >>= granularity_shift;
+ std::function<std::string (offs_t pc, offs_t size)> dump_raw_bytes;
+
+ switch(granularity) {
+ case 1:
+ dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string {
+ std::string result = "";
+ for(offs_t i=0; i != size; i++) {
+ if(i)
+ result += ' ';
+ result += util::string_format("%02x", base_buffer.r8(pc));
+ pc = next_pc(pc, step);
+ }
+ return result;
+ };
+ max_len = (max_len * 3) - 1;
+ break;
+
+ case 2:
+ dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string {
+ std::string result = "";
+ for(offs_t i=0; i != size; i++) {
+ if(i)
+ result += ' ';
+ result += util::string_format("%04x", base_buffer.r16(pc));
+ pc = next_pc(pc, step);
+ }
+ return result;
+ };
+ max_len = (max_len * 5) - 1;
+ break;
+
+ case 4:
+ dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string {
+ std::string result = "";
+ for(offs_t i=0; i != size; i++) {
+ if(i)
+ result += ' ';
+ result += util::string_format("%08x", base_buffer.r32(pc));
+ pc = next_pc(pc, step);
+ }
+ return result;
+ };
+ max_len = (max_len * 9) - 1;
+ break;
+
+ case 8:
+ dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string {
+ std::string result = "";
+ for(offs_t i=0; i != size; i++) {
+ if(i)
+ result += ' ';
+ result += util::string_format("%016x", base_buffer.r64(pc));
+ pc = next_pc(pc, step);
+ }
+ return result;
+ };
+ max_len = (max_len * 17) - 1;
+ break;
}
- catch (...)
- {
- fprintf(stderr, "Caught unhandled exception\n");
- result = 1;
+
+ if(opts.flipped) {
+ if(opts.norawbytes)
+ for(const auto &l : dasm_lines)
+ util::stream_format(std::cout, "%-*s ; %s\n", max_text, tf(l.dasm), tf(pc_to_string(l.pc)));
+ else
+ for(const auto &l : dasm_lines)
+ util::stream_format(std::cout, "%-*s ; %s: %s\n", max_text, tf(l.dasm), tf(pc_to_string(l.pc)), tf(dump_raw_bytes(l.pc, l.size >> granularity_shift)));
+ } else {
+ if(opts.norawbytes)
+ for(const auto &l : dasm_lines)
+ util::stream_format(std::cout, "%s: %s\n", tf(pc_to_string(l.pc)), tf(l.dasm));
+ else
+ for(const auto &l : dasm_lines)
+ util::stream_format(std::cout, "%s: %-*s %s\n", tf(pc_to_string(l.pc)), max_len, tf(dump_raw_bytes(l.pc, l.size >> granularity_shift)), tf(l.dasm));
}
free(data);
- return result;
+ return 0;
}