Lots of changes. Maybe for the better, maybe not.

This commit is contained in:
2008-11-28 21:50:56 +00:00
parent aaee3363c4
commit fc0606303b
20 changed files with 966 additions and 72 deletions
+18 -2
View File
@@ -2,5 +2,21 @@
all: ay8910test
ay8910test: ay8910.c
gcc -o ay8910test ay8910.c
ay8910test: ay8910.o sound.o sndintrf.o
gcc -o ay8910test sound.o ay8910.o sndintrf.o -lSDL
ay8910.o: ay8910.c
gcc -c -Wall ay8910.c
sound.o: sound.c
gcc -c -Wall sound.c
#streams.o: streams.c
# gcc -c -Wall streams.c
sndintrf.o: sndintrf.c
gcc -c -Wall sndintrf.c
.PHONY clean:
rm ay8910test *.o
+146 -60
View File
@@ -61,9 +61,9 @@
| |
GND GND
Each Volume level x will select a different resistor Rx. Measurements from fpgaarcade.com
where used to calibrate channel mixing for the YM2149. This was done using
a least square approach using a fixed RL of 1K Ohm.
Each Volume level x will select a different resistor Rx. Measurements from
fpgaarcade.com were used to calibrate channel mixing for the YM2149. This was
done using a least square approach using a fixed RL of 1K Ohm.
For the AY measurements cited in e.g. openmsx as "Hacker Kay" for a single
channel were taken. These were normalized to 0 ... 65535 and consequently
@@ -73,14 +73,13 @@ line e.g. with the formula used by pcmenc for the volume: vol(i) = exp(i/2-7.5).
The following is documentation from the code moved here and amended to reflect
the changes done:
Careful studies of the chip output prove that the chip counts up from 0
until the counter becomes greater or equal to the period. This is an
important difference when the program is rapidly changing the period to
modulate the sound. This is worthwhile noting, since the datasheets
say, that the chip counts down.
Also, note that period = 0 is the same as period = 1. This is mentioned
in the YM2203 data sheets. However, this does NOT apply to the Envelope
period. In that case, period = 0 is half as period = 1.
Careful studies of the chip output prove that the chip counts up from 0 until
the counter becomes greater or equal to the period. This is an important
difference when the program is rapidly changing the period to modulate the
sound. This is worthwhile noting, since the datasheets say, that the chip
counts down. Also, note that period = 0 is the same as period = 1. This is
mentioned in the YM2203 data sheets. However, this does NOT apply to the
Envelope period. In that case, period = 0 is half as period = 1.
Envelope shapes:
C AtAlH
@@ -99,20 +98,35 @@ The envelope counter on the AY-3-8910 has 16 steps. On the YM2149 it
has twice the steps, happening twice as fast.
***************************************************************************/
#include <SDL/SDL.h>
#include <unistd.h>
#include <math.h>
// MAME headers
/*
#include "osdcomm.h"
#include "mamecore.h"
#include "deprecat.h"
#include "sndintrf.h"
#include "deprecat.h"
//#include "deprecat.h"
#include "streams.h"
//#include "cpuintrf.h"
#include "cpuintrf.h"
*/
#include "sndint.h"
#include "ay8910.h"
// lazyness
#define logerror printf
/* pen_t is used to represent pixel values in bitmaps */
typedef UINT32 pen_t;
/* stream_sample_t is used to represent a single sample in a sound stream */
typedef INT32 stream_sample_t;
/*************************************
*
* Defines
*
*************************************/
#define MAX_OUTPUT 0x7fff
@@ -145,8 +159,19 @@ has twice the steps, happening twice as fast.
#define TONE_ENVELOPE(_psg, _chan) (((_psg)->regs[AY_AVOL + (_chan)] >> 4) & 1)
#define ENVELOPE_PERIOD(_psg) (((_psg)->regs[AY_EFINE] | ((_psg)->regs[AY_ECOARSE]<<8)))
/*************************************
*
// prototypes
extern int sdl_init(int samplerate);
extern int sdlaudio_init(int samplerate);
extern void sdl_kill();
extern int sdl_create_buffers(void);
extern void sdl_destroy_buffers(void);
extern void sdl_cleanup_audio(int samplerate);
extern void sdl_callback(void *userdata, Uint8 *stream, int len);
extern void osd_update_audio_stream(int samplerate, INT16 *b, int s);
/**************************************
* Type definitions
*
*************************************/
@@ -166,7 +191,7 @@ struct _ay8910_context
int index;
int streams;
int ready;
sound_stream *channel;
//sound_stream *channel;
const ay8910_interface *intf;
INT32 register_latch;
UINT8 regs[16];
@@ -216,7 +241,7 @@ static const ay_ym_param ym2149_param_env =
1397, 1123, 925, 762, 578, 438, 332, 251 },
};
#if 0
#if 1
/* RL = 1000, Hacker Kay normalized, 2.1V to 3.2V */
static const ay_ym_param ay8910_param =
{
@@ -270,6 +295,7 @@ static const ay_ym_param ay8910_param =
*
*************************************/
INLINE void build_3D_table(double rl, const ay_ym_param *par, const ay_ym_param *par_env, int normalize, double factor, int zero_is_off, INT32 *tab)
{
int j, j1, j2, j3, e, indx;
@@ -393,8 +419,7 @@ static void ay8910_write_reg(ay8910_context *psg, int r, int v)
//if (r >= 11 && r <= 13 ) printf("%d %x %02x\n", PSG->index, r, v);
psg->regs[r] = v;
switch( r )
{
switch ( r ) {
case AY_AFINE:
case AY_ACOARSE:
case AY_BFINE:
@@ -608,8 +633,8 @@ static void ay8910_update(void *param,stream_sample_t **inputs, stream_sample_t
static void build_mixer_table(ay8910_context *psg)
{
int normalize = 0;
int chan;
int normalize = 0;
int chan;
if ((psg->intf->flags & AY8910_LEGACY_OUTPUT) != 0)
{
@@ -628,7 +653,7 @@ static void build_mixer_table(ay8910_context *psg)
*/
build_3D_table(psg->intf->res_load[0], psg->par, psg->par_env, normalize, 3, psg->zero_is_off, psg->vol3d_table);
}
/*
static void ay8910_statesave(ay8910_context *psg, int sndindex)
{
state_save_register_item("AY8910", sndindex, psg->register_latch);
@@ -651,7 +676,7 @@ static void ay8910_statesave(ay8910_context *psg, int sndindex)
state_save_register_item("AY8910", sndindex, psg->holding);
state_save_register_item("AY8910", sndindex, psg->rng);
}
*/
/*************************************
*
* Public functions
@@ -664,8 +689,8 @@ void *ay8910_start_ym(sound_type chip_type, int sndindex, int clock, const ay891
{
ay8910_context *info;
info = (ay8910_context*) auto_malloc(sizeof(*info));
memset(info, 0, sizeof(*info));
info = malloc(sizeof(ay8910_context));
memset(info, 0, sizeof(ay8910_context));
info->index = sndindex;
info->intf = intf;
if ((info->intf->flags & AY8910_SINGLE_OUTPUT) != 0)
@@ -710,7 +735,7 @@ void *ay8910_start_ym(sound_type chip_type, int sndindex, int clock, const ay891
info->channel = stream_create(0,info->streams,clock / 8 ,info,ay8910_update);
ay8910_set_clock_ym(info,clock);
ay8910_statesave(info, sndindex);
//ay8910_statesave(info, sndindex);
return info;
}
@@ -754,7 +779,7 @@ void ay8910_set_volume(int chip,int channel,int volume)
void ay8910_set_clock_ym(void *chip, int clock)
{
ay8910_context *psg = chip;
stream_set_sample_rate(psg->channel, clock / 8 );
//stream_set_sample_rate(psg->channel, clock / 8 );
}
void ay8910_write_ym(void *chip, int addr, int data)
@@ -769,7 +794,7 @@ void ay8910_write_ym(void *chip, int addr, int data)
if (r == AY_ESHAPE || psg->regs[r] != data)
{
/* update the output buffer before changing the register */
stream_update(psg->channel);
//stream_update(psg->channel);
}
ay8910_write_reg(psg,r,data);
@@ -798,16 +823,16 @@ int ay8910_read_ym(void *chip)
*/
if (psg->intf->portAread)
psg->regs[AY_PORTA] = (*psg->intf->portAread)(Machine, 0);
else
logerror("PC %04x: warning - read 8910 #%d Port A\n",activecpu_get_pc(),psg->index);
//else
//logerror("PC %04x: warning - read 8910 #%d Port A\n",activecpu_get_pc(),psg->index);
break;
case AY_PORTB:
if ((psg->regs[AY_ENABLE] & 0x80) != 0)
logerror("warning: read from 8910 #%d Port B set as output\n",psg->index);
if (psg->intf->portBread)
psg->regs[AY_PORTB] = (*psg->intf->portBread)(Machine, 0);
else
logerror("PC %04x: warning - read 8910 #%d Port B\n",activecpu_get_pc(),psg->index);
//else
// logerror("PC %04x: warning - read 8910 #%d Port B\n",activecpu_get_pc(),psg->index);
break;
}
return psg->regs[r];
@@ -819,7 +844,7 @@ int ay8910_read_ym(void *chip)
*
*************************************/
static void *ay8910_start(const char *tag, int sndindex, int clock, const void *config)
void *ay8910_start(const char *tag, int sndindex, int clock, const void *config)
{
static const ay8910_interface generic_ay8910 =
{
@@ -831,7 +856,8 @@ static void *ay8910_start(const char *tag, int sndindex, int clock, const void *
return ay8910_start_ym(SOUND_AY8910, sndindex+16, clock, intf);
}
static void *ym2149_start(const char *tag, int sndindex, int clock, const void *config)
/*static void
*ym2149_start(const char *tag, int sndindex, int clock, const void *config)
{
static const ay8910_interface generic_ay8910 =
{
@@ -841,7 +867,7 @@ static void *ym2149_start(const char *tag, int sndindex, int clock, const void *
};
const ay8910_interface *intf = (config ? config : &generic_ay8910);
return ay8910_start_ym(SOUND_YM2149, sndindex+16, clock, intf);
}
}*/
static void ay8910_stop(void *chip)
{
@@ -902,19 +928,34 @@ void ay8912_get_info(void *token, UINT32 state, sndinfo *info)
{
switch (state)
{
case SNDINFO_PTR_START: info->start = ay8910_start; break;
case SNDINFO_STR_NAME: info->s = "AY-3-8912A"; break;
default: ay8910_get_info(token, state, info); break;
case SNDINFO_PTR_START:
info->start = ay8910_start;
break;
case SNDINFO_STR_NAME:
info->s = "AY-3-8912A";
break;
default:
ay8910_get_info(token, state, info);
break;
}
}
void ay8913_get_info(void *token, UINT32 state, sndinfo *info)
{
switch (state)
{
case SNDINFO_PTR_START: info->start = ay8910_start; break;
case SNDINFO_STR_NAME: info->s = "AY-3-8913A"; break;
default: ay8910_get_info(token, state, info); break;
switch (state) {
case SNDINFO_PTR_START:
info->start = ay8910_start;
break;
case SNDINFO_STR_NAME:
info->s = "AY-3-8913A";
break;
default:
ay8910_get_info(token, state, info);
break;
}
}
/*
@@ -954,26 +995,29 @@ void ymz284_get_info(void *token, UINT32 state, sndinfo *info)
{
case SNDINFO_PTR_START: info->start = ym2149_start; break;
case SNDINFO_STR_NAME: info->s = "YMZ284"; break;
default: ay8910_get_info(token, state, info); break;
default:
ay8910_get_info(token, state, info);
break;
}
}
void ymz294_get_info(void *token, UINT32 state, sndinfo *info)
{
switch (state)
{
case SNDINFO_PTR_START: info->start = ym2149_start; break;
case SNDINFO_STR_NAME: info->s = "YMZ294"; break;
default: ay8910_get_info(token, state, info); break;
switch (state) {
case SNDINFO_PTR_START:
info->start = ym2149_start;
break;
case SNDINFO_STR_NAME:
info->s = "YMZ294";
break;
default:
ay8910_get_info(token, state, info);
break;
}
}
*/
int
main(int argc, char* argv[])
{
printf("ay8910test.\n");
return 0;
}
/*************************************
*
@@ -1002,9 +1046,25 @@ WRITE8_HANDLER( ay8910_control_port_1_w ) { ay8910_write_ym(sndti_token(SOUND_AY
WRITE8_HANDLER( ay8910_control_port_2_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 2),0,data); }
WRITE8_HANDLER( ay8910_control_port_3_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 3),0,data); }
WRITE8_HANDLER( ay8910_control_port_4_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 4),0,data); }
WRITE16_HANDLER( ay8910_control_port_0_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 0),0,data & 0xff); }
WRITE16_HANDLER( ay8910_control_port_1_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 1),0,data & 0xff); }
WRITE16_HANDLER( ay8910_control_port_2_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 2),0,data & 0xff); }
WRITE16_HANDLER( ay8910_control_port_0_lsb_w )
{
if (ACCESSING_BITS_0_7)
ay8910_write_ym(sndti_token(SOUND_AY8910, 0),0,data & 0xff);
}
WRITE16_HANDLER( ay8910_control_port_1_lsb_w )
{
if (ACCESSING_BITS_0_7)
ay8910_write_ym(sndti_token(SOUND_AY8910, 1),0,data & 0xff);
}
WRITE16_HANDLER( ay8910_control_port_2_lsb_w )
{
if (ACCESSING_BITS_0_7)
ay8910_write_ym(sndti_token(SOUND_AY8910, 2),0,data & 0xff);
}
WRITE16_HANDLER( ay8910_control_port_3_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 3),0,data & 0xff); }
WRITE16_HANDLER( ay8910_control_port_4_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 4),0,data & 0xff); }
WRITE16_HANDLER( ay8910_control_port_0_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 0),0,data >> 8); }
@@ -1028,3 +1088,29 @@ WRITE16_HANDLER( ay8910_write_port_1_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_w
WRITE16_HANDLER( ay8910_write_port_2_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 2),1,data >> 8); }
WRITE16_HANDLER( ay8910_write_port_3_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 3),1,data >> 8); }
WRITE16_HANDLER( ay8910_write_port_4_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 4),1,data >> 8); }
int
main(int argc, char* argv[])
{
//running_machine *machine;
INT16 sounddata[100];
int i=0, sndindex=1, clock=500000;
ay8910_context *info;
const ay8910_interface ay8910_inf;
int sample_rate = 11025;
printf("ay8910test.\n");
for (i=0; i<100; ++i)
sounddata[i] = 32000 + 100 * i;
//machine = malloc(sizeof(running_machine));
sdlaudio_init(sample_rate);
info = ay8910_start(NULL, sndindex, clock, &ay8910_inf);
while (1)
osd_update_audio_stream(sample_rate,sounddata,100);
sdl_kill();
//free(machine);
return 0;
}
+3 -2
View File
@@ -2,8 +2,8 @@
#define __AY8910_H__
//#include "osdcomm.h"
#include "mamecore.h"
#include "memory.h"
//#include "mamecore.h"
//#include "memory.h"
//typedef UINT32 offs_t;
//typedef UINT8 (*read8_machine_func) (ATTR_UNUSED running_machine *machine, ATTR_UNUSED offs_t offset);
@@ -142,6 +142,7 @@ WRITE16_HANDLER( ay8910_write_port_4_msb_w );
/*********** An interface for SSG of YM2203 ***********/
void *ay8910_start_ym(sound_type chip_type, int sndindex, int clock, const ay8910_interface *intf);
void *ay8910_s(void *chip);
void ay8910_stop_ym(void *chip);
void ay8910_reset_ym(void *chip);
+1 -1
View File
@@ -10,7 +10,7 @@
***************************************************************************/
#pragma once
#pragma once
#ifndef __DEPRECAT_H__
#define __DEPRECAT_H__
+11
View File
@@ -56,6 +56,17 @@ typedef UINT64 FPTR;
typedef UINT32 FPTR;
#endif
struct _running_machine
{
/* audio-related information */
int sample_rate; /* the digital audio sample rate */
/* debugger-related information */
UINT32 debug_flags; /* the current debug flags */
void * driver_data; /* drivers can hang data off of here instead of using globals */
};
/* These are forward struct declarations that are used to break
circular dependencies in the code */
+2 -2
View File
@@ -14,12 +14,12 @@
#ifndef __MEMORY_H__
#define __MEMORY_H__
/*
#include "mamecore.h"
#include "devintrf.h"
#include "tokenize.h"
#include "osdcomm.h"
*/
/***************************************************************************
CONSTANTS
***************************************************************************/
+2 -1
View File
@@ -150,7 +150,8 @@ typedef enum _sound_type sound_type;
/* Sound information constants */
enum
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
/* --- the following bits of info are returned as 64-bit signed
* integers --- */
SNDINFO_INT_FIRST = 0x00000,
SNDINFO_INT_ALIAS = SNDINFO_INT_FIRST, /* R/O: alias to sound type for (type,index) identification */
+6 -4
View File
@@ -12,15 +12,16 @@
#ifndef STREAMS_H
#define STREAMS_H
#include "attotime.h"
#include "osdcomm.h"
#include "deprecat.h"
#include "mamecore.h"
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
typedef struct _sound_stream sound_stream;
#if 0
typedef void (*stream_update_func)(void *param, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
@@ -36,6 +37,7 @@ typedef void (*stream_update_func)(void *param, stream_sample_t **inputs, stream
/* initialize the streams engine */
void streams_init(running_machine *machine, attoseconds_t update_subseconds);
#endif
/* set the tag to be associated with all streams allocated from now on */
void streams_set_tag(running_machine *machine, void *streamtag);