mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
Sync with MESS (no whatsnew)
This commit is contained in:
parent
3f82bc4d81
commit
39746064c6
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1458,6 +1458,8 @@ src/lib/formats/a26_cas.c svneol=native#text/plain
|
||||
src/lib/formats/a26_cas.h svneol=native#text/plain
|
||||
src/lib/formats/ace_tap.c svneol=native#text/plain
|
||||
src/lib/formats/ace_tap.h svneol=native#text/plain
|
||||
src/lib/formats/adam_cas.c svneol=native#text/plain
|
||||
src/lib/formats/adam_cas.h svneol=native#text/plain
|
||||
src/lib/formats/ami_dsk.c svneol=native#text/plain
|
||||
src/lib/formats/ami_dsk.h svneol=native#text/plain
|
||||
src/lib/formats/ap2_dsk.c svneol=native#text/plain
|
||||
|
@ -104,17 +104,17 @@ void cassette_image_device::update()
|
||||
|
||||
if (is_motor_on())
|
||||
{
|
||||
double new_position = m_position + (cur_time - m_position_time);
|
||||
double new_position = m_position + (cur_time - m_position_time)*m_speed*m_direction;
|
||||
|
||||
switch(m_state & CASSETTE_MASK_UISTATE) {
|
||||
case CASSETTE_RECORD:
|
||||
cassette_put_sample(m_cassette, 0, m_position, new_position - m_position, m_value);
|
||||
cassette_put_sample(m_cassette, m_channel, m_position, new_position - m_position, m_value);
|
||||
break;
|
||||
|
||||
case CASSETTE_PLAY:
|
||||
if ( m_cassette )
|
||||
{
|
||||
cassette_get_sample(m_cassette, 0, new_position, 0.0, &m_value);
|
||||
cassette_get_sample(m_cassette, m_channel, new_position, 0.0, &m_value);
|
||||
/* See if reached end of tape */
|
||||
double length = get_length();
|
||||
if (new_position > length)
|
||||
@ -122,6 +122,11 @@ void cassette_image_device::update()
|
||||
m_state = (cassette_state)(( m_state & ~CASSETTE_MASK_UISTATE ) | CASSETTE_STOPPED);
|
||||
new_position = length;
|
||||
}
|
||||
else if (new_position < 0)
|
||||
{
|
||||
m_state = (cassette_state)(( m_state & ~CASSETTE_MASK_UISTATE ) | CASSETTE_STOPPED);
|
||||
new_position = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -182,7 +187,7 @@ double cassette_image_device::get_position()
|
||||
double position = m_position;
|
||||
|
||||
if (is_motor_on())
|
||||
position += device().machine().time().as_double() - m_position_time;
|
||||
position += (device().machine().time().as_double() - m_position_time)*m_speed*m_direction;
|
||||
return position;
|
||||
}
|
||||
|
||||
@ -196,6 +201,25 @@ double cassette_image_device::get_length()
|
||||
return ((double) info.sample_count) / info.sample_frequency;
|
||||
}
|
||||
|
||||
void cassette_image_device::set_channel(int channel)
|
||||
{
|
||||
m_channel = channel;
|
||||
}
|
||||
|
||||
void cassette_image_device::set_speed(double speed)
|
||||
{
|
||||
m_speed = speed;
|
||||
}
|
||||
|
||||
void cassette_image_device::go_forward()
|
||||
{
|
||||
m_direction = 1;
|
||||
}
|
||||
|
||||
void cassette_image_device::go_reverse()
|
||||
{
|
||||
m_direction = -1;
|
||||
}
|
||||
|
||||
|
||||
void cassette_image_device::seek(double time, int origin)
|
||||
@ -300,6 +324,11 @@ bool cassette_image_device::call_load()
|
||||
/* reset the position */
|
||||
m_position = 0.0;
|
||||
m_position_time = device().machine().time().as_double();
|
||||
|
||||
/* default channel to 0, speed multiplier to 1 */
|
||||
m_channel = 0;
|
||||
m_speed = 1;
|
||||
m_direction = 1;
|
||||
|
||||
return IMAGE_INIT_PASS;
|
||||
|
||||
|
@ -92,6 +92,10 @@ public:
|
||||
cassette_image *get_image() { return m_cassette; }
|
||||
double get_position();
|
||||
double get_length();
|
||||
void set_speed(double speed);
|
||||
void set_channel(int channel);
|
||||
void go_forward();
|
||||
void go_reverse();
|
||||
void seek(double time, int origin);
|
||||
|
||||
protected:
|
||||
@ -107,6 +111,9 @@ private:
|
||||
double m_position;
|
||||
double m_position_time;
|
||||
INT32 m_value;
|
||||
int m_channel;
|
||||
double m_speed; // speed multiplier for tape speeds other than standard 1.875ips (used in adam driver)
|
||||
int m_direction; // direction select
|
||||
char m_extension_list[256];
|
||||
};
|
||||
|
||||
|
210
src/lib/formats/adam_cas.c
Normal file
210
src/lib/formats/adam_cas.c
Normal file
@ -0,0 +1,210 @@
|
||||
|
||||
#include "cassimg.h"
|
||||
#include "adam_cas.h"
|
||||
|
||||
// This code will reproduce the timing of an adam tape played back on a standard tape deck with a 1 7/8ips speed.
|
||||
#define CASS_AMP 0x1fffffff
|
||||
#define SPEED_MULTIPLIER 20.0/1.875
|
||||
#define COL_ADAM_PERIOD 0.00007*SPEED_MULTIPLIER
|
||||
#define COL_ADAM_PERIOD1 0.000031*SPEED_MULTIPLIER
|
||||
#define COL_ADAM_PERIOD2 0.000039*SPEED_MULTIPLIER
|
||||
#define TYPE_HE 0
|
||||
#define TYPE_GW 1
|
||||
|
||||
/***************************************************************
|
||||
Coleco Adam Digital Data Pack format:
|
||||
The packs are the same shape as a standard audio cassette, but with different alignment and capstan holes
|
||||
The tape only has one side and has two widely separated mono data tracks (second track readable on an audio
|
||||
cassette deck by flipping the tape over and reversing the recorded signal).
|
||||
|
||||
Header format:
|
||||
2 byte header id: 0x48 0x45 (central directory HE type) or 0x47 0x57 (GW type)
|
||||
2 byte block number
|
||||
2 byte NOT block number
|
||||
1 byte number of blocks (0x80)
|
||||
1 byte sum of the above (checksum)
|
||||
|
||||
|
||||
track format:
|
||||
leading zeros: ~2753
|
||||
|
||||
block format:
|
||||
sync byte 0x16
|
||||
header
|
||||
pad zero bytes ~21
|
||||
sync byte 0x16
|
||||
data(1k)
|
||||
pad zero bytes ~21
|
||||
sync byte 0x16
|
||||
2 byte checksum-16
|
||||
pad zero bytes ~2
|
||||
sync bytes 0xaa ~922
|
||||
pad zero bytes ~2
|
||||
|
||||
Data is phase encoded, with 70us bit cells with a transition at 31us for a 1 and no transition for a 0
|
||||
|
||||
****************************************************************/
|
||||
|
||||
|
||||
static casserr_t coladam_ddp_identify ( cassette_image *cass, struct CassetteOptions *opts )
|
||||
{
|
||||
opts -> bits_per_sample = 16;
|
||||
opts -> channels = 2;
|
||||
opts -> sample_frequency = 44100;
|
||||
return CASSETTE_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Store byte of data
|
||||
casserr_t coladam_put_byte(cassette_image *cass, int channel, double *time_index, int byte, int *prev_sign)
|
||||
{
|
||||
casserr_t err;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if(byte & 0x80)
|
||||
{
|
||||
err = cassette_put_sample( cass, channel, *time_index, COL_ADAM_PERIOD1, -CASS_AMP*(*prev_sign) );
|
||||
(*time_index) += COL_ADAM_PERIOD1;
|
||||
err = cassette_put_sample( cass, channel, *time_index, COL_ADAM_PERIOD2, CASS_AMP*(*prev_sign) );
|
||||
(*time_index) += COL_ADAM_PERIOD2;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = cassette_put_sample( cass, channel, *time_index, COL_ADAM_PERIOD, -CASS_AMP*(*prev_sign) );
|
||||
(*prev_sign) *=-1;
|
||||
(*time_index) += COL_ADAM_PERIOD;
|
||||
}
|
||||
byte <<= 1;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
casserr_t coladam_put_block(cassette_image *cass, int channel, double *time_index, int *prev_sign, int block_index, UINT8 *buffer, int layout_type)
|
||||
{
|
||||
int i, checksum_16=0;
|
||||
UINT8 header[] = { 0x16, 0x48, 0x45, 0x00, block_index, 0xff, (0xff - block_index), 0x00, 0x80, 0xf4 };
|
||||
casserr_t err;
|
||||
if (layout_type == TYPE_GW)
|
||||
{
|
||||
header[1] = 0x47;
|
||||
header[2] = 0x57;
|
||||
header[9] = 0xe3;
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) // header
|
||||
{
|
||||
err = coladam_put_byte(cass, channel, time_index, header[i], prev_sign);
|
||||
}
|
||||
for (i = 0; i < 21; i++) // leading zero bytes
|
||||
{
|
||||
err = coladam_put_byte(cass, channel, time_index, 0x00, prev_sign);
|
||||
}
|
||||
err = coladam_put_byte(cass, channel, time_index, 0x16, prev_sign); // data start
|
||||
for ( i = 0; i < 0x400; i++ )
|
||||
{
|
||||
err = coladam_put_byte(cass, channel, time_index, buffer[i], prev_sign);
|
||||
checksum_16 += buffer[i];
|
||||
}
|
||||
for (i = 0; i < 21; i++) // trailing padding zeros
|
||||
{
|
||||
err = coladam_put_byte(cass, channel, time_index, 0x00, prev_sign);
|
||||
}
|
||||
err = coladam_put_byte(cass, channel, time_index, 0x16, prev_sign);
|
||||
err = coladam_put_byte(cass, channel, time_index, (checksum_16 & 0xff00) >> 8, prev_sign); // write checksum
|
||||
err = coladam_put_byte(cass, channel, time_index, (checksum_16 & 0xff), prev_sign);
|
||||
for (i = 0; i < 922; i++) // sync bytes
|
||||
{
|
||||
err = coladam_put_byte(cass, channel, time_index, 0xaa, prev_sign);
|
||||
}
|
||||
err = coladam_put_byte(cass, channel, time_index, 0x00, prev_sign);
|
||||
err = coladam_put_byte(cass, channel, time_index, 0x00, prev_sign);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static casserr_t coladam_ddp_load( cassette_image *cass )
|
||||
{
|
||||
double time = 0.;
|
||||
int i, block, prev_sign=-1;
|
||||
UINT8 buffer[0x400];
|
||||
casserr_t err;
|
||||
|
||||
// It would appear that data packs that originally had the type GW data layout and headers work fine when converted to type
|
||||
// HE. Thus we set all tapes to type HE.
|
||||
|
||||
int layout_type = TYPE_HE;
|
||||
|
||||
// Track 0
|
||||
for ( i = 0; i < 2753; i++ ) // leading zero bytes
|
||||
{
|
||||
err = coladam_put_byte(cass, 0, &time, 0x00, &prev_sign);
|
||||
}
|
||||
|
||||
for (block = 0; block < 128; block++)
|
||||
{
|
||||
cassette_image_read( cass, buffer, 0x20000+0x400*block, 0x400 );
|
||||
err = coladam_put_block(cass, 0, &time, &prev_sign, block, buffer, layout_type);
|
||||
}
|
||||
for (block = 128; block < 131; block++)
|
||||
{
|
||||
cassette_image_read( cass, buffer, 0x3f400+0x400*(block-128), 0x400 );
|
||||
err = coladam_put_block(cass, 0, &time, &prev_sign, block, buffer, layout_type);
|
||||
}
|
||||
|
||||
// Track 1
|
||||
time = 0.;
|
||||
for ( i = 0; i < 2753; i++ ) // leading zero bytes
|
||||
{
|
||||
err = coladam_put_byte(cass, 1, &time, 0x00, &prev_sign);
|
||||
}
|
||||
if (layout_type == TYPE_HE)
|
||||
{
|
||||
for (block = 0; block < 64; block++)
|
||||
{
|
||||
cassette_image_read( cass, buffer, 0x10000+0x400*block, 0x400 );
|
||||
err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type);
|
||||
}
|
||||
for (block = 64; block < 128; block++)
|
||||
{
|
||||
cassette_image_read( cass, buffer, 0x00000+0x400*(block-64), 0x400 );
|
||||
err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type);
|
||||
}
|
||||
for (block = 128; block < 131; block++)
|
||||
{
|
||||
cassette_image_read( cass, buffer, 0x0f400+0x400*(block-128), 0x400 );
|
||||
err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
time = 0;
|
||||
for ( i = 0; i < 2753; i++ ) // leading zero bytes
|
||||
{
|
||||
err = coladam_put_byte(cass, 1, &time, 0x00, &prev_sign);
|
||||
}
|
||||
for (block = 0; block < 128; block++)
|
||||
{
|
||||
cassette_image_read( cass, buffer, 0x400*block, 0x400 );
|
||||
err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type);
|
||||
}
|
||||
for (block = 128; block < 131; block++)
|
||||
{
|
||||
cassette_image_read( cass, buffer, 0x1f400+0x400*(block-128), 0x400 );
|
||||
err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type);
|
||||
}
|
||||
}
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return CASSETTE_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const struct CassetteFormat coladam_ddp =
|
||||
{ "ddp", coladam_ddp_identify, coladam_ddp_load, NULL /* no save */ };
|
||||
|
||||
CASSETTE_FORMATLIST_START(coleco_adam_cassette_formats)
|
||||
CASSETTE_FORMAT(coladam_ddp)
|
||||
CASSETTE_FORMATLIST_END
|
17
src/lib/formats/adam_cas.h
Normal file
17
src/lib/formats/adam_cas.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*********************************************************************
|
||||
|
||||
adam_cas.h
|
||||
|
||||
Format code for Coleco Adam .ddp casette files.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef __ADAM_CAS_H
|
||||
#define __ADAM_CAS_H
|
||||
|
||||
#include "cassimg.h"
|
||||
|
||||
CASSETTE_FORMATLIST_EXTERN(coleco_adam_cassette_formats);
|
||||
|
||||
#endif
|
||||
|
@ -479,7 +479,7 @@ casserr_t cassette_get_samples(cassette_image *cassette, int channel,
|
||||
|
||||
/* and write out the result */
|
||||
dest_ptr = (UINT8*)samples;
|
||||
dest_ptr += waveform_bytes_per_sample(waveform_flags) * sample_index;
|
||||
dest_ptr += waveform_bytes_per_sample(waveform_flags) * sample_index * cassette->channels;
|
||||
switch(waveform_bytes_per_sample(waveform_flags))
|
||||
{
|
||||
case 1:
|
||||
|
@ -94,6 +94,7 @@ FORMATSOBJS = \
|
||||
$(LIBOBJ)/formats/basicdsk.o \
|
||||
$(LIBOBJ)/formats/a26_cas.o \
|
||||
$(LIBOBJ)/formats/ace_tap.o \
|
||||
$(LIBOBJ)/formats/adam_cas.o \
|
||||
$(LIBOBJ)/formats/ami_dsk.o \
|
||||
$(LIBOBJ)/formats/ap2_dsk.o \
|
||||
$(LIBOBJ)/formats/apf_apt.o \
|
||||
|
Loading…
Reference in New Issue
Block a user