]> Shamusworld >> Repos - thunder/commitdiff
Emulator working with YM2151 and V63701 emus in place.
authorShamus Hammons <jlhamm@acm.org>
Sat, 19 Apr 2014 20:28:01 +0000 (15:28 -0500)
committerShamus Hammons <jlhamm@acm.org>
Sat, 19 Apr 2014 20:28:01 +0000 (15:28 -0500)
src/sound.cpp
src/thunder.cpp
src/v63701.cpp
src/v63701.h
src/ym2151.c [deleted file]
src/ym2151.h

index 930de351e081505acd3f19a3513c2e70590c8bd3..744eafaca7df547f422fbb06b38e8dace7763b5a 100644 (file)
@@ -14,6 +14,7 @@
 #include "sound.h"
 #include <SDL2/SDL.h>
 #include "resource.h"
+#include "ym2151.h"
 
 // Function prototypes
 void SoundFunc(void *, Uint8 *, int);
@@ -22,7 +23,7 @@ void SoundFunc(void *, Uint8 *, int);
 extern uint8_t voice_rom[];                    // PCM data pointer
 
 static bool soundInitialized = false;
-const float sampleBase = 22050.0/6000.0;  // Btwn 5512.5 and 6000
+const float sampleBase = 44010.0/6000.0;  // Btwn 5512.5 and 6000
 bool snd_go = false;
 bool chan1_go = false, chan2_go = false, chan3_go = false;
 bool chan4_go = false, chan5_go = false, chan6_go = false;
@@ -47,9 +48,17 @@ uint32_t snd_lens[3]   = { sunknownlen, scyalen, scameralen };
 
 void InitSound(void)
 {
+       // params 1, 4 & 5 are useless
+//     if (YMInit(1, 3579580, 22050, 16, 512))//, (SAMPLE **)sbp))
+       if (YMInit(1, 3579580, 44100, 16, 512))
+       {
+               printf("SOUND: Could not init YM2151 emulator!\n");
+               return;// -1;
+       }
+
        SDL_AudioSpec desired, obtained;
-       desired.freq = 22050;
-       desired.format = AUDIO_U8;
+       desired.freq = 44100;
+       desired.format = AUDIO_S16;
        desired.channels = 1;
        desired.samples = 1024;
        desired.callback = SoundFunc;
@@ -58,7 +67,7 @@ void InitSound(void)
        if (SDL_OpenAudio(&desired, &obtained) < 0)
        {
                soundInitialized = false;
-               printf("Couldn't open audio: %s\n", SDL_GetError());
+               printf("SOUND: Couldn't open audio: %s\n", SDL_GetError());
                return;
        }
 
@@ -145,6 +154,7 @@ void SpawnSound(int type, int snd, int channel/* = 0*/)
                                chan4_go = false;                                               // No sound loaded, so don't do it!
                }
        }
+#if 0
        else if (type == FMSOUND)
        {
                spos5 = 0;
@@ -155,6 +165,7 @@ void SpawnSound(int type, int snd, int channel/* = 0*/)
                if (spos5 == end_pos5)
                        chan5_go = false;                                                       // No sound loaded, so don't do it!
        }
+#endif
        else if (type == USERSOUND)
        {
                spos6 = 0;
@@ -167,6 +178,13 @@ void SpawnSound(int type, int snd, int channel/* = 0*/)
 
 void SoundFunc(void * userdata, Uint8 * buff, int num)
 {
+       static bool psg1go = false, psg2go = false;
+       // Length / 2 is because it's set up for 16-bit samples
+//     YM2151UpdateOne(buffer, length / 2);
+       // Have to go into ym2151.cpp and change this manually back to 8 bit
+       YM2151UpdateOne(buff, num / 2);
+//     return;
+
        // 0-22 different sounds...
        uint16_t cnt = 0, sample;
        uint8_t start_samp1, end_samp1, start_samp2, end_samp2;
@@ -174,123 +192,127 @@ void SoundFunc(void * userdata, Uint8 * buff, int num)
                samp4 = 128, samp5 = 128, samp6 = 128;                  // Zero samples...
 
        // Kill sound...
-       memset(buff, 128, num);
+//     memset(buff, 128, num);
+
+       if (!(chan1_go || chan2_go || chan3_go || chan4_go /*|| chan5_go*/ || chan6_go))
+               return;
 
-       if (chan1_go || chan2_go || chan3_go || chan4_go || chan5_go || chan6_go)
+       while (cnt != (num / 2))
        {
-               while (cnt != num)
+               if (chan1_go)
                {
-                       if (chan1_go)
+                       if (sample1 < 1)
                        {
-                               if (sample1 < 1)
+                               samp1 = voice_rom[spos1++];
+
+                               // Kill channel 1 if done...
+                               if (samp1 == 0xFF)
                                {
-                                       samp1 = voice_rom[spos1++];
-
-                                       // Kill channel 1 if done...
-                                       if (samp1 == 0xFF)
-                                       {
-                                               chan1_go = false;
-                                               samp1 = 128;
-                                       }
-                                       // RLE compression...
-                                       else if (samp1 == 0x00)
-                                       {
-                                               // # of repeats
-                                               sample1 += (float)voice_rom[spos1++] * sampleBase;
-                                               // Get last good sample
-                                               samp1   = prevSamp1;
-                                       }
-                                       else
-                                               // Keep fractional part intact
-                                               sample1 += sampleBase;
+                                       chan1_go = false;
+                                       samp1 = 128;
                                }
-
-                               prevSamp1 = samp1;              // Save last sample value
-                               sample1 -= 1.0;                 // Decrement repeat counter
+                               // RLE compression...
+                               else if (samp1 == 0x00)
+                               {
+                                       // # of repeats
+                                       sample1 += (float)voice_rom[spos1++] * sampleBase;
+                                       // Get last good sample
+                                       samp1   = prevSamp1;
+                               }
+                               else
+                                       // Keep fractional part intact
+                                       sample1 += sampleBase;
                        }
 
+                       prevSamp1 = samp1;              // Save last sample value
+                       sample1 -= 1.0;                 // Decrement repeat counter
+               }
+
 // Stretching 5KHz samples to 22KHz:
 //   numRepeats = 4;
 //            6KHz -> 22KHz:  22/6 repeats...
-                       if (chan2_go)
+               if (chan2_go)
+               {
+                       if (sample2 < 1)
                        {
-                               if (sample2 < 1)
+                               samp2 = voice_rom[spos2++];
+
+                               if (samp2 == 0xFF)
                                {
-                                       samp2 = voice_rom[spos2++];
-
-                                       if (samp2 == 0xFF)
-                                       {
-                                               chan2_go = false;
-                                               samp2 = 128;                                    // Kill channel 2 if done...
-                                       }
-                                       else if (samp2 == 0x00)                         // RLE compression...
-                                       {
-                                               sample2 += (float)voice_rom[spos2++] * sampleBase;      // # of repeats
-                                               samp2   = prevSamp2;
-                                       }
-                                       else
-                                               sample2 += sampleBase;
+                                       chan2_go = false;
+                                       samp2 = 128;                                    // Kill channel 2 if done...
                                }
+                               else if (samp2 == 0x00)                         // RLE compression...
+                               {
+                                       sample2 += (float)voice_rom[spos2++] * sampleBase;      // # of repeats
+                                       samp2   = prevSamp2;
+                               }
+                               else
+                                       sample2 += sampleBase;
+                       }
 
 // Delta-X values were making the samples sound like crap...
 //                             start_samp2 += delta_x2;
-                               prevSamp2 = samp2;
-                               sample2 -= 1.0;
-                       }
+                       prevSamp2 = samp2;
+                       sample2 -= 1.0;
+               }
 
-                       if (chan3_go)
-                       {
-                               samp3 = sndp3[spos3++];
+               if (chan3_go)
+               {
+                       samp3 = (psg1go ? sndp3[spos3++] : sndp3[spos3]);
+                       psg1go = !psg1go;
 
-                               if (spos3 == end_pos3)
-                               {
-                                       chan3_go = false;
-                                       samp3 = 128; // Kill channel 3 if done...
-                               }
+                       if (spos3 == end_pos3)
+                       {
+                               chan3_go = false;
+                               samp3 = 128; // Kill channel 3 if done...
                        }
+               }
 
-                       if (chan4_go)
-                       {
-                               samp4 = sndp4[spos4++];
+               if (chan4_go)
+               {
+                       samp4 = (psg2go ? sndp4[spos4++] : sndp4[spos4]);
+                       psg2go = !psg2go;
 
-                               if (spos4 == end_pos4)
-                               {
-                                       chan4_go = false;
-                                       samp4 = 128; // Kill channel 4 if done...
-                               }
+                       if (spos4 == end_pos4)
+                       {
+                               chan4_go = false;
+                               samp4 = 128; // Kill channel 4 if done...
                        }
+               }
+#if 0
+               if (chan5_go)
+               {
+                       samp5 = sndp5[spos5++];
 
-                       if (chan5_go)
+                       if (spos5 == end_pos5)
                        {
-                               samp5 = sndp5[spos5++];
-
-                               if (spos5 == end_pos5)
-                               {
-                                       chan5_go = false;
-                                       samp5 = 128; // Kill channel 5 if done...
-                               }
+                               chan5_go = false;
+                               samp5 = 128; // Kill channel 5 if done...
                        }
+               }
+#endif
+               if (chan6_go)
+               {
+                       samp6 = sndp6[spos6++];
 
-                       if (chan6_go)
+                       if (spos6 == end_pos6)
                        {
-                               samp6 = sndp6[spos6++];
-
-                               if (spos6 == end_pos6)
-                               {
-                                       chan6_go = false;
-                                       samp6 = 128;            // Kill channel 6...
-                               }
+                               chan6_go = false;
+                               samp6 = 128;            // Kill channel 6...
                        }
+               }
 
-                       // Mix 'em...
-                       sample = samp1 + samp2 + samp3 + samp4 + samp5 + samp6 - 640;
+               // Mix 'em...
+//             sample = samp1 + samp2 + samp3 + samp4 + samp5 + samp6 - 640;
+               sample = samp1 + samp2 + samp3 + samp4 + samp6 - (5 * 128);
 
-                       // If it overflowed, clip it
-                       if (sample & 0xFF00)
-                               sample = (sample & 0x8000 ? 0x00 : 0xFF);
+               // If it overflowed, clip it
+               if (sample & 0xFF00)
+//                     sample = (sample & 0x8000 ? 0x00 : 0xFF);
+                       sample = (sample & 0x8000 ? 0x0000 : 0xFFFF);
 
-                       buff[cnt++] = sample;
-               }
+               ((uint16_t *)buff)[cnt++] += sample << 7;
        }
 }
 
index 521980578b027f8d9720e89cf9dd504a548f0d34..d1ebfde22f9e07fbac870ff4c933170210cba2cf 100644 (file)
@@ -33,6 +33,8 @@
 #include "v63701.h"
 #include "v6809.h"
 #include "video.h"
+#include "ym2151.h"
+
 
 using namespace std;
 
@@ -98,8 +100,10 @@ uint8_t * psg_adrs[16];
 //uint32_t voc_lens[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 //                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 //uint8_t * voc_adrs[32];
-uint32_t fm_lens[14] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-uint8_t * fm_adrs[14];
+//uint32_t fm_lens[14] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+//uint8_t * fm_adrs[14];
+
+Byte input1, input2, input3, input4, input5;
 
 fstream tr;                                                    // Tracelog hook
 uint16_t pcx;                                          // Where we at?
@@ -167,7 +171,10 @@ if (((addr >= 0x4180) && (addr <= 0x4191)) || (addr == 0x4380))
        }
 #endif
 //     if (addr < 0x423D || addr > 0x425C)                                     // Protect writes to DSWs
-
+//if (addr == 0x4191)
+//{
+//     printf("V6809: Writing %02X to $4191...\n", b);
+//}
        // Memory shared with MCU (CPU #1 only! CPU #2 does not)
        if ((addr >= 0x4000) && (addr <= 0x43FF))
                mcuMem[addr - 0x3000] = b;
@@ -279,34 +286,42 @@ if (((addr >= 0x0180) && (addr <= 0x0191)) || (addr == 0x0380))
 
 uint8_t MCUReadMemory(uint16_t address)
 {
-#if 1
        if (address < 0x20)
        {
 //             printf("V63701 read $%02X from $%02X...\n", memory[address], address);
                return InternalRegisterRead(address);
        }
-#endif
-
-#if 0
-       // Translate local reads @ $1000-$13FF to $4000-$43FF in shared RAM
-       if ((address >= 0x1000) && (address <= 0x13FF))
-               return gram1[0x3000 + address];
-       else
-#endif
-               if ((address >= 0x2000) && (address <= 0x2001))
+       else if ((address >= 0x2000) && (address <= 0x2001))
+       {
+//             return 0;       //for now
+               return YMReadReg(0);
+       }
+       // Various joystick + buttons; all are active low.
+       else if (address == 0x2020)
+       {
+//printf("MCURead: Returning $%02X from $2020...\n", input1.byte);
+               return input1.byte;
+       }
+       else if (address == 0x2021)
        {
-               return 0;       //for now
-//             return YMReadReg(0);
+//extern bool V63701LogGo;
+//if (input2.byte == 0xDF)
+//     V63701LogGo = true;
+
+//printf("MCURead: Returning $%02X from $2021...\n", input2.byte);
+               return input2.byte;
        }
-//     else if (address == 0x2020)
-//             return input_port_0_r(0);
-//     else if (address == 0x2021)
-//             return input_port_1_r(0);
        // This is DSW1 & 2. All switch settings are active low.
        else if (address == 0x2030)
-               return 0xFF;
+       {
+//printf("MCURead: Returning $%02X from $2030...\n", input4.byte);
+               return input4.byte;
+       }
        else if (address == 0x2031)
-               return 0xFF;
+       {
+//printf("MCURead: Returning $%02X from $2031...\n", input5.byte);
+               return input5.byte;
+       }
 
        return mcuMem[address];
 }
@@ -325,6 +340,10 @@ void MCUWriteMemory(uint16_t address, uint8_t data)
        }
 #endif
 
+//if (address == 0x1191)
+//{
+//     printf("V63701: Writing $%02X to $1191...\n", data);
+//}
 #if 0
        // Translate local reads @ $1000-$13FF to $4000-$43FF in shared RAM
        if ((address >= 0x1000) && (address <= 0x13FF))
@@ -345,7 +364,7 @@ void MCUWriteMemory(uint16_t address, uint8_t data)
        else if (address == 0x2001)
        {
 //printf("Writing $%02X to YM2151 register $%02X...\n", data, ymRegister);
-//             YMWriteReg(0, ymRegister, data);
+               YMWriteReg(0, ymRegister, data);
                return;
        }
 
@@ -354,6 +373,31 @@ void MCUWriteMemory(uint16_t address, uint8_t data)
 }
 
 
+uint8_t V63701ReadPort1(void)
+{
+//     printf("V63701ReadPort1: Read $%02X...\n", input3.byte);
+       return input3.byte;
+}
+
+
+uint8_t V63701ReadPort2(void)
+{
+       return 0xFF;
+}
+
+
+void V63701WritePort1(uint8_t data)
+{
+//     printf("V63701WritePort1: Wrote $%02X...\n", data);
+}
+
+
+void V63701WritePort2(uint8_t data)
+{
+//     printf("V63701WritePort2: Wrote $%02X...\n", data);
+}
+
+
 //
 // Generic Load file into image space
 // (No error checking performed!  Responsibility of caller!)
@@ -584,6 +628,7 @@ void LoadPSGs(void)
 }
 
 
+#if 0
 //
 // Load FM samples from disk
 //
@@ -622,6 +667,7 @@ void LoadFMs(void)
                fp.close();
        }
 }
+#endif
 
 
 //
@@ -743,7 +789,7 @@ extern bool disasm; // From 'V6809.CPP'
 
        // Load samples if they're there...
        LoadPSGs();
-       LoadFMs();
+//     LoadFMs();
 
        // Set up V6809 execution contexts
 
@@ -767,6 +813,10 @@ extern bool disasm;        // From 'V6809.CPP'
        trace1 = false;
        SetRefreshRate(refresh2);                                       // Tell GUI our refresh rate
 
+       // Set all inputs to inactive...
+       input1.byte = input2.byte = input3.byte = input4.byte = input5.byte = 0xFF;
+//     mcu.port1 = 0xFF;
+//     mcu.port2 = 0xFF;
 #if 0
        // This is data that is supposed to come from the MCU... So that's why it hangs
        gram1[0x4182] = 0xA6;          // Temp kludge
@@ -860,53 +910,135 @@ WriteLog("About to enter main loop...\n");
                                        SavePCXSnapshot();
 //                                     debounce = 10;
                                }
-                               else if (event.key.keysym.sym == SDLK_F10)
-                                       gram1[0x41A5]++;                        // Coin? (F10)
-                               else if (event.key.keysym.sym == SDLK_c)
-                                       gram1[0x418C]++;                        // ? (C) Start
+#if 1
+                               else if (event.key.keysym.sym == SDLK_5)
+                                       input1.bit.b5 = 0;
+                               else if (event.key.keysym.sym == SDLK_1)
+                                       input1.bit.b6 = 0;
                                else if (event.key.keysym.sym == SDLK_RIGHT)
-                               {
-                                       // Disallow opposite directions @ same time
-                                       if (gram1[0x4281] == 0)
-                                               gram1[0x427F] = 1;              // Stick right
-                               }
+                                       input3.bit.b5 = 0;
                                else if (event.key.keysym.sym == SDLK_LEFT)
-                               {
-                                       // Disallow opposite directions@same time
-                                       if (gram1[0x427F] == 0)
-                                               gram1[0x4281] = 1;              // Stick left
-                               }
+                                       input3.bit.b4 = 0;
                                else if (event.key.keysym.sym == SDLK_UP)
-                               {
-                                       // Disallow opposite directions@same time
-                                       if (gram1[0x427D] == 0)
-                                               gram1[0x427B] = 1;              // Stick up
-                               }
+                                       input2.bit.b2 = 0;
                                else if (event.key.keysym.sym == SDLK_DOWN)
-                               {
-                                       // Disallow opposite directions@same time
-                                       if (gram1[0x427B] == 0)
-                                               gram1[0x427D] = 1;              // Stick down
-                               }
-                               else if (event.key.keysym.sym == SDLK_q)
-                                       gram1[0x4276] = 1;                      // (Q)  Jump
+                                       input1.bit.b2 = 0;
+                               else if (event.key.keysym.sym == SDLK_q)        // (Q)  Jump
+                                       input1.bit.b1 = 0;
                                else if (event.key.keysym.sym == SDLK_e)        // (E) Fire
-                                       gram1[0x4278] = 1;
+                                       input3.bit.b3 = 0;
+#else
+                               else if (event.key.keysym.sym == SDLK_1)
+                                       input1.bit.b0 = 0;
+                               else if (event.key.keysym.sym == SDLK_2)
+                                       input1.bit.b1 = 0;
+                               else if (event.key.keysym.sym == SDLK_3)
+                                       input1.bit.b2 = 0;
+                               else if (event.key.keysym.sym == SDLK_4)
+                                       input1.bit.b3 = 0;
+                               else if (event.key.keysym.sym == SDLK_5)
+                                       input1.bit.b4 = 0;
+                               else if (event.key.keysym.sym == SDLK_6)
+                                       input1.bit.b5 = 0;
+                               else if (event.key.keysym.sym == SDLK_7)
+                                       input1.bit.b6 = 0;
+                               else if (event.key.keysym.sym == SDLK_8)
+                                       input1.bit.b7 = 0;
+
+                               else if (event.key.keysym.sym == SDLK_q)
+                                       input2.bit.b0 = 0;
+                               else if (event.key.keysym.sym == SDLK_w)
+                                       input2.bit.b1 = 0;
+                               else if (event.key.keysym.sym == SDLK_e)
+                                       input2.bit.b2 = 0;
+                               else if (event.key.keysym.sym == SDLK_r)
+                                       input2.bit.b3 = 0;
+                               else if (event.key.keysym.sym == SDLK_t)
+                                       input2.bit.b4 = 0;
+                               else if (event.key.keysym.sym == SDLK_y)
+                                       input2.bit.b5 = 0;
+                               else if (event.key.keysym.sym == SDLK_u)
+                                       input2.bit.b6 = 0;
+                               else if (event.key.keysym.sym == SDLK_i)
+                                       input2.bit.b7 = 0;
+
+                               else if (event.key.keysym.sym == SDLK_a)
+                                       input3.bit.b0 = 0;
+                               else if (event.key.keysym.sym == SDLK_s)
+                                       input3.bit.b1 = 0;
+                               else if (event.key.keysym.sym == SDLK_d)
+                                       input3.bit.b2 = 0;
+                               else if (event.key.keysym.sym == SDLK_f)
+                                       input3.bit.b3 = 0;
+                               else if (event.key.keysym.sym == SDLK_g)
+                                       input3.bit.b4 = 0;
+#endif
 
                                break;
                        case SDL_KEYUP:
-                               if (event.key.keysym.sym == SDLK_RIGHT)
-                                       gram1[0x427F] = 0;
+#if 1
+                               if (event.key.keysym.sym == SDLK_5)
+                                       input1.bit.b5 = 1;
+                               else if (event.key.keysym.sym == SDLK_1)
+                                       input1.bit.b6 = 1;
+                               else if (event.key.keysym.sym == SDLK_RIGHT)
+                                       input3.bit.b5 = 1;
                                else if (event.key.keysym.sym == SDLK_LEFT)
-                                       gram1[0x4281] = 0;
+                                       input3.bit.b4 = 1;
                                else if (event.key.keysym.sym == SDLK_UP)
-                                       gram1[0x427B] = 0;
+                                       input2.bit.b2 = 1;
                                else if (event.key.keysym.sym == SDLK_DOWN)
-                                       gram1[0x427D] = 0;
-                               else if (event.key.keysym.sym == SDLK_q)
-                                       gram1[0x4276] = 0;                      // (Q)  Jump
+                                       input1.bit.b2 = 1;
+                               else if (event.key.keysym.sym == SDLK_q)        // (Q)  Jump
+                                       input1.bit.b1 = 1;
                                else if (event.key.keysym.sym == SDLK_e)        // (E) Fire
-                                       gram1[0x4278] = 0;
+                                       input3.bit.b3 = 1;
+#else
+                               if (event.key.keysym.sym == SDLK_1)
+                                       input1.bit.b0 = 1;
+                               else if (event.key.keysym.sym == SDLK_2)
+                                       input1.bit.b1 = 1;
+                               else if (event.key.keysym.sym == SDLK_3)
+                                       input1.bit.b2 = 1;
+                               else if (event.key.keysym.sym == SDLK_4)
+                                       input1.bit.b3 = 1;
+                               else if (event.key.keysym.sym == SDLK_5)
+                                       input1.bit.b4 = 1;
+                               else if (event.key.keysym.sym == SDLK_6)
+                                       input1.bit.b5 = 1;
+                               else if (event.key.keysym.sym == SDLK_7)
+                                       input1.bit.b6 = 1;
+                               else if (event.key.keysym.sym == SDLK_8)
+                                       input1.bit.b7 = 1;
+
+                               else if (event.key.keysym.sym == SDLK_q)
+                                       input2.bit.b0 = 1;
+                               else if (event.key.keysym.sym == SDLK_w)
+                                       input2.bit.b1 = 1;
+                               else if (event.key.keysym.sym == SDLK_e)
+                                       input2.bit.b2 = 1;
+                               else if (event.key.keysym.sym == SDLK_r)
+                                       input2.bit.b3 = 1;
+                               else if (event.key.keysym.sym == SDLK_t)
+                                       input2.bit.b4 = 1;
+                               else if (event.key.keysym.sym == SDLK_y)
+                                       input2.bit.b5 = 1;
+                               else if (event.key.keysym.sym == SDLK_u)
+                                       input2.bit.b6 = 1;
+                               else if (event.key.keysym.sym == SDLK_i)
+                                       input2.bit.b7 = 1;
+
+                               else if (event.key.keysym.sym == SDLK_a)
+                                       input3.bit.b0 = 1;
+                               else if (event.key.keysym.sym == SDLK_s)
+                                       input3.bit.b1 = 1;
+                               else if (event.key.keysym.sym == SDLK_d)
+                                       input3.bit.b2 = 1;
+                               else if (event.key.keysym.sym == SDLK_f)
+                                       input3.bit.b3 = 1;
+                               else if (event.key.keysym.sym == SDLK_g)
+                                       input3.bit.b4 = 1;
+#endif
 
                                break;
                        }
@@ -1131,6 +1263,7 @@ WriteLog("About to enter main loop...\n");
                        // We can do this here because we're not executing the cores yet.
                        cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;
                        cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+                       mcu.cpuFlags |= V63701_ASSERT_LINE_IRQ;
 //                                     while (cpu1.clock < 25000)
 // 1.538 MHz = 25633.333... cycles per frame (1/60 s)
 // 25600 cycles/frame
@@ -1170,9 +1303,11 @@ WriteLog("About to enter main loop...\n");
                if (psg_adrs[i])
                        delete[] psg_adrs[i];
 
+#if 0
        for(int i=0; i<14; i++)
                if (fm_adrs[i])
                        delete[] fm_adrs[i];
+#endif
 
        LogDone();
 
index b76063fccc168a931ee92d83e1d8c63b620a0cf9..ea225bd0c6c7642bdfe3ec8df4d013322762ca1e 100644 (file)
@@ -37,7 +37,7 @@
 // conversion to macro style opcodes is completed. :-)
 // [DONE--remain to be seen if there is any performance increase]
 
-//#define __DEBUG__
+#define __DEBUG__
 #define TEST_DONT_BRANCH_OPTIMIZATION
 
 #include "v63701.h"
@@ -46,6 +46,7 @@
 #ifdef __DEBUG__
 #include "dis63701.h"
 //#include "log.h"
+#include <stdio.h>             // for printf()
 #define WriteLog printf
 #endif
 
 
 #define WRITE_BACK(d)          regs.WrMem(addr, (d))
 
-#define PULL                           regs.RdMem(regs.s++)
-#define PUSH(r)                                regs.WrMem(--regs.s, (r))
-#define PULL16                         RdMemW(regs.s);         regs.s += 2
-#define PUSH16(r)                      regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8)
+// This is correct; PUSH writes the location *then* decrements the stack
+// pointer, and PULL does the opposite. Verified from the data sheet.
+#define PULL                           regs.RdMem(++regs.s)
+#define PUSH(r)                                regs.WrMem(regs.s--, (r))
+#define PULL16                         RdMemW(++regs.s);       ++regs.s;
+#define PUSH16(r)                      regs.WrMem(regs.s--, (r) & 0xFF); regs.WrMem(regs.s--, (r) >> 8)
 
 #define PACK_FLAGS                     ((regs.cc & 0xC0) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC)
 #define UNPACK_FLAGS           flagH = (regs.cc & FLAG_H) >> 5; \
 // Private global variables
 
 static V63701REGS regs;
+//V63701REGS regs;
 static V63701REGS * regsPointer;
+//V63701REGS * regsPointer;
 static uint8_t flagH, flagI, flagN, flagZ, flagV, flagC;
 
 static uint8_t CPUCycles[256] = {
@@ -2591,10 +2596,11 @@ static void myMemcpy(void * dst, void * src, uint32_t size)
 
 #ifdef __DEBUG__
 //int instCount[256];
-//static bool logGo = false;
-static bool logGo = true;
+bool V63701LogGo = false;
+//static bool V63701LogGo = true;
 char instBuf[256];
-extern uint8_t memory[];
+extern uint8_t mcuMem[];
+uint8_t * memory = mcuMem;
 #endif
 //
 // Function to execute 63701 for "cycles" cycles
@@ -2618,8 +2624,14 @@ void Execute63701(V63701REGS * context, uint32_t cycles)
        while (regs.clock < endCycles)
 #endif
        {
+#if 0
+if (regs.pc == 0x8236)
+{
+       printf("V63701: $8236 called by $%04X...\n", RdMemW(regs.s));
+}
+#endif
 #ifdef __DEBUG__
-if (logGo)
+if (V63701LogGo)
 {
        Decode63701(memory, regs.pc, instBuf);
        WriteLog("%s\n", instBuf);
@@ -2674,7 +2686,7 @@ if (logGo)
                                }
                        }
 #ifdef __DEBUG__
-if (logGo)
+if (V63701LogGo)
 //     WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%s%s%s%s%s%s%s%s]\n", regs.pc, regs.s, regs.x, regs.d.acc.a, regs.d.acc.b, (regs.cc & FLAG_E ? "E" : " "), (regs.cc & FLAG_F ? "F" : " "), (regs.cc & FLAG_H ? "H" : " "), (regs.cc & FLAG_I ? "I" : " "), (regs.cc & FLAG_N ? "N" : " "), (regs.cc & FLAG_Z ? "Z" : " "), (regs.cc & FLAG_V ? "V" : " "), (regs.cc & FLAG_C ? "C" : " "));
        WriteLog(" [PC=%04X S=%04X X=%04X A=%02X B=%02X CC=%s%s%s%s%s%s TCSR=%s%s%s%s%s%s%s%s CT=%04X OC=%04X]\n", regs.pc, regs.s, regs.x, regs.d.acc.a, regs.d.acc.b, (flagH ? "H" : "."), (flagI ? "I" : "."), (flagN ? "N" : "."), (flagZ ? "Z" : "."), (flagV ? "V" : "."), (flagC ? "C" : "."), (regs.tcsr.bit.icf ? "I" :"."), (regs.tcsr.bit.ocf ? "O" :"."), (regs.tcsr.bit.tof ? "T" :"."), (regs.tcsr.bit.eici ? "i" :"."), (regs.tcsr.bit.eoci ? "o" :"."), (regs.tcsr.bit.etoi ? "t" :"."), (regs.tcsr.bit.iedg ? "E" :"."), (regs.tcsr.bit.olvl ? "O" :"."), regs.counter.word, regs.outputCompare.word);
 #endif
@@ -2683,7 +2695,8 @@ if (logGo)
                if (regs.cpuFlags & V63701_ASSERT_LINE_RESET)
                {
 #ifdef __DEBUG__
-WriteLog("*** RESET LINE ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** RESET LINE ASSERTED ***\n");
 #endif
                        regs.tcsr.byte = 0;
                        regs.tcsrWasRead = false;
@@ -2697,21 +2710,24 @@ WriteLog("*** RESET LINE ASSERTED ***\n");
                else if (regs.cpuFlags & V63701_ASSERT_LINE_NMI)
                {
 #ifdef __DEBUG__
-WriteLog("*** NMI LINE ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** NMI LINE ASSERTED ***\n");
 #endif
                        HandleInterrupt(0xFFFC, V63701_ASSERT_LINE_NMI);
                }
                else if (regs.cpuFlags & V63701_ASSERT_LINE_IRQ)
                {
 #ifdef __DEBUG__
-WriteLog("*** IRQ LINE ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** IRQ LINE ASSERTED ***\n");
 #endif
 //                     if (!(regs.cc & FLAG_I))                        // Process an interrupt (I=0)?
                        if (!flagI)                                                     // Process an interrupt (I=0)?
                        {
 #ifdef __DEBUG__
-WriteLog("    IRQ TAKEN!\n");
-logGo = true;
+if (V63701LogGo)
+       WriteLog("    IRQ TAKEN!\n");
+//V63701LogGo = true;
 #endif
                                HandleInterrupt(0xFFF8, V63701_ASSERT_LINE_IRQ);
                        }
@@ -2719,14 +2735,16 @@ logGo = true;
                else if (regs.cpuFlags & V63701_ASSERT_INPUT_CAPTURE)
                {
 #ifdef __DEBUG__
-WriteLog("*** INPUT CAPTURE ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** INPUT CAPTURE ASSERTED ***\n");
 #endif
                        // Process interrupt if no I inhibit set, & enable in TCSR is set
                        if (!flagI && regs.tcsr.bit.eici)
                        {
 #ifdef __DEBUG__
-WriteLog("    IC TAKEN!\n");
-logGo = true;
+if (V63701LogGo)
+       WriteLog("    IC TAKEN!\n");
+//V63701LogGo = true;
 #endif
                                HandleInterrupt(0xFFF6, V63701_ASSERT_INPUT_CAPTURE);
                        }
@@ -2734,14 +2752,16 @@ logGo = true;
                else if (regs.cpuFlags & V63701_ASSERT_OUTPUT_COMPARE)
                {
 #ifdef __DEBUG__
-WriteLog("*** OUTPUT COMPARE ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** OUTPUT COMPARE ASSERTED ***\n");
 #endif
                        // Process interrupt if no I inhibit set, & enable in TCSR is set
                        if (!flagI && regs.tcsr.bit.eoci)
                        {
 #ifdef __DEBUG__
-WriteLog("    OC TAKEN!\n");
-logGo = true;
+if (V63701LogGo)
+       WriteLog("    OC TAKEN!\n");
+//V63701LogGo = true;
 #endif
                                HandleInterrupt(0xFFF4, V63701_ASSERT_OUTPUT_COMPARE);
                        }
@@ -2749,14 +2769,16 @@ logGo = true;
                else if (regs.cpuFlags & V63701_ASSERT_TIMER_OVERFLOW)
                {
 #ifdef __DEBUG__
-WriteLog("*** TIMER OVER ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** TIMER OVER ASSERTED ***\n");
 #endif
                        // Process interrupt if no I inhibit set, & enable in TCSR is set
                        if (!flagI && regs.tcsr.bit.etoi)
                        {
 #ifdef __DEBUG__
-WriteLog("    TO TAKEN!\n");
-logGo = true;
+if (V63701LogGo)
+       WriteLog("    TO TAKEN!\n");
+//V63701LogGo = true;
 #endif
                                HandleInterrupt(0xFFF2, V63701_ASSERT_TIMER_OVERFLOW);
                        }
@@ -2813,8 +2835,15 @@ uint8_t InternalRegisterRead(uint16_t address)
        {
        case 0x00:
                return regs.ddr1;
+       case 0x01:
+               return regs.ddr2;
        case 0x02:
-               return /*(regs.port1read & ~regs.ddr1) |*/ (regs.port1 & regs.ddr1);
+               return (V63701ReadPort1() & ~regs.ddr1) | (regs.port1data & regs.ddr1);
+//             return /*(regs.port1read & ~regs.ddr1) |*/ (regs.port1r & ~regs.ddr1);
+       case 0x03:
+               // Top 3 bits are MCU mode bits.
+               return (V63701ReadPort2() & ~regs.ddr2) | (regs.port2data & regs.ddr2);
+//             return /*(regs.port1read & ~regs.ddr1) |*/ (regs.port2r & ~regs.ddr2 & 0x1F);
        // Timer Control and Status Register
        case 0x08:
                regs.tcsrWasRead = true;
@@ -2855,6 +2884,8 @@ uint8_t InternalRegisterRead(uint16_t address)
 
 void InternalRegisterWrite(uint16_t address, uint8_t data)
 {
+       uint8_t writeData;
+
        switch (address & 0x1F)
        {
        case 0x00:
@@ -2864,10 +2895,13 @@ void InternalRegisterWrite(uint16_t address, uint8_t data)
                regs.ddr2 = data;
                break;
        case 0x02:
-               regs.port1 = data;
+               regs.port1data = data;
+               writeData = (V63701ReadPort1() & ~regs.ddr1) | (data & regs.ddr1);
+               V63701WritePort1(writeData);
                break;
        case 0x03:
-               regs.port2 = data;
+               // Port 2 only has 5 bits of output, top 3 are the MCU mode bits
+               regs.port2data = ((regs.port2data & ~regs.ddr2) | (data & regs.ddr2)) & 0x1F;
                break;
 //     case 0x05:
        // Timer Control and Status Register
index 47c5b1802d386f164b380f06e42b433e9b8dcc84..2e711dcb0d5a6cb09b7b25c20ff0f148f7afa7d3 100644 (file)
@@ -105,8 +105,8 @@ struct V63701REGS
        Word outputCompare;                             // 63701 Output Compare register
        uint8_t ddr1;
        uint8_t ddr2;
-       uint8_t port1;
-       uint8_t port2;
+       uint8_t port1data;
+       uint8_t port2data;
        uint8_t ramCtrl;
        uint8_t cWriteLatch;                    // Counter write latch
        uint8_t cReadLatch;                             // Counter read latch
@@ -128,5 +128,11 @@ uint64_t GetCurrentV63701Clock(void);              // Get the clock of the currently executi
 uint8_t InternalRegisterRead(uint16_t);
 void InternalRegisterWrite(uint16_t, uint8_t);
 
+// These functions must be implemented by the user...
+extern uint8_t V63701ReadPort1(void);
+extern uint8_t V63701ReadPort2(void);
+extern void V63701WritePort1(uint8_t);
+extern void V63701WritePort2(uint8_t);
+
 #endif // __V63701_H__
 
diff --git a/src/ym2151.c b/src/ym2151.c
deleted file mode 100644 (file)
index a69a281..0000000
+++ /dev/null
@@ -1,1450 +0,0 @@
-//
-// Jarek Burczynski's YM2151 emulator
-//
-// Cleaned of most MAMEisms & cleaned up in general by James Hammons
-// (this is mostly a placeholder until I write my own)
-//
-
-#include "ym2151.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <stdint.h>
-
-
-// Missing shit (from M.A.M.E.)
-
-#if 1
-#define PI 3.1415629535897932338
-static FILE * errorlog = 0;
-//int cpu_scalebyfcount(int);
-//void timer_remove(void *);
-//void * timer_set(int, int, void (*)(int));
-
-// Bogus M.A.M.E. shite
-int cpu_scalebyfcount(int f) { return f; }
-void timer_remove(void * foo) { printf("STUB: timer_remove()\n"); }
-void * timer_set(int foo, int bar, void (* baz)(int)) { printf("STUB: timer_set()\n"); return 0; }
-
-#endif
-
-
-/*
-**  some globals ...
-*/
-
-/*
-**  Shifts below are subject to change if sampling frequency changes...
-*/
-#define FREQ_SH 16  /* 16.16 fixed point for frequency calculations     */
-#define LFO_SH 24   /*  8.24 fixed point for LFO frequency calculations */
-#define ENV_SH 16   /* 16.16 fixed point for envelope calculations      */
-#define TIMER_SH 16 /* 16.16 fixed point for timers calculations        */
-
-#define ENV_BITS 10
-#define ENV_RES ((int)1<<ENV_BITS)
-#define ENV_STEP (96.0/ENV_RES)
-#define MAX_VOLUME_INDEX ((ENV_RES-1)<<ENV_SH)
-#define MIN_VOLUME_INDEX (0)
-#define VOLUME_OFF (ENV_RES<<ENV_SH)
-
-#define SIN_BITS 10
-#define SIN_LEN ((int)1<<SIN_BITS)
-#define SIN_MASK (SIN_LEN-1)
-
-#define FINAL_SH8 7   /*this shift is applied to final output of all channels to get 8-bit sample */
-#define FINAL_SH16 0  /*this shift is applied to final output of all channels to get 16-bit sample*/
-
-static uint8_t FEED[8] = {0,7,6,5,4,3,2,1}; /*shifts (divider) for output of op.0 which feeds into itself*/
-
-#define TL_TAB_LEN (2*(ENV_RES + ENV_RES + ENV_RES + SIN_LEN))
-static signed int * TL_TAB = NULL;
-/*
- *  Offset in this table is calculated as:
- *
- *  1st ENV_RES:
- *     TL- main offset (Total attenuation Level), range 0 to 1023 (0-96 dB)
- *  2nd ENV_RES:
- *     current envelope value of the operator, range 0 to 1023 (0-96 dB)
- *  3rd ENV_RES:
- *     Amplitude Modulation from LFO, range 0 to 1023 (0-96dB)
- *  4th SIN_LEN:
- *     Sin Wave Offset from sin_tab, range 0 to about 56 dB only, but lets
- *     simplify things and assume sin could be 96 dB, range 0 to 1023
- *
- *  Length of this table is doubled because we have two separate parts
- *  for positive and negative halves of sin wave (above and below X axis).
- */
-
-static signed int * sin_tab[SIN_LEN];  /* sin waveform table in decibel scale */
-
-#if 0
-/*tables below are defined for usage by LFO */
-signed int PMsaw     [SIN_LEN];   /*saw waveform table PM      */
-signed int PMsquare  [SIN_LEN];   /*square waveform table PM   */
-signed int PMtriangle[SIN_LEN];   /*triangle waveform table PM */
-signed int PMnoise   [SIN_LEN];   /*noise waveform table PM    */
-
-uint16_t AMsaw     [SIN_LEN];     /*saw waveform table AM      */
-uint16_t AMsquare  [SIN_LEN];     /*square waveform table AM   */
-uint16_t AMtriangle[SIN_LEN];     /*triangle waveform table AM */
-uint16_t AMnoise   [SIN_LEN];     /*noise waveform table AM    */
-#endif
-
-static int YM2151_CLOCK = 1;           /* this will be passed from 2151intf.c */
-static int YM2151_SAMPFREQ = 1;                /* this will be passed from 2151intf.c */
-//static uint8_t sample_16bit; /* 1 -> 16 bit sample, 0 -> 8 bit */
-
-static int YMBufSize;          /* size of sound buffer, in samples */
-static int YMNumChips;         /* total # of YM's emulated */
-
-static int TimerA[1024];
-static int TimerB[256];
-
-/* ASG 980324: added */
-static double TimerATime[1024];
-static double TimerBTime[256];
-
-static YM2151 * YMPSG = NULL;  /* array of YM's */
-
-signed int * BuffTemp = NULL;  /*temporary buffer for speedup purposes*/
-
-static void (* envelope_calc[5])(OscilRec *);
-static void (* register_writes[256])(uint8_t, uint8_t, uint8_t);
-
-//save output as raw 16-bit sample - just in case you would like to listen to it offline ;-)
-//#define SAVE_SAMPLE
-//#define SAVE_SEPARATE_CHANNELS
-
-#ifdef SAVE_SAMPLE
-#ifdef SAVE_SEPARATE_CHANNELS
-FILE * sample1;
-FILE * sample2;
-FILE * sample3;
-FILE * sample4;
-FILE * sample5;
-FILE * sample6;
-#endif
-FILE * samplesum;
-#endif
-
-int PMTab[8]; /*8 channels */
-/*  this table is used for PM setup of LFO */
-
-int AMTab[8]; /*8 channels */
-/*  this table is used for AM setup of LFO */
-
-static int decib45[16];
-/*decibel table to convert from D1L values to index in lookup table*/
-
-static int attack_curve[ENV_RES];
-
-unsigned int divia[64]; //Attack dividers
-unsigned int divid[64]; //Decay dividers
-static unsigned int A_DELTAS[64+31]; //Attack deltas (64 keycodes + 31 RKS's = 95)
-static unsigned int D_DELTAS[64+31]; //Decay  deltas (64 keycodes + 31 RKS's = 95)
-
-float DT1Tab[32][4]={ /* 8 octaves * 4 key codes, 4 DT1 values */
-/*
- *  Table defines offset in Hertz from base frequency depending on KC and DT1
- *  User's Manual page 21
-*/
-/*OCT NOTE DT1=0 DT1=1  DT1=2  DT1=3*/
-/* 0   0*/{0,    0,     0.053, 0.107},
-/* 0   1*/{0,    0,     0.053, 0.107},
-/* 0   2*/{0,    0,     0.053, 0.107},
-/* 0   3*/{0,    0,     0.053, 0.107},
-/* 1   0*/{0,    0.053, 0.107, 0.107},
-/* 1   1*/{0,    0.053, 0.107, 0.160},
-/* 1   2*/{0,    0.053, 0.107, 0.160},
-/* 1   3*/{0,    0.053, 0.107, 0.160},
-/* 2   0*/{0,    0.053, 0.107, 0.213},
-/* 2   1*/{0,    0.053, 0.160, 0.213},
-/* 2   2*/{0,    0.053, 0.160, 0.213},
-/* 2   3*/{0,    0.053, 0.160, 0.267},
-/* 3   0*/{0,    0.107, 0.213, 0.267},
-/* 3   1*/{0,    0.107, 0.213, 0.320},
-/* 3   2*/{0,    0.107, 0.213, 0.320},
-/* 3   3*/{0,    0.107, 0.267, 0.373},
-/* 4   0*/{0,    0.107, 0.267, 0.427},
-/* 4   1*/{0,    0.160, 0.320, 0.427},
-/* 4   2*/{0,    0.160, 0.320, 0.480},
-/* 4   3*/{0,    0.160, 0.373, 0.533},
-/* 5   0*/{0,    0.213, 0.427, 0.587},
-/* 5   1*/{0,    0.213, 0.427, 0.640},
-/* 5   2*/{0,    0.213, 0.480, 0.693},
-/* 5   3*/{0,    0.267, 0.533, 0.747},
-/* 6   0*/{0,    0.267, 0.587, 0.853},
-/* 6   1*/{0,    0.320, 0.640, 0.907},
-/* 6   2*/{0,    0.320, 0.693, 1.013},
-/* 6   3*/{0,    0.373, 0.747, 1.067},
-/* 7   0*/{0,    0.427, 0.853, 1.173},
-/* 7   1*/{0,    0.427, 0.907, 1.173},
-/* 7   2*/{0,    0.480, 1.013, 1.173},
-/* 7   3*/{0,    0.533, 1.067, 1.173}
-};
-
-static uint16_t DT2Tab[4]={ /* 4 DT2 values */
-/*
- *   DT2 defines offset in cents from base note
- *
- *   The table below defines offset in deltas table...
- *   User's Manual page 22
- *   Values below were calculated using formula:  value = orig.val / 1.5625
- *
- * DT2=0 DT2=1 DT2=2 DT2=3
- * 0     600   781   950
- */
-       0,    384,  500,  608
-};
-
-static uint16_t KC_TO_INDEX[16*8];  /*16 note codes * 8 octaves */
-/*translate key code KC (OCT2 OCT1 OCT0 N3 N2 N1 N0) into index in deltas table*/
-
-static signed int DT1deltas[32][8];
-
-static signed int deltas[9*12*64];/*9 octaves, 12 semitones, 64 'cents'  */
-/*deltas in sintable (fixed point) to get the closest frequency possible */
-/*there're 9 octaves because of DT2 (max 950 cents over base frequency)  */
-
-static signed int LFOdeltas[256];  /*frequency deltas for LFO*/
-
-
-void sin_init(void)
-{
-       int x, i;
-       float m;
-
-       for(i=0; i<SIN_LEN; i++)
-       {
-               m = sin(2 * PI * i / SIN_LEN);  /*count sin value*/
-
-               if ((m < 0.0001) && (m > -0.0001)) /*is m very close to zero ?*/
-                       m = ENV_RES - 1;
-               else
-               {
-                       if (m > 0.0)
-                       {
-                               m = 20 * log10(1.0 / m);      /* and how many decibels is it? */
-                               m = m / ENV_STEP;
-                       }
-                       else
-                       {
-                               m = 20 * log10(-1.0 / m);     /* and how many decibels is it? */
-                               m = (m / ENV_STEP) + TL_TAB_LEN / 2;
-                       }
-               }
-
-               sin_tab[i] = &TL_TAB[(unsigned int)m];  /**/
-               //if (errorlog) fprintf(errorlog,"sin %i = %i\n",i,sin_tab[i] );
-       }
-
-       for(x=0; x<TL_TAB_LEN/2; x++)
-       {
-               if (x < ENV_RES)
-               {
-                       if ((x * ENV_STEP) < 6.0)  /*have we passed 6 dB*/
-                       {       /*nope, we didn't */
-                               m = ((1 << 12) - 1) / pow(10, x * ENV_STEP / 20);
-                       }
-                       else
-                       {
-                               /*if yes, we simplify things (and the real chip */
-                               /*probably does it also) and assume that - 6dB   */
-                               /*halves the voltage (it _nearly_ does in fact)  */
-                               m = TL_TAB[(int)((float)x - (6.0 / ENV_STEP))] / 2;
-                       }
-               }
-               else
-               {
-                       m = 0;
-               }
-
-               TL_TAB[        x         ] = m;
-               TL_TAB[x + TL_TAB_LEN / 2] = -m;
-               //if (errorlog) fprintf(errorlog,"tl %04i =%08x\n",x,TL_TAB[x]);
-       }
-
-/* create attack curve */
-       for(i=0; i<ENV_RES; i++)
-       {
-               m = (ENV_RES - 1) / pow(10, i * (48.0 / ENV_RES) / 20);
-               x = m * (1 << ENV_SH);
-               attack_curve[ENV_RES - 1 - i] = x;
-               //if (errorlog) fprintf(errorlog,"attack [%04x] = %08x Volt=%08x\n", ENV_RES-1-i, x/(1<<ENV_SH), TL_TAB[x/(1<<ENV_SH)] );
-       }
-
-       for(x=0; x<16; x++)
-       {
-               i = (x < 15 ? x : x + 16) * (3.0 / ENV_STEP);  /*every 3 dB except for ALL '1' = 45dB+48dB*/
-               i <<= ENV_SH;
-               decib45[x] = i;
-               //if (errorlog) fprintf(errorlog,"decib45[%04x]=%08x\n",x,i );
-       }
-
-#ifdef SAVE_SAMPLE
-#ifdef SAVE_SEPARATE_CHANNELS
-sample1=fopen("samp.raw","wb");
-sample2=fopen("samp2.raw","wb");
-sample3=fopen("samp3.raw","wb");
-sample4=fopen("samp4.raw","wb");
-sample5=fopen("samp5.raw","wb");
-sample6=fopen("samp6.raw","wb");
-#endif
-samplesum=fopen("sampsum.raw","wb");
-#endif
-}
-
-
-void hertz(void)
-{
-       int i, j, oct;
-       long int mult;
-       float pom, pom2, m;
-       float scaler;   /* formula below is true for chip clock=3579545 */
-       /* so we need to scale its output accordingly to the chip clock */
-
-/*this loop calculates Hertz values for notes from c#0 up to c-8*/
-/*including 64 'cents' (100/64 which is 1.5625 of real cent) for each semitone*/
-
-       scaler = (float)YM2151_CLOCK / 3579545.0;
-
-       oct = 768;
-       mult = (long int)1 << FREQ_SH;
-
-       for(i=0; i<1*12*64; i++)
-       {
-               pom = scaler * 6.875 * pow(2, ((i + 4 * 64) * 1.5625 / 1200.0)); /*13.75Hz is note A 12semitones below A-0, so C#0 is 4 semitones above then*/
-               /*calculate phase increment for above precounted Hertz value*/
-               pom2 = ((pom * SIN_LEN) / (float)YM2151_SAMPFREQ) * mult; /*fixed point*/
-
-               deltas[i + oct * 4] = pom2 * 16;  /*oct 4 - center*/
-               deltas[i + oct * 5] = deltas[oct * 4 + i] << 1; //oct 5
-               deltas[i + oct * 6] = deltas[oct * 4 + i] << 2; //oct 6
-               deltas[i + oct * 7] = deltas[oct * 4 + i] << 3; //oct 7
-               deltas[i + oct * 8] = deltas[oct * 4 + i] << 4; //oct 8
-
-               deltas[i + oct * 3] = deltas[oct * 4 + i] >> 1; //oct 3
-               deltas[i + oct * 2] = deltas[oct * 4 + i] >> 2; //oct 2
-               deltas[i + oct * 1] = deltas[oct * 4 + i] >> 3; //oct 1
-               deltas[i + oct * 0] = deltas[oct * 4 + i] >> 4; //oct 0
-
-               //if (errorlog) fprintf(errorlog,"deltas[%04i] = %08x\n",i,deltas[i]);
-       }
-
-       for(j=0; j<4; j++)
-       {
-               for(i=0; i<32; i++)
-               {
-                       pom = scaler * DT1Tab[i][j];
-                       //calculate phase increment for above precounted Hertz value
-                       DT1deltas[i][j] = ((pom * SIN_LEN) / (float)YM2151_SAMPFREQ) * mult; /*fixed point*/
-                       DT1deltas[i][j + 4] = -DT1deltas[i][j];
-               }
-       }
-
-       mult = (long int)1 << LFO_SH;
-       m = (float)YM2151_CLOCK;
-
-       for(i=0; i<256; i++)
-       {
-               j = i & 0x0F;
-               pom = scaler * fabs((m / 65536 / (1 << (i / 16))) - (m / 65536 / 32 / (1 << (i / 16)) * (j + 1)));
-
-               /*calculate phase increment for above precounted Hertz value*/
-               pom2 = ((pom * SIN_LEN) / (float)YM2151_SAMPFREQ) * mult; /*fixed point*/
-               LFOdeltas[0xFF - i] = pom2;
-               //if (errorlog) fprintf(errorlog, "LFO[%02x] = %08x\n",0xff-i, LFOdeltas[0xff-i]);
-       }
-
-       /* calculate KC to index table */
-       j=0;
-       for(i=0; i<16*8; i++)
-       {
-               KC_TO_INDEX[i] = (i >> 4) * 12 * 64 + j * 64 ;
-
-               if ((i & 3) != 3)
-                       j++;    /* change note code */
-
-               if ((i & 15) == 15)
-                       j = 0;  /* new octave */
-
-               //if (errorlog) fprintf(errorlog,"NOTE[%i] = %i\n",i,KC_TO_INDEX[i]);
-       }
-
-       /* precalculate envelope times */
-       for(i=0; i<64; i++)
-       {
-               pom = (16 << (i >> 2)) + (4 << (i >> 2)) * (i & 0x03);
-
-               if ((i >> 2) == 0)
-                       pom = 1; //infinity
-
-               if ((i >> 2) == 15)
-                       pom = 524288; //const
-
-               divid[i] = pom;
-       }
-
-       for(i=0; i<64; i++)
-       {
-               pom = ((128+64+32)<<(i>>2))+((32+16+8)<<(i>>2))*(i&0x03);
-
-               if ((i>>2)==0)  pom=1;    //infinity
-
-               if ((i>>2)==15)
-               {
-                       if ((i & 0x03) == 3)
-                               pom = 153293300; //zero attack time
-                       else
-                               pom = 6422528; //const attack time
-               }
-
-               divia[i] = pom;
-       }
-
-       mult = (long int)1 << ENV_SH;
-
-       for(i=0; i<64; i++)
-       {
-               if (divid[i] == 1)
-                       pom = 0;  //infinity
-               else
-                       pom = (scaler * ENV_RES * mult) / ((float)YM2151_SAMPFREQ * ((float)YM2151_CLOCK / 1000.0 / (float)divid[i]));
-               //if (errorlog) fprintf(errorlog,"i=%03i div=%i time=%f delta=%f\n",i,divid[i],
-               //              (float)YM2151_CLOCK/1000.0/(float)divid[i], pom );
-               D_DELTAS[i] = pom;
-       }
-
-       for (i=0; i<64; i++)
-       {
-               if (divia[i] == 1)
-                       pom = 0;  //infinity
-               else
-                       pom = (scaler * ENV_RES * mult) / ((float)YM2151_SAMPFREQ * ((float)YM2151_CLOCK / 1000.0 / (float)divia[i]));
-
-               //if (errorlog) fprintf(errorlog,"i=%03i div=%i time=%f delta=%f\n",i,divia[i],
-               //              (float)YM2151_CLOCK/1000.0/(float)divia[i], pom );
-               A_DELTAS[i] = pom;
-       }
-
-       // This is only for speedup purposes -> to avoid testing if (keycode+RKS is
-       // over 63)
-       for(i=0; i<32; i++)
-       {
-               D_DELTAS[64 + i] = D_DELTAS[63];
-               A_DELTAS[64 + i] = A_DELTAS[63];
-       }
-
-       /* precalculate timers deltas */
-       /* User's Manual pages 15,16  */
-       mult = (int)1 << TIMER_SH;
-
-       for(i=0; i<1024; i++)
-       {
-               /* ASG 980324: changed to compute both TimerA and TimerATime */
-               pom = (64.0 * (1024.0 - i) / YM2151_CLOCK);
-               TimerATime[i] = pom;
-               TimerA[i] = pom * YM2151_SAMPFREQ * mult;  /*number of samples that timer period should last (fixed point) */
-       }
-
-       for(i=0; i<256; i++)
-       {
-               /* ASG 980324: changed to compute both TimerB and TimerBTime */
-               pom = (1024.0 * (256.0 - i) / YM2151_CLOCK);
-               TimerBTime[i] = pom;
-               TimerB[i] = pom * YM2151_SAMPFREQ * mult;  /*number of samples that timer period should last (fixed point) */
-       }
-}
-
-
-void envelope_attack(OscilRec * op)
-{
-       if ((op->attack_volume -= op->delta_AR) < MIN_VOLUME_INDEX)  //is volume index min already ?
-       {
-               op->volume = MIN_VOLUME_INDEX;
-               op->state++;
-       }
-       else
-               op->volume = attack_curve[op->attack_volume>>ENV_SH];
-}
-
-
-void envelope_decay(OscilRec * op)
-{
-       if ((op->volume += op->delta_D1R) > op->D1L)
-       {
-               //op->volume = op->D1L;
-               op->state++;
-       }
-}
-
-
-void envelope_sustain(OscilRec * op)
-{
-       if ((op->volume += op->delta_D2R) > MAX_VOLUME_INDEX)
-       {
-               op->state = 4;
-               op->volume = VOLUME_OFF;
-       }
-}
-
-
-void envelope_release(OscilRec * op)
-{
-       if ((op->volume += op->delta_RR) > MAX_VOLUME_INDEX)
-       {
-               op->state = 4;
-               op->volume = VOLUME_OFF;
-       }
-}
-
-
-void envelope_nothing(OscilRec *op)
-{
-}
-
-
-inline void envelope_KOFF(OscilRec * op)
-{
-       op->state = 3; /*release*/
-}
-
-
-inline void envelope_KON(OscilRec * op)
-{
-       /*this is to remove the gap time if TL>0*/
-       op->volume = VOLUME_OFF; //(ENV_RES - op->TL)<<ENV_SH; /***  <-  SURE ABOUT IT ?  No, but let's give it a try...*/
-       op->attack_volume = op->volume;
-       op->phase = 0;
-       op->state = 0;    /*KEY ON = attack*/
-       op->OscilFB = 0;  /*Clear feedback after key on */
-}
-
-
-void refresh_chip(YM2151 * PSG)
-{
-       uint16_t kc_index_oscil, kc_index_channel, mul;
-       uint8_t op,v,kc;
-       signed char k,chan;
-       OscilRec * osc;
-
-       for(chan=7; chan>=0; chan--)
-       {
-               kc = PSG->KC[chan];
-               kc_index_channel = KC_TO_INDEX[kc] + PSG->KF[chan];
-               kc >>=2;
-
-               for(k=24; k>=0; k-=8)
-               {
-                       op = chan + k;
-                       osc = &PSG->Oscils[op];
-
-/*calc freq begin*/
-                       v = (PSG->Regs[YM_DT2_D2R_BASE + op] >> 6) & 0x03;   //DT2 value
-                       kc_index_oscil = kc_index_channel + DT2Tab[v]; //DT2 offset
-                       v = PSG->Regs[YM_DT1_MUL_BASE + op];
-                       mul = (v & 0x0F) << 1;
-
-                       if (mul)
-                               osc->freq = deltas[kc_index_oscil] * mul;
-                       else
-                               osc->freq = deltas[kc_index_oscil];
-
-                       osc->freq += DT1deltas[kc][(v >> 4) & 0x07];  //DT1 value
-/*calc freq end*/
-
-/*calc envelopes begin*/
-                       v = kc >> PSG->KS[op];
-                       osc->delta_AR  = A_DELTAS[ osc->AR + v];    /* 2*RR + RKS =max 95*/
-                       osc->delta_D1R = D_DELTAS[osc->D1R + v];    /* 2*RR + RKS =max 95*/
-                       osc->delta_D2R = D_DELTAS[osc->D2R + v];    /* 2*RR + RKS =max 95*/
-                       osc->delta_RR =  D_DELTAS[ osc->RR + v];    /* 2*RR + RKS =max 95*/
-/*calc envelopes end*/
-               }
-       }
-}
-
-
-void write_YM_NON_EMULATED(uint8_t n, uint8_t r, uint8_t v)
-{
-       if (errorlog)
-               fprintf(errorlog, "Write to non emulated register %02x value %02x\n", r, v);
-}
-
-
-void write_YM_KON(uint8_t n, uint8_t r, uint8_t v)
-{
-       uint8_t chan;
-       YM2151 * PSG = &(YMPSG[n]);
-
-       chan = v & 0x07;
-
-       if (v & 0x08)
-               envelope_KON(&PSG->Oscils[chan]);
-       else
-               envelope_KOFF(&PSG->Oscils[chan]);
-
-       if (v & 0x10)
-               envelope_KON(&PSG->Oscils[chan + 16]);
-       else
-               envelope_KOFF(&PSG->Oscils[chan + 16]);
-
-       if (v & 0x20)
-               envelope_KON(&PSG->Oscils[chan + 8]);
-       else
-               envelope_KOFF(&PSG->Oscils[chan + 8]);
-
-       if (v & 0x40)
-               envelope_KON(&PSG->Oscils[chan + 24]);
-       else
-               envelope_KOFF(&PSG->Oscils[chan + 24]);
-}
-
-
-void write_YM_CLOCKA1(uint8_t n, uint8_t r, uint8_t v)
-{
-       YMPSG[n].Regs[r] = v;
-}
-
-
-void write_YM_CLOCKA2(uint8_t n, uint8_t r, uint8_t v)
-{
-       YMPSG[n].Regs[r] = v & 0x03;
-}
-
-
-void write_YM_CLOCKB(uint8_t n, uint8_t r, uint8_t v)
-{
-       YMPSG[n].Regs[r] = v;
-}
-
-
-static void timer_callback_a(int n)
-{
-       YM2151 * PSG = &YMPSG[n];
-//     YM2151UpdateOne(n, cpu_scalebyfcount(YMBufSize));
-
-       if (PSG->handler)
-               (*PSG->handler)();
-
-       PSG->TimA = 0;
-       PSG->TimIRQ |= 1;
-       PSG->TimATimer = 0;
-}
-
-
-static void timer_callback_b(int n)
-{
-       YM2151 * PSG = &YMPSG[n];
-//     YM2151UpdateOne(n, cpu_scalebyfcount(YMBufSize));
-
-       if (PSG->handler)
-               (*PSG->handler)();
-
-       PSG->TimB = 0;
-       PSG->TimIRQ |= 2;
-       PSG->TimBTimer = 0;
-}
-
-
-void write_YM_CLOCKSET(uint8_t n, uint8_t r, uint8_t v)
-{
-       YM2151 * PSG = &(YMPSG[n]);
-
-       v &= 0xBF;
-       //PSG->Regs[r]=v;
-//     if (errorlog) fprintf(errorlog,"CSM= %01x FRESET=%02x, IRQEN=%02x, LOAD=%02x\n",v>>7,(v>>4)&0x03,(v>>2)&0x03,v&0x03 );
-
-       if (v & 0x80) //CSM
-       {}
-
-       /* ASG 980324: remove the timers if they exist */
-       if (PSG->TimATimer)
-               timer_remove(PSG->TimATimer);
-
-       if (PSG->TimBTimer)
-               timer_remove(PSG->TimBTimer);
-
-       PSG->TimATimer = 0;
-       PSG->TimBTimer = 0;
-
-       if (v & 0x01) //LOAD A
-       {
-               PSG->TimA = 1;
-               PSG->TimAVal = TimerA[(PSG->Regs[YM_CLOCKA1] << 2) | PSG->Regs[YM_CLOCKA2]];
-               /* ASG 980324: added a real timer if we have a handler */
-
-               if (PSG->handler)
-                       PSG->TimATimer = timer_set(TimerATime[(PSG->Regs[YM_CLOCKA1] << 2) | PSG->Regs[YM_CLOCKA2]], n, timer_callback_a);
-       }
-       else
-               PSG->TimA = 0;
-
-       if (v & 0x02) //load B
-       {
-               PSG->TimB = 1;
-               PSG->TimBVal = TimerB[PSG->Regs[YM_CLOCKB]];
-
-               /* ASG 980324: added a real timer if we have a handler */
-               if (PSG->handler)
-                       PSG->TimBTimer = timer_set (TimerBTime[PSG->Regs[YM_CLOCKB]], n, timer_callback_b);
-       }
-       else
-               PSG->TimB = 0;
-
-       if (v & 0x04) //IRQEN A
-       {}
-
-       if (v & 0x08) //IRQEN B
-       {}
-
-       if (v & 0x10) //FRESET A
-       {
-               PSG->TimIRQ &= 0xFE;
-       }
-
-       if (v & 0x20) //FRESET B
-       {
-               PSG->TimIRQ &= 0xFD;
-       }
-}
-
-
-void write_YM_CT1_CT2_W(uint8_t n, uint8_t r, uint8_t v)
-{
-       YMPSG[n].Regs[r] = v;
-}
-
-
-void write_YM_CONNECT_BASE(uint8_t n, uint8_t r, uint8_t v)
-{
-       // NOTE: L/R Channel enables are ignored! This emu is mono!
-       YM2151 * PSG = &(YMPSG[n]);
-
-       //PSG->Regs[r] = v;
-       uint8_t chan = r - YM_CONNECT_BASE;
-
-       PSG->ConnectTab[chan] = v & 7; /*connection number*/
-       PSG->FeedBack[chan] = FEED[(v >> 3) & 7];
-}
-
-
-void write_YM_KC_BASE(uint8_t n, uint8_t r, uint8_t v)
-{
-       YMPSG[n].KC[r - YM_KC_BASE] = v;
-       //freq_calc(chan,PSG);
-}
-
-
-void write_YM_KF_BASE(uint8_t n, uint8_t r, uint8_t v)
-{
-       YMPSG[n].KF[r - YM_KF_BASE] = v >> 2;
-       //freq_calc(chan,PSG);
-}
-
-
-void write_YM_PMS_AMS_BASE(uint8_t n, uint8_t r, uint8_t v)
-{
-//     uint8_t chan, i;
-       YM2151 * PSG = &(YMPSG[n]);
-       PSG->Regs[r] = v;
-       uint8_t chan = r - YM_PMS_AMS_BASE;
-
-       PMTab[chan] = v >> 4;  //PMS;
-
-//     if (i && errorlog)
-//             fprintf(errorlog,"PMS CHN %02x =%02x\n", chan, i);
-
-       AMTab[chan] = v & 0x03; //AMS;
-
-//     if (i && errorlog)
-//             fprintf(errorlog,"AMS CHN %02x =%02x\n", chan, i);
-
-}
-
-
-void write_YM_DT1_MUL_BASE(uint8_t n, uint8_t r, uint8_t v)
-{
-       YMPSG[n].Regs[r] = v;
-       //freq_calc(chan,PSG);
-}
-
-
-void write_YM_TL_BASE(uint8_t n, uint8_t r, uint8_t v)
-{
-       v &= 0x7F;
-       YMPSG[n].Oscils[r - YM_TL_BASE].TL =  v << (ENV_BITS - 7); /*7bit TL*/
-}
-
-
-void write_YM_KS_AR_BASE(uint8_t n, uint8_t r, uint8_t v)
-{
-       uint8_t op;
-       YM2151 * PSG;
-
-       op = r - YM_KS_AR_BASE;
-       PSG = &(YMPSG[n]);
-
-       PSG->KS[op] = 3 - (v >> 6);
-       PSG->Oscils[op].AR = (v & 0x1F) << 1;
-}
-
-
-void write_YM_AMS_D1R_BASE(uint8_t n, uint8_t r, uint8_t v)
-{
-       uint8_t op = r - YM_AMS_D1R_BASE;
-
-       if ((v & 0x80) && errorlog)
-               fprintf(errorlog,"AMS ON oper%02x\n", op);
-
-       //HERE something to do with AMS;
-
-       YMPSG[n].Oscils[op].D1R = (v & 0x1F) << 1;
-}
-
-
-void write_YM_DT2_D2R_BASE(uint8_t n, uint8_t r, uint8_t v)
-{
-       YM2151 * PSG = &(YMPSG[n]);
-       OscilRec * osc = &PSG->Oscils[r - YM_DT2_D2R_BASE];
-       PSG->Regs[r] = v;
-
-       osc->D2R = (v & 0x1F) << 1;
-       //freq_calc(chan,PSG);
-}
-
-
-void write_YM_D1L_RR_BASE(uint8_t n, uint8_t r, uint8_t v)
-{
-    OscilRec * osc = &YMPSG[n].Oscils[r - YM_D1L_RR_BASE];
-
-       osc->D1L = decib45[(v >> 4) & 0x0F];
-       osc->RR = ((v & 0x0F) << 2) | 0x02;
-}
-
-
-/*
-** Initialize YM2151 emulator(s).
-**
-** 'num' is the number of virtual YM2151's to allocate
-** 'clock' is the chip clock
-** 'rate' is sampling rate and 'bufsiz' is the size of the
-** buffer that should be updated at each interval
-*/
-int YMInit(int num, int clock, int rate, int sample_bits, int bufsiz)//, SAMPLE ** buffer)
-{
-       int i;
-
-       if (YMPSG)
-               return (-1);    /* duplicate init. */
-
-       YMNumChips = num;
-       YM2151_SAMPFREQ = rate;
-
-#if 0
-       if (sample_bits == 16)
-               sample_16bit = 1;
-       else
-               sample_16bit = 0;
-#endif
-
-       YM2151_CLOCK = clock;
-       YMBufSize = bufsiz;
-
-       envelope_calc[0] = envelope_attack;
-       envelope_calc[1] = envelope_decay;
-       envelope_calc[2] = envelope_sustain;
-       envelope_calc[3] = envelope_release;
-       envelope_calc[4] = envelope_nothing;
-
-       for(i=0; i<256; i++)
-               register_writes[i] = write_YM_NON_EMULATED;
-
-       register_writes[YM_KON] = write_YM_KON;
-       register_writes[YM_CLOCKA1] = write_YM_CLOCKA1;
-       register_writes[YM_CLOCKA2] = write_YM_CLOCKA2;
-       register_writes[YM_CLOCKB] = write_YM_CLOCKB;
-       register_writes[YM_CLOCKSET] = write_YM_CLOCKSET;
-       register_writes[YM_CT1_CT2_W] = write_YM_CT1_CT2_W;
-
-       for(i=YM_CONNECT_BASE; i<YM_CONNECT_BASE+8; i++)
-               register_writes[i] = write_YM_CONNECT_BASE;
-
-       for(i=YM_KC_BASE; i<YM_KC_BASE+8; i++)
-               register_writes[i] = write_YM_KC_BASE;
-
-       for(i=YM_KF_BASE; i<YM_KF_BASE+8; i++)
-               register_writes[i] = write_YM_KF_BASE;
-
-       for(i=YM_PMS_AMS_BASE; i<YM_PMS_AMS_BASE+8; i++)
-               register_writes[i] = write_YM_PMS_AMS_BASE;
-
-       for(i=YM_DT1_MUL_BASE; i<YM_DT1_MUL_BASE+32; i++)
-               register_writes[i] = write_YM_DT1_MUL_BASE;
-
-       for(i=YM_TL_BASE; i<YM_TL_BASE+32; i++)
-               register_writes[i] = write_YM_TL_BASE;
-
-       for(i=YM_KS_AR_BASE; i<YM_KS_AR_BASE+32; i++)
-               register_writes[i] = write_YM_KS_AR_BASE;
-
-       for(i=YM_AMS_D1R_BASE; i<YM_AMS_D1R_BASE+32; i++)
-               register_writes[i] = write_YM_AMS_D1R_BASE;
-
-       for(i=YM_DT2_D2R_BASE; i<YM_DT2_D2R_BASE+32; i++)
-               register_writes[i] = write_YM_DT2_D2R_BASE;
-
-       for(i=YM_D1L_RR_BASE; i<YM_D1L_RR_BASE+32; i++)
-               register_writes[i] = write_YM_D1L_RR_BASE;
-
-       YMPSG = (YM2151 *)malloc(sizeof(YM2151) * YMNumChips);
-
-       if (YMPSG == NULL)
-               return (1);
-
-       TL_TAB = (signed int *)malloc(sizeof(signed int) * TL_TAB_LEN);
-
-       if (TL_TAB == NULL)
-               return (1);
-
-//     BuffTemp = (signed int *)malloc(sizeof(signed int) * YMBufSize);
-       // 16K ought to be enough for anybody
-       BuffTemp = (signed int *)malloc(sizeof(signed int) * 16384);
-
-       if (BuffTemp == NULL)
-               return (1);
-
-       hertz();
-       sin_init();
-
-       for(i=0; i<YMNumChips; i++)
-       {
-               YMPSG[i].Buf = 0;//buffer[i];
-               YMPSG[i].bufp = 0;
-               YMResetChip(i);
-       }
-
-       return 0;
-}
-
-
-void YMShutdown()
-{
-       if (!YMPSG)
-               return;
-
-       free(YMPSG);
-       YMPSG = NULL;
-
-       if (TL_TAB)
-       {
-               free(TL_TAB);
-               TL_TAB = NULL;
-       }
-
-       if (BuffTemp)
-       {
-               free(BuffTemp);
-               BuffTemp = NULL;
-       }
-
-       YM2151_SAMPFREQ = YMBufSize = 0;
-
-#ifdef SAVE_SAMPLE
-#ifdef SAVE_SEPARATE_CHANNELS
-fclose(sample1);
-fclose(sample2);
-fclose(sample3);
-fclose(sample4);
-fclose(sample5);
-fclose(sample6);
-#endif
-fclose(samplesum);
-#endif
-}
-
-
-/* write a register on YM2151 chip number 'n' */
-void YMWriteReg(int n, int r, int v)
-{
-       register_writes[(uint8_t)r]((uint8_t)n, (uint8_t)r, (uint8_t)v);
-}
-
-
-uint8_t YMReadReg(uint8_t n)
-{
-       return YMPSG[n].TimIRQ;
-}
-
-
-/*
-** reset all chip registers.
-*/
-void YMResetChip(int num)
-{
-       int i;
-       YM2151 * PSG = &(YMPSG[num]);
-
-       memset(PSG->Buf, '\0', YMBufSize);
-
-       /* ASG 980324 -- reset the timers before writing to the registers */
-       PSG->TimATimer = 0;
-       PSG->TimBTimer = 0;
-
-       /* initialize hardware registers */
-       for(i=0; i<256; i++)
-               PSG->Regs[i] = 0;
-
-       for(i=0; i<32; i++)
-       {
-               memset(&PSG->Oscils[i], '\0', sizeof(OscilRec));
-               PSG->Oscils[i].volume = VOLUME_OFF;
-               PSG->Oscils[i].state = 4;  //envelope off
-       }
-
-       for(i=0; i<8; i++)
-       {
-               PSG->ConnectTab[i] = 0;
-               PSG->FeedBack[i] = 0;
-       }
-
-       PSG->TimA = 0;
-       PSG->TimB = 0;
-       PSG->TimAVal = 0;
-       PSG->TimBVal = 0;
-       PSG->TimIRQ = 0;
-}
-
-
-static inline signed int op_calc(OscilRec * OP, signed int pm)
-{
-       return sin_tab[(((OP->phase += OP->freq) >> FREQ_SH) + (pm)) & SIN_MASK]
-               [OP->TL + (OP->volume >> ENV_SH)];
-}
-
-
-//void YM2151UpdateOne(int num, int endp)
-void YM2151UpdateOne(void * BUF, int endp)
-{
-//    YM2151 * PSG = &(YMPSG[num]);
-       YM2151 * PSG = &(YMPSG[0]);
-       PSG->bufp = 0;
-//    SAMPLE * BUF;
-       signed int * PSGBUF;
-       OscilRec * OP0, * OP1, * OP2, * OP3;
-       uint16_t i;
-       signed int k, wy;
-#ifdef SAVE_SEPARATE_CHANNELS
-       signed int pom;
-#endif
-
-       refresh_chip(PSG);
-
-       //calculate timers...
-       if (PSG->TimA)
-       {
-               PSG->TimAVal -= ((endp - PSG->bufp) << TIMER_SH);
-
-               if (PSG->TimAVal <= 0)
-               {
-                       PSG->TimA = 0;
-                       PSG->TimIRQ |= 1;
-                       /* ASG 980324 - handled by real timers now
-                       if (PSG->handler !=0) PSG->handler();*/
-               }
-       }
-
-       if (PSG->TimB)
-       {
-               PSG->TimBVal -= ((endp - PSG->bufp) << TIMER_SH);
-
-               if (PSG->TimBVal <= 0)
-               {
-                       PSG->TimB = 0;
-                       PSG->TimIRQ |= 2;
-                       /* ASG 980324 - handled by real timers now
-                       if (PSG->handler !=0) PSG->handler();*/
-               }
-       }
-
-       OP0 = &PSG->Oscils[0     ];
-       OP1 = &PSG->Oscils[0 +  8];
-       OP2 = &PSG->Oscils[0 + 16];
-       OP3 = &PSG->Oscils[0 + 24];
-
-       for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
-       {
-               //chan0
-               envelope_calc[OP0->state](OP0);
-               envelope_calc[OP1->state](OP1);
-               envelope_calc[OP2->state](OP2);
-               envelope_calc[OP3->state](OP3);
-
-               wy = op_calc(OP0, OP0->OscilFB);
-
-               if (PSG->FeedBack[0])
-                       OP0->OscilFB = wy >> PSG->FeedBack[0];
-               else
-                       OP0->OscilFB = 0;
-
-               switch(PSG->ConnectTab[0])
-               {
-               case 0: *(PSGBUF) = op_calc(OP3, op_calc(OP1, op_calc(OP2, wy))); break;
-               case 1: *(PSGBUF) = op_calc(OP3, op_calc(OP1, op_calc(OP2, 0) + wy)); break;
-               case 2: *(PSGBUF) = op_calc(OP3, op_calc(OP1, op_calc(OP2, 0)) + wy); break;
-               case 3: *(PSGBUF) = op_calc(OP3, op_calc(OP2, wy) + op_calc(OP1, 0)); break;
-               case 4: *(PSGBUF) = op_calc(OP2, wy) + op_calc(OP3, op_calc(OP1, 0)); break;
-               case 5: *(PSGBUF) = op_calc(OP2, wy) + op_calc(OP1, wy) + op_calc(OP3, wy); break;
-               case 6: *(PSGBUF) = op_calc(OP2, wy) + op_calc(OP1, 0) + op_calc(OP3, 0); break;
-               default: *(PSGBUF) = wy + op_calc(OP2, 0) + op_calc(OP1, 0) + op_calc(OP3, 0); break;
-               }
-#ifdef SAVE_SEPARATE_CHANNELS
-fputc((uint16_t)(*PSGBUF) & 0xFF, sample1);
-fputc(((uint16_t)(*PSGBUF) >> 8) & 0xFF, sample1);
-#endif
-       }
-
-       //chan1
-       OP0 = &PSG->Oscils[1     ];
-       OP1 = &PSG->Oscils[1 +  8];
-       OP2 = &PSG->Oscils[1 + 16];
-       OP3 = &PSG->Oscils[1 + 24];
-
-       for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
-       {
-               envelope_calc[OP0->state](OP0);
-               envelope_calc[OP1->state](OP1);
-               envelope_calc[OP2->state](OP2);
-               envelope_calc[OP3->state](OP3);
-
-               wy = op_calc(OP0, OP0->OscilFB);
-
-               if (PSG->FeedBack[1])
-                               OP0->OscilFB = wy >> PSG->FeedBack[1];
-               else
-                               OP0->OscilFB = 0;
-
-#ifdef SAVE_SEPARATE_CHANNELS
-pom = *(PSGBUF);
-#endif
-               switch(PSG->ConnectTab[1])
-               {
-               case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
-               case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
-               case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
-               case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
-               case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
-               case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
-               case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
-               default: *(PSGBUF) += wy + op_calc(OP2, 0) + op_calc(OP1, 0) + op_calc(OP3, 0); break;
-               }
-
-#ifdef SAVE_SEPARATE_CHANNELS
-fputc((uint16_t)((*PSGBUF)-pom)&0xff,sample2);
-fputc(((uint16_t)((*PSGBUF)-pom)>>8)&0xff,sample2);
-#endif
-       }
-
-//chan2
-       OP0 = &PSG->Oscils[2     ];
-       OP1 = &PSG->Oscils[2 +  8];
-       OP2 = &PSG->Oscils[2 + 16];
-       OP3 = &PSG->Oscils[2 + 24];
-
-for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
-{
-       envelope_calc[OP0->state](OP0);
-       envelope_calc[OP1->state](OP1);
-       envelope_calc[OP2->state](OP2);
-       envelope_calc[OP3->state](OP3);
-
-       wy = op_calc(OP0, OP0->OscilFB);
-       if (PSG->FeedBack[2])
-                       OP0->OscilFB = wy >> PSG->FeedBack[2];
-       else
-                       OP0->OscilFB = 0;
-
-#ifdef SAVE_SEPARATE_CHANNELS
-       pom=*(PSGBUF);
-#endif
-       switch(PSG->ConnectTab[2])
-       {
-       case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
-       case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
-       case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
-       case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
-       case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
-       case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
-       case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
-       default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
-       }
-#ifdef SAVE_SEPARATE_CHANNELS
-fputc((uint16_t)((*PSGBUF)-pom)&0xff,sample3);
-fputc(((uint16_t)((*PSGBUF)-pom)>>8)&0xff,sample3);
-#endif
-}
-
-//chan3
-       OP0 = &PSG->Oscils[3     ];
-       OP1 = &PSG->Oscils[3 +  8];
-       OP2 = &PSG->Oscils[3 + 16];
-       OP3 = &PSG->Oscils[3 + 24];
-
-for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
-{
-       envelope_calc[OP0->state](OP0);
-       envelope_calc[OP1->state](OP1);
-       envelope_calc[OP2->state](OP2);
-       envelope_calc[OP3->state](OP3);
-
-       wy = op_calc(OP0, OP0->OscilFB);
-       if (PSG->FeedBack[3])
-                       OP0->OscilFB = wy >> PSG->FeedBack[3];
-       else
-                       OP0->OscilFB = 0;
-
-#ifdef SAVE_SEPARATE_CHANNELS
-       pom=*(PSGBUF);
-#endif
-       switch(PSG->ConnectTab[3])
-       {
-       case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
-       case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
-       case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
-       case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
-       case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
-       case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
-       case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
-       default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
-       }
-#ifdef SAVE_SEPARATE_CHANNELS
-fputc((uint16_t)((*PSGBUF)-pom)&0xff,sample4);
-fputc(((uint16_t)((*PSGBUF)-pom)>>8)&0xff,sample4);
-#endif
-}
-
-       //chan4
-       OP0 = &PSG->Oscils[4     ];
-       OP1 = &PSG->Oscils[4 +  8];
-       OP2 = &PSG->Oscils[4 + 16];
-       OP3 = &PSG->Oscils[4 + 24];
-
-       for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
-       {
-               envelope_calc[OP0->state](OP0);
-               envelope_calc[OP1->state](OP1);
-               envelope_calc[OP2->state](OP2);
-               envelope_calc[OP3->state](OP3);
-
-               wy = op_calc(OP0, OP0->OscilFB);
-
-               if (PSG->FeedBack[4])
-                       OP0->OscilFB = wy >> PSG->FeedBack[4];
-               else
-                       OP0->OscilFB = 0;
-
-       #ifdef SAVE_SEPARATE_CHANNELS
-               pom = *(PSGBUF);
-       #endif
-
-               switch(PSG->ConnectTab[4])
-               {
-               case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
-               case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
-               case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
-               case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
-               case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
-               case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
-               case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
-               default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
-               }
-
-#ifdef SAVE_SEPARATE_CHANNELS
-fputc((uint16_t)((*PSGBUF)-pom)&0xff,sample5);
-fputc(((uint16_t)((*PSGBUF)-pom)>>8)&0xff,sample5);
-#endif
-       }
-
-       //chan5
-       OP0 = &PSG->Oscils[5     ];
-       OP1 = &PSG->Oscils[5 +  8];
-       OP2 = &PSG->Oscils[5 + 16];
-       OP3 = &PSG->Oscils[5 + 24];
-
-for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
-{
-       envelope_calc[OP0->state](OP0);
-       envelope_calc[OP1->state](OP1);
-       envelope_calc[OP2->state](OP2);
-       envelope_calc[OP3->state](OP3);
-
-       wy = op_calc(OP0, OP0->OscilFB);
-       if (PSG->FeedBack[5])
-                       OP0->OscilFB = wy >> PSG->FeedBack[5];
-       else
-                       OP0->OscilFB = 0;
-
-#ifdef SAVE_SEPARATE_CHANNELS
-       pom=*(PSGBUF);
-#endif
-       switch(PSG->ConnectTab[5])
-       {
-       case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
-       case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
-       case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
-       case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
-       case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
-       case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
-       case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
-       default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
-       }
-#ifdef SAVE_SEPARATE_CHANNELS
-fputc((uint16_t)((*PSGBUF)-pom)&0xff,sample6);
-fputc(((uint16_t)((*PSGBUF)-pom)>>8)&0xff,sample6);
-#endif
-}
-
-//chan6
-       OP0 = &PSG->Oscils[6     ];
-       OP1 = &PSG->Oscils[6 +  8];
-       OP2 = &PSG->Oscils[6 + 16];
-       OP3 = &PSG->Oscils[6 + 24];
-
-for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
-{
-       envelope_calc[OP0->state](OP0);
-       envelope_calc[OP1->state](OP1);
-       envelope_calc[OP2->state](OP2);
-       envelope_calc[OP3->state](OP3);
-
-       wy = op_calc(OP0, OP0->OscilFB);
-       if (PSG->FeedBack[6])
-                       OP0->OscilFB = wy >> PSG->FeedBack[6];
-       else
-                       OP0->OscilFB = 0;
-
-       switch(PSG->ConnectTab[6])
-       {
-       case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
-       case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
-       case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
-       case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
-       case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
-       case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
-       case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
-       default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
-       }
-}
-
-       //chan7
-       OP0 = &PSG->Oscils[7     ];
-       OP1 = &PSG->Oscils[7 +  8];
-       OP2 = &PSG->Oscils[7 + 16];
-       OP3 = &PSG->Oscils[7 + 24];
-
-       for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
-       {
-               envelope_calc[OP0->state](OP0);
-               envelope_calc[OP1->state](OP1);
-               envelope_calc[OP2->state](OP2);
-               envelope_calc[OP3->state](OP3);
-
-               wy = op_calc(OP0, OP0->OscilFB);
-
-               if (PSG->FeedBack[7])
-                       OP0->OscilFB = wy >> PSG->FeedBack[7];
-               else
-                       OP0->OscilFB = 0;
-
-               switch(PSG->ConnectTab[7])
-               {
-               case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
-               case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
-               case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
-               case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
-               case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
-               case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
-               case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
-               default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
-               }
-       }
-
-//     BUF = PSG->Buf;
-       PSGBUF = &BuffTemp[PSG->bufp];
-
-       for(i=PSG->bufp; i<endp; i++)
-       {
-               k = *(PSGBUF++);
-
-#ifdef SAVE_SAMPLE
-fputc((uint16_t)(-k) & 0xFF, samplesum);
-fputc(((uint16_t)(-k) >> 8) & 0xFF, samplesum);
-#endif
-
-//             if (sample_16bit)
-               {
-                       /*16 bit mode*/
-                       k >>= FINAL_SH16;  //AUDIO_CONV
-                       k <<= 2;
-
-                       if (k > 32767)
-                               k = 32767;
-                       else if (k < -32768)
-                               k = -32768;
-
-                       ((uint16_t *)BUF)[i] = (uint16_t)k;
-               }
-#if 0
-               else
-               {
-                       /*8 bit mode*/
-                       k >>= FINAL_SH8;  //AUDIO_CONV
-
-                       if (k > 127)
-                               k = 127;
-                       else if (k < -128)
-                               k = -128;
-
-                       ((uint8_t *)BUF)[i] = (uint8_t)k;
-               }
-#endif
-       }
-
-       PSG->bufp = endp;
-}
-
-
-/*
-** called to update all chips
-*/
-void YM2151Update(void)
-{
-       int i;
-       for(i=0; i<YMNumChips; i++)
-       {
-               if (YMPSG[i].bufp < YMBufSize)
-;//                    YM2151UpdateOne(i, YMBufSize);
-
-               YMPSG[i].bufp = 0;
-       }
-}
-
-
-/*
-** return the buffer into which YM2151Update() has just written it's sample
-** data
-*/
-SAMPLE * YMBuffer(int n)
-{
-       return YMPSG[n].Buf;
-}
-
-
-void YMSetIrqHandler(int n, void(* handler)(void))
-{
-       YMPSG[n].handler = handler;
-}
-
index cb5f077a8e433e6064701cc26b8b16945be83552..06b330d547f8f2f075ba44cec07336e3d36075a8 100644 (file)
@@ -117,7 +117,7 @@ typedef struct ym2151_f {
 ** 'rate' is sampling rate and 'bufsiz' is the size of the
 ** buffer that should be updated at each interval
 */
-int YMInit(int num, int clock, int rate, int sample_bits, int bufsiz);//, SAMPLE ** buffer);
+int YMInit(int num, int clock, int rate, int sample_bits, int bufsiz); //, SAMPLE ** buffer);
 
 /*
 ** shutdown the YM2151 emulators ...