********************************************* *NTSC delta modulation channel documentation* ********************************************* Brad Taylor (big_time_software@hotmail.com) 2nd release: February 19th, 2K3 All results were obtained by studying prior information available (from nestech 1.00, and postings on NESDev from miscellanious people), and through a series of experiments conducted by me. Results acquired by individuals prior to my reverse-engineering have been double checked, and final results have been confirmed. Credit is due to those individual(s) who contributed miscellanious information in regards to NES DMC hardware. Such individuals are: Goroh FluBBa Izumi Memblers Description ----------- The delta modulation channel (DMC) is a complex digital network of counters and registers used to produce analog sound. It's primary function is to play "samples" from memory, and have an internal counter connected to a digital to analog converter (DAC) updated accordingly. The channel is able to be assigned a pointer to a chunk of memory to be played. At timed intervals, the DMC will halt the 2A03 (NES's CPU) for *2 clock cycles to retrieve the sample to be played. This method of playback will be refered to here on as direct memory access (DMA). Another method of playback known as pulse code modulation (PCM) is available by the channel, which requires the constant updating of one of the DMC's memory-mapped registers. *: Goroh has quietly mentioned that a DMC DMA byte fetch phase takes 2 CPU clock cycles. However, I haven't confirmed this, and it is my belief that Nintendo would not design such a sloppy DMA unit; a 1 clock cycle DMA fetch would sound more logical. At best, this information should be taken with a grain of salt. Registers --------- The DMC has 5 registers assigned to it. They are as follows: $4010: play mode and DMA frequency $4011: delta counter $4012: play code's starting address $4013: length of play code $4015: DMC/IRQ status Note that $4015 is the only R/W register. All others are write only (attempt to read them will most likely result in a returned 040H, due to heavy capacitance on the NES's data bus). $4010 - Play mode and DMA frequency ----------------------------------- This register is used to control the frequency of the DMA fetches, and to control the playback mode. Bits ---- 6-7 this is the playback mode. 00 - play DMC sample until length counter reaches 0 (see $4013) x1 - loop the DMC sample (x = immaterial) 10 - play DMC sample until length counter reaches 0, then generate a CPU IRQ Looping (playback mode "x1") will have the chunk of memory played over and over, until the channel is disabled (via $4015). In this case, after the length counter reaches 0, it will be reloaded with the calculated length value of $4013. If playback mode "10" is chosen, an interrupt will be dispached when the length counter reaches 0 (after the sample is done playing). There are 2 ways to acknowledge the DMC's interrupt request upon recieving it. The first is a write to this register ($4010), with the MSB (bit 7) cleared (0). The second is any write to $4015 (see the $4015 register description for more details). If playback mode "00" is chosen, the sample plays until the length counter reaches 0. No interrupt is generated. 5-4 appear to be unused 3-0 this is the DMC frequency control. Valid values are from 0 - F. The value of this register determines how many CPU clocks to wait before the DMA will fetch another byte from memory. The # of clocks to wait -1 is initially loaded into an internal 12-bit down counter. The down counter is then decremented at the frequency of the CPU (1.79MHz). The channel fetches the next DMC sample byte when the count reaches 0, and then reloads the count. This process repeats until the channel is disabled by $4015, or when the length counter has reached 0 (if not in the looping playback mode). The exact number of CPU clock cycles is as follows: value CPU written clocks octave scale ------- ------ ------ ----- F 1B0 8 C E 240 7 G D 2A8 7 E C 350 7 C B 400 6 A A 470 6 G 9 500 6 F 8 5F0 6 D 7 6B0 6 C 6 710 5 B 5 7F0 5 A 4 8F0 5 G 3 A00 5 F 2 AA0 5 E 1 BE0 5 D 0 D60 5 C The octave and scale values shown represent the DMC DMA clock cycle rate equivelant. These values are merely shown for the music enthusiast programmer, who is more familiar with notes than clock cycles. Every fetched byte is loaded into a internal 8-bit shift register. The shift register is then clocked at 8x the DMA frequency (which means that the CPU clock count would be 1/8th that of the DMA clock count), or shifted at +3 the octave of the DMA (same scale). The data shifted out of the register is in serial form, and the least significant bit (LSB, or bit 0) of the fetched byte is the first one to be shifted out (then bit 1, bit 2, etc.). The bits shifted out are then fed to the UP/DOWN control pin of the internal delta counter, which will effectively have the counter increment it's retained value by one on "1" bit samples, and decrement it's value by one on "0" bit samples. This counter is clocked at the same frequency of the shift register's. The counter is only 6 bits in size, and has it's 6 outputs tied to the 6 MSB inputs of a 7 bit DAC. The analog output of the DAC is then what you hear being played by the DMC. Wrap around counting is not allowed on this counter. Instead, a "clipping" behaviour is exhibited. If the internal value of the counter has reached 0, and the next bit sample is a 0 (instructing a decrement), the counter will take no action. Likewise, if the counter's value is currently at -1 (111111B, or 03FH), and the bit sample to be played is a 1, the counter will not increment. $4011 - Delta counter load register ----------------------------------- bits ---- 7 appears to be unused 1-6 the load inputs of the internal delta counter 0 LSB of the DAC A write to this register effectively loads the internal delta counter with a 6 bit value. Bit 0 is connected directly to the LSB (bit 0) of the DAC, and has no effect on the internal delta counter. Bit 7 appears to be unused. This register can be used to output direct 7-bit digital PCM data to the DMC's audio output. To use this register for PCM playback, the programmer would be responsible for making sure that this register is updated at a constant rate (therefore it is completely user-definable). A practical update rate for this register would be every scanline (113.67 CPU clocks) for a 15.7458 KHz playback rate. Another use of this register (although unrelated to DMC playback) has been to somewhat control the volume of the Triangle & Noise sound channel outputs. Please see NESSOUND.TXT for more information. $4012 - DMA address load register ---------------------------- This register contains the initial address where the DMC is to fetch samples from memory for playback. The effective address value is $4012 shl 6 or 0C000H. This register is connected to the load pins of the internal DMA address pointer register (counter). The counter is incremented after every DMA byte fetch. The counter is 15 bits in size, and has addresses wrap around from $FFFF to $8000 (not $C000, as you might have guessed). The DMA address pointer register is reloaded with the initial calculated address, when the DMC is activated from an inactive state, or when the length counter has arrived at terminal count (count=0), if in the looping playback mode. $4013 - DMA length register --------------------------- This register contains the length of the chunk of memory to be played by the DMC, and it's size is measured in bytes. The value of $4013 shl 4 is loaded into a 12 bit internal down counter, dubbed the length counter. The length counter is decremented after every DMA fetch, and when it arrives at 0, the DMC will take action(s) based on the 2 MSB of $4010. This counter will be loaded with the current calculated address value of $4013 when the DMC is activated from an inactive state. Because the value that is loaded by the length counter is $4013 shl 4, this effectively produces a calculated byte sample length of $4013 shl 4 + 1 (i.e. if $4013=0, sample length is 1 byte long; if $4013=FF, sample length is $FF1 bytes long). $4015 - DMC status ------------------ This contains the current status of the DMC channel. There are 2 read bits, and 1 write bit. bits ---- 7(R) DMC's IRQ status (1=CPU IRQ being caused by DMC) 4(R) DMC is currently enabled (playing a stream of samples) 4(W) enable/disable DMC (1=start/continue playing a sample;0=stop playing) When an IRQ goes off inside the 2A03, Bit 7 of $4015 can tell the interrupt handler if it was caused by the DMC hardware or not. This bit will be set (1) if the DMC is responsible for the IRQ. Of course, if your program has no other IRQ-generating hardware going while it's using the DMC, then reading this register is not neccessary upon IRQ generation. Note that reading this register will NOT clear bit 7 (meaning that the DMC's IRQ will still NOT be acknowledged). Also note that if the 2 MSB of $4010 were set to 10, no IRQ will be generated, and bit 7 will always be 0. Upon generation of a IRQ, to let the DMC know that the software has acknowledged the /IRQ (and to reset the DMC's internal IRQ flag), any write out to $4015 will reset the flag, or a write out to $4010 with the MSB set to 0 will do. These practices should be performed inside the IRQ handler routine. To replay the same sample that just finished, all you need to do is just write a 1 out to bit 4 of $4015. Bit 4 of $4015 reports the real-time status of the DMC. A returned value of 1 denotes that the channel is currently playing a stream of samples. A returned value of 0 indicates that the channel is inactive. If the programmer needed to know when a stream of samples was finished playing, but didn't want to use the IRQ generation feature of the DMC, then polling this bit would be a valid option. Writing a value to $4015's 4th bit has the effect of enabling the channel (start, or continue playing a stream of samples), or disabling the channel (stop all DMC activity). Note that writing a 1 to this bit while the channel is currently enabled, will have no effect on counters or registers internal to the DMC. The conditions that control the time the DMC will stay enabled are determined by the 2 MSB of $4010, and register $4013 (if applicable). System Reset ------------ On system reset, all 7 used bits of $4011 are reset to 0, the IRQ flag is cleared (disabled), and the channel is disabled. All other registers will remain unmodified. EOF