Ejemplo n.º 1
0
		public void okim6295_write_rom(byte ChipID, int ROMSize, int DataStart, int DataLength, byte[] ROMData)
		{
			okim6295_state chip = OKIM6295Data[ChipID];

			if (chip.ROMSize != ROMSize)
			{
				chip.ROM = new byte[ROMSize];// (byte*)realloc(chip.ROM, ROMSize);
				chip.ROMSize = (uint)ROMSize;
				//printf("OKIM6295: New ROM Size: 0x%05X\n", ROMSize);
				//memset(chip->ROM, 0xFF, ROMSize);
				for (int i = 0; i < ROMSize; i++)
				{
					chip.ROM[i] = 0xff;
				}
			}
			if (DataStart > ROMSize)
				return;
			if (DataStart + DataLength > ROMSize)
				DataLength = ROMSize - DataStart;

			//memcpy(chip->ROM + DataStart, ROMData, DataLength);
			for (int i = 0; i < DataLength; i++)
			{
				chip.ROM[i + DataStart] = ROMData[i];
			}

			return;
		}
Ejemplo n.º 2
0
		public void okim6295_write_rom2(byte ChipID, int ROMSize, int DataStart, int DataLength, byte[] ROMData,uint srcStartAddr)
		{
			//System.Console.Write("OKIM6295:okim6295_write_rom2: ChipID:{0} ROMSize:{1:X} DataStart:{2:X} DataLength:{3:X} srcStartAddr:{4:X}\n", ChipID, ROMSize, DataStart, DataLength, srcStartAddr);

			okim6295_state chip = OKIM6295Data[ChipID];

			if (chip.ROMSize != ROMSize)
			{
				chip.ROM = new byte[ROMSize];// (byte*)realloc(chip.ROM, ROMSize);
				chip.ROMSize = (uint)ROMSize;
				//printf("OKIM6295: New ROM Size: 0x%05X\n", ROMSize);
				//memset(chip->ROM, 0xFF, ROMSize);
				for (int i = 0; i < ROMSize; i++)
				{
					chip.ROM[i] = 0xff;
				}
			}
			if (DataStart > ROMSize)
				return;
			if (DataStart + DataLength > ROMSize)
				DataLength = ROMSize - DataStart;

			//memcpy(chip->ROM + DataStart, ROMData, DataLength);
			for (int i = 0; i < DataLength; i++)
			{
				chip.ROM[i + DataStart] = ROMData[i + srcStartAddr];

				//Console.Write("{0:X02} ", chip.ROM[i + DataStart]);
			}

			return;
		}
Ejemplo n.º 3
0
        private static byte memory_raw_read_byte(okim6295_state chip, int offset)
		{
			int CurOfs;

			if (chip.nmk_mode==0)
			{
				CurOfs = chip.bank_offs | offset;
			}
			else
			{
				byte BankID;

				if (offset < NMK_TABLESIZE && (chip.nmk_mode & 0x80)!=0)
				{
					// pages sample table
					BankID = (byte)(offset >> (int)NMK_BNKTBLBITS);
					CurOfs = (int)(offset & NMK_TABLEMASK);    // 0x3FF, not 0xFF
				}
				else
				{
					BankID = (byte)(offset >> (int)NMK_BANKBITS);
					CurOfs = (int)(offset & NMK_BANKMASK);
				}
				CurOfs |= (chip.nmk_bank[BankID & 0x03] << (int)NMK_BANKBITS);
				// I modified MAME to write a clean sample ROM.
				// (Usually it moves the data by NMK_ROMBASE.)
				//CurOfs += NMK_ROMBASE;
			}
			if (CurOfs < chip.ROMSize)
				return chip.ROM[CurOfs];
			else
				return 0x00;
		}
Ejemplo n.º 4
0
		/**********************************************************************************************

			 DEVICE_RESET( okim6295 ) -- stop emulation of an OKIM6295-compatible chip

		***********************************************************************************************/

		//static DEVICE_RESET( okim6295 )
		private void device_reset_okim6295(byte ChipID)
		{
			//okim6295_state *info = get_safe_token(device);
			okim6295_state info = OKIM6295Data[ChipID];
			int voice;

			//stream_update(info->stream);

			info.command = -1;
			info.bank_offs = 0;
			info.nmk_mode = 0x00;
			//memset(info->nmk_bank, 0x00, 4 * sizeof(UINT8));
			for (int i = 0; i < 4; i++)
			{
				info.nmk_bank[i] = 0x00;
			}
			info.master_clock = info.initial_clock & 0x7FFFFFFF;
			infos[ChipID].masterClock = info.master_clock;
			info.pin7_state = (byte)((info.initial_clock & 0x80000000) >> 31);
			infos[ChipID].pin7State = (byte)((info.initial_clock & 0x80000000) >> 31);

			for (voice = 0; voice < okim6295_state.OKIM6295_VOICES; voice++)
			{
				info.voice[voice].volume = 0;
				reset_adpcm(info.voice[voice].adpcm);

				info.voice[voice].playing = 0;
			}
		}
Ejemplo n.º 5
0
		/**********************************************************************************************

			 okim6295_set_pin7 -- adjust pin 7, which controls the internal clock division

		***********************************************************************************************/

		private static void okim6295_clock_changed(okim6295_state info)
		{
			int divisor;
			divisor = info.pin7_state != 0 ? 132 : 165;
            //stream_set_sample_rate(info->stream, info->master_clock/divisor);
            info.SmpRateFunc?.Invoke(info.SmpRateData, (int)info.master_clock / divisor);

        }
Ejemplo n.º 6
0
		private void device_stop_okim6295(byte ChipID)
		{
			okim6295_state chip = OKIM6295Data[ChipID];

			chip.ROM = null;
			chip.ROMSize = 0x00;

			return;
		}
Ejemplo n.º 7
0
        //void okim6295_set_pin7(running_device *device, int pin7)
        private static void okim6295_set_pin7(okim6295_state info, int pin7)
        {
            //okim6295_state *info = get_safe_token(device);
            //int divisor = pin7 ? 132 : 165;

            info.pin7_state = (byte)pin7;
            //stream_set_sample_rate(info->stream, info->master_clock/divisor);
            okim6295_clock_changed(info);
        }
Ejemplo n.º 8
0
        public void okim6295_set_srchg_cb(byte ChipID, dlgSRATE_CALLBACK CallbackFunc, MDSound.Chip DataPtr)
        {
            okim6295_state info = OKIM6295Data[ChipID];

            // set Sample Rate Change Callback routine
            info.SmpRateFunc = CallbackFunc;
            info.SmpRateData = DataPtr;

            return;
        }
Ejemplo n.º 9
0
		public void okim6295_set_mute_mask(byte ChipID, uint MuteMask)
		{
			okim6295_state chip = OKIM6295Data[ChipID];
			byte CurChn;

			for (CurChn = 0; CurChn < okim6295_state.OKIM6295_VOICES; CurChn++)
				chip.voice[CurChn].Muted = (byte)((MuteMask >> CurChn) & 0x01);

			return;
		}
Ejemplo n.º 10
0
		/**********************************************************************************************
		 *
		 *  OKIM 6295 ADPCM chip:
		 *
		 *  Command bytes are sent:
		 *
		 *      1xxx xxxx = start of 2-byte command sequence, xxxxxxx is the sample number to trigger
		 *      abcd vvvv = second half of command; one of the abcd bits is set to indicate which voice
		 *                  the v bits seem to be volumed
		 *
		 *      0abc d000 = stop playing; one or more of the abcd bits is set to indicate which voice(s)
		 *
		 *  Status is read:
		 *
		 *      ???? abcd = one bit per voice, set to 0 if nothing is playing, or 1 if it is active
		 *
		***********************************************************************************************/


		/**********************************************************************************************

			 okim6295_update -- update the sound chip so that it is in sync with CPU execution

		***********************************************************************************************/

		//static STREAM_UPDATE( okim6295_update )
		private void okim6295_update(byte ChipID, int[][] outputs, int samples)
		{
			//System.Console.Write("samples:{0}\n"        , samples);
			//okim6295_state *chip = (okim6295_state *)param;
			okim6295_state chip = OKIM6295Data[ChipID];
			int i;

			//memset(outputs[0], 0, samples * sizeof(*outputs[0]));
			for (i = 0; i < samples; i++)
			{
				outputs[0][i] = 0;
			}

			for (i = 0; i < okim6295_state.OKIM6295_VOICES; i++)
			//    for (i = 0; i < 1; i++)
			{
				ADPCMVoice voice = chip.voice[i];
				infos[ChipID].chInfo[i].mask = voice.Muted == 0;
				if (voice.Muted == 0)
				{
					int[][] buffer = outputs;
					int ptrBuffer = 0;
					short[] sample_data = new short[MAX_SAMPLE_CHUNK];
					int remaining = samples;

					/* loop while we have samples remaining */
					while (remaining != 0)
					{
						int Samples = (remaining > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : remaining;
						int samp;

						generate_adpcm(chip, voice, sample_data, Samples);
						for (samp = 0; samp < Samples; samp++)
						{
							buffer[0][ptrBuffer++] += sample_data[samp];
                            //if (sample_data[samp] != 0)
                            //{
                            //    System.Console.WriteLine("ch:{0} sampledata[{1}]={2} count:{3} sample:{4}"
                            //    , i, samp, sample_data[samp]
                            //    , voice.count, voice.sample);
                            //}
                        }

                        remaining -= samples;
					}
                }
            }

			//memcpy(outputs[1], outputs[0], samples * sizeof(*outputs[0]));
			for (i = 0; i < samples; i++)
			{
				outputs[1][i] = outputs[0][i];
            }

        }
Ejemplo n.º 11
0
        private void okim6295_w(byte ChipID, int offset, byte data)
        {
            okim6295_state chip = OKIM6295Data[ChipID];

            switch (offset)
            {
            case 0x00:
                okim6295_write_command(chip, data);
                break;

            case 0x08:
                chip.master_clock &= ~((uint)0x000000FF);
                chip.master_clock |= (uint)(data << 0);
                break;

            case 0x09:
                chip.master_clock &= ~((uint)0x0000FF00);
                chip.master_clock |= (uint)(data << 8);
                break;

            case 0x0A:
                chip.master_clock &= ~((uint)0x00FF0000);
                chip.master_clock |= (uint)(data << 16);
                break;

            case 0x0B:
                data &= 0x7F;
                chip.master_clock &= ~((uint)0xFF000000);
                chip.master_clock |= (uint)(data << 24);
                okim6295_clock_changed(chip);
                break;

            case 0x0C:
                okim6295_set_pin7(chip, data);
                break;

            case 0x0E:                      // NMK112 bank switch enable
                chip.nmk_mode = data;
                break;

            case 0x0F:
                okim6295_set_bank_base(chip, data << 18);
                break;

            case 0x10:
            case 0x11:
            case 0x12:
            case 0x13:
                chip.nmk_bank[offset & 0x03] = data;
                break;
            }

            return;
        }
Ejemplo n.º 12
0
		private void generate_adpcm(okim6295_state chip, ADPCMVoice voice, short[] buffer, int samples)
		{
			int ptrBuffer = 0;

			/* if this voice is active */
			if (voice.playing != 0)
			{
				//System.Console.Write("base_offset[{0:X}] sample[{1:X}] count[{2:X}]\n", voice.base_offset, voice.sample, voice.count);
				int iBase = (int)voice.base_offset;
				int sample = (int)voice.sample;
				int count = (int)voice.count;

				/* loop while we still have samples to generate */
				while (samples != 0)
				{
					/* compute the new amplitude and update the current step */
					//int nibble = memory_raw_read_byte(chip->device->space(), base + sample / 2) >> (((sample & 1) << 2) ^ 4);
					//System.Console.Write("nibblecal1[{0:d}]2[{1:d}]\n", iBase + sample / 2, (((sample & 1) << 2) ^ 4));
					byte nibble = (byte)(memory_raw_read_byte(chip, iBase + sample / 2) >> (((sample & 1) << 2) ^ 4));
					//System.Console.Write( "nibble[{0:X}]\n", nibble);

					/* output to the buffer, scaling by the volume */
					/* signal in range -2048..2047, volume in range 2..32 => signal * volume / 2 in range -32768..32767 */
					buffer[ptrBuffer++] = (short)(clock_adpcm(voice.adpcm, nibble) * voice.volume / 2);
					//System.Console.Write("*buffer[{0}]\n", buffer[ptrBuffer-1]);
					samples--;

					/* next! */
					if (++sample >= count)
					{
						voice.playing = 0;
						break;
					}
				}

				/* update the parameters */
				voice.sample = (uint)sample;
			}

			/* fill the rest with silence */
			while (samples-- != 0)
			{
				buffer[ptrBuffer++] = 0;
			}
		}
Ejemplo n.º 13
0
		/**********************************************************************************************

			 okim6295_status_r -- read the status port of an OKIM6295-compatible chip

		***********************************************************************************************/

		//READ8_DEVICE_HANDLER( okim6295_r )
		private byte okim6295_r(byte ChipID, int offset)
		{
			//okim6295_state *info = get_safe_token(device);
			okim6295_state info = OKIM6295Data[ChipID];
			int i, result;

			result = 0xf0;  /* naname expects bits 4-7 to be 1 */

			/* set the bit to 1 if something is playing on a given channel */
			//stream_update(info->stream);
			for (i = 0; i < okim6295_state.OKIM6295_VOICES; i++)
			{
				ADPCMVoice voice = info.voice[i];

				/* set the bit if it's playing */
				if (voice.playing != 0)
					result |= 1 << i;
			}

			return (byte)result;
		}
Ejemplo n.º 14
0
		/**********************************************************************************************

			 okim6295_set_bank_base -- set the base of the bank for a given voice on a given chip

		***********************************************************************************************/

		//void okim6295_set_bank_base(running_device *device, int base)
		private void okim6295_set_bank_base(okim6295_state info, int iBase)
		{
			//okim6295_state *info = get_safe_token(device);
			//stream_update(info->stream);

			/* if we are setting a non-zero base, and we have no bank, allocate one */
			//if (info.bank_installed == 0 && iBase != 0)
			//{
			/* override our memory map with a bank */
			//memory_install_read_bank(device->space(), 0x00000, 0x3ffff, 0, 0, device->tag());
			//info.bank_installed = 1;// TRUE;
			//}

			/* if we have a bank number, set the base pointer */
			//if (info.bank_installed != 0)
			//{
			//info.bank_offs = iBase;
			//memory_set_bankptr(device->machine, device->tag(), device->region->base.u8 + base);
			//}
			info.bank_offs = iBase;
		}
Ejemplo n.º 15
0
		/**********************************************************************************************

			 okim6295_data_w -- write to the data port of an OKIM6295-compatible chip

		***********************************************************************************************/

		//WRITE8_DEVICE_HANDLER( okim6295_w )
		private void okim6295_write_command(okim6295_state info, byte data,okim6295Info Info)
		{
			//okim6295_state *info = get_safe_token(device);

			/* if a command is pending, process the second half */
			if (info.command != -1)
			{
				int temp = data >> 4, i, start, stop;
				int iBase;

				/* the manual explicitly says that it's not possible to start multiple voices at the same time */
//				if (temp != 0 && temp != 1 && temp != 2 && temp != 4 && temp != 8)
//					System.Console.Write("OKI6295 start %x contact MAMEDEV\n", temp);

				/* update the stream */
				//stream_update(info->stream);

				/* determine which voice(s) (voice is set by a 1 bit in the upper 4 bits of the second byte) */
				for (i = 0; i < okim6295_state.OKIM6295_VOICES; i++, temp >>= 1)
				{
					if ((temp & 1) != 0)
					{
						ADPCMVoice voice = info.voice[i];

						/* determine the start/stop positions */
						iBase = info.command * 8;

						//start  = memory_raw_read_byte(device->space(), base + 0) << 16;
						start = memory_raw_read_byte(info, iBase + 0) << 16;
						start |= memory_raw_read_byte(info, iBase + 1) << 8;
						start |= memory_raw_read_byte(info, iBase + 2) << 0;
						start &= 0x3ffff;
						Info.chInfo[i].stAdr = start;

						stop = memory_raw_read_byte(info, iBase + 3) << 16;
						stop |= memory_raw_read_byte(info, iBase + 4) << 8;
						stop |= memory_raw_read_byte(info, iBase + 5) << 0;
						stop &= 0x3ffff;
						Info.chInfo[i].edAdr = stop;

						/* set up the voice to play this sample */
						if (start < stop)
						{
							if (voice.playing == 0) /* fixes Got-cha and Steel Force */
							{
								voice.playing = 1;
								voice.base_offset = (uint)start;
								voice.sample = 0;
								voice.count = (uint)(2 * (stop - start + 1));

								/* also reset the ADPCM parameters */
								reset_adpcm(voice.adpcm);
								voice.volume = (uint)volume_table[data & 0x0f];
								Info.keyon[i] = true;
							}
							else
							{
								//logerror("OKIM6295:'%s' requested to play sample %02x on non-stopped voice\n",device->tag(),info->command);
								// just displays warnings when seeking
								//logerror("OKIM6295: Voice %u requested to play sample %02x on non-stopped voice\n",i,info->command);
							}
						}
						/* invalid samples go here */
						else
						{
							//logerror("OKIM6295:'%s' requested to play invalid sample %02x\n",device->tag(),info->command);
							//System.Console.Write("OKIM6295: Voice {0}  requested to play invalid sample {1:X2} StartAddr {2:X} StopAdr {3:X} \n", i, info.command, start, stop);
							voice.playing = 0;
						}
					}
				}

				/* reset the command */
				info.command = -1;
			}

			/* if this is the start of a command, remember the sample number for next time */
			else if ((data & 0x80) != 0)
			{
				info.command = data & 0x7f;
			}

			/* otherwise, see if this is a silence command */
			else
			{
				int temp = data >> 3, i;

				/* update the stream, then turn it off */
				//stream_update(info->stream);

				/* determine which voice(s) (voice is set by a 1 bit in bits 3-6 of the command */
				for (i = 0; i < okim6295_state.OKIM6295_VOICES; i++, temp >>= 1)
				{
					if ((temp & 1) != 0)
					{
						ADPCMVoice voice = info.voice[i];

						voice.playing = 0;
					}
				}
			}
		}