mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
Pico PCM, only one hardcoded mode for now
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@444 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
1e6b5e39f4
commit
ef4eb506de
7 changed files with 151 additions and 12 deletions
|
@ -71,14 +71,18 @@ extern int (*PicoMCDcloseTray)(void);
|
||||||
extern int PicoCDBuffers;
|
extern int PicoCDBuffers;
|
||||||
|
|
||||||
// Pico/Pico.c
|
// Pico/Pico.c
|
||||||
|
#define XPCM_BUFFER_SIZE (320+32)
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int pen_pos[2];
|
int pen_pos[2];
|
||||||
int page;
|
int page;
|
||||||
// internal
|
// internal
|
||||||
int fifo_bytes;
|
int fifo_bytes; // free bytes in FIFO
|
||||||
|
int fifo_line_bytes; // float part, << 16
|
||||||
int line_counter;
|
int line_counter;
|
||||||
unsigned int r1, r12;
|
unsigned short r1, r12;
|
||||||
|
unsigned char xpcm_buffer[XPCM_BUFFER_SIZE+4];
|
||||||
|
unsigned char *xpcm_ptr;
|
||||||
} picohw_state;
|
} picohw_state;
|
||||||
extern picohw_state PicoPicohw;
|
extern picohw_state PicoPicohw;
|
||||||
|
|
||||||
|
|
|
@ -143,8 +143,20 @@ static void PicoWritePico16(u32 a,u16 d)
|
||||||
if ((a&0xfffff0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP
|
if ((a&0xfffff0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP
|
||||||
|
|
||||||
// if (a == 0x800010) dump(d);
|
// if (a == 0x800010) dump(d);
|
||||||
if (a == 0x800010) PicoPicohw.fifo_bytes += 2;
|
if (a == 0x800010)
|
||||||
if (a == 0x800012) PicoPicohw.r12 = d;
|
{
|
||||||
|
PicoPicohw.fifo_bytes += 2;
|
||||||
|
|
||||||
|
if (PicoPicohw.xpcm_ptr < PicoPicohw.xpcm_buffer + XPCM_BUFFER_SIZE) {
|
||||||
|
*PicoPicohw.xpcm_ptr++ = d >> 8;
|
||||||
|
*PicoPicohw.xpcm_ptr++ = d;
|
||||||
|
}
|
||||||
|
else if (PicoPicohw.xpcm_ptr == PicoPicohw.xpcm_buffer + XPCM_BUFFER_SIZE) {
|
||||||
|
elprintf(EL_ANOMALY, "xpcm_buffer overflow!");
|
||||||
|
PicoPicohw.xpcm_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (a == 0x800012) PicoPicohw.r12 = d;
|
||||||
|
|
||||||
elprintf(EL_UIO, "w16: %06x, %04x", a&0xffffff, d);
|
elprintf(EL_UIO, "w16: %06x, %04x", a&0xffffff, d);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,9 @@
|
||||||
picohw_state PicoPicohw;
|
picohw_state PicoPicohw;
|
||||||
|
|
||||||
static int prev_line_cnt_irq3 = 0, prev_line_cnt_irq5 = 0;
|
static int prev_line_cnt_irq3 = 0, prev_line_cnt_irq5 = 0;
|
||||||
|
static int fifo_bytes_line = (16000<<16)/60/262/2; // fifo bytes/line. FIXME: other rates, modes
|
||||||
|
|
||||||
static void PicoLineHookPico(int count)
|
static void PicoLinePico(int count)
|
||||||
{
|
{
|
||||||
PicoPicohw.line_counter += count;
|
PicoPicohw.line_counter += count;
|
||||||
|
|
||||||
|
@ -29,11 +30,18 @@ static void PicoLineHookPico(int count)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((PicoPicohw.line_counter & 3) == 0 || count > 10)
|
|
||||||
{
|
|
||||||
if (PicoPicohw.fifo_bytes > 0)
|
if (PicoPicohw.fifo_bytes > 0)
|
||||||
PicoPicohw.fifo_bytes--;
|
{
|
||||||
|
PicoPicohw.fifo_line_bytes += fifo_bytes_line * count;
|
||||||
|
if (PicoPicohw.fifo_line_bytes >= (1<<16)) {
|
||||||
|
PicoPicohw.fifo_bytes -= PicoPicohw.fifo_line_bytes >> 16;
|
||||||
|
PicoPicohw.fifo_line_bytes &= 0xffff;
|
||||||
|
if (PicoPicohw.fifo_bytes < 0)
|
||||||
|
PicoPicohw.fifo_bytes = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
PicoPicohw.fifo_line_bytes = 0;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (PicoPicohw.line_counter - prev_line_cnt_irq5 > 512) {
|
if (PicoPicohw.line_counter - prev_line_cnt_irq5 > 512) {
|
||||||
|
@ -44,20 +52,26 @@ static void PicoLineHookPico(int count)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void PicoResetPico(void)
|
||||||
|
{
|
||||||
|
PicoPicoPCMReset();
|
||||||
|
PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
PICO_INTERNAL int PicoInitPico(void)
|
PICO_INTERNAL int PicoInitPico(void)
|
||||||
{
|
{
|
||||||
elprintf(EL_STATUS, "Pico detected");
|
elprintf(EL_STATUS, "Pico detected");
|
||||||
PicoLineHook = PicoLineHookPico;
|
PicoLineHook = PicoLinePico;
|
||||||
|
PicoResetHook = PicoResetPico;
|
||||||
|
|
||||||
PicoAHW = PAHW_PICO;
|
PicoAHW = PAHW_PICO;
|
||||||
memset(&PicoPicohw, 0, sizeof(PicoPicohw));
|
memset(&PicoPicohw, 0, sizeof(PicoPicohw));
|
||||||
PicoPicohw.pen_pos[0] = 0x03c + 352/2;
|
PicoPicohw.pen_pos[0] = 0x03c + 352/2;
|
||||||
PicoPicohw.pen_pos[1] = 0x200 + 252/2;
|
PicoPicohw.pen_pos[1] = 0x200 + 252/2;
|
||||||
prev_line_cnt_irq3 = 0, prev_line_cnt_irq5 = 0;
|
prev_line_cnt_irq3 = prev_line_cnt_irq5 = 0;
|
||||||
|
|
||||||
// map version register
|
// map version register
|
||||||
PicoDetectRegion();
|
PicoDetectRegion();
|
||||||
elprintf(EL_STATUS, "a %x", Pico.m.hardware);
|
|
||||||
switch (Pico.m.hardware >> 6) {
|
switch (Pico.m.hardware >> 6) {
|
||||||
case 0: PicoPicohw.r1 = 0x00; break;
|
case 0: PicoPicohw.r1 = 0x00; break;
|
||||||
case 1: PicoPicohw.r1 = 0x00; break;
|
case 1: PicoPicohw.r1 = 0x00; break;
|
||||||
|
|
100
Pico/Pico/xpcm.c
Normal file
100
Pico/Pico/xpcm.c
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* The following ADPCM algorithm was stolen from MAME aica driver.
|
||||||
|
* I'm quite sure it's not the right one, but it's the
|
||||||
|
* best sounding of the ones that I tried.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../PicoInt.h"
|
||||||
|
|
||||||
|
#define ADPCMSHIFT 8
|
||||||
|
#define ADFIX(f) (int) ((double)f * (double)(1<<ADPCMSHIFT))
|
||||||
|
|
||||||
|
/* limitter */
|
||||||
|
#define Limit(val, max, min) { \
|
||||||
|
if ( val > max ) val = max; \
|
||||||
|
else if ( val < min ) val = min; \
|
||||||
|
}
|
||||||
|
|
||||||
|
const int TableQuant[8] =
|
||||||
|
{
|
||||||
|
ADFIX(0.8984375),
|
||||||
|
ADFIX(0.8984375),
|
||||||
|
ADFIX(0.8984375),
|
||||||
|
ADFIX(0.8984375),
|
||||||
|
ADFIX(1.19921875),
|
||||||
|
ADFIX(1.59765625),
|
||||||
|
ADFIX(2.0),
|
||||||
|
ADFIX(2.3984375)
|
||||||
|
};
|
||||||
|
|
||||||
|
// changed using trial and error..
|
||||||
|
//const int quant_mul[16] = { 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15 };
|
||||||
|
const int quant_mul[16] = { 1, 3, 5, 7, 9, 11, 13, -1, -1, -3, -5, -7, -9, -11, -13, -15 };
|
||||||
|
|
||||||
|
static int sample = 0, quant = 0;
|
||||||
|
|
||||||
|
PICO_INTERNAL void PicoPicoPCMReset(void)
|
||||||
|
{
|
||||||
|
sample = 0;
|
||||||
|
quant = 0x7f;
|
||||||
|
memset(PicoPicohw.xpcm_buffer, 0, sizeof(PicoPicohw.xpcm_buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define XSHIFT 7
|
||||||
|
|
||||||
|
#define do_sample() \
|
||||||
|
{ \
|
||||||
|
sample += quant * quant_mul[srcval] >> XSHIFT; \
|
||||||
|
quant = (quant * TableQuant[srcval&7]) >> ADPCMSHIFT; \
|
||||||
|
Limit(quant, 0x6000, 0x7f); \
|
||||||
|
Limit(sample, 32767, -32768); \
|
||||||
|
}
|
||||||
|
|
||||||
|
PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo)
|
||||||
|
{
|
||||||
|
unsigned char *src = PicoPicohw.xpcm_buffer;
|
||||||
|
unsigned char *lim = PicoPicohw.xpcm_ptr;
|
||||||
|
int srcval, stepsamples = (44100<<10)/16000, needsamples = 0; // TODO: stepsamples
|
||||||
|
|
||||||
|
if (src == lim)
|
||||||
|
{
|
||||||
|
if (stereo)
|
||||||
|
// still must expand SN76496 to stereo
|
||||||
|
for (; length > 0; buffer+=2, length--)
|
||||||
|
buffer[1] = buffer[0];
|
||||||
|
sample = quant = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; length > 0 && src < lim; src++)
|
||||||
|
{
|
||||||
|
srcval = *src >> 4;
|
||||||
|
do_sample();
|
||||||
|
|
||||||
|
for (needsamples += stepsamples; needsamples > (1<<10) && length > 0; needsamples -= (1<<10), length--) {
|
||||||
|
*buffer++ = sample;
|
||||||
|
if (stereo) { buffer[0] = buffer[-1]; buffer++; }
|
||||||
|
}
|
||||||
|
|
||||||
|
srcval = *src & 0xf;
|
||||||
|
do_sample();
|
||||||
|
|
||||||
|
for (needsamples += stepsamples; needsamples > (1<<10) && length > 0; needsamples -= (1<<10), length--) {
|
||||||
|
*buffer++ = sample;
|
||||||
|
if (stereo) { buffer[0] = buffer[-1]; buffer++; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src < lim) {
|
||||||
|
int di = lim - src;
|
||||||
|
memmove(PicoPicohw.xpcm_buffer, src, di);
|
||||||
|
PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer + di;
|
||||||
|
elprintf(EL_STATUS, "xpcm update: over %i", di);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elprintf(EL_STATUS, "xpcm update: under %i", length);
|
||||||
|
PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -444,6 +444,10 @@ PICO_INTERNAL int PicoFrameMCD(void);
|
||||||
// Pico/Pico.c
|
// Pico/Pico.c
|
||||||
PICO_INTERNAL int PicoInitPico(void);
|
PICO_INTERNAL int PicoInitPico(void);
|
||||||
|
|
||||||
|
// Pico/xpcm.c
|
||||||
|
PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo);
|
||||||
|
PICO_INTERNAL void PicoPicoPCMReset(void);
|
||||||
|
|
||||||
// Sek.c
|
// Sek.c
|
||||||
PICO_INTERNAL int SekInit(void);
|
PICO_INTERNAL int SekInit(void);
|
||||||
PICO_INTERNAL int SekReset(void);
|
PICO_INTERNAL int SekReset(void);
|
||||||
|
|
|
@ -326,6 +326,11 @@ PICO_INTERNAL int PsndRender(int offset, int length)
|
||||||
if (PicoOpt & POPT_EN_PSG)
|
if (PicoOpt & POPT_EN_PSG)
|
||||||
SN76496Update(PsndOut+offset, length, stereo);
|
SN76496Update(PsndOut+offset, length, stereo);
|
||||||
|
|
||||||
|
if (PicoAHW & PAHW_PICO) {
|
||||||
|
PicoPicoPCMUpdate(PsndOut+offset, length, stereo);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
// Add in the stereo FM buffer
|
// Add in the stereo FM buffer
|
||||||
if (PicoOpt & POPT_EN_FM) {
|
if (PicoOpt & POPT_EN_FM) {
|
||||||
buf32_updated = YM2612UpdateOne(buf32, length, stereo, 1);
|
buf32_updated = YM2612UpdateOne(buf32, length, stereo, 1);
|
||||||
|
|
|
@ -42,7 +42,7 @@ OBJS += Pico/cd/Pico.o Pico/cd/Memory.o Pico/cd/Sek.o Pico/cd/LC89510.o \
|
||||||
Pico/cd/cd_sys.o Pico/cd/cd_file.o Pico/cd/cue.o Pico/cd/gfx_cd.o \
|
Pico/cd/cd_sys.o Pico/cd/cd_file.o Pico/cd/cue.o Pico/cd/gfx_cd.o \
|
||||||
Pico/cd/Area.o Pico/cd/Misc.o Pico/cd/pcm.o Pico/cd/buffering.o
|
Pico/cd/Area.o Pico/cd/Misc.o Pico/cd/pcm.o Pico/cd/buffering.o
|
||||||
# Pico - Pico
|
# Pico - Pico
|
||||||
OBJS += Pico/Pico/Pico.o Pico/Pico/Memory.o
|
OBJS += Pico/Pico/Pico.o Pico/Pico/Memory.o Pico/Pico/xpcm.o
|
||||||
# Pico - sound
|
# Pico - sound
|
||||||
OBJS += Pico/sound/sound.o Pico/sound/sn76496.o Pico/sound/ym2612.o Pico/sound/mix.o
|
OBJS += Pico/sound/sound.o Pico/sound/sn76496.o Pico/sound/ym2612.o Pico/sound/mix.o
|
||||||
# Pico - carthw
|
# Pico - carthw
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue