2018-09-11 10:21:59 +00:00
using System ;
using System.Collections.Generic ;
2018-03-05 11:17:22 +00:00
using System.Linq ;
using System.Text ;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
2018-06-14 10:31:09 +00:00
/// <summary>
/// The abstract class that all emulated models will inherit from
/// * Imported media *
/// </summary>
2018-03-05 11:17:22 +00:00
public abstract partial class SpectrumBase
{
/// <summary>
/// The tape or disk image(s) that are passed in from the main ZXSpectrum class
/// </summary>
protected List < byte [ ] > mediaImages { get ; set ; }
/// <summary>
/// Tape images
/// </summary>
2018-04-26 11:54:10 +00:00
public List < byte [ ] > tapeImages { get ; set ; }
2018-03-05 11:17:22 +00:00
/// <summary>
/// Disk images
/// </summary>
2018-04-26 11:54:10 +00:00
public List < byte [ ] > diskImages { get ; set ; }
2018-03-05 11:17:22 +00:00
2018-08-06 12:00:57 +00:00
/// <summary>
/// Set when a savestate is loaded
/// (Used to cancel any tape/disk load messages after a loadstate)
/// </summary>
public bool IsLoadState ;
2018-03-05 11:17:22 +00:00
/// <summary>
2018-03-13 13:09:44 +00:00
/// The index of the currently 'loaded' tape image
2018-03-05 11:17:22 +00:00
/// </summary>
protected int tapeMediaIndex ;
public int TapeMediaIndex
{
get { return tapeMediaIndex ; }
set
{
int tmp = value ;
int result = value ;
if ( tapeImages = = null | | tapeImages . Count ( ) = = 0 )
{
// no tape images found
return ;
}
if ( value > = tapeImages . Count ( ) )
{
// media at this index does not exist - loop back to 0
result = 0 ;
}
else if ( value < 0 )
{
// negative index not allowed - move to last item in the collection
result = tapeImages . Count ( ) - 1 ;
}
// load the media into the tape device
tapeMediaIndex = result ;
2019-01-02 14:02:09 +00:00
2018-03-05 13:29:34 +00:00
// fire osd message
2018-08-06 12:00:57 +00:00
if ( ! IsLoadState )
Spectrum . OSD_TapeInserted ( ) ;
2018-03-05 11:17:22 +00:00
LoadTapeMedia ( ) ;
}
}
/// <summary>
2018-03-13 13:09:44 +00:00
/// The index of the currently 'loaded' disk image
2018-03-05 11:17:22 +00:00
/// </summary>
protected int diskMediaIndex ;
public int DiskMediaIndex
{
get { return diskMediaIndex ; }
set
{
int tmp = value ;
int result = value ;
if ( diskImages = = null | | diskImages . Count ( ) = = 0 )
{
// no tape images found
return ;
}
if ( value > = diskImages . Count ( ) )
{
// media at this index does not exist - loop back to 0
result = 0 ;
}
else if ( value < 0 )
{
// negative index not allowed - move to last item in the collection
result = diskImages . Count ( ) - 1 ;
}
// load the media into the disk device
diskMediaIndex = result ;
2018-04-26 11:54:10 +00:00
// fire osd message
2018-08-06 12:00:57 +00:00
if ( ! IsLoadState )
Spectrum . OSD_DiskInserted ( ) ;
2018-04-26 11:54:10 +00:00
2018-03-05 11:17:22 +00:00
LoadDiskMedia ( ) ;
}
}
/// <summary>
/// Called on first instantiation (and subsequent core reboots)
/// </summary>
/// <param name="files"></param>
protected void InitializeMedia ( List < byte [ ] > files )
{
mediaImages = files ;
LoadAllMedia ( ) ;
}
/// <summary>
/// Attempts to load all media into the relevant structures
/// </summary>
protected void LoadAllMedia ( )
{
tapeImages = new List < byte [ ] > ( ) ;
diskImages = new List < byte [ ] > ( ) ;
2018-04-26 11:54:10 +00:00
int cnt = 0 ;
foreach ( var m in mediaImages )
2018-03-05 11:17:22 +00:00
{
2018-04-26 11:54:10 +00:00
switch ( IdentifyMedia ( m ) )
2018-03-05 11:17:22 +00:00
{
case SpectrumMediaType . Tape :
tapeImages . Add ( m ) ;
2018-04-26 11:54:10 +00:00
Spectrum . _tapeInfo . Add ( Spectrum . _gameInfo [ cnt ] ) ;
2018-03-05 11:17:22 +00:00
break ;
case SpectrumMediaType . Disk :
diskImages . Add ( m ) ;
2018-04-26 11:54:10 +00:00
Spectrum . _diskInfo . Add ( Spectrum . _gameInfo [ cnt ] ) ;
2018-03-05 11:17:22 +00:00
break ;
2018-09-11 10:21:59 +00:00
case SpectrumMediaType . DiskDoubleSided :
// this is a bit tricky. we will attempt to parse the double sided disk image byte array,
// then output two separate image byte arrays
List < byte [ ] > working = new List < byte [ ] > ( ) ;
foreach ( DiskType type in Enum . GetValues ( typeof ( DiskType ) ) )
{
bool found = false ;
switch ( type )
{
case DiskType . CPCExtended :
found = CPCExtendedFloppyDisk . SplitDoubleSided ( m , working ) ;
break ;
case DiskType . CPC :
found = CPCFloppyDisk . SplitDoubleSided ( m , working ) ;
break ;
2018-09-13 09:44:48 +00:00
case DiskType . UDI :
found = UDI1_0FloppyDisk . SplitDoubleSided ( m , working ) ;
break ;
2018-09-11 10:21:59 +00:00
}
if ( found )
{
// add side 1
diskImages . Add ( working [ 0 ] ) ;
// add side 2
diskImages . Add ( working [ 1 ] ) ;
Common . GameInfo one = new Common . GameInfo ( ) ;
Common . GameInfo two = new Common . GameInfo ( ) ;
var gi = Spectrum . _gameInfo [ cnt ] ;
for ( int i = 0 ; i < 2 ; i + + )
{
Common . GameInfo work = new Common . GameInfo ( ) ;
if ( i = = 0 )
{
work = one ;
}
else if ( i = = 1 )
{
work = two ;
}
work . FirmwareHash = gi . FirmwareHash ;
work . Hash = gi . Hash ;
work . Name = gi . Name + " (Parsed Side " + ( i + 1 ) + ")" ;
work . Region = gi . Region ;
work . NotInDatabase = gi . NotInDatabase ;
work . Status = gi . Status ;
work . System = gi . System ;
Spectrum . _diskInfo . Add ( work ) ;
}
}
else
{
}
}
break ;
2018-03-05 11:17:22 +00:00
}
2018-04-26 11:54:10 +00:00
cnt + + ;
2018-03-05 11:17:22 +00:00
}
if ( tapeImages . Count > 0 )
LoadTapeMedia ( ) ;
if ( diskImages . Count > 0 )
LoadDiskMedia ( ) ;
}
/// <summary>
/// Attempts to load a tape into the tape device based on tapeMediaIndex
/// </summary>
protected void LoadTapeMedia ( )
{
TapeDevice . LoadTape ( tapeImages [ tapeMediaIndex ] ) ;
}
/// <summary>
/// Attempts to load a disk into the disk device based on diskMediaIndex
/// </summary>
protected void LoadDiskMedia ( )
{
2018-04-26 11:54:10 +00:00
if ( this . GetType ( ) ! = typeof ( ZX128Plus3 ) )
{
Spectrum . CoreComm . ShowMessage ( "You are trying to load one of more disk images.\n\n Please select ZX Spectrum +3 emulation immediately and reboot the core" ) ;
return ;
}
UPDDiskDevice . FDD_LoadDisk ( diskImages [ diskMediaIndex ] ) ;
2018-03-05 11:17:22 +00:00
}
/// <summary>
/// Identifies and sorts the various media types
/// </summary>
/// <returns></returns>
private SpectrumMediaType IdentifyMedia ( byte [ ] data )
{
// get first 16 bytes as a string
string hdr = Encoding . ASCII . GetString ( data . Take ( 16 ) . ToArray ( ) ) ;
// disk checking first
2018-04-29 08:34:23 +00:00
if ( hdr . ToUpper ( ) . Contains ( "EXTENDED CPC DSK" ) | | hdr . ToUpper ( ) . Contains ( "MV - CPC" ) )
2018-03-05 11:17:22 +00:00
{
// spectrum .dsk disk file
2018-09-11 10:21:59 +00:00
// check for number of sides
var sides = data [ 0x31 ] ;
if ( sides = = 1 )
return SpectrumMediaType . Disk ;
else
return SpectrumMediaType . DiskDoubleSided ;
2018-03-05 11:17:22 +00:00
}
if ( hdr . ToUpper ( ) . StartsWith ( "FDI" ) )
{
// spectrum .fdi disk file
return SpectrumMediaType . Disk ;
}
2018-09-13 09:44:48 +00:00
if ( hdr . ToUpper ( ) . StartsWith ( "CAPS" ) )
{
// IPF format file
return SpectrumMediaType . Disk ;
}
if ( hdr . ToUpper ( ) . StartsWith ( "UDI!" ) & & data [ 0x08 ] = = 0 )
{
// UDI v1.0
if ( hdr . StartsWith ( "udi!" ) )
{
throw new NotSupportedException ( "ZXHawk currently does not supported UDIv1.0 with compression." ) ;
}
else
{
if ( data [ 0x0A ] = = 0x01 )
return SpectrumMediaType . DiskDoubleSided ;
else
return SpectrumMediaType . Disk ;
}
}
2018-03-05 11:17:22 +00:00
// tape checking
if ( hdr . ToUpper ( ) . StartsWith ( "ZXTAPE!" ) )
{
// spectrum .tzx tape file
return SpectrumMediaType . Tape ;
}
2018-06-20 14:03:11 +00:00
if ( hdr . ToUpper ( ) . StartsWith ( "PZXT" ) )
{
// spectrum .tzx tape file
return SpectrumMediaType . Tape ;
}
2018-06-22 12:23:33 +00:00
if ( hdr . ToUpper ( ) . StartsWith ( "COMPRESSED SQ" ) )
{
// spectrum .tzx tape file
return SpectrumMediaType . Tape ;
}
2018-06-22 13:40:40 +00:00
if ( hdr . ToUpper ( ) . Contains ( "WAVE" ) )
{
// spectrum .tzx tape file
return SpectrumMediaType . Tape ;
}
2018-03-05 11:17:22 +00:00
// if we get this far, assume a .tap file
return SpectrumMediaType . Tape ;
}
}
public enum SpectrumMediaType
{
None ,
Tape ,
2018-09-11 10:21:59 +00:00
Disk ,
DiskDoubleSided
2018-03-05 11:17:22 +00:00
}
}