Trash80toHP_Mini
NIGHT STALKER
I love this thread, great job, fascinating from a technical perspective and entertaining as well. :approve:
So for a fact, they're saying the EASC doesn't support the four-voice mode that's used to generate the II-series startup chime/death chime. No big surprise there. The hardware sample rate conversion is interesting, and this also confirms the real-time hardware decompression capability Back to the 475, I'm starting to think they lied about the 475 actually having the EASC. My educated guess is they took only the subset of it that the Mac OS used and crammed it into a bigger chip with other stuff like floppy control and the VIA registers. I could be totally wrong though...Although the ASC has been enhanced, it remains plug compatible with the older ASC. The enhanced ASC no longer supports four voice synthesis (mono) or two-voice synthesis (stereo), but it does support the following features:
- record mode for sound input (together with the DFAC)
- hardware sample rate conversion
- real-time hardware decompression
- 8-bit final amplitude scaling registers
- 16-bit digital serial output
- 10-bit PWM (pulse-width-modulated) signal resolution at 44.1 kHz sample rate
I can verify that the PowerBook 140 ROM is identical to the Q700 ROM. I dumped mine a while ago. Unfortunately, the computer itself has since died and fallen to pieces, so I can't test it on the actual hardware.This page seems to indicate that the Quadra 700, Quadra 900, PowerBook 140, PowerBook 145B, and PowerBook 170 all have the same ROM checksum (and thus, likely, the same ROM). Maybe those models are the only ones with the required ASC support? I would be VERY curious to see (err...hear) if it worked on one of those PowerBooks.
Wait a minute - Steve Jobs was long gone when they built the Quadra 700.Wouldn't it have been awesome to work at Apple back then and know what all of these code words and inside jokes meant?? Well maybe not under Steve Jobs' reign of terror!
76543210
||||\\\\__ "range" setting
||\\______ "filter" setting
\\________ unknown, unused here? (in cd-xa format one of these bits means LOOP and the other one means END I think? They're irrelevant for a fifo streamed format. It is possible that the lower of the 2 bits will select the fifth filter (filter #4) if set...)
/* Apple(/Sony?) EASC BRR sample decoder, by Jonathan Gevaryahu AKA Lord Nightmare
* Using a bunch of code from psxAuthor's playstation emulator,
* which had been integrated with mame, in git.redump.net/mame/tree/src/emu/sound/spu.c around line 2851
* and a few lines from Dennis Nedry's decoder from 68kmla forums.
* The BRR sample format used here seems to be similar but not exactly the same as the
* format used on the SNES and PSX and CD-I etc;
* There is one format byte with the MODE and RANGE in it, but 14 packed-nybble sample bytes instead of 8
* The filters sound distorted unless they are in the order they are currently in, verified via testing.
*/
#include
// globals
int xa_last[2] = { 0, 0 };
// filter coefficents are in 1/64ths
static const int filter_coef[5][2]=
{
{ 0,0 },
{ 60,0 },
{ 115,-52 },
{ 98,-55 },
{ 122,-60 },
};
static inline int clamp(const int v)
{
if (v<-32768) return -32768;
if (v>32767) return 32767;
return v;
}
void decode_xa_mono(const unsigned char flags, unsigned char *src, signed short *dp)
{
int i, shift, filter;
int l0=xa_last[0],
l1=xa_last[1];
signed short d;
shift=flags&0xf,
filter=flags>>4;
int f0=filter_coef[filter][0],
f1=filter_coef[filter][1];
for (i=0; i<28; i++)
{
if ((i&1)==0)
d=(src[i>>1]&0xf)<<12;
else
d=(src[i>>1]&0xf0)<<8;
//fprintf(stderr, "shifted src sample %d: %04x; final: ", i, (d>>shift));
d=clamp((d>>shift)+(((l0*f0)+(l1*f1)+32)>>6));
//fprintf(stderr, "%04x\n", d);
*dp++=d;
l1=l0;
l0=d;
}
xa_last[0]=l0;
xa_last[1]=l1;
}
int main(int argc, char **argv)
{
FILE *in, *out;
signed short decoded[28];
unsigned char packet[15];
int i;
in = fopen(argv[1], "rb");
if (!in) return 1;
out = fopen(argv[2], "wb");
if (!out) return 1;
while (fread(packet, 1, 15, in)) // Read in entire packets until EOF; this line borrowed from Dennis Nedry
{
decode_xa_mono(packet[0], packet+1, decoded);
//fprintf(stderr, "DEBUG: decoded pkt word 1: %04X\n", decoded[0]);
for (i = 0; i < 28; i++)
{
fputc((unsigned char)(decoded[i]&0xFF), out);
fputc((unsigned char)((decoded[i]>>&0xFF), out);
}
}
return 0;
}
Based on the linked EASC information, I was completely right about bit 7 in those registers being the "compression enable" flagThen, depending on the compression type (0x0006 in this case), it writes a value into registers (ASC_BASE + $F08 and ASC_BASE + $F28) ($02 in this case, ORed with 0x80 to become $82 -- perhaps the $80 flag is a "compression enable" flag?) before using the exact same "dumb" "keep writing samples into the ASC being careful not to overflow the FIFO" algorithm that I had already traced out for uncompressed sampled sounds.