mirror of
https://github.com/holub/mame
synced 2025-05-17 03:10:43 +03:00

integer value, regions are now referred to by a region class and a region tag. The class specifies the type of region (one of CPU, gfx, sound, user, disk, prom, pld) while the tag uniquely specifies the region. This change required updating all the ROM region definitions in the project to specify the class/tag instead of region number. Updated the core memory_region_* functions to accept a class/tag pair. Added new memory_region_next() function to allow for iteration over all memory regions of a given class. Added new function memory_region_class_name() to return the name for a given CPU memory region class. Changed the auto-binding behavior of CPU regions. Previously, the first CPU would auto-bind to REGION_CPU1 (that is, any ROM references would automatically assume that they lived in the corresponding region). Now, each CPU automatically binds to the RGNCLASS_CPU region with the same tag as the CPU itself. This behavior required ensuring that all previous REGION_CPU* regions were changed to RGNCLASS_CPU with the same tag as the CPU. Introduced a new auto-binding mechanism for sound cores. This works similarly to the CPU binding. Each sound core that requires a memory region now auto-binds to the RGNCLASS_SOUND with the same tag as the sound core. In almost all cases, this allowed for the removal of the explicit region item in the sound configuration, which in turn allowed for many sound configurations to removed altogether. Updated the expression engine's memory reference behavior. A recent update expanded the scope of memory references to allow for referencing data in non-active CPU spaces, in memory regions, and in EEPROMs. However, this previous update required an index, which is no longer appropriate for regions and will become increasingly less appropriate for CPUs over time. Instead, a new syntax is supported, of the form: "[tag.][space]size@addr", where 'tag' is an optional tag for the CPU or memory region you wish to access, followed by a period as a separator; 'space' is the memory address space or region class you wish to access (p/d/i for program/data/I/O spaces; o for opcode space; r for direct RAM; c/u/g/s for CPU/user/gfx/sound regions; e for EEPROMs); and 'size' is the usual b/w/d/q for byte/word/dword/qword. Cleaned up ROM definition flags and removed some ugly hacks that had existed previously. Expanded to support up to 256 BIOSes. Updated ROM_COPY to support specifying class/tag for the source region. Updated the address map AM_REGION macro to support specifying a class/tag for the region. Updated debugger windows to display the CPU and region tags where appropriate. Updated -listxml to output region class and tag for each ROM entry.
297 lines
8.4 KiB
C
297 lines
8.4 KiB
C
/**********************************************************************************************
|
|
|
|
TMS5220 interface
|
|
|
|
Written for MAME by Frank Palazzolo
|
|
With help from Neill Corlett
|
|
Additional tweaking by Aaron Giles
|
|
Speech ROM support and a few bug fixes by R Nabet
|
|
|
|
***********************************************************************************************/
|
|
|
|
#include <math.h>
|
|
|
|
#include "sndintrf.h"
|
|
#include "streams.h"
|
|
#include "tms5220.h"
|
|
#include "5220intf.h"
|
|
|
|
|
|
#define MAX_SAMPLE_CHUNK 10000
|
|
|
|
|
|
/* the state of the streamed output */
|
|
struct tms5220_info
|
|
{
|
|
const struct TMS5220interface *intf;
|
|
sound_stream *stream;
|
|
int clock;
|
|
void *chip;
|
|
};
|
|
|
|
|
|
/* static function prototypes */
|
|
static void tms5220_update(void *param, stream_sample_t **inputs, stream_sample_t **buffer, int length);
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
tms5220_start -- allocate buffers and reset the 5220
|
|
|
|
***********************************************************************************************/
|
|
|
|
static void *tms5220_start(const char *tag, int sndindex, int clock, const void *config)
|
|
{
|
|
static const struct TMS5220interface dummy = { 0 };
|
|
struct tms5220_info *info;
|
|
|
|
info = auto_malloc(sizeof(*info));
|
|
memset(info, 0, sizeof(*info));
|
|
info->intf = config ? config : &dummy;
|
|
|
|
info->chip = tms5220_create(sndindex);
|
|
if (!info->chip)
|
|
return NULL;
|
|
sndintrf_register_token(info);
|
|
|
|
/* initialize a info->stream */
|
|
info->stream = stream_create(0, 1, clock / 80, info, tms5220_update);
|
|
info->clock = clock;
|
|
|
|
/* reset the 5220 */
|
|
tms5220_reset_chip(info->chip);
|
|
tms5220_set_irq(info->chip, info->intf->irq);
|
|
|
|
/* init the speech ROM handlers */
|
|
tms5220_set_read(info->chip, info->intf->read);
|
|
tms5220_set_load_address(info->chip, info->intf->load_address);
|
|
tms5220_set_read_and_branch(info->chip, info->intf->read_and_branch);
|
|
|
|
/* request a sound channel */
|
|
return info;
|
|
}
|
|
|
|
|
|
#if (HAS_TMC0285 || HAS_TMS5200)
|
|
static void *tms5200_start(const char *tag, int sndindex, int clock, const void *config)
|
|
{
|
|
struct tms5220_info *info = tms5220_start(tag, sndindex, clock, config);
|
|
tms5220_set_variant(info->chip, variant_tmc0285);
|
|
return info;
|
|
}
|
|
#endif /* (HAS_TMC0285) && (HAS_TMS5200) */
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
tms5220_stop -- free buffers
|
|
|
|
***********************************************************************************************/
|
|
|
|
static void tms5220_stop(void *chip)
|
|
{
|
|
struct tms5220_info *info = chip;
|
|
tms5220_destroy(info->chip);
|
|
}
|
|
|
|
|
|
|
|
static void tms5220_reset(void *chip)
|
|
{
|
|
struct tms5220_info *info = chip;
|
|
tms5220_reset_chip(info->chip);
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
tms5220_data_w -- write data to the sound chip
|
|
|
|
***********************************************************************************************/
|
|
|
|
WRITE8_HANDLER( tms5220_data_w )
|
|
{
|
|
struct tms5220_info *info = sndti_token(SOUND_TMS5220, 0);
|
|
/* bring up to date first */
|
|
stream_update(info->stream);
|
|
tms5220_data_write(info->chip, data);
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
tms5220_status_r -- read status or data from the sound chip
|
|
|
|
***********************************************************************************************/
|
|
|
|
READ8_HANDLER( tms5220_status_r )
|
|
{
|
|
struct tms5220_info *info = sndti_token(SOUND_TMS5220, 0);
|
|
/* bring up to date first */
|
|
stream_update(info->stream);
|
|
return tms5220_status_read(info->chip);
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
tms5220_ready_r -- return the not ready status from the sound chip
|
|
|
|
***********************************************************************************************/
|
|
|
|
int tms5220_ready_r(void)
|
|
{
|
|
struct tms5220_info *info = sndti_token(SOUND_TMS5220, 0);
|
|
/* bring up to date first */
|
|
stream_update(info->stream);
|
|
return tms5220_ready_read(info->chip);
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
tms5220_ready_r -- return the time in seconds until the ready line is asserted
|
|
|
|
***********************************************************************************************/
|
|
|
|
double tms5220_time_to_ready(void)
|
|
{
|
|
struct tms5220_info *info = sndti_token(SOUND_TMS5220, 0);
|
|
double cycles;
|
|
|
|
/* bring up to date first */
|
|
stream_update(info->stream);
|
|
cycles = tms5220_cycles_to_ready(info->chip);
|
|
return cycles * 80.0 / info->clock;
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
tms5220_int_r -- return the int status from the sound chip
|
|
|
|
***********************************************************************************************/
|
|
|
|
int tms5220_int_r(void)
|
|
{
|
|
struct tms5220_info *info = sndti_token(SOUND_TMS5220, 0);
|
|
/* bring up to date first */
|
|
stream_update(info->stream);
|
|
return tms5220_int_read(info->chip);
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
tms5220_update -- update the sound chip so that it is in sync with CPU execution
|
|
|
|
***********************************************************************************************/
|
|
|
|
static void tms5220_update(void *param, stream_sample_t **inputs, stream_sample_t **_buffer, int length)
|
|
{
|
|
struct tms5220_info *info = param;
|
|
INT16 sample_data[MAX_SAMPLE_CHUNK];
|
|
stream_sample_t *buffer = _buffer[0];
|
|
|
|
/* loop while we still have samples to generate */
|
|
while (length)
|
|
{
|
|
int samples = (length > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : length;
|
|
int index;
|
|
|
|
/* generate the samples and copy to the target buffer */
|
|
tms5220_process(info->chip, sample_data, samples);
|
|
for (index = 0; index < samples; index++)
|
|
*buffer++ = sample_data[index];
|
|
|
|
/* account for the samples */
|
|
length -= samples;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
tms5220_set_frequency -- adjusts the playback frequency
|
|
|
|
***********************************************************************************************/
|
|
|
|
void tms5220_set_frequency(int frequency)
|
|
{
|
|
struct tms5220_info *info = sndti_token(SOUND_TMS5220, 0);
|
|
stream_set_sample_rate(info->stream, frequency / 80);
|
|
info->clock = frequency;
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
* Generic get_info
|
|
**************************************************************************/
|
|
|
|
static void tms5220_set_info(void *token, UINT32 state, sndinfo *info)
|
|
{
|
|
struct tms5220_info *ti = token;
|
|
|
|
switch (state)
|
|
{
|
|
case SNDINFO_INT_TMS5220_VARIANT: tms5220_set_variant(ti->chip, (tms5220_variant) info->i); break;
|
|
}
|
|
}
|
|
|
|
|
|
void tms5220_get_info(void *token, UINT32 state, sndinfo *info)
|
|
{
|
|
switch (state)
|
|
{
|
|
/* --- the following bits of info are returned as 64-bit signed integers --- */
|
|
case SNDINFO_INT_ALIAS: info->i = SOUND_TMS5220; break;
|
|
|
|
/* --- the following bits of info are returned as pointers to data or functions --- */
|
|
case SNDINFO_PTR_SET_INFO: info->set_info = tms5220_set_info; break;
|
|
case SNDINFO_PTR_START: info->start = tms5220_start; break;
|
|
case SNDINFO_PTR_STOP: info->stop = tms5220_stop; break;
|
|
case SNDINFO_PTR_RESET: info->reset = tms5220_reset; break;
|
|
|
|
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
|
case SNDINFO_STR_NAME: info->s = "TMS5220"; break;
|
|
case SNDINFO_STR_CORE_FAMILY: info->s = "TI Speech"; break;
|
|
case SNDINFO_STR_CORE_VERSION: info->s = "1.0"; break;
|
|
case SNDINFO_STR_CORE_FILE: info->s = __FILE__; break;
|
|
case SNDINFO_STR_CORE_CREDITS: info->s = "Copyright Nicola Salmoria and the MAME Team"; break;
|
|
}
|
|
}
|
|
|
|
#if (HAS_TMC0285)
|
|
void tmc0285_get_info(void *token, UINT32 state, sndinfo *info)
|
|
{
|
|
switch (state)
|
|
{
|
|
case SNDINFO_PTR_START: info->start = tms5200_start; break;
|
|
case SNDINFO_STR_NAME: info->s = "TMC0285"; break;
|
|
default: tms5220_get_info(token, state, info); break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if (HAS_TMS5200)
|
|
void tms5200_get_info(void *token, UINT32 state, sndinfo *info)
|
|
{
|
|
switch (state)
|
|
{
|
|
case SNDINFO_PTR_START: info->start = tms5200_start; break;
|
|
case SNDINFO_STR_NAME: info->s = "TMS5200"; break;
|
|
default: tms5220_get_info(token, state, info); break;
|
|
}
|
|
}
|
|
#endif
|