mirror of
https://github.com/holub/mame
synced 2025-07-02 08:39:21 +03:00
(MESS) camplynx: added TAP cassette format.
This commit is contained in:
parent
c3573f9201
commit
c26b5dadc4
@ -168,6 +168,8 @@ project "formats"
|
||||
MAME_DIR .. "src/lib/formats/c4040_dsk.h",
|
||||
MAME_DIR .. "src/lib/formats/c8280_dsk.c",
|
||||
MAME_DIR .. "src/lib/formats/c8280_dsk.h",
|
||||
MAME_DIR .. "src/lib/formats/camplynx_cas.c",
|
||||
MAME_DIR .. "src/lib/formats/camplynx_cas.h",
|
||||
MAME_DIR .. "src/lib/formats/cbm_crt.c",
|
||||
MAME_DIR .. "src/lib/formats/cbm_crt.h",
|
||||
MAME_DIR .. "src/lib/formats/cbm_tap.c",
|
||||
|
205
src/lib/formats/camplynx_cas.c
Normal file
205
src/lib/formats/camplynx_cas.c
Normal file
@ -0,0 +1,205 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Robbbert
|
||||
/********************************************************************
|
||||
|
||||
Support for Camputers Lynx cassette images
|
||||
|
||||
|
||||
We support TAP files used by the Pale and Jynx emulators.
|
||||
|
||||
Tape format:
|
||||
- about 7 seconds of zeroes
|
||||
- A5 byte
|
||||
- 22 byte
|
||||
- program name
|
||||
- 22 byte
|
||||
- about 7 seconds of zeroes
|
||||
- A5 byte
|
||||
- header
|
||||
- main program
|
||||
- checksum
|
||||
|
||||
Each byte is 8 bits (MSB first) with no start or stop bits.
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "camplynx_cas.h"
|
||||
|
||||
#define WAVEENTRY_LOW -32768
|
||||
#define WAVEENTRY_HIGH 32767
|
||||
|
||||
#define LYNX48K_WAV_FREQUENCY 4000
|
||||
#define LYNX128K_WAV_FREQUENCY 8000
|
||||
|
||||
|
||||
// image size
|
||||
static int camplynx_image_size;
|
||||
|
||||
static int camplynx_put_samples(INT16 *buffer, int sample_pos, int count, int level)
|
||||
{
|
||||
if (buffer)
|
||||
{
|
||||
for (int i=0; i<count; i++)
|
||||
buffer[sample_pos + i] = level;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int camplynx_output_bit(INT16 *buffer, int sample_pos, bool bit)
|
||||
{
|
||||
int samples = 0;
|
||||
|
||||
if (bit)
|
||||
{
|
||||
samples += camplynx_put_samples(buffer, sample_pos + samples, 4, WAVEENTRY_HIGH);
|
||||
samples += camplynx_put_samples(buffer, sample_pos + samples, 4, WAVEENTRY_LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
samples += camplynx_put_samples(buffer, sample_pos + samples, 2, WAVEENTRY_HIGH);
|
||||
samples += camplynx_put_samples(buffer, sample_pos + samples, 2, WAVEENTRY_LOW);
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
static int camplynx_output_byte(INT16 *buffer, int sample_pos, UINT8 byte)
|
||||
{
|
||||
int samples = 0;
|
||||
UINT8 i;
|
||||
|
||||
/* data */
|
||||
for (i = 0; i<8; i++)
|
||||
samples += camplynx_output_bit (buffer, sample_pos + samples, (byte >> (7-i)) & 1);
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
static int camplynx_handle_cassette(INT16 *buffer, const UINT8 *bytes)
|
||||
{
|
||||
UINT32 sample_count = 0;
|
||||
UINT32 byte_count = 1;
|
||||
UINT32 i;
|
||||
|
||||
|
||||
/* header zeroes */
|
||||
for (i=0; i<555; i++)
|
||||
sample_count += camplynx_output_byte(buffer, sample_count, 0);
|
||||
|
||||
sample_count += camplynx_output_byte(buffer, sample_count, 0xA5);
|
||||
sample_count += camplynx_output_byte(buffer, sample_count, bytes[0]); // should be 0x22
|
||||
|
||||
/* program name - include protection in case tape is corrupt */
|
||||
for (int i=1; bytes[i]!=0x22; i++)
|
||||
{
|
||||
if (i < camplynx_image_size)
|
||||
sample_count += camplynx_output_byte(buffer, sample_count, bytes[i]);
|
||||
else
|
||||
return sample_count;
|
||||
byte_count++;
|
||||
}
|
||||
|
||||
sample_count += camplynx_output_byte(buffer, sample_count, bytes[byte_count++]); // should be 0x22
|
||||
|
||||
/* data zeroes */
|
||||
for (i=0; i<555; i++)
|
||||
sample_count += camplynx_output_byte(buffer, sample_count, 0);
|
||||
|
||||
sample_count += camplynx_output_byte(buffer, sample_count, 0xA5);
|
||||
|
||||
/* data */
|
||||
for (i=byte_count; i<camplynx_image_size; i++)
|
||||
sample_count += camplynx_output_byte(buffer, sample_count, bytes[i]);
|
||||
|
||||
return sample_count;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
Generate samples for the tape image
|
||||
********************************************************************/
|
||||
|
||||
static int camplynx_cassette_fill_wave(INT16 *buffer, int length, UINT8 *bytes)
|
||||
{
|
||||
return camplynx_handle_cassette(buffer, bytes);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Calculate the number of samples needed for this tape image
|
||||
********************************************************************/
|
||||
|
||||
static int camplynx_cassette_calculate_size_in_samples(const UINT8 *bytes, int length)
|
||||
{
|
||||
camplynx_image_size = length;
|
||||
|
||||
return camplynx_handle_cassette(NULL, bytes);
|
||||
}
|
||||
|
||||
static const struct CassetteLegacyWaveFiller lynx48k_legacy_fill_wave =
|
||||
{
|
||||
camplynx_cassette_fill_wave, /* fill_wave */
|
||||
-1, /* chunk_size */
|
||||
0, /* chunk_samples */
|
||||
camplynx_cassette_calculate_size_in_samples, /* chunk_sample_calc */
|
||||
LYNX48K_WAV_FREQUENCY, /* sample_frequency */
|
||||
0, /* header_samples */
|
||||
0 /* trailer_samples */
|
||||
};
|
||||
|
||||
static const struct CassetteLegacyWaveFiller lynx128k_legacy_fill_wave =
|
||||
{
|
||||
camplynx_cassette_fill_wave, /* fill_wave */
|
||||
-1, /* chunk_size */
|
||||
0, /* chunk_samples */
|
||||
camplynx_cassette_calculate_size_in_samples, /* chunk_sample_calc */
|
||||
LYNX128K_WAV_FREQUENCY, /* sample_frequency */
|
||||
0, /* header_samples */
|
||||
0 /* trailer_samples */
|
||||
};
|
||||
|
||||
static casserr_t lynx48k_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts)
|
||||
{
|
||||
return cassette_legacy_identify(cassette, opts, &lynx48k_legacy_fill_wave);
|
||||
}
|
||||
|
||||
static casserr_t lynx128k_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts)
|
||||
{
|
||||
return cassette_legacy_identify(cassette, opts, &lynx128k_legacy_fill_wave);
|
||||
}
|
||||
|
||||
static casserr_t lynx48k_cassette_load(cassette_image *cassette)
|
||||
{
|
||||
return cassette_legacy_construct(cassette, &lynx48k_legacy_fill_wave);
|
||||
}
|
||||
|
||||
static casserr_t lynx128k_cassette_load(cassette_image *cassette)
|
||||
{
|
||||
return cassette_legacy_construct(cassette, &lynx128k_legacy_fill_wave);
|
||||
}
|
||||
|
||||
static const struct CassetteFormat lynx48k_cassette_image_format =
|
||||
{
|
||||
"tap",
|
||||
lynx48k_cassette_identify,
|
||||
lynx48k_cassette_load,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct CassetteFormat lynx128k_cassette_image_format =
|
||||
{
|
||||
"tap",
|
||||
lynx128k_cassette_identify,
|
||||
lynx128k_cassette_load,
|
||||
NULL
|
||||
};
|
||||
|
||||
CASSETTE_FORMATLIST_START(lynx48k_cassette_formats)
|
||||
CASSETTE_FORMAT(lynx48k_cassette_image_format)
|
||||
CASSETTE_FORMATLIST_END
|
||||
|
||||
CASSETTE_FORMATLIST_START(lynx128k_cassette_formats)
|
||||
CASSETTE_FORMAT(lynx128k_cassette_image_format)
|
||||
CASSETTE_FORMATLIST_END
|
15
src/lib/formats/camplynx_cas.h
Normal file
15
src/lib/formats/camplynx_cas.h
Normal file
@ -0,0 +1,15 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Robbbert
|
||||
/*********************************************************************
|
||||
|
||||
camplynx_cas.h
|
||||
|
||||
Format code for Camputers Lynx cassette images (TAP format)
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
#include "cassimg.h"
|
||||
|
||||
CASSETTE_FORMATLIST_EXTERN(lynx48k_cassette_formats);
|
||||
CASSETTE_FORMATLIST_EXTERN(lynx128k_cassette_formats);
|
@ -95,6 +95,7 @@
|
||||
#include "sound/dac.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "sound/wave.h"
|
||||
#include "formats/camplynx_cas.h"
|
||||
|
||||
class camplynx_state : public driver_device
|
||||
{
|
||||
@ -573,6 +574,7 @@ static MACHINE_CONFIG_START( lynx48k, camplynx_state )
|
||||
MCFG_MC6845_UPDATE_ROW_CB(camplynx_state, lynx48k_update_row)
|
||||
|
||||
MCFG_CASSETTE_ADD("cassette")
|
||||
MCFG_CASSETTE_FORMATS(lynx48k_cassette_formats)
|
||||
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_DISABLED)
|
||||
//MCFG_CASSETTE_INTERFACE("camplynx_cass")
|
||||
MACHINE_CONFIG_END
|
||||
@ -611,6 +613,7 @@ static MACHINE_CONFIG_START( lynx128k, camplynx_state )
|
||||
MCFG_MC6845_OUT_HSYNC_CB(WRITE8(camplynx_state, lynx128k_irq))
|
||||
|
||||
MCFG_CASSETTE_ADD("cassette")
|
||||
MCFG_CASSETTE_FORMATS(lynx128k_cassette_formats)
|
||||
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_DISABLED)
|
||||
//MCFG_CASSETTE_INTERFACE("camplynx_cass")
|
||||
MACHINE_CONFIG_END
|
||||
|
Loading…
Reference in New Issue
Block a user