📄 pokey.c
字号:
/* then compare to the poly4 bit */
toggle = poly4[P4] == !Outbit[next_event];
} else {
/* if 9-bit poly is selected on this chip */
if (audctl & POLY9) {
/* compare to the poly9 bit */
toggle = poly9[P9] == !Outbit[next_event];
} else {
/* otherwise compare to the poly17 bit 0 */
toggle = poly17[P17] == !Outbit[next_event];
}
}
}
/* check channel 1 filter (clocked by channel 3) */
if (audctl & CH1_FILTER) {
/* if we're processing channel 3 */
if ((next_event & 3) == CHAN3) {
/* check output of channel 1 on same chip */
if (Outbit[next_event-2]) {
/* if on, turn it off */
Outbit[next_event-2] = 0;
cur_val -= AUDV[next_event & ~2];
}
}
}
/* check channel 2 filter (clocked by channel 4) */
if (audctl & CH2_FILTER) {
/* if we're processing channel 4 */
if ((next_event & 3) == CHAN4) {
/* check output of channel 2 on same chip */
if (Outbit[next_event-2]) {
/* if on, turn it off */
Outbit[next_event-2] = 0;
cur_val -= AUDV[next_event & ~2];
}
}
}
/* if the current output bit has changed */
if (toggle) {
if (Outbit[next_event]) {
/* remove this channel from the signal */
cur_val -= AUDV[next_event];
/* and turn the output off */
Outbit[next_event] = 0;
} else {
/* turn the output on */
Outbit[next_event] = 1;
/* and add it to the output signal */
cur_val += AUDV[next_event];
}
}
} else {
/* otherwise we're processing a sample.
adjust the sample counter - note we're using the
24.8 integer includes an 8 bit fraction for accuracy */
Samp_n_cnt[1] += Samp_n_max;
if ( Samp_n_cnt[1] & 0xffffff00 )
{
Samp_n_cnt[0] += (Samp_n_cnt[1]>>8);
Samp_n_cnt[1] &= 0x000000ff;
}
#ifdef CLIP /* if clipping is selected */
if (clip)
{
if (cur_val > 127) *buf_ptr++ = 127;
else if (cur_val < -128) *buf_ptr++ = -128;
else *buf_ptr++ = (INT8)cur_val;
}
else *buf_ptr++ = (INT8)cur_val;
#else
*buf_ptr++ = (INT8)cur_val; /* clipping not selected, use value */
#endif
/* and indicate one less byte in the buffer */
n--;
}
}
}
int pokey_sh_start (struct POKEYinterface *interface)
{
int res;
intf = interface;
res = Pokey_sound_init (intf->baseclock, Machine->sample_rate, intf->volume, intf->num, intf->clip);
return res;
}
void pokey_sh_stop (void)
{
if (rand17) free (rand17);
rand17 = NULL;
if (poly17) free (poly17);
poly17 = NULL;
}
static void update_pokeys(void)
{
int chip;
for (chip = 0; chip < Num_pokeys; chip++)
stream_update(channel[chip], 0);
}
/*****************************************************************************/
/* Module: Read_pokey_regs() */
/* Purpose: To return the values of the Pokey registers. Currently, only the */
/* random number generator register is returned. */
/* */
/* Author: Keith Gerdes, Brad Oliver & Eric Smith */
/* Date: August 8, 1997 */
/* */
/* Inputs: addr - the address of the parameter to be changed */
/* chip - the pokey chip to read */
/* */
/* Outputs: Adjusts local globals, returns the register in question */
/* */
/*****************************************************************************/
int Read_pokey_regs (int addr, int chip)
{
int data = 0; /* note: not returning 0 for unsupported ports breaks */
/* Quantum and Food Fight */
switch (addr & 0x0f)
{
case POT0_C:
if (intf->pot0_r[chip]) data = (*intf->pot0_r[chip])(addr);
break;
case POT1_C:
if (intf->pot1_r[chip]) data = (*intf->pot1_r[chip])(addr);
break;
case POT2_C:
if (intf->pot2_r[chip]) data = (*intf->pot2_r[chip])(addr);
break;
case POT3_C:
if (intf->pot3_r[chip]) data = (*intf->pot3_r[chip])(addr);
break;
case POT4_C:
if (intf->pot4_r[chip]) data = (*intf->pot4_r[chip])(addr);
break;
case POT5_C:
if (intf->pot5_r[chip]) data = (*intf->pot5_r[chip])(addr);
break;
case POT6_C:
if (intf->pot6_r[chip]) data = (*intf->pot6_r[chip])(addr);
break;
case POT7_C:
if (intf->pot7_r[chip]) data = (*intf->pot7_r[chip])(addr);
break;
case ALLPOT_C:
if (intf->allpot_r[chip]) data = (*intf->allpot_r[chip])(addr);
break;
case KBCODE_C:
/* clear keyboard status bit */
data = KBCODE[chip];
break;
case RANDOM_C:
{
/****************************************************************
* If the 2 least significant bits of SKCTL are 0, the random
* number generator is disabled (SKRESET). Thanks to Eric Smith
* for pointing out this critical bit of info! If the random
* number generator is enabled, get a new random number. Take
* the time gone since the last read into account and read the
* new value from an appropriate offset in the rand17 table.
****************************************************************/
/* save the absolute time of this read */
if (SKCTL[chip] & SK_RESET)
{
UINT32 rngoffs = (UINT32)(timer_get_time() * intf->baseclock) % POLY17_SIZE;
/* and get the random value */
RANDOM[chip] = rand17[rngoffs];
}
}
data = RANDOM[chip];
break;
case SERIN_C:
if (intf->serin_r[chip]) SERIN[chip] = (*intf->serin_r[chip])(addr);
data = SERIN[chip];
break;
case IRQST_C:
/* IRQST is an active low input port; we keep it active high */
/* internally to ease the (un-)masking of bits */
data = IRQST[chip] ^ 0xff;
break;
case SKSTAT_C:
/* SKSTAT is an active low input port also */
data = SKSTAT[chip] ^ 0xff;
break;
default:
break;
}
return data;
}
int pokey1_r (int offset)
{
return Read_pokey_regs (offset,0);
}
int pokey2_r (int offset)
{
return Read_pokey_regs (offset,1);
}
int pokey3_r (int offset)
{
return Read_pokey_regs (offset,2);
}
int pokey4_r (int offset)
{
return Read_pokey_regs (offset,3);
}
int quad_pokey_r (int offset)
{
int pokey_num = (offset >> 3) & ~0x04;
int control = (offset & 0x20) >> 2;
int pokey_reg = (offset % 8) | control;
return Read_pokey_regs (pokey_reg,pokey_num);
}
void pokey1_w (int offset,int data)
{
update_pokeys ();
Update_pokey_sound (offset,data,0,intf->gain);
}
void pokey2_w (int offset,int data)
{
update_pokeys ();
Update_pokey_sound (offset,data,1,intf->gain);
}
void pokey3_w (int offset,int data)
{
update_pokeys ();
Update_pokey_sound (offset,data,2,intf->gain);
}
void pokey4_w (int offset,int data)
{
update_pokeys ();
Update_pokey_sound (offset,data,3,intf->gain);
}
void quad_pokey_w (int offset,int data)
{
int pokey_num = (offset >> 3) & ~0x04;
int control = (offset & 0x20) >> 2;
int pokey_reg = (offset % 8) | control;
switch (pokey_num) {
case 0:
pokey1_w (pokey_reg, data);
break;
case 1:
pokey2_w (pokey_reg, data);
break;
case 2:
pokey3_w (pokey_reg, data);
break;
case 3:
pokey4_w (pokey_reg, data);
break;
}
}
void pokey1_serin_ready(int after)
{
timer_set(1.0 * after / intf->baseclock, 0, Pokey_SerinReady);
}
void pokey2_serin_ready(int after)
{
timer_set(1.0 * after / intf->baseclock, 1, Pokey_SerinReady);
}
void pokey3_serin_ready(int after)
{
timer_set(1.0 * after / intf->baseclock, 2, Pokey_SerinReady);
}
void pokey4_serin_ready(int after)
{
timer_set(1.0 * after / intf->baseclock, 3, Pokey_SerinReady);
}
void pokey_break_w(int chip, int shift)
{
if (shift) /* shift code ? */
SKSTAT[chip] |= SK_SHIFT;
else
SKSTAT[chip] &= ~SK_SHIFT;
/* check if the break IRQ is enabled */
if (IRQEN[chip] & IRQ_BREAK) {
/* set break IRQ status and call back the interrupt handler */
IRQST[chip] |= IRQ_BREAK;
if (intf->interrupt_cb[chip])
(*intf->interrupt_cb[chip])(IRQ_BREAK);
}
}
void pokey1_break_w(int shift)
{
pokey_break_w(0, shift);
}
void pokey2_break_w(int shift)
{
pokey_break_w(1, shift);
}
void pokey3_break_w(int shift)
{
pokey_break_w(2, shift);
}
void pokey4_break_w(int shift)
{
pokey_break_w(3, shift);
}
void pokey_kbcode_w(int chip, int kbcode, int make)
{
/* make code ? */
if (make) {
KBCODE[chip] = kbcode;
SKSTAT[chip] |= SK_KEYBD;
if (kbcode & 0x40) /* shift code ? */
SKSTAT[chip] |= SK_SHIFT;
else
SKSTAT[chip] &= ~SK_SHIFT;
if (IRQEN[chip] & IRQ_KEYBD) {
/* last interrupt not acknowledged ? */
if (IRQST[chip] & IRQ_KEYBD)
SKSTAT[chip] |= SK_KBERR;
IRQST[chip] |= IRQ_KEYBD;
if (intf->interrupt_cb[chip])
(*intf->interrupt_cb[chip])(IRQ_KEYBD);
}
} else {
KBCODE[chip] = kbcode;
SKSTAT[chip] &= ~SK_KEYBD;
}
}
void pokey1_kbcode_w(int kbcode, int make)
{
pokey_kbcode_w(0, kbcode, make);
}
void pokey2_kbcode_w(int kbcode, int make)
{
pokey_kbcode_w(1, kbcode, make);
}
void pokey3_kbcode_w(int kbcode, int make)
{
pokey_kbcode_w(2, kbcode, make);
}
void pokey4_kbcode_w(int kbcode, int make)
{
pokey_kbcode_w(3, kbcode, make);
}
void pokey_sh_update (void)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -