ref: 23fe5dd09ffe2e3c2d925945bc1adcbf6fc6fc97
parent: 6dc689653c52eb5db90d3adf00f0d1ab2caacc0e
author: Jean-André Santoni <jean.andre.santoni@gmail.com>
date: Thu Mar 12 10:02:10 EDT 2026
Improve psg
--- a/psg.c
+++ b/psg.c
@@ -8,7 +8,6 @@
static int fd;
static short sbuf[2 * 2000], *sbufp;
-static const u8int noise_table[3] = { 0x10, 0x20, 0x40 }; static const short vol_table[16] = {8191, 6507, 5168, 4105, 3261, 2590, 2057,
1642, 1298, 1031, 819, 650, 516, 410, 326, 0
@@ -21,9 +20,25 @@
static u8int attn[4];
static int flipflop[4];
static u16int noise;
+static int noiseflip;
+static int noiseout;
static u8int curr_reg;
static u8int curr_type;
+static void
+psgreset(void)
+{+ memset(freqreg, 0, sizeof freqreg);
+ memset(countreg, 0, sizeof countreg);
+ memset(flipflop, 0, sizeof flipflop);
+ memset(attn, 0x0f, sizeof attn);
+ noise = 0x8000;
+ noiseflip = 0;
+ noiseout = 0;
+ curr_reg = 0;
+ curr_type = 0;
+}
+
void
psgwrite(const u8int data)
{@@ -37,14 +52,15 @@
if(curr_type){attn[curr_reg] = data & 0x0F;
- }else if(first && curr_reg == 3){+ }else if(curr_reg == 3){freqreg[3] = data & 7;
noise = 0x8000;
- }
- else if(first)
+ noiseflip = 0;
+ noiseout = 0;
+ }else if(first)
freqreg[curr_reg] = (freqreg[curr_reg] & 0x3F0) | (data & 0x0F);
else
- countreg[curr_reg] = freqreg[curr_reg] = (freqreg[curr_reg] & 0x0F) | ((data & 0x3F) << 4);
+ freqreg[curr_reg] = (freqreg[curr_reg] & 0x0F) | ((data & 0x3F) << 4);
}
static inline u16int
@@ -61,30 +77,45 @@
static inline s16int
vol(u8int chn)
{- return (flipflop[chn] ? 1 : -1) * vol_table[attn[chn]];
+ int on;
+
+ on = chn == 3 ? noiseout : flipflop[chn];
+ return (on ? 1 : -1) * vol_table[attn[chn]];
}
-u16int
-psgstep(void)
+static inline void
+toneclock(u8int chn)
{- while(cyc > 0){- for(u8int i = 0; i < 4; i++){- countreg[i]--;
- if(!countreg[i]){- if(i < 3){- countreg[i] = freqreg[i];
- flipflop[i] = !flipflop[i];
- }else{- u8int nf = freqreg[3] & 3;
- u8int fb = (freqreg[3] >> 2) & 1;
- countreg[3] = nf == 3 ? freqreg[2] : (0x10 << nf);
+ if(countreg[chn] == 0 || --countreg[chn] == 0){+ countreg[chn] = freqreg[chn];
+ flipflop[chn] ^= 1;
+ }
+}
- noise = (noise >> 1) | ((fb ? parity(noise & 0x9) : noise & 1) << 15);
- flipflop[3] = (noise & 1);
- }
- }
+static inline void
+noiseclock(void)
+{+ u8int nf, fb;
+
+ nf = freqreg[3] & 3;
+ fb = (freqreg[3] >> 2) & 1;
+ if(countreg[3] == 0 || --countreg[3] == 0){+ countreg[3] = nf == 3 ? freqreg[2] : (0x10 << nf);
+ if((noiseflip ^= 1) != 0){+ noiseout = noise & 1;
+ noise = (noise >> 1) | ((fb ? parity(noise & 0x9) : noise & 1) << 15);
}
+ }
+}
+u16int
+psgstep(void)
+{+ while(cyc > 0){+ toneclock(0);
+ toneclock(1);
+ toneclock(2);
+ noiseclock();
cyc--;
}
@@ -130,6 +161,7 @@
{cyclespersample = (double)clockspd / (double)PSGDIV/ (double)rate;
cyc = cyclespersample;
+ psgreset();
fd = open("/dev/audio", OWRITE);if(fd < 0)
--
⑨