mirror of
https://git.code.sf.net/p/fuse-emulator/libspectrum
synced 2025-04-19 12:22:14 +03:00
398 lines
12 KiB
C
398 lines
12 KiB
C
/* internals.h: functions which need to be called inter-file by libspectrum
|
|
routines, but not by user code
|
|
Copyright (c) 2001-2015 Philip Kendall, Darren Salt
|
|
|
|
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: philip-fuse@shadowmagic.org.uk
|
|
|
|
*/
|
|
|
|
#ifndef LIBSPECTRUM_INTERNALS_H
|
|
#define LIBSPECTRUM_INTERNALS_H
|
|
|
|
#ifdef HAVE_LIB_GLIB /* Only if we've got the real glib */
|
|
#include <glib.h>
|
|
#endif /* #ifdef HAVE_LIB_GLIB */
|
|
|
|
#ifndef LIBSPECTRUM_LIBSPECTRUM_H
|
|
#include "libspectrum.h"
|
|
#endif /* #ifndef LIBSPECTRUM_LIBSPECTRUM_H */
|
|
|
|
#ifdef __GNUC__
|
|
#define GCC_UNUSED __attribute__ ((unused))
|
|
#define GCC_PRINTF( fmtstring, args ) __attribute__ ((format( printf, fmtstring, args )))
|
|
#else /* #ifdef __GNUC__ */
|
|
#define GCC_UNUSED
|
|
#define GCC_PRINTF( fmtstring, args )
|
|
#endif /* #ifdef __GNUC__ */
|
|
|
|
#ifdef _MSC_VER
|
|
#if _MSC_VER > 1200 /* VC2005 or later */
|
|
#define __func__ __FUNCTION__
|
|
#else /* #if _MSC_VER > 1200 */
|
|
#define __func__ "__func__"
|
|
#endif /* _MSC_VER > 1200 */
|
|
#endif /* #ifdef _MSC_VER */
|
|
|
|
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
|
#define GNUC_VERSION \
|
|
(__GNUC__ << 16) + __GNUC_MINOR__
|
|
#define GNUC_PREREQ(maj, min) \
|
|
(GNUC_VERSION >= ((maj) << 16) + (min))
|
|
#else
|
|
#define GNUC_PREREQ(maj, min) 0
|
|
#endif
|
|
|
|
#define BUILD_BUG_ON_ZERO(e) \
|
|
(sizeof(struct { int:-!!(e) * 1234; }))
|
|
|
|
#if !GNUC_PREREQ(3, 1) || defined( __STRICT_ANSI__ )
|
|
#define MUST_BE_ARRAY(a) \
|
|
BUILD_BUG_ON_ZERO(sizeof(a) % sizeof(*a))
|
|
#else
|
|
#define SAME_TYPE(a, b) \
|
|
__builtin_types_compatible_p(typeof(a), typeof(b))
|
|
#define MUST_BE_ARRAY(a) \
|
|
BUILD_BUG_ON_ZERO(SAME_TYPE((a), &(*a)))
|
|
#endif
|
|
|
|
#define ARRAY_SIZE(a) ( \
|
|
(sizeof(a) / sizeof(*a)) \
|
|
+ MUST_BE_ARRAY(a))
|
|
|
|
/* C90 lacks SIZE_MAX. size_t is always unsigned so this is safe. */
|
|
#ifndef SIZE_MAX
|
|
#define SIZE_MAX (~(size_t)0)
|
|
#endif
|
|
|
|
/* VC6 lacks M_LN2, and VS2003+ require _USE_MATH_DEFINES defined before math.h
|
|
*/
|
|
#ifndef M_LN2
|
|
#define M_LN2 0.693147180559945309417
|
|
#endif
|
|
|
|
/* On Win32 systems, map snprintf -> _snprintf, strcasecmp -> _stricmp and
|
|
strncasecmp -> _strnicmp */
|
|
#if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF)
|
|
#define snprintf _snprintf
|
|
#endif /* #if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF) */
|
|
|
|
#if !defined(HAVE_STRCASECMP) && defined(HAVE__STRICMP)
|
|
#define strcasecmp _stricmp
|
|
#endif /* #if !defined(HAVE_STRCASECMP) && defined(HAVE__STRICMP) */
|
|
|
|
#if !defined(HAVE_STRNCASECMP) && defined(HAVE__STRNICMP)
|
|
#define strncasecmp _strnicmp
|
|
#endif /* #if !defined(HAVE_STRNCASECMP) && defined(HAVE__STRNICMP) */
|
|
|
|
#ifndef MAX
|
|
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
|
#endif
|
|
|
|
/* Print using the user-provided error function */
|
|
libspectrum_error
|
|
libspectrum_print_error( libspectrum_error error, const char *format, ... )
|
|
GCC_PRINTF( 2, 3 );
|
|
|
|
/* Acquire more memory for a buffer */
|
|
void libspectrum_make_room( libspectrum_byte **dest, size_t requested,
|
|
libspectrum_byte **ptr, size_t *allocated );
|
|
|
|
/* Read and write (d)words */
|
|
libspectrum_word libspectrum_read_word( const libspectrum_byte **buffer );
|
|
libspectrum_dword libspectrum_read_dword( const libspectrum_byte **buffer );
|
|
int libspectrum_write_word( libspectrum_byte **buffer, libspectrum_word w );
|
|
int libspectrum_write_dword( libspectrum_byte **buffer, libspectrum_dword d );
|
|
|
|
/* (de)compression routines */
|
|
|
|
libspectrum_error
|
|
libspectrum_uncompress_file( unsigned char **new_buffer, size_t *new_length,
|
|
char **new_filename, libspectrum_id_t type,
|
|
const unsigned char *old_buffer,
|
|
size_t old_length, const char *old_filename );
|
|
|
|
libspectrum_error
|
|
libspectrum_gzip_inflate( const libspectrum_byte *gzptr, size_t gzlength,
|
|
libspectrum_byte **outptr, size_t *outlength );
|
|
|
|
libspectrum_error
|
|
libspectrum_bzip2_inflate( const libspectrum_byte *bzptr, size_t bzlength,
|
|
libspectrum_byte **outptr, size_t *outlength );
|
|
|
|
libspectrum_error
|
|
libspectrum_zip_inflate( const libspectrum_byte *zipptr, size_t ziplength,
|
|
libspectrum_byte **outptr, size_t *outlength );
|
|
|
|
libspectrum_error
|
|
libspectrum_zip_blind_read( const libspectrum_byte *zipptr, size_t ziplength,
|
|
libspectrum_byte **outptr, size_t *outlength );
|
|
|
|
/* The TZX file signature */
|
|
|
|
extern const char * const libspectrum_tzx_signature;
|
|
|
|
/* Convert a 48K memory dump into separate RAM pages */
|
|
|
|
libspectrum_error
|
|
libspectrum_split_to_48k_pages( libspectrum_snap *snap,
|
|
const libspectrum_byte* data );
|
|
|
|
/* 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
|
|
|
|
/* Get memory for a snap */
|
|
|
|
libspectrum_error
|
|
libspectrum_snap_write_buffer( libspectrum_buffer *buffer, int *out_flags,
|
|
libspectrum_snap *snap, libspectrum_id_t type,
|
|
libspectrum_creator *creator, int in_flags );
|
|
|
|
/* Format specific snapshot routines */
|
|
|
|
libspectrum_error
|
|
libspectrum_plusd_read( libspectrum_snap *snap,
|
|
const libspectrum_byte *buffer, size_t buffer_length );
|
|
libspectrum_error
|
|
internal_sna_read( libspectrum_snap *snap,
|
|
const libspectrum_byte *buffer, size_t buffer_length );
|
|
libspectrum_error
|
|
libspectrum_sna_write( libspectrum_buffer *buffer, int *out_flags,
|
|
libspectrum_snap *snap, int in_flags );
|
|
libspectrum_error
|
|
internal_dsnap_read( libspectrum_snap *snap,
|
|
const libspectrum_byte *buffer, size_t buffer_length );
|
|
libspectrum_error
|
|
libspectrum_dsnap_write( libspectrum_buffer *buffer, int *out_flags,
|
|
libspectrum_snap *snap, int in_flags );
|
|
libspectrum_error
|
|
libspectrum_snp_read( libspectrum_snap *snap,
|
|
const libspectrum_byte *buffer, size_t buffer_length );
|
|
libspectrum_error
|
|
libspectrum_sp_read( libspectrum_snap *snap,
|
|
const libspectrum_byte *buffer, size_t buffer_length );
|
|
libspectrum_error
|
|
libspectrum_szx_read( libspectrum_snap *snap,
|
|
const libspectrum_byte *buffer, size_t buffer_length );
|
|
libspectrum_error
|
|
libspectrum_szx_write( libspectrum_buffer *buffer, int *out_flags,
|
|
libspectrum_snap *snap, libspectrum_creator *creator,
|
|
int in_flags );
|
|
libspectrum_error
|
|
internal_z80_read( libspectrum_snap *snap,
|
|
const libspectrum_byte *buffer, size_t buffer_length );
|
|
libspectrum_error
|
|
libspectrum_z80_write2( libspectrum_buffer *buffer, int *out_flags,
|
|
libspectrum_snap *snap, int in_flags );
|
|
libspectrum_error
|
|
libspectrum_zxs_read( libspectrum_snap *snap,
|
|
const libspectrum_byte *buffer, size_t buffer_length );
|
|
|
|
/*** Tape constants ***/
|
|
|
|
/* The timings for the standard ROM loader */
|
|
extern const libspectrum_dword LIBSPECTRUM_TAPE_TIMING_PILOT;
|
|
extern const libspectrum_dword LIBSPECTRUM_TAPE_TIMING_SYNC1;
|
|
extern const libspectrum_dword LIBSPECTRUM_TAPE_TIMING_SYNC2;
|
|
extern const libspectrum_dword LIBSPECTRUM_TAPE_TIMING_DATA0;
|
|
extern const libspectrum_dword LIBSPECTRUM_TAPE_TIMING_DATA1;
|
|
extern const libspectrum_dword LIBSPECTRUM_TAPE_TIMING_TAIL;
|
|
|
|
/* Tape routines */
|
|
|
|
void libspectrum_tape_block_zero( libspectrum_tape_block *block );
|
|
|
|
libspectrum_error libspectrum_tape_block_read_symbol_table_parameters(
|
|
libspectrum_tape_block *block, int pilot, const libspectrum_byte **ptr );
|
|
|
|
libspectrum_error
|
|
libspectrum_tape_block_read_symbol_table(
|
|
libspectrum_tape_generalised_data_symbol_table *table,
|
|
const libspectrum_byte **ptr, size_t length );
|
|
|
|
void libspectrum_init_bits_set( void );
|
|
|
|
/* Format specific tape routines */
|
|
|
|
libspectrum_error
|
|
internal_tap_read( libspectrum_tape *tape, const libspectrum_byte *buffer,
|
|
const size_t length, libspectrum_id_t type );
|
|
|
|
libspectrum_error
|
|
internal_tap_write( libspectrum_buffer *buffer, libspectrum_tape *tape,
|
|
libspectrum_id_t type );
|
|
|
|
libspectrum_error
|
|
internal_tzx_read( libspectrum_tape *tape, const libspectrum_byte *buffer,
|
|
const size_t length );
|
|
|
|
libspectrum_error
|
|
internal_tzx_write( libspectrum_buffer *buffer, libspectrum_tape *tape );
|
|
|
|
libspectrum_error
|
|
internal_warajevo_read( libspectrum_tape *tape,
|
|
const libspectrum_byte *buffer, size_t length );
|
|
|
|
libspectrum_error
|
|
libspectrum_z80em_read( libspectrum_tape *tape,
|
|
const libspectrum_byte *buffer, size_t length );
|
|
|
|
libspectrum_error
|
|
libspectrum_csw_read( libspectrum_tape *tape,
|
|
const libspectrum_byte *buffer, size_t length );
|
|
|
|
libspectrum_error
|
|
libspectrum_csw_write( libspectrum_buffer *buffer, libspectrum_tape *tape );
|
|
|
|
libspectrum_error
|
|
libspectrum_wav_read( libspectrum_tape *tape, const char *filename );
|
|
|
|
libspectrum_error
|
|
internal_pzx_read( libspectrum_tape *tape, const libspectrum_byte *buffer,
|
|
const size_t length );
|
|
|
|
libspectrum_tape_block*
|
|
libspectrum_tape_block_internal_init(
|
|
libspectrum_tape_block_state *iterator,
|
|
libspectrum_tape *tape );
|
|
|
|
libspectrum_error
|
|
libspectrum_tape_get_next_edge_internal( libspectrum_dword *tstates, int *flags,
|
|
libspectrum_tape *tape,
|
|
libspectrum_tape_block_state *it );
|
|
/* Disk routines */
|
|
|
|
typedef struct libspectrum_hdf_header {
|
|
|
|
libspectrum_byte signature[0x06];
|
|
libspectrum_byte id;
|
|
libspectrum_byte revision;
|
|
libspectrum_byte flags;
|
|
libspectrum_byte datastart_low;
|
|
libspectrum_byte datastart_hi;
|
|
libspectrum_byte reserved[0x0b];
|
|
libspectrum_byte drive_identity[0x6a];
|
|
|
|
} libspectrum_hdf_header;
|
|
|
|
typedef struct libspectrum_ide_drive {
|
|
|
|
/* HDF filepointer and information */
|
|
FILE *disk;
|
|
libspectrum_word data_offset;
|
|
libspectrum_word sector_size;
|
|
libspectrum_hdf_header hdf;
|
|
|
|
/* Drive geometry */
|
|
int cylinders;
|
|
int heads;
|
|
int sectors;
|
|
|
|
libspectrum_byte error;
|
|
libspectrum_byte status;
|
|
|
|
} libspectrum_ide_drive;
|
|
|
|
libspectrum_error
|
|
libspectrum_ide_insert_into_drive( libspectrum_ide_drive *drv,
|
|
const char *filename );
|
|
|
|
libspectrum_error
|
|
libspectrum_ide_eject_from_drive( libspectrum_ide_drive *drv,
|
|
GHashTable *cache );
|
|
|
|
int
|
|
libspectrum_ide_read_sector_from_hdf(
|
|
libspectrum_ide_drive *drv,
|
|
GHashTable *cache,
|
|
libspectrum_dword sector_number,
|
|
libspectrum_byte *dest );
|
|
|
|
void
|
|
libspectrum_ide_write_sector_to_hdf(
|
|
libspectrum_ide_drive *drv,
|
|
GHashTable *cache,
|
|
libspectrum_dword sector_number,
|
|
libspectrum_byte *src );
|
|
|
|
void
|
|
libspectrum_ide_commit_drive( libspectrum_ide_drive *drv, GHashTable *cache );
|
|
|
|
/* Crypto functions */
|
|
|
|
libspectrum_error
|
|
libspectrum_sign_data( libspectrum_byte **signature, size_t *signature_length,
|
|
libspectrum_byte *data, size_t data_length,
|
|
libspectrum_rzx_dsa_key *key );
|
|
|
|
/* Utility functions */
|
|
|
|
libspectrum_dword
|
|
libspectrum_ms_to_tstates( libspectrum_dword ms );
|
|
|
|
libspectrum_dword
|
|
libspectrum_tstates_to_ms( libspectrum_dword tstates );
|
|
|
|
void
|
|
libspectrum_set_pause_ms( libspectrum_tape_block *block,
|
|
libspectrum_dword pause_ms );
|
|
|
|
void
|
|
libspectrum_set_pause_tstates( libspectrum_tape_block *block,
|
|
libspectrum_dword pause_tstates );
|
|
|
|
size_t
|
|
libspectrum_bits_to_bytes( size_t bits );
|
|
|
|
extern const int LIBSPECTRUM_BITS_IN_BYTE;
|
|
|
|
char*
|
|
libspectrum_safe_strdup( const char *src );
|
|
|
|
/* glib replacement functions */
|
|
|
|
#ifndef HAVE_LIB_GLIB /* Only if we are using glib replacement */
|
|
void
|
|
libspectrum_slist_cleanup( void );
|
|
|
|
void
|
|
libspectrum_hashtable_cleanup( void );
|
|
|
|
#ifdef HAVE_STDATOMIC_H
|
|
#include <stdatomic.h>
|
|
|
|
void
|
|
atomic_lock( atomic_char *lock_ptr );
|
|
|
|
void
|
|
atomic_unlock( atomic_char *lock_ptr );
|
|
|
|
#endif /* #ifdef HAVE_STDATOMIC_H */
|
|
|
|
#endif /* #ifndef HAVE_LIB_GLIB */
|
|
|
|
#endif /* #ifndef LIBSPECTRUM_INTERNALS_H */
|