mirror of
https://github.com/holub/mame
synced 2025-06-26 06:14:12 +03:00
trs80m3: Added support for high-speed CAS files.
This commit is contained in:
parent
2c52caf49a
commit
c5f293954d
@ -15,7 +15,7 @@ Support for TRS80 .cas cassette images
|
|||||||
#define SMPHI 32767
|
#define SMPHI 32767
|
||||||
|
|
||||||
|
|
||||||
static int cas_size; // FIXME: global variable prevents multiple instances
|
static int cas_size = 0; // FIXME: global variable prevents multiple instances
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
@ -41,10 +41,7 @@ static inline int trs80l2_cas_cycle(int16_t *buffer, int sample_pos, bool bit)
|
|||||||
static int trs80l2_handle_cas(int16_t *buffer, const uint8_t *casdata)
|
static int trs80l2_handle_cas(int16_t *buffer, const uint8_t *casdata)
|
||||||
{
|
{
|
||||||
int data_pos = 0, sample_count = 0;
|
int data_pos = 0, sample_count = 0;
|
||||||
bool a5sw = false;
|
bool sw = false;
|
||||||
|
|
||||||
data_pos = 0;
|
|
||||||
sample_count = 0;
|
|
||||||
|
|
||||||
while( data_pos < cas_size )
|
while( data_pos < cas_size )
|
||||||
{
|
{
|
||||||
@ -61,9 +58,9 @@ static int trs80l2_handle_cas(int16_t *buffer, const uint8_t *casdata)
|
|||||||
data <<= 1;
|
data <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!a5sw && (casdata[data_pos] == 0xA5))
|
if (!sw && (casdata[data_pos] == 0xA5))
|
||||||
{
|
{
|
||||||
a5sw = true;
|
sw = true;
|
||||||
// Need 1ms silence here while rom is busy
|
// Need 1ms silence here while rom is busy
|
||||||
sample_count += trs80l2_cas_cycle( buffer, sample_count, false );
|
sample_count += trs80l2_cas_cycle( buffer, sample_count, false );
|
||||||
}
|
}
|
||||||
@ -77,12 +74,91 @@ static int trs80l2_handle_cas(int16_t *buffer, const uint8_t *casdata)
|
|||||||
return sample_count;
|
return sample_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int trs80m3_cas_cycle(int16_t *buffer, int sample_pos, bool bit)
|
||||||
|
{
|
||||||
|
uint8_t i, counts = bit ? 8 : 16;
|
||||||
|
|
||||||
|
if ( buffer )
|
||||||
|
{
|
||||||
|
for (i = 0; i < counts; i++)
|
||||||
|
buffer[ sample_pos++ ] = SMPHI;
|
||||||
|
for (i = 0; i < counts; i++)
|
||||||
|
buffer[ sample_pos++ ] = SMPLO;
|
||||||
|
}
|
||||||
|
return counts*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int trs80m3_handle_cas(int16_t *buffer, const uint8_t *casdata)
|
||||||
|
{
|
||||||
|
int data_pos = 0, sample_count = 0;
|
||||||
|
uint8_t sw = 0, bitout = 0, byteout = 0;
|
||||||
|
|
||||||
|
// Make sure this is a trs80m3 tape
|
||||||
|
// Should have ~256 0x55 then one 0x7f
|
||||||
|
while ((cas_size > data_pos) && (casdata[data_pos] == 0x55))
|
||||||
|
data_pos++;
|
||||||
|
if (casdata[data_pos] != 0x7f)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
data_pos = 0;
|
||||||
|
while( data_pos < cas_size )
|
||||||
|
{
|
||||||
|
uint8_t data = casdata[data_pos];
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 8; i++ )
|
||||||
|
{
|
||||||
|
sample_count += trs80m3_cas_cycle( buffer, sample_count, data >> 7 );
|
||||||
|
|
||||||
|
// This paragraph unscrambles and prints the SYSTEM name.
|
||||||
|
// If the first character is U, type SYSTEM, then the next 6 characters; otherwise use CLOAD.
|
||||||
|
if ((sw == 1) && buffer)
|
||||||
|
{
|
||||||
|
if (bitout)
|
||||||
|
{
|
||||||
|
byteout = (byteout << 1) | (data >> 7);
|
||||||
|
if (bitout == 8)
|
||||||
|
{
|
||||||
|
if (byteout == 0)
|
||||||
|
sw = 2;
|
||||||
|
printf("%c",byteout);
|
||||||
|
byteout = 0;
|
||||||
|
bitout = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bitout++;
|
||||||
|
}
|
||||||
|
else bitout++;
|
||||||
|
}
|
||||||
|
|
||||||
|
data <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sw && (casdata[data_pos] == 0x7F))
|
||||||
|
{
|
||||||
|
sw = 1;
|
||||||
|
// This 1ms of silence isn't absolutely necessary, but the system writes it, so we may as emulate it.
|
||||||
|
sample_count += trs80l2_cas_cycle( buffer, sample_count, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
data_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specification requires a short silence to indicate EOF
|
||||||
|
sample_count += trs80l2_cas_cycle( buffer, sample_count, false );
|
||||||
|
sample_count += trs80l2_cas_cycle( buffer, sample_count, false );
|
||||||
|
return sample_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
Generate samples for the tape image
|
Generate samples for the tape image
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
static int trs80l2_cas_fill_wave(int16_t *buffer, int sample_count, uint8_t *bytes)
|
static int trs80l2_cas_fill_wave(int16_t *buffer, int sample_count, uint8_t *bytes)
|
||||||
{
|
{
|
||||||
|
if (cas_size && (bytes[0] == 0x55))
|
||||||
|
return trs80m3_handle_cas( buffer, bytes );
|
||||||
|
else
|
||||||
return trs80l2_handle_cas( buffer, bytes );
|
return trs80l2_handle_cas( buffer, bytes );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +170,9 @@ static int trs80l2_cas_to_wav_size(const uint8_t *casdata, int caslen)
|
|||||||
{
|
{
|
||||||
cas_size = caslen;
|
cas_size = caslen;
|
||||||
|
|
||||||
|
if (cas_size && (casdata[0] == 0x55))
|
||||||
|
return trs80m3_handle_cas( nullptr, casdata );
|
||||||
|
else
|
||||||
return trs80l2_handle_cas( nullptr, casdata );
|
return trs80l2_handle_cas( nullptr, casdata );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user