1
0
mirror of https://git.code.sf.net/p/fuse-emulator/fuse-utils synced 2025-04-19 08:42:15 +03:00

New snapdump utility

Allows to dump information about machine status stored in a snapshot file.
This commit is contained in:
Sergio Baldoví 2017-11-27 23:46:26 +01:00
parent f1d1942b2a
commit 64e27910a6
9 changed files with 1061 additions and 0 deletions

1
.gitignore vendored
View File

@ -46,6 +46,7 @@
/scl2trd
/snap2tzx
/snapconv
/snapdump
/stamp-h
/stamp-h1
/stamp-h.in

View File

@ -20,4 +20,6 @@ The Fuse utilities have been brought to you by:
* Gergely Szasz: fmfconv.
* Sergio Baldoví: snapdump.
* Philip Kendall: everything else.

View File

@ -1,3 +1,11 @@
2017-12-xx Philip Kendall <philip-fuse@shadowmagic.org.uk>
* Version 1.x.x released
* snapdump
* New utility to dump information about machine status stored in
a snapshot file (Sergio Baldoví).
2017-10-10 Philip Kendall <philip-fuse@shadowmagic.org.uk>
* Version 1.3.5 released

View File

@ -34,6 +34,7 @@ bin_PROGRAMS = createhdf \
scl2trd \
snap2tzx \
snapconv \
snapdump \
tapeconv \
tape2pulses \
tzxlist
@ -102,6 +103,9 @@ snap2tzx_LDADD = $(LIBSPECTRUM_LIBS) compat/libcompatos.a
snapconv_SOURCES = snapconv.c utils.c
snapconv_LDADD = $(LIBSPECTRUM_LIBS) compat/libcompatos.a
snapdump_SOURCES = snapdump.c utils.c
snapdump_LDADD = $(LIBSPECTRUM_LIBS) compat/libcompatos.a
tapeconv_SOURCES = tapeconv.c utils.c
tapeconv_LDADD = $(LIBSPECTRUM_LIBS) compat/libcompatos.a
@ -155,6 +159,7 @@ rzxtool_SOURCES += rzxtool_res.rc
scl2trd_SOURCES += scl2trd_res.rc
snap2tzx_SOURCES += snap2tzx_res.rc
snapconv_SOURCES += snapconv_res.rc
snapdump_SOURCES += snapdump_res.rc
tape2pulses_SOURCES += tape2pulses_res.rc
tape2wav_SOURCES += tape2wav_res.rc
tapeconv_SOURCES += tapeconv_res.rc

View File

@ -34,6 +34,7 @@ man_MANS = \
man/scl2trd.1 \
man/snap2tzx.1 \
man/snapconv.1 \
man/snapdump.1 \
man/tape2pulses.1 \
man/tape2wav.1 \
man/tapeconv.1 \

View File

@ -97,6 +97,11 @@ Convert a snapshot into a .tzx tape image.
Convert between various snapshot formats.
.RE
.PP
.I snapdump
.RS
List contents of ZX Spectrum snapshot files
.RE
.PP
.I tape2pulses
.RS
Dumps the pulse information from tape images to text files.
@ -133,6 +138,8 @@ Display the contents of a .tzx tape image.
.IR scl2trd "(1),"
.IR snap2tzx "(1),"
.IR snapconv "(1),"
.IR snapdump "(1),"
.IR tape2pulses "(1),"
.IR tape2wav "(1),"
.IR tapeconv "(1),"
.IR tzxlist "(1),"

78
man/snapdump.1 Normal file
View File

@ -0,0 +1,78 @@
.\" -*- nroff -*-
.\"
.\" snapdump.1: snapdump man page
.\" Copyright (c) 2017 Sergio Baldoví
.\"
.\" This program is free software; you can redistribute it and/or modify
.\" it under the terms of the GNU General Public License as published by
.\" the Free Software Foundation; either version 2 of the License, or
.\" (at your option) any later version.
.\"
.\" This program is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
.\" GNU General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public License along
.\" with this program; if not, write to the Free Software Foundation, Inc.,
.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
.\"
.\" Author contact information:
.\"
.\" E-mail: serbalgi@gmail.com
.\"
.\"
.TH snapdump 1 "10th October, 2017" "Version 1.3.5" "Emulators"
.\"
.\"------------------------------------------------------------------
.\"
.SH NAME
snapdump \(em List contents of Sinclair ZX Spectrum snapshot files
.\"
.\"------------------------------------------------------------------
.\"
.SH SYNOPSIS
.B snapdump
[ \-m ]
.I infile
.\"
.\"------------------------------------------------------------------
.\"
.SH DESCRIPTION
snapdump describes the machine status and the attached peripherals stored
in a snapshot.
.\"
.\"------------------------------------------------------------------
.\"
.SH OPTIONS
.TP
.I \-m
Dump ROM/RAM/Flash memory pages to separate files.
.TP
.IR \-h ", " \-\-help
give brief usage help, listing available options.
.TP
.IR \-V ", " \-\-version
output version information.
.TP
.I infile
specifies the snapshot to be described. This file can be in any of the
snapshot formats supported by
.IR libspectrum "(3)."
.\"
.\"------------------------------------------------------------------
.\"
.SH BUGS
None known.
.\"
.\"------------------------------------------------------------------
.\"
.SH SEE ALSO
.IR fuse "(1),"
.IR fuse\-utils "(1),"
.IR libspectrum "(3)"
.\"
.\"------------------------------------------------------------------
.\"
.SH AUTHOR
Sergio Baldov\('i (serbalgi@gmail.com).

899
snapdump.c Normal file
View File

@ -0,0 +1,899 @@
/* snapdump.c: List contents of ZX Spectrum snapshot files
Copyright (c) 2017 Sergio Baldoví
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Author contact information:
E-mail: serbalgi@gmail.com
*/
#include <config.h>
#include <errno.h>
#include <getopt.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#ifdef HAVE_GCRYPT_H
#include <gcrypt.h>
#endif /* #ifdef HAVE_GCRYPT_H */
#include <libspectrum.h>
#include "compat.h"
#include "utils.h"
/* Sizes of some of the arrays in the snap structure */
#define SNAPSHOT_RAM_PAGES 16
#define SNAPSHOT_SLT_PAGES 256
#define SNAPSHOT_ZXATASP_PAGES 32
#define SNAPSHOT_ZXCF_PAGES 64
#define SNAPSHOT_DOCK_EXROM_PAGES 8
#define SNAPSHOT_JOYSTICKS 7
#define SNAPSHOT_DIVIDE_PAGES 4
#define SNAPSHOT_DIVMMC_PAGES 64
#define PROGRAM_NAME "snapdump"
char *progname;
static int dump_memory = 0;
static const char *snap_file = NULL;
typedef int (*periph_active_fn)( libspectrum_snap *snap );
typedef void (*periph_dump_fn)( libspectrum_snap *snap );
typedef struct snap_periph_t {
periph_active_fn active;
periph_dump_fn dump;
const char *name;
} snap_periph_t;
#ifdef HAVE_GCRYPT_H
static char *
calculate_sha1sum( const libspectrum_byte *data, size_t data_length )
{
unsigned int digest_length, i;
libspectrum_byte *digest;
char *hash, *p;
if( !data || !data_length ) return NULL;
/* Get SHA1 sum */
digest_length = gcry_md_get_algo_dlen( GCRY_MD_SHA1 );
digest = libspectrum_new( libspectrum_byte, digest_length );
gcry_md_hash_buffer( GCRY_MD_SHA1, digest, data, data_length );
/* Convert bytes to hex */
hash = libspectrum_new( char, digest_length * 2 + 1 );
p = hash;
for ( i = 0; i < digest_length; i++ ) {
snprintf( p, 3, "%02x", digest[i] );
p += 2;
}
*p = '\0';
libspectrum_free( digest );
return hash;
}
#else
static char *
calculate_sha1sum( const libspectrum_byte *data, size_t data_length )
{
return NULL;
}
#endif /* #ifdef HAVE_GCRYPT_H */
static char *
get_memory_filename( const char *memory_name, int page )
{
char *buffer, *buffer2, *last_dot, *filename;
size_t filename_len;
/* Get the basename without the last extension */
buffer = strdup( snap_file );
if( !buffer ) {
fprintf( stderr, "out of memory at %s:%d", __FILE__, __LINE__ );
return NULL;
}
buffer2 = compat_basename( buffer );
last_dot = strrchr( buffer2, '.' ); if( last_dot ) *last_dot = '\0';
filename_len = strlen( buffer2 ) + strlen( memory_name ) + sizeof( page ) + 7;
filename = libspectrum_new( char, filename_len );
if( page >= 0 )
snprintf( filename, filename_len, "%s_%s_%d.bin", buffer2, memory_name,
page );
else
snprintf( filename, filename_len, "%s_%s.bin", buffer2, memory_name );
free( buffer );
return filename;
}
static void
print_memory_block( const char *name, const libspectrum_byte *data, size_t size )
{
char *sha1, *filename;
sha1 = calculate_sha1sum( data, size );
if( sha1 ) {
printf( "%s size: 0x%04lX, sha1: %s\n", name, size, sha1 );
libspectrum_free( sha1 );
} else {
printf( "%s size: 0x%04lX\n", name, size );
}
if( dump_memory ) {
filename = get_memory_filename( name, -1 );
write_file( filename, data, size );
free( filename );
}
}
static void
print_memory_page( const char *name, int page, const libspectrum_byte *data,
size_t size )
{
char *sha1, *filename;
sha1 = calculate_sha1sum( data, size );
if( sha1 ) {
printf( "%s_%d size: 0x%04lX, sha1: %s\n", name, page, size, sha1 );
libspectrum_free( sha1 );
} else {
printf( "%s_%d size: 0x%04lX\n", name, page, size );
}
if( dump_memory ) {
filename = get_memory_filename( name, page );
write_file( filename, data, size );
free( filename );
}
}
static void
dump_beta128( libspectrum_snap *snap )
{
libspectrum_byte *rom_data;
if( ! libspectrum_snap_beta_active( snap ) )
return;
printf( "\nBETA 128\n" );
printf( "Beta 128 paged: %d\n", libspectrum_snap_beta_paged( snap ) );
printf( "Beta 128 autoboot: %d\n", libspectrum_snap_beta_autoboot( snap ) );
printf( "Beta 128 custom rom: %d\n", libspectrum_snap_beta_custom_rom( snap ) );
rom_data = libspectrum_snap_beta_rom( snap, 0 );
if( rom_data ) print_memory_block( "beta128_rom", rom_data, 0x4000 );
printf( "Beta 128 direction: %d\n", libspectrum_snap_beta_direction( snap ) );
printf( "Beta 128 drive count: %d\n", libspectrum_snap_beta_drive_count( snap ) );
printf( "Beta 128 system: 0x%02X\n", libspectrum_snap_beta_system( snap ) );
printf( "Beta 128 track: 0x%02X\n", libspectrum_snap_beta_track( snap ) );
printf( "Beta 128 sector: 0x%02X\n", libspectrum_snap_beta_sector( snap ) );
printf( "Beta 128 data: 0x%02X\n", libspectrum_snap_beta_data( snap ) );
printf( "Beta 128 status: 0x%02X\n", libspectrum_snap_beta_status( snap ) );
}
static void
dump_covox( libspectrum_snap *snap )
{
if( !libspectrum_snap_covox_active( snap ) )
return;
printf( "\nCOVOX\n" );
printf( "Covox dac: 0x%02X\n", libspectrum_snap_covox_dac( snap ) );
}
static void
dump_divide( libspectrum_snap *snap )
{
libspectrum_byte *eprom_data, *ram_data;
size_t pages, i;
if( ! libspectrum_snap_divide_active( snap ) )
return;
printf( "\nDIVIDE\n" );
printf( "DivIDE paged: %d\n", libspectrum_snap_divide_paged( snap ) );
printf( "DivIDE control: 0x%02X\n", libspectrum_snap_divide_control( snap ) );
printf( "DivIDE eprom writeprotect: %d\n",
libspectrum_snap_divide_eprom_writeprotect( snap ) );
eprom_data = libspectrum_snap_divide_eprom( snap, 0 );
if( eprom_data ) print_memory_block( "divide_eprom", eprom_data, 0x2000 );
pages = libspectrum_snap_divide_pages( snap );
printf( "DivIDE pages: %lu\n", pages );
for( i = 0; i < SNAPSHOT_DIVIDE_PAGES; i++ ) {
ram_data = libspectrum_snap_divide_ram( snap, i );
if( ram_data ) print_memory_page( "divide_ram_page", i, ram_data, 0x2000 );
}
}
static void
dump_divmmc( libspectrum_snap *snap )
{
libspectrum_byte *eprom_data, *ram_data;
size_t pages, i;
if( ! libspectrum_snap_divmmc_active( snap ) )
return;
printf( "\nDIVMMC\n" );
printf( "DivMMC paged: %d\n", libspectrum_snap_divmmc_paged( snap ) );
printf( "DivMMC control: 0x%02X\n", libspectrum_snap_divmmc_control( snap ) );
printf( "DivMMC eprom writeprotect: %d\n",
libspectrum_snap_divmmc_eprom_writeprotect( snap ) );
eprom_data = libspectrum_snap_divmmc_eprom( snap, 0 );
if( eprom_data ) print_memory_block( "divmmc_eprom", eprom_data, 0x2000 );
pages = libspectrum_snap_divmmc_pages( snap );
printf( "DivMMC pages: %lu\n", pages );
for( i = 0; i < SNAPSHOT_DIVMMC_PAGES; i++ ) {
ram_data = libspectrum_snap_divmmc_ram( snap, i );
if( ram_data ) print_memory_page( "divmmc_ram_page", i, ram_data, 0x2000 );
}
}
static void
dump_interface1( libspectrum_snap *snap )
{
libspectrum_byte *rom_data;
size_t rom_length;
if( ! libspectrum_snap_interface1_active( snap ) )
return;
printf( "\nINTERFACE I\n" );
printf( "Interface I paged: %d\n", libspectrum_snap_interface1_paged( snap ) );
printf( "Interface I custom rom: %d\n",
libspectrum_snap_interface1_custom_rom( snap ) );
rom_data = libspectrum_snap_interface1_rom( snap, 0 );
rom_length = libspectrum_snap_interface1_rom_length( snap, 0 );
if( rom_data ) print_memory_block( "Interface_I_rom", rom_data, rom_length );
printf( "Interface I microdrive count: %d\n",
libspectrum_snap_interface1_drive_count( snap ) );
}
static void
dump_interface2( libspectrum_snap *snap )
{
libspectrum_byte *rom_data;
size_t rom_length;
if( ! libspectrum_snap_interface2_active( snap ) )
return;
printf( "\nINTERFACE II\n" );
rom_data = libspectrum_snap_interface2_rom( snap, 0 );
rom_length = 0x4000;
if( rom_data ) print_memory_block( "Interface_II_rom", rom_data, rom_length );
}
static void
dump_multiface( libspectrum_snap *snap )
{
libspectrum_byte *ram_data;
size_t ram_length;
if( ! libspectrum_snap_multiface_active( snap ) )
return;
printf( "\nMULTIFACE\n" );
if( libspectrum_snap_multiface_model_one( snap ) )
printf( "Multiface model: Multiface One\n" );
else if( libspectrum_snap_multiface_model_128( snap ) )
printf( "Multiface model: Multiface 128\n" );
else if( libspectrum_snap_multiface_model_3( snap ) )
printf( "Multiface model: Multiface 3\n" );
else
printf( "Multiface model: unknown\n" );
printf( "Multiface paged: %d\n", libspectrum_snap_multiface_paged( snap ) );
if( libspectrum_snap_multiface_model_one( snap ) ) {
printf( "Multiface One disabled: %d\n",
libspectrum_snap_multiface_disabled( snap ) );
} else {
printf( "Multiface 128/3 software lockout: %d\n",
libspectrum_snap_multiface_software_lockout( snap ) );
}
printf( "Multiface red button disabled: %d\n",
libspectrum_snap_multiface_red_button_disabled( snap ) );
ram_length = libspectrum_snap_multiface_ram_length( snap, 0 );
ram_data = libspectrum_snap_multiface_ram( snap, 0 );
if( ram_data ) print_memory_block( "multiface_ram", ram_data, ram_length );
}
static void
dump_opus( libspectrum_snap *snap )
{
libspectrum_byte *rom_data, *ram_data;
if( ! libspectrum_snap_opus_active( snap ) )
return;
printf( "\nOPUS DISCOVERY\n" );
printf( "Opus Discovery paged: %d\n", libspectrum_snap_opus_paged( snap ) );
printf( "Opus Discovery custom rom: %d\n",
libspectrum_snap_opus_custom_rom( snap ) );
rom_data = libspectrum_snap_opus_rom( snap, 0 );
if( rom_data ) print_memory_block( "opus_rom", rom_data, 0x2000 );
ram_data = libspectrum_snap_opus_ram( snap, 0 );
if( ram_data ) print_memory_block( "opus_ram", ram_data, 0x0800 );
printf( "Opus Discovery control register A: %d\n",
libspectrum_snap_opus_control_a( snap ) );
printf( "Opus Discovery data direction A: %d\n",
libspectrum_snap_opus_data_dir_a( snap ) );
printf( "Opus Discovery peripheral reg A: %d\n",
libspectrum_snap_opus_data_reg_a( snap ) );
printf( "Opus Discovery control register B: %d\n",
libspectrum_snap_opus_control_b( snap ) );
printf( "Opus Discovery data direction B: %d\n",
libspectrum_snap_opus_data_dir_b( snap ) );
printf( "Opus Discovery peripheral reg B: %d\n",
libspectrum_snap_opus_data_reg_b( snap ) );
printf( "Opus Discovery direction: %d\n",
libspectrum_snap_opus_direction( snap ) );
printf( "Opus Discovery drive count: %d\n",
libspectrum_snap_opus_drive_count( snap ) );
printf( "Opus Discovery track: 0x%02X\n",
libspectrum_snap_opus_track( snap ) );
printf( "Opus Discovery sector: 0x%02X\n",
libspectrum_snap_opus_sector( snap ) );
printf( "Opus Discovery data: 0x%02X\n",
libspectrum_snap_opus_data( snap ) );
printf( "Opus Discovery status: 0x%02X\n",
libspectrum_snap_opus_status( snap ) );
}
static void
dump_plusd( libspectrum_snap *snap )
{
libspectrum_byte *rom_data, *ram_data;
if( ! libspectrum_snap_plusd_active( snap ) )
return;
printf( "\n+D\n" );
printf( "+D paged: %d\n", libspectrum_snap_plusd_paged( snap ) );
printf( "+D custom rom: %d\n", libspectrum_snap_plusd_custom_rom( snap ) );
rom_data = libspectrum_snap_plusd_rom( snap, 0 );
if( rom_data ) print_memory_block( "plusd_rom", rom_data, 0x2000 );
ram_data = libspectrum_snap_plusd_ram( snap, 0 );
if( ram_data ) print_memory_block( "plusd_ram", ram_data, 0x2000 );
printf( "+D control register B: %d\n",
libspectrum_snap_plusd_control( snap ) );
printf( "+D direction: %d\n", libspectrum_snap_plusd_direction( snap ) );
printf( "+D drive count: %d\n", libspectrum_snap_plusd_drive_count( snap ) );
printf( "+D track: 0x%02X\n", libspectrum_snap_plusd_track( snap ) );
printf( "+D sector: 0x%02X\n", libspectrum_snap_plusd_sector( snap ) );
printf( "+D data: 0x%02X\n", libspectrum_snap_plusd_data( snap ) );
printf( "+D status: 0x%02X\n", libspectrum_snap_plusd_status( snap ) );
}
static void
dump_specdrum( libspectrum_snap *snap )
{
if( ! libspectrum_snap_specdrum_active( snap ) )
return;
printf( "\nSPECDRUM\n" );
printf( "SpecDrum dac: %d\n", libspectrum_snap_specdrum_dac( snap ) );
}
static void
dump_spectranet( libspectrum_snap *snap )
{
libspectrum_byte *w5100_regs;
int i;
if( ! libspectrum_snap_spectranet_active( snap ) )
return;
printf( "\nSPECTRANET\n" );
printf( "Spectranet paged: %d\n",
libspectrum_snap_spectranet_paged( snap ) );
printf( "Spectranet paged via io: %d\n",
libspectrum_snap_spectranet_paged_via_io( snap ) );
printf( "Spectranet programmable trap: 0x%04X\n",
libspectrum_snap_spectranet_programmable_trap( snap ) );
printf( "Spectranet programmable trap active: %d\n",
libspectrum_snap_spectranet_programmable_trap_active( snap ) );
printf( "Spectranet programmable trap msb: %d\n",
libspectrum_snap_spectranet_programmable_trap_msb( snap ) );
printf( "Spectranet deny downstream a15: %d\n",
libspectrum_snap_spectranet_deny_downstream_a15( snap ) );
printf( "Spectranet nmi flipflop: %d\n",
libspectrum_snap_spectranet_nmi_flipflop( snap ) );
printf( "Spectranet all traps disabled: %d\n",
libspectrum_snap_spectranet_all_traps_disabled( snap ) );
printf( "Spectranet rst8 trap disabled: %d\n",
libspectrum_snap_spectranet_rst8_trap_disabled( snap ) );
printf( "Spectranet page A: %d\n",
libspectrum_snap_spectranet_page_a( snap ) );
printf( "Spectranet page B: %d\n",
libspectrum_snap_spectranet_page_b( snap ) );
printf( "Spectranet W5100 registers:" );
w5100_regs = libspectrum_snap_spectranet_w5100( snap, 0 );
for( i = 0; i < 48; i++ ) {
if( i % 16 == 0 ) printf( "\n " );
printf( " %02X", w5100_regs[i] );
}
printf( "\n" );
if( libspectrum_snap_spectranet_flash( snap, 0 ) )
print_memory_block( "spectranet_flash",
libspectrum_snap_spectranet_flash( snap, 0 ), 0x20000 );
if( libspectrum_snap_spectranet_ram( snap, 0 ) )
print_memory_block( "spectranet_ram",
libspectrum_snap_spectranet_ram( snap, 0 ), 0x20000 );
}
static void
dump_slt( libspectrum_snap *snap )
{
libspectrum_byte *slt_data;
size_t slt_length;
int i, have_slt;
have_slt = 0;
for( i = 0; i < SNAPSHOT_SLT_PAGES; i++ ) {
if( libspectrum_snap_slt_length( snap, i ) ) {
have_slt = 1;
break;
}
}
if( !have_slt ) return;
printf( "\nSLT\n" );
slt_data = libspectrum_snap_slt_screen( snap );
if( slt_data ) {
printf( "slt screen level: %d\n",
libspectrum_snap_slt_screen_level( snap ) );
print_memory_block( "slt_screen", slt_data, 6912 );
}
for( i = 0; i < SNAPSHOT_SLT_PAGES; i++ ) {
slt_length = libspectrum_snap_slt_length( snap, i );
if( slt_length ) {
slt_data = libspectrum_snap_slt( snap, i );
print_memory_page( "slt_level", i, slt_data, slt_length );
}
}
}
static void
dump_ulaplus( libspectrum_snap *snap )
{
libspectrum_byte *buffer;
unsigned int i;
if( ! libspectrum_snap_ulaplus_active( snap ) )
return;
printf( "\nULAplus\n" );
printf( "ULAplus enabled: %d\n",
libspectrum_snap_ulaplus_palette_enabled( snap ) );
printf( "ULAplus current register: %d\n",
libspectrum_snap_ulaplus_current_register( snap ) );
buffer = libspectrum_snap_ulaplus_palette( snap, 0 );
printf( "ULAplus registers:" );
for( i = 0; i < 64; i++ ) {
if( i % 16 == 0 ) printf( "\n " );
printf( " %02X", buffer[i] );
}
printf( "\n" );
printf( "ULAplus ff register: %d\n",
libspectrum_snap_ulaplus_ff_register( snap ) );
}
static void
dump_zxatasp( libspectrum_snap *snap )
{
libspectrum_byte *ram_page;
int i;
if( ! libspectrum_snap_zxatasp_active( snap ) )
return;
printf( "\nZXATASP\n" );
printf( "ZXATASP upload: %d\n", libspectrum_snap_zxatasp_upload( snap ) );
printf( "ZXATASP write protected: %d\n",
libspectrum_snap_zxatasp_writeprotect( snap ) );
printf( "ZXATASP port A: 0x%02X\n", libspectrum_snap_zxatasp_port_a( snap ) );
printf( "ZXATASP port B: 0x%02X\n", libspectrum_snap_zxatasp_port_b( snap ) );
printf( "ZXATASP port C: 0x%02X\n", libspectrum_snap_zxatasp_port_c( snap ) );
printf( "ZXATASP control port: 0x%02X\n",
libspectrum_snap_zxatasp_control( snap ) );
printf( "ZXATASP RAM pages: %lu\n",
libspectrum_snap_zxatasp_pages( snap ) );
printf( "ZXATASP active page: %lu\n",
libspectrum_snap_zxatasp_current_page( snap ) );
for( i = 0; i < SNAPSHOT_ZXATASP_PAGES; i++ ) {
ram_page = libspectrum_snap_zxatasp_ram( snap, i );
if( ram_page )
print_memory_page( "zxatasp_ram_page", i, ram_page, 0x4000 );
}
}
static void
dump_zxcf( libspectrum_snap *snap )
{
libspectrum_byte *ram_page;
int i;
if( ! libspectrum_snap_zxcf_active( snap ) )
return;
printf( "\nZXCF\n" );
printf( "ZXCF upload: %d\n", libspectrum_snap_zxcf_upload( snap ) );
printf( "ZXCF memmory control register: 0x%02X\n",
libspectrum_snap_zxcf_memctl( snap ) );
printf( "ZXCF RAM pages: %lu\n",
libspectrum_snap_zxcf_pages( snap ) );
for( i = 0; i < SNAPSHOT_ZXCF_PAGES; i++ ) {
ram_page = libspectrum_snap_zxcf_ram( snap, i );
if( ram_page )
print_memory_page( "zxcf_ram_page", i, ram_page, 0x4000 );
}
}
static const snap_periph_t periph_list[] = {
{ libspectrum_snap_beta_active, dump_beta128, "Beta 128" },
{ libspectrum_snap_covox_active, dump_covox, "Covox" },
{ libspectrum_snap_plusd_active, dump_plusd, "+D" },
{ libspectrum_snap_didaktik80_active, NULL, "Didaktik 80" },
{ libspectrum_snap_disciple_active, NULL, "DISCiPLE" },
{ libspectrum_snap_divide_active, dump_divide, "DivIDE" },
{ libspectrum_snap_divmmc_active, dump_divmmc, "DivMMC" },
{ libspectrum_snap_fuller_box_active, NULL, "Fuller box" },
{ libspectrum_snap_interface1_active, dump_interface1, "Interface I" },
{ libspectrum_snap_interface2_active, dump_interface2, "Interface II cartridge" },
{ libspectrum_snap_kempston_mouse_active, NULL, "Kempston mouse" },
{ libspectrum_snap_issue2, NULL, "Keyboard issue 2" },
{ libspectrum_snap_melodik_active, NULL, "Melodik" },
{ libspectrum_snap_multiface_active, dump_multiface, "Multiface" },
{ libspectrum_snap_opus_active, dump_opus, "Opus Discovery" },
{ libspectrum_snap_simpleide_active, NULL, "Simple IDE" },
{ libspectrum_snap_specdrum_active, dump_specdrum, "SpecDrum" },
{ libspectrum_snap_spectranet_active, dump_spectranet, "Spectranet" },
{ libspectrum_snap_dock_active, NULL, "Timex Dock cartridge" },
{ libspectrum_snap_ulaplus_active, dump_ulaplus, "ULAplus" },
{ libspectrum_snap_usource_active, NULL, "uSource" },
{ libspectrum_snap_zxatasp_active, dump_zxatasp, "ZXATASP" },
{ libspectrum_snap_zxcf_active, dump_zxcf, "ZXCF" },
{ libspectrum_snap_zxmmc_active, NULL, "ZXMMC" },
{ libspectrum_snap_zx_printer_active, NULL, "ZX Printer" },
{ NULL, NULL, NULL }
};
static void
dump_snapshot( libspectrum_snap *snap )
{
size_t i, custom_rom_pages, num_joysticks;
const snap_periph_t *p;
libspectrum_machine machine;
int capabilities, custom_rom;
printf( "filename: %s\n", snap_file );
machine = libspectrum_snap_machine( snap );
printf( "machine: %s\n", libspectrum_machine_name( machine ) );
capabilities = libspectrum_machine_capabilities( machine );
/* Registers and the like */
printf( "\nREGISTERS\n" );
printf( "PC: 0x%04X\n", libspectrum_snap_pc( snap ) );
printf( "SP: 0x%04X\n", libspectrum_snap_sp( snap ) );
printf( "AF: 0x%02X%02X\n", libspectrum_snap_a( snap ),
libspectrum_snap_f( snap ) );
printf( "AF': 0x%02X%02X\n", libspectrum_snap_a_( snap ),
libspectrum_snap_f_( snap ) );
printf( "BC: 0x%04X\n", libspectrum_snap_bc( snap ) );
printf( "BC': 0x%04X\n", libspectrum_snap_bc_( snap ) );
printf( "DE: 0x%04X\n", libspectrum_snap_de( snap ) );
printf( "DE': 0x%04X\n", libspectrum_snap_de_( snap ) );
printf( "HL: 0x%04X\n", libspectrum_snap_hl( snap ) );
printf( "HL': 0x%04X\n", libspectrum_snap_hl_( snap ) );
printf( "IX: 0x%04X\n", libspectrum_snap_ix( snap ) );
printf( "IY: 0x%04X\n", libspectrum_snap_iy( snap ) );
printf( "I: 0x%02X\n", libspectrum_snap_i( snap ) );
printf( "R: 0x%02X\n", libspectrum_snap_r( snap ) );
printf( "meptr: 0x%04X\n", libspectrum_snap_memptr( snap ) );
printf( "IFF1: %u\n", libspectrum_snap_iff1( snap ) );
printf( "IFF2: %u\n", libspectrum_snap_iff2( snap ) );
printf( "IM: %u\n", libspectrum_snap_im( snap ) );
printf( "halted: %u\n", libspectrum_snap_halted( snap ) );
printf( "last instruction EI: %u\n",
libspectrum_snap_last_instruction_ei( snap ) );
printf( "last instruction set flags: %u\n",
libspectrum_snap_last_instruction_set_f( snap ) );
/* Custom ROM */
custom_rom = libspectrum_snap_custom_rom( snap );
if( custom_rom ) {
printf( "\nCUSTOM ROM\n" );
printf( "custom rom: %u\n", custom_rom );
custom_rom_pages = libspectrum_snap_custom_rom_pages( snap );
printf( "custom rom pages: %lu\n", custom_rom_pages );
for( i = 0; i < custom_rom_pages; i++ ) {
print_memory_page( "custom_rom_", i, libspectrum_snap_roms( snap, i ),
libspectrum_snap_rom_length( snap, i ) );
}
}
printf( "\nRAM PAGES\n" );
for( i = 0; i < SNAPSHOT_RAM_PAGES; i++ )
if( libspectrum_snap_pages( snap, i ) )
print_memory_page( "ram_page", i, libspectrum_snap_pages( snap, i ),
0x4000 );
if( libspectrum_snap_dock_active( snap ) ) {
printf( "\nTIMEX PAGES\n" );
for( i = 0; i < 8; i++ ) {
if( libspectrum_snap_dock_cart( snap, i ) ) {
if( libspectrum_snap_dock_ram( snap, i ) )
print_memory_page( "dock_ram_page", i,
libspectrum_snap_dock_cart( snap, i ), 0x2000 );
else
print_memory_page( "dock_rom_page", i,
libspectrum_snap_dock_cart( snap, i ), 0x2000 );
}
}
for( i = 0; i < 8; i++ ) {
if( libspectrum_snap_exrom_cart( snap, i ) ) {
if( libspectrum_snap_exrom_ram( snap, i ) )
print_memory_page( "exrom_ram_page", i,
libspectrum_snap_exrom_cart( snap, i ), 0x2000 );
else
print_memory_page( "exrom_rom_page", i,
libspectrum_snap_exrom_cart( snap, i ), 0x2000 );
}
}
}
/* Peripheral status */
printf( "\nPERIPHERAL STATUS\n" );
printf( "tstates: %u\n", libspectrum_snap_tstates( snap ) );
printf( "late timings: %u\n", libspectrum_snap_late_timings( snap ) );
printf( "ULA: %02X\n", libspectrum_snap_out_ula( snap ) );
printf( "128 mem: 0x%02X\n", libspectrum_snap_out_128_memoryport( snap ) );
printf( "+3 mem: 0x%02X\n", libspectrum_snap_out_plus3_memoryport( snap ) );
if( capabilities & ( LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_MEMORY |
LIBSPECTRUM_MACHINE_CAPABILITY_SE_MEMORY ) ||
libspectrum_snap_out_scld_hsr( snap ) != 0 )
printf( "Timex SCLD hsr: 0x%02X\n", libspectrum_snap_out_scld_hsr( snap ) );
if( capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_VIDEO ||
libspectrum_snap_out_scld_dec( snap ) != 0 )
printf( "Timex SCLD dec: 0x%02X\n", libspectrum_snap_out_scld_dec( snap ) );
/* AY status */
if( capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ||
libspectrum_snap_melodik_active( snap ) ||
libspectrum_snap_fuller_box_active( snap ) ) {
printf( "AY: 0x%02X\n", libspectrum_snap_out_ay_registerport( snap ) );
printf( "AY registers:" );
for( i = 0; i < 16; i++ ) {
printf( " %02X", libspectrum_snap_ay_registers( snap, i ) );
}
printf( "\n" );
}
/* .slt data */
dump_slt( snap );
num_joysticks = libspectrum_snap_joystick_active_count( snap );
printf( "Joysticks: %lu\n", num_joysticks );
for( i = 0; i < num_joysticks; i++ ) {
printf( "Joystick %lu Type: %s\n", i,
libspectrum_joystick_name( libspectrum_snap_joystick_list( snap, i ) ) );
}
for( i = 0; i < num_joysticks; i++ ) {
printf( "Joystick %lu Inputs: %d\n", i,
libspectrum_snap_joystick_inputs( snap, i ) );
}
/* Peripherals list */
printf( "Peripherals: " );
i = 0;
p = periph_list;
while( p->active ) {
if( p->active( snap ) ) {
if( i++ ) printf( ", " );
printf( "%s", p->name );
}
p++;
}
printf( "\n" );
/* Peripheral details */
p = periph_list;
while( p->active ) {
if( p->dump && p->active( snap ) ) {
p->dump( snap );
}
p++;
}
printf( "\n" );
}
static void
show_version( void )
{
printf(
PROGRAM_NAME " (" PACKAGE ") " PACKAGE_VERSION "\n"
"Copyright (c) 2017 Sergio Baldoví\n"
"License GPLv2+: GNU GPL version 2 or later "
"<http://gnu.org/licenses/gpl.html>\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n" );
}
static void
show_help( void )
{
printf(
"Usage: %s [OPTION] <infile>\n"
"List contents of Sinclair ZX Spectrum input snapshot files.\n"
"\n"
"Options:\n"
" -m Dump ROM/RAM memory pages to files.\n"
" -h, --help Display this help and exit.\n"
" -V, --version Output version information and exit.\n"
"\n"
"Report %s bugs to <%s>\n"
"%s home page: <%s>\n"
"For complete documentation, see the manual page of %s.\n",
progname,
PROGRAM_NAME, PACKAGE_BUGREPORT, PACKAGE_NAME, PACKAGE_URL, PROGRAM_NAME
);
}
int
main( int argc, char **argv )
{
libspectrum_snap *snap;
libspectrum_id_t type; libspectrum_class_t class;
unsigned char *buffer; size_t length;
int error = 0;
int c;
struct option long_options[] = {
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'V' },
{ 0, 0, 0, 0 }
};
progname = argv[0];
while( ( c = getopt_long( argc, argv, "mhV", long_options, NULL ) ) != -1 ) {
switch( c ) {
case 'm':
dump_memory = 1;
break;
case 'h': show_help(); return 0;
case 'V': show_version(); return 0;
case '?':
/* getopt prints an error message to stderr */
error = 1;
break;
default:
error = 1;
fprintf( stderr, "%s: unknown option `%c'\n", progname, (char) c );
break;
}
}
argc -= optind;
argv += optind;
if( error ) {
fprintf( stderr, "Try `%s --help' for more information.\n", progname );
return error;
}
if( argc < 1 ) {
fprintf( stderr, "%s: usage: %s [OPTION] <snapfile>\n",
progname, progname );
fprintf( stderr, "Try `%s --help' for more information.\n", progname );
return 1;
}
error = init_libspectrum(); if( error ) return error;
snap = libspectrum_snap_alloc();
snap_file = argv[0];
if( read_file( snap_file, &buffer, &length ) ) {
libspectrum_snap_free( snap );
return 1;
}
/* Parse snapshot */
error = libspectrum_snap_read( snap, buffer, length, LIBSPECTRUM_ID_UNKNOWN,
snap_file );
if( error ) {
libspectrum_snap_free( snap ); free( buffer );
return error;
}
free( buffer );
/* Is it really an snapshot? */
error = libspectrum_identify_file_with_class( &type, &class, snap_file, NULL,
0 );
if( error ) { libspectrum_snap_free( snap ); return error; }
if( class != LIBSPECTRUM_CLASS_SNAPSHOT ) {
fprintf( stderr, "%s: '%s' is not a snapshot file\n", progname, snap_file );
libspectrum_snap_free( snap );
return 1;
}
dump_snapshot( snap );
error = libspectrum_snap_free( snap );
if( error ) return error;
return 0;
}

60
snapdump_res.rc Normal file
View File

@ -0,0 +1,60 @@
/* snapdump_res.rc: resources for Windows executable
Copyright (c) 2017 Sergio Baldoví
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Author contact information:
E-mail: serbalgi@gmail.com
*/
#include <config.h>
#include <windows.h>
/* VERSIONINFO specs:
http://msdn.microsoft.com/en-us/library/aa381058%28VS.85%29.aspx
*/
VS_VERSION_INFO VERSIONINFO
FILEVERSION FUSE_UTILS_RC_VERSION
PRODUCTVERSION FUSE_UTILS_RC_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0x0L
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "List contents of ZX Spectrum snapshot files\0"
VALUE "FileVersion", VERSION##"\0"
VALUE "InternalName", "snapdump\0"
VALUE "LegalCopyright", "Copyright (c) 2017 Sergio Baldoví\0"
VALUE "License", "snapdump is licensed under the GNU General Public License, version 2 or later\0"
VALUE "OriginalFilename", "snapdump.exe\0"
VALUE "ProductName", PACKAGE##"\0"
VALUE "ProductVersion", VERSION##"\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END